From dba185605b1f9ce2d8d7e90b956abe9fa0487f24 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Wed, 26 Oct 2005 19:05:32 +0000 Subject: Relevant BUGIDs: Red Hat bz 168180 Purpose of commit: bugfix Commit summary: --------------- 2005-10-26 Tomas Mraz * modules/pam_unix/pam_unix_acct.c (_unix_run_verify_binary), modules/pam_unix/pam_unix_passwd.c (_unix_run_shadow_binary), modules/pam_unix/support.c (_unix_run_shadow_binary_): Set real uid to 0 before executing the helper if SELinux is enabled. * modules/pam_unix/unix_chkpwd.c (main): Disable user check only if real uid is 0 (CVE-2005-2977). Log failed password check attempt. --- ChangeLog | 10 ++++++++++ NEWS | 2 ++ modules/pam_unix/pam_unix_acct.c | 7 +++++++ modules/pam_unix/pam_unix_passwd.c | 7 +++++++ modules/pam_unix/support.c | 7 +++++++ modules/pam_unix/unix_chkpwd.c | 12 ++++++------ 6 files changed, 39 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 27289235..8941c316 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2005-10-26 Tomas Mraz + + * modules/pam_unix/pam_unix_acct.c (_unix_run_verify_binary), + modules/pam_unix/pam_unix_passwd.c (_unix_run_shadow_binary), + modules/pam_unix/support.c (_unix_run_shadow_binary_): Set real + uid to 0 before executing the helper if SELinux is enabled. + * modules/pam_unix/unix_chkpwd.c (main): Disable user check only + if real uid is 0 (CVE-2005-2977). Log failed password check attempt. + + 2005-10-20 Tomas Mraz * configure.in: Added check for xauth binary and --with-xauth option. diff --git a/NEWS b/NEWS index 2b829e3c..c31d57ee 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,8 @@ Linux-PAM NEWS -- history of user-visible changes. * pam_xauth: Look for xauth executable in multiple places +* pam_unix: Disable user check in unix_chkpwd only if real uid + is 0 (CVE-2005-2977). Log failed password check attempt. Release 0.99.1.0 diff --git a/modules/pam_unix/pam_unix_acct.c b/modules/pam_unix/pam_unix_acct.c index 324ab5ed..ec47d4b6 100644 --- a/modules/pam_unix/pam_unix_acct.c +++ b/modules/pam_unix/pam_unix_acct.c @@ -116,6 +116,13 @@ struct spwd *_unix_run_verify_binary(pam_handle_t *pamh, unsigned int ctrl, cons } } } + + if (SELINUX_ENABLED && geteuid() == 0) { + /* must set the real uid to 0 so the helper will not error + out if pam is called from setuid binary (su, sudo...) */ + setuid(0); + } + /* exec binary helper */ args[0] = x_strdup(CHKPWD_HELPER); args[1] = x_strdup(user); diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c index 50a81e38..727f3b3b 100644 --- a/modules/pam_unix/pam_unix_passwd.c +++ b/modules/pam_unix/pam_unix_passwd.c @@ -263,6 +263,13 @@ static int _unix_run_shadow_binary(pam_handle_t *pamh, unsigned int ctrl, const close(i); } } + + if (SELINUX_ENABLED && geteuid() == 0) { + /* must set the real uid to 0 so the helper will not error + out if pam is called from setuid binary (su, sudo...) */ + setuid(0); + } + /* exec binary helper */ args[0] = x_strdup(CHKPWD_HELPER); args[1] = x_strdup(user); diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index 3ed4b1f3..38a5d88b 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -521,6 +521,13 @@ static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd, close(i); } } + + if (SELINUX_ENABLED && geteuid() == 0) { + /* must set the real uid to 0 so the helper will not error + out if pam is called from setuid binary (su, sudo...) */ + setuid(0); + } + /* exec binary helper */ args[0] = x_strdup(CHKPWD_HELPER); args[1] = x_strdup(user); diff --git a/modules/pam_unix/unix_chkpwd.c b/modules/pam_unix/unix_chkpwd.c index cc42c4df..b817f658 100644 --- a/modules/pam_unix/unix_chkpwd.c +++ b/modules/pam_unix/unix_chkpwd.c @@ -457,13 +457,12 @@ int main(int argc, char *argv[]) } /* - * determine the current user's name is. - * On a SELinux enabled system, policy will prevent third parties from using - * unix_chkpwd as a password guesser. Leaving the existing check prevents - * su from working, Since the current uid is the users and the password is - * for root. + * Determine what the current user's name is. + * On a SELinux enabled system with a strict policy leaving the + * existing check prevents shadow password authentication from working. + * We must thus skip the check if the real uid is 0. */ - if (SELINUX_ENABLED) { + if (SELINUX_ENABLED && getuid() == 0) { user=argv[1]; } else { @@ -525,6 +524,7 @@ int main(int argc, char *argv[]) /* return pass or fail */ if ((retval != PAM_SUCCESS) || force_failure) { + _log_err(LOG_NOTICE, "password check failed for user (%s)", user); return PAM_AUTH_ERR; } else { return PAM_SUCCESS; -- cgit v1.2.3