]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imap-hibernate: Support kicking connections
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Tue, 25 Jan 2022 10:48:55 +0000 (11:48 +0100)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Mon, 21 Feb 2022 06:30:26 +0000 (06:30 +0000)
src/imap-hibernate/imap-client.c
src/imap-hibernate/imap-client.h
src/imap-hibernate/imap-hibernate-settings.c
src/imap-hibernate/main.c

index 55ffd528d0062ace02ce83c5b33bdc0bb1e32b59..0928837c5e044896d3a734e87a1894f34eb59f09 100644 (file)
@@ -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);
index 185da7e2435011c04abe34bc50e97f22936dbbff..edc2ff2ee36de4a9fe4ed871469596239d5fed30 100644 (file)
@@ -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);
 
index d7618c02483b9fb18ff5191bd27d00243ea179e1..8a09483228563fcd129145b5650acaa8c43849d8 100644 (file)
 
 /* <settings checks> */
 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) } }
index dce14e0116e901cc0a3277ab43674b2b28f919ca..2221d906a899cc9004823e4b939767bccf8bba23 100644 (file)
@@ -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"
 
 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();