summaryrefslogtreecommitdiffstats
path: root/src/environment.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/environment.c')
-rw-r--r--src/environment.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/environment.c b/src/environment.c
new file mode 100644
index 0000000..9cb90c8
--- /dev/null
+++ b/src/environment.c
@@ -0,0 +1,83 @@
+/*************************************************
+* Exim - an Internet mail transport agent *
+*************************************************/
+
+/* Copyright (c) Heiko Schlittermann 2016
+ * hs@schlittermann.de
+ * See the file NOTICE for conditions of use and distribution.
+ */
+
+#include "exim.h"
+
+extern char **environ;
+
+/* The cleanup_environment() function is used during the startup phase
+of the Exim process, right after reading the configurations main
+part, before any expansions take place. It retains the environment
+variables we trust (via the keep_environment option) and allows to
+set additional variables (via add_environment).
+
+Returns: TRUE if successful
+ FALSE otherwise
+*/
+
+BOOL
+cleanup_environment()
+{
+int old_pool = store_pool;
+store_pool = POOL_PERM; /* Need perm memory for any created env vars */
+
+if (!keep_environment || *keep_environment == '\0')
+ {
+ /* From: https://github.com/dovecot/core/blob/master/src/lib/env-util.c#L55
+ Try to clear the environment.
+ a) environ = NULL crashes on OS X.
+ b) *environ = NULL doesn't work on FreeBSD 7.0.
+ c) environ = emptyenv doesn't work on Haiku OS
+ d) environ = calloc() should work everywhere */
+
+ if (environ) *environ = NULL;
+
+ }
+else if (Ustrcmp(keep_environment, "*") != 0)
+ {
+ rmark reset_point = store_mark();
+ if (environ) for (uschar ** p = USS environ; *p; /* see below */)
+ {
+ /* It's considered broken if we do not find the '=', according to
+ Florian Weimer. For now we ignore such strings. unsetenv() would complain,
+ getenv() would complain. */
+ uschar * eqp = Ustrchr(*p, '=');
+
+ if (eqp)
+ {
+ uschar * name = string_copyn(*p, eqp - *p);
+
+ if (OK != match_isinlist(name, CUSS &keep_environment,
+ 0, NULL, NULL, MCL_NOEXPAND, FALSE, NULL))
+ if (os_unsetenv(name) < 0) return FALSE;
+ else p = USS environ; /* RESTART from the beginning */
+ else p++;
+ }
+ }
+ store_reset(reset_point);
+ }
+if (add_environment)
+ {
+ uschar * p;
+ int sep = 0;
+ const uschar * envlist = add_environment;
+
+ while ((p = string_nextinlist(&envlist, &sep, NULL, 0)))
+ {
+ DEBUG(D_expand) debug_printf("adding %s\n", p);
+ putenv(CS p);
+ }
+ }
+#ifndef DISABLE_TLS
+tls_clean_env();
+#endif
+
+store_pool = old_pool;
+return TRUE;
+}