]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
*-login: Use master_service_settings_get[_or_fatal]()
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Thu, 5 Jan 2023 11:27:27 +0000 (13:27 +0200)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 20 Nov 2023 12:11:41 +0000 (14:11 +0200)
14 files changed:
src/imap-login/imap-login-client.c
src/imap-login/imap-login-settings.c
src/imap-login/imap-login-settings.h
src/imap-urlauth-login/imap-urlauth-login.c
src/login-common/client-common.c
src/login-common/client-common.h
src/login-common/login-common.h
src/login-common/login-settings.c
src/login-common/login-settings.h
src/login-common/main.c
src/pop3-login/client.c
src/submission-login/client.c
src/submission-login/submission-login-settings.c
src/submission-login/submission-login-settings.h

index 0ecef9f26fb010f76fb33cfbe713bd621e600432..2d9f82dacd04bae11d4a4765ad51236a9999e8cb 100644 (file)
@@ -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);
 }
index d12e4a82b84ba7410135222f8fe31479013e9ce1..d32eb8c3cdde88bff6ec50f688af4f887dbff3ce 100644 (file)
@@ -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
 };
 
index cb4f2d8c2753a7e972e58817f3294bd67c59b046..00ca7202ead9c8e3ff0196fa6a927fc588ea888d 100644 (file)
@@ -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
index 12df297d732a313977ef7e8484acc7f9b19dcaf9..cb4f8e8d3e546f50d6684faa67375f95cde7c254 100644 (file)
@@ -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;
 }
index 89025fe33b233ffeed09d0f6c2d63670f69a8c80..446679dc12907ea124fce724a7b4b55fb3ffc560 100644 (file)
@@ -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);
index 11ba054af855c216cdb925c6b0a565f56363cd48..6c22bbefdfe38b9fe14a865409e7583301c2b0cf 100644 (file)
@@ -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);
index b91cdbe83a65a818955293ee05b148635636bf3f..c32c7ed66aaf25e83da9bf4bcf801ddd78e9a929 100644 (file)
@@ -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;
index 2f5fdbf03752e41eb85d0ad97bcc16300279138f..629d143cc7735d87d7d4e37b099055c8fe5ad9c0 100644 (file)
@@ -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,
 }
 /* </settings checks> */
 
-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);
 }
index 46071567f293a0c485a92f1f8f4a393079ff7a7d..73f204d7a36d018473e6c4d50da0f713b6ae0898 100644 (file)
@@ -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
index 2c7f487da141cc3978c8e8d56a6d7d62ebb44326..b61514a7ff90fb8dfaf429629dded5541894bccb 100644 (file)
@@ -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;
 }
index b1042344ad78dc2be3cfef16a54f952139b8d06b..f90a5387b4a29be592c2f0f1da8fc579eff3942d 100644 (file)
@@ -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;
 }
index 6ba53caef388006cb8ea2df88b4be625b2f33c50..95cb95ab21a3b64aba6ec8b7902f5ac17ba578de 100644 (file)
@@ -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);
 }
 
index 89ba2084b7e97e8c2a915d96840bfb34f911cfb5..d34484b1a369f47f704654c345b0bc47c00995ae 100644 (file)
@@ -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
 };
index 57334b46d1e8e0965ffb0959b460bf2fe964fc44..f4f7c2c8598989b8f1ad02596ad8516e54ebb045 100644 (file)
@@ -9,6 +9,7 @@ enum submission_login_client_workarounds {
 /* </settings checks> */
 
 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