From: Timo Sirainen Date: Thu, 25 Feb 2021 19:58:17 +0000 (+0200) Subject: login-common: Fix assert-crash if client is destroyed during anvil lookup X-Git-Tag: 2.3.15~249 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f32daf5ac9eaa886e28659965fc0156b52b60bda;p=thirdparty%2Fdovecot%2Fcore.git login-common: Fix assert-crash if client is destroyed during anvil lookup This could happen if the client gets disconnected due to "Connection queue full". Fixes: Panic: file client-common.c: line 323 (client_destroy): assertion failed: (!client->authenticating) --- diff --git a/src/login-common/client-common.c b/src/login-common/client-common.c index b2615228ba..65ce12766b 100644 --- a/src/login-common/client-common.c +++ b/src/login-common/client-common.c @@ -24,6 +24,7 @@ #include "master-service.h" #include "master-service-ssl-settings.h" #include "master-auth.h" +#include "anvil-client.h" #include "auth-client.h" #include "dsasl-client.h" #include "login-proxy.h" @@ -323,6 +324,8 @@ void client_destroy(struct client *client, const char *reason) } else if (client->auth_request != NULL) { i_assert(client->authenticating); sasl_server_auth_abort(client); + } else if (client->anvil_query != NULL) { + anvil_client_query_abort(anvil, &client->anvil_query); } else { i_assert(!client->authenticating); } diff --git a/src/login-common/client-common.h b/src/login-common/client-common.h index dbcaee1cc0..93f9bb7f2b 100644 --- a/src/login-common/client-common.h +++ b/src/login-common/client-common.h @@ -193,6 +193,7 @@ struct client { time_t auth_first_started, auth_finished; const char *sasl_final_resp; const char *const *auth_passdb_args; + struct anvil_query *anvil_query; unsigned int master_auth_id; unsigned int master_tag; diff --git a/src/login-common/sasl-server.c b/src/login-common/sasl-server.c index d7b6c9db65..e4a585c513 100644 --- a/src/login-common/sasl-server.c +++ b/src/login-common/sasl-server.c @@ -221,6 +221,8 @@ anvil_lookup_callback(const char *reply, void *context) unsigned int conn_count; int ret; + client->anvil_query = NULL; + conn_count = 0; if (reply != NULL && str_to_uint(reply, &conn_count) < 0) i_fatal("Received invalid reply from anvil: %s", reply); @@ -270,7 +272,8 @@ anvil_check_too_many_connections(struct client *client, query = t_strconcat("LOOKUP\t", login_binary->protocol, "/", net_ip2addr(&client->ip), "/", str_tabescape(client->virtual_user), NULL); - anvil_client_query(anvil, query, anvil_lookup_callback, req); + client->anvil_query = + anvil_client_query(anvil, query, anvil_lookup_callback, req); } static bool