Provide unhooked version of getenv() and use it when looking up

DISPLAY and SUDO_ASKPASS in the environment.
This commit is contained in:
Todd C. Miller
2012-05-27 12:48:55 -04:00
parent 7a6cad5026
commit af9492d117
3 changed files with 86 additions and 76 deletions

View File

@@ -70,16 +70,8 @@ rpl_getenv(const char *name)
typedef char * (*sudo_fn_getenv_t)(const char *); typedef char * (*sudo_fn_getenv_t)(const char *);
char * char *
getenv(const char *name) getenv_unhooked(const char *name)
{ {
char *val = NULL;
switch (process_hooks_getenv(name, &val)) {
case SUDO_HOOK_RET_STOP:
return val;
case SUDO_HOOK_RET_ERROR:
return NULL;
default: {
#if defined(HAVE_DLOPEN) && defined(RTLD_NEXT) #if defined(HAVE_DLOPEN) && defined(RTLD_NEXT)
sudo_fn_getenv_t fn; sudo_fn_getenv_t fn;
@@ -89,6 +81,19 @@ getenv(const char *name)
#endif /* HAVE_DLOPEN && RTLD_NEXT */ #endif /* HAVE_DLOPEN && RTLD_NEXT */
return rpl_getenv(name); return rpl_getenv(name);
} }
char *
getenv(const char *name)
{
char *val = NULL;
switch (process_hooks_getenv(name, &val)) {
case SUDO_HOOK_RET_STOP:
return val;
case SUDO_HOOK_RET_ERROR:
return NULL;
default:
return getenv_unhooked(name);
} }
} }
@@ -136,15 +141,9 @@ rpl_putenv(PUTENV_CONST char *string)
typedef int (*sudo_fn_putenv_t)(PUTENV_CONST char *); typedef int (*sudo_fn_putenv_t)(PUTENV_CONST char *);
int static int
putenv(PUTENV_CONST char *string) putenv_unhooked(PUTENV_CONST char *string)
{ {
switch (process_hooks_putenv((char *)string)) {
case SUDO_HOOK_RET_STOP:
return 0;
case SUDO_HOOK_RET_ERROR:
return -1;
default: {
#if defined(HAVE_DLOPEN) && defined(RTLD_NEXT) #if defined(HAVE_DLOPEN) && defined(RTLD_NEXT)
sudo_fn_putenv_t fn; sudo_fn_putenv_t fn;
@@ -154,6 +153,17 @@ putenv(PUTENV_CONST char *string)
#endif /* HAVE_DLOPEN && RTLD_NEXT */ #endif /* HAVE_DLOPEN && RTLD_NEXT */
return rpl_putenv(string); return rpl_putenv(string);
} }
int
putenv(PUTENV_CONST char *string)
{
switch (process_hooks_putenv((char *)string)) {
case SUDO_HOOK_RET_STOP:
return 0;
case SUDO_HOOK_RET_ERROR:
return -1;
default:
return putenv_unhooked(string);
} }
} }
@@ -201,15 +211,9 @@ rpl_setenv(const char *var, const char *val, int overwrite)
typedef int (*sudo_fn_setenv_t)(const char *, const char *, int); typedef int (*sudo_fn_setenv_t)(const char *, const char *, int);
int static int
setenv(const char *var, const char *val, int overwrite) setenv_unhooked(const char *var, const char *val, int overwrite)
{ {
switch (process_hooks_setenv(var, val, overwrite)) {
case SUDO_HOOK_RET_STOP:
return 0;
case SUDO_HOOK_RET_ERROR:
return -1;
default: {
#if defined(HAVE_SETENV) && defined(HAVE_DLOPEN) && defined(RTLD_NEXT) #if defined(HAVE_SETENV) && defined(HAVE_DLOPEN) && defined(RTLD_NEXT)
sudo_fn_setenv_t fn; sudo_fn_setenv_t fn;
@@ -219,14 +223,21 @@ setenv(const char *var, const char *val, int overwrite)
#endif /* HAVE_SETENV && HAVE_DLOPEN && RTLD_NEXT */ #endif /* HAVE_SETENV && HAVE_DLOPEN && RTLD_NEXT */
return rpl_setenv(var, val, overwrite); return rpl_setenv(var, val, overwrite);
} }
int
setenv(const char *var, const char *val, int overwrite)
{
switch (process_hooks_setenv(var, val, overwrite)) {
case SUDO_HOOK_RET_STOP:
return 0;
case SUDO_HOOK_RET_ERROR:
return -1;
default:
return setenv_unhooked(var, val, overwrite);
} }
} }
#ifdef UNSETENV_VOID static int
static void
#else
int
#endif
rpl_unsetenv(const char *var) rpl_unsetenv(const char *var)
{ {
char **ep = environ; char **ep = environ;
@@ -234,11 +245,7 @@ rpl_unsetenv(const char *var)
if (var == NULL || *var == '\0' || strchr(var, '=') != NULL) { if (var == NULL || *var == '\0' || strchr(var, '=') != NULL) {
errno = EINVAL; errno = EINVAL;
#ifdef UNSETENV_VOID
return;
#else
return -1; return -1;
#endif
} }
len = strlen(var); len = strlen(var);
@@ -253,9 +260,7 @@ rpl_unsetenv(const char *var)
ep++; ep++;
} }
} }
#ifndef UNSETENV_VOID
return 0; return 0;
#endif
} }
#ifdef UNSETENV_VOID #ifdef UNSETENV_VOID
@@ -264,47 +269,49 @@ typedef void (*sudo_fn_unsetenv_t)(const char *);
typedef int (*sudo_fn_unsetenv_t)(const char *); typedef int (*sudo_fn_unsetenv_t)(const char *);
#endif #endif
static int
unsetenv_unhooked(const char *var)
{
int rval = 0;
#if defined(HAVE_UNSETENV) && defined(HAVE_DLOPEN) && defined(RTLD_NEXT)
sudo_fn_unsetenv_t fn;
fn = (sudo_fn_unsetenv_t)dlsym(RTLD_NEXT, "unsetenv");
if (fn != NULL) {
# ifdef UNSETENV_VOID
fn(var);
# else
rval = fn(var);
# endif
} else
#endif /* HAVE_UNSETENV && HAVE_DLOPEN && RTLD_NEXT */
{
rval = rpl_unsetenv(var);
}
return rval;
}
#ifdef UNSETENV_VOID #ifdef UNSETENV_VOID
void void
unsetenv(const char *var)
{
switch (process_hooks_unsetenv(var)) {
case SUDO_HOOK_RET_STOP:
return 0;
case SUDO_HOOK_RET_ERROR:
return -1;
default: {
#if defined(HAVE_UNSETENV) && defined(HAVE_DLOPEN) && defined(RTLD_NEXT)
sudo_fn_unsetenv_t fn;
fn = (sudo_fn_unsetenv_t)dlsym(RTLD_NEXT, "unsetenv");
if (fn != NULL)
fn(var);
else
#endif /* HAVE_UNSETENV && HAVE_DLOPEN && RTLD_NEXT */
rpl_unsetenv(var);
}
}
}
#else #else
int int
#endif
unsetenv(const char *var) unsetenv(const char *var)
{ {
int rval;
switch (process_hooks_unsetenv(var)) { switch (process_hooks_unsetenv(var)) {
case SUDO_HOOK_RET_STOP: case SUDO_HOOK_RET_STOP:
return 0; rval = 0;
break;
case SUDO_HOOK_RET_ERROR: case SUDO_HOOK_RET_ERROR:
return -1; rval = -1;
default: { break;
#if defined(HAVE_UNSETENV) && defined(HAVE_DLOPEN) && defined(RTLD_NEXT) default:
sudo_fn_unsetenv_t fn; rval = unsetenv_unhooked(var);
break;
fn = (sudo_fn_unsetenv_t)dlsym(RTLD_NEXT, "unsetenv");
if (fn != NULL)
return fn(var);
#endif /* HAVE_UNSETENV && HAVE_DLOPEN && RTLD_NEXT */
return rpl_unsetenv(var);
} }
#ifndef UNSETENV_VOID
return rval;
#endif
} }
}
#endif /* UNSETENV_VOID */

