diff options
Diffstat (limited to 'modules/pam_unix/support.c')
-rw-r--r-- | modules/pam_unix/support.c | 52 |
1 files changed, 29 insertions, 23 deletions
diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index 41db1f04..043273d2 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -19,7 +19,7 @@ #include <ctype.h> #include <syslog.h> #include <sys/resource.h> -#ifdef HAVE_RPCSVC_YPCLNT_H +#ifdef HAVE_NIS #include <rpcsvc/ypclnt.h> #endif @@ -601,6 +601,9 @@ _unix_blankpasswd (pam_handle_t *pamh, unsigned long long ctrl, const char *name char *salt = NULL; int daysleft; int retval; + int blank = 0; + int execloop; + int nonexistent_check = 1; D(("called")); @@ -624,32 +627,35 @@ _unix_blankpasswd (pam_handle_t *pamh, unsigned long long ctrl, const char *name /* 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; - } + /* + * Execute this loop twice: one checking the password hash of an existing + * user and another one for a non-existing user. This way the runtimes + * are equal, making it more difficult to differentiate existing from + * non-existing users. + */ + for (execloop = 0; execloop < 2; ++execloop) { + retval = get_pwd_hash(pamh, name, &pwd, &salt); - /* Does this user have a password? */ - if (salt == NULL) { - retval = 0; - } else { - if (strlen(salt) == 0) - retval = 1; - else - retval = 0; + if (retval == PAM_UNIX_RUN_HELPER) { + if (_unix_run_helper_binary(pamh, NULL, ctrl, name) == PAM_SUCCESS) + blank = nonexistent_check; + } else if (retval == PAM_USER_UNKNOWN) { + name = "root"; + nonexistent_check = 0; + continue; + } else if (salt != NULL) { + if (strlen(salt) == 0) + blank = nonexistent_check; + } + name = "pam_unix_non_existent:"; + /* non-existent user check will not affect the blank value */ } /* tidy up */ - if (salt) _pam_delete(salt); - return retval; + return blank; } int _unix_verify_password(pam_handle_t * pamh, const char *name @@ -658,7 +664,7 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name struct passwd *pwd = NULL; char *salt = NULL; char *data_name; - char pw[MAXPASS + 1]; + char pw[PAM_MAX_RESP_SIZE + 1]; int retval; @@ -685,7 +691,7 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name strcpy(data_name + sizeof(FAIL_PREFIX) - 1, name); } - if (p != NULL && strlen(p) > MAXPASS) { + if (p != NULL && strlen(p) > PAM_MAX_RESP_SIZE) { memset(pw, 0, sizeof(pw)); p = strncpy(pw, p, sizeof(pw) - 1); } @@ -799,7 +805,7 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name } cleanup: - memset(pw, 0, sizeof(pw)); /* clear memory of the password */ + pam_overwrite_array(pw); /* clear memory of the password */ if (data_name) _pam_delete(data_name); if (salt) |