diff options
Diffstat (limited to 'Linux-PAM/modules/pam_unix')
-rw-r--r-- | Linux-PAM/modules/pam_unix/pam_unix_passwd.c | 27 | ||||
-rw-r--r-- | Linux-PAM/modules/pam_unix/support.c | 12 | ||||
-rw-r--r-- | Linux-PAM/modules/pam_unix/unix_chkpwd.c | 33 |
3 files changed, 34 insertions, 38 deletions
diff --git a/Linux-PAM/modules/pam_unix/pam_unix_passwd.c b/Linux-PAM/modules/pam_unix/pam_unix_passwd.c index 8921d1cc..c8ee5492 100644 --- a/Linux-PAM/modules/pam_unix/pam_unix_passwd.c +++ b/Linux-PAM/modules/pam_unix/pam_unix_passwd.c @@ -330,11 +330,12 @@ static int check_old_password(const char *forwho, const char *newpass) while (fgets(buf, 16380, opwfile)) { if (!strncmp(buf, forwho, strlen(forwho))) { + char *sptr; buf[strlen(buf) - 1] = '\0'; - s_luser = strtok(buf, ":,"); - s_uid = strtok(NULL, ":,"); - s_npas = strtok(NULL, ":,"); - s_pas = strtok(NULL, ":,"); + s_luser = strtok_r(buf, ":,", &sptr); + s_uid = strtok_r(NULL, ":,", &sptr); + s_npas = strtok_r(NULL, ":,", &sptr); + s_pas = strtok_r(NULL, ":,", &sptr); while (s_pas != NULL) { char *md5pass = Goodcrypt_md5(newpass, s_pas); if (!strcmp(md5pass, s_pas)) { @@ -342,7 +343,7 @@ static int check_old_password(const char *forwho, const char *newpass) retval = PAM_AUTHTOK_ERR; break; } - s_pas = strtok(NULL, ":,"); + s_pas = strtok_r(NULL, ":,", &sptr); _pam_delete(md5pass); } break; @@ -432,11 +433,12 @@ static int save_old_password(pam_handle_t *pamh, while (fgets(buf, 16380, opwfile)) { if (!strncmp(buf, forwho, strlen(forwho))) { + char *sptr; buf[strlen(buf) - 1] = '\0'; - s_luser = strtok(buf, ":"); - s_uid = strtok(NULL, ":"); - s_npas = strtok(NULL, ":"); - s_pas = strtok(NULL, ":"); + s_luser = strtok_r(buf, ":", &sptr); + s_uid = strtok_r(NULL, ":", &sptr); + s_npas = strtok_r(NULL, ":", &sptr); + s_pas = strtok_r(NULL, ":", &sptr); npas = strtol(s_npas, NULL, 10) + 1; while (npas > howmany) { s_pas = strpbrk(s_pas, ","); @@ -1077,13 +1079,6 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags, user); return PAM_USER_UNKNOWN; } - if (!_unix_shadowed(pwd) && - (strchr(pwd->pw_passwd, '*') != NULL)) { - pam_syslog(pamh, LOG_DEBUG, - "user \"%s\" does not have modifiable password", - user); - return PAM_USER_UNKNOWN; - } } /* diff --git a/Linux-PAM/modules/pam_unix/support.c b/Linux-PAM/modules/pam_unix/support.c index 954f2c73..fc95f2c0 100644 --- a/Linux-PAM/modules/pam_unix/support.c +++ b/Linux-PAM/modules/pam_unix/support.c @@ -679,7 +679,7 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name } } } else { - int salt_len = strlen(salt); + size_t salt_len = strlen(salt); if (!salt_len) { /* the stored password is NULL */ if (off(UNIX__NONULL, ctrl)) {/* this means we've succeeded */ @@ -689,19 +689,19 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name 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 { /* @@ -715,7 +715,7 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name /* 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; diff --git a/Linux-PAM/modules/pam_unix/unix_chkpwd.c b/Linux-PAM/modules/pam_unix/unix_chkpwd.c index 87d29256..236ad5c2 100644 --- a/Linux-PAM/modules/pam_unix/unix_chkpwd.c +++ b/Linux-PAM/modules/pam_unix/unix_chkpwd.c @@ -144,7 +144,7 @@ static int _unix_verify_password(const char *name, const char *p, int nullok) char *salt = NULL; char *pp = NULL; int retval = PAM_AUTH_ERR; - int salt_len; + size_t salt_len; /* UNIX passwords area */ setpwent(); @@ -189,6 +189,8 @@ static int _unix_verify_password(const char *name, const char *p, int nullok) return (nullok == 0) ? PAM_AUTH_ERR : PAM_SUCCESS; } if (p == NULL || strlen(p) == 0) { + _pam_overwrite(salt); + _pam_drop(salt); return PAM_AUTHTOK_ERR; } @@ -196,11 +198,13 @@ static int _unix_verify_password(const char *name, const char *p, int nullok) 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 == '$') { @@ -209,10 +213,10 @@ static int _unix_verify_password(const char *name, const char *p, int nullok) * 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); @@ -223,24 +227,21 @@ static int _unix_verify_password(const char *name, const char *p, int nullok) * 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; } |