From c25a858bb548b4eb881dabbf10aed4a08b11e973 Mon Sep 17 00:00:00 2001
From: Tobias Stoeckmann <tobias@stoeckmann.org>
Date: Mon, 15 Jan 2024 21:36:38 +0100
Subject: pam_unix: do not allow comma as a field separator

The opasswd file shall not use comma as a separator. Enforce colon just
like pam_pwhistory does as well.

A comma can be part of a user name, although its usage is discouraged.
If such a user exists, it could happen that stored passwords of another
user are checked.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
---
 modules/pam_unix/pam_unix_passwd.c | 13 ++++++-------
 modules/pam_unix/passverify.c      |  4 ++--
 2 files changed, 8 insertions(+), 9 deletions(-)

(limited to 'modules/pam_unix')

diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c
index 444d61ca..897de6ce 100644
--- a/modules/pam_unix/pam_unix_passwd.c
+++ b/modules/pam_unix/pam_unix_passwd.c
@@ -351,14 +351,13 @@ static int check_old_password(const char *forwho, const char *newpass)
 		return PAM_ABORT;
 
 	for (; getline(&buf, &n, opwfile) != -1; pam_overwrite_n(buf, n)) {
-		if (!strncmp(buf, forwho, len) && (buf[len] == ':' ||
-			buf[len] == ',')) {
+		if (!strncmp(buf, forwho, len) && buf[len] == ':') {
 			char *sptr;
 			buf[strlen(buf) - 1] = '\0';
-			/* s_luser = */ strtok_r(buf, ":,", &sptr);
-			/* s_uid = */ strtok_r(NULL, ":,", &sptr);
-			/* s_npas = */ strtok_r(NULL, ":,", &sptr);
-			s_pas = strtok_r(NULL, ":,", &sptr);
+			/* 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 (md5pass == NULL || !strcmp(md5pass, s_pas)) {
@@ -366,7 +365,7 @@ static int check_old_password(const char *forwho, const char *newpass)
 					retval = PAM_AUTHTOK_ERR;
 					break;
 				}
-				s_pas = strtok_r(NULL, ":,", &sptr);
+				s_pas = strtok_r(NULL, ",", &sptr);
 				_pam_delete(md5pass);
 			}
 			break;
diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c
index 426d4028..5c4f862e 100644
--- a/modules/pam_unix/passverify.c
+++ b/modules/pam_unix/passverify.c
@@ -730,7 +730,7 @@ save_old_password(pam_handle_t *pamh, const char *forwho, const char *oldpass,
     }
 
     for (; getline(&buf, &bufsize, opwfile) != -1; pam_overwrite_n(buf, bufsize)) {
-	if (!strncmp(buf, forwho, len) && strchr(":,\n", buf[len]) != NULL) {
+	if (!strncmp(buf, forwho, len) && strchr(":\n", buf[len]) != NULL) {
 	    char *ep, *sptr = NULL;
 	    long value;
 	    found = 1;
@@ -752,7 +752,7 @@ save_old_password(pam_handle_t *pamh, const char *forwho, const char *oldpass,
 		found = 0;
 		continue;
 	    }
-	    s_pas = strtok_r(NULL, ":", &sptr);
+	    s_pas = strtok_r(NULL, "", &sptr);
 	    value = strtol(s_npas, &ep, 10);
 	    if (value < 0 || value >= INT_MAX || s_npas == ep || *ep != '\0')
 		npas = 0;
-- 
cgit v1.2.3