Transport: fix smtp under combo of mua_wrapper and limited max_rcpt
authorJeremy Harris <jgh146exb@wizmail.org>
Sat, 15 Apr 2017 15:22:52 +0000 (16:22 +0100)
committerHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
Wed, 28 Jun 2017 09:18:06 +0000 (11:18 +0200)
(cherry picked from commit 4c2471caf34b901ee481cd1e742b3620e734b16b)

doc/doc-txt/ChangeLog
src/src/transports/smtp.c

index 8035ec4a580c0ed0ccbf70be15b451a113b512b6..7c70bc97e32415c999b2534e7c9be2a0cba7c927 100644 (file)
@@ -21,6 +21,10 @@ JH/06 Default openssl_options to include +no_ticket, to reduce load on peers.
       by default on recent versions (3.1.3 +) unless the PFS priority string
       is used (3.2.4 +).
 
+JH/07 Fix smtp transport use of limited max_rcpt under mua_wrapper. Previously
+      the check for any unsuccessful recipients did not notice the limit, and
+      erroneously found still-pending ones.
+
 
 Exim version 4.89
 -----------------
index 0bbd8d96e1adfb36a42aff0b815925763bb56878..ecb4e79a98ad29a1e43033e2a55109adaff69110 100644 (file)
@@ -789,7 +789,9 @@ with an address by scanning for the next address whose status is PENDING_DEFER.
 
 while (count-- > 0)
   {
-  while (addr->transport_return != PENDING_DEFER) addr = addr->next;
+  while (addr->transport_return != PENDING_DEFER)
+    if (!(addr = addr->next))
+      return -2;
 
   /* The address was accepted */
   addr->host_used = sx->host;
@@ -2435,7 +2437,8 @@ for (addr = sx->first_addr, address_count = 0;
     ? dsn_support_yes : dsn_support_no;
 
   address_count++;
-  no_flush = pipelining_active && !sx->verify && (!mua_wrapper || addr->next);
+  no_flush = pipelining_active && !sx->verify
+         && (!mua_wrapper || addr->next && address_count < sx->max_rcpt);
 
   build_rcptcmd_options(sx, addr);
 
@@ -2636,16 +2639,36 @@ RCPT. */
 
 if (mua_wrapper)
   {
-  address_item *badaddr;
-  for (badaddr = sx.first_addr; badaddr; badaddr = badaddr->next)
-    if (badaddr->transport_return != PENDING_OK)
-      {
-      /*XXX could we find a better errno than 0 here? */
-      set_errno_nohost(addrlist, 0, badaddr->message, FAIL,
-       testflag(badaddr, af_pass_message));
-      sx.ok = FALSE;
-      break;
-      }
+  /* Initiate a message transfer. */
+
+  switch(smtp_write_mail_and_rcpt_cmds(&sx, &yield))
+    {
+    case 0:            break;
+    case -1: case -2:  goto RESPONSE_FAILED;
+    case -3:           goto END_OFF;
+    case -4:           goto SEND_QUIT;
+    default:           goto SEND_FAILED;
+    }
+
+  /* If we are an MUA wrapper, abort if any RCPTs were rejected, either
+  permanently or temporarily. We should have flushed and synced after the last
+  RCPT. */
+
+  if (mua_wrapper)
+    {
+    address_item * a;
+    unsigned cnt;
+
+    for (a = sx.first_addr, cnt = 0; a && cnt < sx.max_rcpt; a = a->next, cnt++)
+      if (a->transport_return != PENDING_OK)
+       {
+       /*XXX could we find a better errno than 0 here? */
+       set_errno_nohost(addrlist, 0, a->message, FAIL,
+         testflag(a, af_pass_message));
+       sx.ok = FALSE;
+       break;
+       }
+    }
   }
 
 /* If ok is TRUE, we know we have got at least one good recipient, and must now