aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modules/pam_pwhistory/opasswd.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/modules/pam_pwhistory/opasswd.c b/modules/pam_pwhistory/opasswd.c
index a4bcbaae..289b4461 100644
--- a/modules/pam_pwhistory/opasswd.c
+++ b/modules/pam_pwhistory/opasswd.c
@@ -121,21 +121,32 @@ parse_entry (char *line, opwd *data)
return 0;
}
+/* Return 1 if the passwords are equal, 0 if they are not, and -1 on error. */
static int
compare_password(const char *newpass, const char *oldpass)
{
char *outval;
int retval;
#ifdef HAVE_CRYPT_R
- struct crypt_data output = { 0 };
+ struct crypt_data *cdata;
- outval = crypt_r (newpass, oldpass, &output);
+ cdata = calloc(1, sizeof(*cdata));
+ if (!cdata)
+ return -1;
+
+ outval = crypt_r (newpass, oldpass, cdata);
#else
outval = crypt (newpass, oldpass);
#endif
retval = outval != NULL && strcmp(outval, oldpass) == 0;
+
+#ifdef HAVE_CRYPT_R
+ pam_overwrite_object(cdata);
+ free(cdata);
+#else
pam_overwrite_string(outval);
+#endif
return retval;
}
@@ -200,13 +211,19 @@ check_old_pass, const char *user, const char *newpass, const char *filename, int
do {
oldpass = strsep (&running, delimiters);
- if (oldpass && strlen (oldpass) > 0 &&
- compare_password(newpass, oldpass) )
- {
- if (debug)
- pam_syslog (pamh, LOG_DEBUG, "New password already used");
- retval = PAM_AUTHTOK_ERR;
- break;
+ if (oldpass && strlen (oldpass) > 0) {
+ int rc;
+
+ rc = compare_password(newpass, oldpass);
+ if (rc) {
+ if (rc < 0)
+ pam_syslog (pamh, LOG_ERR, "Cannot allocate crypt data");
+ else if (debug)
+ pam_syslog (pamh, LOG_DEBUG, "New password already used");
+
+ retval = PAM_AUTHTOK_ERR;
+ break;
+ }
}
} while (oldpass != NULL);
}