Blame SOURCES/pam-1.3.1-pam-userdb-prevent-garbage-characters-from-db.patch

9a6231
From a7453aeeb398d6cbb7a709c4e2a1d75905220fff Mon Sep 17 00:00:00 2001
9a6231
From: Stanislav Zidek <szidek@redhat.com>
9a6231
Date: Fri, 16 Apr 2021 19:14:18 +0200
9a6231
Subject: [PATCH] pam_userdb: Prevent garbage characters from db
9a6231
9a6231
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1791965
9a6231
---
9a6231
 modules/pam_userdb/pam_userdb.8.xml |  3 +-
9a6231
 modules/pam_userdb/pam_userdb.c     | 56 +++++++++++++++++------------
9a6231
 2 files changed, 36 insertions(+), 23 deletions(-)
9a6231
9a6231
diff --git a/modules/pam_userdb/pam_userdb.8.xml b/modules/pam_userdb/pam_userdb.8.xml
9a6231
index fa628ada..bce92850 100644
9a6231
--- a/modules/pam_userdb/pam_userdb.8.xml
9a6231
+++ b/modules/pam_userdb/pam_userdb.8.xml
9a6231
@@ -100,7 +100,8 @@
9a6231
         </term>
9a6231
         <listitem>
9a6231
           <para>
9a6231
-            Print debug information.
9a6231
+            Print debug information. Note that password hashes, both from db
9a6231
+            and computed, will be printed to syslog.
9a6231
           </para>
9a6231
         </listitem>
9a6231
       </varlistentry>
9a6231
diff --git a/modules/pam_userdb/pam_userdb.c b/modules/pam_userdb/pam_userdb.c
9a6231
index dc2ca232..d59801bf 100644
9a6231
--- a/modules/pam_userdb/pam_userdb.c
9a6231
+++ b/modules/pam_userdb/pam_userdb.c
9a6231
@@ -194,7 +194,7 @@ user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode,
9a6231
     }
9a6231
 
9a6231
     if (data.dptr != NULL) {
9a6231
-	int compare = 0;
9a6231
+	int compare = -2;
9a6231
 
9a6231
 	if (ctrl & PAM_KEY_ONLY_ARG)
9a6231
 	  {
9a6231
@@ -209,36 +209,48 @@ user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode,
9a6231
 	  char *cryptpw = NULL;
9a6231
 
9a6231
 	  if (data.dsize < 13) {
9a6231
-	    compare = -2;
9a6231
+	    /* hash is too short */
9a6231
+	    pam_syslog(pamh, LOG_INFO, "password hash in database is too short");
9a6231
 	  } else if (ctrl & PAM_ICASE_ARG) {
9a6231
-	    compare = -2;
9a6231
+	    pam_syslog(pamh, LOG_INFO,
9a6231
+	       "case-insensitive comparison only works with plaintext passwords");
9a6231
 	  } else {
9a6231
+	    /* libdb is not guaranteed to produce null terminated strings */
9a6231
+	    char *pwhash = strndup(data.dptr, data.dsize);
9a6231
+
9a6231
+	    if (pwhash == NULL) {
9a6231
+	      pam_syslog(pamh, LOG_CRIT, "strndup failed: data.dptr");
9a6231
+	    } else {
9a6231
 #ifdef HAVE_CRYPT_R
9a6231
-	    struct crypt_data *cdata = NULL;
9a6231
-	    cdata = malloc(sizeof(*cdata));
9a6231
-	    if (cdata != NULL) {
9a6231
-		cdata->initialized = 0;
9a6231
-		cryptpw = crypt_r(pass, data.dptr, cdata);
9a6231
-	    }
9a6231
+	      struct crypt_data *cdata = NULL;
9a6231
+	      cdata = malloc(sizeof(*cdata));
9a6231
+	      if (cdata == NULL) {
9a6231
+	        pam_syslog(pamh, LOG_CRIT, "malloc failed: struct crypt_data");
9a6231
+	      } else {
9a6231
+	        cdata->initialized = 0;
9a6231
+	        cryptpw = crypt_r(pass, pwhash, cdata);
9a6231
+	      }
9a6231
 #else
9a6231
-	    cryptpw = crypt (pass, data.dptr);
9a6231
+	      cryptpw = crypt (pass, pwhash);
9a6231
 #endif
9a6231
-	    if (cryptpw && strlen(cryptpw) == (size_t)data.dsize) {
9a6231
-	      compare = memcmp(data.dptr, cryptpw, data.dsize);
9a6231
-	    } else {
9a6231
-	      compare = -2;
9a6231
-	      if (ctrl & PAM_DEBUG_ARG) {
9a6231
-		if (cryptpw)
9a6231
-		  pam_syslog(pamh, LOG_INFO, "lengths of computed and stored hashes differ");
9a6231
-		else
9a6231
-		  pam_syslog(pamh, LOG_INFO, "crypt() returned NULL");
9a6231
+	      if (cryptpw && strlen(cryptpw) == (size_t)data.dsize) {
9a6231
+	        compare = memcmp(data.dptr, cryptpw, data.dsize);
9a6231
+	      } else {
9a6231
+	        if (ctrl & PAM_DEBUG_ARG) {
9a6231
+	          if (cryptpw) {
9a6231
+	            pam_syslog(pamh, LOG_INFO, "lengths of computed and stored hashes differ");
9a6231
+	            pam_syslog(pamh, LOG_INFO, "computed hash: %s", cryptpw);
9a6231
+	          } else {
9a6231
+	            pam_syslog(pamh, LOG_ERR, "crypt() returned NULL");
9a6231
+	          }
9a6231
+	        }
9a6231
 	      }
9a6231
-	    }
9a6231
 #ifdef HAVE_CRYPT_R
9a6231
-	    free(cdata);
9a6231
+	      free(cdata);
9a6231
 #endif
9a6231
+	    }
9a6231
+	    free(pwhash);
9a6231
 	  }
9a6231
-
9a6231
 	} else {
9a6231
 
9a6231
 	  /* Unknown password encryption method -
9a6231
-- 
9a6231
2.30.2
9a6231