]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
config: Change global settings to override filter name-specific defaults
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Fri, 1 Dec 2023 11:04:51 +0000 (13:04 +0200)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Wed, 12 Feb 2025 10:34:11 +0000 (12:34 +0200)
Mainly this means that because we now have defaults like
sdbox/mail_path=~/sdbox, it should still be possible to override that
by changing the global mail_path setting.

src/config/config-parser.c

index 9e36d1b179a3fc2e6e06c855662bd4c89a173897..1088d1e3cd845123c1d18273bdfa9d0b358f6ca1 100644 (file)
@@ -1595,6 +1595,62 @@ config_parse_line(struct config_parser_context *ctx,
        config_line_r->type = CONFIG_LINE_TYPE_SECTION_BEGIN;
 }
 
+static bool
+config_filter_parser_has_changed_recursive(
+       struct config_filter_parser *filter_parser,
+       unsigned int module_idx, unsigned int set_idx)
+{
+       while (filter_parser != NULL) {
+               struct config_module_parser *p =
+                       &filter_parser->module_parsers[module_idx];
+               if (p->change_counters != NULL &&
+                   p->change_counters[set_idx] > CONFIG_PARSER_CHANGE_INTERNAL)
+                       return TRUE;
+               filter_parser = filter_parser->parent;
+       }
+       return FALSE;
+}
+
+static void
+config_filter_parser_drop_overridden_default_settings(
+       struct config_filter_parser *filter_parser)
+{
+       unsigned int module_idx, set_idx;
+
+       if (filter_parser->filter.filter_name == NULL ||
+           filter_parser->filter.filter_name_array)
+               return;
+
+       /* This is a SET_FILTER_NAME filter */
+       module_idx = 0;
+       for (; filter_parser->module_parsers[module_idx].info != NULL; module_idx++) {
+               struct config_module_parser *p =
+                       &filter_parser->module_parsers[module_idx];
+               if (p->change_counters == NULL)
+                       continue;
+               for (set_idx = 0; set_idx < p->set_count; set_idx++) {
+                       if (p->change_counters[set_idx] != CONFIG_PARSER_CHANGE_INTERNAL)
+                               continue;
+
+                       /* Found a default setting. If the same setting is
+                          changed by the parent filters, drop this setting. */
+                       if (config_filter_parser_has_changed_recursive(
+                                       filter_parser->parent,
+                                       module_idx, set_idx))
+                               p->change_counters[set_idx] = 0;
+               }
+       }
+}
+
+static void
+config_drop_overridden_default_filter_settings(struct config_parser_context *ctx)
+{
+       struct config_filter_parser *filter_parser;
+
+       array_foreach_elem(&ctx->all_filter_parsers, filter_parser)
+               config_filter_parser_drop_overridden_default_settings(filter_parser);
+}
+
 static int
 config_parse_finish(struct config_parser_context *ctx,
                    enum config_parse_flags flags,
@@ -1614,6 +1670,8 @@ config_parse_finish(struct config_parser_context *ctx,
        new_config->dovecot_config_version = ctx->dovecot_config_version;
        p_array_init(&new_config->errors, ctx->pool, 1);
 
+       config_drop_overridden_default_filter_settings(ctx);
+
        array_append_zero(&ctx->all_filter_parsers);
        new_config->filter_parsers = array_front(&ctx->all_filter_parsers);
        new_config->module_parsers = ctx->root_module_parsers;