]> 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)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Tue, 13 Nov 2018 11:09:56 +0000 (13:09 +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 2038ce8998d0e57e953ef338e8d308395b2f9cba..618316092b6d04ae0b1c980c16d53f6b9332c85a 100644 (file)
@@ -922,6 +922,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);
        timeout_remove(&kill_ctx->to_move);
        i_free(kill_ctx->socket_path);
        i_free(kill_ctx);
@@ -999,6 +1001,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. */
@@ -1103,8 +1108,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 5503f2b8611b25d6f5b63d1685b96ff2134ae9c9..ef51381536d57b5fce8d1d5280fcba7bf9255077 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;