# HG changeset patch # User Timo Sirainen # Date 1475754791 -10800 # Node ID 8c389aa81c1578e42e294e3786865cebbac64542 # Parent c3cc30b7eda632d8f53e7c4690ca39fe60acafa0 doveadm proxy kick: Added -f parameter. This works for all the user_* passdb fields. diff -r c3cc30b7eda6 -r 8c389aa81c15 src/doveadm/doveadm-proxy.c --- a/src/doveadm/doveadm-proxy.c Thu Oct 06 14:38:04 2016 +0300 +++ b/src/doveadm/doveadm-proxy.c Thu Oct 06 14:53:11 2016 +0300 @@ -2,6 +2,8 @@ #include "lib.h" #include "ioloop.h" +#include "str.h" +#include "strescape.h" #include "ipc-client.h" #include "doveadm.h" #include "doveadm-print.h" @@ -11,6 +13,7 @@ struct proxy_context { struct ipc_client *ipc; + const char *username_field; }; extern struct doveadm_cmd_ver2 doveadm_cmd_proxy[]; @@ -33,6 +36,9 @@ case 'a': socket_path = optarg; break; + case 'f': + ctx->username_field = optarg; + break; default: proxy_cmd_help(cmd); } @@ -138,8 +144,9 @@ static void cmd_proxy_kick(int argc, char *argv[]) { struct proxy_context *ctx; + string_t *cmd; - ctx = cmd_proxy_init(argc, argv, "a:", cmd_proxy_kick); + ctx = cmd_proxy_init(argc, argv, "a:f:", cmd_proxy_kick); if (argv[optind] == NULL) { proxy_cmd_help(cmd_proxy_kick); @@ -149,8 +156,18 @@ doveadm_print_init(DOVEADM_PRINT_TYPE_FORMATTED); doveadm_print_formatted_set_format("%{count} connections kicked"); doveadm_print_header_simple("count"); - ipc_client_cmd(ctx->ipc, t_strdup_printf("proxy\t*\tKICK\t%s", argv[optind]), - cmd_proxy_kick_callback, NULL); + + cmd = t_str_new(128); + str_append(cmd, "proxy\t*\t"); + if (ctx->username_field == NULL) + str_append(cmd, "KICK"); + else { + str_append(cmd, "KICK-ALT\t"); + str_append_tabescaped(cmd, ctx->username_field); + } + str_append_c(cmd, '\t'); + str_append_tabescaped(cmd, argv[optind]); + ipc_client_cmd(ctx->ipc, str_c(cmd), cmd_proxy_kick_callback, NULL); io_loop_run(current_ioloop); ipc_client_deinit(&ctx->ipc); } @@ -166,10 +183,11 @@ }, { .name = "proxy kick", - .usage = "[-a ] ", + .usage = "[-a ] [-f ] ", .old_cmd = cmd_proxy_kick, DOVEADM_CMD_PARAMS_START DOVEADM_CMD_PARAM('a', "socket-path", CMD_PARAM_STR, 0) +DOVEADM_CMD_PARAM('f', "passdb-field", CMD_PARAM_STR, 0) DOVEADM_CMD_PARAM('\0', "user", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL) DOVEADM_CMD_PARAMS_END } diff -r c3cc30b7eda6 -r 8c389aa81c15 src/login-common/login-proxy.c --- a/src/login-common/login-proxy.c Thu Oct 06 14:38:04 2016 +0300 +++ b/src/login-common/login-proxy.c Thu Oct 06 14:53:11 2016 +0300 @@ -839,8 +839,32 @@ } } +static bool +want_kick_virtual_user(struct client *client, const char *const *args, + unsigned int key_idx ATTR_UNUSED) +{ + return str_array_find(args, client->virtual_user); +} + +static bool +want_kick_alt_username(struct client *client, const char *const *args, + unsigned int key_idx) +{ + unsigned int i; + + if (client->alt_usernames == NULL) + return FALSE; + for (i = 0; i < key_idx; i++) { + if (client->alt_usernames[i] == NULL) + return FALSE; + } + return str_array_find(args, client->alt_usernames[i]); +} + static void -login_proxy_cmd_kick(struct ipc_cmd *cmd, const char *const *args) +login_proxy_cmd_kick_full(struct ipc_cmd *cmd, const char *const *args, + bool (*want_kick)(struct client *, const char *const *, + unsigned int), unsigned int key_idx) { struct login_proxy *proxy, *next; unsigned int count = 0; @@ -853,7 +877,7 @@ for (proxy = login_proxies; proxy != NULL; proxy = next) { next = proxy->next; - if (strcmp(proxy->client->virtual_user, args[0]) == 0) { + if (want_kick(proxy->client, args, key_idx)) { login_proxy_free_delayed(&proxy, KILLED_BY_ADMIN_REASON); count++; } @@ -861,7 +885,7 @@ for (proxy = login_proxies_pending; proxy != NULL; proxy = next) { next = proxy->next; - if (strcmp(proxy->client->virtual_user, args[0]) == 0) { + if (want_kick(proxy->client, args, key_idx)) { client_destroy(proxy->client, "Connection kicked"); count++; } @@ -869,6 +893,36 @@ ipc_cmd_success_reply(&cmd, t_strdup_printf("%u", count)); } +static void +login_proxy_cmd_kick(struct ipc_cmd *cmd, const char *const *args) +{ + login_proxy_cmd_kick_full(cmd, args, want_kick_virtual_user, 0); +} + +static void +login_proxy_cmd_kick_alt(struct ipc_cmd *cmd, const char *const *args) +{ + char *const *fields; + unsigned int i, count; + + if (args[0] == NULL) { + ipc_cmd_fail(&cmd, "Missing parameter"); + return; + } + fields = array_get(&global_alt_usernames, &count); + for (i = 0; i < count; i++) { + if (strcmp(fields[i], args[0]) == 0) + break; + } + if (i == count) { + /* field doesn't exist, but it's not an error necessarily */ + ipc_cmd_success_reply(&cmd, "0"); + return; + } + + login_proxy_cmd_kick_full(cmd, args+1, want_kick_alt_username, i); +} + static unsigned int director_username_hash(struct client *client) { return mail_user_hash(client->virtual_user, @@ -973,6 +1027,8 @@ args++; if (strcmp(name, "KICK") == 0) login_proxy_cmd_kick(cmd, args); + else if (strcmp(name, "KICK-ALT") == 0) + login_proxy_cmd_kick_alt(cmd, args); else if (strcmp(name, "KICK-DIRECTOR-HASH") == 0) login_proxy_cmd_kick_director_hash(cmd, args); else if (strcmp(name, "LIST-FULL") == 0)