From 2f89e9caa043fb96a66056e6f5387bcef7c030a3 Mon Sep 17 00:00:00 2001 From: Christian Göttsche Date: Wed, 17 Jan 2024 17:13:05 +0100 Subject: pam_pwhistory: allocate crypt data on the heap The struct crypt_data has the size of 32768 bytes, thus allocate it on the heap for portability. --- modules/pam_pwhistory/opasswd.c | 35 ++++++++++++++++++++++++++--------- 1 file 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); } -- cgit v1.2.3