From: Nicolas François Date: Tue, 20 Aug 2013 18:50:03 +0000 (+0200) Subject: Close PAM session as root. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cf57a6c09d53b14b64b09b269017aa266d9c4c50;p=thirdparty%2Fshadow.git Close PAM session as root. * src/su.c: call handle_session() before changing the UID so that PAM sessions can be closed as root. This require to set the pt slave ownership to the user we are switching to. --- diff --git a/ChangeLog b/ChangeLog index 4b6d0bbed..0083e807e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-08-20 Nicolas François + + * src/su.c: call handle_session() before changing the UID so that + PAM sessions can be closed as root. This require to set the pt + slave ownership to the user we are switching to. + 2013-08-20 Nicolas François * src/su.c: There are no more SIGTSTP signal handler. diff --git a/src/su.c b/src/su.c index 6f06e83f7..927440305 100644 --- a/src/su.c +++ b/src/su.c @@ -124,7 +124,7 @@ static void execve_shell (const char *shellname, char *args[], char *const envp[]); static RETSIGTYPE kill_child (int unused(s)); -static void handle_session (void); +static void handle_session (const struct passwd *pw); #ifndef USE_PAM static RETSIGTYPE die (int); static bool iswheel (const char *); @@ -271,7 +271,7 @@ static void catch_signals (int sig) * or if not a controlling terminal then wait for the child to * terminate and exit. */ -static void handle_session (void) +static void handle_session (const struct passwd *pw) { sigset_t ourset; int status; @@ -343,6 +343,13 @@ static void handle_session (void) (void) close (fd_ptmx); exit (1); } + + if (fchown (fd_pts, pw->pw_uid, -1) != 0) { + fprintf (stderr, _("%s: Cannot set ownership of pt slave\n"), Prog); + (void) close (fd_pts); + (void) close (fd_ptmx); + exit (1); + } } @@ -1243,23 +1250,23 @@ int main (int argc, char **argv) exit (1); } + handle_session (pw); + /* become the new user */ if (change_uid (pw) != 0) { exit (1); } - - handle_session (); #else /* !USE_PAM */ /* no limits if su from root (unless su must fake login's behavior) */ if (!caller_is_root || fakelogin) { setup_limits (pw); } + handle_session (pw); + if (setup_uid_gid (pw, caller_on_console) != 0) { exit (1); } - - handle_session (); #endif /* !USE_PAM */