1
by Thom May
Import upstream version 1.6.7p5 |
1 |
/*
|
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
2 |
* Copyright (c) 2000-2005, 2007-2010
|
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
3 |
* Todd C. Miller <Todd.Miller@courtesan.com>
|
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
4 |
*
|
5 |
* Permission to use, copy, modify, and distribute this software for any
|
|
6 |
* purpose with or without fee is hereby granted, provided that the above
|
|
7 |
* copyright notice and this permission notice appear in all copies.
|
|
8 |
*
|
|
9 |
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10 |
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11 |
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12 |
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13 |
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14 |
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
15 |
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
1
by Thom May
Import upstream version 1.6.7p5 |
16 |
*
|
17 |
* Sponsored in part by the Defense Advanced Research Projects
|
|
18 |
* Agency (DARPA) and Air Force Research Laboratory, Air Force
|
|
19 |
* Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
|
20 |
*/
|
|
21 |
||
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
22 |
#include <config.h> |
1
by Thom May
Import upstream version 1.6.7p5 |
23 |
|
24 |
#include <sys/types.h> |
|
25 |
#include <sys/param.h> |
|
26 |
#include <sys/stat.h> |
|
27 |
#include <stdio.h> |
|
28 |
#ifdef STDC_HEADERS
|
|
29 |
# include <stdlib.h>
|
|
30 |
# include <stddef.h>
|
|
31 |
#else
|
|
32 |
# ifdef HAVE_STDLIB_H
|
|
33 |
# include <stdlib.h>
|
|
34 |
# endif
|
|
35 |
#endif /* STDC_HEADERS */ |
|
36 |
#ifdef HAVE_STRING_H
|
|
37 |
# include <string.h>
|
|
38 |
#endif /* HAVE_STRING_H */ |
|
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
39 |
#ifdef HAVE_STRINGS_H
|
40 |
# include <strings.h>
|
|
41 |
#endif /* HAVE_STRINGS_H */ |
|
1
by Thom May
Import upstream version 1.6.7p5 |
42 |
#ifdef HAVE_UNISTD_H
|
43 |
# include <unistd.h>
|
|
44 |
#endif /* HAVE_UNISTD_H */ |
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
45 |
#include <ctype.h> |
46 |
#include <errno.h> |
|
1
by Thom May
Import upstream version 1.6.7p5 |
47 |
#include <pwd.h> |
48 |
||
49 |
#include "sudo.h" |
|
50 |
||
51 |
/*
|
|
52 |
* Flags used in rebuild_env()
|
|
53 |
*/
|
|
54 |
#undef DID_TERM
|
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
55 |
#define DID_TERM 0x0001
|
1
by Thom May
Import upstream version 1.6.7p5 |
56 |
#undef DID_PATH
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
57 |
#define DID_PATH 0x0002
|
1
by Thom May
Import upstream version 1.6.7p5 |
58 |
#undef DID_HOME
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
59 |
#define DID_HOME 0x0004
|
1
by Thom May
Import upstream version 1.6.7p5 |
60 |
#undef DID_SHELL
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
61 |
#define DID_SHELL 0x0008
|
1
by Thom May
Import upstream version 1.6.7p5 |
62 |
#undef DID_LOGNAME
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
63 |
#define DID_LOGNAME 0x0010
|
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
64 |
#undef DID_USER
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
65 |
#define DID_USER 0x0020
|
66 |
#undef DID_USERNAME
|
|
67 |
#define DID_USERNAME 0x0040
|
|
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
68 |
#undef DID_MAIL
|
69 |
#define DID_MAIL 0x0080
|
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
70 |
#undef DID_MAX
|
71 |
#define DID_MAX 0x00ff
|
|
72 |
||
73 |
#undef KEPT_TERM
|
|
74 |
#define KEPT_TERM 0x0100
|
|
75 |
#undef KEPT_PATH
|
|
76 |
#define KEPT_PATH 0x0200
|
|
77 |
#undef KEPT_HOME
|
|
78 |
#define KEPT_HOME 0x0400
|
|
79 |
#undef KEPT_SHELL
|
|
80 |
#define KEPT_SHELL 0x0800
|
|
81 |
#undef KEPT_LOGNAME
|
|
82 |
#define KEPT_LOGNAME 0x1000
|
|
83 |
#undef KEPT_USER
|
|
84 |
#define KEPT_USER 0x2000
|
|
85 |
#undef KEPT_USERNAME
|
|
86 |
#define KEPT_USERNAME 0x4000
|
|
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
87 |
#undef KEPT_MAIL
|
88 |
#define KEPT_MAIL 0x8000
|
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
89 |
#undef KEPT_MAX
|
90 |
#define KEPT_MAX 0xff00
|
|
1
by Thom May
Import upstream version 1.6.7p5 |
91 |
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
92 |
struct environment { |
93 |
char **envp; /* pointer to the new environment */ |
|
94 |
size_t env_size; /* size of new_environ in char **'s */ |
|
95 |
size_t env_len; /* number of slots used, not counting NULL */ |
|
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
96 |
int owned; /* do we own envp or is it the system's? */ |
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
97 |
};
|
98 |
||
1
by Thom May
Import upstream version 1.6.7p5 |
99 |
/*
|
100 |
* Prototypes
|
|
101 |
*/
|
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
102 |
static void sudo_setenv __P((const char *, const char *, int)); |
103 |
static void sudo_putenv __P((char *, int, int)); |
|
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
104 |
|
105 |
extern char **environ; /* global environment */ |
|
1
by Thom May
Import upstream version 1.6.7p5 |
106 |
|
107 |
/*
|
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
108 |
* Copy of the sudo-managed environment.
|
109 |
*/
|
|
110 |
static struct environment env; |
|
111 |
||
112 |
/*
|
|
1
by Thom May
Import upstream version 1.6.7p5 |
113 |
* Default table of "bad" variables to remove from the environment.
|
114 |
* XXX - how to omit TERMCAP if it starts with '/'?
|
|
115 |
*/
|
|
116 |
static const char *initial_badenv_table[] = { |
|
117 |
"IFS", |
|
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
118 |
"CDPATH", |
5
by Martin Pitt
Revert addition of sudo -t, i. e. revert to version 1.6.8p9-3ubuntu1. As |
119 |
"SHELLOPTS", |
120 |
"PS4", |
|
1
by Thom May
Import upstream version 1.6.7p5 |
121 |
"LOCALDOMAIN", |
122 |
"RES_OPTIONS", |
|
123 |
"HOSTALIASES", |
|
124 |
"NLSPATH", |
|
125 |
"PATH_LOCALE", |
|
126 |
"LD_*", |
|
127 |
"_RLD*", |
|
128 |
#ifdef __hpux
|
|
129 |
"SHLIB_PATH", |
|
130 |
#endif /* __hpux */ |
|
131 |
#ifdef _AIX
|
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
132 |
"LDR_*", |
1
by Thom May
Import upstream version 1.6.7p5 |
133 |
"LIBPATH", |
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
134 |
"AUTHSTATE", |
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
135 |
#endif
|
1
by Thom May
Import upstream version 1.6.7p5 |
136 |
#ifdef __APPLE__
|
137 |
"DYLD_*", |
|
138 |
#endif
|
|
139 |
#ifdef HAVE_KERB4
|
|
140 |
"KRB_CONF*", |
|
141 |
"KRBCONFDIR", |
|
142 |
"KRBTKFILE", |
|
143 |
#endif /* HAVE_KERB4 */ |
|
144 |
#ifdef HAVE_KERB5
|
|
145 |
"KRB5_CONFIG*", |
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
146 |
"KRB5_KTNAME", |
1
by Thom May
Import upstream version 1.6.7p5 |
147 |
#endif /* HAVE_KERB5 */ |
148 |
#ifdef HAVE_SECURID
|
|
149 |
"VAR_ACE", |
|
150 |
"USR_ACE", |
|
151 |
"DLC_ACE", |
|
152 |
#endif /* HAVE_SECURID */ |
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
153 |
"TERMINFO", /* terminfo, exclusive path to terminfo files */ |
154 |
"TERMINFO_DIRS", /* terminfo, path(s) to terminfo files */ |
|
155 |
"TERMPATH", /* termcap, path(s) to termcap files */ |
|
1
by Thom May
Import upstream version 1.6.7p5 |
156 |
"TERMCAP", /* XXX - only if it starts with '/' */ |
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
157 |
"ENV", /* ksh, file to source before script runs */ |
158 |
"BASH_ENV", /* bash, file to source before script runs */ |
|
159 |
"PS4", /* bash, prefix for lines in xtrace mode */ |
|
160 |
"GLOBIGNORE", /* bash, globbing patterns to ignore */ |
|
161 |
"SHELLOPTS", /* bash, extra command line options */ |
|
162 |
"JAVA_TOOL_OPTIONS", /* java, extra command line options */ |
|
163 |
"PERLIO_DEBUG ", /* perl, debugging output file */ |
|
164 |
"PERLLIB", /* perl, search path for modules/includes */ |
|
165 |
"PERL5LIB", /* perl 5, search path for modules/includes */ |
|
166 |
"PERL5OPT", /* perl 5, extra command line options */ |
|
167 |
"PERL5DB", /* perl 5, command used to load debugger */ |
|
168 |
"FPATH", /* ksh, search path for functions */ |
|
169 |
"NULLCMD", /* zsh, command for null file redirection */ |
|
170 |
"READNULLCMD", /* zsh, command for null file redirection */ |
|
171 |
"ZDOTDIR", /* zsh, search path for dot files */ |
|
172 |
"TMPPREFIX", /* zsh, prefix for temporary files */ |
|
173 |
"PYTHONHOME", /* python, module search path */ |
|
174 |
"PYTHONPATH", /* python, search path */ |
|
175 |
"PYTHONINSPECT", /* python, allow inspection */ |
|
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
176 |
"PYTHONUSERBASE", /* python, per user site-packages directory */ |
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
177 |
"RUBYLIB", /* ruby, library load path */ |
178 |
"RUBYOPT", /* ruby, extra command line options */ |
|
1
by Thom May
Import upstream version 1.6.7p5 |
179 |
NULL
|
180 |
};
|
|
181 |
||
182 |
/*
|
|
183 |
* Default table of variables to check for '%' and '/' characters.
|
|
184 |
*/
|
|
185 |
static const char *initial_checkenv_table[] = { |
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
186 |
"COLORTERM", |
1
by Thom May
Import upstream version 1.6.7p5 |
187 |
"LANG", |
188 |
"LANGUAGE", |
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
189 |
"LC_*", |
190 |
"LINGUAS", |
|
6
by Martin Pitt
sudo.c: If the user successfully authenticated and he is in the 'admin' |
191 |
"TERM", |
1
by Thom May
Import upstream version 1.6.7p5 |
192 |
NULL
|
193 |
};
|
|
194 |
||
195 |
/*
|
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
196 |
* Default table of variables to preserve in the environment.
|
1
by Thom May
Import upstream version 1.6.7p5 |
197 |
*/
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
198 |
static const char *initial_keepenv_table[] = { |
199 |
"COLORS", |
|
10
by Martin Pitt
env.c: Preserve additional environment variables for non-almighty sudoers: |
200 |
"DISPLAY", |
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
201 |
"HOSTNAME", |
202 |
"KRB5CCNAME", |
|
203 |
"LS_COLORS", |
|
204 |
"PATH", |
|
205 |
"PS1", |
|
206 |
"PS2", |
|
207 |
"TZ", |
|
10
by Martin Pitt
env.c: Preserve additional environment variables for non-almighty sudoers: |
208 |
"XAUTHORITY", |
209 |
"XAUTHORIZATION", |
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
210 |
NULL
|
211 |
};
|
|
1
by Thom May
Import upstream version 1.6.7p5 |
212 |
|
213 |
/*
|
|
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
214 |
* Initialize env based on envp.
|
215 |
*/
|
|
216 |
void
|
|
217 |
env_init(lazy) |
|
218 |
int lazy; |
|
219 |
{
|
|
220 |
char * const *ep; |
|
221 |
size_t len; |
|
222 |
||
223 |
for (ep = environ; *ep != NULL; ep++) |
|
224 |
continue; |
|
225 |
len = (size_t)(ep - environ); |
|
226 |
||
227 |
if (lazy) { |
|
228 |
/*
|
|
229 |
* If we are already initialized due to lazy init (usualy via getenv())
|
|
230 |
* we need to avoid calling malloc() as it may call getenv() itself.
|
|
231 |
*/
|
|
232 |
env.envp = environ; |
|
233 |
env.env_len = len; |
|
234 |
env.env_size = len; |
|
235 |
} else if (!env.owned) { |
|
236 |
env.env_len = len; |
|
237 |
env.env_size = len + 1 + 128; |
|
238 |
env.envp = emalloc2(env.env_size, sizeof(char *)); |
|
239 |
#ifdef ENV_DEBUG
|
|
240 |
memset(env.envp, 0, env.env_size * sizeof(char *)); |
|
241 |
#endif
|
|
242 |
memcpy(env.envp, environ, len * sizeof(char *)); |
|
243 |
env.envp[len] = '\0'; |
|
244 |
env.owned = TRUE; |
|
245 |
}
|
|
246 |
}
|
|
247 |
||
248 |
char ** |
|
249 |
env_get() |
|
250 |
{
|
|
251 |
return env.envp; |
|
252 |
}
|
|
253 |
||
254 |
/*
|
|
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
255 |
* Similar to setenv(3) but operates on sudo's private copy of the environment
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
256 |
* (not environ) and it always overwrites. The dupcheck param determines
|
257 |
* whether we need to verify that the variable is not already set.
|
|
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
258 |
*/
|
259 |
static void |
|
260 |
sudo_setenv(var, val, dupcheck) |
|
261 |
const char *var; |
|
262 |
const char *val; |
|
263 |
int dupcheck; |
|
264 |
{
|
|
265 |
char *estring; |
|
266 |
size_t esize; |
|
267 |
||
268 |
esize = strlen(var) + 1 + strlen(val) + 1; |
|
269 |
estring = emalloc(esize); |
|
270 |
||
271 |
/* Build environment string and insert it. */
|
|
272 |
if (strlcpy(estring, var, esize) >= esize || |
|
273 |
strlcat(estring, "=", esize) >= esize || |
|
274 |
strlcat(estring, val, esize) >= esize) { |
|
275 |
||
276 |
errorx(1, "internal error, sudo_setenv() overflow"); |
|
277 |
}
|
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
278 |
sudo_putenv(estring, dupcheck, TRUE); |
279 |
}
|
|
280 |
||
281 |
/*
|
|
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
282 |
* Version of getenv(3) that uses our own environ pointer.
|
283 |
*/
|
|
284 |
char * |
|
285 |
getenv(var) |
|
286 |
const char *var; |
|
287 |
{
|
|
288 |
char *cp, **ev; |
|
289 |
size_t vlen = strlen(var); |
|
290 |
||
291 |
if (env.envp == NULL) |
|
292 |
env_init(TRUE); |
|
293 |
||
294 |
for (ev = env.envp; (cp = *ev) != NULL; ev++) { |
|
295 |
if (strncmp(var, cp, vlen) == 0 && cp[vlen] == '=') |
|
296 |
return cp + vlen + 1; |
|
297 |
}
|
|
298 |
return NULL; |
|
299 |
}
|
|
300 |
||
301 |
/*
|
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
302 |
* Version of setenv(3) that uses our own environ pointer.
|
303 |
*/
|
|
304 |
int
|
|
305 |
setenv(var, val, overwrite) |
|
306 |
const char *var; |
|
307 |
const char *val; |
|
308 |
int overwrite; |
|
309 |
{
|
|
310 |
char *estring, *ep; |
|
311 |
const char *cp; |
|
312 |
size_t esize; |
|
313 |
||
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
314 |
if (!var || *var == '\0') { |
315 |
errno = EINVAL; |
|
316 |
return(-1); |
|
317 |
}
|
|
318 |
||
319 |
if (env.envp == NULL) |
|
320 |
env_init(TRUE); |
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
321 |
|
322 |
/*
|
|
323 |
* POSIX says a var name with '=' is an error but BSD
|
|
324 |
* just ignores the '=' and anything after it.
|
|
325 |
*/
|
|
326 |
for (cp = var; *cp && *cp != '='; cp++) |
|
327 |
;
|
|
328 |
esize = (size_t)(cp - var) + 2; |
|
329 |
if (val) { |
|
330 |
esize += strlen(val); /* glibc treats a NULL val as "" */ |
|
331 |
}
|
|
332 |
||
333 |
/* Allocate and fill in estring. */
|
|
334 |
estring = ep = emalloc(esize); |
|
335 |
for (cp = var; *cp && *cp != '='; cp++) |
|
336 |
*ep++ = *cp; |
|
337 |
*ep++ = '='; |
|
338 |
if (val) { |
|
339 |
for (cp = val; *cp; cp++) |
|
340 |
*ep++ = *cp; |
|
341 |
}
|
|
342 |
*ep = '\0'; |
|
343 |
||
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
344 |
#ifdef ENV_DEBUG
|
345 |
if (env.envp[env.env_len] != NULL) |
|
346 |
errorx(1, "setenv: corrupted envp, len mismatch"); |
|
347 |
#endif
|
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
348 |
sudo_putenv(estring, TRUE, overwrite); |
349 |
return(0); |
|
350 |
}
|
|
351 |
||
352 |
/*
|
|
353 |
* Version of unsetenv(3) that uses our own environ pointer.
|
|
354 |
*/
|
|
355 |
#ifdef UNSETENV_VOID
|
|
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
356 |
void
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
357 |
#else
|
358 |
int
|
|
359 |
#endif
|
|
360 |
unsetenv(var) |
|
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
361 |
const char *var; |
362 |
{
|
|
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
363 |
char **ep; |
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
364 |
size_t len; |
365 |
||
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
366 |
if (var == NULL || *var == '\0' || strchr(var, '=') != NULL) { |
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
367 |
errno = EINVAL; |
368 |
#ifdef UNSETENV_VOID
|
|
369 |
return; |
|
370 |
#else
|
|
371 |
return(-1); |
|
372 |
#endif
|
|
373 |
}
|
|
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
374 |
|
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
375 |
if (env.envp == NULL) |
376 |
env_init(TRUE); |
|
377 |
||
378 |
#ifdef ENV_DEBUG
|
|
379 |
if (env.envp[env.env_len] != NULL) |
|
380 |
errorx(1, "unsetenv: corrupted envp, len mismatch"); |
|
381 |
#endif
|
|
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
382 |
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
383 |
len = strlen(var); |
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
384 |
for (ep = env.envp; *ep != NULL;) { |
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
385 |
if (strncmp(var, *ep, len) == 0 && (*ep)[len] == '=') { |
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
386 |
/* Found it; shift remainder + NULL over by one. */
|
387 |
char **cur = ep; |
|
388 |
while ((*cur = *(cur + 1)) != NULL) |
|
389 |
cur++; |
|
1.4.4
by Bdale Garbee
Import upstream version 1.7.2p7 |
390 |
/* Keep going, could be multiple instances of the var. */
|
391 |
} else { |
|
392 |
ep++; |
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
393 |
}
|
394 |
}
|
|
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
395 |
env.env_len = ep - env.envp; |
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
396 |
#ifndef UNSETENV_VOID
|
397 |
return(0); |
|
398 |
#endif
|
|
399 |
}
|
|
400 |
||
401 |
/*
|
|
402 |
* Version of putenv(3) that uses our own environ pointer.
|
|
403 |
*/
|
|
404 |
int
|
|
405 |
#ifdef PUTENV_CONST
|
|
406 |
putenv(const char *string) |
|
407 |
#else
|
|
408 |
putenv(string) |
|
409 |
char *string; |
|
410 |
#endif
|
|
411 |
{
|
|
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
412 |
if (env.envp == NULL) |
413 |
env_init(TRUE); |
|
414 |
||
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
415 |
if (strchr(string, '=') == NULL) { |
416 |
errno = EINVAL; |
|
417 |
return(-1); |
|
418 |
}
|
|
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
419 |
#ifdef ENV_DEBUG
|
420 |
if (env.envp[env.env_len] != NULL) |
|
421 |
errorx(1, "putenv: corrupted envp, len mismatch"); |
|
422 |
#endif
|
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
423 |
sudo_putenv((char *)string, TRUE, TRUE); |
424 |
return(0); |
|
425 |
}
|
|
426 |
||
427 |
/*
|
|
428 |
* Similar to putenv(3) but operates on sudo's private copy of the
|
|
429 |
* environment (not environ) and it always overwrites. The dupcheck param
|
|
430 |
* determines whether we need to verify that the variable is not already set.
|
|
431 |
* Will only overwrite an existing variable if overwrite is set.
|
|
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
432 |
*/
|
433 |
static void |
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
434 |
sudo_putenv(str, dupcheck, overwrite) |
1
by Thom May
Import upstream version 1.6.7p5 |
435 |
char *str; |
436 |
int dupcheck; |
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
437 |
int overwrite; |
1
by Thom May
Import upstream version 1.6.7p5 |
438 |
{
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
439 |
char **ep; |
440 |
size_t len; |
|
1.4.4
by Bdale Garbee
Import upstream version 1.7.2p7 |
441 |
int found = FALSE; |
1
by Thom May
Import upstream version 1.6.7p5 |
442 |
|
443 |
/* Make sure there is room for the new entry plus a NULL. */
|
|
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
444 |
if (env.env_len + 2 > env.env_size) { |
445 |
env.env_size += 128; |
|
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
446 |
if (env.owned) { |
447 |
env.envp = erealloc3(env.envp, env.env_size, sizeof(char *)); |
|
448 |
} else { |
|
449 |
/* We don't own env.envp, allocate a new one. */
|
|
450 |
ep = emalloc2(env.env_size, sizeof(char *)); |
|
451 |
memcpy(ep, env.envp, env.env_size * sizeof(char *)); |
|
452 |
env.envp = ep; |
|
453 |
env.owned = TRUE; |
|
454 |
}
|
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
455 |
#ifdef ENV_DEBUG
|
456 |
memset(env.envp + env.env_len, 0, |
|
457 |
(env.env_size - env.env_len) * sizeof(char *)); |
|
458 |
#endif
|
|
1
by Thom May
Import upstream version 1.6.7p5 |
459 |
}
|
460 |
||
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
461 |
#ifdef ENV_DEBUG
|
462 |
if (env.envp[env.env_len] != NULL) |
|
463 |
errorx(1, "sudo_putenv: corrupted envp, len mismatch"); |
|
464 |
#endif
|
|
465 |
||
1
by Thom May
Import upstream version 1.6.7p5 |
466 |
if (dupcheck) { |
1.4.4
by Bdale Garbee
Import upstream version 1.7.2p7 |
467 |
len = (strchr(str, '=') - str) + 1; |
468 |
for (ep = env.envp; !found && *ep != NULL; ep++) { |
|
469 |
if (strncmp(str, *ep, len) == 0) { |
|
470 |
if (overwrite) |
|
471 |
*ep = str; |
|
472 |
found = TRUE; |
|
473 |
}
|
|
474 |
}
|
|
475 |
/* Prune out duplicate variables. */
|
|
476 |
if (found && overwrite) { |
|
477 |
while (*ep != NULL) { |
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
478 |
if (strncmp(str, *ep, len) == 0) { |
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
479 |
char **cur = ep; |
480 |
while ((*cur = *(cur + 1)) != NULL) |
|
481 |
cur++; |
|
1.4.4
by Bdale Garbee
Import upstream version 1.7.2p7 |
482 |
} else { |
483 |
ep++; |
|
1
by Thom May
Import upstream version 1.6.7p5 |
484 |
}
|
485 |
}
|
|
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
486 |
env.env_len = ep - env.envp; |
1.4.4
by Bdale Garbee
Import upstream version 1.7.2p7 |
487 |
}
|
488 |
}
|
|
489 |
||
490 |
if (!found) { |
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
491 |
ep = env.envp + env.env_len; |
1.4.4
by Bdale Garbee
Import upstream version 1.7.2p7 |
492 |
env.env_len++; |
493 |
*ep++ = str; |
|
494 |
*ep = NULL; |
|
495 |
}
|
|
1
by Thom May
Import upstream version 1.6.7p5 |
496 |
}
|
497 |
||
498 |
/*
|
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
499 |
* Check the env_delete blacklist.
|
500 |
* Returns TRUE if the variable was found, else false.
|
|
501 |
*/
|
|
502 |
static int |
|
503 |
matches_env_delete(var) |
|
504 |
const char *var; |
|
505 |
{
|
|
506 |
struct list_member *cur; |
|
507 |
size_t len; |
|
508 |
int iswild, match = FALSE; |
|
509 |
||
510 |
/* Skip anything listed in env_delete. */
|
|
511 |
for (cur = def_env_delete; cur; cur = cur->next) { |
|
512 |
len = strlen(cur->value); |
|
513 |
/* Deal with '*' wildcard */
|
|
514 |
if (cur->value[len - 1] == '*') { |
|
515 |
len--; |
|
516 |
iswild = TRUE; |
|
517 |
} else |
|
518 |
iswild = FALSE; |
|
519 |
if (strncmp(cur->value, var, len) == 0 && |
|
520 |
(iswild || var[len] == '=')) { |
|
521 |
match = TRUE; |
|
522 |
break; |
|
523 |
}
|
|
524 |
}
|
|
525 |
return(match); |
|
526 |
}
|
|
527 |
||
528 |
/*
|
|
529 |
* Apply the env_check list.
|
|
530 |
* Returns TRUE if the variable is allowed, FALSE if denied
|
|
531 |
* or -1 if no match.
|
|
532 |
*/
|
|
533 |
static int |
|
534 |
matches_env_check(var) |
|
535 |
const char *var; |
|
536 |
{
|
|
537 |
struct list_member *cur; |
|
538 |
size_t len; |
|
539 |
int iswild, keepit = -1; |
|
540 |
||
541 |
for (cur = def_env_check; cur; cur = cur->next) { |
|
542 |
len = strlen(cur->value); |
|
543 |
/* Deal with '*' wildcard */
|
|
544 |
if (cur->value[len - 1] == '*') { |
|
545 |
len--; |
|
546 |
iswild = TRUE; |
|
547 |
} else |
|
548 |
iswild = FALSE; |
|
549 |
if (strncmp(cur->value, var, len) == 0 && |
|
550 |
(iswild || var[len] == '=')) { |
|
551 |
keepit = !strpbrk(var, "/%"); |
|
552 |
break; |
|
553 |
}
|
|
554 |
}
|
|
555 |
return(keepit); |
|
556 |
}
|
|
557 |
||
558 |
/*
|
|
559 |
* Check the env_keep list.
|
|
560 |
* Returns TRUE if the variable is allowed else FALSE.
|
|
561 |
*/
|
|
562 |
static int |
|
563 |
matches_env_keep(var) |
|
564 |
const char *var; |
|
565 |
{
|
|
566 |
struct list_member *cur; |
|
567 |
size_t len; |
|
568 |
int iswild, keepit = FALSE; |
|
569 |
||
570 |
for (cur = def_env_keep; cur; cur = cur->next) { |
|
571 |
len = strlen(cur->value); |
|
572 |
/* Deal with '*' wildcard */
|
|
573 |
if (cur->value[len - 1] == '*') { |
|
574 |
len--; |
|
575 |
iswild = TRUE; |
|
576 |
} else |
|
577 |
iswild = FALSE; |
|
578 |
if (strncmp(cur->value, var, len) == 0 && |
|
579 |
(iswild || var[len] == '=')) { |
|
580 |
keepit = TRUE; |
|
581 |
break; |
|
582 |
}
|
|
583 |
}
|
|
584 |
return(keepit); |
|
585 |
}
|
|
586 |
||
587 |
/*
|
|
1
by Thom May
Import upstream version 1.6.7p5 |
588 |
* Build a new environment and ether clear potentially dangerous
|
589 |
* variables from the old one or start with a clean slate.
|
|
590 |
* Also adds sudo-specific variables (SUDO_*).
|
|
591 |
*/
|
|
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
592 |
void
|
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
593 |
rebuild_env(noexec) |
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
594 |
int noexec; |
1
by Thom May
Import upstream version 1.6.7p5 |
595 |
{
|
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
596 |
char **old_envp, **ep, *cp, *ps1; |
597 |
char idbuf[MAX_UID_T_LEN]; |
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
598 |
unsigned int didvar; |
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
599 |
int reset_home = FALSE; |
1
by Thom May
Import upstream version 1.6.7p5 |
600 |
|
601 |
/*
|
|
602 |
* Either clean out the environment or reset to a safe default.
|
|
603 |
*/
|
|
604 |
ps1 = NULL; |
|
605 |
didvar = 0; |
|
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
606 |
env.env_len = 0; |
607 |
env.env_size = 128; |
|
608 |
old_envp = env.envp; |
|
609 |
env.envp = emalloc2(env.env_size, sizeof(char *)); |
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
610 |
#ifdef ENV_DEBUG
|
611 |
memset(env.envp, 0, env.env_size * sizeof(char *)); |
|
612 |
#endif
|
|
1.3.10
by Bdale Garbee
* patch from upstream to resolve problem always prompting for a password |
613 |
|
614 |
/* Reset HOME based on target user if configured to. */
|
|
615 |
if (ISSET(sudo_mode, MODE_RUN)) { |
|
616 |
if (def_always_set_home || |
|
617 |
ISSET(sudo_mode, MODE_RESET_HOME | MODE_LOGIN_SHELL) || |
|
618 |
(ISSET(sudo_mode, MODE_SHELL) && def_set_home)) |
|
619 |
reset_home = TRUE; |
|
620 |
}
|
|
621 |
||
1.2.6
by Martin Pitt
Import upstream version 1.6.9p17 |
622 |
if (def_env_reset || ISSET(sudo_mode, MODE_LOGIN_SHELL)) { |
1
by Thom May
Import upstream version 1.6.7p5 |
623 |
/* Pull in vars we want to keep from the old environment. */
|
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
624 |
for (ep = old_envp; *ep; ep++) { |
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
625 |
int keepit; |
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
626 |
|
627 |
/* Skip variables with values beginning with () (bash functions) */
|
|
628 |
if ((cp = strchr(*ep, '=')) != NULL) { |
|
629 |
if (strncmp(cp, "=() ", 3) == 0) |
|
630 |
continue; |
|
631 |
}
|
|
632 |
||
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
633 |
/*
|
634 |
* First check certain variables for '%' and '/' characters.
|
|
635 |
* If no match there, check the keep list.
|
|
636 |
* If nothing matched, we remove it from the environment.
|
|
637 |
*/
|
|
638 |
keepit = matches_env_check(*ep); |
|
639 |
if (keepit == -1) |
|
640 |
keepit = matches_env_keep(*ep); |
|
1
by Thom May
Import upstream version 1.6.7p5 |
641 |
|
1.1.4
by Bdale Garbee
* patch from Petter Reinholdtsen for the LSB info block in the init.d |
642 |
if (!strncmp (*ep, "DISPLAY=",8) |
643 |
|| !strncmp (*ep, "XAUTHORITY=", 11) |
|
644 |
|| !strncmp (*ep, "XAUTHORIZATION=", 15) |
|
16
by Martin Pitt
* Merge to Debian unstable. Remaining Ubuntu changes: |
645 |
|| !strncmp (*ep, "XAPPLRESDIR=", 12) |
646 |
|| !strncmp (*ep, "XFILESEARCHPATH=", 16) |
|
647 |
|| !strncmp (*ep, "XUSERFILESEARCHPATH=", 20) |
|
1.1.4
by Bdale Garbee
* patch from Petter Reinholdtsen for the LSB info block in the init.d |
648 |
|| !strncmp (*ep, "LANG=", 5) |
649 |
|| !strncmp (*ep, "LANGUAGE=", 9) |
|
650 |
|| !strncmp (*ep, "LC_", 3)) |
|
651 |
keepit = 1; |
|
652 |
||
1
by Thom May
Import upstream version 1.6.7p5 |
653 |
/* For SUDO_PS1 -> PS1 conversion. */
|
654 |
if (strncmp(*ep, "SUDO_PS1=", 8) == 0) |
|
655 |
ps1 = *ep + 5; |
|
656 |
||
657 |
if (keepit) { |
|
658 |
/* Preserve variable. */
|
|
659 |
switch (**ep) { |
|
660 |
case 'H': |
|
661 |
if (strncmp(*ep, "HOME=", 5) == 0) |
|
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
662 |
SET(didvar, DID_HOME); |
1
by Thom May
Import upstream version 1.6.7p5 |
663 |
break; |
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
664 |
case 'L': |
665 |
if (strncmp(*ep, "LOGNAME=", 8) == 0) |
|
666 |
SET(didvar, DID_LOGNAME); |
|
667 |
break; |
|
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
668 |
case 'M': |
669 |
if (strncmp(*ep, "MAIL=", 5) == 0) |
|
670 |
SET(didvar, DID_MAIL); |
|
671 |
break; |
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
672 |
case 'P': |
673 |
if (strncmp(*ep, "PATH=", 5) == 0) |
|
674 |
SET(didvar, DID_PATH); |
|
675 |
break; |
|
1
by Thom May
Import upstream version 1.6.7p5 |
676 |
case 'S': |
677 |
if (strncmp(*ep, "SHELL=", 6) == 0) |
|
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
678 |
SET(didvar, DID_SHELL); |
1
by Thom May
Import upstream version 1.6.7p5 |
679 |
break; |
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
680 |
case 'T': |
681 |
if (strncmp(*ep, "TERM=", 5) == 0) |
|
682 |
SET(didvar, DID_TERM); |
|
1
by Thom May
Import upstream version 1.6.7p5 |
683 |
break; |
684 |
case 'U': |
|
685 |
if (strncmp(*ep, "USER=", 5) == 0) |
|
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
686 |
SET(didvar, DID_USER); |
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
687 |
if (strncmp(*ep, "USERNAME=", 5) == 0) |
688 |
SET(didvar, DID_USERNAME); |
|
1
by Thom May
Import upstream version 1.6.7p5 |
689 |
break; |
690 |
}
|
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
691 |
sudo_putenv(*ep, FALSE, FALSE); |
1
by Thom May
Import upstream version 1.6.7p5 |
692 |
}
|
693 |
}
|
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
694 |
didvar |= didvar << 8; /* convert DID_* to KEPT_* */ |
1
by Thom May
Import upstream version 1.6.7p5 |
695 |
|
696 |
/*
|
|
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
697 |
* Add in defaults. In -i mode these come from the runas user,
|
698 |
* otherwise they may be from the user's environment (depends
|
|
699 |
* on sudoers options).
|
|
1
by Thom May
Import upstream version 1.6.7p5 |
700 |
*/
|
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
701 |
if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) { |
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
702 |
sudo_setenv("SHELL", runas_pw->pw_shell, ISSET(didvar, DID_SHELL)); |
703 |
sudo_setenv("LOGNAME", runas_pw->pw_name, |
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
704 |
ISSET(didvar, DID_LOGNAME)); |
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
705 |
sudo_setenv("USER", runas_pw->pw_name, ISSET(didvar, DID_USER)); |
706 |
sudo_setenv("USERNAME", runas_pw->pw_name, |
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
707 |
ISSET(didvar, DID_USERNAME)); |
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
708 |
} else { |
709 |
if (!ISSET(didvar, DID_SHELL)) |
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
710 |
sudo_setenv("SHELL", sudo_user.pw->pw_shell, FALSE); |
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
711 |
if (!ISSET(didvar, DID_LOGNAME)) |
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
712 |
sudo_setenv("LOGNAME", user_name, FALSE); |
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
713 |
if (!ISSET(didvar, DID_USER)) |
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
714 |
sudo_setenv("USER", user_name, FALSE); |
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
715 |
if (!ISSET(didvar, DID_USERNAME)) |
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
716 |
sudo_setenv("USERNAME", user_name, FALSE); |
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
717 |
}
|
1.3.10
by Bdale Garbee
* patch from upstream to resolve problem always prompting for a password |
718 |
|
719 |
/* If we didn't keep HOME, reset it based on target user. */
|
|
720 |
if (!ISSET(didvar, KEPT_HOME)) |
|
721 |
reset_home = TRUE; |
|
722 |
||
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
723 |
/*
|
724 |
* Set MAIL to target user in -i mode or if MAIL is not preserved
|
|
725 |
* from user's environment.
|
|
726 |
*/
|
|
727 |
if (ISSET(sudo_mode, MODE_LOGIN_SHELL) || !ISSET(didvar, KEPT_MAIL)) { |
|
728 |
cp = _PATH_MAILDIR; |
|
729 |
if (cp[sizeof(_PATH_MAILDIR) - 2] == '/') |
|
730 |
easprintf(&cp, "MAIL=%s%s", _PATH_MAILDIR, runas_pw->pw_name); |
|
731 |
else
|
|
732 |
easprintf(&cp, "MAIL=%s/%s", _PATH_MAILDIR, runas_pw->pw_name); |
|
733 |
sudo_putenv(cp, ISSET(didvar, DID_MAIL), TRUE); |
|
734 |
}
|
|
1
by Thom May
Import upstream version 1.6.7p5 |
735 |
} else { |
736 |
/*
|
|
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
737 |
* Copy environ entries as long as they don't match env_delete or
|
1
by Thom May
Import upstream version 1.6.7p5 |
738 |
* env_check.
|
739 |
*/
|
|
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
740 |
for (ep = old_envp; *ep; ep++) { |
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
741 |
int okvar; |
1
by Thom May
Import upstream version 1.6.7p5 |
742 |
|
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
743 |
/* Skip variables with values beginning with () (bash functions) */
|
744 |
if ((cp = strchr(*ep, '=')) != NULL) { |
|
745 |
if (strncmp(cp, "=() ", 3) == 0) |
|
746 |
continue; |
|
747 |
}
|
|
748 |
||
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
749 |
/*
|
750 |
* First check variables against the blacklist in env_delete.
|
|
751 |
* If no match there check for '%' and '/' characters.
|
|
752 |
*/
|
|
753 |
okvar = matches_env_delete(*ep) != TRUE; |
|
754 |
if (okvar) |
|
755 |
okvar = matches_env_check(*ep) != FALSE; |
|
9
by Martin Pitt
* env.c: Unbreak the env_keep option. Closes: LP#31690 |
756 |
|
1
by Thom May
Import upstream version 1.6.7p5 |
757 |
if (okvar) { |
758 |
if (strncmp(*ep, "SUDO_PS1=", 9) == 0) |
|
759 |
ps1 = *ep + 5; |
|
760 |
else if (strncmp(*ep, "PATH=", 5) == 0) |
|
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
761 |
SET(didvar, DID_PATH); |
1
by Thom May
Import upstream version 1.6.7p5 |
762 |
else if (strncmp(*ep, "TERM=", 5) == 0) |
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
763 |
SET(didvar, DID_TERM); |
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
764 |
sudo_putenv(*ep, FALSE, FALSE); |
1
by Thom May
Import upstream version 1.6.7p5 |
765 |
}
|
766 |
}
|
|
767 |
}
|
|
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
768 |
/* Replace the PATH envariable with a secure one? */
|
769 |
if (def_secure_path && !user_is_exempt()) { |
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
770 |
sudo_setenv("PATH", def_secure_path, TRUE); |
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
771 |
SET(didvar, DID_PATH); |
772 |
}
|
|
773 |
||
774 |
/* Set $USER, $LOGNAME and $USERNAME to target if "set_logname" is true. */
|
|
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
775 |
if (def_set_logname && !ISSET(sudo_mode, MODE_LOGIN_SHELL)) { |
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
776 |
if (!ISSET(didvar, KEPT_LOGNAME)) |
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
777 |
sudo_setenv("LOGNAME", runas_pw->pw_name, TRUE); |
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
778 |
if (!ISSET(didvar, KEPT_USER)) |
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
779 |
sudo_setenv("USER", runas_pw->pw_name, TRUE); |
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
780 |
if (!ISSET(didvar, KEPT_USERNAME)) |
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
781 |
sudo_setenv("USERNAME", runas_pw->pw_name, TRUE); |
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
782 |
}
|
783 |
||
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
784 |
/* Set $HOME to target user if not preserving user's value. */
|
1.3.10
by Bdale Garbee
* patch from upstream to resolve problem always prompting for a password |
785 |
if (reset_home) |
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
786 |
sudo_setenv("HOME", runas_pw->pw_dir, TRUE); |
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
787 |
|
1
by Thom May
Import upstream version 1.6.7p5 |
788 |
/* Provide default values for $TERM and $PATH if they are not set. */
|
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
789 |
if (!ISSET(didvar, DID_TERM)) |
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
790 |
sudo_putenv("TERM=unknown", FALSE, FALSE); |
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
791 |
if (!ISSET(didvar, DID_PATH)) |
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
792 |
sudo_setenv("PATH", _PATH_STDPATH, FALSE); |
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
793 |
|
794 |
/*
|
|
795 |
* Preload a noexec file? For a list of LD_PRELOAD-alikes, see
|
|
796 |
* http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html
|
|
797 |
* XXX - should prepend to original value, if any
|
|
798 |
*/
|
|
1.1.2
by Martin Pitt
Import upstream version 1.6.8p9 |
799 |
if (noexec && def_noexec_file != NULL) { |
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
800 |
#if defined(__darwin__) || defined(__APPLE__)
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
801 |
sudo_setenv("DYLD_INSERT_LIBRARIES", def_noexec_file, TRUE); |
802 |
sudo_setenv("DYLD_FORCE_FLAT_NAMESPACE", "", TRUE); |
|
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
803 |
#else
|
804 |
# if defined(__osf__) || defined(__sgi)
|
|
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
805 |
easprintf(&cp, "%s:DEFAULT", def_noexec_file); |
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
806 |
sudo_setenv("_RLD_LIST", cp, TRUE); |
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
807 |
efree(cp); |
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
808 |
# else
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
809 |
# ifdef _AIX
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
810 |
sudo_setenv("LDR_PRELOAD", def_noexec_file, TRUE); |
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
811 |
# else
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
812 |
sudo_setenv("LD_PRELOAD", def_noexec_file, TRUE); |
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
813 |
# endif /* _AIX */ |
814 |
# endif /* __osf__ || __sgi */ |
|
815 |
#endif /* __darwin__ || __APPLE__ */ |
|
1.1.2
by Martin Pitt
Import upstream version 1.6.8p9 |
816 |
}
|
1
by Thom May
Import upstream version 1.6.7p5 |
817 |
|
818 |
/* Set PS1 if SUDO_PS1 is set. */
|
|
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
819 |
if (ps1 != NULL) |
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
820 |
sudo_putenv(ps1, TRUE, TRUE); |
1
by Thom May
Import upstream version 1.6.7p5 |
821 |
|
822 |
/* Add the SUDO_COMMAND envariable (cmnd + args). */
|
|
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
823 |
if (user_args) { |
824 |
easprintf(&cp, "%s %s", user_cmnd, user_args); |
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
825 |
sudo_setenv("SUDO_COMMAND", cp, TRUE); |
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
826 |
efree(cp); |
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
827 |
} else { |
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
828 |
sudo_setenv("SUDO_COMMAND", user_cmnd, TRUE); |
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
829 |
}
|
1
by Thom May
Import upstream version 1.6.7p5 |
830 |
|
831 |
/* Add the SUDO_USER, SUDO_UID, SUDO_GID environment variables. */
|
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
832 |
sudo_setenv("SUDO_USER", user_name, TRUE); |
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
833 |
snprintf(idbuf, sizeof(idbuf), "%lu", (unsigned long) user_uid); |
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
834 |
sudo_setenv("SUDO_UID", idbuf, TRUE); |
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
835 |
snprintf(idbuf, sizeof(idbuf), "%lu", (unsigned long) user_gid); |
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
836 |
sudo_setenv("SUDO_GID", idbuf, TRUE); |
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
837 |
|
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
838 |
/* Free old environment. */
|
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
839 |
efree(old_envp); |
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
840 |
}
|
841 |
||
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
842 |
void
|
843 |
insert_env_vars(env_vars) |
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
844 |
struct list_member *env_vars; |
845 |
{
|
|
846 |
struct list_member *cur; |
|
847 |
||
848 |
/* Add user-specified environment variables. */
|
|
849 |
for (cur = env_vars; cur != NULL; cur = cur->next) |
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
850 |
putenv(cur->value); |
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
851 |
}
|
852 |
||
853 |
/*
|
|
854 |
* Validate the list of environment variables passed in on the command
|
|
855 |
* line against env_delete, env_check, and env_keep.
|
|
856 |
* Calls log_error() if any specified variables are not allowed.
|
|
857 |
*/
|
|
858 |
void
|
|
859 |
validate_env_vars(env_vars) |
|
860 |
struct list_member *env_vars; |
|
861 |
{
|
|
862 |
struct list_member *var; |
|
863 |
char *eq, *bad = NULL; |
|
864 |
size_t len, blen = 0, bsize = 0; |
|
865 |
int okvar; |
|
866 |
||
1.4.5
by Bdale Garbee
Import upstream version 1.7.4p4 |
867 |
/* Add user-specified environment variables. */
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
868 |
for (var = env_vars; var != NULL; var = var->next) { |
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
869 |
if (def_secure_path && !user_is_exempt() && |
870 |
strncmp(var->value, "PATH=", 5) == 0) { |
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
871 |
okvar = FALSE; |
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
872 |
} else if (def_env_reset) { |
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
873 |
okvar = matches_env_check(var->value); |
874 |
if (okvar == -1) |
|
875 |
okvar = matches_env_keep(var->value); |
|
876 |
} else { |
|
877 |
okvar = matches_env_delete(var->value) == FALSE; |
|
878 |
if (okvar == FALSE) |
|
879 |
okvar = matches_env_check(var->value) != FALSE; |
|
880 |
}
|
|
881 |
if (okvar == FALSE) { |
|
882 |
/* Not allowed, add to error string, allocating as needed. */
|
|
883 |
if ((eq = strchr(var->value, '=')) != NULL) |
|
884 |
*eq = '\0'; |
|
885 |
len = strlen(var->value) + 2; |
|
886 |
if (blen + len >= bsize) { |
|
887 |
do { |
|
888 |
bsize += 1024; |
|
889 |
} while (blen + len >= bsize); |
|
890 |
bad = erealloc(bad, bsize); |
|
891 |
bad[blen] = '\0'; |
|
892 |
}
|
|
893 |
strlcat(bad, var->value, bsize); |
|
894 |
strlcat(bad, ", ", bsize); |
|
895 |
blen += len; |
|
896 |
if (eq != NULL) |
|
897 |
*eq = '='; |
|
898 |
}
|
|
899 |
}
|
|
900 |
if (bad != NULL) { |
|
901 |
bad[blen - 2] = '\0'; /* remove trailing ", " */ |
|
902 |
log_error(NO_MAIL, |
|
903 |
"sorry, you are not allowed to set the following environment variables: %s", bad); |
|
904 |
/* NOTREACHED */
|
|
905 |
efree(bad); |
|
906 |
}
|
|
1
by Thom May
Import upstream version 1.6.7p5 |
907 |
}
|
908 |
||
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
909 |
/*
|
910 |
* Read in /etc/environment ala AIX and Linux.
|
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
911 |
* Lines may be in either of three formats:
|
912 |
* NAME=VALUE
|
|
913 |
* NAME="VALUE"
|
|
914 |
* NAME='VALUE'
|
|
915 |
* with an optional "export" prefix so the shell can source the file.
|
|
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
916 |
* Invalid lines, blank lines, or lines consisting solely of a comment
|
917 |
* character are skipped.
|
|
918 |
*/
|
|
919 |
void
|
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
920 |
read_env_file(path, overwrite) |
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
921 |
const char *path; |
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
922 |
int overwrite; |
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
923 |
{
|
924 |
FILE *fp; |
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
925 |
char *cp, *var, *val; |
926 |
size_t var_len, val_len; |
|
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
927 |
|
928 |
if ((fp = fopen(path, "r")) == NULL) |
|
929 |
return; |
|
930 |
||
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
931 |
while ((var = sudo_parseln(fp)) != NULL) { |
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
932 |
/* Skip blank or comment lines */
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
933 |
if (*var == '\0') |
934 |
continue; |
|
935 |
||
936 |
/* Skip optional "export " */
|
|
937 |
if (strncmp(var, "export", 6) == 0 && isspace((unsigned char) var[6])) { |
|
938 |
var += 7; |
|
939 |
while (isspace((unsigned char) *var)) { |
|
940 |
var++; |
|
941 |
}
|
|
942 |
}
|
|
943 |
||
944 |
/* Must be of the form name=["']value['"] */
|
|
945 |
for (val = var; *val != '\0' && *val != '='; val++) |
|
946 |
;
|
|
947 |
if (var == val || *val != '=') |
|
948 |
continue; |
|
949 |
var_len = (size_t)(val - var); |
|
950 |
val_len = strlen(++val); |
|
30
by Loïc Minier
env.c: add logic similar to pam_env's stripping of single and double |
951 |
|
952 |
/* Strip leading and trailing single/double quotes */
|
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
953 |
if ((val[0] == '\'' || val[0] == '\"') && val[0] == val[val_len - 1]) { |
954 |
val[val_len - 1] = '\0'; |
|
955 |
val++; |
|
956 |
val_len -= 2; |
|
30
by Loïc Minier
env.c: add logic similar to pam_env's stripping of single and double |
957 |
}
|
1.2.8
by Bdale Garbee
Import upstream version 1.7.2 |
958 |
|
959 |
cp = emalloc(var_len + 1 + val_len + 1); |
|
960 |
memcpy(cp, var, var_len + 1); /* includes '=' */ |
|
961 |
memcpy(cp + var_len + 1, val, val_len + 1); /* includes NUL */ |
|
962 |
||
963 |
sudo_putenv(cp, TRUE, overwrite); |
|
1.2.7
by Bdale Garbee
Import upstream version 1.7.0 |
964 |
}
|
965 |
fclose(fp); |
|
966 |
}
|
|
967 |
||
1
by Thom May
Import upstream version 1.6.7p5 |
968 |
void
|
969 |
init_envtables() |
|
970 |
{
|
|
971 |
struct list_member *cur; |
|
972 |
const char **p; |
|
973 |
||
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
974 |
/* Fill in the "env_delete" list. */
|
1
by Thom May
Import upstream version 1.6.7p5 |
975 |
for (p = initial_badenv_table; *p; p++) { |
976 |
cur = emalloc(sizeof(struct list_member)); |
|
977 |
cur->value = estrdup(*p); |
|
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
978 |
cur->next = def_env_delete; |
979 |
def_env_delete = cur; |
|
1
by Thom May
Import upstream version 1.6.7p5 |
980 |
}
|
981 |
||
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
982 |
/* Fill in the "env_check" list. */
|
1
by Thom May
Import upstream version 1.6.7p5 |
983 |
for (p = initial_checkenv_table; *p; p++) { |
984 |
cur = emalloc(sizeof(struct list_member)); |
|
985 |
cur->value = estrdup(*p); |
|
1.1.1
by Thom May
Import upstream version 1.6.8p5 |
986 |
cur->next = def_env_check; |
987 |
def_env_check = cur; |
|
1
by Thom May
Import upstream version 1.6.7p5 |
988 |
}
|
1.2.1
by Martin Pitt
Import upstream version 1.6.9p6 |
989 |
|
990 |
/* Fill in the "env_keep" list. */
|
|
991 |
for (p = initial_keepenv_table; *p; p++) { |
|
992 |
cur = emalloc(sizeof(struct list_member)); |
|
993 |
cur->value = estrdup(*p); |
|
994 |
cur->next = def_env_keep; |
|
995 |
def_env_keep = cur; |
|
996 |
}
|
|
1
by Thom May
Import upstream version 1.6.7p5 |
997 |
}
|