aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorChristian Göttsche <cgzones@googlemail.com>2024-01-17 17:13:05 +0100
committerDmitry V. Levin <ldv@strace.io>2024-01-21 08:00:00 +0000
commit2f89e9caa043fb96a66056e6f5387bcef7c030a3 (patch)
tree19dcfbdbe2098e7756ab13cb061f8f304a047414 /modules
parent42a8f233f5e8694995e19aead3f0d589fd75aaa8 (diff)
downloadpam-2f89e9caa043fb96a66056e6f5387bcef7c030a3.tar.gz
pam-2f89e9caa043fb96a66056e6f5387bcef7c030a3.tar.bz2
pam-2f89e9caa043fb96a66056e6f5387bcef7c030a3.zip
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.
Diffstat (limited to 'modules')
-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);
}