From: Timo Sirainen Date: Fri, 30 Jan 2026 18:53:50 +0000 (+0200) Subject: *-login: Reload settings after ID/XCLIENT has changed addresses X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=db6bc64cb46477eeeae07afe7b737f018d5a331f;p=thirdparty%2Fdovecot%2Fcore.git *-login: Reload settings after ID/XCLIENT has changed addresses --- diff --git a/src/imap-login/imap-login-client.h b/src/imap-login/imap-login-client.h index cf7fb2be50..ffac6ec855 100644 --- a/src/imap-login/imap-login-client.h +++ b/src/imap-login/imap-login-client.h @@ -55,6 +55,9 @@ struct imap_client_cmd_id { an ID command with some parameters. Note that Dovecot proxy can send an ID command with both internal and external keys. */ bool seen_external_keys; + /* ID contained internal x-* keys which can affect settings. Reload + the login settings after the ID command handling is finished. */ + bool reload_settings; }; struct imap_client { diff --git a/src/imap-login/imap-login-cmd-id.c b/src/imap-login/imap-login-cmd-id.c index f7520d2196..24b365dc0c 100644 --- a/src/imap-login/imap-login-cmd-id.c +++ b/src/imap-login/imap-login-cmd-id.c @@ -6,6 +6,7 @@ #include "connection.h" #include "imap-parser.h" #include "imap-quote.h" +#include "imap-resp-code.h" #include "imap-login-settings.h" #include "imap-login-client.h" @@ -30,6 +31,7 @@ struct imap_id_params { enum imap_id_param_flag { IMAP_ID_PARAM_FLAG_KEY_IS_PREFIX = BIT(0), + IMAP_ID_PARAM_FLAG_RELOAD_SETTINGS = BIT(1), }; struct imap_id_param_handler { @@ -146,11 +148,16 @@ cmd_id_x_connected_name(struct imap_id_params *params, } static const struct imap_id_param_handler imap_login_id_params[] = { - { "x-originating-ip", 0, cmd_id_x_originating_ip }, - { "x-originating-port", 0, cmd_id_x_originating_port }, - { "x-connected-ip", 0, cmd_id_x_connected_ip }, - { "x-connected-port", 0, cmd_id_x_connected_port }, - { "x-connected-name", 0, cmd_id_x_connected_name }, + { "x-originating-ip", IMAP_ID_PARAM_FLAG_RELOAD_SETTINGS, + cmd_id_x_originating_ip }, + { "x-originating-port", IMAP_ID_PARAM_FLAG_RELOAD_SETTINGS, + cmd_id_x_originating_port }, + { "x-connected-ip", IMAP_ID_PARAM_FLAG_RELOAD_SETTINGS, + cmd_id_x_connected_ip }, + { "x-connected-port", IMAP_ID_PARAM_FLAG_RELOAD_SETTINGS, + cmd_id_x_connected_port }, + { "x-connected-name", IMAP_ID_PARAM_FLAG_RELOAD_SETTINGS, + cmd_id_x_connected_name }, { "x-proxy-ttl", 0, cmd_id_x_proxy_ttl }, { "x-session-id", 0, cmd_id_x_session_id }, { "x-session-ext-id", 0, cmd_id_x_session_id }, @@ -204,6 +211,8 @@ static bool cmd_id_handle_keyvalue(struct imap_client *client, "Client sent invalid ID parameter '%s'", key); return FALSE; } + if ((handler->flags & IMAP_ID_PARAM_FLAG_RELOAD_SETTINGS) != 0) + client->cmd_id->reload_settings = TRUE; } if (client->set->imap_id_retain && !is_login_id_param && @@ -297,7 +306,7 @@ static void cmd_id_copy_params(struct imap_client *client, } } -static void cmd_id_finish(struct imap_client *client) +static int cmd_id_finish(struct imap_client *client) { if (!client->id_logged) { client->id_logged = TRUE; @@ -335,7 +344,20 @@ static void cmd_id_finish(struct imap_client *client) cmd_id_copy_params(client, client->cmd_id->params); msg = "Trusted ID completed."; } + + if (client->cmd_id->reload_settings) { + const char *error; + if (client_addresses_changed(&client->common, &error) < 0) { + client_send_reply_code(&client->common, + IMAP_CMD_REPLY_NO, + IMAP_RESP_CODE_SERVERBUG, + "Failed to reload configuration"); + client_destroy(&client->common, error); + return -1; + } + } client_send_reply(&client->common, IMAP_CMD_REPLY_OK, msg); + return 0; } void cmd_id_free(struct imap_client *client) @@ -406,7 +428,8 @@ int cmd_id(struct imap_client *client) } if (ret == 0) { /* finished the line */ - cmd_id_finish(client); + if (cmd_id_finish(client) < 0) + return -1; cmd_id_free(client); return 1; } else if (ret == -1) { diff --git a/src/login-common/client-common.c b/src/login-common/client-common.c index 0d0135f67b..17a4ca30b6 100644 --- a/src/login-common/client-common.c +++ b/src/login-common/client-common.c @@ -705,6 +705,24 @@ void clients_destroy_all(void) clients_destroy_all_reason(MASTER_SERVICE_SHUTTING_DOWN_MSG); } +int client_addresses_changed(struct client *client, const char **error_r) +{ + const char *error; + + event_add_ip(client->event, "local_ip", &client->local_ip); + event_add_int(client->event, "local_port", client->local_port); + event_add_ip(client->event, "remote_ip", &client->ip); + event_add_int(client->event, "remote_port", client->remote_port); + event_add_str(client->event, "local_name", client->local_name); + + if (client_settings_reload(client, &error) < 0) { + e_error(client->event, "%s", error); + *error_r = error; + return -1; + } + return 0; +} + int client_settings_reload(struct client *client, const char **error_r) { const struct login_settings *old_set = client->set; diff --git a/src/login-common/client-common.h b/src/login-common/client-common.h index 1a3f58e250..bc6af6f7a0 100644 --- a/src/login-common/client-common.h +++ b/src/login-common/client-common.h @@ -361,6 +361,8 @@ bool client_unref(struct client **client) ATTR_NOWARN_UNUSED_RESULT; int client_settings_reload(struct client *client, const char **error_r) ATTR_WARN_UNUSED_RESULT; +int client_addresses_changed(struct client *client, const char **error_r) + ATTR_WARN_UNUSED_RESULT; void client_rawlog_init(struct client *client); void client_rawlog_deinit(struct client *client); diff --git a/src/pop3-login/client.c b/src/pop3-login/client.c index 46755e0c0a..ad7d9d263d 100644 --- a/src/pop3-login/client.c +++ b/src/pop3-login/client.c @@ -95,6 +95,15 @@ static bool cmd_xclient(struct pop3_client *client, const char *args) } /* args ok, set them and reset the state */ + const char *error; + if (client_addresses_changed(&client->common, &error) < 0) { + client_send_reply(&client->common, + POP3_CMD_REPLY_ERROR, + "Failed to reload configuration"); + client_destroy(&client->common, error); + return TRUE; + } + client_send_reply(&client->common, POP3_CMD_REPLY_OK, "Updated"); return TRUE; } diff --git a/src/submission-login/client.c b/src/submission-login/client.c index 1309deaed8..322b60cf43 100644 --- a/src/submission-login/client.c +++ b/src/submission-login/client.c @@ -250,6 +250,14 @@ client_connection_cmd_xclient(void *context, } } } + + const char *error; + if (client_addresses_changed(&client->common, &error) < 0) { + client_notify_disconnect(&client->common, + CLIENT_DISCONNECT_INTERNAL_ERROR, + "Failed to reload configuration"); + client_disconnect(&client->common, error); + } } static void client_connection_disconnect(void *context, const char *reason)