|
| 1 | +From b3020da7da384d769f27a8713257fbe1001878be Mon Sep 17 00:00:00 2001 |
| 2 | +From: "Dmitry V. Levin" <ldv@strace.io> |
| 3 | +Date: Mon, 1 Jan 2024 12:00:00 +0000 |
| 4 | +Subject: [PATCH] pam_unix/passverify: always run the helper to obtain shadow |
| 5 | + password file entries |
| 6 | + |
| 7 | +Initially, when pam_unix.so verified the password, it used to try to |
| 8 | +obtain the shadow password file entry for the given user by invoking |
| 9 | +getspnam(3), and only when that didn't work and the effective uid |
| 10 | +was nonzero, pam_unix.so used to invoke the helper as a fallback. |
| 11 | + |
| 12 | +When SELinux support was introduced by commit |
| 13 | +67aab1ff5515054341a438cf9804e9c9b3a88033, the fallback was extended |
| 14 | +also for the case when SELinux was enabled. |
| 15 | + |
| 16 | +Later, commit f220cace205332a3dc34e7b37a85e7627e097e7d extended the |
| 17 | +fallback conditions for the case when pam_modutil_getspnam() failed |
| 18 | +with EACCES. |
| 19 | + |
| 20 | +Since commit 470823c4aacef5cb3b1180be6ed70846b61a3752, the helper is |
| 21 | +invoked as a fallback when pam_modutil_getspnam() fails for any reason. |
| 22 | + |
| 23 | +The ultimate solution for the case when pam_unix.so does not have |
| 24 | +permissions to obtain the shadow password file entry is to stop trying |
| 25 | +to use pam_modutil_getspnam() and to invoke the helper instead. |
| 26 | +Here are two recent examples. |
| 27 | + |
| 28 | +https://github.com/linux-pam/linux-pam/pull/484 describes a system |
| 29 | +configuration where libnss_systemd is enabled along with libnss_files |
| 30 | +in the shadow entry of nsswitch.conf, so when libnss_files is unable |
| 31 | +to obtain the shadow password file entry for the root user, e.g. when |
| 32 | +SELinux is enabled, NSS falls back to libnss_systemd which returns |
| 33 | +a synthesized shadow password file entry for the root user, which |
| 34 | +in turn locks the root user out. |
| 35 | + |
| 36 | +https://bugzilla.redhat.com/show_bug.cgi?id=2150155 describes |
| 37 | +essentially the same problem in a similar system configuration. |
| 38 | + |
| 39 | +This commit is the final step in the direction of addressing the issue: |
| 40 | +for password verification pam_unix.so now invokes the helper instead of |
| 41 | +making the pam_modutil_getspnam() call. |
| 42 | + |
| 43 | +* modules/pam_unix/passverify.c (get_account_info) [!HELPER_COMPILE]: |
| 44 | +Always return PAM_UNIX_RUN_HELPER instead of trying to obtain |
| 45 | +the shadow password file entry. |
| 46 | + |
| 47 | +Complements: https://github.com/linux-pam/linux-pam/pull/386 |
| 48 | +Resolves: https://github.com/linux-pam/linux-pam/pull/484 |
| 49 | +Link: https://github.com/authselect/authselect/commit/1e78f7e048747024a846fd22d68afc6993734e92 |
| 50 | +--- |
| 51 | +diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c |
| 52 | +index f6132f8..7ab674b 100644 |
| 53 | +--- a/modules/pam_unix/passverify.c |
| 54 | ++++ b/modules/pam_unix/passverify.c |
| 55 | +@@ -239,17 +239,21 @@ PAMH_ARG_DECL(int get_account_info, |
| 56 | + return PAM_UNIX_RUN_HELPER; |
| 57 | + #endif |
| 58 | + } else if (is_pwd_shadowed(*pwd)) { |
| 59 | ++#ifdef HELPER_COMPILE |
| 60 | + /* |
| 61 | +- * ...and shadow password file entry for this user, |
| 62 | ++ * shadow password file entry for this user, |
| 63 | + * if shadowing is enabled |
| 64 | + */ |
| 65 | +-#ifndef HELPER_COMPILE |
| 66 | +- if (geteuid() || SELINUX_ENABLED) |
| 67 | +- return PAM_UNIX_RUN_HELPER; |
| 68 | +-#endif |
| 69 | +- *spwdent = pam_modutil_getspnam(pamh, name); |
| 70 | ++ *spwdent = getspnam(name); |
| 71 | + if (*spwdent == NULL || (*spwdent)->sp_pwdp == NULL) |
| 72 | + return PAM_AUTHINFO_UNAVAIL; |
| 73 | ++#else |
| 74 | ++ /* |
| 75 | ++ * The helper has to be invoked to deal with |
| 76 | ++ * the shadow password file entry. |
| 77 | ++ */ |
| 78 | ++ return PAM_UNIX_RUN_HELPER; |
| 79 | ++#endif |
| 80 | + } |
| 81 | + } else { |
| 82 | + return PAM_USER_UNKNOWN; |
0 commit comments