Cutthrough: Reflect 5xx recipient reject from target to originator
authorJeremy Harris <jgh146exb@wizmail.org>
Tue, 1 Mar 2016 20:58:00 +0000 (20:58 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Thu, 3 Mar 2016 13:25:30 +0000 (13:25 +0000)
When connection not opened by verify and target hard-rejects a RCPT,
the reject was not being passed to the originating system (just the
cutthrough connection was being dropped).  Fix this.

doc/doc-txt/ChangeLog
src/src/acl.c
src/src/functions.h
src/src/verify.c
test/confs/5400
test/log/5400
test/rejectlog/5400 [new file with mode: 0644]
test/scripts/5400-cutthrough/5400
test/stdout/5400

index eab7419be9999f07c910c591f6e5daf1114016ab..211588b400ce3cc5604c5f3adbffb2410d123d16 100644 (file)
@@ -183,6 +183,9 @@ JH/44 Bug 1800: The combination of a -bhc commandline option and cutthrough
       delivery resulted in actual delivery.  Cancel cutthrough before DATA
       stage.
 
       delivery resulted in actual delivery.  Cancel cutthrough before DATA
       stage.
 
+JH/45 Fix cutthrough, when connection not opened by verify and target hard-
+      rejects a recipient: pass the reject to the originator.
+
 
 
 Exim version 4.86
 
 
 Exim version 4.86
index d508a29e772c9b6bb78e50fd24ea963110f9ce82..f17e2848827c1ddbea3a0b44e6c932c8e92e62df 100644 (file)
@@ -4489,8 +4489,8 @@ and WHERE_RCPT and not yet opened conn as result of recipient-verify,
 and rcpt acl returned accept,
 and first recipient (cancel on any subsequents)
 open one now and run it up to RCPT acceptance.
 and rcpt acl returned accept,
 and first recipient (cancel on any subsequents)
 open one now and run it up to RCPT acceptance.
-A failed verify should cancel cutthrough request.
-
+A failed verify should cancel cutthrough request,
+and will pass the fail to the originator.
 Initial implementation:  dual-write to spool.
 Assume the rxd datastream is now being copied byte-for-byte to an open cutthrough connection.
 
 Initial implementation:  dual-write to spool.
 Assume the rxd datastream is now being copied byte-for-byte to an open cutthrough connection.
 
@@ -4512,7 +4512,7 @@ case ACL_WHERE_PRDR:
   if (host_checking_callout)   /* -bhc mode */
     cancel_cutthrough_connection("host-checking mode");
   else if (rc == OK && cutthrough.delivery && rcpt_count > cutthrough.nrcpt)
   if (host_checking_callout)   /* -bhc mode */
     cancel_cutthrough_connection("host-checking mode");
   else if (rc == OK && cutthrough.delivery && rcpt_count > cutthrough.nrcpt)
-    open_cutthrough_connection(addr);
+    rc = open_cutthrough_connection(addr);
   break;
 
 case ACL_WHERE_PREDATA:
   break;
 
 case ACL_WHERE_PREDATA:
index 97af70cee8a83279e720728aad8487a74414ab27..53ed643453c109dcf43ee136841b469f6010fe9e 100644 (file)
@@ -280,7 +280,7 @@ extern BOOL    moan_to_sender(int, error_block *, header_line *, FILE *, BOOL);
 extern void    moan_write_from(FILE *);
 extern FILE   *modefopen(const uschar *, const char *, mode_t);
 
 extern void    moan_write_from(FILE *);
 extern FILE   *modefopen(const uschar *, const char *, mode_t);
 
-extern void   open_cutthrough_connection( address_item * addr );
+extern int     open_cutthrough_connection( address_item * addr );
 
 extern uschar *parse_extract_address(uschar *, uschar **, int *, int *, int *,
                  BOOL);
 
 extern uschar *parse_extract_address(uschar *, uschar **, int *, int *, int *,
                  BOOL);
index ef95394d36aeaf340c47cc6c596abbae993509b5..6aa425a5490df5e1fc59f36a1f2371584ccd6192 100644 (file)
@@ -1413,10 +1413,11 @@ return yield;
 /* Called after recipient-acl to get a cutthrough connection open when
    one was requested and a recipient-verify wasn't subsequently done.
 */
 /* Called after recipient-acl to get a cutthrough connection open when
    one was requested and a recipient-verify wasn't subsequently done.
 */
-void
+int
 open_cutthrough_connection( address_item * addr )
 {
 address_item addr2;
 open_cutthrough_connection( address_item * addr )
 {
 address_item addr2;
+int rc;
 
 /* Use a recipient-verify-callout to set up the cutthrough connection. */
 /* We must use a copy of the address for verification, because it might
 
 /* Use a recipient-verify-callout to set up the cutthrough connection. */
 /* We must use a copy of the address for verification, because it might
@@ -1425,12 +1426,12 @@ get rewritten. */
 addr2 = *addr;
 HDEBUG(D_acl) debug_printf("----------- %s cutthrough setup ------------\n",
   rcpt_count > 1 ? "more" : "start");
 addr2 = *addr;
 HDEBUG(D_acl) debug_printf("----------- %s cutthrough setup ------------\n",
   rcpt_count > 1 ? "more" : "start");
-(void) verify_address(&addr2, NULL,
+rc= verify_address(&addr2, NULL,
        vopt_is_recipient | vopt_callout_recipsender | vopt_callout_no_cache,
        CUTTHROUGH_CMD_TIMEOUT, -1, -1,
        NULL, NULL, NULL);
 HDEBUG(D_acl) debug_printf("----------- end cutthrough setup ------------\n");
        vopt_is_recipient | vopt_callout_recipsender | vopt_callout_no_cache,
        CUTTHROUGH_CMD_TIMEOUT, -1, -1,
        NULL, NULL, NULL);
 HDEBUG(D_acl) debug_printf("----------- end cutthrough setup ------------\n");
-return;
+return rc;
 }
 
 
 }
 
 
index 2bbe6965a440063371bd09eb1b47ed366daaec8e..8cf757768a74b44cb0f9032efe410e93113f3230 100644 (file)
@@ -45,6 +45,7 @@ all:
   transport = ${if eq {special_tpt}{$local_part} {smtp2}{smtp}}
   headers_remove = X-hdr-rtr
   headers_add =    X-hdr-rtr-new: $h_X-hdr-rtr:+++
   transport = ${if eq {special_tpt}{$local_part} {smtp2}{smtp}}
   headers_remove = X-hdr-rtr
   headers_add =    X-hdr-rtr-new: $h_X-hdr-rtr:+++
+  errors_to =     ""
   no_more
 
 
   no_more
 
 
index ceaeb00dd165caea63e644ad4ea8fdac724ea7e0..380b4e1e9c1c3f5777508bb4168267e621c1d002 100644 (file)
 1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss for userx@domain.com
 1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
 1999-03-02 09:44:33 rcpt for no@domain.com
 1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss for userx@domain.com
 1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
 1999-03-02 09:44:33 rcpt for no@domain.com
+1999-03-02 09:44:33 U=CALLER F=<CALLER@myhost.test.ex> rejected RCPT <no@domain.com>
 1999-03-02 09:44:33 rcpt for userx@domain.com
 1999-03-02 09:44:33 rcpt for userx@domain.com
-1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss for no@domain.com userx@domain.com
-1999-03-02 09:44:33 10HmbB-0005vi-00 -> userx@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
-1999-03-02 09:44:33 10HmbB-0005vi-00 => no@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
+1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss for userx@domain.com
+1999-03-02 09:44:33 10HmbB-0005vi-00 => userx@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
 1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
 1999-03-02 09:44:33 rcpt for userx@domain.com
 1999-03-02 09:44:33 rcpt for no@domain.com
 1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
 1999-03-02 09:44:33 rcpt for userx@domain.com
 1999-03-02 09:44:33 rcpt for no@domain.com
-1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss for userx@domain.com no@domain.com
-1999-03-02 09:44:33 10HmbC-0005vi-00 -> no@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
+1999-03-02 09:44:33 U=CALLER F=<CALLER@myhost.test.ex> rejected RCPT <no@domain.com>
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss for userx@domain.com
 1999-03-02 09:44:33 10HmbC-0005vi-00 => userx@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
 1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
 1999-03-02 09:44:33 rcpt for userx@domain.com
 1999-03-02 09:44:33 10HmbC-0005vi-00 => userx@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
 1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
 1999-03-02 09:44:33 rcpt for userx@domain.com
diff --git a/test/rejectlog/5400 b/test/rejectlog/5400
new file mode 100644 (file)
index 0000000..bc0c95b
--- /dev/null
@@ -0,0 +1,2 @@
+1999-03-02 09:44:33 U=CALLER F=<CALLER@myhost.test.ex> rejected RCPT <no@domain.com>
+1999-03-02 09:44:33 U=CALLER F=<CALLER@myhost.test.ex> rejected RCPT <no@domain.com>
index 802cf047ae59d809a39a0abf97d5604e0e4a1e66..10406c2557220c20a76e21a1e99be65d8d244a57 100644 (file)
@@ -120,8 +120,7 @@ QUIT
 #
 # cutthrough for 2 recipients in one domain
 # first one denied
 #
 # cutthrough for 2 recipients in one domain
 # first one denied
-# so we get a 2nd conn with the traditional delivery
-# (for both because it's not a real verify=recipient)
+# so we get a 2nd conn with the traditional delivery for the second
 server PORT_S 2
 220 ESMTP
 EHLO
 server PORT_S 2
 220 ESMTP
 EHLO
@@ -140,8 +139,6 @@ MAIL FROM:
 250 Sender OK
 RCPT TO:
 250 ok rcpt-1
 250 Sender OK
 RCPT TO:
 250 ok rcpt-1
-RCPT TO:
-250 ok rcpt-2
 DATA
 354 Send data
 .
 DATA
 354 Send data
 .
@@ -168,8 +165,7 @@ QUIT
 #
 # cutthrough for 2 recipients in one domain
 # second one denied
 #
 # cutthrough for 2 recipients in one domain
 # second one denied
-# so we get a 2nd conn with the traditional delivery
-# (for both because it's not a real verify=recipient)
+# so we get a 2nd conn with the traditional delivery of the 1st
 server PORT_S 2
 220 ESMTP
 EHLO
 server PORT_S 2
 220 ESMTP
 EHLO
@@ -190,8 +186,6 @@ MAIL FROM:
 250 Sender OK
 RCPT TO:
 250 ok rcpt-1
 250 Sender OK
 RCPT TO:
 250 ok rcpt-1
-RCPT TO:
-250 ok rcpt-2
 DATA
 354 Send data
 .
 DATA
 354 Send data
 .
index 20de2df0981f1bebb11e1853cf900a8861dbcdfe..9fae04fb5f47c72cd2b1174e843007e160209346 100644 (file)
@@ -50,7 +50,7 @@
 250-PIPELINING\r
 250 HELP\r
 250 OK\r
 250-PIPELINING\r
 250 HELP\r
 250 OK\r
-250 Accepted\r
+550 Administrative prohibition\r
 250 Accepted\r
 354 Enter message, ending with "." on a line by itself\r
 250 OK id=10HmbB-0005vi-00\r
 250 Accepted\r
 354 Enter message, ending with "." on a line by itself\r
 250 OK id=10HmbB-0005vi-00\r
@@ -63,7 +63,7 @@
 250 HELP\r
 250 OK\r
 250 Accepted\r
 250 HELP\r
 250 OK\r
 250 Accepted\r
-250 Accepted\r
+550 Administrative prohibition\r
 354 Enter message, ending with "." on a line by itself\r
 250 OK id=10HmbC-0005vi-00\r
 221 myhost.test.ex closing connection\r
 354 Enter message, ending with "." on a line by itself\r
 250 OK id=10HmbC-0005vi-00\r
 221 myhost.test.ex closing connection\r
@@ -255,18 +255,17 @@ Connection request from [ip4.ip4.ip4.ip4]
 220 ESMTP
 EHLO myhost.test.ex
 250 OK
 220 ESMTP
 EHLO myhost.test.ex
 250 OK
-MAIL FROM:<CALLER@myhost.test.ex>
+MAIL FROM:<>
 250 Sender OK
 250 Sender OK
-RCPT TO:<no@domain.com>
-250 ok rcpt-1
 RCPT TO:<userx@domain.com>
 RCPT TO:<userx@domain.com>
-250 ok rcpt-2
+250 ok rcpt-1
 DATA
 354 Send data
 Received: from CALLER (helo=myhost.test.ex)
        by myhost.test.ex with local-esmtp (Exim x.yz)
        (envelope-from <CALLER@myhost.test.ex>)
 DATA
 354 Send data
 Received: from CALLER (helo=myhost.test.ex)
        by myhost.test.ex with local-esmtp (Exim x.yz)
        (envelope-from <CALLER@myhost.test.ex>)
-       id 10HmbB-0005vi-00; Tue, 2 Mar 1999 09:44:33 +0000
+       id 10HmbB-0005vi-00
+       for userx@domain.com; Tue, 2 Mar 1999 09:44:33 +0000
 Message-Id: <E10HmbB-0005vi-00@myhost.test.ex>
 From: CALLER_NAME <CALLER@myhost.test.ex>
 Date: Tue, 2 Mar 1999 09:44:33 +0000
 Message-Id: <E10HmbB-0005vi-00@myhost.test.ex>
 From: CALLER_NAME <CALLER@myhost.test.ex>
 Date: Tue, 2 Mar 1999 09:44:33 +0000
@@ -296,18 +295,17 @@ Connection request from [ip4.ip4.ip4.ip4]
 220 ESMTP
 EHLO myhost.test.ex
 250 OK
 220 ESMTP
 EHLO myhost.test.ex
 250 OK
-MAIL FROM:<CALLER@myhost.test.ex>
+MAIL FROM:<>
 250 Sender OK
 RCPT TO:<userx@domain.com>
 250 ok rcpt-1
 250 Sender OK
 RCPT TO:<userx@domain.com>
 250 ok rcpt-1
-RCPT TO:<no@domain.com>
-250 ok rcpt-2
 DATA
 354 Send data
 Received: from CALLER (helo=myhost.test.ex)
        by myhost.test.ex with local-esmtp (Exim x.yz)
        (envelope-from <CALLER@myhost.test.ex>)
 DATA
 354 Send data
 Received: from CALLER (helo=myhost.test.ex)
        by myhost.test.ex with local-esmtp (Exim x.yz)
        (envelope-from <CALLER@myhost.test.ex>)
-       id 10HmbC-0005vi-00; Tue, 2 Mar 1999 09:44:33 +0000
+       id 10HmbC-0005vi-00
+       for userx@domain.com; Tue, 2 Mar 1999 09:44:33 +0000
 Message-Id: <E10HmbC-0005vi-00@myhost.test.ex>
 From: CALLER_NAME <CALLER@myhost.test.ex>
 Date: Tue, 2 Mar 1999 09:44:33 +0000
 Message-Id: <E10HmbC-0005vi-00@myhost.test.ex>
 From: CALLER_NAME <CALLER@myhost.test.ex>
 Date: Tue, 2 Mar 1999 09:44:33 +0000
@@ -347,7 +345,7 @@ Connection request from [ip4.ip4.ip4.ip4]
 220 ESMTP
 EHLO myhost.test.ex
 250 OK
 220 ESMTP
 EHLO myhost.test.ex
 250 OK
-MAIL FROM:<CALLER@myhost.test.ex>
+MAIL FROM:<>
 250 Sender OK
 RCPT TO:<userx@domain.com>
 250 ok rcpt-1
 250 Sender OK
 RCPT TO:<userx@domain.com>
 250 ok rcpt-1
@@ -372,7 +370,7 @@ Connection request from [ip4.ip4.ip4.ip4]
 220 ESMTP
 EHLO myhost.test.ex
 250 OK
 220 ESMTP
 EHLO myhost.test.ex
 250 OK
-MAIL FROM:<CALLER@myhost.test.ex>
+MAIL FROM:<>
 250 Sender OK
 RCPT TO:<special_tpt@domain.com>
 250 ok rcpt-2
 250 Sender OK
 RCPT TO:<special_tpt@domain.com>
 250 ok rcpt-2
@@ -448,7 +446,7 @@ Connection request from [ip4.ip4.ip4.ip4]
 220 ESMTP
 EHLO myhost.test.ex
 250 OK
 220 ESMTP
 EHLO myhost.test.ex
 250 OK
-MAIL FROM:<CALLER@myhost.test.ex>
+MAIL FROM:<>
 250 Sender OK
 RCPT TO:<userx@domain.com>
 250 ok rcpt-1
 250 Sender OK
 RCPT TO:<userx@domain.com>
 250 ok rcpt-1
@@ -473,7 +471,7 @@ Connection request from [ip4.ip4.ip4.ip4]
 220 ESMTP
 EHLO myhost.test.ex
 250 OK
 220 ESMTP
 EHLO myhost.test.ex
 250 OK
-MAIL FROM:<CALLER@myhost.test.ex>
+MAIL FROM:<>
 250 Sender OK
 RCPT TO:<usery@special.com>
 250 ok rcpt-2
 250 Sender OK
 RCPT TO:<usery@special.com>
 250 ok rcpt-2