File sudo-plugins-sudoers-pam.patch of Package sudo.openSUSE_13.1_Update

# HG changeset patch
# User Todd C. Miller <Todd.Miller@courtesan.com>
# Date 1373579403 14400
# Node ID b6022e26135aa92d36c016f193d1d69ca54bc2a8
# Parent  93dde7d82fde473caf1891cdb5af93988ea10dd3
Go back to ignoring the return value of pam_setcred() since with
stacked PAM auth modules a failure from one module may override
PAM_SUCCESS from another.  If the first module in the stack fails,
the others may be run (and succeed) but an error will be returned.
This can cause a spurious warning on systems with non-local users
(e.g. pam_ldap or pam_sss) where pam_unix is consulted first.

diff -r 93dde7d82fde -r b6022e26135a plugins/sudoers/auth/pam.c
--- a/plugins/sudoers/auth/pam.c	Thu Jul 11 17:47:39 2013 -0400
+++ b/plugins/sudoers/auth/pam.c	Thu Jul 11 17:50:03 2013 -0400
@@ -79,8 +79,6 @@
 static int converse(int, PAM_CONST struct pam_message **,
 		    struct pam_response **, void *);
 static char *def_prompt = "Password:";
-static bool sudo_pam_cred_established;
-static bool sudo_pam_authenticated;
 static int getpass_error;
 static pam_handle_t *pamh;
 
@@ -144,7 +142,6 @@
 	    *pam_status = pam_acct_mgmt(pamh, PAM_SILENT);
 	    switch (*pam_status) {
 		case PAM_SUCCESS:
-		    sudo_pam_authenticated = true;
 		    debug_return_int(AUTH_SUCCESS);
 		case PAM_AUTH_ERR:
 		    log_warning(NO_MAIL, N_("account validation failure, "
@@ -197,18 +194,18 @@
     debug_decl(sudo_pam_cleanup, SUDO_DEBUG_AUTH)
 
     /* If successful, we can't close the session until pam_end_session() */
-    if (*pam_status == AUTH_SUCCESS)
-	debug_return_int(AUTH_SUCCESS);
-
-    *pam_status = pam_end(pamh, *pam_status | PAM_DATA_SILENT);
-    pamh = NULL;
+    if (*pam_status != PAM_SUCCESS) {
+	*pam_status = pam_end(pamh, *pam_status | PAM_DATA_SILENT);
+	pamh = NULL;
+    }
     debug_return_int(*pam_status == PAM_SUCCESS ? AUTH_SUCCESS : AUTH_FAILURE);
 }
 
 int
 sudo_pam_begin_session(struct passwd *pw, char **user_envp[], sudo_auth *auth)
 {
-    int status = PAM_SUCCESS;
+    int status = AUTH_SUCCESS;
+    int *pam_status = (int *) auth->data;
     debug_decl(sudo_pam_begin_session, SUDO_DEBUG_AUTH)
 
     /*
@@ -232,21 +229,13 @@
 
     /*
      * Set credentials (may include resource limits, device ownership, etc).
-     * We don't check the return value here because in Linux-PAM 0.75
-     * it returns the last saved return code, not the return code
-     * for the setcred module.  Because we haven't called pam_authenticate(),
-     * this is not set and so pam_setcred() returns PAM_PERM_DENIED.
-     * We can't call pam_acct_mgmt() with Linux-PAM for a similar reason.
+     * We don't worry about a failure from pam_setcred() since with
+     * stacked PAM auth modules a failure from one module may override
+     * PAM_SUCCESS from another.  For example, given a non-local user,
+     * pam_unix will fail but pam_ldap or pam_sss may succeed, but if
+     * pam_unix is first in the stack, pam_setcred() will fail.
      */
-    status = pam_setcred(pamh, PAM_ESTABLISH_CRED);
-    if (status == PAM_SUCCESS) {
-	sudo_pam_cred_established = true;
-    } else if (sudo_pam_authenticated) {
-	const char *s = pam_strerror(pamh, status);
-	if (s != NULL)
-	    log_warning(NO_MAIL, N_("unable to establish credentials: %s"), s);
-	goto done;
-    }
+    (void) pam_setcred(pamh, PAM_ESTABLISH_CRED);
 
 #ifdef HAVE_PAM_GETENVLIST
     /*
@@ -269,21 +258,22 @@
 #endif /* HAVE_PAM_GETENVLIST */
 
     if (def_pam_session) {
-	status = pam_open_session(pamh, 0);
-	if (status != PAM_SUCCESS) {
-	    (void) pam_end(pamh, status | PAM_DATA_SILENT);
+	*pam_status = pam_open_session(pamh, 0);
+	if (*pam_status != PAM_SUCCESS) {
+	    (void) pam_end(pamh, *pam_status | PAM_DATA_SILENT);
 	    pamh = NULL;
+	    status = AUTH_FAILURE;
 	}
     }
 
 done:
-    debug_return_int(status == PAM_SUCCESS ? AUTH_SUCCESS : AUTH_FAILURE);
+    debug_return_int(status);
 }
 
 int
 sudo_pam_end_session(struct passwd *pw, sudo_auth *auth)
 {
-    int status = PAM_SUCCESS;
+    int status = AUTH_SUCCESS;
     debug_decl(sudo_pam_end_session, SUDO_DEBUG_AUTH)
 
     if (pamh != NULL) {
@@ -295,13 +285,13 @@
 	(void) pam_set_item(pamh, PAM_USER, pw->pw_name);
 	if (def_pam_session)
 	    (void) pam_close_session(pamh, PAM_SILENT);
-	if (sudo_pam_cred_established)
-	    (void) pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT);
-	status = pam_end(pamh, PAM_SUCCESS | PAM_DATA_SILENT);
+	(void) pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT);
+	if (pam_end(pamh, PAM_SUCCESS | PAM_DATA_SILENT) != PAM_SUCCESS)
+	    status = AUTH_FAILURE;
 	pamh = NULL;
     }
 
-    debug_return_int(status == PAM_SUCCESS ? AUTH_SUCCESS : AUTH_FAILURE);
+    debug_return_int(status);
 }
 
 /*

openSUSE Build Service is sponsored by