version 1.1.1.2, 2012/05/29 12:26:49
|
version 1.1.1.3, 2012/10/09 09:29:52
|
Line 42
|
Line 42
|
#ifdef HAVE_UNISTD_H |
#ifdef HAVE_UNISTD_H |
# include <unistd.h> |
# include <unistd.h> |
#endif /* HAVE_UNISTD_H */ |
#endif /* HAVE_UNISTD_H */ |
|
#ifdef HAVE_INTTYPES_H |
|
# include <inttypes.h> |
|
#endif |
#ifdef HAVE_LOGIN_CAP_H |
#ifdef HAVE_LOGIN_CAP_H |
# include <login_cap.h> |
# include <login_cap.h> |
# ifndef LOGIN_SETENV |
# ifndef LOGIN_SETENV |
Line 50
|
Line 53
|
#endif /* HAVE_LOGIN_CAP_H */ |
#endif /* HAVE_LOGIN_CAP_H */ |
#include <ctype.h> |
#include <ctype.h> |
#include <errno.h> |
#include <errno.h> |
|
#include <limits.h> |
#include <pwd.h> |
#include <pwd.h> |
|
|
#include "sudoers.h" |
#include "sudoers.h" |
|
|
/* |
/* |
|
* If there is no SIZE_MAX or SIZE_T_MAX we have to assume that size_t |
|
* could be signed (as it is on SunOS 4.x). This just means that |
|
* emalloc2() and erealloc3() cannot allocate huge amounts on such a |
|
* platform but that is OK since sudo doesn't need to do so anyway. |
|
*/ |
|
#ifndef SIZE_MAX |
|
# ifdef SIZE_T_MAX |
|
# define SIZE_MAX SIZE_T_MAX |
|
# else |
|
# define SIZE_MAX INT_MAX |
|
# endif /* SIZE_T_MAX */ |
|
#endif /* SIZE_MAX */ |
|
|
|
/* |
* Flags used in rebuild_env() |
* Flags used in rebuild_env() |
*/ |
*/ |
#undef DID_TERM |
#undef DID_TERM |
Line 229 env_init(char * const envp[])
|
Line 247 env_init(char * const envp[])
|
memset(env.envp, 0, env.env_size * sizeof(char *)); |
memset(env.envp, 0, env.env_size * sizeof(char *)); |
#endif |
#endif |
memcpy(env.envp, envp, len * sizeof(char *)); |
memcpy(env.envp, envp, len * sizeof(char *)); |
env.envp[len] = '\0'; | env.envp[len] = NULL; |
|
|
/* Free the old envp we allocated, if any. */ |
/* Free the old envp we allocated, if any. */ |
if (env.old_envp != NULL) |
if (env.old_envp != NULL) |
Line 263 sudo_putenv_nodebug(char *str, bool dupcheck, bool ove
|
Line 281 sudo_putenv_nodebug(char *str, bool dupcheck, bool ove
|
bool found = false; |
bool found = false; |
|
|
/* Make sure there is room for the new entry plus a NULL. */ |
/* Make sure there is room for the new entry plus a NULL. */ |
if (env.env_len + 2 > env.env_size) { | if (env.env_size > 2 && env.env_len > env.env_size - 2) { |
char **nenvp; |
char **nenvp; |
size_t nsize = env.env_size + 128; | size_t nsize; |
nenvp = env.envp ? realloc(env.envp, nsize * sizeof(char *)) : | |
malloc(nsize * sizeof(char *)); | if (env.env_size > SIZE_MAX - 128) { |
| errorx2(1, _("internal error, %s overflow"), |
| "sudo_putenv_nodebug()"); |
| } |
| nsize = env.env_size + 128; |
| if (nsize > SIZE_MAX / sizeof(char *)) { |
| errorx2(1, _("internal error, %s overflow"), |
| "sudo_putenv_nodebug()"); |
| } |
| nenvp = realloc(env.envp, nsize * sizeof(char *)); |
if (nenvp == NULL) { |
if (nenvp == NULL) { |
errno = ENOMEM; |
errno = ENOMEM; |
return -1; |
return -1; |
Line 289 sudo_putenv_nodebug(char *str, bool dupcheck, bool ove
|
Line 316 sudo_putenv_nodebug(char *str, bool dupcheck, bool ove
|
|
|
if (dupcheck) { |
if (dupcheck) { |
len = (strchr(str, '=') - str) + 1; |
len = (strchr(str, '=') - str) + 1; |
for (ep = env.envp; !found && *ep != NULL; ep++) { | for (ep = env.envp; *ep != NULL; ep++) { |
if (strncmp(str, *ep, len) == 0) { |
if (strncmp(str, *ep, len) == 0) { |
if (overwrite) |
if (overwrite) |
*ep = str; |
*ep = str; |
found = true; |
found = true; |
|
break; |
} |
} |
} |
} |
/* Prune out duplicate variables. */ | /* Prune out extra instances of the variable we just overwrote. */ |
if (found && overwrite) { |
if (found && overwrite) { |
while (*ep != NULL) { | while (*++ep != NULL) { |
if (strncmp(str, *ep, len) == 0) { |
if (strncmp(str, *ep, len) == 0) { |
char **cur = ep; |
char **cur = ep; |
while ((*cur = *(cur + 1)) != NULL) |
while ((*cur = *(cur + 1)) != NULL) |
cur++; |
cur++; |
} else { | ep--; |
ep++; | |
} |
} |
} |
} |
env.env_len = ep - env.envp; |
env.env_len = ep - env.envp; |
Line 332 sudo_putenv(char *str, bool dupcheck, bool overwrite)
|
Line 359 sudo_putenv(char *str, bool dupcheck, bool overwrite)
|
int rval; |
int rval; |
debug_decl(sudo_putenv, SUDO_DEBUG_ENV) |
debug_decl(sudo_putenv, SUDO_DEBUG_ENV) |
|
|
|
sudo_debug_printf(SUDO_DEBUG_INFO, "sudo_putenv: %s", str); |
|
|
rval = sudo_putenv_nodebug(str, dupcheck, overwrite); |
rval = sudo_putenv_nodebug(str, dupcheck, overwrite); |
if (rval == -1) { |
if (rval == -1) { |
#ifdef ENV_DEBUG |
#ifdef ENV_DEBUG |
Line 353 sudo_setenv2(const char *var, const char *val, bool du
|
Line 382 sudo_setenv2(const char *var, const char *val, bool du
|
{ |
{ |
char *estring; |
char *estring; |
size_t esize; |
size_t esize; |
|
int rval; |
debug_decl(sudo_setenv2, SUDO_DEBUG_ENV) |
debug_decl(sudo_setenv2, SUDO_DEBUG_ENV) |
|
|
esize = strlen(var) + 1 + strlen(val) + 1; |
esize = strlen(var) + 1 + strlen(val) + 1; |
Line 363 sudo_setenv2(const char *var, const char *val, bool du
|
Line 393 sudo_setenv2(const char *var, const char *val, bool du
|
strlcat(estring, "=", esize) >= esize || |
strlcat(estring, "=", esize) >= esize || |
strlcat(estring, val, esize) >= esize) { |
strlcat(estring, val, esize) >= esize) { |
|
|
errorx(1, _("internal error, sudo_setenv2() overflow")); | errorx(1, _("internal error, %s overflow"), "sudo_setenv2()"); |
} |
} |
debug_return_int(sudo_putenv(estring, dupcheck, overwrite)); | rval = sudo_putenv(estring, dupcheck, overwrite); |
| if (rval == -1) |
| efree(estring); |
| debug_return_int(rval); |
} |
} |
|
|
/* |
/* |
Line 377 sudo_setenv_nodebug(const char *var, const char *val,
|
Line 410 sudo_setenv_nodebug(const char *var, const char *val,
|
{ |
{ |
char *estring; |
char *estring; |
size_t esize; |
size_t esize; |
|
int rval = -1; |
|
|
esize = strlen(var) + 1 + strlen(val) + 1; |
esize = strlen(var) + 1 + strlen(val) + 1; |
if ((estring = malloc(esize)) == NULL) { |
if ((estring = malloc(esize)) == NULL) { |
errno = ENOMEM; |
errno = ENOMEM; |
return -1; | goto done; |
} |
} |
|
|
/* Build environment string and insert it. */ |
/* Build environment string and insert it. */ |
Line 390 sudo_setenv_nodebug(const char *var, const char *val,
|
Line 424 sudo_setenv_nodebug(const char *var, const char *val,
|
strlcat(estring, val, esize) >= esize) { |
strlcat(estring, val, esize) >= esize) { |
|
|
errno = EINVAL; |
errno = EINVAL; |
return -1; | goto done; |
} |
} |
return sudo_putenv_nodebug(estring, true, overwrite); | rval = sudo_putenv_nodebug(estring, true, overwrite); |
| done: |
| if (rval == -1) |
| efree(estring); |
| return rval; |
} |
} |
|
|
/* |
/* |
Line 407 sudo_setenv(const char *var, const char *val, int over
|
Line 445 sudo_setenv(const char *var, const char *val, int over
|
rval = sudo_setenv_nodebug(var, val, overwrite); |
rval = sudo_setenv_nodebug(var, val, overwrite); |
if (rval == -1) { |
if (rval == -1) { |
if (errno == EINVAL) |
if (errno == EINVAL) |
errorx(1, _("internal error, sudo_setenv() overflow")); | errorx(1, _("internal error, %s overflow"), "sudo_setenv()"); |
errorx(1, _("unable to allocate memory")); |
errorx(1, _("unable to allocate memory")); |
} |
} |
debug_return_int(rval); |
debug_return_int(rval); |
Line 452 sudo_unsetenv(const char *name)
|
Line 490 sudo_unsetenv(const char *name)
|
int rval; |
int rval; |
debug_decl(sudo_unsetenv, SUDO_DEBUG_ENV) |
debug_decl(sudo_unsetenv, SUDO_DEBUG_ENV) |
|
|
|
sudo_debug_printf(SUDO_DEBUG_INFO, "sudo_unsetenv: %s", name); |
|
|
rval = sudo_unsetenv_nodebug(name); |
rval = sudo_unsetenv_nodebug(name); |
|
|
debug_return_int(rval); |
debug_return_int(rval); |
Line 490 sudo_getenv(const char *name)
|
Line 530 sudo_getenv(const char *name)
|
char *val; |
char *val; |
debug_decl(sudo_getenv, SUDO_DEBUG_ENV) |
debug_decl(sudo_getenv, SUDO_DEBUG_ENV) |
|
|
|
sudo_debug_printf(SUDO_DEBUG_INFO, "sudo_getenv: %s", name); |
|
|
val = sudo_getenv_nodebug(name); |
val = sudo_getenv_nodebug(name); |
|
|
debug_return_str(val); |
debug_return_str(val); |
Line 621 env_should_delete(const char *var)
|
Line 663 env_should_delete(const char *var)
|
delete_it = matches_env_delete(var); |
delete_it = matches_env_delete(var); |
if (!delete_it) |
if (!delete_it) |
delete_it = matches_env_check(var) == false; |
delete_it = matches_env_check(var) == false; |
|
|
|
sudo_debug_printf(SUDO_DEBUG_INFO, "delete %s: %s", |
|
var, delete_it ? "YES" : "NO"); |
debug_return_bool(delete_it); |
debug_return_bool(delete_it); |
} |
} |
|
|
Line 638 env_should_keep(const char *var)
|
Line 683 env_should_keep(const char *var)
|
if (keepit == -1) |
if (keepit == -1) |
keepit = matches_env_keep(var); |
keepit = matches_env_keep(var); |
|
|
|
sudo_debug_printf(SUDO_DEBUG_INFO, "keep %s: %s", |
|
var, keepit ? "YES" : "NO"); |
debug_return_bool(keepit == true); |
debug_return_bool(keepit == true); |
} |
} |
|
|
Line 687 void
|
Line 734 void
|
rebuild_env(void) |
rebuild_env(void) |
{ |
{ |
char **old_envp, **ep, *cp, *ps1; |
char **old_envp, **ep, *cp, *ps1; |
char idbuf[MAX_UID_T_LEN]; | char idbuf[MAX_UID_T_LEN + 1]; |
unsigned int didvar; |
unsigned int didvar; |
bool reset_home = false; |
bool reset_home = false; |
|
|
Line 788 rebuild_env(void)
|
Line 835 rebuild_env(void)
|
} else { |
} else { |
if (!ISSET(didvar, DID_SHELL)) |
if (!ISSET(didvar, DID_SHELL)) |
sudo_setenv2("SHELL", sudo_user.pw->pw_shell, false, true); |
sudo_setenv2("SHELL", sudo_user.pw->pw_shell, false, true); |
if (!ISSET(didvar, DID_LOGNAME)) | /* We will set LOGNAME later in the !def_set_logname case. */ |
sudo_setenv2("LOGNAME", user_name, false, true); | if (!def_set_logname) { |
if (!ISSET(didvar, DID_USER)) | if (!ISSET(didvar, DID_LOGNAME)) |
sudo_setenv2("USER", user_name, false, true); | sudo_setenv2("LOGNAME", user_name, false, true); |
if (!ISSET(didvar, DID_USERNAME)) | if (!ISSET(didvar, DID_USER)) |
sudo_setenv2("USERNAME", user_name, false, true); | sudo_setenv2("USER", user_name, false, true); |
| if (!ISSET(didvar, DID_USERNAME)) |
| sudo_setenv2("USERNAME", user_name, false, true); |
| } |
} |
} |
|
|
/* If we didn't keep HOME, reset it based on target user. */ |
/* If we didn't keep HOME, reset it based on target user. */ |
Line 845 rebuild_env(void)
|
Line 895 rebuild_env(void)
|
/* |
/* |
* Set $USER, $LOGNAME and $USERNAME to target if "set_logname" is not |
* Set $USER, $LOGNAME and $USERNAME to target if "set_logname" is not |
* disabled. We skip this if we are running a login shell (because |
* disabled. We skip this if we are running a login shell (because |
* they have already been set them) or sudoedit (because we want the | * they have already been set) or sudoedit (because we want the editor |
* editor to find the user's startup files). | * 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|MODE_EDIT)) { |
if (!ISSET(didvar, KEPT_LOGNAME)) |
if (!ISSET(didvar, KEPT_LOGNAME)) |