Add recognition of SMTP error codes in bespoke messages.
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Thu, 13 Jul 2006 13:53:32 +0000 (13:53 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Thu, 13 Jul 2006 13:53:32 +0000 (13:53 +0000)
22 files changed:
doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
src/README.UPDATING
src/src/exim.c
src/src/functions.h
src/src/globals.c
src/src/globals.h
src/src/receive.c
src/src/routers/redirect.c
src/src/routers/redirect.h
src/src/smtp_in.c
test/aux-fixed/0536.aliases [new file with mode: 0644]
test/confs/0536 [new file with mode: 0644]
test/log/0536 [new file with mode: 0644]
test/mail/0536.oksender [new file with mode: 0644]
test/mail/0536.user1 [new file with mode: 0644]
test/mail/0536.user2 [new file with mode: 0644]
test/paniclog/0536 [new file with mode: 0644]
test/rejectlog/0536 [new file with mode: 0644]
test/scripts/0000-Basic/0536 [new file with mode: 0644]
test/stderr/0536 [new file with mode: 0644]
test/stdout/0536 [new file with mode: 0644]

index 90a8a83504284edaf4f7fc554e3748e9827b51af..b4d476aacb87607fb64d7c0901c0b440727abfd0 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.372 2006/07/07 14:36:04 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.373 2006/07/13 13:53:32 ph10 Exp $
 
 Change log file for Exim from version 4.21
 -------------------------------------------
 
 Change log file for Exim from version 4.21
 -------------------------------------------
@@ -89,6 +89,10 @@ PH/14 In the default configuration, change the use of "message" in ACL warn
 PH/15 Diagnose a filter syntax error for "seen", "unseen", or "noerror" if not
       not followed by a command (e.g. "seen endif").
 
 PH/15 Diagnose a filter syntax error for "seen", "unseen", or "noerror" if not
       not followed by a command (e.g. "seen endif").
 
+PH/16 Recognize SMTP codes at the start of "message" in ACLs and after :fail:
+      and :defer: in a redirect router. Add forbid_smtp_code to suppress the
+      latter.
+
 
 Exim version 4.62
 -----------------
 
 Exim version 4.62
 -----------------
index 4f7ca84709c1c0d2fb5525079d7b4332bd505615..1ec1bdd2cf5ee19784963327447da1be0e334917 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/NewStuff,v 1.104 2006/06/28 16:00:23 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/NewStuff,v 1.105 2006/07/13 13:53:32 ph10 Exp $
 
 New Features in Exim
 --------------------
 
 New Features in Exim
 --------------------
@@ -31,6 +31,19 @@ Version 4.63
    Variables such as $authenticated_ sender are also available. It is possible
    to specify added header lines in this ACL.
 
    Variables such as $authenticated_ sender are also available. It is possible
    to specify added header lines in this ACL.
 
+3. When an SMTP error message is specified in a "message" modifier in an ACL,
+   or in a :fail: or :defer: message in a redirect router, Exim now checks the
+   start of the message for an SMTP error code. This consists of three digits
+   followed by a space, optionally followed by an extended code of the form
+   n.n.n, also followed by a space. If this is the case and the very first
+   digit is the same as the default error code, the code from the message is
+   used instead. If the very first digit is incorrect, a panic error is logged,
+   and the default code is used. This is an incompatible change, but it is not
+   expected to affect many (if any) configurations. It is possible to suppress
+   the use of the supplied code in a redirect router by setting the
+   smtp_error_code option false. In this case, any SMTP code is quietly
+   ignored.
+
 
 Version 4.62
 ------------
 
 Version 4.62
 ------------
index 05f89f40e12001bdb562aadfeef4db58217de06b..e4975ba6a77db839f7eeb6b13400120c890f4caf 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/src/README.UPDATING,v 1.11 2006/02/20 16:31:49 ph10 Exp $
+$Cambridge: exim/src/README.UPDATING,v 1.12 2006/07/13 13:53:33 ph10 Exp $
 
 This document contains detailed information about incompatibilities that might
 be encountered when upgrading from one release of Exim to another. The
 
 This document contains detailed information about incompatibilities that might
 be encountered when upgrading from one release of Exim to another. The
@@ -28,6 +28,22 @@ The rest of this document contains information about changes in 4.xx releases
 that might affect a running system.
 
 
 that might affect a running system.
 
 
+Exim version 4.63
+-----------------
+
+When an SMTP error message is specified in a "message" modifier in an ACL, or
+in a :fail: or :defer: message in a redirect router, Exim now checks the start
+of the message for an SMTP error code. This consists of three digits followed
+by a space, optionally followed by an extended code of the form n.n.n, also
+followed by a space. If this is the case and the very first digit is the same
+as the default error code, the code from the message is used instead. If the
+very first digit is incorrect, a panic error is logged, and the default code is
+used. This is an incompatible change, but it is not expected to affect many (if
+any) configurations. It is possible to suppress the use of the supplied code in
+a redirect router by setting the smtp_error_code option false. In this case,
+any SMTP code is quietly ignored.
+
+
 Exim version 4.61
 -----------------
 
 Exim version 4.61
 -----------------
 
index a40ded77e7ea2af2bae92662347cc8e48c911ce6..3ac7d83134ec3916ad65fddf3e4963ee4e51e8ce 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/exim.c,v 1.40 2006/06/28 16:00:24 ph10 Exp $ */
+/* $Cambridge: exim/src/src/exim.c,v 1.41 2006/07/13 13:53:33 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -1492,6 +1492,13 @@ using mac_ismsgid, which uses this. */
 regex_ismsgid =
   regex_must_compile(US"^(?:[^\\W_]{6}-){2}[^\\W_]{2}$", FALSE, TRUE);
 
 regex_ismsgid =
   regex_must_compile(US"^(?:[^\\W_]{6}-){2}[^\\W_]{2}$", FALSE, TRUE);
 
+/* Precompile the regular expression that is used for matching an SMTP error
+code, possibly extended, at the start of an error message. */
+
+regex_smtp_code =
+  regex_must_compile(US"^\\d\\d\\d\\s(?:\\d\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\s)?",
+    FALSE, TRUE);
+
 /* If the program is called as "mailq" treat it as equivalent to "exim -bp";
 this seems to be a generally accepted convention, since one finds symbolic
 links called "mailq" in standard OS configurations. */
 /* If the program is called as "mailq" treat it as equivalent to "exim -bp";
 this seems to be a generally accepted convention, since one finds symbolic
 links called "mailq" in standard OS configurations. */
index 2728d79f13f62a3e79d442b0075e8c07173b0662..32b3d2d248f03b3ac5ef963d9adb791c87a8b13a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/functions.h,v 1.24 2006/03/08 11:13:07 ph10 Exp $ */
+/* $Cambridge: exim/src/src/functions.h,v 1.25 2006/07/13 13:53:33 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -266,7 +266,7 @@ extern BOOL    smtp_get_port(uschar *, address_item *, int *, uschar *);
 extern int     smtp_getc(void);
 extern int     smtp_handle_acl_fail(int, int, uschar *, uschar *);
 extern BOOL    smtp_read_response(smtp_inblock *, uschar *, int, int, int);
 extern int     smtp_getc(void);
 extern int     smtp_handle_acl_fail(int, int, uschar *, uschar *);
 extern BOOL    smtp_read_response(smtp_inblock *, uschar *, int, int, int);
-extern void    smtp_respond(int, BOOL, uschar *);
+extern void    smtp_respond(uschar *, int, BOOL, uschar *);
 extern void    smtp_send_prohibition_message(int, uschar *);
 extern int     smtp_setup_msg(void);
 extern BOOL    smtp_start_session(void);
 extern void    smtp_send_prohibition_message(int, uschar *);
 extern int     smtp_setup_msg(void);
 extern BOOL    smtp_start_session(void);
index 4455f384eaeb377258c8e67cdc65980382c4328f..2a6aba59273e0d4f35c8a9e6e15d6c70f27c0a03 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.c,v 1.54 2006/06/28 16:00:24 ph10 Exp $ */
+/* $Cambridge: exim/src/src/globals.c,v 1.55 2006/07/13 13:53:33 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -211,22 +211,22 @@ uschar *acl_wherenames[]       = { US"RCPT",
                                    US"VRFY"
                                  };
 
                                    US"VRFY"
                                  };
 
-int     acl_wherecodes[]       = { 550,     /* RCPT */
-                                   550,     /* MAIL */
-                                   550,     /* PREDATA */
-                                   550,     /* MIME */
-                                   550,     /* DATA */
-                                   0,       /* not SMTP; not relevant */
-                                   503,     /* AUTH */
-                                   550,     /* connect */
-                                   458,     /* ETRN */
-                                   550,     /* EXPN */
-                                   550,     /* HELO/EHLO */
-                                   0,       /* MAILAUTH; not relevant */
-                                   0,       /* not SMTP; not relevant */
-                                   0,       /* QUIT; not relevant */
-                                   550,     /* STARTTLS */
-                                   252      /* VRFY */
+uschar *acl_wherecodes[]       = { US"550",     /* RCPT */
+                                   US"550",     /* MAIL */
+                                   US"550",     /* PREDATA */
+                                   US"550",     /* MIME */
+                                   US"550",     /* DATA */
+                                   US"0",       /* not SMTP; not relevant */
+                                   US"503",     /* AUTH */
+                                   US"550",     /* connect */
+                                   US"458",     /* ETRN */
+                                   US"550",     /* EXPN */
+                                   US"550",     /* HELO/EHLO */
+                                   US"0",       /* MAILAUTH; not relevant */
+                                   US"0",       /* not SMTP; not relevant */
+                                   US"0",       /* QUIT; not relevant */
+                                   US"550",     /* STARTTLS */
+                                   US"252"      /* VRFY */
                                  };
 
 BOOL    active_local_from_check = FALSE;
                                  };
 
 BOOL    active_local_from_check = FALSE;
