]> granicus.if.org Git - sudo/commitdiff
Fix a PAM_USER mismatch in session open/close. We update PAM_USER
authorTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 27 Sep 2011 15:13:44 +0000 (11:13 -0400)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 27 Sep 2011 15:13:44 +0000 (11:13 -0400)
to the target user immediately before setting resource limits, which
is after the monitor process has forked (so it has the old value).
Also, if the user did not authenticate, there is no pamh in the
monitor so we need to init pam here too.  This means we end up
calling pam_start() twice, which should be fixed, but at least the
session is always properly closed now.

plugins/sudoers/auth/pam.c
plugins/sudoers/auth/sudo_auth.c
plugins/sudoers/auth/sudo_auth.h
plugins/sudoers/sudoers.c

index d66e30285c8a2bebb87d109bb09cf03dc4592f0a..f0b539452904004ff71f77ae33a08f8da2abb031 100644 (file)
@@ -242,16 +242,26 @@ done:
 }
 
 int
-pam_end_session(sudo_auth *auth)
+pam_end_session(struct passwd *pw, sudo_auth *auth)
 {
     int status = PAM_SUCCESS;
 
-    if (pamh) {
 #ifndef NO_PAM_SESSION
-       (void) pam_close_session(pamh, PAM_SILENT);
+    /* If the user did not have to authenticate there is no pam handle yet. */
+    if (pamh == NULL)
+       pam_init(pw, NULL, NULL);
+
+    /*
+     * Update PAM_USER to reference the user we are running the command
+     * as to match the call to pam_open_session().
+     */
+    (void) pam_set_item(pamh, PAM_USER, pw->pw_name);
+
+    (void) pam_close_session(pamh, PAM_SILENT);
 #endif
+
+    if (pamh != NULL)
        status = pam_end(pamh, PAM_SUCCESS | PAM_DATA_SILENT);
-    }
     return status == PAM_SUCCESS ? AUTH_SUCCESS : AUTH_FAILURE;
 }
 
index f82b5cb7fd76726f2bb7d49d846610b99a99caa4..66d8f46a4d5df66bdc06131c206fdc53bd410651 100644 (file)
@@ -274,14 +274,14 @@ int auth_begin_session(struct passwd *pw)
     return TRUE;
 }
 
-int auth_end_session(void)
+int auth_end_session(struct passwd *pw)
 {
     sudo_auth *auth;
     int status;
 
     for (auth = auth_switch; auth->name; auth++) {
        if (auth->end_session && !IS_DISABLED(auth)) {
-           status = (auth->end_session)(auth);
+           status = (auth->end_session)(pw, auth);
            if (status == AUTH_FATAL) { /* XXX log */
                return -1;              /* assume error msg already printed */
            }
index 91124bfea095aec08a44e218891199fbef7ea883..83ea46398fcca6cb55c0391416b963c203b923c4 100644 (file)
@@ -33,7 +33,7 @@ typedef struct sudo_auth {
     int (*verify)(struct passwd *pw, char *p, struct sudo_auth *auth);
     int (*cleanup)(struct passwd *pw, struct sudo_auth *auth);
     int (*begin_session)(struct passwd *pw, struct sudo_auth *auth);
-    int (*end_session)(struct sudo_auth *auth);
+    int (*end_session)(struct passwd *pw, struct sudo_auth *auth);
 } sudo_auth;
 
 /* Values for sudo_auth.flags.  */
@@ -62,7 +62,7 @@ int pam_init(struct passwd *pw, char **prompt, sudo_auth *auth);
 int pam_verify(struct passwd *pw, char *prompt, sudo_auth *auth);
 int pam_cleanup(struct passwd *pw, sudo_auth *auth);
 int pam_begin_session(struct passwd *pw, sudo_auth *auth);
-int pam_end_session(sudo_auth *auth);
+int pam_end_session(struct passwd *pw, sudo_auth *auth);
 int sia_setup(struct passwd *pw, char **prompt, sudo_auth *auth);
 int sia_verify(struct passwd *pw, char *prompt, sudo_auth *auth);
 int sia_cleanup(struct passwd *pw, sudo_auth *auth);
index 9f27fe8121bc3d210106b42d7423e3515114c4a1..d2595dd8d00108fa46e75e12061844461fd98fc2 100644 (file)
@@ -254,7 +254,7 @@ sudoers_policy_close(int exit_status, int error_code)
 
     /* Close the session we opened in sudoers_policy_init_session(). */
     if (ISSET(sudo_mode, MODE_RUN|MODE_EDIT))
-       (void)auth_end_session();
+       (void)auth_end_session(runas_pw);
 
     /* Free remaining references to password and group entries. */
     pw_delref(sudo_user.pw);