]> granicus.if.org Git - sudo/commitdiff
The fix for bug #843 was incomplete and caused pam_end() to be called early.
authorTodd C. Miller <Todd.Miller@sudo.ws>
Fri, 7 Dec 2018 16:51:34 +0000 (09:51 -0700)
committerTodd C. Miller <Todd.Miller@sudo.ws>
Fri, 7 Dec 2018 16:51:34 +0000 (09:51 -0700)
sudo_pam_approval() must not set the global pam status to an error
value if it returns AUTH_SUCCESS.  Otherwise, sudo_pam_cleanup()
will call pam_end() before sudo_pam_begin_session().  This resulted
in a NULL PAM handle being used in sudo_pam_begin_session().

plugins/sudoers/auth/pam.c

index f7c6b33c2f6434be28106914afd5ace46901af8e..b7d916cd8607717faec580ed61d69db6115dba73 100644 (file)
@@ -210,59 +210,68 @@ int
 sudo_pam_approval(struct passwd *pw, sudo_auth *auth, bool exempt)
 {
     const char *s;
+    int rc, status = AUTH_SUCCESS;
     int *pam_status = (int *) auth->data;
     debug_decl(sudo_pam_approval, SUDOERS_DEBUG_AUTH)
 
-    *pam_status = pam_acct_mgmt(pamh, PAM_SILENT);
-    switch (*pam_status) {
+    rc = pam_acct_mgmt(pamh, PAM_SILENT);
+    switch (rc) {
        case PAM_SUCCESS:
-           debug_return_int(AUTH_SUCCESS);
+           break;
        case PAM_AUTH_ERR:
            log_warningx(0, N_("account validation failure, "
                "is your account locked?"));
-           debug_return_int(AUTH_FATAL);
+           status = AUTH_FATAL;
+           break;
        case PAM_NEW_AUTHTOK_REQD:
            /* Ignore if user is exempt from password restrictions. */
            if (exempt)
-               debug_return_int(AUTH_SUCCESS);
+               break;
            /* New password required, try to change it. */
            log_warningx(0, N_("Account or password is "
                "expired, reset your password and try again"));
-           *pam_status = pam_chauthtok(pamh,
-               PAM_CHANGE_EXPIRED_AUTHTOK);
-           if (*pam_status == PAM_SUCCESS)
-               debug_return_int(AUTH_SUCCESS);
-           if ((s = pam_strerror(pamh, *pam_status)) == NULL)
+           rc = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
+           if (rc == PAM_SUCCESS)
+               break;
+           if ((s = pam_strerror(pamh, rc)) == NULL)
                s = "unknown error";
            log_warningx(0,
                N_("unable to change expired password: %s"), s);
-           debug_return_int(AUTH_FAILURE);
+           status = AUTH_FAILURE;
+           break;
        case PAM_AUTHTOK_EXPIRED:
            /* Ignore if user is exempt from password restrictions. */
            if (exempt)
-               debug_return_int(AUTH_SUCCESS);
+               break;
            /* Password expired, cannot be updated by user. */
            log_warningx(0,
                N_("Password expired, contact your system administrator"));
-           debug_return_int(AUTH_FATAL);
+           status = AUTH_FATAL;
+           break;
        case PAM_ACCT_EXPIRED:
            log_warningx(0,
                N_("Account expired or PAM config lacks an \"account\" "
                "section for sudo, contact your system administrator"));
-           debug_return_int(AUTH_FATAL);
+           status = AUTH_FATAL;
+           break;
        case PAM_AUTHINFO_UNAVAIL:
        case PAM_MAXTRIES:
        case PAM_PERM_DENIED:
-           s = pam_strerror(pamh, *pam_status);
+           s = pam_strerror(pamh, rc);
            log_warningx(0, N_("PAM account management error: %s"),
                s ? s : "unknown error");
-           debug_return_int(AUTH_FAILURE);
+           status = AUTH_FAILURE;
+           break;
        default:
-           s = pam_strerror(pamh, *pam_status);
+           s = pam_strerror(pamh, rc);
            log_warningx(0, N_("PAM account management error: %s"),
                s ? s : "unknown error");
-           debug_return_int(AUTH_FATAL);
+           status = AUTH_FATAL;
+           break;
     }
+    /* Ignore errors if user is exempt from password restrictions. */
+    *pam_status = exempt ? PAM_SUCCESS : rc;
+    debug_return_int(status);
 }
 
 int