]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
anvil: Add optional conn-guid parameter to KICK-USER command
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Tue, 11 Jan 2022 10:11:31 +0000 (12:11 +0200)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Tue, 8 Feb 2022 09:48:24 +0000 (10:48 +0100)
src/anvil/anvil-connection.c
src/anvil/connect-limit.c
src/anvil/connect-limit.h
src/anvil/test-connect-limit.c

index 59e7ad6abf95c1e95e6f1a343a50e3cb2e56a608..7d6657513cb5c38c7a7cb87154616375b99498cb 100644 (file)
@@ -246,11 +246,12 @@ kick_user_iter(struct anvil_connection *conn, struct connect_limit_iter *iter,
                kick_user_finished(kick);
 }
 
-static void kick_user(struct anvil_connection *conn, const char *username)
+static void kick_user(struct anvil_connection *conn, const char *username,
+                     const guid_128_t conn_guid)
 {
        struct connect_limit_iter *iter;
 
-       iter = connect_limit_iter_begin(connect_limit, username);
+       iter = connect_limit_iter_begin(connect_limit, username, conn_guid);
        kick_user_iter(conn, iter, FALSE);
 }
 
@@ -351,7 +352,14 @@ anvil_connection_request(struct anvil_connection *conn,
                        *error_r = "KICK-USER: Not enough parameters";
                        return -1;
                }
-               kick_user(conn, args[0]);
+               guid_128_t conn_guid;
+               if (args[1] == NULL)
+                       guid_128_empty(conn_guid);
+               else if (guid_128_from_string(args[1], conn_guid) < 0) {
+                       *error_r = "KICK-USER: Invalid conn-guid";
+                       return -1;
+               }
+               kick_user(conn, args[0], conn_guid);
        } else if (strcmp(cmd, "KICK-ALT-USER") == 0) {
                if (args[0] == NULL || args[1] == NULL) {
                        *error_r = "KICK-ALT-USER: Not enough parameters";
index 012dfbd17747e3094b7f38503cd0c00cad05eb29..de48bd1bf0d8e80cdf8e41288300b90075030d7c 100644 (file)
@@ -613,21 +613,27 @@ connect_limit_iter_init_common(struct connect_limit *limit)
 }
 
 struct connect_limit_iter *
-connect_limit_iter_begin(struct connect_limit *limit, const char *username)
+connect_limit_iter_begin(struct connect_limit *limit, const char *username,
+                        const guid_128_t conn_guid)
 {
        struct connect_limit_iter *iter;
        struct session *session;
+       bool check_conn_guid = conn_guid != NULL &&
+               !guid_128_is_empty(conn_guid);
 
        iter = connect_limit_iter_init_common(limit);
        session = hash_table_lookup(limit->user_hash, username);
        while (session != NULL) {
-               struct connect_limit_iter_result *result =
-                       array_append_space(&iter->results);
-               result->kick_type = session->process->kick_type;
-               result->pid = session->process->pid;
-               result->service = session->userip->service;
-               result->username = session->userip->username;
-               guid_128_copy(result->conn_guid, session->conn_guid);
+               if (!check_conn_guid ||
+                   guid_128_cmp(session->conn_guid, conn_guid) == 0) {
+                       struct connect_limit_iter_result *result =
+                               array_append_space(&iter->results);
+                       result->kick_type = session->process->kick_type;
+                       result->pid = session->process->pid;
+                       result->service = session->userip->service;
+                       result->username = session->userip->username;
+                       guid_128_copy(result->conn_guid, session->conn_guid);
+               }
                session = session->user_next;
        }
        array_sort(&iter->results, connect_limit_iter_result_cmp);
index 5b9ae2c0ebbbcc6946e48bc280271f7d8346243c..eecf81acb9eabd0260954f3c2b895a3ef6618b82 100644 (file)
@@ -50,9 +50,11 @@ void connect_limit_disconnect_pid(struct connect_limit *limit, pid_t pid);
 void connect_limit_dump(struct connect_limit *limit, struct ostream *output);
 
 /* Iterate through sessions of the username. The connect-limit shouldn't be
-   modified while the iterator exists. The results are sorted by pid. */
+   modified while the iterator exists. The results are sorted by pid.
+   If conn_guid is empty, all sessions are iterated. */
 struct connect_limit_iter *
-connect_limit_iter_begin(struct connect_limit *limit, const char *username);
+connect_limit_iter_begin(struct connect_limit *limit, const char *username,
+                        const guid_128_t conn_guid);
 struct connect_limit_iter *
 connect_limit_iter_begin_alt_username(struct connect_limit *limit,
                                      const char *alt_username_field,
index 90a3f4468f538767d21f9727b7ef63edd4a30ef6..39056c275b6e2ad25c5fdd3972075b5d70aa5513 100644 (file)
@@ -151,7 +151,7 @@ static void test_connect_limit(void)
 
        /* test user iteration for user1 */
        struct connect_limit_iter *iter =
-               connect_limit_iter_begin(limit, "user1");
+               connect_limit_iter_begin(limit, "user1", NULL);
        struct connect_limit_iter_result iter_result;
        test_assert(connect_limit_iter_next(iter, &iter_result));
        test_assert(iter_result.pid == 501 &&
@@ -167,7 +167,7 @@ static void test_connect_limit(void)
        connect_limit_iter_deinit(&iter);
 
        /* test user iteration for user2 */
-       iter = connect_limit_iter_begin(limit, "user2");
+       iter = connect_limit_iter_begin(limit, "user2", NULL);
        test_assert(connect_limit_iter_next(iter, &iter_result));
        test_assert(iter_result.pid == 600 &&
                    strcmp(iter_result.service, "service2") == 0 &&
@@ -177,7 +177,7 @@ static void test_connect_limit(void)
        connect_limit_iter_deinit(&iter);
 
        /* test user iteration for nonexistent user3 */
-       iter = connect_limit_iter_begin(limit, "user3");
+       iter = connect_limit_iter_begin(limit, "user3", NULL);
        test_assert(!connect_limit_iter_next(iter, &iter_result));
        connect_limit_iter_deinit(&iter);