#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
+#ifdef HAVE_LOGIN_CAP_H
+# include <login_cap.h>
+# ifndef LOGIN_SETENV
+# define LOGIN_SETENV 0
+# endif
+#endif /* HAVE_LOGIN_CAP_H */
#include <ctype.h>
#include <errno.h>
#include <pwd.h>
"TZ",
"XAUTHORITY",
"XAUTHORIZATION",
-#ifdef _AIX
- "ODMDIR",
-#endif
NULL
};
/*
* Check the env_delete blacklist.
- * Returns TRUE if the variable was found, else false.
+ * Returns TRUE if the variable was found, else FALSE.
*/
static int
matches_env_delete(var)
return keepit;
}
+static void
+env_update_didvar(const char *ep, unsigned int *didvar)
+{
+ switch (*ep) {
+ case 'H':
+ if (strncmp(ep, "HOME=", 5) == 0)
+ SET(*didvar, DID_HOME);
+ break;
+ case 'L':
+ if (strncmp(ep, "LOGNAME=", 8) == 0)
+ SET(*didvar, DID_LOGNAME);
+ break;
+ case 'M':
+ if (strncmp(ep, "MAIL=", 5) == 0)
+ SET(*didvar, DID_MAIL);
+ break;
+ case 'P':
+ if (strncmp(ep, "PATH=", 5) == 0)
+ SET(*didvar, DID_PATH);
+ break;
+ case 'S':
+ if (strncmp(ep, "SHELL=", 6) == 0)
+ SET(*didvar, DID_SHELL);
+ break;
+ case 'T':
+ if (strncmp(ep, "TERM=", 5) == 0)
+ SET(*didvar, DID_TERM);
+ break;
+ case 'U':
+ if (strncmp(ep, "USER=", 5) == 0)
+ SET(*didvar, DID_USER);
+ if (strncmp(ep, "USERNAME=", 5) == 0)
+ SET(*didvar, DID_USERNAME);
+ break;
+ }
+}
+
/*
* Build a new environment and ether clear potentially dangerous
* variables from the old one or start with a clean slate.
env.envp = emalloc2(env.env_size, sizeof(char *));
#ifdef ENV_DEBUG
memset(env.envp, 0, env.env_size * sizeof(char *));
+#else
+ env.envp[0] = NULL;
#endif
/* Reset HOME based on target user if configured to. */
}
if (def_env_reset || ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
+ /*
+ * If starting with a fresh environment, initialize it based on
+ * /etc/environment or login.conf. For "sudo -i" we want those
+ * variables to override the invoking user's environment, so we
+ * defer reading them until later.
+ */
+ if (!ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
+#ifdef HAVE_LOGIN_CAP_H
+ /* Insert login class environment variables. */
+ if (login_class) {
+ login_cap_t *lc = login_getclass(login_class);
+ if (lc != NULL) {
+ setusercontext(lc, runas_pw, runas_pw->pw_uid,
+ LOGIN_SETPATH|LOGIN_SETENV);
+ login_close(lc);
+ }
+ }
+#endif /* HAVE_LOGIN_CAP_H */
+#if defined(_AIX) || (defined(__linux__) && !defined(HAVE_PAM))
+ /* Insert system-wide environment variables. */
+ read_env_file(_PATH_ENVIRONMENT, TRUE);
+#endif
+ for (ep = env.envp; *ep; ep++)
+ env_update_didvar(*ep, &didvar);
+ }
+
/* Pull in vars we want to keep from the old environment. */
for (ep = old_envp; *ep; ep++) {
int keepit;
if (keepit) {
/* Preserve variable. */
- switch (**ep) {
- case 'H':
- if (strncmp(*ep, "HOME=", 5) == 0)
- SET(didvar, DID_HOME);
- break;
- case 'L':
- if (strncmp(*ep, "LOGNAME=", 8) == 0)
- SET(didvar, DID_LOGNAME);
- break;
- case 'M':
- if (strncmp(*ep, "MAIL=", 5) == 0)
- SET(didvar, DID_MAIL);
- break;
- case 'P':
- if (strncmp(*ep, "PATH=", 5) == 0)
- SET(didvar, DID_PATH);
- break;
- case 'S':
- if (strncmp(*ep, "SHELL=", 6) == 0)
- SET(didvar, DID_SHELL);
- break;
- case 'T':
- if (strncmp(*ep, "TERM=", 5) == 0)
- SET(didvar, DID_TERM);
- break;
- case 'U':
- if (strncmp(*ep, "USER=", 5) == 0)
- SET(didvar, DID_USER);
- if (strncmp(*ep, "USERNAME=", 5) == 0)
- SET(didvar, DID_USERNAME);
- break;
- }
+ env_update_didvar(*ep, &didvar);
sudo_putenv(*ep, FALSE, FALSE);
}
}
There are two distinct ways to deal with environment variables. By
default, the I<env_reset> I<sudoers> option is enabled. This causes
-commands to be executed with a minimal environment containing the
-C<TERM>, C<PATH>, C<HOME>, C<MAIL>, C<SHELL>, C<LOGNAME>, C<USER>,
-C<USERNAME> and C<SUDO_*> variables in addition to variables from
-the invoking process permitted by the I<env_check> and I<env_keep>
-I<sudoers> options. This is effectively a whitelist for environment
-variables.
+commands to be executed with a new, minimal environment containing.
+On AIX (and Linux systems without PAM), the environment is initialized
+with the contents of the F</etc/environment> file. On BSD systems,
+if the I<use_loginclass> option is enabled, the environment is
+initialized based on the I<path> and I<setenv> settings in
+F</etc/login.conf>. The new environment contains the C<TERM>,
+C<PATH>, C<HOME>, C<MAIL>, C<SHELL>, C<LOGNAME>, C<USER>, C<USERNAME>
+and C<SUDO_*> variables in addition to variables from the invoking
+process permitted by the I<env_check> and I<env_keep> options. This
+is effectively a whitelist for environment variables.
If, however, the I<env_reset> option is disabled in I<sudoers>, any
variables not explicitly denied by the I<env_check> and I<env_delete>
=item F</etc/environment>
-Initial environment for B<-i> mode on Linux and AIX
+Initial environment for B<-i> mode on AIX Linux systems
=back