From 89b96cb85cbd86a3f07a47e5e6826f7c5a69e3d5 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 25 Jun 2018 16:00:17 +0200 Subject: [PATCH] su.c: run pam_getenvlist() after setup_env When "su -l" is used the behaviour is described as similar to a direct login. However login.c is doing a setup_env(pw) and then a pam_getenvlist() in this scenario. But su.c is doing it the other way around. Which means that the value of PATH from /etc/environment is overriden. I think this is a bug because: The man-page claims that "-l": "provides an environment similar to what the user would expect had the user logged in directly." And login.c is using the PATH from /etc/environment. This will fix: https://bugs.launchpad.net/ubuntu/+source/shadow/+bug/984390 --- src/su.c | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/src/su.c b/src/su.c index 685f7bb0..fc0e826f 100644 --- a/src/su.c +++ b/src/su.c @@ -913,27 +913,7 @@ static void set_environment (struct passwd *pw) addenv ("IFS= \t\n", NULL); /* ... instead, set a safe IFS */ } -#ifdef USE_PAM - /* we need to setup the environment *after* pam_open_session(), - * else the UID is changed before stuff like pam_xauth could - * run, and we cannot access /etc/shadow and co - */ - environ = newenvp; /* make new environment active */ - - if (change_environment) { - /* update environment with all pam set variables */ - char **envcp = pam_getenvlist (pamh); - if (NULL != envcp) { - while (NULL != *envcp) { - addenv (*envcp, NULL); - envcp++; - } - } - } - -#else /* !USE_PAM */ environ = newenvp; /* make new environment active */ -#endif /* !USE_PAM */ if (change_environment) { if (fakelogin) { @@ -948,6 +928,21 @@ static void set_environment (struct passwd *pw) addenv ("LOGNAME", pw->pw_name); addenv ("SHELL", shellstr); } + +#ifdef USE_PAM + /* we need to setup the environment *after* pam_open_session(), + * else the UID is changed before stuff like pam_xauth could + * run, and we cannot access /etc/shadow and co + */ + /* update environment with all pam set variables */ + char **envcp = pam_getenvlist (pamh); + if (NULL != envcp) { + while (NULL != *envcp) { + addenv (*envcp, NULL); + envcp++; + } + } +#endif /* !USE_PAM */ } } -- 2.40.0