From: Timo Sirainen Date: Thu, 11 Jan 2024 18:25:27 +0000 (-0500) Subject: auth: Change passdb_default_fields and passdb_override_fields to be strlist X-Git-Tag: 2.4.1~1101 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=398f80367201f939b4ac1ddc338c22baf74bb781;p=thirdparty%2Fdovecot%2Fcore.git auth: Change passdb_default_fields and passdb_override_fields to be strlist 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. --- diff --git a/src/auth/auth-request.c b/src/auth/auth-request.c index 5c7fba1f86..73741d1644 100644 --- a/src/auth/auth-request.c +++ b/src/auth/auth-request.c @@ -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) diff --git a/src/auth/auth-request.h b/src/auth/auth-request.h index 46ec97e11a..3e6117d8b8 100644 --- a/src/auth/auth-request.h +++ b/src/auth/auth-request.h @@ -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, diff --git a/src/auth/auth-settings.c b/src/auth/auth-settings.c index 2299f35eeb..a136427881 100644 --- a/src/auth/auth-settings.c +++ b/src/auth/auth-settings.c @@ -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) diff --git a/src/auth/auth-settings.h b/src/auth/auth-settings.h index 2ee0f0d58e..1f0cdbe74f 100644 --- a/src/auth/auth-settings.h +++ b/src/auth/auth-settings.h @@ -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); diff --git a/src/auth/auth.c b/src/auth/auth.c index ed65e80de3..608fdfea2f 100644 --- a/src/auth/auth.c +++ b/src/auth/auth.c @@ -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) diff --git a/src/auth/auth.h b/src/auth/auth.h index badde58b12..f221b05d4f 100644 --- a/src/auth/auth.h +++ b/src/auth/auth.h @@ -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 */ diff --git a/src/auth/test-mock.c b/src/auth/test-mock.c index 047aac4302..226a7e350c 100644 --- a/src/auth/test-mock.c +++ b/src/auth/test-mock.c @@ -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 = "",