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);
}
*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";
}
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);
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,
/* 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 &&
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 &&
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);