Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / contrib / libpam / modules / pam_shells / pam_shells.c
1 /* pam_shells module */
2
3 #define SHELL_FILE "/etc/shells"
4
5 /*
6  * by Erik Troan <ewt@redhat.com>, Red Hat Software.
7  * August 5, 1996.
8  * This code shamelessly ripped from the pam_securetty module.
9  * $FreeBSD: src/contrib/libpam/modules/pam_shells/pam_shells.c,v 1.3.2.2 2001/06/11 15:28:28 markm Exp $
10  * $DragonFly: src/contrib/libpam/modules/pam_shells/Attic/pam_shells.c,v 1.2 2003/06/17 04:24:03 dillon Exp $
11  */
12
13 #define _BSD_SOURCE
14
15 #include <pwd.h>
16 #include <stdarg.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <sys/stat.h>
20 #include <syslog.h>
21 #include <unistd.h>
22
23 /*
24  * here, we make a definition for the externally accessible function
25  * in this file (this definition is required for static a module
26  * but strongly encouraged generally) it is used to instruct the
27  * modules include file to define the function prototypes.
28  */
29
30 #define PAM_SM_AUTH
31
32 #include <security/pam_modules.h>
33
34 /* some syslogging */
35
36 static void _pam_log(int err, const char *format, ...)
37 {
38     va_list args;
39
40     va_start(args, format);
41     openlog("PAM-shells", LOG_CONS|LOG_PID, LOG_AUTH);
42     vsyslog(err, format, args);
43     va_end(args);
44     closelog();
45 }
46
47 /* --- authentication management functions (only) --- */
48
49 PAM_EXTERN
50 int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
51                         ,const char **argv)
52 {
53      int retval = PAM_AUTH_ERR;
54      const char *userName;
55      char *userShell;
56      char shellFileLine[256];
57      struct stat sb;
58      struct passwd * pw;
59      FILE * shellFile;
60
61      retval = pam_get_user(pamh,&userName,NULL);
62      if(retval != PAM_SUCCESS) 
63        return PAM_SERVICE_ERR;
64
65      if(!userName || (strlen(userName) <= 0)) {
66        /* Don't let them use a NULL username... */
67        pam_get_user(pamh,&userName,NULL);
68         if (retval != PAM_SUCCESS)
69           return PAM_SERVICE_ERR;
70      }
71
72      pw = getpwnam(userName);
73      if (!pw)
74         return PAM_AUTH_ERR;            /* user doesn't exist */
75      userShell = pw->pw_shell;
76
77      if(stat(SHELL_FILE,&sb)) {
78         _pam_log(LOG_ERR,
79                 "%s cannot be stat'd (it probably does not exist)", SHELL_FILE);
80         return PAM_AUTH_ERR;            /* must have /etc/shells */
81      }
82
83      if((sb.st_mode & S_IWOTH) || !S_ISREG(sb.st_mode)) {
84         _pam_log(LOG_ERR,
85                 "%s is either world writable or not a normal file", SHELL_FILE);
86         return PAM_AUTH_ERR;
87      }
88
89      shellFile = fopen(SHELL_FILE,"r");
90      if(shellFile == NULL) { /* Check that we opened it successfully */
91         _pam_log(LOG_ERR,
92                 "Error opening %s", SHELL_FILE);
93        return PAM_SERVICE_ERR;
94      }
95      /* There should be no more errors from here on */
96      retval=PAM_AUTH_ERR;
97      /* This loop assumes that PAM_SUCCESS == 0
98         and PAM_AUTH_ERR != 0 */
99      while((fgets(shellFileLine,255,shellFile) != NULL) 
100            && retval) {
101        if (shellFileLine[strlen(shellFileLine) - 1] == '\n')
102            shellFileLine[strlen(shellFileLine) - 1] = '\0';
103        retval = strcmp(shellFileLine, userShell);
104      }
105      fclose(shellFile);
106      if(retval)
107        retval = PAM_AUTH_ERR;
108      return retval;
109 }
110
111 PAM_EXTERN
112 int pam_sm_setcred(pam_handle_t *pamh,int flags,int argc
113                    ,const char **argv)
114 {
115      return PAM_SUCCESS;
116 }
117
118
119 #ifdef PAM_STATIC
120
121 /* static module data */
122
123 struct pam_module _pam_shells_modstruct = {
124      "pam_shells",
125      pam_sm_authenticate,
126      pam_sm_setcred,
127      NULL,
128      NULL,
129      NULL,
130      NULL,
131 };
132
133 #endif
134
135 /* end of module definition */