/* 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 . */ #define PAM_SM_AUTH #include #include #include #include #include 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; }