From: Timo Sirainen Date: Tue, 11 Jan 2022 10:11:31 +0000 (+0200) Subject: anvil: Add optional conn-guid parameter to KICK-USER command X-Git-Tag: 2.4.0~4493 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e7d9e3e33d8b85fa623046586c1960953c7f7b6e;p=thirdparty%2Fdovecot%2Fcore.git anvil: Add optional conn-guid parameter to KICK-USER command --- diff --git a/src/anvil/anvil-connection.c b/src/anvil/anvil-connection.c index 59e7ad6abf..7d6657513c 100644 --- a/src/anvil/anvil-connection.c +++ b/src/anvil/anvil-connection.c @@ -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"; diff --git a/src/anvil/connect-limit.c b/src/anvil/connect-limit.c index 012dfbd177..de48bd1bf0 100644 --- a/src/anvil/connect-limit.c +++ b/src/anvil/connect-limit.c @@ -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); diff --git a/src/anvil/connect-limit.h b/src/anvil/connect-limit.h index 5b9ae2c0eb..eecf81acb9 100644 --- a/src/anvil/connect-limit.h +++ b/src/anvil/connect-limit.h @@ -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, diff --git a/src/anvil/test-connect-limit.c b/src/anvil/test-connect-limit.c index 90a3f4468f..39056c275b 100644 --- a/src/anvil/test-connect-limit.c +++ b/src/anvil/test-connect-limit.c @@ -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);