summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2017-11-11 16:11:06 +0000
committerJeremy Harris <jgh146exb@wizmail.org>2017-11-11 16:11:06 +0000
commit72934ba73e5ac5fbd64b56dc684e3371a9651909 (patch)
treec1373e0828bd52539188fa6891a7d18afc702976
parentce25e2982bde749c219357bd5983d2735277919f (diff)
Downgrade an unfound-list name from panic to DEFER. Bug 1645
-rw-r--r--doc/doc-txt/ChangeLog7
-rw-r--r--src/src/match.c238
-rw-r--r--test/confs/027510
-rw-r--r--test/scripts/0000-Basic/02759
-rw-r--r--test/stderr/027578
-rw-r--r--test/stdout/027510
6 files changed, 230 insertions, 122 deletions
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index fd188a00a..00377b9ff 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -186,6 +186,13 @@ JH/32 DKIM: when a message has multiple signatures matching an identity given
in dkim_verify_signers, run the dkim acl once for each. Previously only
one run was done. Bug 2189.
+JH/33 Downgrade an unfound-list name (usually a typo in the config file) from
+ "panic the current process" to "deliberately defer". The panic log is
+ still written with the problem list name; the mail and reject logs now
+ get a temp-reject line for the message that was being handled, saying
+ something like "domains check lookup or other defer". The SMTP 451
+ message is still "Temporary local problem".
+
Exim version 4.89
-----------------
diff --git a/src/src/match.c b/src/src/match.c
index c21711410..08ec0eeab 100644
--- a/src/src/match.c
+++ b/src/src/match.c
@@ -461,12 +461,9 @@ HDEBUG(D_any)
/* If the list is empty, the answer is no. Skip the debugging output for
an unnamed list. */
-if (*listptr == NULL)
+if (!*listptr)
{
- HDEBUG(D_lists)
- {
- if (ot != NULL) debug_printf("%s no (option unset)\n", ot);
- }
+ HDEBUG(D_lists) if (ot) debug_printf("%s no (option unset)\n", ot);
return FAIL;
}
@@ -485,17 +482,17 @@ else
/* If we are searching a domain list, and $domain is not set, set it to the
subject that is being sought for the duration of the expansion. */
- if (type == MCL_DOMAIN && deliver_domain == NULL)
+ if (type == MCL_DOMAIN && !deliver_domain)
{
check_string_block *cb = (check_string_block *)arg;
deliver_domain = string_copy(cb->subject);
list = expand_cstring(*listptr);
deliver_domain = NULL;
}
+ else
+ list = expand_cstring(*listptr);
- else list = expand_cstring(*listptr);
-
- if (list == NULL)
+ if (!list)
{
if (expand_string_forcedfail)
{
@@ -511,17 +508,14 @@ else
/* For an unnamed list, use the expanded version in comments */
-HDEBUG(D_any)
- {
- if (ot == NULL) ot = string_sprintf("%s in \"%s\"?", name, list);
- }
+HDEBUG(D_any) if (ot == NULL) ot = string_sprintf("%s in \"%s\"?", name, list);
/* Now scan the list and process each item in turn, until one of them matches,
or we hit an error. */
-while ((sss = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
+while ((sss = string_nextinlist(&list, &sep, buffer, sizeof(buffer))))
{
- uschar *ss = sss;
+ uschar * ss = sss;
/* Address lists may contain +caseful, to restore caseful matching of the
local part. We have to know the layout of the control block, unfortunately.
@@ -534,7 +528,8 @@ while ((sss = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
{
check_address_block *cb = (check_address_block *)arg;
uschar *at = Ustrrchr(cb->origaddress, '@');
- if (at != NULL)
+
+ if (at)
Ustrncpy(cb->address, cb->origaddress, at - cb->origaddress);
cb->caseless = FALSE;
continue;
@@ -594,7 +589,8 @@ while ((sss = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
yield = FAIL;
while (isspace((*(++ss))));
}
- else yield = OK;
+ else
+ yield = OK;
/* If the item does not begin with '/', it might be a + item for a named
list. Otherwise, it is just a single list entry that has to be matched.
@@ -602,7 +598,7 @@ while ((sss = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
if (*ss != '/')
{
- if (*ss == '+' && anchorptr != NULL)
+ if (*ss == '+' && anchorptr)
{
int bits = 0;
int offset = 0;
@@ -610,15 +606,18 @@ while ((sss = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
unsigned int *use_cache_bits = original_cache_bits;
uschar *cached = US"";
namedlist_block *nb;
- tree_node *t = tree_search(*anchorptr, ss+1);
-
- if (t == NULL)
- log_write(0, LOG_MAIN|LOG_PANIC_DIE, "unknown named%s list \"%s\"",
- (type == MCL_DOMAIN)? " domain" :
- (type == MCL_HOST)? " host" :
- (type == MCL_ADDRESS)? " address" :
- (type == MCL_LOCALPART)? " local part" : "",
+ tree_node * t;
+
+ if (!(t = tree_search(*anchorptr, ss+1)))
+ {
+ log_write(0, LOG_MAIN|LOG_PANIC, "unknown named%s list \"%s\"",
+ type == MCL_DOMAIN ? " domain" :
+ type == MCL_HOST ? " host" :
+ type == MCL_ADDRESS ? " address" :
+ type == MCL_LOCALPART ? " local part" : "",
ss);
+ return DEFER;
+ }
nb = t->data.ptr;
/* If the list number is negative, it means that this list is not
@@ -630,7 +629,7 @@ while ((sss = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
because the pointer may be NULL from the start if caching is not
required. */
- if (use_cache_bits != NULL)
+ if (use_cache_bits)
{
offset = (nb->number)/16;
shift = ((nb->number)%16)*2;
@@ -654,15 +653,13 @@ while ((sss = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
wasn't before. Ensure that this is passed up to the next level.
Otherwise, remember the result of the search in the cache. */
- if (use_cache_bits == NULL)
- {
+ if (!use_cache_bits)
*cache_ptr = NULL;
- }
else
{
use_cache_bits[offset] |= bits << shift;
- if (valueptr != NULL)
+ if (valueptr)
{
int old_pool = store_pool;
namedlist_cacheblock *p;
@@ -675,16 +672,14 @@ while ((sss = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
p->key = string_copy(get_check_key(arg, type));
- p->data = (*valueptr == NULL)? NULL : string_copy(*valueptr);
+ p->data = *valueptr ? string_copy(*valueptr) : NULL;
store_pool = old_pool;
p->next = nb->cache_data;
nb->cache_data = p;
- if (*valueptr != NULL)
- {
+ if (*valueptr)
DEBUG(D_lists) debug_printf("data from lookup saved for "
"cache for %s: %s\n", ss, *valueptr);
- }
}
}
}
@@ -697,19 +692,18 @@ while ((sss = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
{
DEBUG(D_lists) debug_printf("cached %s match for %s\n",
((bits & (-bits)) == bits)? "yes" : "no", ss);
+
cached = US" - cached";
- if (valueptr != NULL)
+ if (valueptr)
{
const uschar *key = get_check_key(arg, type);
namedlist_cacheblock *p;
- for (p = nb->cache_data; p != NULL; p = p->next)
- {
+ for (p = nb->cache_data; p; p = p->next)
if (Ustrcmp(key, p->key) == 0)
{
*valueptr = p->data;
break;
}
- }
DEBUG(D_lists) debug_printf("cached lookup data = %s\n", *valueptr);
}
}
@@ -729,30 +723,30 @@ while ((sss = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
else
{
- uschar *error = NULL;
+ uschar * error = NULL;
switch ((func)(arg, ss, valueptr, &error))
{
case OK:
- HDEBUG(D_lists) debug_printf("%s %s (matched \"%s\")\n", ot,
- (yield == OK)? "yes" : "no", sss);
- return yield;
+ HDEBUG(D_lists) debug_printf("%s %s (matched \"%s\")\n", ot,
+ (yield == OK)? "yes" : "no", sss);
+ return yield;
case DEFER:
- if (error == NULL)
- error = string_sprintf("DNS lookup of \"%s\" deferred", ss);
- if (ignore_defer)
- {
- HDEBUG(D_lists) debug_printf("%s: item ignored by +ignore_defer\n",
- error);
- break;
- }
- if (include_defer)
- {
- log_write(0, LOG_MAIN, "%s: accepted by +include_defer", error);
- return OK;
- }
- if (!search_error_message) search_error_message = error;
- goto DEFER_RETURN;
+ if (!error)
+ error = string_sprintf("DNS lookup of \"%s\" deferred", ss);
+ if (ignore_defer)
+ {
+ HDEBUG(D_lists) debug_printf("%s: item ignored by +ignore_defer\n",
+ error);
+ break;
+ }
+ if (include_defer)
+ {
+ log_write(0, LOG_MAIN, "%s: accepted by +include_defer", error);
+ return OK;
+ }
+ if (!search_error_message) search_error_message = error;
+ goto DEFER_RETURN;
/* The ERROR return occurs when checking hosts, when either a forward
or reverse lookup has failed. It can also occur in a match_ip list if a
@@ -760,24 +754,24 @@ while ((sss = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
which it was. */
case ERROR:
- if (ignore_unknown)
- {
- HDEBUG(D_lists) debug_printf("%s: item ignored by +ignore_unknown\n",
- error);
- }
- else
- {
- HDEBUG(D_lists) debug_printf("%s %s (%s)\n", ot,
- include_unknown? "yes":"no", error);
- if (!include_unknown)
- {
- if (LOGGING(unknown_in_list))
- log_write(0, LOG_MAIN, "list matching forced to fail: %s", error);
- return FAIL;
- }
- log_write(0, LOG_MAIN, "%s: accepted by +include_unknown", error);
- return OK;
- }
+ if (ignore_unknown)
+ {
+ HDEBUG(D_lists) debug_printf("%s: item ignored by +ignore_unknown\n",
+ error);
+ }
+ else
+ {
+ HDEBUG(D_lists) debug_printf("%s %s (%s)\n", ot,
+ include_unknown? "yes":"no", error);
+ if (!include_unknown)
+ {
+ if (LOGGING(unknown_in_list))
+ log_write(0, LOG_MAIN, "list matching forced to fail: %s", error);
+ return FAIL;
+ }
+ log_write(0, LOG_MAIN, "%s: accepted by +include_unknown", error);
+ return OK;
+ }
}
}
}
@@ -788,16 +782,16 @@ while ((sss = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
else
{
int file_yield = yield; /* In case empty file */
- uschar *filename = ss;
- FILE *f = Ufopen(filename, "rb");
+ uschar * filename = ss;
+ FILE * f = Ufopen(filename, "rb");
uschar filebuffer[1024];
/* ot will be null in non-debugging cases, and anyway, we get better
wording by reworking it. */
- if (f == NULL)
+ if (!f)
{
- uschar *listname = readconf_find_option(listptr);
+ uschar * listname = readconf_find_option(listptr);
if (listname[0] == 0)
listname = string_sprintf("\"%s\"", *listptr);
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s",
@@ -845,48 +839,48 @@ while ((sss = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
switch ((func)(arg, ss, valueptr, &error))
{
case OK:
- (void)fclose(f);
- HDEBUG(D_lists) debug_printf("%s %s (matched \"%s\" in %s)\n", ot,
- (yield == OK)? "yes" : "no", sss, filename);
- return file_yield;
+ (void)fclose(f);
+ HDEBUG(D_lists) debug_printf("%s %s (matched \"%s\" in %s)\n", ot,
+ yield == OK ? "yes" : "no", sss, filename);
+ return file_yield;
case DEFER:
- if (error == NULL)
- error = string_sprintf("DNS lookup of %s deferred", ss);
- if (ignore_defer)
- {
- HDEBUG(D_lists) debug_printf("%s: item ignored by +ignore_defer\n",
- error);
- break;
- }
- (void)fclose(f);
- if (include_defer)
- {
- log_write(0, LOG_MAIN, "%s: accepted by +include_defer", error);
- return OK;
- }
- goto DEFER_RETURN;
-
- case ERROR: /* host name lookup failed - this can only */
- if (ignore_unknown) /* be for an incoming host (not outgoing) */
- {
- HDEBUG(D_lists) debug_printf("%s: item ignored by +ignore_unknown\n",
- error);
- }
- else
- {
- HDEBUG(D_lists) debug_printf("%s %s (%s)\n", ot,
- include_unknown? "yes":"no", error);
- (void)fclose(f);
- if (!include_unknown)
- {
- if (LOGGING(unknown_in_list))
- log_write(0, LOG_MAIN, "list matching forced to fail: %s", error);
- return FAIL;
- }
- log_write(0, LOG_MAIN, "%s: accepted by +include_unknown", error);
- return OK;
- }
+ if (!error)
+ error = string_sprintf("DNS lookup of %s deferred", ss);
+ if (ignore_defer)
+ {
+ HDEBUG(D_lists) debug_printf("%s: item ignored by +ignore_defer\n",
+ error);
+ break;
+ }
+ (void)fclose(f);
+ if (include_defer)
+ {
+ log_write(0, LOG_MAIN, "%s: accepted by +include_defer", error);
+ return OK;
+ }
+ goto DEFER_RETURN;
+
+ case ERROR: /* host name lookup failed - this can only */
+ if (ignore_unknown) /* be for an incoming host (not outgoing) */
+ {
+ HDEBUG(D_lists) debug_printf("%s: item ignored by +ignore_unknown\n",
+ error);
+ }
+ else
+ {
+ HDEBUG(D_lists) debug_printf("%s %s (%s)\n", ot,
+ include_unknown? "yes":"no", error);
+ (void)fclose(f);
+ if (!include_unknown)
+ {
+ if (LOGGING(unknown_in_list))
+ log_write(0, LOG_MAIN, "list matching forced to fail: %s", error);
+ return FAIL;
+ }
+ log_write(0, LOG_MAIN, "%s: accepted by +include_unknown", error);
+ return OK;
+ }
}
}
@@ -901,8 +895,8 @@ while ((sss = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
/* End of list reached: if the last item was negated yield OK, else FAIL. */
HDEBUG(D_lists)
- debug_printf("%s %s (end of list)\n", ot, (yield == OK)? "no":"yes");
-return (yield == OK)? FAIL : OK;
+ debug_printf("%s %s (end of list)\n", ot, yield == OK ? "no":"yes");
+return yield == OK ? FAIL : OK;
/* Something deferred */
diff --git a/test/confs/0275 b/test/confs/0275
index 3734e03ea..7117d517c 100644
--- a/test/confs/0275
+++ b/test/confs/0275
@@ -6,6 +6,8 @@ primary_hostname = myhost.test.ex
# ----- Main settings -----
+acl_smtp_rcpt = accept verify = recipient
+
domainlist nocache = $local_part
domainlist nocache2 = +nocache
domainlist local_domains = test.ex
@@ -36,6 +38,14 @@ t1:
begin routers
+.ifdef FAKE
+r0f:
+ driver = accept
+ local_parts = error
+ domains = +no_such_list
+ transport = t1
+.endif
+
r00:
driver = accept
domains = +nocache
diff --git a/test/scripts/0000-Basic/0275 b/test/scripts/0000-Basic/0275
index 410efa8d3..953ab7e8f 100644
--- a/test/scripts/0000-Basic/0275
+++ b/test/scripts/0000-Basic/0275
@@ -1,5 +1,14 @@
# named domain lists
exim -d -bt userx@test.ex
****
+#
exim -d -odi userx@test.ex
****
+#
+exim -d -DFAKE -bh 127.0.0.1
+HELO test
+MAIL FROM:<test@test.ex>
+RCPT TO:<error@test.ex>
+QUIT
+****
+#
diff --git a/test/stderr/0275 b/test/stderr/0275
index b663ad4b8..f34132b55 100644
--- a/test/stderr/0275
+++ b/test/stderr/0275
@@ -357,3 +357,81 @@ search_tidyup called
>>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
search_tidyup called
>>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
+Exim version x.yz ....
+changed uid/gid: forcing real = effective
+ uid=uuuu gid=CALLER_GID pid=pppp
+configuration file is TESTSUITE/test-config
+admin user
+changed uid/gid: privilege not needed
+ uid=EXIM_UID gid=EXIM_GID pid=pppp
+seeking password data for user "CALLER": cache not available
+getpwnam() succeeded uid=CALLER_UID gid=CALLER_GID
+DSN: r0f propagating DSN
+DSN: r00 propagating DSN
+DSN: r01 propagating DSN
+DSN: r02 propagating DSN
+DSN: r03 propagating DSN
+DSN: r04 propagating DSN
+DSN: r05 propagating DSN
+DSN: r1 propagating DSN
+DSN: r2 propagating DSN
+DSN: r3 propagating DSN
+originator: uid=CALLER_UID gid=CALLER_GID login=CALLER name=CALLER_NAME
+sender address = CALLER@test.ex
+sender_fullhost = [127.0.0.1]
+sender_rcvhost = [127.0.0.1]
+host in hosts_connection_nolog? no (option unset)
+LOG: smtp_connection MAIN
+ SMTP connection from [127.0.0.1]
+host in host_lookup? no (option unset)
+set_process_info: pppp handling incoming connection from [127.0.0.1]
+host in host_reject_connection? no (option unset)
+host in sender_unqualified_hosts? no (option unset)
+host in recipient_unqualified_hosts? no (option unset)
+host in helo_verify_hosts? no (option unset)
+host in helo_try_verify_hosts? no (option unset)
+host in helo_accept_junk_hosts? no (option unset)
+SMTP>> 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+smtp_setup_msg entered
+SMTP<< HELO test
+test in helo_lookup_domains? no (end of list)
+sender_fullhost = (test) [127.0.0.1]
+sender_rcvhost = [127.0.0.1] (helo=test)
+set_process_info: pppp handling incoming connection from (test) [127.0.0.1]
+SMTP>> 250 myhost.test.ex Hello test [127.0.0.1]
+SMTP<< MAIL FROM:<test@test.ex>
+spool directory space = nnnnnK inodes = nnnnn check_space = 10240K inodes = 100 msg_size = 0
+log directory space = nnnnnK inodes = nnnnn check_space = 10240K inodes = 100
+SMTP>> 250 OK
+SMTP<< RCPT TO:<error@test.ex>
+test.ex in "! *.ex"? no (matched "! *.ex")
+test.ex in "test.ex"? yes (matched "test.ex")
+test.ex in percent_hack_domains? yes (matched "+not_queue_domains")
+processing "accept"
+check verify = recipient
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+Verifying error@test.ex
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+Considering error@test.ex
+cached no match for +hold_domains
+cached yes match for +not_queue_domains
+test.ex in percent_hack_domains? yes (matched "+not_queue_domains" - cached)
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+routing error@test.ex
+--------> r0f router <--------
+local_part=error domain=test.ex
+checking domains
+LOG: MAIN PANIC
+ unknown named domain list "+no_such_list"
+domains check lookup or other defer
+----------- end verify ------------
+accept: condition test deferred in inline ACL
+SMTP>> 451 Temporary local problem - please try later
+LOG: MAIN REJECT
+ H=(test) [127.0.0.1] F=<test@test.ex> temporarily rejected RCPT <error@test.ex>: domains check lookup or other defer
+SMTP<< QUIT
+SMTP>> 221 myhost.test.ex closing connection
+LOG: smtp_connection MAIN
+ SMTP connection from (test) [127.0.0.1] closed by QUIT
+search_tidyup called
+>>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
diff --git a/test/stdout/0275 b/test/stdout/0275
index fa02efa75..1642be115 100644
--- a/test/stdout/0275
+++ b/test/stdout/0275
@@ -1,2 +1,12 @@
userx@test.ex
router = r3, transport = t1
+
+**** SMTP testing session as if from host 127.0.0.1
+**** but without any ident (RFC 1413) callback.
+**** This is not for real!
+
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+250 myhost.test.ex Hello test [127.0.0.1]
+250 OK
+451 Temporary local problem - please try later
+221 myhost.test.ex closing connection