diff options
author | Tomas Mraz <tm@t8m.info> | 2008-01-23 15:35:12 +0000 |
---|---|---|
committer | Tomas Mraz <tm@t8m.info> | 2008-01-23 15:35:12 +0000 |
commit | 459e97431e99fa2c32e30e957993f95794b98dd0 (patch) | |
tree | dcf013e6644eba5ee5bdbaf6b2f78999bf43dc9b /modules/pam_unix/support.c | |
parent | ca2cb12dd3165ab006c674d673a2d596d642c875 (diff) | |
download | pam-459e97431e99fa2c32e30e957993f95794b98dd0.tar.gz pam-459e97431e99fa2c32e30e957993f95794b98dd0.tar.bz2 pam-459e97431e99fa2c32e30e957993f95794b98dd0.zip |
Relevant BUGIDs:
Purpose of commit: cleanup, new feature
Commit summary:
---------------
Merging the the refactorization pam_unix_ref branch into the trunk.
Added support for sha256 and sha512 password hashes to pam_unix
when the libcrypt supports them.
Diffstat (limited to 'modules/pam_unix/support.c')
-rw-r--r-- | modules/pam_unix/support.c | 216 |
1 files changed, 72 insertions, 144 deletions
diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index 60acc958..b82cad26 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -52,8 +52,8 @@ int _make_remark(pam_handle_t * pamh, unsigned int ctrl, * set the control flags for the UNIX module. */ -int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int argc, - const char **argv) +int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds, + int argc, const char **argv) { unsigned int ctrl; @@ -109,6 +109,16 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int argc, *remember = 400; } } + if (rounds != NULL) { + if (j == UNIX_ALGO_ROUNDS) { + *rounds = strtol(*argv + 7, NULL, 10); + if ((*rounds < 1000) || (*rounds == INT_MAX)) + /* don't care about bogus values */ + unset(UNIX_ALGO_ROUNDS, ctrl); + if (*rounds >= 10000000) + *rounds = 9999999; + } + } } ++argv; /* step to next argument */ @@ -376,95 +386,6 @@ int _unix_comesfromsource(pam_handle_t *pamh, } /* - * _unix_blankpasswd() is a quick check for a blank password - * - * returns TRUE if user does not have a password - * - to avoid prompting for one in such cases (CG) - */ - -int -_unix_blankpasswd (pam_handle_t *pamh, unsigned int ctrl, const char *name) -{ - struct passwd *pwd = NULL; - struct spwd *spwdent = NULL; - char *salt = NULL; - int retval; - - D(("called")); - - /* - * This function does not have to be too smart if something goes - * wrong, return FALSE and let this case to be treated somewhere - * else (CG) - */ - - if (on(UNIX__NONULL, ctrl)) - return 0; /* will fail but don't let on yet */ - - /* UNIX passwords area */ - - /* Get password file entry... */ - pwd = pam_modutil_getpwnam (pamh, name); - - if (pwd != NULL) { - if (strcmp( pwd->pw_passwd, "*NP*" ) == 0) - { /* NIS+ */ - uid_t save_euid, save_uid; - - save_euid = geteuid(); - save_uid = getuid(); - if (save_uid == pwd->pw_uid) - setreuid( save_euid, save_uid ); - else { - setreuid( 0, -1 ); - if (setreuid( -1, pwd->pw_uid ) == -1) { - setreuid( -1, 0 ); - setreuid( 0, -1 ); - if(setreuid( -1, pwd->pw_uid ) == -1) - /* Will fail elsewhere. */ - return 0; - } - } - - spwdent = pam_modutil_getspnam (pamh, name); - if (save_uid == pwd->pw_uid) - setreuid( save_uid, save_euid ); - else { - if (setreuid( -1, 0 ) == -1) - setreuid( save_uid, -1 ); - setreuid( -1, save_euid ); - } - } else if (_unix_shadowed(pwd)) { - /* - * ...and shadow password file entry for this user, - * if shadowing is enabled - */ - spwdent = pam_modutil_getspnam(pamh, name); - } - if (spwdent) - salt = x_strdup(spwdent->sp_pwdp); - else - salt = x_strdup(pwd->pw_passwd); - } - /* Does this user have a password? */ - if (salt == NULL) { - retval = 0; - } else { - if (strlen(salt) == 0) - retval = 1; - else - retval = 0; - } - - /* tidy up */ - - if (salt) - _pam_delete(salt); - - return retval; -} - -/* * verify the password of a user */ @@ -518,7 +439,7 @@ static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd, } } - if (SELINUX_ENABLED && geteuid() == 0) { + if (geteuid() == 0) { /* must set the real uid to 0 so the helper will not error out if pam is called from setuid binary (su, sudo...) */ setuid(0); @@ -572,11 +493,65 @@ static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd, return retval; } +/* + * _unix_blankpasswd() is a quick check for a blank password + * + * returns TRUE if user does not have a password + * - to avoid prompting for one in such cases (CG) + */ + +int +_unix_blankpasswd (pam_handle_t *pamh, unsigned int ctrl, const char *name) +{ + struct passwd *pwd = NULL; + char *salt = NULL; + int retval; + + D(("called")); + + /* + * This function does not have to be too smart if something goes + * wrong, return FALSE and let this case to be treated somewhere + * else (CG) + */ + + if (on(UNIX__NONULL, ctrl)) + return 0; /* will fail but don't let on yet */ + + /* UNIX passwords area */ + + retval = get_pwd_hash(pamh, name, &pwd, &salt); + + if (retval == PAM_UNIX_RUN_HELPER) { + /* salt will not be set here so we can return immediately */ + if (_unix_run_helper_binary(pamh, NULL, ctrl, name) == PAM_SUCCESS) + return 1; + else + return 0; + } + + /* Does this user have a password? */ + if (salt == NULL) { + retval = 0; + } else { + if (strlen(salt) == 0) + retval = 1; + else + retval = 0; + } + + /* tidy up */ + + if (salt) + _pam_delete(salt); + + return retval; +} + int _unix_verify_password(pam_handle_t * pamh, const char *name ,const char *p, unsigned int ctrl) { struct passwd *pwd = NULL; - struct spwd *spwdent = NULL; char *salt = NULL; char *data_name; int retval; @@ -595,48 +570,7 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name D(("locating user's record")); - /* UNIX passwords area */ - pwd = pam_modutil_getpwnam (pamh, name); /* Get password file entry... */ - - if (pwd != NULL) { - if (strcmp( pwd->pw_passwd, "*NP*" ) == 0) - { /* NIS+ */ - uid_t save_euid, save_uid; - - save_euid = geteuid(); - save_uid = getuid(); - if (save_uid == pwd->pw_uid) - setreuid( save_euid, save_uid ); - else { - setreuid( 0, -1 ); - if (setreuid( -1, pwd->pw_uid ) == -1) { - setreuid( -1, 0 ); - setreuid( 0, -1 ); - if(setreuid( -1, pwd->pw_uid ) == -1) - return PAM_CRED_INSUFFICIENT; - } - } - - spwdent = pam_modutil_getspnam (pamh, name); - if (save_uid == pwd->pw_uid) - setreuid( save_uid, save_euid ); - else { - if (setreuid( -1, 0 ) == -1) - setreuid( save_uid, -1 ); - setreuid( -1, save_euid ); - } - } else if (_unix_shadowed(pwd)) { - /* - * ...and shadow password file entry for this user, - * if shadowing is enabled - */ - spwdent = pam_modutil_getspnam (pamh, name); - } - if (spwdent) - salt = x_strdup(spwdent->sp_pwdp); - else - salt = x_strdup(pwd->pw_passwd); - } + retval = get_pwd_hash(pamh, name, &pwd, &salt); data_name = (char *) malloc(sizeof(FAIL_PREFIX) + strlen(name)); if (data_name == NULL) { @@ -646,20 +580,13 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name strcpy(data_name + sizeof(FAIL_PREFIX) - 1, name); } - retval = PAM_SUCCESS; - if (pwd == NULL || salt == NULL || !strcmp(salt, "x") || ((salt[0] == '#') && (salt[1] == '#') && !strcmp(salt + 2, name))) { - - if (pwd != NULL && (geteuid() || SELINUX_ENABLED)) { - /* we are not root perhaps this is the reason? Run helper */ + if (retval != PAM_SUCCESS) { + if (retval == PAM_UNIX_RUN_HELPER) { D(("running helper binary")); retval = _unix_run_helper_binary(pamh, p, ctrl, name); } else { D(("user's record unavailable")); p = NULL; - if (pwd == NULL) - retval = PAM_USER_UNKNOWN; - else - retval = PAM_AUTHINFO_UNAVAIL; if (on(UNIX_AUDIT, ctrl)) { /* this might be a typo and the user has given a password instead of a username. Careful with this. */ @@ -931,6 +858,7 @@ int _unix_read_password(pam_handle_t * pamh * Copyright (c) Andrew G. Morgan 1996-8. * Copyright (c) Alex O. Yuriev, 1996. * Copyright (c) Cristian Gafton 1996. + * Copyright (c) Red Hat, Inc. 2007. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions |