]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
auth: Change passdb_default_fields and passdb_override_fields to be strlist
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Thu, 11 Jan 2024 18:25:27 +0000 (13:25 -0500)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Wed, 12 Feb 2025 10:34:11 +0000 (12:34 +0200)
Now that the %variable expansion is done by settings lookups, they had to
be moved to their own settings structs that are looked up at appropriate
times. Especially the override_fields must be looked up only after the
passdb lookup has finished, since it can refer to extra fields returned by
it.

src/auth/auth-request.c
src/auth/auth-request.h
src/auth/auth-settings.c
src/auth/auth-settings.h
src/auth/auth.c
src/auth/auth.h
src/auth/test-mock.c

index 5c7fba1f862672685a882f2880ebc9b1f2c62d76..73741d1644cb3b4c3bc78302f6dbd4cf08a919f6 100644 (file)
@@ -14,6 +14,7 @@
 #include "var-expand.h"
 #include "dns-lookup.h"
 #include "hostpid.h"
+#include "settings.h"
 #include "master-service.h"
 #include "auth-cache.h"
 #include "auth-request.h"
@@ -680,7 +681,11 @@ void auth_request_passdb_lookup_begin(struct auth_request *request)
        event = event_create(request->event);
        event_add_str(event, "passdb", request->passdb->name);
        event_add_str(event, "passdb_id", dec2str(request->passdb->passdb->id));
-       event_add_str(event, "passdb_driver", request->passdb->passdb->iface.name);
+       const char *passdb_driver = request->passdb->passdb->iface.name;
+       event_add_str(event, "passdb_driver", passdb_driver);
+       event_set_ptr(event, SETTINGS_EVENT_FILTER_NAME,
+                     p_strconcat(event_get_pool(event), "passdb_",
+                                 passdb_driver, NULL));
        event_set_log_prefix_callback(event, FALSE,
                auth_request_get_log_prefix_db, request);
 
@@ -794,6 +799,40 @@ static void auth_request_passdb_internal_failure(struct auth_request *request)
        auth_request_unref(&request);
 }
 
+static int auth_request_set_default_fields(struct auth_request *request)
+{
+       struct event *event = authdb_event(request);
+       const struct auth_passdb_pre_settings *pre_set;
+       const char *error;
+
+       if (settings_get(event, &auth_passdb_pre_setting_parser_info, 0,
+                        &pre_set, &error) < 0) {
+               e_error(event, "%s", error);
+               return -1;
+       }
+       auth_request_set_strlist(request, &pre_set->default_fields,
+                                STATIC_PASS_SCHEME);
+       settings_free(pre_set);
+       return 0;
+}
+
+static int auth_request_set_override_fields(struct auth_request *request)
+{
+       struct event *event = authdb_event(request);
+       const struct auth_passdb_post_settings *post_set;
+       const char *error;
+
+       if (settings_get(event, &auth_passdb_post_setting_parser_info, 0,
+                        &post_set, &error) < 0) {
+               e_error(event, "%s", error);
+               return -1;
+       }
+       auth_request_set_strlist(request, &post_set->override_fields,
+                                STATIC_PASS_SCHEME);
+       settings_free(post_set);
+       return 0;
+}
+
 static int
 auth_request_finish_passdb_lookup(enum passdb_result *result,
                                  struct auth_request *request,
@@ -997,15 +1036,11 @@ void
 auth_request_verify_plain_callback_finish(enum passdb_result result,
                                          struct auth_request *request)
 {
-       const char *error;
        int ret;
 
-       if (passdb_template_export(request->passdb->override_fields_tmpl,
-                                  request, &error) < 0) {
-               e_error(authdb_event(request),
-                       "Failed to expand override_fields: %s", error);
+       if (auth_request_set_override_fields(request) < 0)
                result = PASSDB_RESULT_INTERNAL_FAILURE;
-       }
+
        if ((ret = auth_request_handle_passdb_callback(&result, request)) == 0) {
                /* try next passdb */
                auth_request_verify_plain(request, request->mech_password,
@@ -1168,7 +1203,7 @@ void auth_request_default_verify_plain_continue(
 {
        struct auth_passdb *passdb;
        enum passdb_result result;
-       const char *cache_key, *error;
+       const char *cache_key;
        const char *password = request->mech_password;
 
        i_assert(request->state == AUTH_REQUEST_STATE_MECH_CONTINUE);
@@ -1220,10 +1255,7 @@ void auth_request_default_verify_plain_continue(
                        PASSDB_RESULT_INTERNAL_FAILURE, request);
        } else if (passdb->passdb->blocking) {
                passdb_blocking_verify_plain(request);
-       } else if (passdb_template_export(passdb->default_fields_tmpl,
-                                         request, &error) < 0) {
-               e_error(authdb_event(request),
-                       "Failed to expand default_fields: %s", error);
+       } else if (auth_request_set_default_fields(request) < 0) {
                auth_request_verify_plain_callback(
                        PASSDB_RESULT_INTERNAL_FAILURE, request);
        } else {
@@ -1238,15 +1270,11 @@ auth_request_lookup_credentials_finish(enum passdb_result result,
                                       size_t size,
                                       struct auth_request *request)
 {
-       const char *error;
        int ret;
 
-       if (passdb_template_export(request->passdb->override_fields_tmpl,
-                                  request, &error) < 0) {
-               e_error(authdb_event(request),
-                       "Failed to expand override_fields: %s", error);
+       if (auth_request_set_override_fields(request) < 0)
                result = PASSDB_RESULT_INTERNAL_FAILURE;
-       }
+
        if ((ret = auth_request_handle_passdb_callback(&result, request)) == 0) {
                /* try next passdb */
                if (request->fields.skip_password_check &&
@@ -1359,7 +1387,7 @@ auth_request_lookup_credentials_policy_continue(
        struct auth_request *request, lookup_credentials_callback_t *callback)
 {
        struct auth_passdb *passdb;
-       const char *cache_key, *cache_cred, *cache_scheme, *error;
+       const char *cache_key, *cache_cred, *cache_scheme;
        enum passdb_result result;
 
        i_assert(request->state == AUTH_REQUEST_STATE_MECH_CONTINUE);
@@ -1408,10 +1436,7 @@ auth_request_lookup_credentials_policy_continue(
                                        uchar_empty_ptr, 0, request);
        } else if (passdb->passdb->blocking) {
                passdb_blocking_lookup_credentials(request);
-       } else if (passdb_template_export(passdb->default_fields_tmpl,
-                                         request, &error) < 0) {
-               e_error(authdb_event(request),
-                       "Failed to expand default_fields: %s", error);
+       } else if (auth_request_set_default_fields(request) < 0) {
                auth_request_lookup_credentials_callback(
                                        PASSDB_RESULT_INTERNAL_FAILURE,
                                        uchar_empty_ptr, 0, request);
@@ -2040,6 +2065,22 @@ void auth_request_set_fields(struct auth_request *request,
        }
 }
 
+void auth_request_set_strlist(struct auth_request *request,
+                             const ARRAY_TYPE(const_string) *strlist,
+                             const char *default_scheme)
+{
+       if (!array_is_created(strlist))
+               return;
+
+       unsigned int i, count;
+       const char *const *fields = array_get(strlist, &count);
+       i_assert(count % 2 == 0);
+       for (i = 0; i < count; i += 2) {
+               auth_request_set_field(request, fields[i], fields[i + 1],
+                                      default_scheme);
+       }
+}
+
 static void
 auth_request_set_uidgid_file(struct auth_request *request,
                             const char *path_template)
index 46ec97e11a854132cd34727a53adc8606c841d81..3e6117d8b8d7230123305e7e1c24aecde170840e 100644 (file)
@@ -323,6 +323,9 @@ void auth_request_set_field_keyvalue(struct auth_request *request,
 void auth_request_set_fields(struct auth_request *request,
                             const char *const *fields,
                             const char *default_scheme) ATTR_NULL(3);
+void auth_request_set_strlist(struct auth_request *request,
+                             const ARRAY_TYPE(const_string) *strlist,
+                             const char *default_scheme);
 
 void auth_request_init_userdb_reply(struct auth_request *request);
 void auth_request_set_userdb_field(struct auth_request *request,
index 2299f35eeb6e165ebac59e91429db6dc3b38126e..a1364278815ce6d3cad465fcefb9da2fca91f80e 100644 (file)
@@ -106,8 +106,6 @@ static const struct setting_define auth_passdb_setting_defines[] = {
        DEF(STR, name),
        DEF(STR, driver),
        DEF(STR_NOVARS, args),
-       DEF(STR_NOVARS, default_fields),
-       DEF(STR_NOVARS, override_fields),
        DEF(BOOLLIST, mechanisms),
        DEF(STR, username_filter),
 
@@ -126,8 +124,6 @@ static const struct auth_passdb_settings auth_passdb_default_settings = {
        .name = "",
        .driver = "",
        .args = "",
-       .default_fields = "",
-       .override_fields = "",
        .mechanisms = ARRAY_INIT,
        .username_filter = "",
 
@@ -152,6 +148,48 @@ const struct setting_parser_info auth_passdb_setting_parser_info = {
        .check_func = auth_passdb_settings_check
 };
 
+static const struct setting_define auth_passdb_pre_setting_defines[] = {
+       { .type = SET_STRLIST, .key = "passdb_default_fields",
+         .offset = offsetof(struct auth_passdb_pre_settings, default_fields) },
+
+       SETTING_DEFINE_LIST_END
+};
+
+static const struct auth_passdb_pre_settings auth_passdb_pre_default_settings = {
+       .default_fields = ARRAY_INIT,
+};
+
+const struct setting_parser_info auth_passdb_pre_setting_parser_info = {
+       .name = "auth_passdb_pre",
+
+       .defines = auth_passdb_pre_setting_defines,
+       .defaults = &auth_passdb_pre_default_settings,
+
+       .struct_size = sizeof(struct auth_passdb_pre_settings),
+       .pool_offset1 = 1 + offsetof(struct auth_passdb_pre_settings, pool),
+};
+
+static const struct setting_define auth_passdb_post_setting_defines[] = {
+       { .type = SET_STRLIST, .key = "passdb_override_fields",
+         .offset = offsetof(struct auth_passdb_post_settings, override_fields) },
+
+       SETTING_DEFINE_LIST_END
+};
+
+static const struct auth_passdb_post_settings auth_passdb_post_default_settings = {
+       .override_fields = ARRAY_INIT,
+};
+
+const struct setting_parser_info auth_passdb_post_setting_parser_info = {
+       .name = "auth_passdb_post",
+
+       .defines = auth_passdb_post_setting_defines,
+       .defaults = &auth_passdb_post_default_settings,
+
+       .struct_size = sizeof(struct auth_passdb_post_settings),
+       .pool_offset1 = 1 + offsetof(struct auth_passdb_post_settings, pool),
+};
+
 #undef DEF
 #define DEF(type, name) \
        SETTING_DEFINE_STRUCT_##type("userdb_"#name, name, struct auth_userdb_settings)
index 2ee0f0d58ef8523f949bc25daefd2e493a5e2ece..1f0cdbe74f534cd6e944183253ff5ca8666d7d95 100644 (file)
@@ -4,13 +4,21 @@
 struct master_service;
 struct master_service_settings_output;
 
+struct auth_passdb_pre_settings {
+       pool_t pool;
+       ARRAY_TYPE(const_string) default_fields;
+};
+
+struct auth_passdb_post_settings {
+       pool_t pool;
+       ARRAY_TYPE(const_string) override_fields;
+};
+
 struct auth_passdb_settings {
        pool_t pool;
        const char *name;
        const char *driver;
        const char *args;
-       const char *default_fields;
-       const char *override_fields;
        ARRAY_TYPE(const_string) mechanisms;
        const char *username_filter;
 
@@ -98,6 +106,8 @@ struct auth_settings {
 };
 
 extern const struct setting_parser_info auth_setting_parser_info;
+extern const struct setting_parser_info auth_passdb_pre_setting_parser_info;
+extern const struct setting_parser_info auth_passdb_post_setting_parser_info;
 extern const struct auth_settings *global_auth_settings;
 
 void auth_settings_read(struct master_service_settings_output *output_r);
index ed65e80de3956ffa0613e630bdfe25a2da5f989a..608fdfea2f839ed331014875c35c042390c01fc2 100644 (file)
@@ -92,7 +92,6 @@ auth_passdb_preinit(struct auth *auth, const struct auth_passdb_settings *set,
        auth_passdb = p_new(auth->pool, struct auth_passdb, 1);
        auth_passdb->auth_set =
                settings_get_or_fatal(event, &auth_setting_parser_info);
-       event_unref(&event);
 
        auth_passdb->name = set->name;
        auth_passdb->set = set;
@@ -104,11 +103,6 @@ auth_passdb_preinit(struct auth *auth, const struct auth_passdb_settings *set,
        auth_passdb->result_internalfail =
                auth_db_rule_parse(set->result_internalfail);
 
-       auth_passdb->default_fields_tmpl =
-               passdb_template_build(auth->pool, set->default_fields);
-       auth_passdb->override_fields_tmpl =
-               passdb_template_build(auth->pool, set->override_fields);
-
        if (!array_is_created(&set->mechanisms) ||
            array_is_empty(&set->mechanisms)) {
                auth_passdb->mechanisms = NULL;
@@ -130,13 +124,22 @@ auth_passdb_preinit(struct auth *auth, const struct auth_passdb_settings *set,
        auth_passdb->passdb = passdb_preinit(auth->pool, set);
        /* make sure any %variables in default_fields exist in cache_key */
        if (auth_passdb->passdb->default_cache_key != NULL) {
-               auth_passdb->cache_key =
-                       p_strconcat(auth->pool, auth_passdb->passdb->default_cache_key,
-                               set->default_fields, NULL);
-       }
-       else {
+               struct auth_passdb_pre_settings *passdb_pre_set;
+               const char *error;
+               if (settings_get(event, &auth_passdb_pre_setting_parser_info,
+                                SETTINGS_GET_FLAG_NO_EXPAND,
+                                &passdb_pre_set, &error) < 0)
+                       i_fatal("%s", error);
+               auth_passdb->cache_key = p_strconcat(
+                       auth->pool,
+                       auth_passdb->passdb->default_cache_key,
+                       t_array_const_string_join(&passdb_pre_set->default_fields, ""),
+                       NULL);
+               settings_free(passdb_pre_set);
+       } else {
                auth_passdb->cache_key = NULL;
        }
+       event_unref(&event);
 }
 
 static void auth_passdb_deinit(struct auth_passdb *passdb)
index badde58b12c573b5e7373659d99b8457392a88df..f221b05d4fd4ecc8e7550bf195db4367942bec62 100644 (file)
@@ -40,9 +40,6 @@ struct auth_passdb {
        /* The caching key for this passdb, or NULL if caching isn't wanted. */
        const char *cache_key;
 
-       struct passdb_template *default_fields_tmpl;
-       struct passdb_template *override_fields_tmpl;
-
        /* Supported authentication mechanisms, NULL is all, {NULL} is none */
        const char *const *mechanisms;
        /* Username filter, NULL is no filter */
index 047aac4302efabf454cf9a3bd0558b6c57259df2..226a7e350ccaa16b47d0db68b448cfa8f85c3790 100644 (file)
@@ -47,8 +47,6 @@ struct auth_passdb_settings mock_passdb_set = {
        .name = "mock",
        .driver = "mock",
        .args = "",
-       .default_fields = "",
-       .override_fields = "",
        .mechanisms = ARRAY_INIT,
        .username_filter = "",
        .skip = "never",
@@ -72,8 +70,6 @@ void passdb_mock_mod_init(void)
                .name = "mock",
                .driver = "mock",
                .args = "",
-               .default_fields = "",
-               .override_fields = "",
                .mechanisms = ARRAY_INIT,
                .username_filter = "",