--- Linux-PAM-0.99.7.1/modules/pam_unix/support.c.bigcrypt 2007-02-21 20:30:24.000000000 +0100 +++ Linux-PAM-0.99.7.1/modules/pam_unix/support.c 2007-02-21 21:17:29.000000000 +0100 @@ -694,7 +694,7 @@ } } } else { - int salt_len; + size_t salt_len; strip_hpux_aging(salt); salt_len = strlen(salt); if (!salt_len) { @@ -706,19 +706,19 @@ D(("user has empty password - access denied")); retval = PAM_AUTH_ERR; } - } else if (!p || (*salt == '*')) { + } else if (!p || *salt == '*' || *salt == '!') { retval = PAM_AUTH_ERR; } else { if (!strncmp(salt, "$1$", 3)) { pp = Goodcrypt_md5(p, salt); - if (strcmp(pp, salt) != 0) { + if (pp && strcmp(pp, salt) != 0) { _pam_delete(pp); pp = Brokencrypt_md5(p, salt); } } else if (*salt != '$' && salt_len >= 13) { pp = bigcrypt(p, salt); - if (strlen(pp) > salt_len) { - pp[salt_len] = '\0'; + if (pp && salt_len == 13 && strlen(pp) > salt_len) { + _pam_overwrite(pp + salt_len); } } else { /* @@ -732,7 +732,7 @@ /* the moment of truth -- do we agree with the password? */ D(("comparing state of pp[%s] and salt[%s]", pp, salt)); - if (strcmp(pp, salt) == 0) { + if (pp && strcmp(pp, salt) == 0) { retval = PAM_SUCCESS; } else { retval = PAM_AUTH_ERR; --- Linux-PAM-0.99.7.1/modules/pam_unix/unix_chkpwd.c.bigcrypt 2007-02-21 20:30:24.000000000 +0100 +++ Linux-PAM-0.99.7.1/modules/pam_unix/unix_chkpwd.c 2007-02-21 21:18:57.000000000 +0100 @@ -159,7 +159,7 @@ char *salt = NULL; char *pp = NULL; int retval = PAM_AUTH_ERR; - int salt_len; + size_t salt_len; /* UNIX passwords area */ setpwent(); @@ -205,6 +205,8 @@ return (nullok == 0) ? PAM_AUTH_ERR : PAM_SUCCESS; } if (p == NULL || strlen(p) == 0) { + _pam_overwrite(salt); + _pam_drop(salt); return PAM_AUTHTOK_ERR; } @@ -212,11 +214,13 @@ retval = PAM_AUTH_ERR; if (!strncmp(salt, "$1$", 3)) { pp = Goodcrypt_md5(p, salt); - if (strcmp(pp, salt) == 0) { + if (pp && strcmp(pp, salt) == 0) { retval = PAM_SUCCESS; } else { + _pam_overwrite(pp); + _pam_drop(pp); pp = Brokencrypt_md5(p, salt); - if (strcmp(pp, salt) == 0) + if (pp && strcmp(pp, salt) == 0) retval = PAM_SUCCESS; } } else if (*salt == '$') { @@ -225,10 +229,10 @@ * libcrypt nows about it? We should try it. */ pp = x_strdup (crypt(p, salt)); - if (strcmp(pp, salt) == 0) { + if (pp && strcmp(pp, salt) == 0) { retval = PAM_SUCCESS; } - } else if ((*salt == '*') || (salt_len < 13)) { + } else if (*salt == '*' || *salt == '!' || salt_len < 13) { retval = PAM_AUTH_ERR; } else { pp = bigcrypt(p, salt); @@ -239,24 +243,21 @@ * have been truncated for storage relative to the output * of bigcrypt here. As such we need to compare only the * stored string with the subset of bigcrypt's result. - * Bug 521314: the strncmp comparison is for legacy support. + * Bug 521314. */ - if (strncmp(pp, salt, salt_len) == 0) { + if (pp && salt_len == 13 && strlen(pp) > salt_len) { + _pam_overwrite(pp+salt_len); + } + + if (pp && strcmp(pp, salt) == 0) { retval = PAM_SUCCESS; } } p = NULL; /* no longer needed here */ /* clean up */ - { - char *tp = pp; - if (pp != NULL) { - while (tp && *tp) - *tp++ = '\0'; - free(pp); - } - pp = tp = NULL; - } + _pam_overwrite(pp); + _pam_drop(pp); return retval; }