From 2b1c6e3a3a41b680dcefcb87d6c373431f718607 Mon Sep 17 00:00:00 2001 From: Philip Hazel Date: Tue, 5 Sep 2006 13:24:10 +0000 Subject: (1) Update version number to 4.64. (2) Ignore callout cached information that MAIL FROM:<> is rejected when verifying a recipient using a non-null MAIL address. --- src/src/dbstuff.h | 10 ++++---- src/src/macros.h | 5 ++-- src/src/verify.c | 72 +++++++++++++++++++++++++++++++++++++++---------------- src/src/version.c | 4 ++-- 4 files changed, 63 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/src/dbstuff.h b/src/src/dbstuff.h index 06facfb09..2b51b0ba8 100644 --- a/src/src/dbstuff.h +++ b/src/src/dbstuff.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/dbstuff.h,v 1.4 2006/02/07 11:19:00 ph10 Exp $ */ +/* $Cambridge: exim/src/src/dbstuff.h,v 1.5 2006/09/05 13:24:10 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -564,9 +564,11 @@ performed on them. There are two groups of records: 2. keyed by domain - Domain response upto MAIL FROM:<>, postmaster, random local part; -If a record exists, the result field is either ccache_accept or ccache_reject. -The other fields, however, (which are only relevant to domain records) may also -contain ccache_unknown if that particular test has not been done. +If a record exists, the result field is either ccache_accept or ccache_reject, +or, for a domain record only, ccache_reject_mfnull when MAIL FROM:<> was +rejected. The other fields, however, (which are only relevant to domain +records) may also contain ccache_unknown if that particular test has not been +done. Originally, there was only one structure, used for both types. However, it got expanded for domain records, so it got split. To make it possible for Exim to diff --git a/src/src/macros.h b/src/src/macros.h index 59c05e697..0b0215bdc 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/macros.h,v 1.26 2006/06/28 16:00:24 ph10 Exp $ */ +/* $Cambridge: exim/src/src/macros.h,v 1.27 2006/09/05 13:24:10 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -626,7 +626,8 @@ enum { v_none, v_sender, v_recipient, v_expn }; #define ccache_unknown 0 /* test hasn't been done */ #define ccache_accept 1 -#define ccache_reject 2 +#define ccache_reject 2 /* All rejections except */ +#define ccache_reject_mfnull 3 /* MAIL FROM:<> was rejected */ /* Options for lookup functions */ diff --git a/src/src/verify.c b/src/src/verify.c index 841285fdc..783378946 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/verify.c,v 1.37 2006/06/30 15:36:08 ph10 Exp $ */ +/* $Cambridge: exim/src/src/verify.c,v 1.38 2006/09/05 13:24:10 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -148,6 +148,7 @@ BOOL callout_no_cache = (options & vopt_callout_no_cache) != 0; BOOL callout_random = (options & vopt_callout_random) != 0; int yield = OK; +int old_domain_cache_result = ccache_accept; BOOL done = FALSE; uschar *address_key; uschar *from_address; @@ -228,10 +229,18 @@ if (dbm_file != NULL) if (cache_record != NULL) { - /* If an early command (up to and including MAIL FROM:<>) was rejected, - there is no point carrying on. The callout fails. */ - - if (cache_record->result == ccache_reject) + /* In most cases, if an early command (up to and including MAIL FROM:<>) + was rejected, there is no point carrying on. The callout fails. However, if + we are doing a recipient verification with use_sender or use_postmaster + set, a previous failure of MAIL FROM:<> doesn't count, because this time we + will be using a non-empty sender. We have to remember this situation so as + not to disturb the cached domain value if this whole verification succeeds + (we don't want it turning into "accept"). */ + + old_domain_cache_result = cache_record->result; + + if (cache_record->result == ccache_reject || + (*from_address == 0 && cache_record->result == ccache_reject_mfnull)) { setflag(addr, af_verify_nsfail); HDEBUG(D_verify) @@ -462,50 +471,73 @@ for (host = host_list; host != NULL && !done; host = host->next) continue; } - /* Wait for initial response, and then run the initial SMTP commands. The - smtp_write_command() function leaves its command in big_buffer. This is - used in error responses. Initialize it in case the connection is - rejected. */ + /* Wait for initial response, and send HELO. The smtp_write_command() + function leaves its command in big_buffer. This is used in error responses. + Initialize it in case the connection is rejected. */ Ustrcpy(big_buffer, "initial connection"); done = smtp_read_response(&inblock, responsebuffer, sizeof(responsebuffer), '2', callout) && - smtp_write_command(&outblock, FALSE, "%s %s\r\n", helo, smtp_active_hostname) >= 0 && smtp_read_response(&inblock, responsebuffer, sizeof(responsebuffer), - '2', callout) && + '2', callout); + /* Failure to accept HELO is cached; this blocks the whole domain for all + senders. I/O errors and defer responses are not cached. */ + + if (!done) + { + *failure_ptr = US"mail"; /* At or before MAIL */ + if (errno == 0 && responsebuffer[0] == '5') + { + setflag(addr, af_verify_nsfail); + new_domain_record.result = ccache_reject; + } + } + + /* Send the MAIL command */ + + else done = smtp_write_command(&outblock, FALSE, "MAIL FROM:<%s>\r\n", from_address) >= 0 && smtp_read_response(&inblock, responsebuffer, sizeof(responsebuffer), '2', callout); - /* If the host gave an initial error, or does not accept HELO or MAIL - FROM:<>, arrange to cache this information, but don't record anything for an - I/O error or a defer. Do not cache rejections when a non-empty sender has - been used, because that blocks the whole domain for all senders. */ + /* If the host does not accept MAIL FROM:<>, arrange to cache this + information, but again, don't record anything for an I/O error or a defer. Do + not cache rejections of MAIL when a non-empty sender has been used, because + that blocks the whole domain for all senders. */ if (!done) { - *failure_ptr = US"mail"; + *failure_ptr = US"mail"; /* At or before MAIL */ if (errno == 0 && responsebuffer[0] == '5') { setflag(addr, af_verify_nsfail); - if (from_address[0] == 0) new_domain_record.result = ccache_reject; + if (from_address[0] == 0) + new_domain_record.result = ccache_reject_mfnull; } } /* Otherwise, proceed to check a "random" address (if required), then the given address, and the postmaster address (if required). Between each check, issue RSET, because some servers accept only one recipient after MAIL - FROM:<>. */ + FROM:<>. + + Before doing this, set the result in the domain cache record to "accept", + unless its previous value was ccache_reject_mfnull. In that case, the domain + rejects MAIL FROM:<> and we want to continue to remember that. When that is + the case, we have got here only in the case of a recipient verification with + a non-null sender. */ else { - new_domain_record.result = ccache_accept; + new_domain_record.result = + (old_domain_cache_result == ccache_reject_mfnull)? + ccache_reject_mfnull: ccache_accept; /* Do the random local part check first */ @@ -685,7 +717,7 @@ However, there may be domain-specific information to cache in both cases. The value of the result field in the new_domain record is ccache_unknown if there was an error before or with MAIL FROM:, and errno was not zero, implying some kind of I/O error. We don't want to write the cache in that case. -Otherwise the value is ccache_accept or ccache_reject. */ +Otherwise the value is ccache_accept, ccache_reject, or ccache_reject_mfnull. */ if (!callout_no_cache && new_domain_record.result != ccache_unknown) { diff --git a/src/src/version.c b/src/src/version.c index 179ebaa90..e83905eb4 100644 --- a/src/src/version.c +++ b/src/src/version.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/version.c,v 1.17 2006/06/27 13:39:24 ph10 Exp $ */ +/* $Cambridge: exim/src/src/version.c,v 1.18 2006/09/05 13:24:10 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -12,7 +12,7 @@ #include "exim.h" -#define THIS_VERSION "4.63" +#define THIS_VERSION "4.64" /* The header file cnumber.h contains a single line containing the -- cgit v1.2.3