From: Timo Sirainen Date: Thu, 11 Jan 2024 18:32:55 +0000 (-0500) Subject: auth: Change userdb_default_fields and userdb_override_fields to be strlist X-Git-Tag: 2.4.1~1100 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f6ff0191494cef105141c046d804298616122f70;p=thirdparty%2Fdovecot%2Fcore.git auth: Change userdb_default_fields and userdb_override_fields to be strlist Similarly to the previous passdb change, these settings were moved to their own structs. --- diff --git a/src/auth/auth-request.c b/src/auth/auth-request.c index 73741d1644..76bdb07469 100644 --- a/src/auth/auth-request.c +++ b/src/auth/auth-request.c @@ -737,7 +737,11 @@ void auth_request_userdb_lookup_begin(struct auth_request *request) event = event_create(request->event); event_add_str(event, "userdb", request->userdb->name); event_add_str(event, "userdb_id", dec2str(request->userdb->userdb->id)); - event_add_str(event, "userdb_driver", request->userdb->userdb->iface->name); + const char *userdb_driver = request->userdb->userdb->iface->name; + event_add_str(event, "userdb_driver", userdb_driver); + event_set_ptr(event, SETTINGS_EVENT_FILTER_NAME, + p_strconcat(event_get_pool(event), "userdb_", + userdb_driver, NULL)); event_set_log_prefix_callback(event, FALSE, auth_request_get_log_prefix_db, request); @@ -833,6 +837,38 @@ static int auth_request_set_override_fields(struct auth_request *request) return 0; } +int auth_request_set_userdb_default_fields(struct auth_request *request) +{ + struct event *event = authdb_event(request); + const struct auth_userdb_pre_settings *pre_set; + const char *error; + + if (settings_get(event, &auth_userdb_pre_setting_parser_info, 0, + &pre_set, &error) < 0) { + e_error(event, "%s", error); + return -1; + } + auth_request_set_userdb_strlist(request, &pre_set->default_fields); + settings_free(pre_set); + return 0; +} + +static int auth_request_set_userdb_override_fields(struct auth_request *request) +{ + struct event *event = authdb_event(request); + const struct auth_userdb_post_settings *post_set; + const char *error; + + if (settings_get(event, &auth_userdb_post_setting_parser_info, 0, + &post_set, &error) < 0) { + e_error(event, "%s", error); + return -1; + } + auth_request_set_userdb_strlist(request, &post_set->override_fields); + settings_free(post_set); + return 0; +} + static int auth_request_finish_passdb_lookup(enum passdb_result *result, struct auth_request *request, @@ -1562,7 +1598,6 @@ void auth_request_userdb_callback(enum userdb_result result, struct auth_userdb *userdb = request->userdb; struct auth_userdb *next_userdb; enum auth_db_rule result_rule; - const char *error; bool userdb_continue = FALSE; if (!request->userdb_lookup_tempfailed && @@ -1575,14 +1610,10 @@ void auth_request_userdb_callback(enum userdb_result result, if (result == USERDB_RESULT_OK) { /* this userdb lookup succeeded, preserve its extra fields */ - if (userdb_template_export(userdb->override_fields_tmpl, - request, &error) < 0) { - e_error(authdb_event(request), - "Failed to expand override_fields: %s", error); + if (auth_request_set_userdb_override_fields(request) < 0) result = USERDB_RESULT_INTERNAL_FAILURE; - } else { + else auth_fields_snapshot(request->fields.userdb_reply); - } } else { /* this userdb lookup failed, remove any extra fields it set */ @@ -1700,7 +1731,7 @@ void auth_request_lookup_user(struct auth_request *request, userdb_callback_t *callback) { struct auth_userdb *userdb = request->userdb; - const char *cache_key, *error; + const char *cache_key; request->private_callback.userdb = callback; request->user_returned_by_lookup = FALSE; @@ -1708,20 +1739,18 @@ void auth_request_lookup_user(struct auth_request *request, request->userdb_cache_result = AUTH_REQUEST_CACHE_NONE; if (request->fields.userdb_reply == NULL) auth_request_init_userdb_reply(request); + + auth_request_userdb_lookup_begin(request); + /* we still want to set default_fields. these override any existing fields set by previous userdbs (because if that is unwanted, ":protected" can be used). */ - if (userdb_template_export(userdb->default_fields_tmpl, - request, &error) < 0) { - e_error(authdb_event(request), - "Failed to expand default_fields: %s", error); + if (auth_request_set_userdb_default_fields(request) < 0) { auth_request_userdb_callback( USERDB_RESULT_INTERNAL_FAILURE, request); return; } - auth_request_userdb_lookup_begin(request); - /* (for now) auth_cache is shared between passdb and userdb */ cache_key = passdb_cache == NULL ? NULL : userdb->cache_key; if (cache_key != NULL) { @@ -2225,6 +2254,21 @@ void auth_request_set_userdb_field_values(struct auth_request *request, } } +void auth_request_set_userdb_strlist(struct auth_request *request, + const ARRAY_TYPE(const_string) *strlist) +{ + 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_userdb_field(request, fields[i], + fields[i + 1]); + } +} + static bool auth_request_proxy_is_self(struct auth_request *request) { const char *port = NULL; diff --git a/src/auth/auth-request.h b/src/auth/auth-request.h index 3e6117d8b8..f77d1f2b4c 100644 --- a/src/auth/auth-request.h +++ b/src/auth/auth-request.h @@ -333,6 +333,8 @@ void auth_request_set_userdb_field(struct auth_request *request, void auth_request_set_userdb_field_values(struct auth_request *request, const char *name, const char *const *values); +void auth_request_set_userdb_strlist(struct auth_request *request, + const ARRAY_TYPE(const_string) *strlist); /* returns -1 = failed, 0 = callback is called later, 1 = finished */ int auth_request_proxy_finish(struct auth_request *request, auth_request_proxy_cb_t *callback); @@ -413,6 +415,8 @@ void auth_request_userdb_lookup_begin(struct auth_request *request); void auth_request_userdb_lookup_end(struct auth_request *request, enum userdb_result result); +int auth_request_set_userdb_default_fields(struct auth_request *request); + /* Fetches the current authdb event, this is done because some lookups can recurse into new lookups, requiring new event, which will be returned here. */ diff --git a/src/auth/auth-settings.c b/src/auth/auth-settings.c index a136427881..7a3f9bd2db 100644 --- a/src/auth/auth-settings.c +++ b/src/auth/auth-settings.c @@ -198,8 +198,6 @@ static const struct setting_define auth_userdb_setting_defines[] = { DEF(STR, name), DEF(STR, driver), DEF(STR_NOVARS, args), - DEF(STR_NOVARS, default_fields), - DEF(STR_NOVARS, override_fields), DEF(ENUM, skip), DEF(ENUM, result_success), @@ -214,8 +212,6 @@ static const struct auth_userdb_settings auth_userdb_default_settings = { .name = "", .driver = "", .args = "", - .default_fields = "", - .override_fields = "", .skip = "never:found:notfound", .result_success = "return-ok:return:return-fail:continue:continue-ok:continue-fail", @@ -233,6 +229,49 @@ const struct setting_parser_info auth_userdb_setting_parser_info = { .pool_offset1 = 1 + offsetof(struct auth_userdb_settings, pool), }; +static const struct setting_define auth_userdb_pre_setting_defines[] = { + { .type = SET_STRLIST, .key = "userdb_default_fields", + .offset = offsetof(struct auth_userdb_pre_settings, default_fields) }, + + SETTING_DEFINE_LIST_END +}; + +static const struct auth_userdb_pre_settings auth_userdb_pre_default_settings = { + .default_fields = ARRAY_INIT, +}; + +const struct setting_parser_info auth_userdb_pre_setting_parser_info = { + .name = "auth_userdb_pre", + + .defines = auth_userdb_pre_setting_defines, + .defaults = &auth_userdb_pre_default_settings, + + .struct_size = sizeof(struct auth_userdb_pre_settings), + .pool_offset1 = 1 + offsetof(struct auth_userdb_pre_settings, pool), +}; + +static const struct setting_define auth_userdb_post_setting_defines[] = { + { .type = SET_STRLIST, .key = "userdb_override_fields", + .offset = offsetof(struct auth_userdb_post_settings, override_fields) }, + + SETTING_DEFINE_LIST_END +}; + +static const struct auth_userdb_post_settings auth_userdb_post_default_settings = { + .override_fields = ARRAY_INIT, +}; + +const struct setting_parser_info auth_userdb_post_setting_parser_info = { + .name = "auth_userdb_post", + + .defines = auth_userdb_post_setting_defines, + .defaults = &auth_userdb_post_default_settings, + + .struct_size = sizeof(struct auth_userdb_post_settings), + .pool_offset1 = 1 + offsetof(struct auth_userdb_post_settings, pool), +}; + + /* we're kind of kludging here to avoid "auth_" prefix in the struct fields */ #undef DEF #undef DEF_NOPREFIX diff --git a/src/auth/auth-settings.h b/src/auth/auth-settings.h index 1f0cdbe74f..afafa9ff5b 100644 --- a/src/auth/auth-settings.h +++ b/src/auth/auth-settings.h @@ -30,13 +30,21 @@ struct auth_passdb_settings { bool master; }; +struct auth_userdb_pre_settings { + pool_t pool; + ARRAY_TYPE(const_string) default_fields; +}; + +struct auth_userdb_post_settings { + pool_t pool; + ARRAY_TYPE(const_string) override_fields; +}; + struct auth_userdb_settings { pool_t pool; const char *name; const char *driver; const char *args; - const char *default_fields; - const char *override_fields; const char *skip; const char *result_success; @@ -108,6 +116,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 setting_parser_info auth_userdb_pre_setting_parser_info; +extern const struct setting_parser_info auth_userdb_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-worker-server.c b/src/auth/auth-worker-server.c index facea38e95..b7874e9c41 100644 --- a/src/auth/auth-worker-server.c +++ b/src/auth/auth-worker-server.c @@ -569,7 +569,6 @@ auth_worker_handle_user(struct auth_worker_command *cmd, /* lookup user */ struct auth_request *auth_request; unsigned int userdb_id; - const char *error; /* [] */ if (str_to_uint(args[0], &userdb_id) < 0) { @@ -594,10 +593,7 @@ auth_worker_handle_user(struct auth_worker_command *cmd, auth_request_userdb_lookup_begin(auth_request); if (auth_request->fields.userdb_reply == NULL) auth_request_init_userdb_reply(auth_request); - if (userdb_template_export(auth_request->userdb->default_fields_tmpl, - auth_request, &error) < 0) { - e_error(authdb_event(auth_request), - "Failed to expand default_fields: %s", error); + if (auth_request_set_userdb_default_fields(auth_request) < 0) { lookup_user_callback(USERDB_RESULT_INTERNAL_FAILURE, auth_request); return TRUE; diff --git a/src/auth/auth.c b/src/auth/auth.c index 608fdfea2f..b51c6d138d 100644 --- a/src/auth/auth.c +++ b/src/auth/auth.c @@ -25,8 +25,6 @@ static const struct auth_userdb_settings userdb_dummy_set = { .name = "", .driver = "static", .args = "", - .default_fields = "", - .override_fields = "", .skip = "never", .result_success = "return-ok", @@ -164,7 +162,6 @@ auth_userdb_preinit(struct auth *auth, const struct auth_userdb_settings *set) auth_userdb = p_new(auth->pool, struct auth_userdb, 1); auth_userdb->auth_set = settings_get_or_fatal(event, &auth_setting_parser_info); - event_unref(&event); auth_userdb->name = set->name; auth_userdb->set = set; @@ -176,26 +173,29 @@ auth_userdb_preinit(struct auth *auth, const struct auth_userdb_settings *set) auth_userdb->result_internalfail = auth_db_rule_parse(set->result_internalfail); - auth_userdb->default_fields_tmpl = - userdb_template_build(auth->pool, set->driver, - set->default_fields); - auth_userdb->override_fields_tmpl = - userdb_template_build(auth->pool, set->driver, - set->override_fields); - for (dest = &auth->userdbs; *dest != NULL; dest = &(*dest)->next) ; *dest = auth_userdb; auth_userdb->userdb = userdb_preinit(auth->pool, set); /* make sure any %variables in default_fields exist in cache_key */ if (auth_userdb->userdb->default_cache_key != NULL) { - auth_userdb->cache_key = - p_strconcat(auth->pool, auth_userdb->userdb->default_cache_key, - set->default_fields, NULL); - } - else { + struct auth_userdb_pre_settings *userdb_pre_set; + const char *error; + if (settings_get(event, &auth_userdb_pre_setting_parser_info, + SETTINGS_GET_FLAG_NO_EXPAND, + &userdb_pre_set, &error) < 0) + i_fatal("%s", error); + auth_userdb->cache_key = p_strconcat( + auth->pool, + auth_userdb->userdb->default_cache_key, + t_array_const_string_join( + &userdb_pre_set->default_fields, ""), + NULL); + settings_free(userdb_pre_set); + } else { auth_userdb->cache_key = NULL; } + event_unref(&event); } static void auth_userdb_deinit(struct auth_userdb *userdb) diff --git a/src/auth/auth.h b/src/auth/auth.h index f221b05d4f..7e59e5d8fc 100644 --- a/src/auth/auth.h +++ b/src/auth/auth.h @@ -62,9 +62,6 @@ struct auth_userdb { /* The caching key for this userdb, or NULL if caching isn't wanted. */ const char *cache_key; - struct userdb_template *default_fields_tmpl; - struct userdb_template *override_fields_tmpl; - enum auth_userdb_skip skip; enum auth_db_rule result_success; enum auth_db_rule result_failure;