]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
*-login: Fix error code for "Maximum number of connections from user+IP exceeded"
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 11 Mar 2024 12:30:00 +0000 (14:30 +0200)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 11 Mar 2024 12:49:22 +0000 (14:49 +0200)
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.

src/imap-login/client-authenticate.c
src/login-common/client-common-auth.c
src/login-common/client-common.h
src/login-common/sasl-server.c
src/login-common/sasl-server.h

index 45071db2af297ab9d75cb4567bdb5dd1e6b906d9..c063f1bf079fbce1e2750274f82eaf193ac60869 100644 (file)
@@ -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,
index b2ce98f9e5281adc697a2beedf210912f5b3f6d0..857efb27e88ced6154dccbc3ad543b12c76f1b41 100644 (file)
@@ -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
index ed38cf6ed58931d98996b62c0fe1228e6fe29638..9af3052bdbe22a8638acc82a7d2180cf2de894b2 100644 (file)
@@ -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,
index 66c67789abe607d4456ff1f09c574cbc4e21875a..0ed75b6375be226335c65b6af127068ad5c1b405 100644 (file)
@@ -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);
 }
index 99795e57942660a1b2af8c2e0c9d0c6e6c8c6b0e..e6b1a104bcb634213d321023081200d3c2f0721c 100644 (file)
@@ -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
 };