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