#include #include #include #include #include #include #define PAM_SM_AUTH #include #include #include #define TTY_PREFIX "/dev/" PAM_EXTERN int pam_sm_authenticate(pam_handle_t * pamh, int flags, int argc, const char * argv[]) { struct passwd *pwd; struct ttyent *ttyinfo; const char *user; const char *tty; int pam_err; if ( ( (pam_err = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS ) || ( user == NULL ) ) { PAM_ERROR("Error recovering username."); return (pam_err); } if ( (pwd = getpwnam(user)) == NULL ) { PAM_ERROR("Could not get passwd entry for user [%s]",user); return (PAM_SERVICE_ERR); } if ( pwd->pw_uid != 0 ) { /* secure tty applies only to root */ return (PAM_SUCCESS); } if ( (pam_err = pam_get_item(pamh, PAM_TTY,(void *) &tty) ) != PAM_SUCCESS ) { return (pam_err); } if (tty != NULL && strncmp(TTY_PREFIX, tty, sizeof(TTY_PREFIX)) == 0) { PAM_LOG("tty starts with " TTY_PREFIX); /* get rid of prefix */ tty = (const char *)tty + sizeof(TTY_PREFIX) - 1; } /* * Linux-PAM, before checking the actual tty, * opens /etc/securettys to check if it's world * writable or not a normal file and only continues * if neither is correct. Sounds like a good idea - * maybe it should be done here as well... */ if ( tty != NULL && (ttyinfo = getttynam(tty)) != NULL && (ttyinfo->ty_status & TTY_SECURE) != 0) return (PAM_SUCCESS); PAM_ERROR("Access denied: tty %s is not secure", tty); return (PAM_AUTH_ERR); } PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh , int flags , int argc , const char *argv[]) { return (PAM_SUCCESS); } PAM_MODULE_ENTRY("pam_securetty");