| 1 | /* pam_nologin module */ |
| 2 | |
| 3 | /* |
| 4 | * $Id: pam_nologin.c,v 1.2 2000/12/04 19:02:34 baggins Exp $ |
| 5 | * $FreeBSD: src/contrib/libpam/modules/pam_nologin/pam_nologin.c,v 1.3.2.2 2001/06/11 15:28:22 markm Exp $ |
| 6 | * $DragonFly: src/contrib/libpam/modules/pam_nologin/Attic/pam_nologin.c,v 1.2 2003/06/17 04:24:03 dillon Exp $ |
| 7 | * |
| 8 | * Written by Michael K. Johnson <johnsonm@redhat.com> 1996/10/24 |
| 9 | * |
| 10 | */ |
| 11 | |
| 12 | #include <stdio.h> |
| 13 | #include <stdlib.h> |
| 14 | #include <unistd.h> |
| 15 | #include <fcntl.h> |
| 16 | #include <sys/types.h> |
| 17 | #include <sys/stat.h> |
| 18 | #include <pwd.h> |
| 19 | |
| 20 | #include <security/_pam_macros.h> |
| 21 | /* |
| 22 | * here, we make a definition for the externally accessible function |
| 23 | * in this file (this definition is required for static a module |
| 24 | * but strongly encouraged generally) it is used to instruct the |
| 25 | * modules include file to define the function prototypes. |
| 26 | */ |
| 27 | |
| 28 | #define PAM_SM_AUTH |
| 29 | |
| 30 | #include <security/pam_modules.h> |
| 31 | |
| 32 | /* --- authentication management functions (only) --- */ |
| 33 | |
| 34 | PAM_EXTERN |
| 35 | int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, |
| 36 | const char **argv) |
| 37 | { |
| 38 | int retval = PAM_SUCCESS; |
| 39 | int fd; |
| 40 | const char *username; |
| 41 | char *mtmp=NULL; |
| 42 | struct passwd *user_pwd; |
| 43 | struct pam_conv *conversation; |
| 44 | struct pam_message message; |
| 45 | struct pam_message *pmessage = &message; |
| 46 | struct pam_response *resp = NULL; |
| 47 | struct stat st; |
| 48 | |
| 49 | if ((fd = open("/etc/nologin", O_RDONLY, 0)) >= 0) { |
| 50 | /* root can still log in; lusers cannot */ |
| 51 | if ((pam_get_user(pamh, &username, NULL) != PAM_SUCCESS) |
| 52 | || !username) { |
| 53 | return PAM_SERVICE_ERR; |
| 54 | } |
| 55 | user_pwd = getpwnam(username); |
| 56 | if (user_pwd && user_pwd->pw_uid == 0) { |
| 57 | message.msg_style = PAM_TEXT_INFO; |
| 58 | } else { |
| 59 | if (!user_pwd) { |
| 60 | retval = PAM_USER_UNKNOWN; |
| 61 | } else { |
| 62 | retval = PAM_AUTH_ERR; |
| 63 | } |
| 64 | message.msg_style = PAM_ERROR_MSG; |
| 65 | } |
| 66 | |
| 67 | /* fill in message buffer with contents of /etc/nologin */ |
| 68 | if (fstat(fd, &st) < 0) /* give up trying to display message */ |
| 69 | return retval; |
| 70 | message.msg = mtmp = malloc(st.st_size+1); |
| 71 | /* if malloc failed... */ |
| 72 | if (!message.msg) return retval; |
| 73 | read(fd, mtmp, st.st_size); |
| 74 | mtmp[st.st_size] = '\000'; |
| 75 | |
| 76 | /* Use conversation function to give user contents of /etc/nologin */ |
| 77 | pam_get_item(pamh, PAM_CONV, (const void **)&conversation); |
| 78 | conversation->conv(1, (const struct pam_message **)&pmessage, |
| 79 | &resp, conversation->appdata_ptr); |
| 80 | free(mtmp); |
| 81 | if (resp) |
| 82 | _pam_drop_reply(resp, 1); |
| 83 | } |
| 84 | |
| 85 | return retval; |
| 86 | } |
| 87 | |
| 88 | PAM_EXTERN |
| 89 | int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, |
| 90 | const char **argv) |
| 91 | { |
| 92 | return PAM_SUCCESS; |
| 93 | } |
| 94 | |
| 95 | |
| 96 | /* end of module definition */ |
| 97 | |
| 98 | PAM_MODULE_ENTRY("pam_nologin"); |