diff options
-rw-r--r-- | doc/doc-txt/ChangeLog | 7 | ||||
-rw-r--r-- | src/src/match.c | 238 | ||||
-rw-r--r-- | test/confs/0275 | 10 | ||||
-rw-r--r-- | test/scripts/0000-Basic/0275 | 9 | ||||
-rw-r--r-- | test/stderr/0275 | 78 | ||||
-rw-r--r-- | test/stdout/0275 | 10 |
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
|