From: Timo Sirainen Date: Thu, 5 Jan 2023 11:27:27 +0000 (+0200) Subject: *-login: Use master_service_settings_get[_or_fatal]() X-Git-Tag: 2.4.0~2325 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c6a0b4e7f795c7fe9c152437cb35ae4c26df372c;p=thirdparty%2Fdovecot%2Fcore.git *-login: Use master_service_settings_get[_or_fatal]() --- diff --git a/src/imap-login/imap-login-client.c b/src/imap-login/imap-login-client.c index 0ecef9f26f..2d9f82dacd 100644 --- a/src/imap-login/imap-login-client.c +++ b/src/imap-login/imap-login-client.c @@ -11,6 +11,7 @@ #include "imap-id.h" #include "imap-resp-code.h" #include "master-service.h" +#include "master-service-settings.h" #include "master-service-ssl-settings.h" #include "login-client.h" #include "imap-login-client.h" @@ -376,11 +377,18 @@ static struct client *imap_client_alloc(pool_t pool) return &imap_client->common; } -static int imap_client_create(struct client *client, void **other_sets) +static int imap_client_create(struct client *client) { struct imap_client *imap_client = (struct imap_client *)client; + const char *error; + + if (master_service_settings_get(client->event, + &imap_login_setting_parser_info, 0, + &imap_client->set, &error) < 0) { + e_error(client->event, "%s", error); + return -1; + } - imap_client->set = other_sets[0]; imap_client->parser = imap_parser_create(imap_client->common.input, imap_client->common.output, @@ -402,6 +410,7 @@ static void imap_client_destroy(struct client *client) cmd_id_free(imap_client); } + master_service_settings_free(imap_client->set); i_free_and_null(imap_client->proxy_backend_capability); imap_parser_unref(&imap_client->parser); } diff --git a/src/imap-login/imap-login-settings.c b/src/imap-login/imap-login-settings.c index d12e4a82b8..d32eb8c3cd 100644 --- a/src/imap-login/imap-login-settings.c +++ b/src/imap-login/imap-login-settings.c @@ -100,12 +100,13 @@ static const struct setting_parser_info *imap_login_setting_dependencies[] = { NULL }; -static const struct setting_parser_info imap_login_setting_parser_info = { +const struct setting_parser_info imap_login_setting_parser_info = { .module_name = "imap-login", .defines = imap_login_setting_defines, .defaults = &imap_login_default_settings, .struct_size = sizeof(struct imap_login_settings), + .pool_offset1 = 1 + offsetof(struct imap_login_settings, pool), .dependencies = imap_login_setting_dependencies }; diff --git a/src/imap-login/imap-login-settings.h b/src/imap-login/imap-login-settings.h index cb4f2d8c27..00ca7202ea 100644 --- a/src/imap-login/imap-login-settings.h +++ b/src/imap-login/imap-login-settings.h @@ -2,6 +2,7 @@ #define IMAP_LOGIN_SETTINGS_H struct imap_login_settings { + pool_t pool; const char *imap_capability; const char *imap_id_send; bool imap_literal_minus; @@ -9,5 +10,6 @@ struct imap_login_settings { }; extern const struct setting_parser_info *imap_login_setting_roots[]; +extern const struct setting_parser_info imap_login_setting_parser_info; #endif diff --git a/src/imap-urlauth-login/imap-urlauth-login.c b/src/imap-urlauth-login/imap-urlauth-login.c index 12df297d73..cb4f8e8d3e 100644 --- a/src/imap-urlauth-login/imap-urlauth-login.c +++ b/src/imap-urlauth-login/imap-urlauth-login.c @@ -19,8 +19,6 @@ struct imap_urlauth_client { struct client common; - const struct imap_urlauth_login_settings *set; - bool version_received:1; }; @@ -143,13 +141,8 @@ static struct client *imap_urlauth_client_alloc(pool_t pool) return &uauth_client->common; } -static int imap_urlauth_client_create -(struct client *client, void **other_sets) +static int imap_urlauth_client_create(struct client *client) { - struct imap_urlauth_client *uauth_client = - (struct imap_urlauth_client *)client; - - uauth_client->set = other_sets[0]; client->io = io_add_istream(client->input, client_input, client); return 0; } diff --git a/src/login-common/client-common.c b/src/login-common/client-common.c index 89025fe33b..446679dc12 100644 --- a/src/login-common/client-common.c +++ b/src/login-common/client-common.c @@ -24,6 +24,7 @@ #include "var-expand.h" #include "master-interface.h" #include "master-service.h" +#include "master-service-settings.h" #include "master-service-ssl-settings.h" #include "login-client.h" #include "anvil-client.h" @@ -77,6 +78,8 @@ static_assert_array_size(client_auth_fail_code_event_reasons, CLIENT_AUTH_FAIL_CODE_COUNT); static const char *client_get_log_str(struct client *client, const char *msg); +static const struct var_expand_table * +get_var_expand_table(struct client *client); void login_client_hooks_add(struct module *module, const struct login_client_hooks *hooks) @@ -197,17 +200,47 @@ static bool client_is_trusted(struct client *client) return FALSE; } -struct client * -client_alloc(int fd, pool_t pool, - const struct master_service_connection *conn, - const struct login_settings *set, - const struct master_service_ssl_settings *ssl_set, - const struct master_service_ssl_server_settings *ssl_server_set) +static void +client_var_expand_callback(struct event *event, + const struct var_expand_table **tab_r, + const struct var_expand_func_table **func_tab_r ATTR_UNUSED) +{ + struct client *client = event_get_ptr(event, "client"); + + *tab_r = get_var_expand_table(client); +} + +static int client_settings_read(struct client *client, const char **error_r) +{ + i_assert(client->set == NULL); + + if (login_settings_read(&client->local_ip, &client->ip, + client->local_name, error_r) < 0 || + master_service_settings_get(client->event, + &login_setting_parser_info, + 0, &client->set, error_r) < 0 || + master_service_settings_get(client->event, + &master_service_ssl_setting_parser_info, + 0, &client->ssl_set, error_r) < 0 || + master_service_settings_get(client->event, + &master_service_ssl_server_setting_parser_info, + 0, &client->ssl_server_set, error_r) < 0) { + master_service_settings_free(client->set); + master_service_settings_free(client->ssl_set); + return -1; + } + return 0; +} + +int client_alloc(int fd, const struct master_service_connection *conn, + struct client **client_r) { struct client *client; + const char *error; i_assert(fd != -1); + pool_t pool = pool_alloconly_create("login client", 8*1024); client = login_binary->client_vfuncs->alloc(pool); client->v = *login_binary->client_vfuncs; if (client->v.auth_send_challenge == NULL) @@ -220,9 +253,6 @@ client_alloc(int fd, pool_t pool, client->pool = pool; client->preproxy_pool = pool_alloconly_create(MEMPOOL_GROWING"preproxy pool", 256); - client->set = set; - client->ssl_set = ssl_set; - client->ssl_server_set = ssl_server_set; p_array_init(&client->module_contexts, client->pool, 5); client->fd = fd; @@ -243,6 +273,18 @@ client_alloc(int fd, pool_t pool, event_add_ip(client->event, "remote_ip", &conn->remote_ip); event_add_int(client->event, "remote_port", conn->remote_port); event_add_str(client->event, "service", login_binary->protocol); + + /* Get settings before using log callback */ + event_set_ptr(client->event, MASTER_SERVICE_VAR_EXPAND_CALLBACK, + client_var_expand_callback); + event_set_ptr(client->event, "client", client); + if (client_settings_read(client, &error) < 0) { + e_error(client->event, "%s", error); + event_unref(&client->event); + pool_unref(&client->pool); + return -1; + } + event_set_log_message_callback(client->event, client_log_msg_callback, client); client->connection_trusted = client_is_trusted(client); @@ -282,10 +324,11 @@ client_alloc(int fd, pool_t pool, client_open_streams(client); - return client; + *client_r = client; + return 0; } -int client_init(struct client *client, void **other_sets) +int client_init(struct client *client) { if (last_client == NULL) last_client = client; @@ -298,7 +341,7 @@ int client_init(struct client *client, void **other_sets) client_idle_disconnect_timeout, client); hook_login_client_allocated(client); - if (client->v.create(client, other_sets) < 0) + if (client->v.create(client) < 0) return -1; client->create_finished = TRUE; @@ -494,6 +537,13 @@ void client_ref(struct client *client) client->refcount++; } +static void client_settings_free(struct client *client) +{ + master_service_settings_free(client->set); + master_service_settings_free(client->ssl_set); + master_service_settings_free(client->ssl_server_set); +} + bool client_unref(struct client **_client) { struct client *client = *_client; @@ -505,6 +555,7 @@ bool client_unref(struct client **_client) return TRUE; if (!client->create_finished) { + client_settings_free(client); i_stream_unref(&client->input); o_stream_unref(&client->output); pool_unref(&client->preproxy_pool); @@ -537,6 +588,7 @@ bool client_unref(struct client **_client) i_close_fd(&client->fd); event_unref(&client->event); event_unref(&client->event_auth); + client_settings_free(client); i_free(client->proxy_user); i_free(client->proxy_master_user); @@ -615,18 +667,30 @@ static int client_sni_callback(const char *name, const char **error_r, struct client *client = context; struct ssl_iostream_context *ssl_ctx; struct ssl_iostream_settings ssl_set; - void **other_sets; const char *error; if (client->ssl_servername_settings_read) return 0; client->ssl_servername_settings_read = TRUE; + const struct login_settings *old_set = client->set; + const struct master_service_ssl_settings *old_ssl_set = client->ssl_set; + const struct master_service_ssl_server_settings *old_ssl_server_set = + client->ssl_server_set; + client->set = NULL; + client->ssl_set = NULL; + client->ssl_server_set = NULL; + client->local_name = p_strdup(client->pool, name); - client->set = login_settings_read(client->pool, &client->local_ip, - &client->ip, name, - &client->ssl_set, - &client->ssl_server_set, &other_sets); + if (client_settings_read(client, error_r) < 0) { + client->set = old_set; + client->ssl_set = old_ssl_set; + client->ssl_server_set = old_ssl_server_set; + return -1; + } + master_service_settings_free(old_set); + master_service_settings_free(old_ssl_set); + master_service_settings_free(old_ssl_server_set); master_service_ssl_server_settings_to_iostream_set(client->ssl_set, client->ssl_server_set, pool_datastack_create(), &ssl_set); diff --git a/src/login-common/client-common.h b/src/login-common/client-common.h index 11ba054af8..6c22bbefdf 100644 --- a/src/login-common/client-common.h +++ b/src/login-common/client-common.h @@ -119,7 +119,7 @@ struct client_auth_reply { struct client_vfuncs { struct client *(*alloc)(pool_t pool); - int (*create)(struct client *client, void **other_sets); + int (*create)(struct client *client); void (*destroy)(struct client *client); void (*notify_auth_ready)(struct client *client); void (*notify_disconnect)(struct client *client, @@ -313,13 +313,9 @@ void login_client_hooks_add(struct module *module, const struct login_client_hooks *hooks); void login_client_hooks_remove(const struct login_client_hooks *hooks); -struct client * -client_alloc(int fd, pool_t pool, - const struct master_service_connection *conn, - const struct login_settings *set, - const struct master_service_ssl_settings *ssl_set, - const struct master_service_ssl_server_settings *ssl_server_set); -int client_init(struct client *client, void **other_sets); +int client_alloc(int fd, const struct master_service_connection *conn, + struct client **client_r); +int client_init(struct client *client); void client_disconnect(struct client *client, const char *reason, bool add_disconnected_prefix); void client_destroy(struct client *client, const char *reason); diff --git a/src/login-common/login-common.h b/src/login-common/login-common.h index b91cdbe83a..c32c7ed66a 100644 --- a/src/login-common/login-common.h +++ b/src/login-common/login-common.h @@ -60,7 +60,6 @@ extern bool login_ssl_initialized; extern const struct login_settings *global_login_settings; extern const struct master_service_ssl_settings *global_ssl_settings; -extern void **global_other_settings; extern const struct ip_addr *login_source_ips; extern unsigned int login_source_ips_idx, login_source_ips_count; diff --git a/src/login-common/login-settings.c b/src/login-common/login-settings.c index 2f5fdbf037..629d143cc7 100644 --- a/src/login-common/login-settings.c +++ b/src/login-common/login-settings.c @@ -82,6 +82,7 @@ const struct setting_parser_info login_setting_parser_info = { .defaults = &login_default_settings, .struct_size = sizeof(struct login_settings), + .pool_offset1 = 1 + offsetof(struct login_settings, pool), .check_func = login_settings_check }; @@ -110,112 +111,24 @@ static bool login_settings_check(void *_set, pool_t pool, } /* */ -static const struct var_expand_table * -login_set_var_expand_table(const struct master_service_settings_input *input) -{ - const struct var_expand_table stack_tab[] = { - { 'l', net_ip2addr(&input->local_ip), "lip" }, - { 'r', net_ip2addr(&input->remote_ip), "rip" }, - { 'p', my_pid, "pid" }, - { 's', input->service, "service" }, - { '\0', input->local_name, "local_name" }, - /* aliases */ - { '\0', net_ip2addr(&input->local_ip), "local_ip" }, - { '\0', net_ip2addr(&input->remote_ip), "remote_ip" }, - /* NOTE: Make sure login_log_format_elements_split has all these - variables (in client-common.c:get_var_expand_table()). */ - { '\0', NULL, NULL } - }; - struct var_expand_table *tab; - - tab = t_malloc_no0(sizeof(stack_tab)); - memcpy(tab, stack_tab, sizeof(stack_tab)); - return tab; -} - -static void * -login_setting_dup(pool_t pool, const struct setting_parser_info *info, - const struct setting_parser_context *parser) -{ - const char *error; - void *src_set, *dest; - - src_set = settings_parser_get_root_set(parser, info); - dest = settings_dup(info, src_set, pool); - if (!settings_check(info, pool, dest, &error)) { - const char *name = info->module_name; - - i_fatal("settings_check(%s) failed: %s", - name != NULL ? name : "unknown", error); - } - return dest; -} - -static struct login_settings * -login_settings_read_real( - pool_t pool, const struct ip_addr *local_ip, - const struct ip_addr *remote_ip, const char *local_name, - const struct master_service_ssl_settings **ssl_set_r, - const struct master_service_ssl_server_settings **ssl_server_set_r, - void ***other_settings_r) +int login_settings_read(const struct ip_addr *local_ip, + const struct ip_addr *remote_ip, + const char *local_name, const char **error_r) { struct master_service_settings_input input; struct master_service_settings_output output; - const char *error; - struct setting_parser_context *parser; - void **sets; - unsigned int i, count; i_zero(&input); input.roots = login_set_roots; input.service = login_binary->protocol; input.local_name = local_name; + input.disable_check_settings = TRUE; if (local_ip != NULL) input.local_ip = *local_ip; if (remote_ip != NULL) input.remote_ip = *remote_ip; - if (master_service_settings_read(master_service, &input, - &output, &error) < 0) - i_fatal("%s", error); - parser = master_service_get_settings_parser(master_service); - - for (count = 0; input.roots[count] != NULL; count++) ; - sets = p_new(pool, void *, count + 1); - for (i = 0; i < count; i++) - sets[i] = login_setting_dup(pool, input.roots[i], parser); - - if (settings_var_expand(&login_setting_parser_info, sets[0], pool, - login_set_var_expand_table(&input), &error) <= 0) - i_fatal("Failed to expand settings: %s", error); - - *ssl_set_r = - login_setting_dup(pool, &master_service_ssl_setting_parser_info, - parser); - *ssl_server_set_r = - login_setting_dup(pool, &master_service_ssl_server_setting_parser_info, - parser); - *other_settings_r = sets + 1; - return sets[0]; -} - -struct login_settings * -login_settings_read( - pool_t pool, const struct ip_addr *local_ip, - const struct ip_addr *remote_ip, const char *local_name, - const struct master_service_ssl_settings **ssl_set_r, - const struct master_service_ssl_server_settings **ssl_server_set_r, - void ***other_settings_r) -{ - struct login_settings *login_set; - - T_BEGIN { - login_set = login_settings_read_real(pool, local_ip, remote_ip, - local_name, ssl_set_r, - ssl_server_set_r, - other_settings_r); - } T_END; - - return login_set; + return master_service_settings_read(master_service, &input, + &output, error_r); } diff --git a/src/login-common/login-settings.h b/src/login-common/login-settings.h index 46071567f2..73f204d7a3 100644 --- a/src/login-common/login-settings.h +++ b/src/login-common/login-settings.h @@ -5,6 +5,7 @@ struct master_service_ssl_settings; struct master_service_ssl_server_settings; struct login_settings { + pool_t pool; const char *login_trusted_networks; const char *login_source_ips; const char *login_greeting; @@ -38,13 +39,9 @@ struct login_settings { extern const struct setting_parser_info **login_set_roots; extern const struct setting_parser_info login_setting_parser_info; -struct login_settings * -login_settings_read(pool_t pool, - const struct ip_addr *local_ip, - const struct ip_addr *remote_ip, - const char *local_name, - const struct master_service_ssl_settings **ssl_set_r, - const struct master_service_ssl_server_settings **ssl_server_set_r, - void ***other_settings_r) ATTR_NULL(2, 3, 4); +int login_settings_read(const struct ip_addr *local_ip, + const struct ip_addr *remote_ip, + const char *local_name, const char **error_r) + ATTR_NULL(1, 2, 3); #endif diff --git a/src/login-common/main.c b/src/login-common/main.c index 2c7f487da1..b61514a7ff 100644 --- a/src/login-common/main.c +++ b/src/login-common/main.c @@ -19,6 +19,7 @@ #include "anvil-client.h" #include "auth-client.h" #include "dsasl-client.h" +#include "master-service-settings.h" #include "master-service-ssl-settings.h" #include "login-proxy.h" @@ -153,11 +154,6 @@ static void client_connected(struct master_service_connection *conn) { struct client *client; - const struct login_settings *set; - const struct master_service_ssl_settings *ssl_set; - const struct master_service_ssl_server_settings *ssl_server_set; - pool_t pool; - void **other_sets; master_service_client_connection_accept(conn); @@ -171,13 +167,11 @@ client_connected(struct master_service_connection *conn) /* make sure we're connected (or attempting to connect) to auth */ auth_client_connect(auth_client); - pool = pool_alloconly_create("login client", 8*1024); - set = login_settings_read(pool, &conn->local_ip, - &conn->remote_ip, NULL, - &ssl_set, &ssl_server_set, &other_sets); - - client = client_alloc(conn->fd, pool, conn, set, - ssl_set, ssl_server_set); + if (client_alloc(conn->fd, conn, &client) < 0) { + net_disconnect(conn->fd); + master_service_client_connection_destroyed(master_service); + return; + } if (ssl_connections || conn->ssl) { if (client_init_ssl(client) < 0) { client_unref(&client); @@ -186,13 +180,13 @@ client_connected(struct master_service_connection *conn) return; } } - if (client_init(client, other_sets) < 0) { + if (client_init(client) < 0) { client_destroy(client, "Failed to initialize client"); return; } client->event_auth = event_create(client->event); event_add_category(client->event_auth, &event_category_auth); - event_set_min_log_level(client->event_auth, set->auth_verbose ? + event_set_min_log_level(client->event_auth, client->set->auth_verbose ? LOG_TYPE_INFO : LOG_TYPE_WARNING); timeout_remove(&auth_client_to); @@ -458,6 +452,10 @@ static void main_deinit(void) timeout_remove(&auth_client_to); client_common_deinit(); dsasl_clients_deinit(); + + master_service_settings_free(global_login_settings); + master_service_settings_free(global_ssl_settings); + master_service_settings_free(global_ssl_server_settings); } int login_binary_run(struct login_binary *binary, @@ -467,8 +465,7 @@ int login_binary_run(struct login_binary *binary, MASTER_SERVICE_FLAG_TRACK_LOGIN_STATE | MASTER_SERVICE_FLAG_HAVE_STARTTLS | MASTER_SERVICE_FLAG_NO_SSL_INIT; - pool_t set_pool; - const char *login_socket; + const char *login_socket, *error; int c; login_binary = binary; @@ -502,12 +499,15 @@ int login_binary_run(struct login_binary *binary, login_binary->preinit(); - set_pool = pool_alloconly_create("global login settings", 4096); - global_login_settings = - login_settings_read(set_pool, NULL, NULL, NULL, - &global_ssl_settings, - &global_ssl_server_settings, - &global_other_settings); + if (login_settings_read(NULL, NULL, NULL, &error) < 0 || + master_service_settings_get(NULL, &login_setting_parser_info, + MASTER_SERVICE_SETTINGS_GET_FLAG_NO_EXPAND, + &global_login_settings, &error) < 0) + i_fatal("%s", error); + global_ssl_settings = master_service_settings_get_or_fatal(NULL, + &master_service_ssl_setting_parser_info); + global_ssl_server_settings = master_service_settings_get_or_fatal(NULL, + &master_service_ssl_server_setting_parser_info); if (argv[optind] != NULL) login_socket = argv[optind]; @@ -521,7 +521,6 @@ int login_binary_run(struct login_binary *binary, master_service_run(master_service, client_connected); main_deinit(); array_free(&login_source_ips_array); - pool_unref(&set_pool); master_service_deinit(&master_service); return 0; } diff --git a/src/pop3-login/client.c b/src/pop3-login/client.c index b1042344ad..f90a5387b4 100644 --- a/src/pop3-login/client.c +++ b/src/pop3-login/client.c @@ -207,8 +207,7 @@ static struct client *pop3_client_alloc(pool_t pool) return &pop3_client->common; } -static int pop3_client_create(struct client *client ATTR_UNUSED, - void **other_sets ATTR_UNUSED) +static int pop3_client_create(struct client *client ATTR_UNUSED) { return 0; } diff --git a/src/submission-login/client.c b/src/submission-login/client.c index 6ba53caef3..95cb95ab21 100644 --- a/src/submission-login/client.c +++ b/src/submission-login/client.c @@ -12,6 +12,7 @@ #include "str.h" #include "strescape.h" #include "master-service.h" +#include "master-service-settings.h" #include "master-service-ssl-settings.h" #include "client.h" #include "client-authenticate.h" @@ -90,16 +91,22 @@ static struct client *submission_client_alloc(pool_t pool) return &subm_client->common; } -static int submission_client_create(struct client *client, - void **other_sets) +static int submission_client_create(struct client *client) { static const char *const xclient_extensions[] = { "FORWARD", NULL }; struct submission_client *subm_client = container_of(client, struct submission_client, common); struct smtp_server_settings smtp_set; + const char *error; + + if (master_service_settings_get(client->event, + &submission_login_setting_parser_info, + 0, &subm_client->set, &error) < 0) { + e_error(client->event, "%s", error); + return -1; + } - subm_client->set = other_sets[0]; client_parse_backend_capabilities(subm_client); i_zero(&smtp_set); @@ -132,6 +139,7 @@ static void submission_client_destroy(struct client *client) if (subm_client->conn != NULL) smtp_server_connection_close(&subm_client->conn, NULL); + master_service_settings_free(subm_client->set); i_free_and_null(subm_client->proxy_xclient); } diff --git a/src/submission-login/submission-login-settings.c b/src/submission-login/submission-login-settings.c index 89ba2084b7..d34484b1a3 100644 --- a/src/submission-login/submission-login-settings.c +++ b/src/submission-login/submission-login-settings.c @@ -113,6 +113,7 @@ const struct setting_parser_info submission_login_setting_parser_info = { .defaults = &submission_login_default_settings, .struct_size = sizeof(struct submission_login_settings), + .pool_offset1 = 1 + offsetof(struct submission_login_settings, pool), .check_func = submission_login_settings_check, .dependencies = submission_login_setting_dependencies }; diff --git a/src/submission-login/submission-login-settings.h b/src/submission-login/submission-login-settings.h index 57334b46d1..f4f7c2c859 100644 --- a/src/submission-login/submission-login-settings.h +++ b/src/submission-login/submission-login-settings.h @@ -9,6 +9,7 @@ enum submission_login_client_workarounds { /* */ struct submission_login_settings { + pool_t pool; const char *hostname; /* submission: */ @@ -20,5 +21,6 @@ struct submission_login_settings { }; extern const struct setting_parser_info *submission_login_setting_roots[]; +extern const struct setting_parser_info submission_login_setting_parser_info; #endif