-/* $Cambridge: exim/src/src/routers/dnslookup.c,v 1.7 2005/09/19 09:41:37 fanf2 Exp $ */
-
/*************************************************
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2005 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
#include "../exim.h"
(void *)(offsetof(dnslookup_router_options_block, check_secondary_mx)) },
{ "check_srv", opt_stringptr,
(void *)(offsetof(dnslookup_router_options_block, check_srv)) },
+ { "fail_defer_domains", opt_stringptr,
+ (void *)(offsetof(dnslookup_router_options_block, fail_defer_domains)) },
{ "mx_domains", opt_stringptr,
(void *)(offsetof(dnslookup_router_options_block, mx_domains)) },
{ "mx_fail_domains", opt_stringptr,
NULL, /* mx_domains */
NULL, /* mx_fail_domains */
NULL, /* srv_fail_domains */
- NULL /* check_srv */
+ NULL, /* check_srv */
+ NULL /* fail_defer_domains */
};
(dnslookup_router_options_block *)(rblock->options_block);
uschar *srv_service = NULL;
uschar *widen = NULL;
-uschar *pre_widen = addr->domain;
-uschar *post_widen = NULL;
-uschar *fully_qualified_name;
-uschar *listptr;
+const uschar *pre_widen = addr->domain;
+const uschar *post_widen = NULL;
+const uschar *fully_qualified_name;
+const uschar *listptr;
uschar widen_buffer[256];
addr_new = addr_new; /* Keep picky compilers happy */
/* If an SRV check is required, expand the service name */
-if (ob->check_srv != NULL)
+if (ob->check_srv)
{
- srv_service = expand_string(ob->check_srv);
- if (srv_service == NULL && !expand_string_forcedfail)
+ if ( !(srv_service = expand_string(ob->check_srv))
+ && !expand_string_forcedfail)
{
addr->message = string_sprintf("%s router: failed to expand \"%s\": %s",
rblock->name, ob->check_srv, expand_string_message);
suppression of widening for sender addresses is silent because it is the
normal desirable behaviour. */
-if (ob->widen_domains != NULL &&
- (verify != v_sender || !ob->rewrite_headers || addr->parent != NULL))
+if ( ob->widen_domains
+ && (verify != v_sender || !ob->rewrite_headers || addr->parent))
{
listptr = ob->widen_domains;
widen = string_nextinlist(&listptr, &widen_sep, widen_buffer,
int flags = whichrrs;
BOOL removed = FALSE;
- if (pre_widen != NULL)
+ if (pre_widen)
{
h.name = pre_widen;
pre_widen = NULL;
}
- else if (widen != NULL)
+ else if (widen)
{
h.name = string_sprintf("%s.%s", addr->domain, widen);
widen = string_nextinlist(&listptr, &widen_sep, widen_buffer,
DEBUG(D_route) debug_printf("%s router widened %s to %s\n", rblock->name,
addr->domain, h.name);
}
- else if (post_widen != NULL)
+ else if (post_widen)
{
h.name = post_widen;
post_widen = NULL;
subsequently. We use the same logic as that for widen_domains above to avoid
requesting a header rewrite that cannot work. */
- if (verify != v_sender || !ob->rewrite_headers || addr->parent != NULL)
+ if (verify != v_sender || !ob->rewrite_headers || addr->parent)
{
if (ob->qualify_single) flags |= HOST_FIND_QUALIFY_SINGLE;
if (ob->search_parents) flags |= HOST_FIND_SEARCH_PARENTS;
}
- rc = host_find_bydns(&h, rblock->ignore_target_hosts, flags, srv_service,
- ob->srv_fail_domains, ob->mx_fail_domains, &fully_qualified_name, &removed);
+ rc = host_find_bydns(&h, CUS rblock->ignore_target_hosts, flags, srv_service,
+ ob->srv_fail_domains, ob->mx_fail_domains,
+ &rblock->dnssec, &fully_qualified_name, &removed);
if (removed) setflag(addr, af_local_host_removed);
/* If host found with only address records, test for the domain's being in
the option is historical. */
if ((rc == HOST_FOUND || rc == HOST_FOUND_LOCAL) && h.mx < 0 &&
- ob->mx_domains != NULL)
- {
- switch(match_isinlist(fully_qualified_name, &(ob->mx_domains), 0,
+ ob->mx_domains)
+ switch(match_isinlist(fully_qualified_name,
+ CUSS &(ob->mx_domains), 0,
&domainlist_anchor, addr->domain_cache, MCL_DOMAIN, TRUE, NULL))
{
case DEFER:
rblock->name, fully_qualified_name);
continue;
}
- }
/* Deferral returns forthwith, and anything other than failure breaks the
loop. */
+ if (rc == HOST_FIND_SECURITY)
+ {
+ addr->message = US"host lookup done insecurely";
+ return DEFER;
+ }
if (rc == HOST_FIND_AGAIN)
{
if (rblock->pass_on_timeout)
if (rc != HOST_FIND_FAILED) break;
- /* Check to see if the failure is the result of MX records pointing
- to non-existent domains, and if so, set an appropriate error message; the
- case of an SRV record pointing to "." is another special case that we can
+ if (ob->fail_defer_domains)
+ switch(match_isinlist(fully_qualified_name,
+ CUSS &ob->fail_defer_domains, 0,
+ &domainlist_anchor, addr->domain_cache, MCL_DOMAIN, TRUE, NULL))
+ {
+ case DEFER:
+ addr->message = US"lookup defer for fail_defer_domains option";
+ return DEFER;
+
+ case OK:
+ DEBUG(D_route) debug_printf("%s router: matched fail_defer_domains\n",
+ rblock->name);
+ addr->message = US"missing MX, or all MXs point to missing A records,"
+ " and defer requested";
+ return DEFER;
+ }
+ /* Check to see if the failure is the result of MX records pointing to
+ non-existent domains, and if so, set an appropriate error message; the case
+ of an MX or SRV record pointing to "." is another special case that we can
detect. Otherwise "unknown mail domain" is used, which is confusing. Also, in
this case don't do the widening. We need check only the first host to see if
its MX has been filled in, but there is no address, because if there were any
{
setflag(addr, af_pass_message); /* This is not a security risk */
if (h.name[0] == 0)
- addr->message = US"an SRV record indicated no SMTP service";
+ addr->message = US"an MX or SRV record indicated no SMTP service";
else
{
+ addr->basic_errno = ERRNO_UNKNOWNHOST;
addr->message = US"all relevant MX records point to non-existent hosts";
- if (!allow_mx_to_ip && string_is_ip_address(h.name, NULL) > 0)
+ if (!allow_mx_to_ip && string_is_ip_address(h.name, NULL) != 0)
{
addr->user_message =
string_sprintf("It appears that the DNS operator for %s\n"
/* Set up the errors address, if any. */
-rc = rf_get_errors_address(addr, rblock, verify, &(addr->p.errors_address));
+rc = rf_get_errors_address(addr, rblock, verify, &addr->prop.errors_address);
if (rc != OK) return rc;
/* Set up the additional and removeable headers for this address. */
-rc = rf_get_munge_headers(addr, rblock, &(addr->p.extra_headers),
- &(addr->p.remove_headers));
+rc = rf_get_munge_headers(addr, rblock, &addr->prop.extra_headers,
+ &addr->prop.remove_headers);
if (rc != OK) return rc;
/* Get store in which to preserve the original host item, chained on
}
/* End of routers/dnslookup.c */
+/* vi: aw ai sw=2
+*/