From: Timo Sirainen Date: Sat, 16 Mar 2024 11:00:07 +0000 (+0200) Subject: lib-dict, global: Add dict named list filter and require using it X-Git-Tag: 2.4.1~912 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=20227640ac1fa6928dc7fa8538beb73a9ee26f05;p=thirdparty%2Fdovecot%2Fcore.git lib-dict, global: Add dict named list filter and require using it It's no longer possible to simply specify dict_driver setting without dict named list filter. This makes it more consistent with lib-fs. --- diff --git a/src/lib-dict-extra/test-dict-fs.c b/src/lib-dict-extra/test-dict-fs.c index 5211936c20..d95b21b0f8 100644 --- a/src/lib-dict-extra/test-dict-fs.c +++ b/src/lib-dict-extra/test-dict-fs.c @@ -39,7 +39,8 @@ static void test_dict_fs_set_get(void) const char *error; struct dict *dict; const char *const settings[] = { - "dict_driver", "fs", + "dict", "fs", + "dict/fs/dict_driver", "fs", "fs", "posix", "fs/posix/fs_driver", "posix", "fs_posix_prefix", ".test-dict/", diff --git a/src/lib-dict/dict.c b/src/lib-dict/dict.c index 99e2e8e00d..173e6e4d63 100644 --- a/src/lib-dict/dict.c +++ b/src/lib-dict/dict.c @@ -30,16 +30,24 @@ struct dict_lookup_callback_ctx { void *context; }; +static bool dict_settings_check(void *_set, pool_t pool, const char **error_r); + #undef DEF #define DEF(type, name) \ SETTING_DEFINE_STRUCT_##type(#name, name, struct dict_settings) static const struct setting_define dict_setting_defines[] = { + DEF(STR, dict_name), DEF(STR, dict_driver), + { .type = SET_FILTER_ARRAY, .key = "dict", + .offset = offsetof(struct dict_settings, dicts), + .filter_array_field_name = "dict_name", }, SETTING_DEFINE_LIST_END }; static const struct dict_settings dict_default_settings = { + .dict_name = "", .dict_driver = "", + .dicts = ARRAY_INIT, }; const struct setting_parser_info dict_setting_parser_info = { .name = "dict", @@ -49,6 +57,8 @@ const struct setting_parser_info dict_setting_parser_info = { .struct_size = sizeof(struct dict_settings), .pool_offset1 = 1 + offsetof(struct dict_settings, pool), + + .check_func = dict_settings_check, }; static ARRAY(struct dict *) dict_drivers; @@ -154,6 +164,20 @@ int dict_init_legacy(const char *uri, const struct dict_legacy_settings *set, return 0; } +static bool dict_settings_check(void *_set, pool_t pool ATTR_UNUSED, + const char **error_r ATTR_UNUSED) +{ + struct dict_settings *set = _set; + + if (set->dict_driver[0] == '\0' && set->dict_name[0] != '\0') { + /* default an empty dict_driver to dict_name, so it's possible + to configure simply: dict driver { .. }, but to still allow + the same driver to be used multiple times if necessary. */ + set->dict_driver = set->dict_name; + } + return TRUE; +} + int dict_init_auto(struct event *event, struct dict **dict_r, const char **error_r) { @@ -166,21 +190,44 @@ int dict_init_auto(struct event *event, struct dict **dict_r, if (settings_get(event, &dict_setting_parser_info, 0, &dict_set, error_r) < 0) return -1; - - if (dict_set->dict_driver[0] == '\0') { - *error_r = "dict_driver setting is empty"; + if (array_is_empty(&dict_set->dicts)) { + *error_r = "dict { .. } named list filter is missing"; settings_free(dict_set); return 0; } + const char *dict_name_first = + t_strdup(array_idx_elem(&dict_set->dicts, 0)); + if (array_count(&dict_set->dicts) > 1) { + /* There are currently no dicts that support child dicts. */ + const char *dict_name_extra = + array_idx_elem(&dict_set->dicts, 1); + *error_r = t_strdup_printf( + "Extra dict %s { .. } named list filter - " + "the parent dict %s { .. } doesn't support a child dict", + dict_name_extra, dict_name_first); + settings_free(dict_set); + return -1; + } + + /* Get settings for the first dict list filter */ + event = event_create(event); + event_add_str(event, "dict", dict_name_first); + settings_free(dict_set); + if (settings_get(event, &dict_setting_parser_info, 0, + &dict_set, error_r) < 0) { + event_unref(&event); + return -1; + } + dict_driver = dict_driver_lookup(dict_set->dict_driver); if (dict_driver == NULL) { *error_r = t_strdup_printf("Unknown dict module: %s", dict_set->dict_driver); + event_unref(&event); settings_free(dict_set); return -1; } - event = event_create(event); event_add_category(event, &event_category_dict); event_add_str(event, "driver", dict_driver->name); event_set_append_log_prefix(event, t_strdup_printf("dict(%s): ", diff --git a/src/lib-dict/dict.h b/src/lib-dict/dict.h index 36fbd96cd6..6e57aed7b4 100644 --- a/src/lib-dict/dict.h +++ b/src/lib-dict/dict.h @@ -39,7 +39,9 @@ struct dict_legacy_settings { struct dict_settings { pool_t pool; + const char *dict_name; const char *dict_driver; + ARRAY_TYPE(const_string) dicts; }; extern const struct setting_parser_info dict_setting_parser_info; diff --git a/src/lib-fs/fs-dict.c b/src/lib-fs/fs-dict.c index 69598cbd52..415b816f3c 100644 --- a/src/lib-fs/fs-dict.c +++ b/src/lib-fs/fs-dict.c @@ -113,7 +113,7 @@ fs_dict_init(struct fs *_fs, const struct fs_parameters *params ATTR_UNUSED, ret = dict_init_auto(event, &fs->dict, error_r); event_unref(&event); if (ret == 0) - *error_r = "fs_dict { dict_driver } not set"; + *error_r = "fs_dict { dict { .. } } not set"; return ret <= 0 ? -1 : 0; } diff --git a/src/lib-storage/mail-storage-settings.c b/src/lib-storage/mail-storage-settings.c index 765ea455d4..1283cd644f 100644 --- a/src/lib-storage/mail-storage-settings.c +++ b/src/lib-storage/mail-storage-settings.c @@ -40,7 +40,7 @@ static const struct setting_define mail_storage_setting_defines[] = { DEF(SIZE, mail_ext_attachment_min_size), DEF(STR, mail_attachment_detection_options), { .type = SET_FILTER_NAME, .key = "mail_attribute", - .required_setting = "dict_driver", }, + .required_setting = "dict", }, DEF(UINT, mail_prefetch_count), DEF(STR, mail_cache_fields), DEF(STR, mail_always_cache_fields), diff --git a/src/lib-storage/mailbox-attribute.c b/src/lib-storage/mailbox-attribute.c index a5273f6fc4..8d7a6322af 100644 --- a/src/lib-storage/mailbox-attribute.c +++ b/src/lib-storage/mailbox-attribute.c @@ -483,7 +483,7 @@ int mailbox_attribute_dict_is_enabled(struct mail_user *user, event_set_ptr(event, SETTINGS_EVENT_FILTER_NAME, "mail_attribute"); int ret = settings_get(event, &dict_setting_parser_info, 0, &dict_set, error_r); - if (ret == 0 && dict_set->dict_driver[0] != '\0') + if (ret == 0 && array_not_empty(&dict_set->dicts)) ret = 1; settings_free(dict_set); event_unref(&event); diff --git a/src/plugins/acl/acl-settings.c b/src/plugins/acl/acl-settings.c index fafd8e0ed9..5e0ec86da6 100644 --- a/src/plugins/acl/acl-settings.c +++ b/src/plugins/acl/acl-settings.c @@ -53,7 +53,7 @@ static const struct setting_define acl_setting_defines[] = { DEF(BOOL, acl_defaults_from_inbox), DEF(BOOL, acl_ignore), { .type = SET_FILTER_NAME, .key = "acl_sharing_map", - .required_setting = "dict_driver", }, + .required_setting = "dict", }, { .type = SET_FILTER_ARRAY, .key = "acl", .filter_array_field_name = "acl_id", diff --git a/src/plugins/mail-crypt/test-mail-key.c b/src/plugins/mail-crypt/test-mail-key.c index 03bc190a2d..5ee58f85bb 100644 --- a/src/plugins/mail-crypt/test-mail-key.c +++ b/src/plugins/mail-crypt/test-mail-key.c @@ -375,7 +375,8 @@ static void test_setup(void) test_ctx = test_mail_storage_init(); const char *username = "mcp_test@example.com"; const char *const extra_input[] = { - "mail_attribute/dict_driver=file", + "mail_attribute/dict=file", + "mail_attribute/dict/file/driver=file", t_strdup_printf("dict_file_path=%s/%s/dovecot-attributes", test_ctx->home_root, username), NULL diff --git a/src/plugins/notify-status/notify-status-plugin.c b/src/plugins/notify-status/notify-status-plugin.c index 7a1bce45bc..8e6efd04cd 100644 --- a/src/plugins/notify-status/notify-status-plugin.c +++ b/src/plugins/notify-status/notify-status-plugin.c @@ -44,7 +44,7 @@ static const struct setting_define notify_status_plugin_setting_defines[] = { DEF(BOOL, mailbox_notify_status), DEF(STR_NOVARS, notify_status_value), { .type = SET_FILTER_NAME, .key = "notify_status", - .required_setting = "dict_driver", }, + .required_setting = "dict", }, SETTING_DEFINE_LIST_END }; diff --git a/src/plugins/quota-clone/quota-clone-settings.c b/src/plugins/quota-clone/quota-clone-settings.c index c1d9faf1fb..dac2e5435c 100644 --- a/src/plugins/quota-clone/quota-clone-settings.c +++ b/src/plugins/quota-clone/quota-clone-settings.c @@ -12,7 +12,7 @@ SETTING_DEFINE_STRUCT_##type("quota_clone_"#name, name, struct quota_clone_settings) static const struct setting_define quota_clone_setting_defines[] = { - { .type = SET_FILTER_NAME, .key = "quota_clone", .required_setting = "dict_driver" }, + { .type = SET_FILTER_NAME, .key = "quota_clone", .required_setting = "dict" }, DEF(BOOL, unset), SETTING_DEFINE_LIST_END };