diff options
Diffstat (limited to 'pam_file.c')
-rw-r--r-- | pam_file.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/pam_file.c b/pam_file.c new file mode 100644 index 0000000..72cd877 --- /dev/null +++ b/pam_file.c @@ -0,0 +1,114 @@ +/* + + pam_file - Simple PAM module to check a username in a file + + Copyright (C) 2018 Ian Cowburn (ianc@noddybox.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +*/ +#define PAM_SM_AUTH + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <security/pam_appl.h> +#include <security/pam_modules.h> + +static void RemoveNL(char *p) +{ + size_t l = strlen(p); + + while(l && p[l-1] == '\n') + { + p[--l] = 0; + } +} + +PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pam, + int flags, + int argc, + const char *argv[]) +{ + static const char *file_arg="file="; + static const char *mode_arg="mode="; + const char *file = NULL; + const char *mode = NULL; + const char *user; + char buff[1024]; + FILE *fp; + int block; + int result; + int f; + + if (pam_get_user(pam, &user, NULL) != PAM_SUCCESS || user == NULL) + { + return PAM_IGNORE; + } + + for(f = 0; f < argc; f++) + { + if (strncmp(file_arg, argv[f], strlen(file_arg)) == 0) + { + file = argv[f] + strlen(file_arg); + } + + if (strncmp(mode_arg, argv[f], strlen(mode_arg)) == 0) + { + mode = argv[f] + strlen(mode_arg); + } + } + + if (!file && !mode) + { + return PAM_IGNORE; + } + + block = strcmp(mode, "block") == 0; + + if (!(fp = fopen(file, "r"))) + { + return PAM_IGNORE; + } + + if (block) + { + result = PAM_SUCCESS; + } + else + { + result = PAM_AUTH_ERR; + } + + while(fgets(buff, sizeof buff, fp)) + { + RemoveNL(buff); + + if (strcmp(buff, user) == 0) + { + if (block) + { + result = PAM_AUTH_ERR; + } + else + { + result = PAM_SUCCESS; + } + } + } + + fclose(fp); + + return result; +} |