]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
doveadm proxy kick: Added -f <passdb field> parameter.
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 6 Oct 2016 11:53:11 +0000 (14:53 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 13 Oct 2016 08:27:00 +0000 (10:27 +0200)
This works for all the user_* passdb fields.

src/doveadm/doveadm-proxy.c
src/login-common/login-proxy.c

index aba622240ea94f948c3dcd2fcda8b3993255dd01..b1d4761e05b84c7a37e42b3e2668a067ae268f39 100644 (file)
@@ -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 @@ 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);
                }
@@ -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);
@@ -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);
 }
@@ -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
 }
index 8f587c26d08ee2983990baa4ab519144867a787d..0b87a0917136d1ce4230cd441813f251cc2f1bc9 100644 (file)
@@ -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;
@@ -853,7 +877,7 @@ 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++;
                }
@@ -861,7 +885,7 @@ login_proxy_cmd_kick(struct ipc_cmd *cmd, const char *const *args)
        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 @@ login_proxy_cmd_kick(struct ipc_cmd *cmd, const char *const *args)
        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 @@ 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)