deliver
[exim.git] / src / src / host.c
index 456365c8f3c13e15a3a34e31c449564b76395155..e11931b604781f8b64740d14d7dc645a2ee1a027 100644 (file)
@@ -3,6 +3,7 @@
 *************************************************/
 
 /* Copyright (c) University of Cambridge 1995 - 2018 */
 *************************************************/
 
 /* Copyright (c) University of Cambridge 1995 - 2018 */
+/* Copyright (c) The Exim Maintainers 2020 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* Functions for finding hosts, either by gethostbyname(), gethostbyaddr(), or
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* Functions for finding hosts, either by gethostbyname(), gethostbyaddr(), or
@@ -221,7 +222,8 @@ if ((ipa = string_is_ip_address(lname, NULL)) != 0)
   else
     {
     *error_num = HOST_NOT_FOUND;
   else
     {
     *error_num = HOST_NOT_FOUND;
-    return NULL;
+    yield = NULL;
+    goto out;
     }
 
 /* Handle a host name */
     }
 
 /* Handle a host name */
@@ -237,11 +239,11 @@ else
   switch(rc)
     {
     case DNS_SUCCEED: break;
   switch(rc)
     {
     case DNS_SUCCEED: break;
-    case DNS_NOMATCH: *error_num = HOST_NOT_FOUND; return NULL;
-    case DNS_NODATA:  *error_num = NO_DATA; return NULL;
-    case DNS_AGAIN:   *error_num = TRY_AGAIN; return NULL;
+    case DNS_NOMATCH: *error_num = HOST_NOT_FOUND; yield = NULL; goto out;
+    case DNS_NODATA:  *error_num = NO_DATA; yield = NULL; goto out;
+    case DNS_AGAIN:   *error_num = TRY_AGAIN; yield = NULL; goto out;
     default:
     default:
-    case DNS_FAIL:    *error_num = NO_RECOVERY; return NULL;
+    case DNS_FAIL:    *error_num = NO_RECOVERY; yield = NULL; goto out;
     }
 
   for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS);
     }
 
   for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS);
@@ -279,6 +281,9 @@ else
   *alist = NULL;
   }
 
   *alist = NULL;
   }
 
+out:
+
+store_free_dns_answer(dnsa);
 return yield;
 }
 
 return yield;
 }
 
