From: Jeremy Harris Date: Sat, 15 Apr 2017 15:22:52 +0000 (+0100) Subject: Transport: fix smtp under combo of mua_wrapper and limited max_rcpt X-Git-Tag: exim-4_89_1~17 X-Git-Url: https://git.exim.org/exim.git/commitdiff_plain/c92df897f31aae2f87f69349eda4ad4f295d11b2 Transport: fix smtp under combo of mua_wrapper and limited max_rcpt (cherry picked from commit 4c2471caf34b901ee481cd1e742b3620e734b16b) --- diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 8035ec4a5..7c70bc97e 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -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 ----------------- diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index 0bbd8d96e..ecb4e79a9 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -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