@@ -866,6 +866,7 @@ const pcre *regex_From         = NULL;
 const pcre *regex_IGNOREQUOTA  = NULL;
 const pcre *regex_PIPELINING   = NULL;
 const pcre *regex_SIZE         = NULL;
 const pcre *regex_IGNOREQUOTA  = NULL;
 const pcre *regex_PIPELINING   = NULL;
 const pcre *regex_SIZE         = NULL;
+const pcre *regex_smtp_code    = NULL;
 const pcre *regex_ismsgid      = NULL;
 #ifdef WITH_CONTENT_SCAN
 uschar *regex_match_string     = NULL;
 const pcre *regex_ismsgid      = NULL;
 #ifdef WITH_CONTENT_SCAN
 uschar *regex_match_string     = NULL;
index 53272ceef1be14bdd91c050269864a46e5807eac..a235869c1b375b1c310949b0fe883bae08bb042d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.h,v 1.38 2006/06/28 16:00:24 ph10 Exp $ */
+/* $Cambridge: exim/src/src/globals.h,v 1.39 2006/07/13 13:53:33 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -131,7 +131,7 @@ extern BOOL    acl_temp_details;       /* TRUE to give details for 4xx error */
 extern uschar *acl_var[ACL_CVARS+ACL_MVARS]; /* User ACL variables */
 extern uschar *acl_verify_message;     /* User message for verify failure */
 extern string_item *acl_warn_logged;   /* Logged lines */
 extern uschar *acl_var[ACL_CVARS+ACL_MVARS]; /* User ACL variables */
 extern uschar *acl_verify_message;     /* User message for verify failure */
 extern string_item *acl_warn_logged;   /* Logged lines */
-extern int     acl_wherecodes[];       /* Response codes for ACL fails */
+extern uschar *acl_wherecodes[];       /* Response codes for ACL fails */
 extern uschar *acl_wherenames[];       /* Names for messages */
 extern BOOL    active_local_from_check;/* For adding Sender: (switchable) */
 extern BOOL    active_local_sender_retain; /* For keeping Sender: (switchable) */
 extern uschar *acl_wherenames[];       /* Names for messages */
 extern BOOL    active_local_from_check;/* For adding Sender: (switchable) */
 extern BOOL    active_local_sender_retain; /* For keeping Sender: (switchable) */
@@ -556,6 +556,7 @@ extern const pcre  *regex_From;        /* For recognizing "From_" lines */
 extern const pcre  *regex_IGNOREQUOTA; /* For recognizing IGNOREQUOTA (LMTP) */
 extern const pcre  *regex_PIPELINING;  /* For recognizing PIPELINING */
 extern const pcre  *regex_SIZE;        /* For recognizing SIZE settings */
 extern const pcre  *regex_IGNOREQUOTA; /* For recognizing IGNOREQUOTA (LMTP) */
 extern const pcre  *regex_PIPELINING;  /* For recognizing PIPELINING */
 extern const pcre  *regex_SIZE;        /* For recognizing SIZE settings */
