1 /* pam_securetty module */
3 #define SECURETTY_FILE "/etc/securetty"
4 #define TTY_PREFIX "/dev/"
7 * by Elliot Lee <sopwith@redhat.com>, Red Hat Software.
9 * This code shamelessly ripped from the pam_rootok module.
10 * Slight modifications AGM. 1996/12/3
17 #include <sys/types.h>
28 * here, we make a definition for the externally accessible function
29 * in this file (this definition is required for static a module
30 * but strongly encouraged generally) it is used to instruct the
31 * modules include file to define the function prototypes.
36 #include <security/pam_modules.h>
40 static void _pam_log(int err, const char *format, ...)
44 va_start(args, format);
45 openlog("PAM-securetty", LOG_CONS|LOG_PID, LOG_AUTH);
46 vsyslog(err, format, args);
51 /* argument parsing */
53 #define PAM_DEBUG_ARG 0x0001
55 static int _pam_parse(int argc, const char **argv)
59 /* step through arguments */
60 for (ctrl=0; argc-- > 0; ++argv) {
64 if (!strcmp(*argv,"debug"))
65 ctrl |= PAM_DEBUG_ARG;
67 _pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv);
74 /* --- authentication management functions (only) --- */
77 int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
80 int retval = PAM_AUTH_ERR;
83 char ttyfileline[256];
84 struct stat ttyfileinfo;
85 struct passwd *user_pwd;
89 /* parse the arguments */
90 ctrl = _pam_parse(argc, argv);
92 retval = pam_get_user(pamh, &username, NULL);
93 if (retval != PAM_SUCCESS || username == NULL) {
94 if (ctrl & PAM_DEBUG_ARG) {
95 _pam_log(LOG_WARNING, "cannot determine username");
97 return (retval == PAM_CONV_AGAIN
98 ? PAM_INCOMPLETE:PAM_SERVICE_ERR);
101 retval = pam_get_item(pamh, PAM_TTY, (const void **)&uttyname);
102 if (retval != PAM_SUCCESS || uttyname == NULL) {
103 if (ctrl & PAM_DEBUG_ARG) {
104 _pam_log(LOG_WARNING, "cannot determine user's tty");
106 return PAM_SERVICE_ERR;
109 /* The PAM_TTY item may be prefixed with "/dev/" - skip that */
110 if (strncmp(TTY_PREFIX, uttyname, sizeof(TTY_PREFIX)-1) == 0)
111 uttyname += sizeof(TTY_PREFIX)-1;
113 user_pwd = getpwnam(username);
114 if (user_pwd == NULL) {
116 } else if (user_pwd->pw_uid != 0) { /* If the user is not root,
117 securetty's does not apply
122 if (stat(SECURETTY_FILE, &ttyfileinfo)) {
123 _pam_log(LOG_NOTICE, "Couldn't open " SECURETTY_FILE);
124 return PAM_SUCCESS; /* for compatibility with old securetty handling,
125 this needs to succeed. But we still log the
129 if ((ttyfileinfo.st_mode & S_IWOTH)
130 || !S_ISREG(ttyfileinfo.st_mode)) {
131 /* If the file is world writable or is not a
132 normal file, return error */
133 _pam_log(LOG_ERR, SECURETTY_FILE
134 " is either world writable or not a normal file");
138 ttyfile = fopen(SECURETTY_FILE,"r");
139 if(ttyfile == NULL) { /* Check that we opened it successfully */
141 "Error opening " SECURETTY_FILE);
142 return PAM_SERVICE_ERR;
144 /* There should be no more errors from here on */
146 /* This loop assumes that PAM_SUCCESS == 0
147 and PAM_AUTH_ERR != 0 */
148 while((fgets(ttyfileline,sizeof(ttyfileline)-1, ttyfile) != NULL)
150 if(ttyfileline[strlen(ttyfileline) - 1] == '\n')
151 ttyfileline[strlen(ttyfileline) - 1] = '\0';
152 retval = strcmp(ttyfileline,uttyname);
156 if (ctrl & PAM_DEBUG_ARG)
157 _pam_log(LOG_WARNING, "access denied: tty '%s' is not secure !",
159 retval = PAM_AUTH_ERR;
161 if ((retval == PAM_SUCCESS) && (ctrl & PAM_DEBUG_ARG))
162 _pam_log(LOG_DEBUG, "access allowed for '%s' on '%s'",
168 int pam_sm_setcred(pam_handle_t *pamh,int flags,int argc
177 /* static module data */
179 struct pam_module _pam_securetty_modstruct = {
191 /* end of module definition */