From: Timo Sirainen Date: Tue, 25 Jan 2022 10:48:55 +0000 (+0100) Subject: imap-hibernate: Support kicking connections X-Git-Tag: 2.4.0~4394 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3cb6ecf81f9c6077cd713bb152fc1883ca946ee4;p=thirdparty%2Fdovecot%2Fcore.git imap-hibernate: Support kicking connections --- diff --git a/src/imap-hibernate/imap-client.c b/src/imap-hibernate/imap-client.c index 55ffd528d0..0928837c5e 100644 --- a/src/imap-hibernate/imap-client.c +++ b/src/imap-hibernate/imap-client.c @@ -637,7 +637,7 @@ imap_client_create(int fd, const struct imap_client_state *state) .ip = client->state.remote_ip, }; if (master_service_anvil_connect(master_service, &anvil_session, - FALSE, client->state.anvil_conn_guid)) + TRUE, client->state.anvil_conn_guid)) client->state.anvil_sent = TRUE; p_array_init(&client->notifys, pool, 2); @@ -787,6 +787,21 @@ static void imap_client_kick(struct imap_client *client) imap_client_destroy(&client, MASTER_SERVICE_SHUTTING_DOWN_MSG); } +unsigned int imap_clients_kick(const char *user, const guid_128_t conn_guid) +{ + struct imap_client *client, *next; + unsigned int count = 0; + + for (client = imap_clients; client != NULL; client = next) { + next = client->next; + if (strcmp(client->state.username, user) == 0 && + (guid_128_is_empty(conn_guid) || + guid_128_cmp(client->state.anvil_conn_guid, conn_guid) == 0)) + imap_client_kick(client); + } + return count; +} + void imap_clients_init(void) { unhibernate_queue = priorityq_init(client_unhibernate_cmp, 64); diff --git a/src/imap-hibernate/imap-client.h b/src/imap-hibernate/imap-client.h index 185da7e243..edc2ff2ee3 100644 --- a/src/imap-hibernate/imap-client.h +++ b/src/imap-hibernate/imap-client.h @@ -35,6 +35,8 @@ void imap_client_add_notify_fd(struct imap_client *client, int fd); void imap_client_create_finish(struct imap_client *client); void imap_client_destroy(struct imap_client **_client, const char *reason); +unsigned int imap_clients_kick(const char *user, const guid_128_t conn_guid); + void imap_clients_init(void); void imap_clients_deinit(void); diff --git a/src/imap-hibernate/imap-hibernate-settings.c b/src/imap-hibernate/imap-hibernate-settings.c index d7618c0248..8a09483228 100644 --- a/src/imap-hibernate/imap-hibernate-settings.c +++ b/src/imap-hibernate/imap-hibernate-settings.c @@ -10,10 +10,12 @@ /* */ static struct file_listener_settings imap_hibernate_unix_listeners_array[] = { - { "imap-hibernate", 0660, "", "$default_internal_group" } + { "imap-hibernate", 0660, "", "$default_internal_group" }, + { "srv.imap-hibernate/%{pid}", 0600, "", "" }, }; static struct file_listener_settings *imap_hibernate_unix_listeners[] = { - &imap_hibernate_unix_listeners_array[0] + &imap_hibernate_unix_listeners_array[0], + &imap_hibernate_unix_listeners_array[1], }; static buffer_t imap_hibernate_unix_listeners_buf = { { { imap_hibernate_unix_listeners, sizeof(imap_hibernate_unix_listeners) } } diff --git a/src/imap-hibernate/main.c b/src/imap-hibernate/main.c index dce14e0116..2221d906a8 100644 --- a/src/imap-hibernate/main.c +++ b/src/imap-hibernate/main.c @@ -3,6 +3,7 @@ #include "lib.h" #include "restrict-access.h" #include "master-service.h" +#include "master-admin-client.h" #include "master-service-settings.h" #include "imap-client.h" #include "imap-hibernate-client.h" @@ -10,6 +11,10 @@ static bool debug = FALSE; +static const struct master_admin_client_callback admin_callbacks = { + .cmd_kick_user = imap_clients_kick, +}; + static void client_connected(struct master_service_connection *conn) { master_service_client_connection_accept(conn); @@ -42,6 +47,7 @@ int main(int argc, char *argv[]) restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL); restrict_access_allow_coredumps(TRUE); + master_admin_clients_init(&admin_callbacks); imap_clients_init(); imap_master_connections_init(); imap_hibernate_clients_init();