Diff for /embedaddon/sudo/plugins/sudoers/env.c between versions 1.1.1.3 and 1.1.1.6

version 1.1.1.3, 2012/10/09 09:29:52 version 1.1.1.6, 2014/06/15 16:12:54
Line 1 Line 1
 /*  /*
 * Copyright (c) 2000-2005, 2007-2011 * Copyright (c) 2000-2005, 2007-2013
  *      Todd C. Miller <Todd.Miller@courtesan.com>   *      Todd C. Miller <Todd.Miller@courtesan.com>
  *   *
  * Permission to use, copy, modify, and distribute this software for any   * Permission to use, copy, modify, and distribute this software for any
Line 22 Line 22
 #include <config.h>  #include <config.h>
   
 #include <sys/types.h>  #include <sys/types.h>
 #include <sys/param.h>  
 #include <sys/stat.h>  #include <sys/stat.h>
 #include <stdio.h>  #include <stdio.h>
 #ifdef STDC_HEADERS  #ifdef STDC_HEADERS
Line 286  sudo_putenv_nodebug(char *str, bool dupcheck, bool ove Line 285  sudo_putenv_nodebug(char *str, bool dupcheck, bool ove
         size_t nsize;          size_t nsize;
   
         if (env.env_size > SIZE_MAX - 128) {          if (env.env_size > SIZE_MAX - 128) {
            errorx2(1, _("internal error, %s overflow"),            fatalx_nodebug(U_("internal error, %s overflow"),
                 "sudo_putenv_nodebug()");                  "sudo_putenv_nodebug()");
         }          }
         nsize = env.env_size + 128;          nsize = env.env_size + 128;
         if (nsize > SIZE_MAX / sizeof(char *)) {          if (nsize > SIZE_MAX / sizeof(char *)) {
            errorx2(1, _("internal error, %s overflow"),            fatalx_nodebug(U_("internal error, %s overflow"),
                 "sudo_putenv_nodebug()");                  "sudo_putenv_nodebug()");
         }          }
         nenvp = realloc(env.envp, nsize * sizeof(char *));          nenvp = realloc(env.envp, nsize * sizeof(char *));
Line 365  sudo_putenv(char *str, bool dupcheck, bool overwrite) Line 364  sudo_putenv(char *str, bool dupcheck, bool overwrite)
     if (rval == -1) {      if (rval == -1) {
 #ifdef ENV_DEBUG  #ifdef ENV_DEBUG
         if (env.envp[env.env_len] != NULL)          if (env.envp[env.env_len] != NULL)
            errorx(1, _("sudo_putenv: corrupted envp, length mismatch"));            fatalx(U_("sudo_putenv: corrupted envp, length mismatch"));
 #endif  #endif
        errorx(1, _("unable to allocate memory"));        fatal(NULL);
     }      }
     debug_return_int(rval);      debug_return_int(rval);
 }  }
Line 393  sudo_setenv2(const char *var, const char *val, bool du Line 392  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, %s overflow"), "sudo_setenv2()");        fatalx(U_("internal error, %s overflow"), "sudo_setenv2()");
     }      }
     rval = sudo_putenv(estring, dupcheck, overwrite);      rval = sudo_putenv(estring, dupcheck, overwrite);
     if (rval == -1)      if (rval == -1)
Line 403  sudo_setenv2(const char *var, const char *val, bool du Line 402  sudo_setenv2(const char *var, const char *val, bool du
   
 /*  /*
  * Similar to setenv(3) but operates on a private copy of the environment.   * 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.   * Does not include warnings or debugging to avoid recursive calls.
  */   */
 static int  static int
 sudo_setenv_nodebug(const char *var, const char *val, int overwrite)  sudo_setenv_nodebug(const char *var, const char *val, int overwrite)
 {  {
    char *estring;    char *ep, *estring = NULL;
     const char *cp;
     size_t esize;      size_t esize;
     int rval = -1;      int rval = -1;
   
    esize = strlen(var) + 1 + strlen(val) + 1;    if (var == NULL || *var == '\0') {
    if ((estring = malloc(esize)) == NULL) {        errno = EINVAL;
        errno = ENOMEM; 
         goto done;          goto done;
     }      }
   
    /* Build environment string and insert it. */    /*
    if (strlcpy(estring, var, esize) >= esize ||     * POSIX says a var name with '=' is an error but BSD
        strlcat(estring, "=", esize) >= esize ||     * just ignores the '=' and anything after it.
        strlcat(estring, val, esize) >= esize) {     */
     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;          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);      rval = sudo_putenv_nodebug(estring, true, overwrite);
 done:  done:
     if (rval == -1)      if (rval == -1)
        efree(estring);        free(estring);
     return rval;      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.   * Similar to unsetenv(3) but operates on a private copy of the environment.
  * Does not include warnings or debugging to avoid recursive calls.   * Does not include warnings or debugging to avoid recursive calls.
  */   */
Line 538  sudo_getenv(const char *name) Line 545  sudo_getenv(const char *name)
 }  }
   
 /*  /*
  * Merge another environment with our private copy.  
  */  
 void  
 env_merge(char * const envp[], bool overwrite)  
 {  
     char * const *ep;  
     debug_decl(env_merge, SUDO_DEBUG_ENV)  
   
     for (ep = envp; *ep != NULL; ep++)  
         sudo_putenv(*ep, true, overwrite);  
   
     debug_return;  
 }  
   
 /*  
  * Check the env_delete blacklist.   * Check the env_delete blacklist.
  * Returns true if the variable was found, else false.   * Returns true if the variable was found, else false.
  */   */
