]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lmtp: local: Don't deliver more than once to the same recipient.
authorStephan Bosch <stephan.bosch@dovecot.fi>
Sat, 13 Jan 2018 10:53:43 +0000 (11:53 +0100)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Thu, 18 Jan 2018 07:10:12 +0000 (09:10 +0200)
Duplicate RCPT TO commands for local recipients are now mostly ignored,
by repeating the reply for the first instance of that RCPT TO command.

src/lmtp/lmtp-common.c
src/lmtp/lmtp-common.h
src/lmtp/lmtp-local.c

index 612ec57a628d91be06bb8f727a2d096fdc26995c..b3f13dec418b9eaec08434531f3dccb5bdc1436c 100644 (file)
@@ -26,3 +26,23 @@ void lmtp_recipient_finish(struct lmtp_recipient *rcpt,
        rcpt->index = index;
        rcpt->rcpt_cmd = NULL;
 }
+
+struct lmtp_recipient *
+lmtp_recipient_find_duplicate(struct lmtp_recipient *rcpt,
+                             struct smtp_server_transaction *trans)
+{
+       struct smtp_server_recipient *drcpt;
+       struct lmtp_recipient *dup_rcpt;
+
+       i_assert(rcpt->rcpt != NULL);
+       drcpt = smtp_server_transaction_find_rcpt_duplicate(trans, rcpt->rcpt);
+       if (drcpt == NULL)
+               return NULL;
+
+       dup_rcpt = drcpt->context;
+       i_assert(dup_rcpt->rcpt == drcpt);
+       i_assert(dup_rcpt->type == rcpt->type);
+
+       return dup_rcpt;
+}
+
index e7e90d757f92e9d6a802bd2d336d926f0cc212fe..664f933f6ea1d4273434d517ff363ac77a3ead85 100644 (file)
@@ -32,4 +32,8 @@ void lmtp_recipient_finish(struct lmtp_recipient *rcpt,
                           struct smtp_server_recipient *trcpt,
                           unsigned int index);
 
+struct lmtp_recipient *
+lmtp_recipient_find_duplicate(struct lmtp_recipient *rcpt,
+                             struct smtp_server_transaction *trans);
+
 #endif
index 9c313c011662ebe2515350adbb60fd5e08efbe61..c770e35e5b1ec30ec343bd40cb9caf786c04657c 100644 (file)
@@ -41,6 +41,8 @@ struct lmtp_local_recipient {
        struct mail_storage_service_user *service_user;
        struct anvil_query *anvil_query;
 
+       struct lmtp_local_recipient *duplicate;
+
        bool anvil_connect_sent:1;
 };
 
@@ -253,7 +255,7 @@ lmtp_local_rcpt_check_quota(struct lmtp_local_recipient *rcpt)
 
 static void lmtp_local_rcpt_finished(
        struct smtp_server_cmd_ctx *cmd,
-       struct smtp_server_transaction *trans ATTR_UNUSED,
+       struct smtp_server_transaction *trans,
        struct smtp_server_recipient *trcpt,
        unsigned int index)
 {
@@ -271,6 +273,11 @@ static void lmtp_local_rcpt_finished(
 
        lmtp_recipient_finish(&rcpt->rcpt, trcpt, index);
 
+       /* resolve duplicate recipient */
+       rcpt->duplicate = (struct lmtp_local_recipient *)
+               lmtp_recipient_find_duplicate(&rcpt->rcpt, trans);
+       i_assert(rcpt->duplicate == NULL || rcpt->duplicate->duplicate == NULL);
+
        /* add to local recipients */
        array_append(&client->local->rcpt_to, &rcpt, 1);
 }
@@ -651,6 +658,13 @@ lmtp_local_deliver_to_rcpts(struct lmtp_local *local,
        for (i = 0; i < count; i++) {
                struct lmtp_local_recipient *rcpt = rcpts[i];
 
+               if (rcpt->duplicate != NULL) {
+                       /* don't deliver more than once to the same recipient */
+                       smtp_server_reply_submit_duplicate(cmd,
+                           rcpt->rcpt.index, rcpt->duplicate->rcpt.index);
+                       continue;
+               }
+
                ret = lmtp_local_deliver(local, cmd,
                        trans, rcpt, src_mail, session);
                i_set_failure_prefix("lmtp(%s): ", my_pid);