]> granicus.if.org Git - sudo/commitdiff
Replace the guts of sudo_setenv_nodebug() with our old setenv.c
authorTodd C. Miller <Todd.Miller@courtesan.com>
Sun, 16 Sep 2012 19:18:58 +0000 (15:18 -0400)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Sun, 16 Sep 2012 19:18:58 +0000 (15:18 -0400)
which supports non-standard BSD and glibc semantics.
sudo_setenv() now simply calls sudo_setenv2().

plugins/sudoers/env.c

index d678fa1fbc1601c9129e3b0104bdfc7f2806f252..b28f45eaf9a96a01a576da807e02fa8b2e422637 100644 (file)
@@ -401,6 +401,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 +417,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.