summaryrefslogtreecommitdiff
path: root/modules/pam_nologin/pam_nologin.c
blob: 306619e160b8ec46e36fcc77c0bc6a29c481c177 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* pam_nologin module */

/*
 * $Id$
 *
 * Written by Michael K. Johnson <johnsonm@redhat.com> 1996/10/24
 *
 * $Log$
 * Revision 1.1  2000/06/20 22:11:46  agmorgan
 * Initial revision
 *
 * Revision 1.1.1.1  1998/07/12 05:17:17  morgan
 * Linux PAM sources pre-0.66
 *
 * Revision 1.4  1997/04/05 06:36:47  morgan
 * display message when the user is unknown
 *
 * Revision 1.3  1996/12/01 03:00:54  morgan
 * added prototype to conversation, gave static structure name of module
 *
 * Revision 1.2  1996/11/10 21:02:31  morgan
 * compile against .53
 *
 * Revision 1.1  1996/10/25 03:19:36  morgan
 * Initial revision
 *
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>

#include <security/_pam_macros.h>
/*
 * here, we make a definition for the externally accessible function
 * in this file (this definition is required for static a module
 * but strongly encouraged generally) it is used to instruct the
 * modules include file to define the function prototypes.
 */

#define PAM_SM_AUTH

#include <security/pam_modules.h>

/* --- authentication management functions (only) --- */

PAM_EXTERN
int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
                        const char **argv)
{
     int retval = PAM_SUCCESS;
     int fd;
     const char *username;
     char *mtmp=NULL;
     struct passwd *user_pwd;
     struct pam_conv *conversation;
     struct pam_message message;
     struct pam_message *pmessage = &message;
     struct pam_response *resp = NULL;
     struct stat st;

     if ((fd = open("/etc/nologin", O_RDONLY, 0)) >= 0) {
       /* root can still log in; lusers cannot */
       if ((pam_get_user(pamh, &username, NULL) != PAM_SUCCESS)
           || !username) {
         return PAM_SERVICE_ERR;
       }
       user_pwd = getpwnam(username);
       if (user_pwd && user_pwd->pw_uid == 0) {
         message.msg_style = PAM_TEXT_INFO;
       } else {
	   if (!user_pwd) {
	       retval = PAM_USER_UNKNOWN;
	   } else {
	       retval = PAM_AUTH_ERR;
	   }
	   message.msg_style = PAM_ERROR_MSG;
       }

       /* fill in message buffer with contents of /etc/nologin */
       if (fstat(fd, &st) < 0) /* give up trying to display message */
         return retval;
       message.msg = mtmp = malloc(st.st_size+1);
       /* if malloc failed... */
       if (!message.msg) return retval;
       read(fd, mtmp, st.st_size);
       mtmp[st.st_size] = '\000';

       /* Use conversation function to give user contents of /etc/nologin */
       pam_get_item(pamh, PAM_CONV, (const void **)&conversation);
       conversation->conv(1, (const struct pam_message **)&pmessage,
			  &resp, conversation->appdata_ptr);
       free(mtmp);
       if (resp)
	   _pam_drop_reply(resp, 1);
     }

     return retval;
}

PAM_EXTERN
int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc,
                   const char **argv)
{
     return PAM_SUCCESS;
}


#ifdef PAM_STATIC

/* static module data */

struct pam_module _pam_nologin_modstruct = {
     "pam_nologin",
     pam_sm_authenticate,
     pam_sm_setcred,
     NULL,
     NULL,
     NULL,
     NULL,
};

#endif

/* end of module definition */