From: Todd C. Miller Date: Wed, 21 Jan 2004 22:06:02 +0000 (+0000) Subject: If real uid == 0 and the SUDO_USER environment variables is set, X-Git-Tag: SUDO_1_6_8~220 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8ab5b8c596516c645d8716aa50c0de5b2b253e5d;p=sudo If real uid == 0 and the SUDO_USER environment variables is set, use that to determine the invoking user's true identity. That way the proper info gets logged by someone who has done "sudo su" but still uses sudo to as root. We can't do this for non-root users since that would open up a security hole, though perhaps it would be acceptable to use getlogin(2) on OSes where this a system call (and doesn't just look in the utmp file). --- diff --git a/env.c b/env.c index 09a0403ce..eda955053 100644 --- a/env.c +++ b/env.c @@ -169,6 +169,7 @@ zero_env(envp) { char **ep, **nep; static char *newenv[7]; + extern char *prev_user; for (ep = envp; *ep; ep++) { switch (**ep) { @@ -190,8 +191,10 @@ zero_env(envp) case 'S': if (strncmp("SHELL=", *ep, 6) == 0) user_shell = *ep + 6; - else if (!user_prompt && !strncmp("SUDO_PROMPT=", *ep, 12)) + else if (!user_prompt && strncmp("SUDO_PROMPT=", *ep, 12) == 0) user_prompt = *ep + 12; + else if (strncmp("SUDO_USER=", *ep, 10) == 0) + prev_user = *ep + 10; continue; case 'T': if (strncmp("TZ=", *ep, 3) == 0) diff --git a/sudo.c b/sudo.c index 62bad0c96..e8e0d0a8b 100644 --- a/sudo.c +++ b/sudo.c @@ -133,6 +133,7 @@ extern struct passwd *sudo_pwdup __P((const struct passwd *)); */ int Argc, NewArgc; char **Argv, **NewArgv; +char *prev_user; struct sudo_user sudo_user; struct passwd *auth_pw; FILE *sudoers_fp; @@ -514,9 +515,16 @@ init_vars(sudo_mode) /* * Get a local copy of the user's struct passwd with the shadow password * if necessary. It is assumed that euid is 0 at this point so we - * can read the shadow passwd file if necessary. + * can read the shadow passwd file if necessary. If we are being run + * as root and the user is chaining sudo commands, use the SUDO_USER + * environment variable to determine the user's real identity. + * It is not safe to trust SUDO_USER if the real uid != 0. */ - if ((sudo_user.pw = sudo_getpwuid(getuid())) == NULL) { + if (getuid() == 0 && prev_user != NULL) + sudo_user.pw = sudo_getpwnam(prev_user); + else + sudo_user.pw = sudo_getpwuid(getuid()); + if (sudo_user.pw == NULL) { /* Need to make a fake struct passwd for logging to work. */ struct passwd pw; char pw_name[MAX_UID_T_LEN + 1]; @@ -570,7 +578,7 @@ init_vars(sudo_mode) char **dst, **src = NewArgv; NewArgv = (char **) emalloc2((++NewArgc + 1), sizeof(char *)); - if (sudo_mode & MODE_LOGIN_SHELL) + if (sudo_mode & MODE_LOGIN_SHELL) NewArgv[0] = runas_pw->pw_shell; else if (user_shell && *user_shell) NewArgv[0] = user_shell;