]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
doveadm director kick command added.
authorTimo Sirainen <tss@iki.fi>
Mon, 2 Jun 2014 01:00:19 +0000 (04:00 +0300)
committerTimo Sirainen <tss@iki.fi>
Mon, 2 Jun 2014 01:00:19 +0000 (04:00 +0300)
The kick gets sent to all the proxies within the director ring.

src/director/director-connection.c
src/director/director.c
src/director/director.h
src/director/doveadm-connection.c
src/doveadm/doveadm-director.c

index a1018e9359318829dea4e15258fd8a2610ae6f5a..e9c9ed5b1184be4e0161cdf99b67eb52f03c7baf 100644 (file)
@@ -938,6 +938,25 @@ director_cmd_user_move(struct director_connection *conn,
        return TRUE;
 }
 
+static bool
+director_cmd_user_kick(struct director_connection *conn,
+                      const char *const *args)
+{
+       struct director_host *dir_host;
+       int ret;
+
+       if ((ret = director_cmd_is_seen(conn, &args, &dir_host)) != 0)
+               return ret > 0;
+
+       if (str_array_length(args) != 1) {
+               director_cmd_error(conn, "Invalid parameters");
+               return FALSE;
+       }
+
+       director_kick_user(conn->dir, conn->host, dir_host, args[0]);
+       return TRUE;
+}
+
 static bool
 director_cmd_user_killed(struct director_connection *conn,
                         const char *const *args)
@@ -1316,6 +1335,8 @@ director_connection_handle_cmd(struct director_connection *conn,
                return director_cmd_host_flush(conn, args);
        if (strcmp(cmd, "USER-MOVE") == 0)
                return director_cmd_user_move(conn, args);
+       if (strcmp(cmd, "USER-KICK") == 0)
+               return director_cmd_user_kick(conn, args);
        if (strcmp(cmd, "USER-KILLED") == 0)
                return director_cmd_user_killed(conn, args);
        if (strcmp(cmd, "USER-KILLED-EVERYWHERE") == 0)
index 9757a8a12195d4b1c0886c8b27c445edb24b9280..e02e2ab9670fb70a99d05e2136281ffa765fb5ce 100644 (file)
@@ -756,6 +756,32 @@ void director_move_user(struct director *dir, struct director_host *src,
                user->username_hash, net_ip2addr(&user->host->ip)));
 }
 
