]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
director: Fix crash when user kill times out before IPC finishes
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 5 Jul 2018 11:53:02 +0000 (14:53 +0300)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Fri, 25 Jan 2019 10:47:18 +0000 (12:47 +0200)
Abort the IPC kick command when freeing kill context so the IPC callback
won't be called.

src/director/director.c
src/director/director.h

index 5fb842a9df3dbc182a78c9921accf37767ba5dc8..f4a50d59720e6b1461f9207f89212f7a4063b185 100644 (file)
@@ -925,6 +925,8 @@ static void director_user_move_free(struct user *user)
        dir_debug("User %u move finished at state=%s", user->username_hash,
                  user_kill_state_names[kill_ctx->kill_state]);
 
+       if (kill_ctx->ipc_cmd != NULL)
+               ipc_client_cmd_abort(dir->ipc_proxy, &kill_ctx->ipc_cmd);
        if (kill_ctx->to_move != NULL)
                timeout_remove(&kill_ctx->to_move);
        i_free(kill_ctx->socket_path);
@@ -1003,6 +1005,9 @@ static void director_kill_user_callback(enum ipc_client_cmd_state state,
        struct director_kill_context *ctx = context;
        struct user *user;
 
+       /* don't try to abort the IPC command anymore */
+       ctx->ipc_cmd = NULL;
+
        /* this is an asynchronous notification about user being killed.
           there are no guarantees about what might have happened to the user
           in the mean time. */
@@ -1107,8 +1112,8 @@ void director_kill_user(struct director *dir, struct director_host *src,
                                      user->username_hash);
                ctx->callback_pending = TRUE;
                dir->users_kicking_count++;
-               ipc_client_cmd(dir->ipc_proxy, cmd,
-                              director_kill_user_callback, ctx);
+               ctx->ipc_cmd = ipc_client_cmd(dir->ipc_proxy, cmd,
+                                             director_kill_user_callback, ctx);
        } else {
                /* a) we didn't even know about the user before now.
                   don't bother performing a local kick, since it wouldn't
index 0a43a41817c38055c73d815be55f7ccecbfb4961..bfda64992af0ccf8c8ab810d058748a5d7c75010 100644 (file)
@@ -90,6 +90,8 @@ struct director_kill_context {
        /* Move timeout to make sure user's connections won't silently hang
           indefinitely if there is some trouble moving it. */
        struct timeout *to_move;
+       /* IPC command to kick the user */
+       struct ipc_client_cmd *ipc_cmd;
 
        /* these are set only for director_flush_socket handling: */
        struct ip_addr host_ip;