Eliminate calls to fatal()/fatalx()/log_fatal() in env.c and just
pass back a return value.
This commit is contained in:
@@ -93,7 +93,8 @@ sudo_aix_cleanup(struct passwd *pw, sudo_auth *auth)
|
||||
debug_decl(sudo_aix_cleanup, SUDO_DEBUG_AUTH)
|
||||
|
||||
/* Unset AUTHSTATE as it may not be correct for the runas user. */
|
||||
sudo_unsetenv("AUTHSTATE");
|
||||
if (sudo_unsetenv("AUTHSTATE") == -1)
|
||||
debug_return_int(AUTH_FAILURE);
|
||||
|
||||
debug_return_int(AUTH_SUCCESS);
|
||||
}
|
||||
|
@@ -261,7 +261,8 @@ sudo_pam_begin_session(struct passwd *pw, char **user_envp[], sudo_auth *auth)
|
||||
if (pam_envp != NULL) {
|
||||
/* Merge pam env with user env. */
|
||||
env_init(*user_envp);
|
||||
env_merge(pam_envp);
|
||||
if (!env_merge(pam_envp))
|
||||
status = PAM_SYSTEM_ERR;
|
||||
*user_envp = env_get();
|
||||
env_init(NULL);
|
||||
efree(pam_envp);
|
||||
|
@@ -285,13 +285,17 @@ sudo_putenv_nodebug(char *str, bool dupcheck, bool overwrite)
|
||||
size_t nsize;
|
||||
|
||||
if (env.env_size > SIZE_MAX - 128) {
|
||||
fatalx_nodebug(U_("internal error, %s overflow"),
|
||||
warningx_nodebug(U_("internal error, %s overflow"),
|
||||
"sudo_putenv_nodebug");
|
||||
errno = EOVERFLOW;
|
||||
return -1;
|
||||
}
|
||||
nsize = env.env_size + 128;
|
||||
if (nsize > SIZE_MAX / sizeof(char *)) {
|
||||
fatalx_nodebug(U_("internal error, %s overflow"),
|
||||
warningx_nodebug(U_("internal error, %s overflow"),
|
||||
"sudo_putenv_nodebug");
|
||||
errno = EOVERFLOW;
|
||||
return -1;
|
||||
}
|
||||
nenvp = realloc(env.envp, nsize * sizeof(char *));
|
||||
if (nenvp == NULL) {
|
||||
@@ -364,9 +368,8 @@ sudo_putenv(char *str, bool dupcheck, bool overwrite)
|
||||
if (rval == -1) {
|
||||
#ifdef ENV_DEBUG
|
||||
if (env.envp[env.env_len] != NULL)
|
||||
fatalx(U_("sudo_putenv: corrupted envp, length mismatch"));
|
||||
warningx(U_("sudo_putenv: corrupted envp, length mismatch"));
|
||||
#endif
|
||||
fatal(NULL);
|
||||
}
|
||||
debug_return_int(rval);
|
||||
}
|
||||
@@ -381,7 +384,7 @@ sudo_setenv2(const char *var, const char *val, bool dupcheck, bool overwrite)
|
||||
{
|
||||
char *estring;
|
||||
size_t esize;
|
||||
int rval;
|
||||
int rval = -1;
|
||||
debug_decl(sudo_setenv2, SUDO_DEBUG_ENV)
|
||||
|
||||
esize = strlen(var) + 1 + strlen(val) + 1;
|
||||
@@ -392,9 +395,11 @@ sudo_setenv2(const char *var, const char *val, bool dupcheck, bool overwrite)
|
||||
strlcat(estring, "=", esize) >= esize ||
|
||||
strlcat(estring, val, esize) >= esize) {
|
||||
|
||||
fatalx(U_("internal error, %s overflow"), __func__);
|
||||
warningx(U_("internal error, %s overflow"), __func__);
|
||||
errno = EOVERFLOW;
|
||||
} else {
|
||||
rval = sudo_putenv(estring, dupcheck, overwrite);
|
||||
}
|
||||
rval = sudo_putenv(estring, dupcheck, overwrite);
|
||||
if (rval == -1)
|
||||
efree(estring);
|
||||
debug_return_int(rval);
|
||||
@@ -684,17 +689,23 @@ env_should_keep(const char *var)
|
||||
* Merge another environment with our private copy.
|
||||
* Only overwrite an existing variable if it is not
|
||||
* being preserved from the user's environment.
|
||||
* Returns true on success or false on failure.
|
||||
*/
|
||||
void
|
||||
bool
|
||||
env_merge(char * const envp[])
|
||||
{
|
||||
char * const *ep;
|
||||
bool rval = true;
|
||||
debug_decl(env_merge, SUDO_DEBUG_ENV)
|
||||
|
||||
for (ep = envp; *ep != NULL; ep++)
|
||||
sudo_putenv(*ep, true, !env_should_keep(*ep));
|
||||
|
||||
debug_return;
|
||||
for (ep = envp; *ep != NULL; ep++) {
|
||||
if (sudo_putenv(*ep, true, !env_should_keep(*ep)) == -1) {
|
||||
/* XXX cannot undo on failure */
|
||||
rval = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
debug_return_bool(rval);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -738,14 +749,16 @@ env_update_didvar(const char *ep, unsigned int *didvar)
|
||||
* Build a new environment and ether clear potentially dangerous
|
||||
* variables from the old one or start with a clean slate.
|
||||
* Also adds sudo-specific variables (SUDO_*).
|
||||
* Returns true on success or false on failure.
|
||||
*/
|
||||
void
|
||||
bool
|
||||
rebuild_env(void)
|
||||
{
|
||||
char **old_envp, **ep, *cp, *ps1;
|
||||
char idbuf[MAX_UID_T_LEN + 1];
|
||||
unsigned int didvar;
|
||||
bool reset_home = false;
|
||||
debug_decl(rebuild_env, SUDO_DEBUG_ENV)
|
||||
|
||||
/*
|
||||
* Either clean out the environment or reset to a safe default.
|
||||
@@ -821,7 +834,8 @@ rebuild_env(void)
|
||||
|
||||
if (keepit) {
|
||||
/* Preserve variable. */
|
||||
sudo_putenv(*ep, false, false);
|
||||
if (sudo_putenv(*ep, false, false) == -1)
|
||||
goto bad;
|
||||
env_update_didvar(*ep, &didvar);
|
||||
}
|
||||
}
|
||||
@@ -869,7 +883,10 @@ rebuild_env(void)
|
||||
easprintf(&cp, "MAIL=%s%s", _PATH_MAILDIR, runas_pw->pw_name);
|
||||
else
|
||||
easprintf(&cp, "MAIL=%s/%s", _PATH_MAILDIR, runas_pw->pw_name);
|
||||
sudo_putenv(cp, ISSET(didvar, DID_MAIL), true);
|
||||
if (sudo_putenv(cp, ISSET(didvar, DID_MAIL), true) == -1) {
|
||||
free(cp);
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
@@ -891,13 +908,15 @@ rebuild_env(void)
|
||||
SET(didvar, DID_PATH);
|
||||
else if (strncmp(*ep, "TERM=", 5) == 0)
|
||||
SET(didvar, DID_TERM);
|
||||
sudo_putenv(*ep, false, false);
|
||||
if (sudo_putenv(*ep, false, false) == -1)
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Replace the PATH envariable with a secure one? */
|
||||
if (def_secure_path && !user_is_exempt()) {
|
||||
sudo_setenv2("PATH", def_secure_path, true, true);
|
||||
if (sudo_setenv2("PATH", def_secure_path, true, true) == -1)
|
||||
goto bad;
|
||||
SET(didvar, DID_PATH);
|
||||
}
|
||||
|
||||
@@ -921,63 +940,94 @@ rebuild_env(void)
|
||||
sudo_setenv2("HOME", runas_pw->pw_dir, true, true);
|
||||
|
||||
/* Provide default values for $TERM and $PATH if they are not set. */
|
||||
if (!ISSET(didvar, DID_TERM))
|
||||
sudo_putenv("TERM=unknown", false, false);
|
||||
if (!ISSET(didvar, DID_PATH))
|
||||
sudo_setenv2("PATH", _PATH_STDPATH, false, true);
|
||||
if (!ISSET(didvar, DID_TERM)) {
|
||||
if (sudo_putenv("TERM=unknown", false, false) == -1)
|
||||
goto bad;
|
||||
}
|
||||
if (!ISSET(didvar, DID_PATH)) {
|
||||
if (sudo_setenv2("PATH", _PATH_STDPATH, false, true) == -1)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* Set PS1 if SUDO_PS1 is set. */
|
||||
if (ps1 != NULL)
|
||||
sudo_putenv(ps1, true, true);
|
||||
if (ps1 != NULL) {
|
||||
if (sudo_putenv(ps1, true, true) == -1)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* Add the SUDO_COMMAND envariable (cmnd + args). */
|
||||
if (user_args) {
|
||||
easprintf(&cp, "%s %s", user_cmnd, user_args);
|
||||
sudo_setenv2("SUDO_COMMAND", cp, true, true);
|
||||
efree(cp);
|
||||
easprintf(&cp, "SUDO_COMMAND=%s %s", user_cmnd, user_args);
|
||||
if (sudo_putenv(cp, true, true) == -1) {
|
||||
efree(cp);
|
||||
goto bad;
|
||||
}
|
||||
} else {
|
||||
sudo_setenv2("SUDO_COMMAND", user_cmnd, true, true);
|
||||
if (sudo_setenv2("SUDO_COMMAND", user_cmnd, true, true) == -1)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* Add the SUDO_USER, SUDO_UID, SUDO_GID environment variables. */
|
||||
sudo_setenv2("SUDO_USER", user_name, true, true);
|
||||
if (sudo_setenv2("SUDO_USER", user_name, true, true) == -1)
|
||||
goto bad;
|
||||
snprintf(idbuf, sizeof(idbuf), "%u", (unsigned int) user_uid);
|
||||
sudo_setenv2("SUDO_UID", idbuf, true, true);
|
||||
if (sudo_setenv2("SUDO_UID", idbuf, true, true) == -1)
|
||||
goto bad;
|
||||
snprintf(idbuf, sizeof(idbuf), "%u", (unsigned int) user_gid);
|
||||
sudo_setenv2("SUDO_GID", idbuf, true, true);
|
||||
if (sudo_setenv2("SUDO_GID", idbuf, true, true) == -1)
|
||||
goto bad;
|
||||
|
||||
/* Free old environment. */
|
||||
efree(old_envp);
|
||||
|
||||
debug_return_bool(true);
|
||||
|
||||
bad:
|
||||
debug_return_bool(false);
|
||||
}
|
||||
|
||||
void
|
||||
/*
|
||||
* Insert all environment variables in envp into the private copy
|
||||
* of the environment.
|
||||
* Returns true on success or false on failure.
|
||||
*/
|
||||
bool
|
||||
insert_env_vars(char * const envp[])
|
||||
{
|
||||
char * const *ep;
|
||||
|
||||
if (envp == NULL)
|
||||
return;
|
||||
bool rval = true;
|
||||
debug_decl(insert_env_vars, SUDO_DEBUG_ENV)
|
||||
|
||||
/* Add user-specified environment variables. */
|
||||
for (ep = envp; *ep != NULL; ep++)
|
||||
sudo_putenv(*ep, true, true);
|
||||
if (envp != NULL) {
|
||||
for (ep = envp; *ep != NULL; ep++) {
|
||||
/* XXX - no undo on failure */
|
||||
if (sudo_putenv(*ep, true, true) == -1) {
|
||||
rval = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
debug_return_bool(rval);
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate the list of environment variables passed in on the command
|
||||
* line against env_delete, env_check, and env_keep.
|
||||
* Calls log_fatal() if any specified variables are not allowed.
|
||||
* Calls log_warning() if any specified variables are not allowed.
|
||||
* Returns true if allowed, else false.
|
||||
*/
|
||||
void
|
||||
bool
|
||||
validate_env_vars(char * const env_vars[])
|
||||
{
|
||||
char * const *ep;
|
||||
char *eq, *bad = NULL;
|
||||
size_t len, blen = 0, bsize = 0;
|
||||
bool okvar;
|
||||
bool okvar, rval = true;
|
||||
debug_decl(validate_env_vars, SUDO_DEBUG_ENV)
|
||||
|
||||
if (env_vars == NULL)
|
||||
return;
|
||||
debug_return_bool(true); /* nothing to do */
|
||||
|
||||
/* Add user-specified environment variables. */
|
||||
for (ep = env_vars; *ep != NULL; ep++) {
|
||||
@@ -1011,11 +1061,12 @@ validate_env_vars(char * const env_vars[])
|
||||
if (bad != NULL) {
|
||||
bad[blen - 2] = '\0'; /* remove trailing ", " */
|
||||
/* XXX - audit? */
|
||||
log_fatal(NO_MAIL,
|
||||
log_warning(NO_MAIL,
|
||||
N_("sorry, you are not allowed to set the following environment variables: %s"), bad);
|
||||
/* NOTREACHED */
|
||||
efree(bad);
|
||||
rval = false;
|
||||
}
|
||||
debug_return_bool(rval);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1028,15 +1079,20 @@ validate_env_vars(char * const env_vars[])
|
||||
* Invalid lines, blank lines, or lines consisting solely of a comment
|
||||
* character are skipped.
|
||||
*/
|
||||
void
|
||||
bool
|
||||
read_env_file(const char *path, int overwrite)
|
||||
{
|
||||
FILE *fp;
|
||||
bool rval = true;
|
||||
char *cp, *var, *val, *line = NULL;
|
||||
size_t var_len, val_len, linesize = 0;
|
||||
debug_decl(read_env_file, SUDO_DEBUG_ENV)
|
||||
|
||||
if ((fp = fopen(path, "r")) == NULL)
|
||||
return;
|
||||
if ((fp = fopen(path, "r")) == NULL) {
|
||||
if (errno != ENOENT)
|
||||
rval = false;
|
||||
debug_return_bool(rval);
|
||||
}
|
||||
|
||||
while (sudo_parseln(&line, &linesize, NULL, fp) != -1) {
|
||||
/* Skip blank or comment lines */
|
||||
@@ -1070,10 +1126,16 @@ read_env_file(const char *path, int overwrite)
|
||||
memcpy(cp, var, var_len + 1); /* includes '=' */
|
||||
memcpy(cp + var_len + 1, val, val_len + 1); /* includes NUL */
|
||||
|
||||
sudo_putenv(cp, true, overwrite);
|
||||
if (sudo_putenv(cp, true, overwrite) == -1) {
|
||||
/* XXX - no undo on failure */
|
||||
rval = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(line);
|
||||
fclose(fp);
|
||||
|
||||
debug_return_bool(rval);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -2082,10 +2082,13 @@ sudo_set_krb5_ccache_name(const char *name, const char **old_name)
|
||||
if (old_name != NULL)
|
||||
*old_name = sudo_getenv("KRB5CCNAME");
|
||||
}
|
||||
if (name != NULL && *name != '\0')
|
||||
sudo_setenv("KRB5CCNAME", name, true);
|
||||
else
|
||||
sudo_unsetenv("KRB5CCNAME");
|
||||
if (name != NULL && *name != '\0') {
|
||||
if (sudo_setenv("KRB5CCNAME", name, true) == -1)
|
||||
rc = -1;
|
||||
} else {
|
||||
if (sudo_unsetenv("KRB5CCNAME") == -1)
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
debug_return_int(rc);
|
||||
}
|
||||
@@ -2500,8 +2503,8 @@ sudo_ldap_open(struct sudo_nss *nss)
|
||||
|
||||
/* Prevent reading of user ldaprc and system defaults. */
|
||||
if (sudo_getenv("LDAPNOINIT") == NULL) {
|
||||
ldapnoinit = true;
|
||||
sudo_setenv("LDAPNOINIT", "1", true);
|
||||
if (sudo_setenv("LDAPNOINIT", "1", true) == 0)
|
||||
ldapnoinit = true;
|
||||
}
|
||||
|
||||
/* Set global LDAP options */
|
||||
@@ -2533,7 +2536,7 @@ sudo_ldap_open(struct sudo_nss *nss)
|
||||
goto done;
|
||||
|
||||
if (ldapnoinit)
|
||||
sudo_unsetenv("LDAPNOINIT");
|
||||
(void) sudo_unsetenv("LDAPNOINIT");
|
||||
|
||||
if (ldap_conf.ssl_mode == SUDO_LDAP_STARTTLS) {
|
||||
#if defined(HAVE_LDAP_START_TLS_S)
|
||||
|
@@ -364,7 +364,8 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
|
||||
def_env_reset = false;
|
||||
|
||||
/* Build a new environment that avoids any nasty bits. */
|
||||
rebuild_env();
|
||||
if (!rebuild_env())
|
||||
goto bad;
|
||||
|
||||
/* Require a password if sudoers says so. */
|
||||
rval = check_user(validated, sudo_mode);
|
||||
@@ -421,8 +422,10 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
|
||||
/* XXX - audit? */
|
||||
warningx(U_("sorry, you are not allowed to preserve the environment"));
|
||||
goto bad;
|
||||
} else
|
||||
validate_env_vars(sudo_user.env_vars);
|
||||
} else {
|
||||
if (!validate_env_vars(sudo_user.env_vars))
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
|
||||
if (ISSET(sudo_mode, (MODE_RUN | MODE_EDIT))) {
|
||||
@@ -489,7 +492,8 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
|
||||
|
||||
#if defined(_AIX) || (defined(__linux__) && !defined(HAVE_PAM))
|
||||
/* Insert system-wide environment variables. */
|
||||
read_env_file(_PATH_ENVIRONMENT, true);
|
||||
if (!read_env_file(_PATH_ENVIRONMENT, true))
|
||||
warning("%s", _PATH_ENVIRONMENT);
|
||||
#endif
|
||||
#ifdef HAVE_LOGIN_CAP_H
|
||||
/* Set environment based on login class. */
|
||||
@@ -504,11 +508,14 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
|
||||
}
|
||||
|
||||
/* Insert system-wide environment variables. */
|
||||
if (def_env_file)
|
||||
read_env_file(def_env_file, false);
|
||||
if (def_env_file) {
|
||||
if (!read_env_file(def_env_file, false))
|
||||
warning("%s", def_env_file);
|
||||
}
|
||||
|
||||
/* Insert user-specified environment variables. */
|
||||
insert_env_vars(sudo_user.env_vars);
|
||||
if (!insert_env_vars(sudo_user.env_vars))
|
||||
goto bad;
|
||||
|
||||
if (ISSET(sudo_mode, MODE_EDIT)) {
|
||||
efree(safe_cmnd);
|
||||
|
@@ -336,13 +336,13 @@ char *expand_iolog_path(const char *prefix, const char *dir, const char *file,
|
||||
|
||||
/* env.c */
|
||||
char **env_get(void);
|
||||
void env_merge(char * const envp[]);
|
||||
bool env_merge(char * const envp[]);
|
||||
void env_init(char * const envp[]);
|
||||
void init_envtables(void);
|
||||
void insert_env_vars(char * const envp[]);
|
||||
void read_env_file(const char *, int);
|
||||
void rebuild_env(void);
|
||||
void validate_env_vars(char * const envp[]);
|
||||
bool insert_env_vars(char * const envp[]);
|
||||
bool read_env_file(const char *, int);
|
||||
bool rebuild_env(void);
|
||||
bool validate_env_vars(char * const envp[]);
|
||||
int sudo_setenv(const char *var, const char *val, int overwrite);
|
||||
int sudo_unsetenv(const char *var);
|
||||
char *sudo_getenv(const char *name);
|
||||
|
Reference in New Issue
Block a user