summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Hazel <ph10@hermes.cam.ac.uk>2006-07-13 13:53:32 +0000
committerPhilip Hazel <ph10@hermes.cam.ac.uk>2006-07-13 13:53:32 +0000
commita5bd321b2f16ff323e3e268d59606e89b747a901 (patch)
tree1808bda34b675ef151fda9d89599bd05c9ad942e
parent41609df58fdd3fe023b91baece7d18a595f57e56 (diff)
Add recognition of SMTP error codes in bespoke messages.
-rw-r--r--doc/doc-txt/ChangeLog6
-rw-r--r--doc/doc-txt/NewStuff15
-rw-r--r--src/README.UPDATING18
-rw-r--r--src/src/exim.c9
-rw-r--r--src/src/functions.h4
-rw-r--r--src/src/globals.c35
-rw-r--r--src/src/globals.h5
-rw-r--r--src/src/receive.c22
-rw-r--r--src/src/routers/redirect.c32
-rw-r--r--src/src/routers/redirect.h3
-rw-r--r--src/src/smtp_in.c92
-rw-r--r--test/aux-fixed/0536.aliases9
-rw-r--r--test/confs/0536104
-rw-r--r--test/log/053641
-rw-r--r--test/mail/0536.oksender32
-rw-r--r--test/mail/0536.user127
-rw-r--r--test/mail/0536.user227
-rw-r--r--test/paniclog/05365
-rw-r--r--test/rejectlog/053642
-rw-r--r--test/scripts/0000-Basic/053642
-rw-r--r--test/stderr/05365
-rw-r--r--test/stdout/053640
22 files changed, 551 insertions, 64 deletions
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 90a8a8350..b4d476aac 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -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
-------------------------------------------
@@ -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/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
-----------------
diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff
index 4f7ca8470..1ec1bdd2c 100644
--- a/doc/doc-txt/NewStuff
+++ b/doc/doc-txt/NewStuff
@@ -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
--------------------
@@ -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.
+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
------------
diff --git a/src/README.UPDATING b/src/README.UPDATING
index 05f89f40e..e4975ba6a 100644
--- a/src/README.UPDATING
+++ b/src/README.UPDATING
@@ -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
@@ -28,6 +28,22 @@ The rest of this document contains information about changes in 4.xx releases
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
-----------------
diff --git a/src/src/exim.c b/src/src/exim.c
index a40ded77e..3ac7d8313 100644
--- a/src/src/exim.c
+++ b/src/src/exim.c
@@ -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 *
@@ -1492,6 +1492,13 @@ using mac_ismsgid, which uses this. */
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. */
diff --git a/src/src/functions.h b/src/src/functions.h
index 2728d79f1..32b3d2d24 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -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 *
@@ -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 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);
diff --git a/src/src/globals.c b/src/src/globals.c
index 4455f384e..2a6aba592 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -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 *
@@ -211,22 +211,22 @@ uschar *acl_wherenames[] = { US"RCPT",
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;
@@ -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_smtp_code = NULL;
const pcre *regex_ismsgid = NULL;
#ifdef WITH_CONTENT_SCAN
uschar *regex_match_string = NULL;
diff --git a/src/src/globals.h b/src/src/globals.h
index 53272ceef..a235869c1 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -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 *
@@ -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 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) */
@@ -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_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) */
diff --git a/src/src/receive.c b/src/src/receive.c
index f711e9ca8..3f430f1aa 100644
--- a/src/src/receive.c
+++ b/src/src/receive.c
@@ -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 *
@@ -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();
- 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 */
@@ -3110,9 +3110,9 @@ else
{
uschar *istemp = US"";
uschar *s = NULL;
+ uschar *smtp_code;
int size = 0;
int sptr = 0;
- int code;
errmsg = local_scan_data;
@@ -3129,7 +3129,7 @@ else
/* Fall through */
case LOCAL_SCAN_REJECT:
- code = 550;
+ smtp_code = US"550";
if (errmsg == NULL) errmsg = US"Administrative prohibition";
break;
@@ -3139,7 +3139,7 @@ else
case LOCAL_SCAN_TEMPREJECT:
TEMPREJECT:
- code = 451;
+ smtp_code = US"451";
if (errmsg == NULL) errmsg = US"Temporary local problem";
istemp = US"temporarily ";
break;
@@ -3157,14 +3157,14 @@ else
{
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
{
- moan_smtp_batch(NULL, "%d %s", code, errmsg);
+ moan_smtp_batch(NULL, "%s %s", smtp_code, errmsg);
/* Does not return */
}
}
@@ -3483,8 +3483,8 @@ if (smtp_input)
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)
@@ -3494,8 +3494,8 @@ if (smtp_input)
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);
}
diff --git a/src/src/routers/redirect.c b/src/src/routers/redirect.c
index d94240ebc..2a9d5e3b2 100644
--- a/src/src/routers/redirect.c
+++ b/src/src/routers/redirect.c
@@ -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 *
@@ -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) },
+ { "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),
@@ -169,6 +171,7 @@ redirect_router_options_block redirect_router_option_defaults = {
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 */
@@ -711,26 +714,39 @@ switch (frc)
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:
- 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);
+ yield = FAIL;
+
+ SORT_MESSAGE:
if (addr->message == NULL)
- addr->message = US"forced rejection";
+ addr->message = (yield == FAIL)? US"forced rejection" : US"forced defer";
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);
}
- 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
diff --git a/src/src/routers/redirect.h b/src/src/routers/redirect.h
index 996f0b003..6825430fd 100644
--- a/src/src/routers/redirect.h
+++ b/src/src/routers/redirect.h
@@ -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 *
@@ -51,6 +51,7 @@ typedef struct {
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;
diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
index 99ac3fb1a..881bfff58 100644
--- a/src/src/smtp_in.c
+++ b/src/src/smtp_in.c
@@ -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 *
@@ -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:
- 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
@@ -1775,26 +1776,36 @@ Returns: nothing
*/
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 (codelen > 3)
+ {
+ esc = code + 4;
+ esclen = codelen - 4;
+ }
+
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)
{
- 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
{
- 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++;
}
@@ -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.
-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
@@ -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 code = acl_wherecodes[where];
BOOL drop = rc == FAIL_DROP;
+int codelen = 3;
+int ovector[3];
+uschar *smtp_code;
uschar *lognl;
uschar *sender_info = US"";
uschar *what =
@@ -1853,6 +1871,41 @@ uschar *what =
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
@@ -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)
- 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"
@@ -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. */
-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,
@@ -1937,12 +1990,13 @@ else
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
- 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.
diff --git a/test/aux-fixed/0536.aliases b/test/aux-fixed/0536.aliases
new file mode 100644
index 000000000..535399bdd
--- /dev/null
+++ b/test/aux-fixed/0536.aliases
@@ -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
index 000000000..0aa7c5201
--- /dev/null
+++ b/test/confs/0536
@@ -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
index 000000000..ab5fe84c6
--- /dev/null
+++ b/test/log/0536
@@ -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
index 000000000..9a3e0ea34
--- /dev/null
+++ b/test/mail/0536.oksender
@@ -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
index 000000000..b918842f9
--- /dev/null
+++ b/test/mail/0536.user1
@@ -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
index 000000000..64bd15814
--- /dev/null
+++ b/test/mail/0536.user2
@@ -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
index 000000000..38a1ee08e
--- /dev/null
+++ b/test/paniclog/0536
@@ -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
index 000000000..bf06473b6
--- /dev/null
+++ b/test/rejectlog/0536
@@ -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
index 000000000..30be87619
--- /dev/null
+++ b/test/scripts/0000-Basic/0536
@@ -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
index 000000000..38a1ee08e
--- /dev/null
+++ b/test/stderr/0536
@@ -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
index 000000000..cc4ce1e60
--- /dev/null
+++ b/test/stdout/0536
@@ -0,0 +1,40 @@
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+250-myhost.test.ex Hello CALLER at test.ex
+250-SIZE 52428800
+250-PIPELINING
+250 HELP
+250 OK
+550 No code
+599 Main code
+599-Main code
+599 on two lines
+599 5.2.3 Main and extended code
+599-5.12.3 Main and extended code
+599 5.12.3 on two lines
+550 Wrong code
+550 Wrong code
+499-4.12.343 Main and extended code
+499 4.12.343 on two lines
+499-4.1234.343 Main and extended code
+499 on two lines
+451 Wrong code
+550 No code
+590 Main code
+590 5.4.3 Main and extended code
+550 Wrong code
+451 Temporary local problem - please try later
+490 Temporary local problem - please try later
+490 4.4.3 Temporary local problem - please try later
+451 Temporary local problem - please try later
+221 myhost.test.ex closing connection
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+250-myhost.test.ex Hello CALLER at test.ex
+250-SIZE 52428800
+250-PIPELINING
+250 HELP
+250 OK
+550 No code
+550 Main code
+550 Main and extended code
+550 Wrong code
+221 myhost.test.ex closing connection