From: Timo Sirainen Date: Thu, 5 Jul 2018 11:53:02 +0000 (+0300) Subject: director: Fix crash when user kill times out before IPC finishes X-Git-Tag: 2.2.36.1~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a5b0cc848a0974a7f0ef370eb0e0907c86d2663d;p=thirdparty%2Fdovecot%2Fcore.git director: Fix crash when user kill times out before IPC finishes Abort the IPC kick command when freeing kill context so the IPC callback won't be called. --- diff --git a/src/director/director.c b/src/director/director.c index 5fb842a9df..f4a50d5972 100644 --- a/src/director/director.c +++ b/src/director/director.c @@ -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 diff --git a/src/director/director.h b/src/director/director.h index 0a43a41817..bfda64992a 100644 --- a/src/director/director.h +++ b/src/director/director.h @@ -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;