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
This commit is contained in:
Michael Vogt 2018-06-25 16:00:17 +02:00
parent 67ec1a5266
commit 89b96cb85c

View File

@ -913,28 +913,8 @@ static void set_environment (struct passwd *pw)
addenv ("IFS= \t\n", NULL); /* ... instead, set a safe IFS */ 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 */ 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 (change_environment) {
if (fakelogin) { if (fakelogin) {
if (shellstr != pw->pw_shell) { if (shellstr != pw->pw_shell) {
@ -948,6 +928,21 @@ static void set_environment (struct passwd *pw)
addenv ("LOGNAME", pw->pw_name); addenv ("LOGNAME", pw->pw_name);
addenv ("SHELL", shellstr); 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 */
} }
} }