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