View File

@@ -237,6 +237,9 @@ int process_hooks_setenv(const char *name, const char *value, int overwrite);
int process_hooks_putenv(char *string); int process_hooks_putenv(char *string);
int process_hooks_unsetenv(const char *name); int process_hooks_unsetenv(const char *name);
/* env_hooks.c */
char *getenv_unhooked(const char *name);
/* interfaces.c */ /* interfaces.c */
int get_net_ifs(char **addrinfo); int get_net_ifs(char **addrinfo);

View File

@@ -78,7 +78,7 @@ tgetpass(const char *prompt, int timeout, int flags)
(void) fflush(stdout); (void) fflush(stdout);
if (askpass == NULL) { if (askpass == NULL) {
askpass = getenv("SUDO_ASKPASS"); askpass = getenv_unhooked("SUDO_ASKPASS");
if (askpass == NULL || *askpass == '\0') if (askpass == NULL || *askpass == '\0')
askpass = sudo_conf_askpass_path(); askpass = sudo_conf_askpass_path();
} }
@@ -86,7 +86,7 @@ tgetpass(const char *prompt, int timeout, int flags)
/* If no tty present and we need to disable echo, try askpass. */ /* If no tty present and we need to disable echo, try askpass. */
if (!ISSET(flags, TGP_STDIN|TGP_ECHO|TGP_ASKPASS|TGP_NOECHO_TRY) && if (!ISSET(flags, TGP_STDIN|TGP_ECHO|TGP_ASKPASS|TGP_NOECHO_TRY) &&
!tty_present()) { !tty_present()) {
if (askpass == NULL || getenv("DISPLAY") == NULL) { if (askpass == NULL || getenv_unhooked("DISPLAY") == NULL) {
warningx(_("no tty present and no askpass program specified")); warningx(_("no tty present and no askpass program specified"));
debug_return_str(NULL); debug_return_str(NULL);
} }