From af9492d117cfc8025f82824805bcb0f19a5235fd Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Sun, 27 May 2012 12:48:55 -0400 Subject: [PATCH] Provide unhooked version of getenv() and use it when looking up DISPLAY and SUDO_ASKPASS in the environment. --- src/env_hooks.c | 149 +++++++++++++++++++++++++----------------------- src/sudo.h | 3 + src/tgetpass.c | 4 +- 3 files changed, 83 insertions(+), 73 deletions(-) diff --git a/src/env_hooks.c b/src/env_hooks.c index c518cb1bc..1e1db8cc0 100644 --- a/src/env_hooks.c +++ b/src/env_hooks.c @@ -69,6 +69,19 @@ rpl_getenv(const char *name) typedef char * (*sudo_fn_getenv_t)(const char *); +char * +getenv_unhooked(const char *name) +{ +#if defined(HAVE_DLOPEN) && defined(RTLD_NEXT) + sudo_fn_getenv_t fn; + + fn = (sudo_fn_getenv_t)dlsym(RTLD_NEXT, "getenv"); + if (fn != NULL) + return fn(name); +#endif /* HAVE_DLOPEN && RTLD_NEXT */ + return rpl_getenv(name); +} + char * getenv(const char *name) { @@ -79,16 +92,8 @@ getenv(const char *name) return val; case SUDO_HOOK_RET_ERROR: return NULL; - default: { -#if defined(HAVE_DLOPEN) && defined(RTLD_NEXT) - sudo_fn_getenv_t fn; - - fn = (sudo_fn_getenv_t)dlsym(RTLD_NEXT, "getenv"); - if (fn != NULL) - return fn(name); -#endif /* HAVE_DLOPEN && RTLD_NEXT */ - return rpl_getenv(name); - } + default: + return getenv_unhooked(name); } } @@ -136,6 +141,19 @@ rpl_putenv(PUTENV_CONST char *string) typedef int (*sudo_fn_putenv_t)(PUTENV_CONST char *); +static int +putenv_unhooked(PUTENV_CONST char *string) +{ +#if defined(HAVE_DLOPEN) && defined(RTLD_NEXT) + sudo_fn_putenv_t fn; + + fn = (sudo_fn_putenv_t)dlsym(RTLD_NEXT, "putenv"); + if (fn != NULL) + return fn(string); +#endif /* HAVE_DLOPEN && RTLD_NEXT */ + return rpl_putenv(string); +} + int putenv(PUTENV_CONST char *string) { @@ -144,16 +162,8 @@ putenv(PUTENV_CONST char *string) return 0; case SUDO_HOOK_RET_ERROR: return -1; - default: { -#if defined(HAVE_DLOPEN) && defined(RTLD_NEXT) - sudo_fn_putenv_t fn; - - fn = (sudo_fn_putenv_t)dlsym(RTLD_NEXT, "putenv"); - if (fn != NULL) - return fn(string); -#endif /* HAVE_DLOPEN && RTLD_NEXT */ - return rpl_putenv(string); - } + default: + return putenv_unhooked(string); } } @@ -201,6 +211,19 @@ rpl_setenv(const char *var, const char *val, int overwrite) typedef int (*sudo_fn_setenv_t)(const char *, const char *, int); +static int +setenv_unhooked(const char *var, const char *val, int overwrite) +{ +#if defined(HAVE_SETENV) && defined(HAVE_DLOPEN) && defined(RTLD_NEXT) + sudo_fn_setenv_t fn; + + fn = (sudo_fn_setenv_t)dlsym(RTLD_NEXT, "setenv"); + if (fn != NULL) + return fn(var, val, overwrite); +#endif /* HAVE_SETENV && HAVE_DLOPEN && RTLD_NEXT */ + return rpl_setenv(var, val, overwrite); +} + int setenv(const char *var, const char *val, int overwrite) { @@ -209,24 +232,12 @@ setenv(const char *var, const char *val, int overwrite) return 0; case SUDO_HOOK_RET_ERROR: return -1; - default: { -#if defined(HAVE_SETENV) && defined(HAVE_DLOPEN) && defined(RTLD_NEXT) - sudo_fn_setenv_t fn; - - fn = (sudo_fn_setenv_t)dlsym(RTLD_NEXT, "setenv"); - if (fn != NULL) - return fn(var, val, overwrite); -#endif /* HAVE_SETENV && HAVE_DLOPEN && RTLD_NEXT */ - return rpl_setenv(var, val, overwrite); - } + default: + return setenv_unhooked(var, val, overwrite); } } -#ifdef UNSETENV_VOID -static void -#else -int -#endif +static int rpl_unsetenv(const char *var) { char **ep = environ; @@ -234,11 +245,7 @@ rpl_unsetenv(const char *var) if (var == NULL || *var == '\0' || strchr(var, '=') != NULL) { errno = EINVAL; -#ifdef UNSETENV_VOID - return; -#else return -1; -#endif } len = strlen(var); @@ -253,9 +260,7 @@ rpl_unsetenv(const char *var) ep++; } } -#ifndef UNSETENV_VOID return 0; -#endif } #ifdef UNSETENV_VOID @@ -264,47 +269,49 @@ typedef void (*sudo_fn_unsetenv_t)(const char *); typedef int (*sudo_fn_unsetenv_t)(const char *); #endif -#ifdef UNSETENV_VOID -void -unsetenv(const char *var) +static int +unsetenv_unhooked(const char *var) { - switch (process_hooks_unsetenv(var)) { - case SUDO_HOOK_RET_STOP: - return 0; - case SUDO_HOOK_RET_ERROR: - return -1; - default: { + 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) - fn(var); - else + 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 */ - rpl_unsetenv(var); - } + { + rval = rpl_unsetenv(var); } + return rval; } + +#ifdef UNSETENV_VOID +void #else int +#endif unsetenv(const char *var) { + int rval; + switch (process_hooks_unsetenv(var)) { case SUDO_HOOK_RET_STOP: - return 0; + rval = 0; + break; 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) - return fn(var); -#endif /* HAVE_UNSETENV && HAVE_DLOPEN && RTLD_NEXT */ - return rpl_unsetenv(var); - } + rval = -1; + break; + default: + rval = unsetenv_unhooked(var); + break; } +#ifndef UNSETENV_VOID + return rval; +#endif } -#endif /* UNSETENV_VOID */ diff --git a/src/sudo.h b/src/sudo.h index 8843914b6..c50f1e1d6 100644 --- a/src/sudo.h +++ b/src/sudo.h @@ -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_unsetenv(const char *name); +/* env_hooks.c */ +char *getenv_unhooked(const char *name); + /* interfaces.c */ int get_net_ifs(char **addrinfo); diff --git a/src/tgetpass.c b/src/tgetpass.c index e9915b2bd..b23db4cc5 100644 --- a/src/tgetpass.c +++ b/src/tgetpass.c @@ -78,7 +78,7 @@ tgetpass(const char *prompt, int timeout, int flags) (void) fflush(stdout); if (askpass == NULL) { - askpass = getenv("SUDO_ASKPASS"); + askpass = getenv_unhooked("SUDO_ASKPASS"); if (askpass == NULL || *askpass == '\0') 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 (!ISSET(flags, TGP_STDIN|TGP_ECHO|TGP_ASKPASS|TGP_NOECHO_TRY) && !tty_present()) { - if (askpass == NULL || getenv("DISPLAY") == NULL) { + if (askpass == NULL || getenv_unhooked("DISPLAY") == NULL) { warningx(_("no tty present and no askpass program specified")); debug_return_str(NULL); } -- 2.40.0