From: Timo Sirainen Date: Thu, 22 Dec 2022 12:18:03 +0000 (+0200) Subject: login-common: Disconnect reason - Return auth counts and secs for most replies X-Git-Tag: 2.4.0~2902 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5736e8e5a56bb2bbbca74db86526fa33bba6c820;p=thirdparty%2Fdovecot%2Fcore.git login-common: Disconnect reason - Return auth counts and secs for most replies Earlier some reasons weren't returned when there were more than one attempt, because it would hide if there were a lot of auth attempts. Now that the auth attempt count is always returned, these less important reasons can also be returned. --- diff --git a/src/login-common/client-common.c b/src/login-common/client-common.c index f04cb364a3..7369e10975 100644 --- a/src/login-common/client-common.c +++ b/src/login-common/client-common.c @@ -1150,57 +1150,49 @@ const char *client_get_extra_disconnect_reason(struct client *client) (unsigned int)(ioloop_time - client->created.tv_sec)); } + const char *last_reason = NULL; if (client->auth_process_comm_fail) - return "auth process communication failure"; - - /* The reasons below are returned only when there is a single - authentication attempt. The main reason is to avoid confusion in - case the client sends tons of auth attempts and disconnection just - happens to be on the last attempt. In that case it's more important - to know the total number of auth attempts instead. */ - if (client->auth_client_continue_pending && client->auth_attempts == 1) { - return t_strdup_printf("client didn't finish SASL auth, " - "waited %u secs", auth_secs); - } - if (client->auth_request != NULL && client->auth_attempts == 1) { - return t_strdup_printf("disconnected while authenticating, " - "waited %u secs", auth_secs); - } - if (client->authenticating && client->auth_attempts == 1) { - return t_strdup_printf("disconnected while finishing login, " - "waited %u secs", auth_secs); - } - if (client->auth_aborted_by_client && client->auth_attempts == 1) - return "auth aborted by client"; - - if (client->auth_nologin_referral) { + last_reason = "auth process communication failure"; + else if (client->auth_client_continue_pending) + last_reason = "client didn't finish SASL auth"; + else if (client->auth_request != NULL) + last_reason = "disconnected while authenticating"; + else if (client->authenticating) + last_reason = "disconnected while finishing login"; + else if (client->auth_aborted_by_client) + last_reason = "auth aborted by client"; + else if (client->auth_nologin_referral) { /* Referral was sent to the connecting client, which is expected to be a trusted Dovecot proxy. There should be no further auth attempts. */ - return "auth referral"; - } - if (client->proxy_auth_failed) { + last_reason = "auth referral"; + } else if (client->proxy_auth_failed) { /* Authentication to the next hop failed. */ - return "proxy dest auth failed"; + last_reason = "proxy dest auth failed"; + } else { + last_reason = client_auth_fail_code_reasons[client->last_auth_fail]; } - if (client->auth_successes > 0) { - return t_strdup_printf("internal failure, %u successful auths", - client->auth_successes); + + if (last_reason != NULL) + ; + else if (client->auth_successes > 0) { + /* ideally we wouldn't get here with such an ambiguous reason */ + last_reason = "internal failure"; + } else { + last_reason = "auth failed"; } - switch (client->last_auth_fail) { - case CLIENT_AUTH_FAIL_CODE_NONE: - break; - case CLIENT_AUTH_FAIL_CODE_AUTHZFAILED: - return t_strdup_printf( - "authorization failed, %u attempts in %u secs", - client->auth_attempts, auth_secs); - default: - return client_auth_fail_code_reasons[client->last_auth_fail]; + string_t *str = t_str_new(128); + str_append(str, last_reason); + if (client->auth_successes > 0) { + str_printfa(str, ", %u/%u successful auths ", + client->auth_successes, client->auth_attempts); + } else { + str_printfa(str, ", %u attempts ", client->auth_attempts); } - return t_strdup_printf("auth failed, %u attempts in %u secs", - client->auth_attempts, auth_secs); + str_printfa(str, "in %u secs", auth_secs); + return str_c(str); } void client_notify_disconnect(struct client *client,