From: Timo Sirainen Date: Mon, 2 Feb 2009 02:49:21 +0000 (-0500) Subject: Fixed variable expansion in master <-> mail processes. X-Git-Tag: 2.0.alpha1~1037^2~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e5e526b31fb261f2333e6537e42ac356d7fa34d0;p=thirdparty%2Fdovecot%2Fcore.git Fixed variable expansion in master <-> mail processes. --HG-- branch : HEAD --- diff --git a/src/deliver/deliver-settings.c b/src/deliver/deliver-settings.c index 488028e7e6..59b50aa61f 100644 --- a/src/deliver/deliver-settings.c +++ b/src/deliver/deliver-settings.c @@ -30,7 +30,6 @@ static struct setting_define deliver_setting_defines[] = { DEF(SET_STR, mail_plugins), DEF(SET_STR, mail_plugin_dir), - DEF(SET_STR_VARS, mail_log_prefix), DEF(SET_STR, postmaster_address), DEF(SET_STR, hostname), @@ -57,7 +56,6 @@ static struct deliver_settings deliver_default_settings = { MEMBER(mail_plugins) "", MEMBER(mail_plugin_dir) MODULEDIR"/lda", - MEMBER(mail_log_prefix) "%Us(%u): ", MEMBER(postmaster_address) "", MEMBER(hostname) "", diff --git a/src/deliver/deliver-settings.h b/src/deliver/deliver-settings.h index 33de1ead7e..ce16d8ec26 100644 --- a/src/deliver/deliver-settings.h +++ b/src/deliver/deliver-settings.h @@ -14,7 +14,6 @@ struct deliver_settings { const char *mail_plugins; const char *mail_plugin_dir; - const char *mail_log_prefix; /* deliver: */ const char *postmaster_address; diff --git a/src/imap/imap-settings.c b/src/imap/imap-settings.c index a8d20f417f..945e01ec35 100644 --- a/src/imap/imap-settings.c +++ b/src/imap/imap-settings.c @@ -22,7 +22,6 @@ static struct setting_define imap_setting_defines[] = { DEF(SET_STR, mail_plugins), DEF(SET_STR, mail_plugin_dir), - DEF(SET_STR_VARS, mail_log_prefix), DEF(SET_UINT, imap_max_line_length), DEF(SET_STR, imap_capability), @@ -41,7 +40,6 @@ static struct imap_settings imap_default_settings = { MEMBER(mail_plugins) "", MEMBER(mail_plugin_dir) MODULEDIR"/imap", - MEMBER(mail_log_prefix) "%Us(%u): ", /* RFC-2683 recommends at least 8000 bytes. Some clients however don't break large message sets to multiple commands, so we're pretty @@ -76,6 +74,7 @@ void imap_settings_read(const struct imap_settings **set_r, &mail_user_setting_parser_info }; struct setting_parser_context *parser; + const char *const *expanded; void **sets; if (settings_pool == NULL) @@ -89,12 +88,14 @@ void imap_settings_read(const struct imap_settings **set_r, roots, N_ELEMENTS(roots), SETTINGS_PARSER_FLAG_IGNORE_UNKNOWN_KEYS); - settings_parse_set_expanded(parser, TRUE); if (settings_parse_environ(parser) < 0) { i_fatal("Error reading configuration: %s", settings_parser_get_error(parser)); } + expanded = t_strsplit(getenv("VARS_EXPANDED"), " "); + settings_parse_set_keys_expandeded(parser, settings_pool, expanded); + sets = settings_parser_get_list(parser); *set_r = sets[0]; *user_set_r = sets[1]; diff --git a/src/imap/imap-settings.h b/src/imap/imap-settings.h index 902ba8cfc9..df188cbcf3 100644 --- a/src/imap/imap-settings.h +++ b/src/imap/imap-settings.h @@ -10,7 +10,6 @@ struct imap_settings { const char *mail_plugins; const char *mail_plugin_dir; - const char *mail_log_prefix; /* imap: */ unsigned int imap_max_line_length; diff --git a/src/lib-settings/settings-parser.c b/src/lib-settings/settings-parser.c index 79804d85a8..f9c32a606a 100644 --- a/src/lib-settings/settings-parser.c +++ b/src/lib-settings/settings-parser.c @@ -336,52 +336,71 @@ settings_parse(struct setting_parser_context *ctx, struct setting_link *link, return -1; } -static int settings_parse_keyvalue(struct setting_parser_context *ctx, - const char *key, const char *value) +static bool +settings_find_key(struct setting_parser_context *ctx, const char *key, + const struct setting_define **def_r, + struct setting_link **link_r) { - const struct setting_define *def = NULL; + const struct setting_define *def; + struct setting_link *link; + const char *end; unsigned int i; - int ret = 1; /* try to find from roots */ for (i = 0; i < ctx->root_count; i++) { def = setting_define_find(ctx->roots[i].info, key); - if (def != NULL) - break; + if (def != NULL) { + *def_r = def; + *link_r = &ctx->roots[i]; + return TRUE; + } } - if (def != NULL) { - if (settings_parse(ctx, &ctx->roots[i], def, key, value) < 0) - ret = -1; + + /* try to find from links */ + end = strrchr(key, SETTINGS_SEPARATOR); + if (end == NULL) + return FALSE; + + link = hash_table_lookup(ctx->links, t_strdup_until(key, end)); + if (link == NULL) + return FALSE; + + *link_r = link; + if (link->info == &strlist_info) { + *def_r = NULL; + return TRUE; } else { - /* try to find from links */ - const char *end = strrchr(key, SETTINGS_SEPARATOR); - struct setting_link *link; - - link = end == NULL ? NULL : - hash_table_lookup(ctx->links, t_strdup_until(key, end)); - if (link == NULL) - def = NULL; - else if (link->info == &strlist_info) { + *def_r = setting_define_find(link->info, end + 1); + return *def_r != NULL; + } +} + +static int settings_parse_keyvalue(struct setting_parser_context *ctx, + const char *key, const char *value) +{ + const struct setting_define *def; + struct setting_link *link; + + if (settings_find_key(ctx, key, &def, &link)) { + if (link->info == &strlist_info) { void *vkey, *vvalue; - vkey = p_strdup(ctx->set_pool, end + 1); + vkey = p_strdup(ctx->set_pool, + strrchr(key, SETTINGS_SEPARATOR) + 1); vvalue = p_strdup(ctx->set_pool, value); array_append(link->array, &vkey, 1); array_append(link->array, &vvalue, 1); return 1; - } else { - def = setting_define_find(link->info, end + 1); - } - if (def != NULL) { - if (settings_parse(ctx, link, def, key, value) < 0) - ret = -1; - } else { - ctx->error = p_strconcat(ctx->parser_pool, - "Unknown setting: ", key, NULL); - ret = 0; } + + if (settings_parse(ctx, link, def, key, value) < 0) + return -1; + return 1; + } else { + ctx->error = p_strconcat(ctx->parser_pool, + "Unknown setting: ", key, NULL); + return 0; } - return ret; } int settings_parse_line(struct setting_parser_context *ctx, const char *line) @@ -668,6 +687,27 @@ settings_var_expand_info(const struct setting_parser_info *info, } } +void settings_parse_set_keys_expandeded(struct setting_parser_context *ctx, + pool_t pool, const char *const *keys) +{ + const struct setting_define *def; + struct setting_link *link; + const char **val; + + for (; *keys != NULL; keys++) { + if (!settings_find_key(ctx, *keys, &def, &link)) + continue; + + val = PTR_OFFSET(link->set_struct, def->offset); + if (def->type == SET_STR_VARS && *val != NULL) { + i_assert(**val == SETTING_STRVAR_UNEXPANDED[0] || + **val == SETTING_STRVAR_EXPANDED[0]); + *val = p_strconcat(pool, SETTING_STRVAR_EXPANDED, + *val + 1, NULL); + } + } +} + void settings_var_expand(const struct setting_parser_info *info, void *set, pool_t pool, const struct var_expand_table *table) diff --git a/src/lib-settings/settings-parser.h b/src/lib-settings/settings-parser.h index a8d42b1fe4..790b63ad06 100644 --- a/src/lib-settings/settings-parser.h +++ b/src/lib-settings/settings-parser.h @@ -119,6 +119,9 @@ int settings_parse_exec(struct setting_parser_context *ctx, /* While parsing values, specifies if STR_VARS strings are already expanded. */ void settings_parse_set_expanded(struct setting_parser_context *ctx, bool is_expanded); +/* Mark all the parsed settings with given keys as being already expanded. */ +void settings_parse_set_keys_expandeded(struct setting_parser_context *ctx, + pool_t pool, const char *const *keys); /* Expand all unexpanded variables using the given table. Update the string pointers so that they can be used without skipping over the '1'. */ void settings_var_expand(const struct setting_parser_info *info, diff --git a/src/master/mail-process.c b/src/master/mail-process.c index 9f1db3840b..28a8c60f6e 100644 --- a/src/master/mail-process.c +++ b/src/master/mail-process.c @@ -217,15 +217,20 @@ has_missing_used_home(const char *str, const struct var_expand_table *table) static void mail_process_set_environment(struct master_settings *set, - const struct var_expand_table *table) + const struct var_expand_table *table, + string_t *expanded_vars) { const char **envs; string_t *str; unsigned int i, count; - settings_var_expand(&master_setting_parser_info, set, - system_pool, table); + str_append(expanded_vars, "VARS_EXPANDED="); + + /* we don't know all the settings, so since we can't expand all of + them just let the mail process expand all of them internally. + except for plugin settings - we know all of them so expand them. */ + master_settings_export_to_env(set); (void)umask(set->umask); @@ -245,10 +250,11 @@ mail_process_set_environment(struct master_settings *set, } str_truncate(str, 0); var_expand(str, envs[i+1], table); - envs[i+1] = t_strdup(str_c(str)); - } + env_put(t_strconcat(t_str_ucase(envs[i]), "=", str_c(str), NULL)); - master_settings_export_to_env(set); + str_append(expanded_vars, envs[i]); + str_append_c(expanded_vars, ' '); + } } void mail_process_exec(const char *protocol, const char **args) @@ -256,6 +262,7 @@ void mail_process_exec(const char *protocol, const char **args) const struct var_expand_table *var_expand_table; struct master_settings *set; const char *executable; + string_t *expanded_vars; if (strcmp(protocol, "ext") == 0) { /* external binary. section contains path for it. */ @@ -296,7 +303,10 @@ void mail_process_exec(const char *protocol, const char **args) env_put(str_c(str)); } - mail_process_set_environment(set, var_expand_table); + expanded_vars = t_str_new(128); + mail_process_set_environment(set, var_expand_table, expanded_vars); + env_put(str_c(expanded_vars)); + if (args == NULL) client_process_exec(executable, ""); else @@ -352,11 +362,11 @@ create_mail_process(enum process_type process_type, struct master_settings *set, { const struct var_expand_table *var_expand_table; const char *p, *addr, *mail, *chroot_dir, *home_dir, *full_home_dir; - const char *system_user, *master_user; + const char *system_user, *master_user, *key; struct mail_process_group *process_group; char title[1024]; struct log_io *log; - string_t *str; + string_t *str, *expanded_vars; pid_t pid; uid_t uid; gid_t gid; @@ -627,7 +637,8 @@ create_mail_process(enum process_type process_type, struct master_settings *set, i_fatal("chdir(/tmp) failed: %m"); } - mail_process_set_environment(set, var_expand_table); + expanded_vars = t_str_new(128); + mail_process_set_environment(set, var_expand_table, expanded_vars); /* extra args. uppercase key value. */ args = array_get(&extra_args, &count); @@ -640,14 +651,18 @@ create_mail_process(enum process_type process_type, struct master_settings *set, p = strchr(args[i], '='); if (p == NULL) { /* boolean */ - env_put(t_strconcat(t_str_ucase(args[i]), "=1", NULL)); + key = args[i]; + env_put(t_strconcat(t_str_ucase(key), "=1", NULL)); } else { /* key=value */ - env_put(t_strconcat(t_str_ucase( - t_strdup_until(args[i], p)), p, NULL)); + key = t_strdup_until(args[i], p); + env_put(t_strconcat(t_str_ucase(key), p, NULL)); } + str_append(expanded_vars, key); + str_append_c(expanded_vars, ' '); } + env_put(str_c(expanded_vars)); if (nfs_check) { /* ideally we should check all of the namespaces, diff --git a/src/master/master-settings.c b/src/master/master-settings.c index f74a2301c1..964ba59702 100644 --- a/src/master/master-settings.c +++ b/src/master/master-settings.c @@ -197,7 +197,7 @@ static struct setting_define master_setting_defines[] = { DEF(SET_STR, mail_executable), DEF(SET_UINT, mail_process_size), - DEF(SET_STR_VARS, mail_log_prefix), + DEF(SET_STR, mail_log_prefix), DEF(SET_UINT, mail_log_max_lines_per_sec), /* dict */ @@ -1023,8 +1023,10 @@ void master_settings_export_to_env(const struct master_settings *set) unsigned int i, count; sets = array_get(&set->all_settings, &count); - for (i = 0; i < count; i++) - env_put(sets[i]); + for (i = 0; i < count; i++) { + if (strncmp(sets[i], "plugin/", 7) != 0) + env_put(sets[i]); + } } void master_settings_init(void) diff --git a/src/pop3/pop3-settings.c b/src/pop3/pop3-settings.c index 24c36b15d0..ae749614da 100644 --- a/src/pop3/pop3-settings.c +++ b/src/pop3/pop3-settings.c @@ -22,7 +22,6 @@ static struct setting_define pop3_setting_defines[] = { DEF(SET_STR, mail_plugins), DEF(SET_STR, mail_plugin_dir), - DEF(SET_STR_VARS, mail_log_prefix), DEF(SET_BOOL, pop3_no_flag_updates), DEF(SET_BOOL, pop3_enable_last), @@ -42,7 +41,6 @@ static struct pop3_settings pop3_default_settings = { MEMBER(mail_plugins) "", MEMBER(mail_plugin_dir) MODULEDIR"/pop3", - MEMBER(mail_log_prefix) "%Us(%u): ", MEMBER(pop3_no_flag_updates) FALSE, MEMBER(pop3_enable_last) FALSE, @@ -75,6 +73,7 @@ void pop3_settings_read(const struct pop3_settings **set_r, &mail_user_setting_parser_info }; struct setting_parser_context *parser; + const char *const *expanded; void **sets; if (settings_pool == NULL) @@ -88,12 +87,14 @@ void pop3_settings_read(const struct pop3_settings **set_r, roots, N_ELEMENTS(roots), SETTINGS_PARSER_FLAG_IGNORE_UNKNOWN_KEYS); - settings_parse_set_expanded(parser, TRUE); if (settings_parse_environ(parser) < 0) { i_fatal("Error reading configuration: %s", settings_parser_get_error(parser)); } + expanded = t_strsplit(getenv("VARS_EXPANDED"), " "); + settings_parse_set_keys_expandeded(parser, settings_pool, expanded); + sets = settings_parser_get_list(parser); *set_r = sets[0]; *user_set_r = sets[1]; diff --git a/src/pop3/pop3-settings.h b/src/pop3/pop3-settings.h index 9301b3cc2b..8555366647 100644 --- a/src/pop3/pop3-settings.h +++ b/src/pop3/pop3-settings.h @@ -10,7 +10,6 @@ struct pop3_settings { const char *mail_plugins; const char *mail_plugin_dir; - const char *mail_log_prefix; /* pop3: */ bool pop3_no_flag_updates;