]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Fixed variable expansion in master <-> mail processes.
authorTimo Sirainen <tss@iki.fi>
Mon, 2 Feb 2009 02:49:21 +0000 (21:49 -0500)
committerTimo Sirainen <tss@iki.fi>
Mon, 2 Feb 2009 02:49:21 +0000 (21:49 -0500)
--HG--
branch : HEAD

src/deliver/deliver-settings.c
src/deliver/deliver-settings.h
src/imap/imap-settings.c
src/imap/imap-settings.h
src/lib-settings/settings-parser.c
src/lib-settings/settings-parser.h
src/master/mail-process.c
src/master/master-settings.c
src/pop3/pop3-settings.c
src/pop3/pop3-settings.h

index 488028e7e6de87c18044af1e64209b724c3b71ca..59b50aa61f364cf43615e54745bbab469110a164 100644 (file)
@@ -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) "",
index 33de1ead7e687e3d9829fb8c512e391eb85ab178..ce16d8ec26a00d000a5d160141a8d876693d81e0 100644 (file)
@@ -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;
index a8d20f417f2df28fee2e171a82a020bb7e711a74..945e01ec35e83118d126e5ff0254e552f352b316 100644 (file)
@@ -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];
index 902ba8cfc9d85bf87d1307d2095da58fdc2cde62..df188cbcf3efcde01f5dc6ae43bd9381214e7259 100644 (file)
@@ -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;
index 79804d85a89332de171e53c5b30e844b1a4aa3f4..f9c32a606a48ee6c107bdbab8a1c59354452c633 100644 (file)
@@ -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)
index a8d42b1fe4f7bbbd9c1bd92c08357ee6b8a2fd52..790b63ad069a30ade92e23aea2388a7e90b7e716 100644 (file)
@@ -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,
index 9f1db3840bffe69aded74a779aee33735b0525ff..28a8c60f6e39a03d16d6e01f7814975556e30507 100644 (file)
@@ -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,
index f74a2301c122b12e40d6c639ed9b45b305bf017b..964ba597028515fdd35f6e77e2ee10c98eb42e8b 100644 (file)
@@ -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)
index 24c36b15d00b66b8fadf4e8f0b0b54b56703f404..ae749614da8bdc9a54bade9c651cd3878d122b4a 100644 (file)
@@ -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];
index 9301b3cc2bb9a35a988167b8a16fa2f143ad6e34..85553666472c0114708c56d5678c6d042e20ec01 100644 (file)
@@ -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;