summaryrefslogtreecommitdiff
path: root/modules/pam_unix
diff options
context:
space:
mode:
authorAndrew G. Morgan <morgan@kernel.org>2021-06-26 14:18:08 -0700
committerTomáš Mráz <tm@t8m.info>2021-06-29 12:22:12 +0200
commitf220cace205332a3dc34e7b37a85e7627e097e7d (patch)
tree08069693a1031424b7c9dc54ce20d8e09c1ed292 /modules/pam_unix
parentfe1307512fb8892b5ceb3d884c793af8dbd4c16a (diff)
Permit unix_chkpwd & pam_unix.so to run without being setuid-root.
Remove the hard-coding of the idea that the only way pam_unix.so can read the shadow file is if it can, in some way, run setuid-root. Linux capabilities only require cap_dac_override to read the /etc/shadow file. This change achieves two things: it opens a path for a linux-pam application to run without being setuid-root; further, it allows unix_chkpwd to run non-setuid-root if it is installed: sudo setcap cap_dac_override=ep unix_chkpwd If we wanted to link against libcap, we could install this binary with cap_dac_override=p, and use cap_set_proc() to raise the effective bit at runtime. However, some distributions already link unix_chkpwd against libcap-ng for some, likely spurious, reason so "ep" is fine for now. Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
Diffstat (limited to 'modules/pam_unix')
-rw-r--r--modules/pam_unix/passverify.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c
index e833402c..5460b057 100644
--- a/modules/pam_unix/passverify.c
+++ b/modules/pam_unix/passverify.c
@@ -241,12 +241,16 @@ PAMH_ARG_DECL(int get_account_info,
* ...and shadow password file entry for this user,
* if shadowing is enabled
*/
+ *spwdent = pam_modutil_getspnam(pamh, name);
+ if (*spwdent == NULL) {
#ifndef HELPER_COMPILE
- if (geteuid() || SELINUX_ENABLED)
- return PAM_UNIX_RUN_HELPER;
+ /* still a chance the user can authenticate */
+ if (errno == EACCES || SELINUX_ENABLED)
+ return PAM_UNIX_RUN_HELPER;
#endif
- *spwdent = pam_modutil_getspnam(pamh, name);
- if (*spwdent == NULL || (*spwdent)->sp_pwdp == NULL)
+ return PAM_AUTHINFO_UNAVAIL;
+ }
+ if ((*spwdent)->sp_pwdp == NULL)
return PAM_AUTHINFO_UNAVAIL;
}
} else {