When initializing the environment for env_reset, start out with
the contents of /etc/environment on AIX and login.conf on BSD.
This commit is contained in:
@@ -89,11 +89,16 @@ environment are inherited by the command to be run. There are two
|
|||||||
distinct ways I<sudoers> can deal with environment variables.
|
distinct ways I<sudoers> can deal with environment variables.
|
||||||
|
|
||||||
By default, the I<env_reset> option is enabled. This causes commands
|
By default, the I<env_reset> option is enabled. This causes commands
|
||||||
to be executed with a minimal environment containing the C<TERM>,
|
to be executed with a new, minimal environment. On AIX (and Linux
|
||||||
C<PATH>, C<HOME>, C<MAIL>, C<SHELL>, C<LOGNAME>, C<USER>, C<USERNAME>
|
systems without PAM), the environment is initialized with the
|
||||||
and C<SUDO_*> variables in addition to variables from the
|
contents of the F</etc/environment> file. On BSD systems, if the
|
||||||
invoking process permitted by the I<env_check> and I<env_keep>
|
I<use_loginclass> option is enabled, the environment is initialized
|
||||||
options. This is effectively a whitelist for environment variables.
|
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, any variables not
|
If, however, the I<env_reset> option is disabled, any variables not
|
||||||
explicitly denied by the I<env_check> and I<env_delete> options are
|
explicitly denied by the I<env_check> and I<env_delete> options are
|
||||||
@@ -119,12 +124,15 @@ As a special case, if B<sudo>'s B<-i> option (initial login) is
|
|||||||
specified, I<sudoers> will initialize the environment regardless
|
specified, I<sudoers> will initialize the environment regardless
|
||||||
of the value of I<env_reset>. The I<DISPLAY>, I<PATH> and I<TERM>
|
of the value of I<env_reset>. The I<DISPLAY>, I<PATH> and I<TERM>
|
||||||
variables remain unchanged; I<HOME>, I<MAIL>, I<SHELL>, I<USER>,
|
variables remain unchanged; I<HOME>, I<MAIL>, I<SHELL>, I<USER>,
|
||||||
and I<LOGNAME> are set based on the target user. On Linux and AIX
|
and I<LOGNAME> are set based on the target user. On AIX (and Linux
|
||||||
systems the contents of F</etc/environment> are also included. All
|
systems without PAM), the contents of F</etc/environment> are also
|
||||||
other environment variables are removed.
|
included. On BSD systems, if the I<use_loginclass> option is
|
||||||
|
enabled, the I<path> and I<setenv> variables in F</etc/login.conf>
|
||||||
|
are also applied. All other environment variables are removed.
|
||||||
|
|
||||||
Lastly, if the I<env_file> option is defined, any variables present
|
Finally, if the I<env_file> option is defined, any variables present
|
||||||
in that file will be set to their specified values.
|
in that file will be set to their specified values as long as they
|
||||||
|
would not conflict with an existing environment variable.
|
||||||
|
|
||||||
=head1 SUDOERS FILE FORMAT
|
=head1 SUDOERS FILE FORMAT
|
||||||
|
|
||||||
@@ -1776,7 +1784,7 @@ Directory containing time stamps for the I<sudoers> security policy
|
|||||||
|
|
||||||
=item F</etc/environment>
|
=item F</etc/environment>
|
||||||
|
|
||||||
Initial environment for B<-i> mode on Linux and AIX
|
Initial environment for B<-i> mode on AIX and Linux systems
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
|
@@ -42,6 +42,12 @@
|
|||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif /* HAVE_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 <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
@@ -638,6 +644,43 @@ env_should_keep(const char *var)
|
|||||||
debug_return_bool(keepit == true);
|
debug_return_bool(keepit == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
env_update_didvar(const char *ep, 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
|
* Build a new environment and ether clear potentially dangerous
|
||||||
* variables from the old one or start with a clean slate.
|
* variables from the old one or start with a clean slate.
|
||||||
@@ -662,6 +705,8 @@ rebuild_env(void)
|
|||||||
env.envp = emalloc2(env.env_size, sizeof(char *));
|
env.envp = emalloc2(env.env_size, sizeof(char *));
|
||||||
#ifdef ENV_DEBUG
|
#ifdef ENV_DEBUG
|
||||||
memset(env.envp, 0, env.env_size * sizeof(char *));
|
memset(env.envp, 0, env.env_size * sizeof(char *));
|
||||||
|
#else
|
||||||
|
env.envp[0] = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Reset HOME based on target user if configured to. */
|
/* Reset HOME based on target user if configured to. */
|
||||||
@@ -673,6 +718,32 @@ rebuild_env(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (def_env_reset || ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
|
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. */
|
/* Pull in vars we want to keep from the old environment. */
|
||||||
for (ep = old_envp; *ep; ep++) {
|
for (ep = old_envp; *ep; ep++) {
|
||||||
bool keepit;
|
bool keepit;
|
||||||
@@ -697,39 +768,8 @@ rebuild_env(void)
|
|||||||
|
|
||||||
if (keepit) {
|
if (keepit) {
|
||||||
/* Preserve variable. */
|
/* 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;
|
|
||||||
}
|
|
||||||
sudo_putenv(*ep, false, false);
|
sudo_putenv(*ep, false, false);
|
||||||
|
env_update_didvar(*ep, &didvar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
didvar |= didvar << 8; /* convert DID_* to KEPT_* */
|
didvar |= didvar << 8; /* convert DID_* to KEPT_* */
|
||||||
|
Reference in New Issue
Block a user