From 7d1e156168d789c8eb8d7a84a6591c924c36eb68 Mon Sep 17 00:00:00 2001 From: ipedrosa Date: Wed, 17 Jun 2020 16:04:16 +0200 Subject: [PATCH] pam_unix and pam_usertype: avoid determining if user exists --- pam-1.3.1-determinine-user-exists.patch | 82 +++++++++++++++++++++++++ pam.spec | 8 ++- 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 pam-1.3.1-determinine-user-exists.patch diff --git a/pam-1.3.1-determinine-user-exists.patch b/pam-1.3.1-determinine-user-exists.patch new file mode 100644 index 0000000..cbf6f8c --- /dev/null +++ b/pam-1.3.1-determinine-user-exists.patch @@ -0,0 +1,82 @@ +diff -up Linux-PAM-1.3.1/modules/pam_unix/passverify.c.determinine-user-exists Linux-PAM-1.3.1/modules/pam_unix/passverify.c +--- Linux-PAM-1.3.1/modules/pam_unix/passverify.c.determinine-user-exists 2020-06-17 15:34:08.089162532 +0200 ++++ Linux-PAM-1.3.1/modules/pam_unix/passverify.c 2020-06-17 15:36:13.233294407 +0200 +@@ -1087,6 +1087,12 @@ helper_verify_password(const char *name, + if (pwd == NULL || salt == NULL) { + helper_log_err(LOG_NOTICE, "check pass; user unknown"); + retval = PAM_USER_UNKNOWN; ++ } else if (p[0] == '\0' && nullok) { ++ if (salt[0] == '\0') { ++ retval = PAM_SUCCESS; ++ } else { ++ retval = PAM_AUTH_ERR; ++ } + } else { + retval = verify_pwd_hash(p, salt, nullok); + } +diff -up Linux-PAM-1.3.1/modules/pam_unix/support.c.determinine-user-exists Linux-PAM-1.3.1/modules/pam_unix/support.c +--- Linux-PAM-1.3.1/modules/pam_unix/support.c.determinine-user-exists 2020-06-17 15:34:08.090162549 +0200 ++++ Linux-PAM-1.3.1/modules/pam_unix/support.c 2020-06-17 15:34:08.101162736 +0200 +@@ -672,6 +672,8 @@ _unix_blankpasswd (pam_handle_t *pamh, u + struct passwd *pwd = NULL; + char *salt = NULL; + int retval; ++ int execloop = 1; ++ int nonexistent = 1; + + D(("called")); + +@@ -686,14 +688,31 @@ _unix_blankpasswd (pam_handle_t *pamh, u + + /* UNIX passwords area */ + +- retval = get_pwd_hash(pamh, name, &pwd, &salt); ++ /* ++ * Execute this loop twice: one checking the password hash of an existing ++ * user and another one for a non-existing user. This way the runtimes ++ * are equal, making it more difficult to differentiate existing from ++ * non-existing users. ++ */ ++ while (execloop) { ++ retval = get_pwd_hash(pamh, name, &pwd, &salt); + +- if (retval == PAM_UNIX_RUN_HELPER) { +- /* salt will not be set here so we can return immediately */ +- if (_unix_run_helper_binary(pamh, NULL, ctrl, name) == PAM_SUCCESS) +- return 1; +- else +- return 0; ++ if (retval == PAM_UNIX_RUN_HELPER) { ++ execloop = 0; ++ if(nonexistent) { ++ get_pwd_hash(pamh, "pam_unix_non_existent:", &pwd, &salt); ++ } ++ /* salt will not be set here so we can return immediately */ ++ if (_unix_run_helper_binary(pamh, NULL, ctrl, name) == PAM_SUCCESS) ++ return 1; ++ else ++ return 0; ++ } else if (retval == PAM_USER_UNKNOWN) { ++ name = "root"; ++ nonexistent = 0; ++ } else { ++ execloop = 0; ++ } + } + + /* Does this user have a password? */ +diff -up Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.c.determinine-user-exists Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.c +--- Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.c.determinine-user-exists 2020-06-17 15:34:08.098162685 +0200 ++++ Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.c 2020-06-17 15:34:08.101162736 +0200 +@@ -236,8 +236,11 @@ pam_usertype_get_uid(struct pam_usertype + "error retrieving information about user %s", username); + } + ++ pam_modutil_getpwnam(pamh, "root"); ++ + return PAM_USER_UNKNOWN; + } ++ pam_modutil_getpwnam(pamh, "pam_usertype_non_existent:"); + + *_uid = pwd->pw_uid; + diff --git a/pam.spec b/pam.spec index cc89bb4..ab16bb7 100644 --- a/pam.spec +++ b/pam.spec @@ -3,7 +3,7 @@ Summary: An extensible library which provides authentication for applications Name: pam Version: 1.3.1 -Release: 26%{?dist} +Release: 27%{?dist} # The library is BSD licensed with option to relicense as GPLv2+ # - this option is redundant as the BSD license allows that anyway. # pam_timestamp, pam_loginuid, and pam_console modules are GPLv2+. @@ -67,6 +67,8 @@ Patch54: pam-1.3.1-pam_selinux-check-unknown-objects.patch Patch55: pam-1.3.1-audit-error.patch # Upstreamed Patch56: pam-1.3.1-pam-modutil-close-write.patch +# Upstreamed +Patch57: pam-1.3.1-determinine-user-exists.patch %global _pamlibdir %{_libdir} %global _moduledir %{_libdir}/security @@ -173,6 +175,7 @@ cp %{SOURCE18} . %patch54 -p1 -b .pam_selinux-check-unknown-objects %patch55 -p1 -b .audit-error %patch56 -p1 -b .pam-modutil-close-write +%patch57 -p1 -b .determinine-user-exists autoreconf -i @@ -425,6 +428,9 @@ done %doc doc/sag/*.txt doc/sag/html %changelog +* Wed Jun 17 2020 Iker Pedrosa - 1.3.1-27 +- pam_unix and pam_usertype: avoid determining if user exists (#1629598) + * Thu May 14 2020 Iker Pedrosa 1.3.1-26 - pam_tty_audit: if kernel audit is disabled return PAM_IGNORE (#1775357) - pam_modutil_sanitize_helper_fds: fix SIGPIPE effect of PAM_MODUTIL_PIPE_FD (#1791970)