c41d19ebac552ac233738a07dcf6756075ed20f6
[exim.git] / src / src / environment.c
1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
4
5 /* Copyright (c) Heiko Schlittermann 2016
6 * hs@schlittermann.de
7 * See the file NOTICE for conditions of use and distribution.
8 */
9
10 #include "exim.h"
11
12 #ifndef environ
13 extern char **environ;
14 #endif
15
16 /* The cleanup_environment() function is used during the startup phase
17 of the Exim process, right after reading the configurations main
18 part, before any expansions take place. It retains the environment
19 variables we trust (via the keep_environment option) and allows to
20 set additional variables (via add_environment).
21
22 Returns: TRUE if successful
23 FALSE otherwise
24 */
25
26 BOOL
27 cleanup_environment()
28 {
29 if (!keep_environment || *keep_environment == '\0')
30 {
31 /* From: https://github.com/dovecot/core/blob/master/src/lib/env-util.c#L55
32 Try to clear the environment.
33 a) environ = NULL crashes on OS X.
34 b) *environ = NULL doesn't work on FreeBSD 7.0.
35 c) environ = emptyenv doesn't work on Haiku OS
36 d) environ = calloc() should work everywhere */
37
38 if (environ) *environ = NULL;
39
40 }
41 else if (Ustrcmp(keep_environment, "*") != 0)
42 {
43 uschar **p;
44 if (environ) for (p = USS environ; *p; /* see below */)
45 {
46 /* It's considered broken if we do not find the '=', according to
47 Florian Weimer. For now we ignore such strings. unsetenv() would complain,
48 getenv() would complain. */
49 uschar *eqp = Ustrchr(*p, '=');
50
51 if (eqp)
52 {
53 uschar *name = string_copyn(*p, eqp - *p);
54 if (OK != match_isinlist(name, CUSS &keep_environment,
55 0, NULL, NULL, MCL_NOEXPAND, FALSE, NULL))
56 if (unsetenv(CS name) < 0) return FALSE;
57 else p = USS environ; /* RESTART from the beginning */
58 else p++;
59 store_reset(name);
60 }
61 }
62 }
63 if (add_environment)
64 {
65 uschar *p;
66 int sep = 0;
67 const uschar* envlist = add_environment;
68 while ((p = string_nextinlist(&envlist, &sep, NULL, 0)))
69 putenv(CS p);
70 }
71
72 return TRUE;
73 }