From: Timo Sirainen Date: Mon, 11 Mar 2024 12:30:00 +0000 (+0200) Subject: *-login: Fix error code for "Maximum number of connections from user+IP exceeded" X-Git-Tag: 2.4.0~1715 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=906c97993469adf9743b2f25ac8aeddace005a73;p=thirdparty%2Fdovecot%2Fcore.git *-login: Fix error code for "Maximum number of connections from user+IP exceeded" IMAP now reports it as [LIMIT] rather than [UNAVAILABLE]. This change also causes proxy_session_finished event's error_code to change: [UNAVAILABLE] maps to proxy_dest_auth_temp_failed, while [LIMIT] maps to proxy_dest_auth_failed. --- diff --git a/src/imap-login/client-authenticate.c b/src/imap-login/client-authenticate.c index 45071db2af..c063f1bf07 100644 --- a/src/imap-login/client-authenticate.c +++ b/src/imap-login/client-authenticate.c @@ -96,6 +96,10 @@ void imap_client_auth_result(struct client *client, client_send_reply_code(client, IMAP_CMD_REPLY_NO, IMAP_RESP_CODE_UNAVAILABLE, text); break; + case CLIENT_AUTH_RESULT_LIMIT_REACHED: + client_send_reply_code(client, IMAP_CMD_REPLY_NO, + IMAP_RESP_CODE_LIMIT, text); + break; case CLIENT_AUTH_RESULT_SSL_REQUIRED: case CLIENT_AUTH_RESULT_MECH_SSL_REQUIRED: client_send_reply_code(client, IMAP_CMD_REPLY_NO, diff --git a/src/login-common/client-common-auth.c b/src/login-common/client-common-auth.c index b2ce98f9e5..857efb27e8 100644 --- a/src/login-common/client-common-auth.c +++ b/src/login-common/client-common-auth.c @@ -916,7 +916,8 @@ sasl_callback(struct client *client, enum sasl_server_reply sasl_reply, i_assert(!client->destroyed || sasl_reply == SASL_SERVER_REPLY_AUTH_ABORTED || - sasl_reply == SASL_SERVER_REPLY_MASTER_FAILED); + sasl_reply == SASL_SERVER_REPLY_MASTER_FAILED || + sasl_reply == SASL_SERVER_REPLY_MASTER_FAILED_LIMIT); client->last_auth_fail = CLIENT_AUTH_FAIL_CODE_NONE; i_zero(&reply); @@ -954,11 +955,17 @@ sasl_callback(struct client *client, enum sasl_server_reply sasl_reply, client_auth_failed(client); break; case SASL_SERVER_REPLY_MASTER_FAILED: - if (data != NULL) { + case SASL_SERVER_REPLY_MASTER_FAILED_LIMIT: + if (data == NULL) + ; + else if (sasl_reply == SASL_SERVER_REPLY_MASTER_FAILED) { /* authentication itself succeeded, we just hit some internal failure. */ client_auth_result(client, CLIENT_AUTH_RESULT_TEMPFAIL, &reply, data); + } else { + client_auth_result(client, + CLIENT_AUTH_RESULT_LIMIT_REACHED, &reply, data); } /* the fd may still be hanging somewhere in kernel or another diff --git a/src/login-common/client-common.h b/src/login-common/client-common.h index ed38cf6ed5..9af3052bdb 100644 --- a/src/login-common/client-common.h +++ b/src/login-common/client-common.h @@ -77,6 +77,7 @@ enum client_auth_result { CLIENT_AUTH_RESULT_AUTHFAILED_REASON, CLIENT_AUTH_RESULT_AUTHZFAILED, CLIENT_AUTH_RESULT_TEMPFAIL, + CLIENT_AUTH_RESULT_LIMIT_REACHED, CLIENT_AUTH_RESULT_PASS_EXPIRED, CLIENT_AUTH_RESULT_SSL_REQUIRED, CLIENT_AUTH_RESULT_INVALID_BASE64, diff --git a/src/login-common/sasl-server.c b/src/login-common/sasl-server.c index 66c67789ab..0ed75b6375 100644 --- a/src/login-common/sasl-server.c +++ b/src/login-common/sasl-server.c @@ -224,7 +224,7 @@ anvil_lookup_callback(const char *reply, struct anvil_request *req) const struct login_settings *set = client->set; const char *errmsg; unsigned int conn_count; - int ret; + enum sasl_server_reply sasl_reply = SASL_SERVER_REPLY_SUCCESS; client->anvil_query = NULL; client->anvil_request = NULL; @@ -236,18 +236,18 @@ anvil_lookup_callback(const char *reply, struct anvil_request *req) /* reply=NULL if we didn't need to do anvil lookup, or if the anvil lookup failed. allow failed anvil lookups in. */ if (reply == NULL || conn_count < set->mail_max_userip_connections) { - ret = master_send_request(req); + if (master_send_request(req) < 0) + sasl_reply = SASL_SERVER_REPLY_MASTER_FAILED; errmsg = NULL; /* client will see internal error */ } else { - ret = -1; + sasl_reply = SASL_SERVER_REPLY_MASTER_FAILED_LIMIT; errmsg = t_strdup_printf(ERR_TOO_MANY_USERIP_CONNECTIONS, set->mail_max_userip_connections); } - if (ret < 0) { + if (sasl_reply != SASL_SERVER_REPLY_SUCCESS) { client->authenticating = FALSE; auth_client_send_cancel(auth_client, client->master_auth_id); - call_client_callback(client, SASL_SERVER_REPLY_MASTER_FAILED, - errmsg, NULL); + call_client_callback(client, sasl_reply, errmsg, NULL); } i_free(req); } diff --git a/src/login-common/sasl-server.h b/src/login-common/sasl-server.h index 99795e5794..e6b1a104bc 100644 --- a/src/login-common/sasl-server.h +++ b/src/login-common/sasl-server.h @@ -9,6 +9,7 @@ enum sasl_server_reply { SASL_SERVER_REPLY_AUTH_FAILED, SASL_SERVER_REPLY_AUTH_ABORTED, SASL_SERVER_REPLY_MASTER_FAILED, + SASL_SERVER_REPLY_MASTER_FAILED_LIMIT, SASL_SERVER_REPLY_CONTINUE };