#include #include #include #include #include #include #include #ifndef __linux__ #include #endif #define PAM_SM_AUTH #include #include #include #define NOLOGIN "/etc/nologin" PAM_EXTERN int pam_sm_authenticate( pam_handle_t *pamh, int flags, int argc, const char * argv[] ) { struct passwd *pwd; struct stat st; char *mtmp = NULL; const char * user; int pam_err, fd; #ifndef __linux__ login_cap_t *lc; #endif if( (pam_err = pam_get_user(pamh,&user, NULL)) != PAM_SUCCESS || (user == NULL) ) { PAM_ERROR("Could not determine user"); return (PAM_USER_UNKNOWN); } #ifndef __linux__ lc = login_getclass(NULL); nologin = login_getcapstr(lc, "nologin", nologin_def, nologin_def); login_close(lc); lc = NULL; fd = open(nologin, O_RDONLY, 0); #else fd = open(NOLOGIN, O_RDONLY, 0); #endif /* * LinuxPAM's nologin returns PAM_IGNORE when no 'nologin' file is * present while freebsd's nologin returns PAM_SUCCESS. We'll go * with PAM_IGNORE * */ if (fd < 0 ) return (PAM_IGNORE); pwd = getpwnam(user); if(pwd && pwd->pw_uid == 0 ) pam_err = PAM_SUCCESS; else { if ( ! pwd ) pam_err = PAM_USER_UNKNOWN; else pam_err = PAM_AUTH_ERR; } /* get contents of /etc/nologin */ if (fstat(fd,&st) < 0) { close(fd); free(mtmp); return (pam_err); } mtmp = malloc(st.st_size + 1); if (!mtmp) { PAM_ERROR("Out of memory"); close(fd); free(mtmp); return (PAM_BUF_ERR); } if ( read(fd, mtmp, st.st_size) == st.st_size ) { mtmp[st.st_size] = '\0'; PAM_ERROR("%s", mtmp); } else pam_err = PAM_SYSTEM_ERR; close(fd); free (mtmp); return (pam_err); } PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh , int flags , int argc , const char *argv[]) { return (PAM_SUCCESS); } PAM_MODULE_ENTRY("pam_nologin");