X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=plugins%2Fsudoers%2Fenv.c;h=5e8822191b1a6bf4af7592f17ab7fb8465b95b34;hb=e8db7f6eea9b35527ddd4532affabd18a30549b5;hp=d678fa1fbc1601c9129e3b0104bdfc7f2806f252;hpb=98b9fd63cd28a3636a7cd24641b8f497eaadcd50;p=debian%2Fsudo diff --git a/plugins/sudoers/env.c b/plugins/sudoers/env.c index d678fa1..5e88221 100644 --- a/plugins/sudoers/env.c +++ b/plugins/sudoers/env.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2005, 2007-2011 + * Copyright (c) 2000-2005, 2007-2013 * Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any @@ -22,7 +22,6 @@ #include #include -#include #include #include #ifdef STDC_HEADERS @@ -286,12 +285,12 @@ sudo_putenv_nodebug(char *str, bool dupcheck, bool overwrite) size_t nsize; if (env.env_size > SIZE_MAX - 128) { - errorx2(1, _("internal error, %s overflow"), + fatalx_nodebug(_("internal error, %s overflow"), "sudo_putenv_nodebug()"); } nsize = env.env_size + 128; if (nsize > SIZE_MAX / sizeof(char *)) { - errorx2(1, _("internal error, %s overflow"), + fatalx_nodebug(_("internal error, %s overflow"), "sudo_putenv_nodebug()"); } nenvp = realloc(env.envp, nsize * sizeof(char *)); @@ -365,9 +364,9 @@ sudo_putenv(char *str, bool dupcheck, bool overwrite) if (rval == -1) { #ifdef ENV_DEBUG if (env.envp[env.env_len] != NULL) - errorx(1, _("sudo_putenv: corrupted envp, length mismatch")); + fatalx(_("sudo_putenv: corrupted envp, length mismatch")); #endif - errorx(1, _("unable to allocate memory")); + fatalx(NULL); } debug_return_int(rval); } @@ -393,7 +392,7 @@ sudo_setenv2(const char *var, const char *val, bool dupcheck, bool overwrite) strlcat(estring, "=", esize) >= esize || strlcat(estring, val, esize) >= esize) { - errorx(1, _("internal error, %s overflow"), "sudo_setenv2()"); + fatalx(_("internal error, %s overflow"), "sudo_setenv2()"); } rval = sudo_putenv(estring, dupcheck, overwrite); if (rval == -1) @@ -401,6 +400,15 @@ sudo_setenv2(const char *var, const char *val, bool dupcheck, bool overwrite) debug_return_int(rval); } +/* + * Similar to setenv(3) but operates on a private copy of the environment. + */ +int +sudo_setenv(const char *var, const char *val, int overwrite) +{ + return sudo_setenv2(var, val, true, (bool)overwrite); +} + /* * Similar to setenv(3) but operates on a private copy of the environment. * Does not include warnings or debugging to avoid recursive calls. @@ -408,49 +416,48 @@ sudo_setenv2(const char *var, const char *val, bool dupcheck, bool overwrite) static int sudo_setenv_nodebug(const char *var, const char *val, int overwrite) { - char *estring; + char *ep, *estring = NULL; + const char *cp; size_t esize; int rval = -1; - esize = strlen(var) + 1 + strlen(val) + 1; - if ((estring = malloc(esize)) == NULL) { - errno = ENOMEM; + if (var == NULL || *var == '\0') { + errno = EINVAL; goto done; } - /* Build environment string and insert it. */ - if (strlcpy(estring, var, esize) >= esize || - strlcat(estring, "=", esize) >= esize || - strlcat(estring, val, esize) >= esize) { + /* + * POSIX says a var name with '=' is an error but BSD + * just ignores the '=' and anything after it. + */ + for (cp = var; *cp && *cp != '='; cp++) + ; + esize = (size_t)(cp - var) + 2; + if (val) { + esize += strlen(val); /* glibc treats a NULL val as "" */ + } - errno = EINVAL; + /* Allocate and fill in estring. */ + if ((estring = ep = malloc(esize)) == NULL) { + errno = ENOMEM; goto done; } + for (cp = var; *cp && *cp != '='; cp++) + *ep++ = *cp; + *ep++ = '='; + if (val) { + for (cp = val; *cp; cp++) + *ep++ = *cp; + } + *ep = '\0'; + rval = sudo_putenv_nodebug(estring, true, overwrite); done: if (rval == -1) - efree(estring); + free(estring); return rval; } -/* - * Similar to setenv(3) but operates on a private copy of the environment. - */ -int -sudo_setenv(const char *var, const char *val, int overwrite) -{ - int rval; - debug_decl(sudo_setenv, SUDO_DEBUG_ENV) - - rval = sudo_setenv_nodebug(var, val, overwrite); - if (rval == -1) { - if (errno == EINVAL) - errorx(1, _("internal error, %s overflow"), "sudo_setenv()"); - errorx(1, _("unable to allocate memory")); - } - debug_return_int(rval); -} - /* * Similar to unsetenv(3) but operates on a private copy of the environment. * Does not include warnings or debugging to avoid recursive calls. @@ -1002,7 +1009,7 @@ validate_env_vars(char * const env_vars[]) if (bad != NULL) { bad[blen - 2] = '\0'; /* remove trailing ", " */ log_fatal(NO_MAIL, - _("sorry, you are not allowed to set the following environment variables: %s"), bad); + N_("sorry, you are not allowed to set the following environment variables: %s"), bad); /* NOTREACHED */ efree(bad); } @@ -1022,15 +1029,15 @@ void read_env_file(const char *path, int overwrite) { FILE *fp; - char *cp, *var, *val; - size_t var_len, val_len; + char *cp, *var, *val, *line = NULL; + size_t var_len, val_len, linesize = 0; if ((fp = fopen(path, "r")) == NULL) return; - while ((var = sudo_parseln(fp)) != NULL) { + while (sudo_parseln(&line, &linesize, NULL, fp) != -1) { /* Skip blank or comment lines */ - if (*var == '\0') + if (*(var = line) == '\0') continue; /* Skip optional "export " */ @@ -1062,6 +1069,7 @@ read_env_file(const char *path, int overwrite) sudo_putenv(cp, true, overwrite); } + free(line); fclose(fp); } @@ -1105,7 +1113,21 @@ sudoers_hook_getenv(const char *name, char **value, void *closure) return SUDO_HOOK_RET_NEXT; in_progress = true; + + /* Hack to make GNU gettext() find the sudoers locale when needed. */ + if (*name == 'L' && sudoers_getlocale() == SUDOERS_LOCALE_SUDOERS) { + if (strcmp(name, "LANGUAGE") == 0 || strcmp(name, "LANG") == 0) { + *value = NULL; + goto done; + } + if (strcmp(name, "LC_ALL") == 0 || strcmp(name, "LC_MESSAGES") == 0) { + *value = def_sudoers_locale; + goto done; + } + } + *value = sudo_getenv_nodebug(name); +done: in_progress = false; return SUDO_HOOK_RET_STOP; }