dovecot-2.0: Added import_environment setting.
dovecot at dovecot.org
dovecot at dovecot.org
Thu Feb 10 01:54:29 EET 2011
details: http://hg.dovecot.org/dovecot-2.0/rev/cec7fa92ff48
changeset: 12591:cec7fa92ff48
user: Timo Sirainen <tss at iki.fi>
date: Thu Feb 10 01:54:26 2011 +0200
description:
Added import_environment setting.
This also cleans up different places in code where TZ and other environments
are preserved. If it's not in the import_environment setting, it's not
preserved.
diffstat:
src/doveadm/doveadm.c | 1 +
src/lib-lda/smtp-client.c | 2 +-
src/lib-master/master-interface.h | 4 ++
src/lib-master/master-service-settings.c | 14 ++++++-
src/lib-master/master-service-settings.h | 2 +
src/lib-master/master-service.c | 24 ++++-------
src/lib-master/master-service.h | 5 +-
src/lib-storage/mail-storage-service.c | 1 +
src/master/main.c | 62 +++++++++++++++++--------------
src/master/master-settings.c | 15 +++++++
src/master/master-settings.h | 1 +
src/master/service-process.c | 6 +--
src/master/service.c | 2 -
src/master/service.h | 2 -
14 files changed, 84 insertions(+), 57 deletions(-)
diffs (truncated from 358 to 300 lines):
diff -r 98f13cc1e649 -r cec7fa92ff48 src/doveadm/doveadm.c
--- a/src/doveadm/doveadm.c Thu Feb 10 00:45:51 2011 +0200
+++ b/src/doveadm/doveadm.c Thu Feb 10 01:54:26 2011 +0200
@@ -234,6 +234,7 @@
memset(&input, 0, sizeof(input));
input.roots = set_roots;
input.module = "doveadm";
+ input.preserve_user = TRUE;
input.preserve_home = TRUE;
if (master_service_settings_read(master_service, &input,
&output, &error) < 0)
diff -r 98f13cc1e649 -r cec7fa92ff48 src/lib-lda/smtp-client.c
--- a/src/lib-lda/smtp-client.c Thu Feb 10 00:45:51 2011 +0200
+++ b/src/lib-lda/smtp-client.c Thu Feb 10 01:54:26 2011 +0200
@@ -51,7 +51,7 @@
if (dup2(fd, STDIN_FILENO) < 0)
i_fatal("dup2() failed: %m");
- master_service_env_clean(TRUE);
+ master_service_env_clean();
execv_const(sendmail_path, argv);
}
diff -r 98f13cc1e649 -r cec7fa92ff48 src/lib-master/master-interface.h
--- a/src/lib-master/master-interface.h Thu Feb 10 00:45:51 2011 +0200
+++ b/src/lib-master/master-interface.h Thu Feb 10 01:54:26 2011 +0200
@@ -59,6 +59,10 @@
if dovecot was started with -p parameter. */
#define MASTER_SSL_KEY_PASSWORD_ENV "SSL_KEY_PASSWORD"
+/* getenv(DOVECOT_PRESERVE_ENVS_ENV) returns a space separated list of
+ environments that should be preserved. */
+#define DOVECOT_PRESERVE_ENVS_ENV "DOVECOT_PRESERVE_ENVS"
+
/* Write pipe to anvil. */
#define MASTER_ANVIL_FD 3
/* Anvil reads new log fds from this fd */
diff -r 98f13cc1e649 -r cec7fa92ff48 src/lib-master/master-service-settings.c
--- a/src/lib-master/master-service-settings.c Thu Feb 10 00:45:51 2011 +0200
+++ b/src/lib-master/master-service-settings.c Thu Feb 10 01:54:26 2011 +0200
@@ -90,12 +90,22 @@
const struct master_service_settings_input *input)
{
const char **conf_argv, *binary_path = service->argv[0];
+ const char *home = NULL, *user = NULL;
unsigned int i, argv_max_count;
(void)t_binary_abspath(&binary_path);
- if (!service->keep_environment)
- master_service_env_clean(input->preserve_home);
+ if (!service->keep_environment && !input->preserve_environment) {
+ if (input->preserve_home)
+ home = getenv("HOME");
+ if (input->preserve_user)
+ user = getenv("USER");
+ master_service_env_clean();
+ if (home != NULL)
+ env_put(t_strconcat("HOME=", home, NULL));
+ if (user != NULL)
+ env_put(t_strconcat("USER=", user, NULL));
+ }
if (input->use_sysexits)
env_put("USE_SYSEXITS=1");
diff -r 98f13cc1e649 -r cec7fa92ff48 src/lib-master/master-service-settings.h
--- a/src/lib-master/master-service-settings.h Thu Feb 10 00:45:51 2011 +0200
+++ b/src/lib-master/master-service-settings.h Thu Feb 10 01:54:26 2011 +0200
@@ -21,6 +21,8 @@
struct master_service_settings_input {
const struct setting_parser_info *const *roots;
const char *config_path;
+ bool preserve_environment;
+ bool preserve_user;
bool preserve_home;
bool never_exec;
bool use_sysexits;
diff -r 98f13cc1e649 -r cec7fa92ff48 src/lib-master/master-service.c
--- a/src/lib-master/master-service.c Thu Feb 10 00:45:51 2011 +0200
+++ b/src/lib-master/master-service.c Thu Feb 10 01:54:26 2011 +0200
@@ -391,22 +391,16 @@
master_status_update(service);
}
-void master_service_env_clean(bool preserve_home)
+void master_service_env_clean(void)
{
- static const char *preserve_envs[] = {
- "HOME", /* keep as the first element */
- "USER",
- "TZ",
-#ifdef DEBUG
- "GDB",
-#endif
-#ifdef HAVE_SYSTEMD
- "LISTEN_PID",
- "LISTEN_FDS",
-#endif
- NULL
- };
- env_clean_except(preserve_envs + (preserve_home ? 0 : 1));
+ const char *value = getenv(DOVECOT_PRESERVE_ENVS_ENV);
+
+ if (value == NULL || *value == '\0')
+ env_clean();
+ else T_BEGIN {
+ value = t_strconcat(value, " "DOVECOT_PRESERVE_ENVS_ENV, NULL);
+ env_clean_except(t_strsplit_spaces(value, " "));
+ } T_END;
}
void master_service_set_client_limit(struct master_service *service,
diff -r 98f13cc1e649 -r cec7fa92ff48 src/lib-master/master-service.h
--- a/src/lib-master/master-service.h Thu Feb 10 00:45:51 2011 +0200
+++ b/src/lib-master/master-service.h Thu Feb 10 01:54:26 2011 +0200
@@ -59,8 +59,9 @@
before calling this. */
void master_service_init_finish(struct master_service *service);
-/* Clean environment from everything except TZ, USER and optionally HOME. */
-void master_service_env_clean(bool preserve_home);
+/* Clean environment from everything except the ones listed in
+ DOVECOT_PRESERVE_ENVS environment. */
+void master_service_env_clean(void);
/* Initialize logging. */
void master_service_init_log(struct master_service *service,
diff -r 98f13cc1e649 -r cec7fa92ff48 src/lib-storage/mail-storage-service.c
--- a/src/lib-storage/mail-storage-service.c Thu Feb 10 00:45:51 2011 +0200
+++ b/src/lib-storage/mail-storage-service.c Thu Feb 10 01:54:26 2011 +0200
@@ -652,6 +652,7 @@
memset(&set_input, 0, sizeof(set_input));
set_input.roots = ctx->set_roots;
+ set_input.preserve_user = TRUE;
/* settings reader may exec doveconf, which is going to clear
environment, and if we're not doing a userdb lookup we want to
use $HOME */
diff -r 98f13cc1e649 -r cec7fa92ff48 src/master/main.c
--- a/src/master/main.c Thu Feb 10 00:45:51 2011 +0200
+++ b/src/master/main.c Thu Feb 10 01:54:26 2011 +0200
@@ -48,7 +48,6 @@
static char *pidfile_path;
static failure_callback_t *orig_fatal_callback;
static failure_callback_t *orig_error_callback;
-static const char *child_process_env[3]; /* @UNSAFE */
static const struct setting_parser_info *set_roots[] = {
&master_setting_parser_info,
@@ -314,8 +313,7 @@
sets = master_service_settings_get_others(master_service);
set = sets[0];
- if (services_create(set, child_process_env,
- &new_services, &error) < 0) {
+ if (services_create(set, &new_services, &error) < 0) {
/* new configuration is invalid, keep the old */
i_error("Config reload failed: %s", error);
return;
@@ -377,12 +375,39 @@
input.roots = set_roots;
input.module = "master";
input.parse_full_config = TRUE;
+ input.preserve_environment = TRUE;
if (master_service_settings_read(master_service, &input, &output,
&error) < 0)
i_fatal("Error reading configuration: %s", error);
return master_service_settings_get_others(master_service)[0];
}
+static void master_set_import_environment(const struct master_settings *set)
+{
+ const char *const *envs, *key, *value;
+ ARRAY_TYPE(const_string) keys;
+
+ if (*set->import_environment == '\0')
+ return;
+
+ t_array_init(&keys, 8);
+ envs = t_strsplit_spaces(set->import_environment, " ");
+ for (; *envs != NULL; envs++) {
+ value = strchr(*envs, '=');
+ if (value == NULL)
+ key = *envs;
+ else {
+ key = t_strdup_until(*envs, value);
+ env_put(*envs);
+ }
+ array_append(&keys, &key, 1);
+ }
+ (void)array_append_space(&keys);
+
+ value = t_strarray_join(array_idx(&keys, 0), " ");
+ env_put(t_strconcat(DOVECOT_PRESERVE_ENVS_ENV"=", value, NULL));
+}
+
static void main_log_startup(void)
{
#define STARTUP_STRING PACKAGE_NAME" v"DOVECOT_VERSION_FULL" starting up"
@@ -598,18 +623,8 @@
int main(int argc, char *argv[])
{
- static const char *preserve_envs[] = {
- /* AIX depends on TZ to get the timezone correctly. */
- "TZ",
-#ifdef HAVE_SYSTEMD
- "LISTEN_PID",
- "LISTEN_FDS",
-#endif
- NULL
- };
struct master_settings *set;
- unsigned int child_process_env_idx = 0;
- const char *error, *env_tz, *doveconf_arg = NULL;
+ const char *error, *doveconf_arg = NULL;
failure_callback_t *orig_info_callback, *orig_debug_callback;
bool foreground = FALSE, ask_key_pass = FALSE;
bool doubleopts[argc];
@@ -618,8 +633,6 @@
#ifdef DEBUG
if (getenv("GDB") == NULL)
fd_debug_verify_leaks(3, 1024);
- else
- child_process_env[child_process_env_idx++] = "GDB=1";
#endif
/* drop -- prefix from all --args. ugly, but the only way that it
works with standard getopt() in all OSes.. */
@@ -740,23 +753,16 @@
master_settings_do_fixes(set);
fatal_log_check(set);
- /* clean up the environment */
- env_clean_except(preserve_envs);
-
- env_tz = getenv("TZ");
- if (env_tz != NULL) {
- child_process_env[child_process_env_idx++] =
- t_strconcat("TZ=", env_tz, NULL);
- }
- i_assert(child_process_env_idx <
- sizeof(child_process_env) / sizeof(child_process_env[0]));
- child_process_env[child_process_env_idx] = NULL;
+ T_BEGIN {
+ master_set_import_environment(set);
+ } T_END;
+ master_service_env_clean();
/* create service structures from settings. if there are any errors in
service configuration we'll catch it here. */
service_pids_init();
service_anvil_global_init();
- if (services_create(set, child_process_env, &services, &error) < 0)
+ if (services_create(set, &services, &error) < 0)
i_fatal("%s", error);
services->config->config_file_path = get_full_config_path(services);
diff -r 98f13cc1e649 -r cec7fa92ff48 src/master/master-settings.c
--- a/src/master/master-settings.c Thu Feb 10 00:45:51 2011 +0200
+++ b/src/master/master-settings.c Thu Feb 10 01:54:26 2011 +0200
@@ -170,6 +170,7 @@
static const struct setting_define master_setting_defines[] = {
DEF(SET_STR, base_dir),
DEF(SET_STR, libexec_dir),
+ DEF(SET_STR, import_environment),
DEF(SET_STR, protocols),
DEF(SET_STR, listen),
DEF(SET_ENUM, ssl),
@@ -192,9 +193,23 @@
SETTING_DEFINE_LIST_END
};
+/* <settings checks> */
+#ifdef HAVE_SYSTEMD
+# define ENV_SYSTEMD " LISTEN_PID LISTEN_FDS"
+#else
+# define ENV_SYSTEMD ""
+#endif
+#ifdef DEBUG
+# define ENV_GDB " GDB"
+#else
+# define ENV_GDB ""
+#endif
+/* </settings checks> */
+
static const struct master_settings master_default_settings = {
.base_dir = PKG_RUNDIR,
.libexec_dir = PKG_LIBEXECDIR,
+ .import_environment = "TZ" ENV_SYSTEMD ENV_GDB,
.protocols = "imap pop3 lmtp",
.listen = "*, ::",
.ssl = "yes:no:required",
diff -r 98f13cc1e649 -r cec7fa92ff48 src/master/master-settings.h
--- a/src/master/master-settings.h Thu Feb 10 00:45:51 2011 +0200
+++ b/src/master/master-settings.h Thu Feb 10 01:54:26 2011 +0200
@@ -6,6 +6,7 @@
struct master_settings {
const char *base_dir;
const char *libexec_dir;
+ const char *import_environment;
More information about the dovecot-cvs
mailing list