Line 566  matches_env_delete(const char *var) Line 558  matches_env_delete(const char *var)
     debug_decl(matches_env_delete, SUDO_DEBUG_ENV)      debug_decl(matches_env_delete, SUDO_DEBUG_ENV)
   
     /* Skip anything listed in env_delete. */      /* Skip anything listed in env_delete. */
    for (cur = def_env_delete; cur; cur = cur->next) {    SLIST_FOREACH(cur, &def_env_delete, entries) {
         len = strlen(cur->value);          len = strlen(cur->value);
         /* Deal with '*' wildcard */          /* Deal with '*' wildcard */
         if (cur->value[len - 1] == '*') {          if (cur->value[len - 1] == '*') {
Line 597  matches_env_check(const char *var) Line 589  matches_env_check(const char *var)
     int keepit = -1;      int keepit = -1;
     debug_decl(matches_env_check, SUDO_DEBUG_ENV)      debug_decl(matches_env_check, SUDO_DEBUG_ENV)
   
    for (cur = def_env_check; cur; cur = cur->next) {    SLIST_FOREACH(cur, &def_env_check, entries) {
         len = strlen(cur->value);          len = strlen(cur->value);
         /* Deal with '*' wildcard */          /* Deal with '*' wildcard */
         if (cur->value[len - 1] == '*') {          if (cur->value[len - 1] == '*') {
Line 632  matches_env_keep(const char *var) Line 624  matches_env_keep(const char *var)
         goto done;          goto done;
     }      }
   
    for (cur = def_env_keep; cur; cur = cur->next) {    SLIST_FOREACH(cur, &def_env_keep, entries) {
         len = strlen(cur->value);          len = strlen(cur->value);
         /* Deal with '*' wildcard */          /* Deal with '*' wildcard */
         if (cur->value[len - 1] == '*') {          if (cur->value[len - 1] == '*') {
Line 688  env_should_keep(const char *var) Line 680  env_should_keep(const char *var)
     debug_return_bool(keepit == true);      debug_return_bool(keepit == true);
 }  }
   
   /*
    * Merge another environment with our private copy.
    * Only overwrite an existing variable if it is not
    * being preserved from the user's environment.
    */
   void
   env_merge(char * const envp[])
   {
       char * const *ep;
       debug_decl(env_merge, SUDO_DEBUG_ENV)
   
       for (ep = envp; *ep != NULL; ep++)
           sudo_putenv(*ep, true, !env_should_keep(*ep));
   
       debug_return;
   }
   
 static void  static void
 env_update_didvar(const char *ep, unsigned int *didvar)  env_update_didvar(const char *ep, unsigned int *didvar)
 {  {
Line 1002  validate_env_vars(char * const env_vars[]) Line 1011  validate_env_vars(char * const env_vars[])
     if (bad != NULL) {      if (bad != NULL) {
         bad[blen - 2] = '\0';           /* remove trailing ", " */          bad[blen - 2] = '\0';           /* remove trailing ", " */
         log_fatal(NO_MAIL,          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 */          /* NOTREACHED */
         efree(bad);          efree(bad);
     }      }
Line 1022  void Line 1031  void
 read_env_file(const char *path, int overwrite)  read_env_file(const char *path, int overwrite)
 {  {
     FILE *fp;      FILE *fp;
    char *cp, *var, *val;    char *cp, *var, *val, *line = NULL;
    size_t var_len, val_len;    size_t var_len, val_len, linesize = 0;
   
     if ((fp = fopen(path, "r")) == NULL)      if ((fp = fopen(path, "r")) == NULL)
         return;          return;
   
    while ((var = sudo_parseln(fp)) != NULL) {    while (sudo_parseln(&line, &linesize, NULL, fp) != -1) {
         /* Skip blank or comment lines */          /* Skip blank or comment lines */
        if (*var == '\0')        if (*(var = line) == '\0')
             continue;              continue;
   
         /* Skip optional "export " */          /* Skip optional "export " */
Line 1062  read_env_file(const char *path, int overwrite) Line 1071  read_env_file(const char *path, int overwrite)
   
         sudo_putenv(cp, true, overwrite);          sudo_putenv(cp, true, overwrite);
     }      }
       free(line);
     fclose(fp);      fclose(fp);
 }  }
   
Line 1075  init_envtables(void) Line 1085  init_envtables(void)
     for (p = initial_badenv_table; *p; p++) {      for (p = initial_badenv_table; *p; p++) {
         cur = ecalloc(1, sizeof(struct list_member));          cur = ecalloc(1, sizeof(struct list_member));
         cur->value = estrdup(*p);          cur->value = estrdup(*p);
        cur->next = def_env_delete;        SLIST_INSERT_HEAD(&def_env_delete, cur, entries);
        def_env_delete = cur; 
     }      }
   
     /* Fill in the "env_check" list. */      /* Fill in the "env_check" list. */
     for (p = initial_checkenv_table; *p; p++) {      for (p = initial_checkenv_table; *p; p++) {
         cur = ecalloc(1, sizeof(struct list_member));          cur = ecalloc(1, sizeof(struct list_member));
         cur->value = estrdup(*p);          cur->value = estrdup(*p);
        cur->next = def_env_check;        SLIST_INSERT_HEAD(&def_env_check, cur, entries);
        def_env_check = cur; 
     }      }
   
     /* Fill in the "env_keep" list. */      /* Fill in the "env_keep" list. */
     for (p = initial_keepenv_table; *p; p++) {      for (p = initial_keepenv_table; *p; p++) {
         cur = ecalloc(1, sizeof(struct list_member));          cur = ecalloc(1, sizeof(struct list_member));
         cur->value = estrdup(*p);          cur->value = estrdup(*p);
        cur->next = def_env_keep;        SLIST_INSERT_HEAD(&def_env_keep, cur, entries);
        def_env_keep = cur; 
     }      }
 }  }
   
Line 1105  sudoers_hook_getenv(const char *name, char **value, vo Line 1112  sudoers_hook_getenv(const char *name, char **value, vo
         return SUDO_HOOK_RET_NEXT;          return SUDO_HOOK_RET_NEXT;
   
     in_progress = true;      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);      *value = sudo_getenv_nodebug(name);
   done:
     in_progress = false;      in_progress = false;
     return SUDO_HOOK_RET_STOP;      return SUDO_HOOK_RET_STOP;
 }  }

Removed from v.1.1.1.3  
changed lines
  Added in v.1.1.1.6


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>