From c95e6e34c26fc95f622b4d0535bccede3c655146 Mon Sep 17 00:00:00 2001 From: "Andrew G. Morgan" Date: Sat, 13 Jul 2002 05:10:54 +0000 Subject: [PATCH] Relevant BUGIDs: 436435 Purpose of commit: new feature Commit summary: --------------- add account management to a bunch of modules. Submitted by Harald Welte. --- CHANGELOG | 5 +- modules/pam_listfile/pam_listfile.c | 14 ++- modules/pam_nologin/pam_nologin.c | 3 +- modules/pam_securetty/pam_securetty.c | 110 +++++++++++++++------- modules/pam_shells/pam_shells.c | 129 +++++++++++++++----------- modules/pam_wheel/pam_wheel.c | 59 ++++++++---- 6 files changed, 204 insertions(+), 116 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index f10c76f5..b3cc17db 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -55,6 +55,9 @@ bug report - outstanding bugs are listed here: 0.77: please submit patches for this section with actual code/doc patches! +* account management support for: pam_shells, pam_listfile, pam_wheel + and pam_securetty (+ static module fix for pam_nologin). Patch from + redhat through Harrold Welte (Bug 436435 - agmorgan). * pam_wheel feature from Nalin - can use the module to provide wheel access to non-root accounts. Also from Nalin, a bugfix related to the primary group of the applicant is the 'wheel' group. (Bugs @@ -69,7 +72,7 @@ bug report - outstanding bugs are listed here: * pam_unix: fix for legacy crypt() support when the password entered was long. (Bug 521314 - agmorgan). -* pam_access no longer include gethostname() prototype complained from +* pam_access no longer include gethostname() prototype complaint from David Lee (Bug 415423 - agmorgan). * make pam_nologin more secure by default, added two new module arguments etc. - acting on suggestion from Nico (Bug 419307 - diff --git a/modules/pam_listfile/pam_listfile.c b/modules/pam_listfile/pam_listfile.c index b560b4b6..527d036f 100644 --- a/modules/pam_listfile/pam_listfile.c +++ b/modules/pam_listfile/pam_listfile.c @@ -35,6 +35,7 @@ */ #define PAM_SM_AUTH +#define PAM_SM_ACCOUNT #include #include @@ -134,8 +135,6 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **ar struct group *grpinfo; char *itemlist[256]; /* Maximum of 256 items */ - D(("called.")); - apply_type=APPLY_TYPE_NULL; memset(apply_val,0,sizeof(apply_val)); @@ -419,6 +418,13 @@ int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) return PAM_SUCCESS; } +PAM_EXTERN +int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, + const char **argv) +{ + return pam_sm_authenticate(pamh, 0, argc, argv); +} + #ifdef PAM_STATIC /* static module data */ @@ -427,13 +433,13 @@ struct pam_module _pam_listfile_modstruct = { "pam_listfile", pam_sm_authenticate, pam_sm_setcred, - NULL, + pam_sm_acct_mgmt, NULL, NULL, NULL, }; -#endif +#endif /* PAM_STATIC */ /* end of module definition */ diff --git a/modules/pam_nologin/pam_nologin.c b/modules/pam_nologin/pam_nologin.c index 7b2394af..6916a7b4 100644 --- a/modules/pam_nologin/pam_nologin.c +++ b/modules/pam_nologin/pam_nologin.c @@ -24,6 +24,7 @@ */ #define PAM_SM_AUTH +#define PAM_SM_ACCOUNT #include @@ -192,6 +193,6 @@ struct pam_module _pam_nologin_modstruct = { NULL, }; -#endif +#endif /* PAM_STATIC */ /* end of module definition */ diff --git a/modules/pam_securetty/pam_securetty.c b/modules/pam_securetty/pam_securetty.c index 9e6121e8..c69180ab 100644 --- a/modules/pam_securetty/pam_securetty.c +++ b/modules/pam_securetty/pam_securetty.c @@ -21,8 +21,7 @@ #include #include #include - -#define PAM_SM_AUTH +#include /* * here, we make a definition for the externally accessible function @@ -32,6 +31,7 @@ */ #define PAM_SM_AUTH +#define PAM_SM_ACCOUNT #include @@ -71,31 +71,30 @@ static int _pam_parse(int argc, const char **argv) return ctrl; } -/* --- authentication management functions (only) --- */ - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc - ,const char **argv) +static int securetty_perform_check(pam_handle_t *pamh, int flags, int ctrl, + const char *function_name) { int retval = PAM_AUTH_ERR; const char *username; char *uttyname; char ttyfileline[256]; + char ptname[256]; struct stat ttyfileinfo; struct passwd *user_pwd; FILE *ttyfile; - int ctrl; - /* parse the arguments */ - ctrl = _pam_parse(argc, argv); + /* log a trail for debugging */ + if (ctrl & PAM_DEBUG_ARG) { + _pam_log(LOG_DEBUG, "pam_securetty called via %s function", + function_name); + } retval = pam_get_user(pamh, &username, NULL); if (retval != PAM_SUCCESS || username == NULL) { if (ctrl & PAM_DEBUG_ARG) { _pam_log(LOG_WARNING, "cannot determine username"); } - return (retval == PAM_CONV_AGAIN - ? PAM_INCOMPLETE:PAM_SERVICE_ERR); + return (retval == PAM_CONV_AGAIN ? PAM_INCOMPLETE:PAM_SERVICE_ERR); } retval = pam_get_item(pamh, PAM_TTY, (const void **)&uttyname); @@ -107,8 +106,9 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc } /* The PAM_TTY item may be prefixed with "/dev/" - skip that */ - if (strncmp(TTY_PREFIX, uttyname, sizeof(TTY_PREFIX)-1) == 0) + if (strncmp(TTY_PREFIX, uttyname, sizeof(TTY_PREFIX)-1) == 0) { uttyname += sizeof(TTY_PREFIX)-1; + } user_pwd = getpwnam(username); if (user_pwd == NULL) { @@ -126,8 +126,7 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc error. */ } - if ((ttyfileinfo.st_mode & S_IWOTH) - || !S_ISREG(ttyfileinfo.st_mode)) { + if ((ttyfileinfo.st_mode & S_IWOTH) || !S_ISREG(ttyfileinfo.st_mode)) { /* If the file is world writable or is not a normal file, return error */ _pam_log(LOG_ERR, SECURETTY_FILE @@ -136,39 +135,82 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc } ttyfile = fopen(SECURETTY_FILE,"r"); - if(ttyfile == NULL) { /* Check that we opened it successfully */ + if (ttyfile == NULL) { /* Check that we opened it successfully */ _pam_log(LOG_ERR, "Error opening " SECURETTY_FILE); return PAM_SERVICE_ERR; } - /* There should be no more errors from here on */ - retval=PAM_AUTH_ERR; - /* This loop assumes that PAM_SUCCESS == 0 - and PAM_AUTH_ERR != 0 */ - while((fgets(ttyfileline,sizeof(ttyfileline)-1, ttyfile) != NULL) - && retval) { - if(ttyfileline[strlen(ttyfileline) - 1] == '\n') + + if (isdigit(uttyname[0])) { + snprintf(ptname, sizeof(ptname), "pts/%s", uttyname); + } else { + ptname[0] = '\0'; + } + + retval = 1; + + while ((fgets(ttyfileline, sizeof(ttyfileline)-1, ttyfile) != NULL) + && retval) { + if (ttyfileline[strlen(ttyfileline) - 1] == '\n') ttyfileline[strlen(ttyfileline) - 1] = '\0'; - retval = strcmp(ttyfileline,uttyname); + + retval = ( strcmp(ttyfileline, uttyname) + && (!ptname[0] || strcmp(ptname, uttyname)) ); } fclose(ttyfile); - if(retval) { - if (ctrl & PAM_DEBUG_ARG) + + if (retval) { + if (ctrl & PAM_DEBUG_ARG) { _pam_log(LOG_WARNING, "access denied: tty '%s' is not secure !", uttyname); + } retval = PAM_AUTH_ERR; + + } else { + if ((retval == PAM_SUCCESS) && (ctrl & PAM_DEBUG_ARG)) { + _pam_log(LOG_DEBUG, "access allowed for '%s' on '%s'", + username, uttyname); + } + retval = PAM_SUCCESS; + } - if ((retval == PAM_SUCCESS) && (ctrl & PAM_DEBUG_ARG)) - _pam_log(LOG_DEBUG, "access allowed for '%s' on '%s'", - username, uttyname); + return retval; } +/* --- authentication management functions --- */ + PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh,int flags,int argc - ,const char **argv) +int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, + const char **argv) { - return PAM_SUCCESS; + int ctrl; + + /* parse the arguments */ + ctrl = _pam_parse(argc, argv); + + return securetty_perform_check(pamh, flags, ctrl, __FUNCTION__); +} + +PAM_EXTERN +int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) +{ + return PAM_SUCCESS; +} + +/* --- account management functions --- */ + +PAM_EXTERN +int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, + const char **argv) +{ + int ctrl; + + /* parse the arguments */ + ctrl = _pam_parse(argc, argv); + + /* take the easy route */ + return securetty_perform_check(pamh, flags, ctrl, __FUNCTION__); } @@ -180,12 +222,12 @@ struct pam_module _pam_securetty_modstruct = { "pam_securetty", pam_sm_authenticate, pam_sm_setcred, - NULL, + pam_sm_acct_mgmt, NULL, NULL, NULL, }; -#endif +#endif /* PAM_STATIC */ /* end of module definition */ diff --git a/modules/pam_shells/pam_shells.c b/modules/pam_shells/pam_shells.c index 36dd1a91..b70ba030 100644 --- a/modules/pam_shells/pam_shells.c +++ b/modules/pam_shells/pam_shells.c @@ -26,6 +26,7 @@ */ #define PAM_SM_AUTH +#define PAM_SM_ACCOUNT #include @@ -42,77 +43,93 @@ static void _pam_log(int err, const char *format, ...) closelog(); } -/* --- authentication management functions (only) --- */ - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc - ,const char **argv) +static int perform_check(pam_handle_t *pamh, int flags) { - int retval = PAM_AUTH_ERR; - const char *userName; - char *userShell; - char shellFileLine[256]; - struct stat sb; - struct passwd * pw; - FILE * shellFile; - - retval = pam_get_user(pamh,&userName,NULL); - if(retval != PAM_SUCCESS) - return PAM_SERVICE_ERR; - - if(!userName || (strlen(userName) <= 0)) { - /* Don't let them use a NULL username... */ - pam_get_user(pamh,&userName,NULL); + int retval = PAM_AUTH_ERR; + const char *userName; + char *userShell; + char shellFileLine[256]; + struct stat sb; + struct passwd * pw; + FILE * shellFile; + + retval = pam_get_user(pamh, &userName, NULL); + if (retval != PAM_SUCCESS) { + return PAM_SERVICE_ERR; + } + + if (!userName || (strlen(userName) <= 0)) { + /* Don't let them use a NULL username... */ + pam_get_user(pamh,&userName,NULL); if (retval != PAM_SUCCESS) - return PAM_SERVICE_ERR; - } + return PAM_SERVICE_ERR; + } - pw = getpwnam(userName); - if (!pw) + pw = getpwnam(userName); + if (!pw) { return PAM_AUTH_ERR; /* user doesn't exist */ - userShell = pw->pw_shell; + } + userShell = pw->pw_shell; - if(stat(SHELL_FILE,&sb)) { - _pam_log(LOG_ERR, - "%s cannot be stat'd (it probably does not exist)", SHELL_FILE); + if (stat(SHELL_FILE,&sb)) { + _pam_log(LOG_ERR, "%s cannot be stat'd (it probably does not exist)", + SHELL_FILE); return PAM_AUTH_ERR; /* must have /etc/shells */ - } + } - if((sb.st_mode & S_IWOTH) || !S_ISREG(sb.st_mode)) { - _pam_log(LOG_ERR, - "%s is either world writable or not a normal file", SHELL_FILE); + if ((sb.st_mode & S_IWOTH) || !S_ISREG(sb.st_mode)) { + _pam_log(LOG_ERR, "%s is either world writable or not a normal file", + SHELL_FILE); return PAM_AUTH_ERR; - } + } - shellFile = fopen(SHELL_FILE,"r"); - if(shellFile == NULL) { /* Check that we opened it successfully */ + shellFile = fopen(SHELL_FILE,"r"); + if (shellFile == NULL) { /* Check that we opened it successfully */ _pam_log(LOG_ERR, - "Error opening %s", SHELL_FILE); - return PAM_SERVICE_ERR; - } - /* There should be no more errors from here on */ - retval=PAM_AUTH_ERR; - /* This loop assumes that PAM_SUCCESS == 0 - and PAM_AUTH_ERR != 0 */ - while((fgets(shellFileLine,255,shellFile) != NULL) - && retval) { - if (shellFileLine[strlen(shellFileLine) - 1] == '\n') - shellFileLine[strlen(shellFileLine) - 1] = '\0'; - retval = strcmp(shellFileLine, userShell); - } - fclose(shellFile); - if(retval) - retval = PAM_AUTH_ERR; - return retval; + "Error opening %s", SHELL_FILE); + return PAM_SERVICE_ERR; + } + + retval = 1; + + while((fgets(shellFileLine, 255, shellFile) != NULL) && retval) { + if (shellFileLine[strlen(shellFileLine) - 1] == '\n') + shellFileLine[strlen(shellFileLine) - 1] = '\0'; + retval = strcmp(shellFileLine, userShell); + } + + fclose(shellFile); + + if (retval) { + return PAM_AUTH_ERR; + } else { + return PAM_SUCCESS; + } +} + +/* --- authentication management functions (only) --- */ + +PAM_EXTERN +int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, + const char **argv) +{ + return perform_check(pamh, flags); } PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh,int flags,int argc - ,const char **argv) +int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc,const char **argv) { return PAM_SUCCESS; } +/* --- account management functions (only) --- */ + +PAM_EXTERN +int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, + const char **argv) +{ + return perform_check(pamh, flags); +} #ifdef PAM_STATIC @@ -122,12 +139,12 @@ struct pam_module _pam_shells_modstruct = { "pam_shells", pam_sm_authenticate, pam_sm_setcred, - NULL, + pam_sm_acct_mgmt, NULL, NULL, NULL, }; -#endif +#endif /* PAM_STATIC */ /* end of module definition */ diff --git a/modules/pam_wheel/pam_wheel.c b/modules/pam_wheel/pam_wheel.c index bdc794ba..c460abc9 100644 --- a/modules/pam_wheel/pam_wheel.c +++ b/modules/pam_wheel/pam_wheel.c @@ -40,6 +40,7 @@ */ #define PAM_SM_AUTH +#define PAM_SM_ACCOUNT #include @@ -105,22 +106,15 @@ static int _pam_parse(int argc, const char **argv, char *use_group, return ctrl; } - -/* --- authentication management functions --- */ - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc, - const char **argv) +static int perform_check(pam_handle_t *pamh, int flags, int ctrl, + const char *use_group) { - int ctrl; const char *username = NULL; char *fromsu; struct passwd *pwd, *tpwd; struct group *grp; int retval = PAM_AUTH_ERR; - char use_group[BUFSIZ]; - - ctrl = _pam_parse(argc, argv, use_group, sizeof(use_group)); + retval = pam_get_user(pamh, &username, NULL); if ((retval != PAM_SUCCESS) || (!username)) { if (ctrl & PAM_DEBUG_ARG) { @@ -177,7 +171,7 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc, if (!use_group[0]) { _pam_log(LOG_NOTICE,"no members in a GID 0 group"); } else { - _pam_log(LOG_NOTICE,"no members in '%s' group",use_group); + _pam_log(LOG_NOTICE,"no members in '%s' group", use_group); } } if (ctrl & PAM_DENY_ARG) { @@ -225,32 +219,57 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc, } else { return PAM_PERM_DENIED; } +} + +/* --- authentication management functions --- */ + +PAM_EXTERN +int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, + const char **argv) +{ + char use_group[BUFSIZ]; + int ctrl; + ctrl = _pam_parse(argc, argv, use_group, sizeof(use_group)); + + return perform_check(pamh, flags, ctrl, use_group); } PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh,int flags,int argc ,const char **argv) { - return PAM_SUCCESS; + return PAM_SUCCESS; } +PAM_EXTERN +int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, + const char **argv) +{ + char use_group[BUFSIZ]; + int ctrl; + + ctrl = _pam_parse(argc, argv, use_group, sizeof(use_group)); + + return perform_check(pamh, flags, ctrl, use_group); +} #ifdef PAM_STATIC /* static module data */ struct pam_module _pam_wheel_modstruct = { - "pam_wheel", - pam_sm_authenticate, - pam_sm_setcred, - NULL, - NULL, - NULL, - NULL, + "pam_wheel", + pam_sm_authenticate, + pam_sm_setcred, + pam_sm_acct_mgmt, + NULL, + NULL, + NULL, + NULL, }; -#endif +#endif /* PAM_STATIC */ /* * Copyright (c) Cristian Gafton , 1996, 1997 -- 2.40.0