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);
}
/*