+static void
+director_kick_user_callback(enum ipc_client_cmd_state state ATTR_UNUSED,
+                           const char *data ATTR_UNUSED,
+                           void *context ATTR_UNUSED)
+{
+}
+
+void director_kick_user(struct director *dir, struct director_host *src,
+                       struct director_host *orig_src, const char *username)
+{
+       const char *cmd;
+
+       cmd = t_strdup_printf("proxy\t*\tKICK\t%s", username);
+       ipc_client_cmd(dir->ipc_proxy, cmd,
+                      director_kick_user_callback, (void *)NULL);
+
+       if (orig_src == NULL) {
+               orig_src = dir->self_host;
+               orig_src->last_seq++;
+       }
+       cmd = t_strdup_printf("USER-KICK\t%s\t%u\t%u\t%s\n",
+               net_ip2addr(&orig_src->ip), orig_src->port, orig_src->last_seq,
+               username);
+       director_update_send_version(dir, src, DIRECTOR_VERSION_USER_KICK, cmd);
+}
+
 void director_user_killed(struct director *dir, unsigned int username_hash)
 {
        struct user *user;
index 1b97cbf4b496b686a6b8c7587cb05995b3358375..87f789a14f500ea5c28fe4c081c69e416c8813c4 100644 (file)
@@ -6,14 +6,16 @@
 
 #define DIRECTOR_VERSION_NAME "director"
 #define DIRECTOR_VERSION_MAJOR 1
-#define DIRECTOR_VERSION_MINOR 3
+#define DIRECTOR_VERSION_MINOR 4
 
-/* weak users supported in protocol v1.1+ */
+/* weak users supported in protocol */
 #define DIRECTOR_VERSION_WEAK_USERS 1
-/* director removes supported in v1.2+ */
+/* director ring remove supported */
 #define DIRECTOR_VERSION_RING_REMOVE 2
-/* quit reason supported in v1.3+ */
+/* quit reason supported */
 #define DIRECTOR_VERSION_QUIT 3
+/* user-kick supported */
+#define DIRECTOR_VERSION_USER_KICK 4
 
 /* Minimum time between even attempting to communicate with a director that
    failed due to a protocol error. */
@@ -131,6 +133,9 @@ void director_move_user(struct director *dir, struct director_host *src,
                        struct director_host *orig_src,
                        unsigned int username_hash, struct mail_host *host)
        ATTR_NULL(3);
+void director_kick_user(struct director *dir, struct director_host *src,
+                       struct director_host *orig_src, const char *username)
+       ATTR_NULL(3);
 void director_user_killed(struct director *dir, unsigned int username_hash);
 void director_user_killed_everywhere(struct director *dir,
                                     struct director_host *src,
index 66bf56834874abaef1e54542ca82d37890fe99dd..02442d8df98bb5e343d0e6c850198ab579e3863b 100644 (file)
@@ -380,6 +380,22 @@ doveadm_cmd_user_move(struct doveadm_connection *conn, const char *line)
        return TRUE;
 }
 
+static bool
+doveadm_cmd_user_kick(struct doveadm_connection *conn, const char *line)
+{
+       const char *const *args;
+
+       args = t_strsplit_tab(line);
+       if (args[0] == NULL) {
+               i_error("doveadm sent invalid USER-KICK parameters: %s", line);
+               return FALSE;
+       }
+
+       director_kick_user(conn->dir, conn->dir->self_host, NULL, args[0]);
+       o_stream_nsend(conn->output, "OK\n", 3);
+       return TRUE;
+}
+
 static void doveadm_connection_input(struct doveadm_connection *conn)
 {
        const char *line, *cmd, *args;
@@ -434,6 +450,8 @@ static void doveadm_connection_input(struct doveadm_connection *conn)
                        ret = doveadm_cmd_user_list(conn, args);
                else if (strcmp(cmd, "USER-MOVE") == 0)
                        ret = doveadm_cmd_user_move(conn, args);
+               else if (strcmp(cmd, "USER-KICK") == 0)
+                       ret = doveadm_cmd_user_kick(conn, args);
                else {
                        i_error("doveadm sent unknown command: %s", line);
                        ret = FALSE;
index 6aff6d0010f38feaefd289215e74b73c1553481d..65c673046734646b331cb2d24570104a3cc2e176 100644 (file)
@@ -500,6 +500,32 @@ static void cmd_director_move(int argc, char *argv[])
        director_disconnect(ctx);
 }
 
+static void cmd_director_kick(int argc, char *argv[])
+{
+       struct director_context *ctx;
+       const char *username, *line;
+
+       ctx = cmd_director_init(argc, argv, "a:", cmd_director_kick);
+       if (argv[optind] == NULL || argv[optind+1] != NULL)
+               director_cmd_help(cmd_director_kick);
+
+       username = argv[optind];
+
+       director_send(ctx, t_strdup_printf("USER-KICK\t%s\n", username));
+       line = i_stream_read_next_line(ctx->input);
+       if (line == NULL) {
+               i_error("failed");
+               doveadm_exit_code = EX_TEMPFAIL;
+       } else if (strcmp(line, "OK") == 0) {
+               if (doveadm_verbose)
+                       printf("User %s kicked\n", username);
+       } else {
+               i_error("failed: %s", line);
+               doveadm_exit_code = EX_TEMPFAIL;
+       }
+       director_disconnect(ctx);
+}
+
 static void cmd_director_flush_all(struct director_context *ctx)
 {
        const char *line;
@@ -729,6 +755,8 @@ struct doveadm_cmd doveadm_cmd_director[] = {
          "[-a <director socket path>] <host>" },
        { cmd_director_move, "director move",
          "[-a <director socket path>] <user> <host>" },
+       { cmd_director_kick, "director kick",
+         "[-a <director socket path>] <user>" },
        { cmd_director_flush, "director flush",
          "[-a <director socket path>] <host>|all" },
        { cmd_director_dump, "director dump",