@@ -814,7 +819,7 @@ host_find_interfaces(void)
 {
 ip_address_item *running_interfaces = NULL;
 
 {
 ip_address_item *running_interfaces = NULL;
 
-if (local_interface_data == NULL)
+if (!local_interface_data)
   {
   void *reset_item = store_mark();
   ip_address_item *dlist = host_build_ifacelist(CUS local_interfaces,
   {
   void *reset_item = store_mark();
   ip_address_item *dlist = host_build_ifacelist(CUS local_interfaces,
@@ -1196,9 +1201,9 @@ for (c = buffer, k = -1, i = 0; i < 8; i++)
   c++;
   }
 
   c++;
   }
 
-c[-1] = '\0';  /* drop trailing colon */
+*--c = '\0';   /* drop trailing colon */
 
 
-/* debug_printf("%s: D k %d <%s> <%s>\n", __FUNCTION__, k, d, d + 2*(k+1)); */
+/* debug_printf("%s: D k %d <%s> <%s>\n", __FUNCTION__, k, buffer, buffer + 2*(k+1)); */
 if (k >= 0)
   {                    /* collapse */
   c = d + 2*(k+1);
 if (k >= 0)
   {                    /* collapse */
   c = d + 2*(k+1);
@@ -1231,14 +1236,11 @@ BOOL
 host_is_tls_on_connect_port(int port)
 {
 int sep = 0;
 host_is_tls_on_connect_port(int port)
 {
 int sep = 0;
-uschar buffer[32];
-const uschar *list = tls_in.on_connect_ports;
-uschar *s;
-uschar *end;
+const uschar * list = tls_in.on_connect_ports;
 
 if (tls_in.on_connect) return TRUE;
 
 
 if (tls_in.on_connect) return TRUE;
 
-while ((s = string_nextinlist(&list, &sep, buffer, sizeof(buffer))))
+for (uschar * s, * end; s = string_nextinlist(&list, &sep, NULL, 0); )
   if (Ustrtol(s, &end, 10) == port)
     return TRUE;
 
   if (Ustrtol(s, &end, 10) == port)
     return TRUE;
 
@@ -1580,7 +1582,7 @@ Put it in permanent memory. */
 
   if (hosts->h_aliases)
     {
 
   if (hosts->h_aliases)
     {
-    int count = 1;
+    int count = 1;  /* need 1 more for terminating NULL */
     uschar **ptr;
 
     for (uschar ** aliases = USS hosts->h_aliases; *aliases; aliases++) count++;
     uschar **ptr;
 
     for (uschar ** aliases = USS hosts->h_aliases; *aliases; aliases++) count++;
@@ -1689,7 +1691,7 @@ while ((ordername = string_nextinlist(&list, &sep, NULL, 0)))
       {
       uschar **aptr = NULL;
       int ssize = 264;
       {
       uschar **aptr = NULL;
       int ssize = 264;
-      int count = 0;
+      int count = 1;  /* need 1 more for terminating NULL */
       int old_pool = store_pool;
 
       sender_host_dnssec = dns_is_secure(dnsa);
       int old_pool = store_pool;
 
       sender_host_dnssec = dns_is_secure(dnsa);
@@ -1945,8 +1947,13 @@ host_find_byname(host_item *host, const uschar *ignore_target_hosts, int flags,
 int yield, times;
 host_item *last = NULL;
 BOOL temp_error = FALSE;
 int yield, times;
 host_item *last = NULL;
 BOOL temp_error = FALSE;
-#if HAVE_IPV6
 int af;
 int af;
+
+#ifndef DISABLE_TLS
+/* Copy the host name at this point to the value which is used for
+TLS certificate name checking, before anything modifies it.  */
+
+host->certname = host->name;
 #endif
 
 /* Make sure DNS options are set as required. This appears to be necessary in
 #endif
 
 /* Make sure DNS options are set as required. This appears to be necessary in
@@ -1966,10 +1973,10 @@ lookups here (except when testing standalone). */
   #ifdef STAND_ALONE
   if (disable_ipv6)
   #else
   #ifdef STAND_ALONE
   if (disable_ipv6)
   #else
-  if (disable_ipv6 ||
-    (dns_ipv4_lookup != NULL &&
-        match_isinlist(host->name, CUSS &dns_ipv4_lookup, 0, NULL, NULL,
-         MCL_DOMAIN, TRUE, NULL) == OK))
+  if (  disable_ipv6
+     ||    dns_ipv4_lookup
+       && match_isinlist(host->name, CUSS &dns_ipv4_lookup, 0,
+           &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL) == OK)
   #endif
 
     { af = AF_INET; times = 1; }
   #endif
 
     { af = AF_INET; times = 1; }
@@ -1979,7 +1986,7 @@ lookups here (except when testing standalone). */
 /* No IPv6 support */
 
 #else   /* HAVE_IPV6 */
 /* No IPv6 support */
 
 #else   /* HAVE_IPV6 */
-  times = 1;
+  af = AF_INET; times = 1;
 #endif  /* HAVE_IPV6 */
 
 /* Initialize the flag that gets set for DNS syntax check errors, so that the
 #endif  /* HAVE_IPV6 */
 
 /* Initialize the flag that gets set for DNS syntax check errors, so that the
@@ -2021,7 +2028,7 @@ for (int i = 1; i <= times;
 
   #else    /* not HAVE_IPV6 */
   if (f.running_in_test_harness)
 
   #else    /* not HAVE_IPV6 */
   if (f.running_in_test_harness)
-    hostdata = host_fake_gethostbyname(host->name, AF_INET, &error_num);
+    hostdata = host_fake_gethostbyname(host->name, af, &error_num);
   else
     {
     hostdata = gethostbyname(CS host->name);
   else
     {
     hostdata = gethostbyname(CS host->name);
@@ -2035,44 +2042,42 @@ for (int i = 1; i <= times;
 
   if (!hostdata)
     {
 
   if (!hostdata)
     {
-    uschar *error;
+    uschar * error;
     switch (error_num)
       {
     switch (error_num)
       {
-      case HOST_NOT_FOUND: error = US"HOST_NOT_FOUND"; break;
-      case TRY_AGAIN:      error = US"TRY_AGAIN"; break;
-      case NO_RECOVERY:    error = US"NO_RECOVERY"; break;
-      case NO_DATA:        error = US"NO_DATA"; break;
+      case HOST_NOT_FOUND: error = US"HOST_NOT_FOUND"; break;
+      case TRY_AGAIN:      error = US"TRY_AGAIN";   temp_error = TRUE; break;
+      case NO_RECOVERY:    error = US"NO_RECOVERY"; temp_error = TRUE; break;
+      case NO_DATA:        error = US"NO_DATA";                break;
     #if NO_DATA != NO_ADDRESS
     #if NO_DATA != NO_ADDRESS
-      case NO_ADDRESS:     error = US"NO_ADDRESS"; break;
+      case NO_ADDRESS:     error = US"NO_ADDRESS";     break;
     #endif
       default: error = US"?"; break;
       }
 
     #endif
       default: error = US"?"; break;
       }
 
-    DEBUG(D_host_lookup) debug_printf("%s returned %d (%s)\n",
+    DEBUG(D_host_lookup) debug_printf("%s(af=%s) returned %d (%s)\n",
       f.running_in_test_harness ? "host_fake_gethostbyname" :
       f.running_in_test_harness ? "host_fake_gethostbyname" :
-      #if HAVE_IPV6
-        #if HAVE_GETIPNODEBYNAME
-        af == AF_INET6 ? "getipnodebyname(af=inet6)" : "getipnodebyname(af=inet)",
-        #else
-        af == AF_INET6 ? "gethostbyname2(af=inet6)" : "gethostbyname2(af=inet)",
-        #endif
-      #else
-      "gethostbyname",
-      #endif
-      error_num, error);
+#if HAVE_IPV6
+if HAVE_GETIPNODEBYNAME
+        "getipnodebyname",
+else
+        "gethostbyname2",
+endif
+#else
+       "gethostbyname",
+#endif
+      af == AF_INET ? "inet" : "inet6", error_num, error);
 
 
-    if (error_num == TRY_AGAIN || error_num == NO_RECOVERY) temp_error = TRUE;
     continue;
     }
     continue;
     }
-  if ((hostdata->h_addr_list)[0] == NULL) continue;
+  if (!(hostdata->h_addr_list)[0]) continue;
 
   /* Replace the name with the fully qualified one if necessary, and fill in
   the fully_qualified_name pointer. */
 
 
   /* Replace the name with the fully qualified one if necessary, and fill in
   the fully_qualified_name pointer. */
 
-  if (hostdata->h_name[0] != 0 &&
-      Ustrcmp(host->name, hostdata->h_name) != 0)
+  if (hostdata->h_name[0] && Ustrcmp(host->name, hostdata->h_name) != 0)
     host->name = string_copy_dnsdomain(US hostdata->h_name);
     host->name = string_copy_dnsdomain(US hostdata->h_name);
-  if (fully_qualified_name != NULL) *fully_qualified_name = host->name;
+  if (fully_qualified_name) *fully_qualified_name = host->name;
 
   /* Get the list of addresses. IPv4 and IPv6 addresses can be distinguished
   by their different lengths. Scan the list, ignoring any that are to be
 
   /* Get the list of addresses. IPv4 and IPv6 addresses can be distinguished
   by their different lengths. Scan the list, ignoring any that are to be
@@ -2086,9 +2091,9 @@ for (int i = 1; i <= times;
       host_ntoa(ipv4_addr? AF_INET:AF_INET6, *addrlist, NULL, NULL);
 
     #ifndef STAND_ALONE
       host_ntoa(ipv4_addr? AF_INET:AF_INET6, *addrlist, NULL, NULL);
 
     #ifndef STAND_ALONE
-    if (ignore_target_hosts != NULL &&
-        verify_check_this_host(&ignore_target_hosts, NULL, host->name,
-          text_address, NULL) == OK)
+    if (  ignore_target_hosts
+       && verify_check_this_host(&ignore_target_hosts, NULL, host->name,
+           text_address, NULL) == OK)
       {
       DEBUG(D_host_lookup)
         debug_printf("ignored host %s [%s]\n", host->name, text_address);
       {
       DEBUG(D_host_lookup)
         debug_printf("ignored host %s [%s]\n", host->name, text_address);
@@ -2096,10 +2101,10 @@ for (int i = 1; i <= times;
       }
     #endif
 
       }
     #endif
 
-    /* If this is the first address, last == NULL and we put the data in the
+    /* If this is the first address, last is NULL and we put the data in the
     original block. */
 
     original block. */
 
-    if (last == NULL)
+    if (!last)
       {
       host->address = text_address;
       host->port = PORT_NONE;
       {
       host->address = text_address;
       host->port = PORT_NONE;
@@ -2116,6 +2121,9 @@ for (int i = 1; i <= times;
       {
       host_item *next = store_get(sizeof(host_item), FALSE);
       next->name = host->name;
       {
       host_item *next = store_get(sizeof(host_item), FALSE);
       next->name = host->name;
+#ifndef DISABLE_TLS
+      next->certname = host->certname;
+#endif
       next->mx = host->mx;
       next->address = text_address;
       next->port = PORT_NONE;
       next->mx = host->mx;
       next->address = text_address;
       next->port = PORT_NONE;
@@ -2134,12 +2142,12 @@ for (int i = 1; i <= times;
 NULL. If temp_error is set, at least one of the lookups gave a temporary error,
 so we pass that back. */
 
 NULL. If temp_error is set, at least one of the lookups gave a temporary error,
 so we pass that back. */
 
-if (host->address == NULL)
+if (!host->address)
   {
   uschar *msg =
     #ifndef STAND_ALONE
   {
   uschar *msg =
     #ifndef STAND_ALONE
-    (message_id[0] == 0 && smtp_in != NULL)?
-      string_sprintf("no IP address found for host %s (during %s)", host->name,
+    !message_id[0] && smtp_in
+      string_sprintf("no IP address found for host %s (during %s)", host->name,
           smtp_get_connection_info()) :
     #endif
     string_sprintf("no IP address found for host %s", host->name);
           smtp_get_connection_info()) :
     #endif
     string_sprintf("no IP address found for host %s", host->name);
@@ -2187,12 +2195,12 @@ dns_again_means_nonexist, return permanent rather than temporary failure. */
 
 RETURN_AGAIN:
   {
 
 RETURN_AGAIN:
   {
-  #ifndef STAND_ALONE
+#ifndef STAND_ALONE
   int rc;
   const uschar *save = deliver_domain;
   deliver_domain = host->name;  /* set $domain */
   int rc;
   const uschar *save = deliver_domain;
   deliver_domain = host->name;  /* set $domain */
-  rc = match_isinlist(host->name, CUSS &dns_again_means_nonexist, 0, NULL, NULL,
-    MCL_DOMAIN, TRUE, NULL);
+  rc = match_isinlist(host->name, CUSS &dns_again_means_nonexist, 0,
+    &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL);
   deliver_domain = save;
   if (rc == OK)
     {
   deliver_domain = save;
   if (rc == OK)
     {
@@ -2200,7 +2208,7 @@ RETURN_AGAIN:
       "returning HOST_FIND_FAILED\n", host->name);
     return HOST_FIND_FAILED;
     }
       "returning HOST_FIND_FAILED\n", host->name);
     return HOST_FIND_FAILED;
     }
-  #endif
+#endif
   return HOST_FIND_AGAIN;
   }
 }
   return HOST_FIND_AGAIN;
   }
 }
@@ -2258,6 +2266,14 @@ host_item *thishostlast = NULL;    /* Indicates not yet filled in anything */
 BOOL v6_find_again = FALSE;
 BOOL dnssec_fail = FALSE;
 int i;
 BOOL v6_find_again = FALSE;
 BOOL dnssec_fail = FALSE;
 int i;
+dns_answer * dnsa;
+
+#ifndef DISABLE_TLS
+/* Copy the host name at this point to the value which is used for
+TLS certificate name checking, before any CNAME-following modifies it.  */
+
+host->certname = host->name;
+#endif
 
 /* If allow_ip is set, a name which is an IP address returns that value
 as its address. This is used for MX records when allow_mx_to_ip is set, for
 
 /* If allow_ip is set, a name which is an IP address returns that value
 as its address. This is used for MX records when allow_mx_to_ip is set, for
@@ -2276,6 +2292,8 @@ if (allow_ip && string_is_ip_address(host->name, NULL) != 0)
   return HOST_FOUND;
   }
 
   return HOST_FOUND;
   }
 
+dnsa = store_get_dns_answer();
+
 /* On an IPv6 system, unless IPv6 is disabled, go round the loop up to twice,
 looking for AAAA records the first time. However, unless doing standalone
 testing, we force an IPv4 lookup if the domain matches dns_ipv4_lookup global.
 /* On an IPv6 system, unless IPv6 is disabled, go round the loop up to twice,
 looking for AAAA records the first time. However, unless doing standalone
 testing, we force an IPv4 lookup if the domain matches dns_ipv4_lookup global.
@@ -2285,9 +2303,9 @@ On an IPv4 system, go round the loop once only, looking only for A records. */
   #ifndef STAND_ALONE
     if (  disable_ipv6
        || !(whichrrs & HOST_FIND_BY_AAAA)
   #ifndef STAND_ALONE
     if (  disable_ipv6
        || !(whichrrs & HOST_FIND_BY_AAAA)
-       || (dns_ipv4_lookup
-          && match_isinlist(host->name, CUSS &dns_ipv4_lookup, 0, NULL, NULL,
-             MCL_DOMAIN, TRUE, NULL) == OK)
+       ||    dns_ipv4_lookup
+          && match_isinlist(host->name, CUSS &dns_ipv4_lookup, 0,
+             &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL) == OK
        )
       i = 0;    /* look up A records only */
     else
        )
       i = 0;    /* look up A records only */
     else
@@ -2307,7 +2325,6 @@ for (; i >= 0; i--)
   int type = types[i];
   int randoffset = i == (whichrrs & HOST_FIND_IPV4_FIRST ? 1 : 0)
     ? 500 : 0;  /* Ensures v6/4 sort order */
   int type = types[i];
   int randoffset = i == (whichrrs & HOST_FIND_IPV4_FIRST ? 1 : 0)
     ? 500 : 0;  /* Ensures v6/4 sort order */
-  dns_answer * dnsa = store_get_dns_answer();
   dns_scan dnss;
 
   int rc = dns_lookup_timerwrap(dnsa, host->name, type, fully_qualified_name);
   dns_scan dnss;
 
   int rc = dns_lookup_timerwrap(dnsa, host->name, type, fully_qualified_name);
@@ -2330,10 +2347,13 @@ for (; i >= 0; i--)
     {
     if (i == 0)  /* Just tried for an A record, i.e. end of loop */
       {
     {
     if (i == 0)  /* Just tried for an A record, i.e. end of loop */
       {
-      if (host->address != NULL) return HOST_FOUND;  /* AAAA was found */
-      if (rc == DNS_AGAIN || rc == DNS_FAIL || v6_find_again)
-        return HOST_FIND_AGAIN;
-      return HOST_FIND_FAILED;    /* DNS_NOMATCH or DNS_NODATA */
+      if (host->address != NULL)
+        i = HOST_FOUND;  /* AAAA was found */
+      else if (rc == DNS_AGAIN || rc == DNS_FAIL || v6_find_again)
+        i = HOST_FIND_AGAIN;
+      else
+       i = HOST_FIND_FAILED;    /* DNS_NOMATCH or DNS_NODATA */
+      goto out;
       }
 
     /* Tried for an AAAA record: remember if this was a temporary
       }
 
     /* Tried for an AAAA record: remember if this was a temporary
@@ -2478,11 +2498,15 @@ for (; i >= 0; i--)
 /* Control gets here only if the second lookup (the A record) succeeded.
 However, the address may not be filled in if it was ignored. */
 
 /* Control gets here only if the second lookup (the A record) succeeded.
 However, the address may not be filled in if it was ignored. */
 
-return host->address
+i = host->address
   ? HOST_FOUND
   : dnssec_fail
   ? HOST_FIND_SECURITY
   : HOST_IGNORED;
   ? HOST_FOUND
   : dnssec_fail
   ? HOST_FIND_SECURITY
   : HOST_IGNORED;
+
+out:
+  store_free_dns_answer(dnsa);
+  return i;
 }
 
 
 }
 
 
@@ -2545,12 +2569,12 @@ int yield;
 dns_answer * dnsa = store_get_dns_answer();
 dns_scan dnss;
 BOOL dnssec_require = dnssec_d
 dns_answer * dnsa = store_get_dns_answer();
 dns_scan dnss;
 BOOL dnssec_require = dnssec_d
-                   && match_isinlist(host->name, CUSS &dnssec_d->require,
-                                   0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK;
+  && match_isinlist(host->name, CUSS &dnssec_d->require,
+                 0, &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL) == OK;
 BOOL dnssec_request = dnssec_require
 BOOL dnssec_request = dnssec_require
-                   || (  dnssec_d
-                      && match_isinlist(host->name, CUSS &dnssec_d->request,
-                                   0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK);
+    || (  dnssec_d
+       && match_isinlist(host->name, CUSS &dnssec_d->request,
+                   0, &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL) == OK);
 dnssec_status_t dnssec;
 
 /* Set the default fully qualified name to the incoming name, initialize the
 dnssec_status_t dnssec;
 
 /* Set the default fully qualified name to the incoming name, initialize the
@@ -2615,13 +2639,13 @@ if (whichrrs & HOST_FIND_BY_SRV)
     }
   if (rc == DNS_FAIL || rc == DNS_AGAIN)
     {
     }
   if (rc == DNS_FAIL || rc == DNS_AGAIN)
     {
-    #ifndef STAND_ALONE
-    if (match_isinlist(host->name, CUSS &srv_fail_domains, 0, NULL, NULL,
-       MCL_DOMAIN, TRUE, NULL) != OK)
-    #endif
+#ifndef STAND_ALONE
+    if (match_isinlist(host->name, CUSS &srv_fail_domains, 0,
+       &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL) != OK)
+#endif
       { yield = HOST_FIND_AGAIN; goto out; }
     DEBUG(D_host_lookup) debug_printf("DNS_%s treated as DNS_NODATA "
       { yield = HOST_FIND_AGAIN; goto out; }
     DEBUG(D_host_lookup) debug_printf("DNS_%s treated as DNS_NODATA "
-      "(domain in srv_fail_domains)\n", (rc == DNS_FAIL)? "FAIL":"AGAIN");
+      "(domain in srv_fail_domains)\n", rc == DNS_FAIL ? "FAIL":"AGAIN");
     }
   }
 
     }
   }
 
@@ -2667,8 +2691,8 @@ if (rc != DNS_SUCCEED  &&  whichrrs & HOST_FIND_BY_MX)
       DEBUG(D_host_lookup)
        debug_printf("dnssec fail on MX for %.256s", host->name);
 #ifndef STAND_ALONE
       DEBUG(D_host_lookup)
        debug_printf("dnssec fail on MX for %.256s", host->name);
 #ifndef STAND_ALONE
-      if (match_isinlist(host->name, CUSS &mx_fail_domains, 0, NULL, NULL,
-         MCL_DOMAIN, TRUE, NULL) != OK)
+      if (match_isinlist(host->name, CUSS &mx_fail_domains, 0,
+         &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL) != OK)
        { yield = HOST_FIND_SECURITY; goto out; }
 #endif
       rc = DNS_FAIL;
        { yield = HOST_FIND_SECURITY; goto out; }
 #endif
       rc = DNS_FAIL;
@@ -2677,8 +2701,8 @@ if (rc != DNS_SUCCEED  &&  whichrrs & HOST_FIND_BY_MX)
     case DNS_FAIL:
     case DNS_AGAIN:
 #ifndef STAND_ALONE
     case DNS_FAIL:
     case DNS_AGAIN:
 #ifndef STAND_ALONE
-      if (match_isinlist(host->name, CUSS &mx_fail_domains, 0, NULL, NULL,
-         MCL_DOMAIN, TRUE, NULL) != OK)
+      if (match_isinlist(host->name, CUSS &mx_fail_domains, 0,
+         &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL) != OK)
 #endif
        { yield = HOST_FIND_AGAIN; goto out; }
       DEBUG(D_host_lookup) debug_printf("DNS_%s treated as DNS_NODATA "
 #endif
        { yield = HOST_FIND_AGAIN; goto out; }
       DEBUG(D_host_lookup) debug_printf("DNS_%s treated as DNS_NODATA "
@@ -3151,6 +3175,7 @@ DEBUG(D_host_lookup)
 out:
 
 dns_init(FALSE, FALSE, FALSE); /* clear the dnssec bit for getaddrbyname */
 out:
 
 dns_init(FALSE, FALSE, FALSE); /* clear the dnssec bit for getaddrbyname */
+store_free_dns_answer(dnsa);
 return yield;
 }
 
 return yield;
 }
 
@@ -3179,7 +3204,7 @@ BOOL sec;
 rc = dns_lookup_timerwrap(dnsa, buffer, T_TLSA, &fullname);
 sec = dns_is_secure(dnsa);
 DEBUG(D_transport)
 rc = dns_lookup_timerwrap(dnsa, buffer, T_TLSA, &fullname);
 sec = dns_is_secure(dnsa);
 DEBUG(D_transport)
-  debug_printf("TLSA lookup ret %d %sDNSSEC\n", rc, sec ? "" : "not ");
+  debug_printf("TLSA lookup ret %s %sDNSSEC\n", dns_rc_names[rc], sec ? "" : "not ");
 
 switch (rc)
   {
 
 switch (rc)
   {
@@ -3249,6 +3274,7 @@ uschar buffer[256];
 
 disable_ipv6 = FALSE;
 primary_hostname = US"";
 
 disable_ipv6 = FALSE;
 primary_hostname = US"";
+store_init();
 store_pool = POOL_MAIN;
 debug_selector = D_host_lookup|D_interface;
 debug_file = stdout;
 store_pool = POOL_MAIN;
 debug_selector = D_host_lookup|D_interface;
 debug_file = stdout;