]> granicus.if.org Git - sudo/commitdiff
For sudoedit, run the editor with the user's original environment
authorTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 17 Mar 2015 02:19:24 +0000 (20:19 -0600)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 17 Mar 2015 02:19:24 +0000 (20:19 -0600)
as per the documentation (and as in sudo 1.7.x).  Bug #688

plugins/sudoers/env.c
plugins/sudoers/sudoers.c
plugins/sudoers/sudoers.h

index d2f844f3e7848d16974100fc9b26ebb7eeaf42ea..3b3664240264661f0d10f7c3e0f03290a839ef55 100644 (file)
 #define KEPT_MAX       0xff00
 
 struct environment {
-    char * const *old_envp;    /* pointer the environment we passed back */
     char **envp;               /* pointer to the new environment */
+    char **old_envp;           /* pointer the old environment we allocated */
     size_t env_size;           /* size of new_environ in char **'s */
     size_t env_len;            /* number of slots used, not counting NULL */
 };
@@ -219,10 +219,14 @@ env_init(char * const envp[])
     debug_decl(env_init, SUDOERS_DEBUG_ENV)
 
     if (envp == NULL) {
+       /* Free the old envp we allocated, if any. */
+       sudo_efree(env.old_envp);
+
        /* Reset to initial state but keep a pointer to what we allocated. */
-       envp = env.envp;
-       memset(&env, 0, sizeof(env));
-       env.old_envp = envp;
+       env.old_envp = env.envp;
+       env.envp = NULL;
+       env.env_size = 0;
+       env.env_len = 0;
     } else {
        /* Make private copy of envp. */
        for (ep = envp; *ep != NULL; ep++)
@@ -239,8 +243,8 @@ env_init(char * const envp[])
        env.envp[len] = NULL;
 
        /* Free the old envp we allocated, if any. */
-       if (env.old_envp != NULL)
-           sudo_efree((void *)env.old_envp);
+       sudo_efree(env.old_envp);
+       env.old_envp = NULL;
     }
 
     debug_return;
@@ -255,6 +259,22 @@ env_get(void)
     return env.envp;
 }
 
+/*
+ * Swap the old and new copies of the environment.
+ */
+bool
+env_swap_old(void)
+{
+    char **old_envp;
+
+    if (env.old_envp == NULL)
+       return false;
+    old_envp = env.old_envp;
+    env.old_envp = env.envp;
+    env.envp = old_envp;
+    return true;
+}
+
 /*
  * Similar to putenv(3) but operates on sudo's private copy of the
  * environment (not environ) and it always overwrites.  The dupcheck param
@@ -810,7 +830,7 @@ env_update_didvar(const char *ep, unsigned int *didvar)
 bool
 rebuild_env(void)
 {
-    char **old_envp, **ep, *cp, *ps1;
+    char **ep, *cp, *ps1;
     char idbuf[MAX_UID_T_LEN + 1];
     unsigned int didvar;
     bool reset_home = false;
@@ -823,7 +843,8 @@ rebuild_env(void)
     didvar = 0;
     env.env_len = 0;
     env.env_size = 128;
-    old_envp = env.envp;
+    sudo_efree(env.old_envp);
+    env.old_envp = env.envp;
     env.envp = sudo_emallocarray(env.env_size, sizeof(char *));
 #ifdef ENV_DEBUG
     memset(env.envp, 0, env.env_size * sizeof(char *));
@@ -867,7 +888,7 @@ rebuild_env(void)
        }
 
        /* Pull in vars we want to keep from the old environment. */
-       for (ep = old_envp; *ep; ep++) {
+       for (ep = env.old_envp; *ep; ep++) {
            bool keepit;
 
            /*
@@ -943,7 +964,7 @@ rebuild_env(void)
         * Copy environ entries as long as they don't match env_delete or
         * env_check.
         */
-       for (ep = old_envp; *ep; ep++) {
+       for (ep = env.old_envp; *ep; ep++) {
            /* Add variable unless it matches a black list. */
            if (!env_should_delete(*ep)) {
                if (strncmp(*ep, "SUDO_PS1=", 9) == 0)
@@ -970,7 +991,7 @@ rebuild_env(void)
      * they have already been set) or sudoedit (because we want the editor
      * to find the invoking user's startup files).
      */
-    if (def_set_logname && !ISSET(sudo_mode, MODE_LOGIN_SHELL|MODE_EDIT)) {
+    if (def_set_logname && !ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
        if (!ISSET(didvar, KEPT_LOGNAME))
            sudo_setenv2("LOGNAME", runas_pw->pw_name, true, true);
        if (!ISSET(didvar, KEPT_USER))
@@ -1021,9 +1042,6 @@ rebuild_env(void)
     if (sudo_setenv2("SUDO_GID", idbuf, true, true) == -1)
        goto bad;
 
-    /* Free old environment. */
-    sudo_efree(old_envp);
-
     debug_return_bool(true);
 
 bad:
index 8359bea8224157ebb59f0bfb149900db1450e891..b165cd02d24f66da2ff86dd0867f566c20eb67d8 100644 (file)
@@ -525,6 +525,9 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
        safe_cmnd = find_editor(NewArgc - 1, NewArgv + 1, &edit_argc, &edit_argv);
        if (safe_cmnd == NULL || audit_success(edit_argc, edit_argv) != 0)
            goto bad;
+
+       /* We want to run the editor with the unmodified environment. */
+       env_swap_old();
     } else {
        if (audit_success(NewArgc, NewArgv) != 0)
            goto bad;
index 1d659b5d5804a1400c10bde6fd6e0cacd06bcb95..a8d22a0a7dd05250c854013b348fed55335d69bc 100644 (file)
@@ -324,6 +324,7 @@ char *expand_iolog_path(const char *prefix, const char *dir, const char *file,
 /* env.c */
 char **env_get(void);
 bool env_merge(char * const envp[]);
+bool env_swap_old(void);
 void env_init(char * const envp[]);
 void init_envtables(void);
 bool insert_env_vars(char * const envp[]);