]> dgit.raspbian.org Git - dovecot.git/commitdiff
[PATCH] login-common, *-login: Add proxy_dest_connection_limit error_code to proxy_se...
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Wed, 3 Dec 2025 10:06:42 +0000 (12:06 +0200)
committerNoah Meyerhans <noahm@debian.org>
Wed, 16 Sep 2026 19:06:35 +0000 (15:06 -0400)
If IMAP backend returns with [LIMIT] or POP3 backend returns with [IN-USE],
use this error code rather than the generic proxy_dest_auth_failed.
Error messages are also updated.

Gbp-Pq: Name 0001-login-common-login-Add-proxy_dest_connection_limit-e.patch

src/imap-login/imap-proxy.c
src/login-common/client-common.c
src/login-common/login-proxy.c
src/login-common/login-proxy.h
src/pop3-login/pop3-proxy.c
src/submission-login/submission-proxy.c

index 6f81dc8b67eeaa097949f863dcc58a1a2990e0ac..69680ea75230d428c06ca7a2009b2fb2acd112b9 100644 (file)
@@ -284,6 +284,12 @@ static bool auth_resp_code_is_serverbug(const char *resp)
                           strlen(IMAP_RESP_CODE_SERVERBUG"]")) == 0;
 }
 
+static bool auth_resp_code_is_limit(const char *resp)
+{
+       return strncasecmp(resp, IMAP_RESP_CODE_LIMIT"]",
+                          strlen(IMAP_RESP_CODE_LIMIT"]")) == 0;
+}
+
 static bool
 auth_resp_code_parse_referral(struct client *client, const char *resp,
                              const char **userhostport_r)
@@ -448,6 +454,8 @@ int imap_proxy_parse_line(struct client *client, const char *line)
                        else if (auth_resp_code_is_serverbug(line + 4))
                                failure_type = LOGIN_PROXY_FAILURE_TYPE_REMOTE;
                        else {
+                               if (auth_resp_code_is_limit(line + 4))
+                                       failure_type = LOGIN_PROXY_FAILURE_TYPE_AUTH_LIMIT_REACHED_REPLIED;
                                client_send_raw(client, t_strconcat(
                                        imap_client->cmd_tag, " ", line, "\r\n", NULL));
                        }
@@ -587,6 +595,7 @@ imap_proxy_send_failure_reply(struct imap_client *imap_client,
                        imap_client->cmd_tag, " NO ", reason, "\r\n", NULL));
                break;
        case LOGIN_PROXY_FAILURE_TYPE_AUTH_REPLIED:
+       case LOGIN_PROXY_FAILURE_TYPE_AUTH_LIMIT_REACHED_REPLIED:
                /* reply was already sent */
                break;
        }
index cefe157bd99cfbe73d6bda4a73669369947d5368..0c11a925f1583760e670aea01fcdb325d540a992 100644 (file)
@@ -1397,6 +1397,10 @@ bool client_get_extra_disconnect_reason(struct client *client,
                        event_reason = "redirected";
                        last_reason = "redirected";
                        break;
+               case LOGIN_PROXY_FAILURE_TYPE_AUTH_LIMIT_REACHED_REPLIED:
+                       event_reason = "connection_limit";
+                       last_reason = "connection limit reached";
+                       break;
                default:
                        i_unreached();
                }
index cba9d9d8cd1d5fdd9d8029348789f4119c86143e..0e3e8c9be23921fa6151d9c04b5945adcef0ff1f 100644 (file)
@@ -830,6 +830,7 @@ bool login_proxy_failed(struct login_proxy *proxy, struct event *event,
                log_prefix = "Remote server sent invalid input: ";
                break;
        case LOGIN_PROXY_FAILURE_TYPE_AUTH_REPLIED:
+       case LOGIN_PROXY_FAILURE_TYPE_AUTH_LIMIT_REACHED_REPLIED:
                log_prefix = "";
                try_reconnect = FALSE;
                break;
@@ -855,6 +856,7 @@ bool login_proxy_failed(struct login_proxy *proxy, struct event *event,
        }
 
        if (type != LOGIN_PROXY_FAILURE_TYPE_AUTH_REPLIED &&
+           type != LOGIN_PROXY_FAILURE_TYPE_AUTH_LIMIT_REACHED_REPLIED &&
            type != LOGIN_PROXY_FAILURE_TYPE_AUTH_TEMPFAIL)
                e_error(event, "%s%s", log_prefix, reason);
        else if (proxy->client->set->auth_verbose)
index 6465cfc6eb1defba79275c160f1f50193ab3753a..65895f3d750c09fbe935ff2418e19d604f16cf3b 100644 (file)
@@ -41,6 +41,9 @@ enum login_proxy_failure_type {
        /* Authentication requests connecting to another host. The reason
           string contains the host (and optionally :port). */
        LOGIN_PROXY_FAILURE_TYPE_AUTH_REDIRECT,
+       /* Authentication failed because user has reached some limit.
+          The LOGIN/AUTH command reply was already sent to the client. */
+       LOGIN_PROXY_FAILURE_TYPE_AUTH_LIMIT_REACHED_REPLIED,
 };
 
 struct login_proxy_settings {
index 1f2934c4b8637a970d191f9c39fa891b93da967b..f8010d3d1285c1efd860ab47e972e3d5ad881b40 100644 (file)
@@ -333,6 +333,8 @@ int pop3_proxy_parse_line(struct client *client, const char *line)
        } else if (pop3_proxy_parse_referral(client, line + 5, &line)) {
                failure_type = LOGIN_PROXY_FAILURE_TYPE_AUTH_REDIRECT;
        } else {
+               if (str_begins_with(line, "-ERR [IN-USE]"))
+                       failure_type = LOGIN_PROXY_FAILURE_TYPE_AUTH_LIMIT_REACHED_REPLIED;
                client_send_raw(client, t_strconcat(line, "\r\n", NULL));
                line += 5;
        }
@@ -374,6 +376,7 @@ pop3_proxy_send_failure_reply(struct client *client,
                client_send_reply(client, POP3_CMD_REPLY_ERROR, reason);
                break;
        case LOGIN_PROXY_FAILURE_TYPE_AUTH_REPLIED:
+       case LOGIN_PROXY_FAILURE_TYPE_AUTH_LIMIT_REACHED_REPLIED:
                /* reply was already sent */
                break;
        }
index ef1a25c264764471cc1aa8c89151eb412cb9291e..a2b7d2ff423ee987e056e3e2458440703dd813a5 100644 (file)
@@ -750,6 +750,7 @@ submission_proxy_send_failure_reply(struct submission_client *subm_client,
                smtp_server_reply_submit(subm_client->proxy_reply);
                break;
        case LOGIN_PROXY_FAILURE_TYPE_AUTH_REPLIED:
+       case LOGIN_PROXY_FAILURE_TYPE_AUTH_LIMIT_REACHED_REPLIED:
                /* reply was already sent */
                i_assert(cmd == NULL);
                break;