+extern const pcre  *regex_smtp_code;   /* For recognizing SMTP codes */
 extern const pcre  *regex_ismsgid;     /* Compiled r.e. for message it */
 #ifdef WITH_CONTENT_SCAN
 extern uschar *regex_match_string;     /* regex that matched a line (regex ACL condition) */
 extern const pcre  *regex_ismsgid;     /* Compiled r.e. for message it */
 #ifdef WITH_CONTENT_SCAN
 extern uschar *regex_match_string;     /* regex that matched a line (regex ACL condition) */
index f711e9ca85a61328721770c0e86c29bbc477befd..3f430f1aa20ff3f47a836ec266e88e5db2369ad6 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/receive.c,v 1.27 2006/03/06 16:05:12 ph10 Exp $ */
+/* $Cambridge: exim/src/src/receive.c,v 1.28 2006/07/13 13:53:33 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -1067,7 +1067,7 @@ if (mbox_file == NULL) {
          "acl_smtp_mime: error while creating mbox spool file, message temporarily rejected.");
   Uunlink(spool_name);
   unspool_mbox();
          "acl_smtp_mime: error while creating mbox spool file, message temporarily rejected.");
   Uunlink(spool_name);
   unspool_mbox();
-  smtp_respond(451, TRUE, US"temporary local problem");
+  smtp_respond(US"451", 3, TRUE, US"temporary local problem");
   message_id[0] = 0;            /* Indicate no message accepted */
   *smtp_reply_ptr = US"";       /* Indicate reply already sent */
   return FALSE;                 /* Indicate skip to end of receive function */
   message_id[0] = 0;            /* Indicate no message accepted */
   *smtp_reply_ptr = US"";       /* Indicate reply already sent */
   return FALSE;                 /* Indicate skip to end of receive function */
