2 * Copyright (c) 1989 - 1992, Julianne Frances Haugh
3 * Copyright (c) 1996 - 1999, Marek Michałkiewicz
4 * Copyright (c) 2003 - 2005, Tomasz Kłoczko
5 * Copyright (c) 2008 , Nicolas François
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the copyright holders or contributors may not be used to
17 * endorse or promote products derived from this software without
18 * specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 #include "prototypes.h"
43 * NEWENVP_STEP must be a power of two. This is the number
44 * of (char *) pointers to allocate at a time, to avoid using
45 * realloc() too often.
47 #define NEWENVP_STEP 16
49 char **newenvp = NULL;
50 extern char **environ;
52 static const char *forbid[] = {
54 "BASH_ENV=", /* GNU creeping featurism strikes again... */
59 "LD_", /* anything with the LD_ prefix */
69 /* these are allowed, but with no slashes inside
70 (to work around security problems in GNU gettext) */
71 static const char *noslash[] = {
74 "LC_", /* anything with the LC_ prefix */
79 * initenv() must be called once before using addenv().
83 newenvp = (char **) xmalloc (NEWENVP_STEP * sizeof (char *));
88 void addenv (const char *string, const char *value)
95 newstring = xmalloc (strlen (string) + strlen (value) + 2);
96 sprintf (newstring, "%s=%s", string, value);
98 newstring = xstrdup (string);
102 * Search for a '=' character within the string and if none is found
103 * just ignore the whole string.
106 cp = strchr (newstring, '=');
112 n = (size_t) (cp - newstring);
114 for (i = 0; i < newenvc; i++) {
115 if (strncmp (newstring, newenvp[i], n) == 0 &&
116 (newenvp[i][n] == '=' || newenvp[i][n] == '\0'))
122 newenvp[i] = newstring;
126 newenvp[newenvc++] = newstring;
129 * Check whether newenvc is a multiple of NEWENVP_STEP.
130 * If so we have to resize the vector.
131 * the expression (newenvc & (NEWENVP_STEP - 1)) == 0
132 * is equal to (newenvc % NEWENVP_STEP) == 0
133 * as long as NEWENVP_STEP is a power of 2.
136 if ((newenvc & (NEWENVP_STEP - 1)) == 0) {
141 * If the resize operation succeds we can
142 * happily go on, else print a message.
145 newsize = (newenvc + NEWENVP_STEP) * sizeof (char *);
146 __newenvp = (char **) realloc (newenvp, newsize);
150 * If this is our current environment, update
151 * environ so that it doesn't point to some
152 * free memory area (realloc() could move it).
154 if (environ == newenvp)
158 fputs (_("Environment overflow\n"), stderr);
159 free (newenvp[--newenvc]);
164 * The last entry of newenvp must be NULL
167 newenvp[newenvc] = NULL;
172 * set_env - copy command line arguments into the environment
174 void set_env (int argc, char *const *argv)
180 for (; argc > 0; argc--, argv++) {
181 if (strlen (*argv) >= sizeof variable)
182 continue; /* ignore long entries */
184 if (!(cp = strchr (*argv, '='))) {
185 snprintf (variable, sizeof variable, "L%d", noname++);
186 addenv (variable, *argv);
190 for (p = forbid; *p; p++)
191 if (strncmp (*argv, *p, strlen (*p)) == 0)
195 strncpy (variable, *argv, cp - *argv);
196 variable[cp - *argv] = '\0';
197 printf (_("You may not change $%s\n"),
202 addenv (*argv, NULL);
208 * sanitize_env - remove some nasty environment variables
209 * If you fall into a total paranoia, you should call this
210 * function for any root-setuid program or anything the user
211 * might change the environment with. 99% useless as almost
212 * all modern Unixes will handle setuid executables properly,
213 * but... I feel better with that silly precaution. -j.
216 void sanitize_env (void)
218 char **envp = environ;
223 for (cur = envp; *cur; cur++) {
224 for (bad = forbid; *bad; bad++) {
225 if (strncmp (*cur, *bad, strlen (*bad)) == 0) {
226 for (move = cur; *move; move++)
234 for (cur = envp; *cur; cur++) {
235 for (bad = noslash; *bad; bad++) {
236 if (strncmp (*cur, *bad, strlen (*bad)) != 0)
238 if (!strchr (*cur, '/'))
240 for (move = cur; *move; move++)