]> granicus.if.org Git - sudo/commitdiff
Defer setting user-specified env vars until after authentication.
authorTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 9 Jul 2007 19:13:38 +0000 (19:13 +0000)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 9 Jul 2007 19:13:38 +0000 (19:13 +0000)
env.c
sudo.c

diff --git a/env.c b/env.c
index 938b1ab3a9a2024d1ae35580654798cf337c8a31..63b37e9b17b4eed8d0edf6e9213b88fdd4f2bc89 100644 (file)
--- a/env.c
+++ b/env.c
@@ -103,6 +103,11 @@ char **rebuild_env         __P((char **, int, int));
 static void insert_env         __P((char *, struct environment *, int));
 static char *format_env                __P((char *, ...));
 
+/*
+ * Copy of the sudo-managed environment.
+ */
+static struct environment env;
+
 /*
  * Default table of "bad" variables to remove from the environment.
  * XXX - how to omit TERMCAP if it starts with '/'?
@@ -386,8 +391,6 @@ rebuild_env(envp, sudo_mode, noexec)
     int sudo_mode;
     int noexec;
 {
-    struct list_member *cur;
-    struct environment env;
     char **ep, *cp, *ps1;
     unsigned int didvar;
 
@@ -590,9 +593,40 @@ rebuild_env(envp, sudo_mode, noexec)
     easprintf(&cp, "SUDO_GID=%lu", (unsigned long) user_gid);
     insert_env(cp, &env, 1);
 
+    return(env.envp);
+}
+
+char **
+insert_env_vars(envp, env_vars)
+    char **envp;
+    struct list_member *env_vars;
+{
+    struct list_member *cur;
+
+    if (env_vars == NULL)
+       return (envp);
+
+    /*
+     * Make sure we still own the environment and steal it back if not.
+     */
+    if (env.envp != envp) {
+       size_t evlen;
+       char **ep;
+
+       for (ep = envp; *ep != NULL; ep++)
+           continue;
+       evlen = ep - envp;
+       if (evlen + 1 > env.env_size) {
+           efree(env.envp);
+           env.env_size = evlen + 1 + 128;
+           env.envp = emalloc2(env.env_size, sizeof(char *));
+       }
+       memcpy(env.envp, envp, evlen + 1);
+       env.env_len = evlen;
+    }
+
     /* Add user-specified environment variables. */
-    /* XXX - this is not safe, should be done after authentication. */
-    for (cur = sudo_user.env_vars; cur != NULL; cur = cur->next)
+    for (cur = env_vars; cur != NULL; cur = cur->next)
        insert_env(cur->value, &env, 1);
 
     return(env.envp);
diff --git a/sudo.c b/sudo.c
index de5b9b731fc534356601c4479c0d217d27270bfe..e0d30a59bbb96c08c2bc3d0f510de51e3ec04826 100644 (file)
--- a/sudo.c
+++ b/sudo.c
@@ -117,6 +117,7 @@ static struct passwd *get_authpw    __P((void));
 extern int sudo_edit                   __P((int, char **, char **));
 extern char **rebuild_env              __P((char **, int, int));
 void validate_env_vars                 __P((struct list_member *));
+char **insert_env_vars                 __P((char **, struct list_member *));
 
 /*
  * Globals
@@ -440,6 +441,9 @@ main(argc, argv, envp)
        if (ISSET(sudo_mode, MODE_EDIT))
            exit(sudo_edit(NewArgc, NewArgv, envp));
 
+       /* Insert user-specified environment variables. */
+       environ = insert_env_vars(environ, sudo_user.env_vars);
+
        /* Restore signal handlers before we exec. */
        (void) sigaction(SIGINT, &saved_sa_int, NULL);
        (void) sigaction(SIGQUIT, &saved_sa_quit, NULL);