Skip to content

Commit

Permalink
doveadm proxy kick: Added -f <passdb field> parameter.
Browse files Browse the repository at this point in the history
This works for all the user_* passdb fields.
  • Loading branch information
sirainen committed Oct 13, 2016
1 parent c82b58c commit 124bfae
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 7 deletions.
26 changes: 22 additions & 4 deletions src/doveadm/doveadm-proxy.c
Expand Up @@ -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"
Expand All @@ -11,6 +13,7 @@

struct proxy_context {
struct ipc_client *ipc;
const char *username_field;
};

extern struct doveadm_cmd_ver2 doveadm_cmd_proxy[];
Expand All @@ -33,6 +36,9 @@ cmd_proxy_init(int argc, char *argv[], const char *getopt_args,
case 'a':
socket_path = optarg;
break;
case 'f':
ctx->username_field = optarg;
break;
default:
proxy_cmd_help(cmd);
}
Expand Down Expand Up @@ -138,8 +144,9 @@ static void cmd_proxy_kick_callback(enum ipc_client_cmd_state state,
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);
Expand All @@ -149,8 +156,18 @@ static void cmd_proxy_kick(int argc, char *argv[])
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);
}
Expand All @@ -166,10 +183,11 @@ DOVEADM_CMD_PARAMS_END
},
{
.name = "proxy kick",
.usage = "[-a <ipc socket path>] <user>",
.usage = "[-a <ipc socket path>] [-f <passdb field>] <user>",
.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
}
Expand Down
62 changes: 59 additions & 3 deletions src/login-common/login-proxy.c
Expand Up @@ -839,8 +839,32 @@ void login_proxy_kill_idle(void)
}
}

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;
Expand All @@ -853,22 +877,52 @@ login_proxy_cmd_kick(struct ipc_cmd *cmd, const char *const *args)
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++;
}
}
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++;
}
}
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,
Expand Down Expand Up @@ -973,6 +1027,8 @@ static void login_proxy_ipc_cmd(struct ipc_cmd *cmd, const char *line)
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)
Expand Down

0 comments on commit 124bfae

Please sign in to comment.