]> granicus.if.org Git - sudo/commitdiff
If real uid == 0 and the SUDO_USER environment variables is set,
authorTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 21 Jan 2004 22:06:02 +0000 (22:06 +0000)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 21 Jan 2004 22:06:02 +0000 (22:06 +0000)
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).

env.c
sudo.c

diff --git a/env.c b/env.c
index 09a0403ce5b868c63dc7dbbd7f9b7363861fdf76..eda955053e1d3e4659de01be0c667dc90b60841e 100644 (file)
--- 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 62bad0c964ee0d59903db8d2a2558c6920ede394..e8e0d0a8bb07d77dbb5b3a34f4c1576082d5f237 100644 (file)
--- 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;