@@ -3110,9 +3110,9 @@ else
   {
   uschar *istemp = US"";
   uschar *s = NULL;
   {
   uschar *istemp = US"";
   uschar *s = NULL;
+  uschar *smtp_code;
   int size = 0;
   int sptr = 0;
   int size = 0;
   int sptr = 0;
-  int code;
 
   errmsg = local_scan_data;
 
 
   errmsg = local_scan_data;
 
@@ -3129,7 +3129,7 @@ else
     /* Fall through */
 
     case LOCAL_SCAN_REJECT:
     /* Fall through */
 
     case LOCAL_SCAN_REJECT:
-    code = 550;
+    smtp_code = US"550";
     if (errmsg == NULL) errmsg =  US"Administrative prohibition";
     break;
 
     if (errmsg == NULL) errmsg =  US"Administrative prohibition";
     break;
 
@@ -3139,7 +3139,7 @@ else
 
     case LOCAL_SCAN_TEMPREJECT:
     TEMPREJECT:
 
     case LOCAL_SCAN_TEMPREJECT:
     TEMPREJECT:
-    code = 451;
+    smtp_code = US"451";
     if (errmsg == NULL) errmsg = US"Temporary local problem";
     istemp = US"temporarily ";
     break;
     if (errmsg == NULL) errmsg = US"Temporary local problem";
     istemp = US"temporarily ";
     break;
@@ -3157,14 +3157,14 @@ else
     {
     if (!smtp_batched_input)
       {
     {
     if (!smtp_batched_input)
       {
-      smtp_respond(code, TRUE, errmsg);
+      smtp_respond(smtp_code, 3, TRUE, errmsg);
       message_id[0] = 0;            /* Indicate no message accepted */
       smtp_reply = US"";            /* Indicate reply already sent */
       goto TIDYUP;                  /* Skip to end of function */
       }
     else
       {
       message_id[0] = 0;            /* Indicate no message accepted */
       smtp_reply = US"";            /* Indicate reply already sent */
       goto TIDYUP;                  /* Skip to end of function */
       }
     else
       {
-      moan_smtp_batch(NULL, "%d %s", code, errmsg);
+      moan_smtp_batch(NULL, "%s %s", smtp_code, errmsg);
       /* Does not return */
       }
     }
       /* Does not return */
       }
     }
@@ -3483,8 +3483,8 @@ if (smtp_input)
     if (smtp_reply == NULL)
       {
       if (fake_response != OK)
     if (smtp_reply == NULL)
       {
       if (fake_response != OK)
-        smtp_respond(fake_response == DEFER ? 450 : 550,
-                     TRUE, fake_response_text);
+        smtp_respond((fake_response == DEFER)? US"450" : US"550", 3, TRUE,
+          fake_response_text);
       else
         smtp_printf("250 OK id=%s\r\n", message_id);
       if (host_checking)
       else
         smtp_printf("250 OK id=%s\r\n", message_id);
       if (host_checking)
@@ -3494,8 +3494,8 @@ if (smtp_input)
     else if (smtp_reply[0] != 0)
       {
       if (fake_response != OK && (smtp_reply[0] == '2'))
     else if (smtp_reply[0] != 0)
       {
       if (fake_response != OK && (smtp_reply[0] == '2'))
-        smtp_respond(fake_response == DEFER ? 450 : 550,
-                     TRUE, fake_response_text);
+        smtp_respond((fake_response == DEFER)? US"450" : US"550", 3, TRUE,
+          fake_response_text);
       else
         smtp_printf("%.1024s\r\n", smtp_reply);
       }
       else
         smtp_printf("%.1024s\r\n", smtp_reply);
       }
index d94240ebc447c37db161e104e005129fb0932922..2a9d5e3b2c150966fb83172be7a2fb983537ce67 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/routers/redirect.c,v 1.16 2006/06/27 14:34:26 ph10 Exp $ */
+/* $Cambridge: exim/src/src/routers/redirect.c,v 1.17 2006/07/13 13:53:33 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -71,6 +71,8 @@ optionlist redirect_router_options[] = {
       (void *)offsetof(redirect_router_options_block, forbid_pipe) },
   { "forbid_sieve_filter",opt_bit | (RDON_SIEVE_FILTER << 16),
       (void *)offsetof(redirect_router_options_block, bit_options) },
       (void *)offsetof(redirect_router_options_block, forbid_pipe) },
   { "forbid_sieve_filter",opt_bit | (RDON_SIEVE_FILTER << 16),
       (void *)offsetof(redirect_router_options_block, bit_options) },
+  { "forbid_smtp_code",     opt_bool,
+      (void *)offsetof(redirect_router_options_block, forbid_smtp_code) },
   { "hide_child_in_errmsg", opt_bool,
       (void *)offsetof(redirect_router_options_block,  hide_child_in_errmsg) },
   { "ignore_eacces",      opt_bit | (RDON_EACCES << 16),
   { "hide_child_in_errmsg", opt_bool,
       (void *)offsetof(redirect_router_options_block,  hide_child_in_errmsg) },
   { "ignore_eacces",      opt_bit | (RDON_EACCES << 16),
@@ -169,6 +171,7 @@ redirect_router_options_block redirect_router_option_defaults = {
   FALSE,       /* forbid_file */
   FALSE,       /* forbid_filter_reply */
   FALSE,       /* forbid_pipe */
   FALSE,       /* forbid_file */
   FALSE,       /* forbid_filter_reply */
   FALSE,       /* forbid_pipe */
+  FALSE,       /* forbid_smtp_code */
   FALSE,       /* hide_child_in_errmsg */
   FALSE,       /* one_time */
   FALSE,       /* qualify_preserve_domain */
   FALSE,       /* hide_child_in_errmsg */
   FALSE,       /* one_time */
   FALSE,       /* qualify_preserve_domain */
@@ -711,26 +714,39 @@ switch (frc)
   break;
 
   /* FF_DEFER and FF_FAIL can arise only as a result of explicit commands
   break;
 
   /* FF_DEFER and FF_FAIL can arise only as a result of explicit commands
-  (:fail: in an alias file or "fail" in a filter). If a configured message was
-  supplied, allow it to be included in an SMTP response after verifying. */
+  (:defer: or :fail: in an alias file or "fail" in a filter). If a configured
+  message was supplied, allow it to be included in an SMTP response after
+  verifying. Remove any SMTP code if it is not allowed. */
 
   case FF_DEFER:
 
   case FF_DEFER:
-  if (addr->message == NULL) addr->message = US"forced defer";
-    else addr->user_message = addr->message;
-  return DEFER;
+  yield = DEFER;
+  goto SORT_MESSAGE;
 
   case FF_FAIL:
   if ((xrc = sort_errors_and_headers(rblock, addr, verify, &addr_prop)) != OK)
     return xrc;
   add_generated(rblock, addr_new, addr, generated, &addr_prop, &ugid, pw);
 
   case FF_FAIL:
   if ((xrc = sort_errors_and_headers(rblock, addr, verify, &addr_prop)) != OK)
     return xrc;
   add_generated(rblock, addr_new, addr, generated, &addr_prop, &ugid, pw);
+  yield = FAIL;
+
+  SORT_MESSAGE:
   if (addr->message == NULL)
   if (addr->message == NULL)
-    addr->message = US"forced rejection";
+    addr->message = (yield == FAIL)? US"forced rejection" : US"forced defer";
   else
     {
   else
     {
+    int ovector[3];
+    if (ob->forbid_smtp_code &&
+        pcre_exec(regex_smtp_code, NULL, CS addr->message,
+        Ustrlen(addr->message), 0, PCRE_EOPT,
+        ovector, sizeof(ovector)/sizeof(int)) >= 0)
+      {
+      DEBUG(D_route) debug_printf("SMTP code at start of error message "
+        "is ignored because forbid_smtp_code is set\n");
+      addr->message += ovector[1];
+      }
     addr->user_message = addr->message;
     setflag(addr, af_pass_message);
     }
     addr->user_message = addr->message;
     setflag(addr, af_pass_message);
     }
-  return FAIL;
+  return yield;
 
   /* As in the case of a system filter, a freeze does not happen after a manual
   thaw. In case deliveries were set up by the filter, we set the child count
 
   /* As in the case of a system filter, a freeze does not happen after a manual
   thaw. In case deliveries were set up by the filter, we set the child count
index 996f0b003ec772c430e672a0d082a7ecda4c82fa..6825430fd62f8e9d7c791901c68ee0885355e927 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/routers/redirect.h,v 1.7 2006/02/07 11:19:02 ph10 Exp $ */
+/* $Cambridge: exim/src/src/routers/redirect.h,v 1.8 2006/07/13 13:53:33 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -51,6 +51,7 @@ typedef struct {
   BOOL  forbid_file;
   BOOL  forbid_filter_reply;
   BOOL  forbid_pipe;
   BOOL  forbid_file;
   BOOL  forbid_filter_reply;
   BOOL  forbid_pipe;
+  BOOL  forbid_smtp_code;
   BOOL  hide_child_in_errmsg;
   BOOL  one_time;
   BOOL  qualify_preserve_domain;
   BOOL  hide_child_in_errmsg;
   BOOL  one_time;
   BOOL  qualify_preserve_domain;
index 99ac3fb1a3f402f866aa47163ef01c2cf510e2bf..881bfff58793cebd610443338ba2b9da96f09551 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/smtp_in.c,v 1.38 2006/04/19 10:58:21 ph10 Exp $ */
+/* $Cambridge: exim/src/src/smtp_in.c,v 1.39 2006/07/13 13:53:33 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -1767,7 +1767,8 @@ responses. If no_multiline_responses is TRUE (it can be set from an ACL), we
 output nothing for non-final calls, and only the first line for anything else.
 
 Arguments:
 output nothing for non-final calls, and only the first line for anything else.
 
 Arguments:
-  code          SMTP code
+  code          SMTP code, may involve extended status codes
+  codelen       length of smtp code; uf > 3 there's an ESC
   final         FALSE if the last line isn't the final line
   msg           message text, possibly containing newlines
 
   final         FALSE if the last line isn't the final line
   msg           message text, possibly containing newlines
 
@@ -1775,26 +1776,36 @@ Returns:        nothing
 */
 
 void
 */
 
 void
-smtp_respond(int code, BOOL final, uschar *msg)
+smtp_respond(uschar* code, int codelen, BOOL final, uschar *msg)
 {
 {
+int esclen = 0;
+uschar *esc = US"";
+
 if (!final && no_multiline_responses) return;
 
 if (!final && no_multiline_responses) return;
 
+if (codelen > 3)
+  {
+  esc = code + 4;
+  esclen = codelen - 4;
+  }
+
 for (;;)
   {
   uschar *nl = Ustrchr(msg, '\n');
   if (nl == NULL)
     {
 for (;;)
   {
   uschar *nl = Ustrchr(msg, '\n');
   if (nl == NULL)
     {
-    smtp_printf("%d%c%s\r\n", code, final? ' ':'-', msg);
+    smtp_printf("%.3s%c%.*s%s\r\n", code, final? ' ':'-', esclen, esc, msg);
     return;
     }
   else if (nl[1] == 0 || no_multiline_responses)
     {
     return;
     }
   else if (nl[1] == 0 || no_multiline_responses)
     {
-    smtp_printf("%d%c%.*s\r\n", code, final? ' ':'-', (int)(nl - msg), msg);
+    smtp_printf("%.3s%c%.*s%.*s\r\n", code, final? ' ':'-', esclen, esc,
+      (int)(nl - msg), msg);
     return;
     }
   else
     {
     return;
     }
   else
     {
-    smtp_printf("%d-%.*s\r\n", code, (int)(nl - msg), msg);
+    smtp_printf("%.3s-%.*s%.*s\r\n", code, esclen, esc, (int)(nl - msg), msg);
     msg = nl + 1;
     while (isspace(*msg)) msg++;
     }
     msg = nl + 1;
     while (isspace(*msg)) msg++;
     }
@@ -1814,13 +1825,18 @@ logging the incident, and sets up the error response. A message containing
 newlines is turned into a multiline SMTP response, but for logging, only the
 first line is used.
 
 newlines is turned into a multiline SMTP response, but for logging, only the
 first line is used.
 
-There's a table of the response codes to use in globals.c, along with the table
-of names. VFRY is special. Despite RFC1123 it defaults disabled in Exim.
-However, discussion in connection with RFC 821bis (aka RFC 2821) has concluded
-that the response should be 252 in the disabled state, because there are broken
-clients that try VRFY before RCPT. A 5xx response should be given only when the
-address is positively known to be undeliverable. Sigh. Also, for ETRN, 458 is
-given on refusal, and for AUTH, 503.
+There's a table of default permanent failure response codes to use in
+globals.c, along with the table of names. VFRY is special. Despite RFC1123 it
+defaults disabled in Exim. However, discussion in connection with RFC 821bis
+(aka RFC 2821) has concluded that the response should be 252 in the disabled
+state, because there are broken clients that try VRFY before RCPT. A 5xx
+response should be given only when the address is positively known to be
+undeliverable. Sigh. Also, for ETRN, 458 is given on refusal, and for AUTH,
+503.
+
+From Exim 4.63, it is possible to override the response code details by
+providing a suitable response code string at the start of the message provided
+in user_msg. The code's first digit is checked for validity.
 
 Arguments:
   where      where the ACL was called from
 
 Arguments:
   where      where the ACL was called from
@@ -1837,8 +1853,10 @@ Returns:     0 in most cases
 int
 smtp_handle_acl_fail(int where, int rc, uschar *user_msg, uschar *log_msg)
 {
 int
 smtp_handle_acl_fail(int where, int rc, uschar *user_msg, uschar *log_msg)
 {
-int code = acl_wherecodes[where];
 BOOL drop = rc == FAIL_DROP;
 BOOL drop = rc == FAIL_DROP;
+int codelen = 3;
+int ovector[3];
+uschar *smtp_code;
 uschar *lognl;
 uschar *sender_info = US"";
 uschar *what =
 uschar *lognl;
 uschar *sender_info = US"";
 uschar *what =
@@ -1853,6 +1871,41 @@ uschar *what =
 
 if (drop) rc = FAIL;
 
 
 if (drop) rc = FAIL;
 
+/* Set the default SMTP code */
+
+smtp_code = (rc != FAIL)? US"451" : acl_wherecodes[where];
+
+/* Check a user message for starting with a response code and optionally an
+extended status code. If found, check that the first digit is valid, and if so,
+use it instead of the default code. */
+
+if (user_msg != NULL)
+  {
+  int n = pcre_exec(regex_smtp_code, NULL, CS user_msg, Ustrlen(user_msg), 0,
+    PCRE_EOPT, ovector, sizeof(ovector)/sizeof(int));
+  if (n >= 0)
+    {
+    if (user_msg[0] != smtp_code[0])
+      {
+      log_write(0, LOG_MAIN|LOG_PANIC, "configured error code starts with "
+        "incorrect digit (expected %c) in \"%s\"", smtp_code[0], user_msg);
+
+      /* If log_msg == user_msg (the default set in acl.c if no log message is
+      specified, we must adjust the log message to show the code that is
+      actually going to be used. */
+
+      if (log_msg == user_msg)
+        log_msg = string_sprintf("%s %s", smtp_code, log_msg + ovector[1]);
+      }
+    else
+      {
+      smtp_code = user_msg;
+      codelen = ovector[1];    /* Includes final space */
+      }
+    user_msg += ovector[1];    /* Chop the code off the message */
+    }
+  }
+
 /* We used to have sender_address here; however, there was a bug that was not
 updating sender_address after a rewrite during a verify. When this bug was
 fixed, sender_address at this point became the rewritten address. I'm not sure
 /* We used to have sender_address here; however, there was a bug that was not
 updating sender_address after a rewrite during a verify. When this bug was
 fixed, sender_address at this point became the rewritten address. I'm not sure
@@ -1888,7 +1941,7 @@ if (sender_verified_failed != NULL &&
       string_sprintf(": %s", sender_verified_failed->message));
 
   if (rc == FAIL && sender_verified_failed->user_message != NULL)
       string_sprintf(": %s", sender_verified_failed->message));
 
   if (rc == FAIL && sender_verified_failed->user_message != NULL)
-    smtp_respond(code, FALSE, string_sprintf(
+    smtp_respond(smtp_code, codelen, FALSE, string_sprintf(
         testflag(sender_verified_failed, af_verify_pmfail)?
           "Postmaster verification failed while checking <%s>\n%s\n"
           "Several RFCs state that you are required to have a postmaster\n"
         testflag(sender_verified_failed, af_verify_pmfail)?
           "Postmaster verification failed while checking <%s>\n%s\n"
           "Several RFCs state that you are required to have a postmaster\n"
@@ -1918,7 +1971,7 @@ if (lognl != NULL) *lognl = 0;
 always a 5xx one - see comments at the start of this function. If the original
 rc was FAIL_DROP we drop the connection and yield 2. */
 
 always a 5xx one - see comments at the start of this function. If the original
 rc was FAIL_DROP we drop the connection and yield 2. */
 
-if (rc == FAIL) smtp_respond(code, TRUE, (user_msg == NULL)?
+if (rc == FAIL) smtp_respond(smtp_code, codelen, TRUE, (user_msg == NULL)?
   US"Administrative prohibition" : user_msg);
 
 /* Send temporary failure response to the command. Don't give any details,
   US"Administrative prohibition" : user_msg);
 
 /* Send temporary failure response to the command. Don't give any details,
@@ -1937,12 +1990,13 @@ else
         sender_verified_failed != NULL &&
         sender_verified_failed->message != NULL)
       {
         sender_verified_failed != NULL &&
         sender_verified_failed->message != NULL)
       {
-      smtp_respond(451, FALSE, sender_verified_failed->message);
+      smtp_respond(smtp_code, codelen, FALSE, sender_verified_failed->message);
       }
       }
-    smtp_respond(451, TRUE, user_msg);
+    smtp_respond(smtp_code, codelen, TRUE, user_msg);
     }
   else
     }
   else
-    smtp_printf("451 Temporary local problem - please try later\r\n");
+    smtp_respond(smtp_code, codelen, TRUE,
+      US"Temporary local problem - please try later");
   }
 
 /* Log the incident. If the connection is not forcibly to be dropped, return 0.
   }
 
 /* Log the incident. If the connection is not forcibly to be dropped, return 0.
diff --git a/test/aux-fixed/0536.aliases b/test/aux-fixed/0536.aliases
new file mode 100644 (file)
index 0000000..535399b
--- /dev/null
@@ -0,0 +1,9 @@
+user20:  :fail: No code
+user21:  :fail: 590 Main code
+user22:  :fail: 590 5.4.3 Main and extended code
+user23:  :fail: 490 4.5.6 Wrong code
+
+user30:  :defer: No code
+user31:  :defer: 490 Main code
+user32:  :defer: 490 4.4.3 Main and extended code
+user33:  :defer: 390 3.5.6 Wrong code
diff --git a/test/confs/0536 b/test/confs/0536
new file mode 100644 (file)
index 0000000..0aa7c52
--- /dev/null
@@ -0,0 +1,104 @@
+# Exim test configuration 0536
+
+FORBID_SMTP_CODE = false
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+rfc1413_query_timeout = 0s
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+
+# ----- Main settings -----
+
+acl_smtp_rcpt = rcpt
+acl_not_smtp = not_smtp
+
+trusted_users = CALLER
+
+
+# ----- ACLs -----
+
+begin ACL
+
+rcpt:
+  deny local_parts = user1
+       message     = No code
+  deny local_parts = user2
+       message     = 599 Main code
+  deny local_parts = user3
+       message     = 599 Main code\non two lines
+  deny local_parts = user4
+       message     = 599 5.2.3 Main and extended code
+  deny local_parts = user5
+       message     = 599 5.12.3 Main and extended code\non two lines
+  deny local_parts = user6
+       message     = 299 Wrong code
+  deny local_parts = user7
+       message     = 299 Wrong code
+       log_message = A different log message
+
+  defer local_parts = user8
+        message     = 499 4.12.343 Main and extended code\non two lines
+  defer local_parts = user9
+        message     = 499 4.1234.343 Main and extended code\non two lines
+  defer local_parts = user10
+        message     = 399 Wrong code
+
+  deny local_parts = user20
+       !verify     = recipient
+  deny local_parts = user21
+       !verify     = recipient
+  deny local_parts = user22
+       !verify     = recipient
+  deny local_parts = user23
+       !verify     = recipient
+
+  deny local_parts = user30
+       !verify     = recipient
+  deny local_parts = user31
+       !verify     = recipient
+  deny local_parts = user32
+       !verify     = recipient
+  deny local_parts = user33
+       !verify     = recipient
+
+  deny message = Should not get this
+
+not_smtp:
+  accept senders = : oksender@test.ex
+
+  deny senders = user1@test.ex
+       message = No code
+
+  deny senders = user2@test.ex
+       message = 599 Main code
+
+  deny message = Should not get this
+
+# ----- Routers -----
+
+begin routers
+
+r1:
+  driver = redirect
+  allow_fail
+  allow_defer
+  data = ${lookup{$local_part}lsearch{DIR/aux-fixed/TESTNUM.aliases}}
+  forbid_smtp_code = FORBID_SMTP_CODE
+
+r2:
+  driver = accept
+  transport = t1
+
+# ----- Transports -----
+
+begin transports
+
+t1:
+  driver = appendfile
+  file = DIR/test-mail/$local_part
+  user = CALLER
+
diff --git a/test/log/0536 b/test/log/0536
new file mode 100644 (file)
index 0000000..ab5fe84
--- /dev/null
@@ -0,0 +1,41 @@
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user1@test.ex>: No code
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user2@test.ex>: 599 Main code
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user3@test.ex>: 599 Main code
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user4@test.ex>: 599 5.2.3 Main and extended code
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user5@test.ex>: 599 5.12.3 Main and extended code
+1999-03-02 09:44:33 configured error code starts with incorrect digit (expected 5) in "299 Wrong code"
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user6@test.ex>: 550 Wrong code
+1999-03-02 09:44:33 configured error code starts with incorrect digit (expected 5) in "299 Wrong code"
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user7@test.ex>: A different log message
+1999-03-02 09:44:33 U=CALLER F=<> temporarily rejected RCPT <user8@test.ex>: 499 4.12.343 Main and extended code
+1999-03-02 09:44:33 U=CALLER F=<> temporarily rejected RCPT <user9@test.ex>: 499 4.1234.343 Main and extended code
+1999-03-02 09:44:33 configured error code starts with incorrect digit (expected 4) in "399 Wrong code"
+1999-03-02 09:44:33 U=CALLER F=<> temporarily rejected RCPT <user10@test.ex>: 451 Wrong code
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user20@test.ex>: No code
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user21@test.ex>: 590 Main code
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user22@test.ex>: 590 5.4.3 Main and extended code
+1999-03-02 09:44:33 configured error code starts with incorrect digit (expected 5) in "490 4.5.6 Wrong code"
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user23@test.ex>: 550 Wrong code
+1999-03-02 09:44:33 U=CALLER F=<> temporarily rejected RCPT <user30@test.ex>: No code
+1999-03-02 09:44:33 U=CALLER F=<> temporarily rejected RCPT <user31@test.ex>: 490 Main code
+1999-03-02 09:44:33 U=CALLER F=<> temporarily rejected RCPT <user32@test.ex>: 490 4.4.3 Main and extended code
+1999-03-02 09:44:33 configured error code starts with incorrect digit (expected 4) in "390 3.5.6 Wrong code"
+1999-03-02 09:44:33 U=CALLER F=<> temporarily rejected RCPT <user33@test.ex>: 451 Wrong code
+1999-03-02 09:44:33 10HmaX-0005vi-00 F=<user1@test.ex> rejected by non-SMTP ACL: No code
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= <> R=10HmaX-0005vi-00 U=EXIMUSER P=local S=sss
+1999-03-02 09:44:33 10HmaZ-0005vi-00 => user1 <user1@test.ex> R=r2 T=t1
+1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
+1999-03-02 09:44:33 10HmaY-0005vi-00 F=<user2@test.ex> rejected by non-SMTP ACL: 599 Main code
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= <> R=10HmaY-0005vi-00 U=EXIMUSER P=local S=sss
+1999-03-02 09:44:33 10HmbA-0005vi-00 => user2 <user2@test.ex> R=r2 T=t1
+1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbB-0005vi-00 <= oksender@test.ex U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmbB-0005vi-00 ** user22@test.ex R=r1: 590 5.4.3 Main and extended code
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= <> R=10HmbB-0005vi-00 U=EXIMUSER P=local S=sss
+1999-03-02 09:44:33 10HmbC-0005vi-00 => oksender <oksender@test.ex> R=r2 T=t1
+1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user20@test.ex>: No code
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user21@test.ex>: Main code
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user22@test.ex>: Main and extended code
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user23@test.ex>: Wrong code
diff --git a/test/mail/0536.oksender b/test/mail/0536.oksender
new file mode 100644 (file)
index 0000000..9a3e0ea
--- /dev/null
@@ -0,0 +1,32 @@
+From MAILER-DAEMON Tue Mar 02 09:44:33 1999
+Received: from EXIMUSER by myhost.test.ex with local (Exim x.yz)
+       id 10HmbC-0005vi-00
+       for oksender@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+X-Failed-Recipients: user22@test.ex
+Auto-Submitted: auto-replied
+From: Mail Delivery System <Mailer-Daemon@myhost.test.ex>
+To: oksender@test.ex
+Subject: Mail delivery failed: returning message to sender
+Message-Id: <E10HmbC-0005vi-00@myhost.test.ex>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+This message was created automatically by mail delivery software.
+
+A message that you sent could not be delivered to one or more of its
+recipients. This is a permanent error. The following address(es) failed:
+
+  user22@test.ex
+    590 5.4.3 Main and extended code
+
+------ This is a copy of the message, including all the headers. ------
+
+Return-path: <oksender@test.ex>
+Received: from CALLER by myhost.test.ex with local (Exim x.yz)
+       (envelope-from <oksender@test.ex>)
+       id 10HmbB-0005vi-00
+       for user22@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+Message-Id: <E10HmbB-0005vi-00@myhost.test.ex>
+From: oksender@test.ex
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+
diff --git a/test/mail/0536.user1 b/test/mail/0536.user1
new file mode 100644 (file)
index 0000000..b918842
--- /dev/null
@@ -0,0 +1,27 @@
+From MAILER-DAEMON Tue Mar 02 09:44:33 1999
+Received: from EXIMUSER by myhost.test.ex with local (Exim x.yz)
+       id 10HmaZ-0005vi-00
+       for user1@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+Auto-Submitted: auto-replied
+From: Mail Delivery System <Mailer-Daemon@myhost.test.ex>
+To: user1@test.ex
+Subject: Mail failure - rejected by local scanning code
+Message-Id: <E10HmaZ-0005vi-00@myhost.test.ex>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+A message that you sent was rejected by the local scanning code that
+checks incoming messages on this system. The following error was given:
+
+  No code
+
+------ This is a copy of your message, including all the headers. ------
+
+Received: from CALLER by myhost.test.ex with local (Exim x.yz)
+       (envelope-from <user1@test.ex>)
+       id 10HmaX-0005vi-00
+       for user1@myhost.test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+Message-Id: <E10HmaX-0005vi-00@myhost.test.ex>
+From: user1@test.ex
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+
diff --git a/test/mail/0536.user2 b/test/mail/0536.user2
new file mode 100644 (file)
index 0000000..64bd158
--- /dev/null
@@ -0,0 +1,27 @@
+From MAILER-DAEMON Tue Mar 02 09:44:33 1999
+Received: from EXIMUSER by myhost.test.ex with local (Exim x.yz)
+       id 10HmbA-0005vi-00
+       for user2@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+Auto-Submitted: auto-replied
+From: Mail Delivery System <Mailer-Daemon@myhost.test.ex>
+To: user2@test.ex
+Subject: Mail failure - rejected by local scanning code
+Message-Id: <E10HmbA-0005vi-00@myhost.test.ex>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+A message that you sent was rejected by the local scanning code that
+checks incoming messages on this system. The following error was given:
+
+  599 Main code
+
+------ This is a copy of your message, including all the headers. ------
+
+Received: from CALLER by myhost.test.ex with local (Exim x.yz)
+       (envelope-from <user2@test.ex>)
+       id 10HmaY-0005vi-00
+       for user1@myhost.test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+Message-Id: <E10HmaY-0005vi-00@myhost.test.ex>
+From: user2@test.ex
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+
diff --git a/test/paniclog/0536 b/test/paniclog/0536
new file mode 100644 (file)
index 0000000..38a1ee0
--- /dev/null
@@ -0,0 +1,5 @@
+1999-03-02 09:44:33 configured error code starts with incorrect digit (expected 5) in "299 Wrong code"
+1999-03-02 09:44:33 configured error code starts with incorrect digit (expected 5) in "299 Wrong code"
+1999-03-02 09:44:33 configured error code starts with incorrect digit (expected 4) in "399 Wrong code"
+1999-03-02 09:44:33 configured error code starts with incorrect digit (expected 5) in "490 4.5.6 Wrong code"
+1999-03-02 09:44:33 configured error code starts with incorrect digit (expected 4) in "390 3.5.6 Wrong code"
diff --git a/test/rejectlog/0536 b/test/rejectlog/0536
new file mode 100644 (file)
index 0000000..bf06473
--- /dev/null
@@ -0,0 +1,42 @@
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user1@test.ex>: No code
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user2@test.ex>: 599 Main code
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user3@test.ex>: 599 Main code
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user4@test.ex>: 599 5.2.3 Main and extended code
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user5@test.ex>: 599 5.12.3 Main and extended code
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user6@test.ex>: 550 Wrong code
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user7@test.ex>: A different log message
+1999-03-02 09:44:33 U=CALLER F=<> temporarily rejected RCPT <user8@test.ex>: 499 4.12.343 Main and extended code
+1999-03-02 09:44:33 U=CALLER F=<> temporarily rejected RCPT <user9@test.ex>: 499 4.1234.343 Main and extended code
+1999-03-02 09:44:33 U=CALLER F=<> temporarily rejected RCPT <user10@test.ex>: 451 Wrong code
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user20@test.ex>: No code
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user21@test.ex>: 590 Main code
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user22@test.ex>: 590 5.4.3 Main and extended code
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user23@test.ex>: 550 Wrong code
+1999-03-02 09:44:33 U=CALLER F=<> temporarily rejected RCPT <user30@test.ex>: No code
+1999-03-02 09:44:33 U=CALLER F=<> temporarily rejected RCPT <user31@test.ex>: 490 Main code
+1999-03-02 09:44:33 U=CALLER F=<> temporarily rejected RCPT <user32@test.ex>: 490 4.4.3 Main and extended code
+1999-03-02 09:44:33 U=CALLER F=<> temporarily rejected RCPT <user33@test.ex>: 451 Wrong code
+1999-03-02 09:44:33 10HmaX-0005vi-00 F=<user1@test.ex> rejected by non-SMTP ACL: No code
+Envelope-from: <user1@test.ex>
+Envelope-to: <user1@myhost.test.ex>
+P Received: from CALLER by myhost.test.ex with local (Exim x.yz)
+       (envelope-from <user1@test.ex>)
+       id 10HmaX-0005vi-00
+       for user1@myhost.test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+I Message-Id: <E10HmaX-0005vi-00@myhost.test.ex>
+F From: user1@test.ex
+  Date: Tue, 2 Mar 1999 09:44:33 +0000
+1999-03-02 09:44:33 10HmaY-0005vi-00 F=<user2@test.ex> rejected by non-SMTP ACL: 599 Main code
+Envelope-from: <user2@test.ex>
+Envelope-to: <user1@myhost.test.ex>
+P Received: from CALLER by myhost.test.ex with local (Exim x.yz)
+       (envelope-from <user2@test.ex>)
+       id 10HmaY-0005vi-00
+       for user1@myhost.test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+I Message-Id: <E10HmaY-0005vi-00@myhost.test.ex>
+F From: user2@test.ex
+  Date: Tue, 2 Mar 1999 09:44:33 +0000
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user20@test.ex>: No code
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user21@test.ex>: Main code
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user22@test.ex>: Main and extended code
+1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <user23@test.ex>: Wrong code
diff --git a/test/scripts/0000-Basic/0536 b/test/scripts/0000-Basic/0536
new file mode 100644 (file)
index 0000000..30be876
--- /dev/null
@@ -0,0 +1,42 @@
+# Specifying SMTP codes in bespoke error messages
+exim -bs
+ehlo test.ex
+mail from:<>
+rcpt to:<user1@test.ex>
+rcpt to:<user2@test.ex>
+rcpt to:<user3@test.ex>
+rcpt to:<user4@test.ex>
+rcpt to:<user5@test.ex>
+rcpt to:<user6@test.ex>
+rcpt to:<user7@test.ex>
+rcpt to:<user8@test.ex>
+rcpt to:<user9@test.ex>
+rcpt to:<user10@test.ex>
+rcpt to:<user20@test.ex>
+rcpt to:<user21@test.ex>
+rcpt to:<user22@test.ex>
+rcpt to:<user23@test.ex>
+rcpt to:<user30@test.ex>
+rcpt to:<user31@test.ex>
+rcpt to:<user32@test.ex>
+rcpt to:<user33@test.ex>
+quit
+****
+1
+exim -f user1@test.ex user1
+****
+1
+exim -f user2@test.ex user1
+****
+exim -odi -f oksender@test.ex user22@test.ex
+****
+exim -DFORBID_SMTP_CODE=true -bs
+ehlo test.ex
+mail from:<>
+rcpt to:<user20@test.ex>
+rcpt to:<user21@test.ex>
+rcpt to:<user22@test.ex>
+rcpt to:<user23@test.ex>
+quit
+****
+no_msglog_check
diff --git a/test/stderr/0536 b/test/stderr/0536
new file mode 100644 (file)
index 0000000..38a1ee0
--- /dev/null
@@ -0,0 +1,5 @@
+1999-03-02 09:44:33 configured error code starts with incorrect digit (expected 5) in "299 Wrong code"
+1999-03-02 09:44:33 configured error code starts with incorrect digit (expected 5) in "299 Wrong code"
+1999-03-02 09:44:33 configured error code starts with incorrect digit (expected 4) in "399 Wrong code"
+1999-03-02 09:44:33 configured error code starts with incorrect digit (expected 5) in "490 4.5.6 Wrong code"
+1999-03-02 09:44:33 configured error code starts with incorrect digit (expected 4) in "390 3.5.6 Wrong code"
diff --git a/test/stdout/0536 b/test/stdout/0536
new file mode 100644 (file)
index 0000000..cc4ce1e
--- /dev/null
@@ -0,0 +1,40 @@
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-myhost.test.ex Hello CALLER at test.ex\r
+250-SIZE 52428800\r
+250-PIPELINING\r
+250 HELP\r
+250 OK\r
+550 No code\r
+599 Main code\r
+599-Main code\r
+599 on two lines\r
+599 5.2.3 Main and extended code\r
+599-5.12.3 Main and extended code\r
+599 5.12.3 on two lines\r
+550 Wrong code\r
+550 Wrong code\r
+499-4.12.343 Main and extended code\r
+499 4.12.343 on two lines\r
+499-4.1234.343 Main and extended code\r
+499 on two lines\r
+451 Wrong code\r
+550 No code\r
+590 Main code\r
+590 5.4.3 Main and extended code\r
+550 Wrong code\r
+451 Temporary local problem - please try later\r
+490 Temporary local problem - please try later\r
+490 4.4.3 Temporary local problem - please try later\r
+451 Temporary local problem - please try later\r
+221 myhost.test.ex closing connection\r
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-myhost.test.ex Hello CALLER at test.ex\r
+250-SIZE 52428800\r
+250-PIPELINING\r
+250 HELP\r
+250 OK\r
+550 No code\r
+550 Main code\r
+550 Main and extended code\r
+550 Wrong code\r
+221 myhost.test.ex closing connection\r