Hintsdb: fix build config phase for sqlite
[exim.git] / src / src / dns.c
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 /* Copyright (c) The Exim Maintainers 2020 - 2024 */
6 /* Copyright (c) University of Cambridge 1995 - 2018 */
7 /* See the file NOTICE for conditions of use and distribution. */
8 /* SPDX-License-Identifier: GPL-2.0-or-later */
9
10 /* Functions for interfacing with the DNS. */
11
12 #include "exim.h"
13
14
15 /*************************************************
16 *               Fake DNS resolver                *
17 *************************************************/
18
19 /* This function is called instead of res_search() when Exim is running in its
20 test harness. It recognizes some special domain names, and uses them to force
21 failure and retry responses (optionally with a delay). Otherwise, it calls an
22 external utility that mocks-up a nameserver, if it can find the utility.
23 If not, it passes its arguments on to res_search(). The fake nameserver may
24 also return a code specifying that the name should be passed on.
25
26 Background: the original test suite required a real nameserver to carry the
27 test zones, whereas the new test suite has the fake server for portability. This
28 code supports both.
29
30 Arguments:
31   domain      the domain name
32   type        the DNS record type
33   answerptr   where to put the answer
34   size        size of the answer area
35
36 Returns:      length of returned data, or -1 on error (h_errno set)
37 */
38
39 static int
40 fakens_search(const uschar *domain, int type, uschar *answerptr, int size)
41 {
42 int len = Ustrlen(domain);
43 int asize = size;                  /* Locally modified */
44 uschar * name;
45 uschar utilname[256];
46 uschar *aptr = answerptr;          /* Locally modified */
47 struct stat statbuf;
48
49 /* Remove terminating dot. */
50
51 if (domain[len - 1] == '.') len--;
52 name = string_copyn(domain, len);
53
54 /* Look for the fakens utility, and if it exists, call it. */
55
56 (void)string_format(utilname, sizeof(utilname), "%s/bin/fakens",
57   config_main_directory);
58
59 if (stat(CS utilname, &statbuf) >= 0)
60   {
61   pid_t pid;
62   int infd, outfd, rc;
63   uschar *argv[5];
64
65   DEBUG(D_dns) debug_printf_indent("DNS lookup of %s (%s) using fakens\n",
66                 name, dns_text_type(type));
67
68   argv[0] = utilname;
69   argv[1] = config_main_directory;
70   argv[2] = name;
71   argv[3] = dns_text_type(type);
72   argv[4] = NULL;
73
74   pid = child_open(argv, NULL, 0000, &infd, &outfd, FALSE, US"fakens-search");
75   if (pid < 0)
76     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to run fakens: %s",
77       strerror(errno));
78
79   len = 0;
80   rc = -1;
81   while (asize > 0 && (rc = read(outfd, aptr, asize)) > 0)
82     {
83     len += rc;
84     aptr += rc;       /* Don't modify the actual arguments, because they */
85     asize -= rc;      /* may need to be passed on to res_search(). */
86     }
87
88   /* If we ran out of output buffer before exhausting the return,
89   carry on reading and counting it. */
90
91   if (asize == 0)
92     while ((rc = read(outfd, name, sizeof(name))) > 0)
93       len += rc;
94
95   if (rc < 0)
96     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "read from fakens failed: %s",
97       strerror(errno));
98
99   switch(child_close(pid, 0))
100     {
101     case 0: return len;
102     case 1: h_errno = HOST_NOT_FOUND; return -1;
103     case 2: h_errno = TRY_AGAIN; return -1;
104     default:
105     case 3: h_errno = NO_RECOVERY; return -1;
106     case 4: h_errno = NO_DATA; return -1;
107     case 5: /* Pass on to res_search() */
108     DEBUG(D_dns) debug_printf_indent("fakens returned PASS_ON\n");
109     }
110   }
111 else
112   {
113   DEBUG(D_dns) debug_printf_indent("fakens (%s) not found\n", utilname);
114   }
115
116 /* fakens utility not found, or it returned "pass on" */
117
118 DEBUG(D_dns) debug_printf_indent("passing %s on to res_search()\n", domain);
119
120 return res_search(CS domain, C_IN, type, answerptr, size);
121 }
122
123
124
125 /*************************************************
126 *        Initialize and configure resolver       *
127 *************************************************/
128
129 /* Initialize the resolver and the storage for holding DNS answers if this is
130 the first time we have been here, and set the resolver options.
131
132 Arguments:
133   qualify_single    TRUE to set the RES_DEFNAMES option
134   search_parents    TRUE to set the RES_DNSRCH option
135   use_dnssec        TRUE to set the RES_USE_DNSSEC option
136
137 Returns:            nothing
138 */
139
140 void
141 dns_init(BOOL qualify_single, BOOL search_parents, BOOL use_dnssec)
142 {
143 res_state resp = os_get_dns_resolver_res();
144
145 if ((resp->options & RES_INIT) == 0)
146   {
147   DEBUG(D_resolver) resp->options |= RES_DEBUG;     /* For Cygwin */
148   os_put_dns_resolver_res(resp);
149   res_init();
150   DEBUG(D_resolver) resp->options |= RES_DEBUG;
151   os_put_dns_resolver_res(resp);
152   }
153
154 resp->options &= ~(RES_DNSRCH | RES_DEFNAMES);
155 resp->options |= (qualify_single? RES_DEFNAMES : 0) |
156                 (search_parents? RES_DNSRCH : 0);
157 if (dns_retrans > 0) resp->retrans = dns_retrans;
158 if (dns_retry > 0) resp->retry = dns_retry;
159
160 #ifdef RES_USE_EDNS0
161 if (dns_use_edns0 >= 0)
162   {
163   if (dns_use_edns0)
164     resp->options |= RES_USE_EDNS0;
165   else
166     resp->options &= ~RES_USE_EDNS0;
167   DEBUG(D_resolver)
168     debug_printf_indent("Coerced resolver EDNS0 support %s.\n",
169         dns_use_edns0 ? "on" : "off");
170   }
171 #else
172 if (dns_use_edns0 >= 0)
173   DEBUG(D_resolver)
174     debug_printf_indent("Unable to %sset EDNS0 without resolver support.\n",
175         dns_use_edns0 ? "" : "un");
176 #endif
177
178 #ifndef DISABLE_DNSSEC
179 # ifdef RES_USE_DNSSEC
180 #  ifndef RES_USE_EDNS0
181 #   error Have RES_USE_DNSSEC but not RES_USE_EDNS0?  Something hinky ...
182 #  endif
183 if (use_dnssec)
184   resp->options |= RES_USE_DNSSEC;
185 if (dns_dnssec_ok >= 0)
186   {
187   if (dns_use_edns0 == 0 && dns_dnssec_ok != 0)
188     {
189     DEBUG(D_resolver)
190       debug_printf_indent("CONFLICT: dns_use_edns0 forced false, dns_dnssec_ok forced true, ignoring latter!\n");
191     }
192   else
193     {
194     if (dns_dnssec_ok)
195       resp->options |= RES_USE_DNSSEC;
196     else
197       resp->options &= ~RES_USE_DNSSEC;
198     DEBUG(D_resolver) debug_printf_indent("Coerced resolver DNSSEC support %s.\n",
199         dns_dnssec_ok ? "on" : "off");
200     }
201   }
202 # else
203 if (dns_dnssec_ok >= 0)
204   DEBUG(D_resolver)
205     debug_printf_indent("Unable to %sset DNSSEC without resolver support.\n",
206         dns_dnssec_ok ? "" : "un");
207 if (use_dnssec)
208   DEBUG(D_resolver)
209     debug_printf_indent("Unable to set DNSSEC without resolver support.\n");
210 # endif
211 #endif /* DISABLE_DNSSEC */
212
213 os_put_dns_resolver_res(resp);
214 }
215
216
217
218 /*************************************************
219 *       Build key name for PTR records           *
220 *************************************************/
221
222 /* This function inverts an IP address and adds the relevant domain, to produce
223 a name that can be used to look up PTR records.
224
225 Arguments:
226   string     the IP address as a string
227
228 Returns:     an allocated string
229 */
230
231 uschar *
232 dns_build_reverse(const uschar * string)
233 {
234 const uschar * p = string + Ustrlen(string);
235 gstring * g = NULL;
236
237 /* Handle IPv4 address */
238
239 #if HAVE_IPV6
240 if (Ustrchr(string, ':') == NULL)
241 #endif
242   {
243   for (int i = 0; i < 4; i++)
244     {
245     const uschar * ppp = p;
246     while (ppp > string && ppp[-1] != '.') ppp--;
247     g = string_catn(g, ppp, p - ppp);
248     g = string_catn(g, US".", 1);
249     p = ppp - 1;
250     }
251   g = string_catn(g, US"in-addr.arpa", 12);
252   }
253
254 /* Handle IPv6 address; convert to binary so as to fill out any
255 abbreviation in the textual form. */
256
257 #if HAVE_IPV6
258 else
259   {
260   int v6[4];
261
262   g = string_get_tainted(32, string);
263   (void)host_aton(string, v6);
264
265   /* The original specification for IPv6 reverse lookup was to invert each
266   nibble, and look in the ip6.int domain. The domain was subsequently
267   changed to ip6.arpa. */
268
269   for (int i = 3; i >= 0; i--)
270     for (int j = 0; j < 32; j += 4)
271       g = string_fmt_append(g, "%x.", (v6[i] >> j) & 15);
272   g = string_catn(g, US"ip6.arpa.", 9);
273
274   /* Another way of doing IPv6 reverse lookups was proposed in conjunction
275   with A6 records. However, it fell out of favour when they did. The
276   alternative was to construct a binary key, and look in ip6.arpa. I tried
277   to make this code do that, but I could not make it work on Solaris 8. The
278   resolver seems to lose the initial backslash somehow. However, now that
279   this style of reverse lookup has been dropped, it doesn't matter. These
280   lines are left here purely for historical interest. */
281
282   /**************************************************
283   Ustrcpy(pp, "\\[x");
284   pp += 3;
285
286   for (int i = 0; i < 4; i++)
287     {
288     sprintf(pp, "%08X", v6[i]);
289     pp += 8;
290     }
291   Ustrcpy(pp, US"].ip6.arpa.");
292   **************************************************/
293
294   }
295 #endif
296 return string_from_gstring(g);
297 }
298
299
300
301
302 /* Check a pointer for being past the end of a dns answer.
303 Exactly one past the end is defined as ok.
304 Return TRUE iff bad.
305 */
306 static BOOL
307 dnsa_bad_ptr(const dns_answer * dnsa, const uschar * ptr)
308 {
309 return ptr > dnsa->answer + dnsa->answerlen;
310 }
311
312 /* Increment the aptr in dnss, checking against dnsa length.
313 Return: TRUE for a bad result
314 */
315 static BOOL
316 dnss_inc_aptr(const dns_answer * dnsa, dns_scan * dnss, unsigned delta)
317 {
318 return dnsa_bad_ptr(dnsa, dnss->aptr += delta);
319 }
320
321 /*************************************************
322 *       Get next DNS record from answer block    *
323 *************************************************/
324
325 /* Call this with reset == RESET_ANSWERS to scan the answer block, reset ==
326 RESET_AUTHORITY to scan the authority records, reset == RESET_ADDITIONAL to
327 scan the additional records, and reset == RESET_NEXT to get the next record.
328 The result is in static storage which must be copied if it is to be preserved.
329
330 Arguments:
331   dnsa      pointer to dns answer block
332   dnss      pointer to dns scan block
333   reset     option specifying what portion to scan, as described above
334
335 Returns:    next dns record, or NULL when no more
336 */
337
338 dns_record *
339 dns_next_rr(const dns_answer *dnsa, dns_scan *dnss, int reset)
340 {
341 const HEADER * h = (const HEADER *)dnsa->answer;
342 int namelen;
343
344 char * trace = NULL;
345 #ifdef rr_trace
346 # define TRACE DEBUG(D_dns)
347 #else
348 # define TRACE if (FALSE)
349 #endif
350
351 /* Reset the saved data when requested to, and skip to the first required RR */
352
353 if (reset != RESET_NEXT)
354   {
355   dnss->rrcount = ntohs(h->qdcount);
356   TRACE debug_printf_indent("%s: reset (Q rrcount %d)\n", __FUNCTION__, dnss->rrcount);
357   dnss->aptr = dnsa->answer + sizeof(HEADER);
358
359   /* Skip over questions; failure to expand the name just gives up */
360
361   while (dnss->rrcount-- > 0)
362     {
363     TRACE trace = "Q-namelen";
364     namelen = dn_expand(dnsa->answer, dnsa->answer + dnsa->answerlen,
365       dnss->aptr, (DN_EXPAND_ARG4_TYPE) &dnss->srr.name, DNS_MAXNAME);
366     if (namelen < 0) goto null_return;
367     /* skip name & type & class */
368     TRACE trace = "Q-skip";
369     if (dnss_inc_aptr(dnsa, dnss, namelen+4)) goto null_return;
370     }
371
372   /* Get the number of answer records. */
373
374   dnss->rrcount = ntohs(h->ancount);
375   TRACE debug_printf_indent("%s: reset (A rrcount %d)\n", __FUNCTION__, dnss->rrcount);
376
377   /* Skip over answers if we want to look at the authority section. Also skip
378   the NS records (i.e. authority section) if wanting to look at the additional
379   records. */
380
381   if (reset == RESET_ADDITIONAL)
382     {
383     TRACE debug_printf_indent("%s: additional\n", __FUNCTION__);
384     dnss->rrcount += ntohs(h->nscount);
385     TRACE debug_printf_indent("%s: reset (NS rrcount %d)\n", __FUNCTION__, dnss->rrcount);
386     }
387
388   if (reset == RESET_AUTHORITY || reset == RESET_ADDITIONAL)
389     {
390     TRACE if (reset == RESET_AUTHORITY)
391       debug_printf_indent("%s: authority\n", __FUNCTION__);
392     while (dnss->rrcount-- > 0)
393       {
394       TRACE trace = "A-namelen";
395       namelen = dn_expand(dnsa->answer, dnsa->answer + dnsa->answerlen,
396         dnss->aptr, (DN_EXPAND_ARG4_TYPE) &dnss->srr.name, DNS_MAXNAME);
397       if (namelen < 0) goto null_return;
398
399       /* skip name, type, class & TTL */
400       TRACE trace = "A-hdr";
401       if (dnss_inc_aptr(dnsa, dnss, namelen+8)) goto null_return;
402
403       if (dnsa_bad_ptr(dnsa, dnss->aptr + sizeof(uint16_t))) goto null_return;
404       GETSHORT(dnss->srr.size, dnss->aptr); /* size of data portion */
405
406       /* skip over it, checking for a bogus size */
407       TRACE trace = "A-skip";
408       if (dnss_inc_aptr(dnsa, dnss, dnss->srr.size)) goto null_return;
409       }
410     dnss->rrcount = reset == RESET_AUTHORITY
411       ? ntohs(h->nscount) : ntohs(h->arcount);
412     TRACE debug_printf_indent("%s: reset (%s rrcount %d)\n", __FUNCTION__,
413       reset == RESET_AUTHORITY ? "NS" : "AR", dnss->rrcount);
414     }
415   TRACE debug_printf_indent("%s: %d RRs to read\n", __FUNCTION__, dnss->rrcount);
416   }
417 else
418   TRACE debug_printf_indent("%s: next (%d left)\n", __FUNCTION__, dnss->rrcount);
419
420 /* The variable dnss->aptr is now pointing at the next RR, and dnss->rrcount
421 contains the number of RR records left. */
422
423 if (dnss->rrcount-- <= 0) return NULL;
424
425 /* If expanding the RR domain name fails, behave as if no more records
426 (something safe). */
427
428 TRACE trace = "R-namelen";
429 namelen = dn_expand(dnsa->answer, dnsa->answer + dnsa->answerlen, dnss->aptr,
430   (DN_EXPAND_ARG4_TYPE) &dnss->srr.name, DNS_MAXNAME);
431 if (namelen < 0) goto null_return;
432
433 /* Move the pointer past the name and fill in the rest of the data structure
434 from the following bytes.  We seem to be assuming here that the RR blob passed
435 to us by the resolver library is the same as that defined for an RR by RFC 1035
436 section 3.2.1 */
437
438 TRACE trace = "R-name";
439 if (dnss_inc_aptr(dnsa, dnss, namelen)) goto null_return;
440
441 /* Check space for type, class, TTL & data-size-word */
442 if (dnsa_bad_ptr(dnsa, dnss->aptr + 3 * sizeof(uint16_t) + sizeof(uint32_t)))
443   goto null_return;
444
445 GETSHORT(dnss->srr.type, dnss->aptr);                   /* Record type */
446
447 TRACE trace = "R-class";
448 (void) dnss_inc_aptr(dnsa, dnss, sizeof(uint16_t));     /* skip class */
449
450 GETLONG(dnss->srr.ttl, dnss->aptr);                     /* TTL */
451 GETSHORT(dnss->srr.size, dnss->aptr);                   /* Size of data portion */
452 dnss->srr.data = dnss->aptr;                            /* The record's data follows */
453
454 /* skip over it, checking for a bogus size */
455 if (dnss_inc_aptr(dnsa, dnss, dnss->srr.size))
456   goto null_return;
457
458 /* Return a pointer to the dns_record structure within the dns_answer. This is
459 for convenience so that the scans can use nice-looking for loops. */
460
461 TRACE debug_printf_indent("%s: return %s\n", __FUNCTION__, dns_text_type(dnss->srr.type));
462 return &dnss->srr;
463
464 null_return:
465   TRACE debug_printf_indent("%s: terminate (%d RRs left). Last op: %s; errno %d %s\n",
466     __FUNCTION__, dnss->rrcount, trace, errno, strerror(errno));
467   dnss->rrcount = 0;
468   return NULL;
469 }
470
471
472 /* Extract the AUTHORITY information from the answer. If the answer isn't
473 authoritative (AA not set), we do not extract anything.
474
475 The AUTHORITY section contains NS records if the name in question was found,
476 it contains a SOA record otherwise. (This is just from experience and some
477 tests, is there some spec?)
478
479 Scan the whole AUTHORITY section, since it may contain other records
480 (e.g. NSEC3) too.
481
482 Return: name for the authority, in an allocated string, or NULL if none found */
483
484 static const uschar *
485 dns_extract_auth_name(const dns_answer * dnsa)  /* FIXME: const dns_answer */
486 {
487 dns_scan dnss;
488 const HEADER * h = (const HEADER *) dnsa->answer;
489
490 if (h->nscount && h->aa)
491   for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_AUTHORITY);
492        rr; rr = dns_next_rr(dnsa, &dnss, RESET_NEXT))
493     if (rr->type == (h->ancount ? T_NS : T_SOA))
494       return string_copy(rr->name);
495 return NULL;
496 }
497
498
499
500
501 /*************************************************
502 *    Return whether AD bit set in DNS result     *
503 *************************************************/
504
505 /* We do not perform DNSSEC work ourselves; if the administrator has installed
506 a verifying resolver which sets AD as appropriate, though, we'll use that.
507 (AD = Authentic Data, AA = Authoritative Answer)
508
509 Argument:   pointer to dns answer block
510 Returns:    bool indicating presence of AD bit
511 */
512
513 BOOL
514 dns_is_secure(const dns_answer * dnsa)
515 {
516 #ifdef DISABLE_DNSSEC
517 DEBUG(D_dns)
518   debug_printf_indent("DNSSEC support disabled at build-time; dns_is_secure() false\n");
519 return FALSE;
520 #else
521 const HEADER * h = (const HEADER *) dnsa->answer;
522 const uschar * auth_name;
523 const uschar * trusted;
524
525 if (dnsa->answerlen < 0) return FALSE;
526 /* Beware that newer versions of glibc on Linux will filter out the ad bit
527 unless their shiny new RES_TRUSTAD bit is set for the resolver.  */
528 if (h->ad) return TRUE;
529
530 /* If the resolver we ask is authoritative for the domain in question, it may
531 not set the AD but the AA bit. If we explicitly trust the resolver for that
532 domain (via a domainlist in dns_trust_aa), we return TRUE to indicate a secure
533 answer.  */
534
535 if (  !h->aa
536    || !dns_trust_aa
537    || !(trusted = expand_string(dns_trust_aa))
538    || !*trusted
539    || !(auth_name = dns_extract_auth_name(dnsa))
540    || OK != match_isinlist(auth_name, &trusted, 0, &domainlist_anchor, NULL,
541                             MCL_DOMAIN, TRUE, NULL)
542    )
543   return FALSE;
544
545 DEBUG(D_dns) debug_printf_indent("DNS faked the AD bit "
546   "(got AA and matched with dns_trust_aa (%s in %s))\n",
547   auth_name, dns_trust_aa);
548
549 return TRUE;
550 #endif
551 }
552
553 static void
554 dns_set_insecure(dns_answer * dnsa)
555 {
556 #ifndef DISABLE_DNSSEC
557 HEADER * h = (HEADER *)dnsa->answer;
558 h->aa = h->ad = 0;
559 #endif
560 }
561
562 /************************************************
563  *      Check whether the AA bit is set         *
564  *      We need this to warn if we requested AD *
565  *      from an authoritative server            *
566  ************************************************/
567
568 BOOL
569 dns_is_aa(const dns_answer * dnsa)
570 {
571 #ifdef DISABLE_DNSSEC
572 return FALSE;
573 #else
574 return dnsa->answerlen >= 0 && ((const HEADER *)dnsa->answer)->aa;
575 #endif
576 }
577
578
579
580 /*************************************************
581 *            Turn DNS type into text             *
582 *************************************************/
583
584 /* Turn the coded record type into a string for printing. All those that Exim
585 uses should be included here.
586
587 Argument:   record type
588 Returns:    pointer to string
589 */
590
591 uschar *
592 dns_text_type(int t)
593 {
594 switch(t)
595   {
596   case T_A:     return US"A";
597   case T_MX:    return US"MX";
598   case T_AAAA:  return US"AAAA";
599   case T_A6:    return US"A6";
600   case T_TXT:   return US"TXT";
601   case T_SPF:   return US"SPF";
602   case T_PTR:   return US"PTR";
603   case T_SOA:   return US"SOA";
604   case T_SRV:   return US"SRV";
605   case T_NS:    return US"NS";
606   case T_CNAME: return US"CNAME";
607   case T_TLSA:  return US"TLSA";
608   default:      return US"?";
609   }
610 }
611
612
613
614 /*************************************************
615 *        Cache a failed DNS lookup result        *
616 *************************************************/
617
618 static void
619 dns_fail_tag(uschar * buf, const uschar * name, int dns_type)
620 {
621 res_state resp = os_get_dns_resolver_res();
622
623 /*XX buf needs to be 255 +1 + (max(typetext) == 5) +1 + max(chars_for_long-max) +1
624 We truncate the name here for safety... could use a dynamic string. */
625
626 sprintf(CS buf, "%.255s-%s-%lx", name, dns_text_type(dns_type),
627   (unsigned long) resp->options);
628 }
629
630
631 /* We cache failed lookup results so as not to experience timeouts many
632 times for the same domain. We need to retain the resolver options because they
633 may change. For successful lookups, we rely on resolver and/or name server
634 caching.
635
636 Arguments:
637   name       the domain name
638   type       the lookup type
639   expiry     time TTL expires, or zero for unlimited
640   rc         the return code
641
642 Returns:     the return code
643 */
644
645 /* we need:  255 +1 + (max(typetext) == 5) +1 + max(chars_for_long-max) +1 */
646 #define DNS_FAILTAG_MAX 290
647 #define DNS_FAILNODE_SIZE \
648   (sizeof(expiring_data) + sizeof(tree_node) + DNS_FAILTAG_MAX)
649
650 static int
651 dns_fail_return(const uschar * name, int type, time_t expiry, int rc)
652 {
653 uschar node_name[DNS_FAILTAG_MAX];
654 tree_node * previous, * new;
655 expiring_data * e;
656
657 dns_fail_tag(node_name, name, type);
658 if ((previous = tree_search(tree_dns_fails, node_name)))
659   e = previous->data.ptr;
660 else
661   {
662   e = store_get_perm(DNS_FAILNODE_SIZE, name);
663   new = (void *)(e+1);
664   dns_fail_tag(new->name, name, type);
665   new->data.ptr = e;
666   (void)tree_insertnode(&tree_dns_fails, new);
667   }
668
669 DEBUG(D_dns) debug_printf_indent(" %s neg-cache entry for %s, ttl %d\n",
670   previous ? "update" : "writing",
671   node_name, expiry ? (int)(expiry - time(NULL)) : -1);
672 e->expiry = expiry;
673 e->data.val = rc;
674 return rc;
675 }
676
677
678 /* Return the cached result of a known-bad lookup, or -1.
679 */
680 static int
681 dns_fail_cache_hit(const uschar * name, int type)
682 {
683 uschar node_name[DNS_FAILTAG_MAX];
684 tree_node * previous;
685 expiring_data * e;
686 int val, rc;
687
688 dns_fail_tag(node_name, name, type);
689 if (!(previous = tree_search(tree_dns_fails, node_name)))
690   return -1;
691
692 e = previous->data.ptr;
693 val = e->data.val;
694 rc = e->expiry && e->expiry <= time(NULL) ? -1 : val;
695
696 DEBUG(D_dns) debug_printf_indent("DNS lookup of %.255s (%s): %scached value %s%s\n",
697   name, dns_text_type(type),
698   rc == -1 ? "" : "using ",
699   dns_rc_names[val],
700   rc == -1 ? " past valid time" : "");
701
702 return rc;
703 }
704
705
706
707 /* This is really gross. The successful return value from res_search() is
708 the packet length, which is stored in dnsa->answerlen. If we get a
709 negative DNS reply then res_search() returns -1, which causes the bounds
710 checks for name decompression to fail when it is treated as a packet
711 length, which in turn causes the authority search to fail. The correct
712 packet length has been lost inside libresolv, so we have to guess a
713 replacement value. (The only way to fix this properly would be to
714 re-implement res_search() and res_query() so that they don't muddle their
715 success and packet length return values.) For added safety we only reset
716 the packet length if the packet header looks plausible.
717
718 Return TRUE iff it seemed ok */
719
720 static BOOL
721 fake_dnsa_len_for_fail(dns_answer * dnsa, int type)
722 {
723 const HEADER * h = (const HEADER *)dnsa->answer;
724
725 if (  h->qr == 1                                /* a response */
726    && h->opcode == QUERY
727    && h->tc == 0                                /* nmessage not truncated */
728    && (h->rcode == NOERROR || h->rcode == NXDOMAIN)
729    && (  ntohs(h->qdcount) == 1                 /* one question record */
730       || f.running_in_test_harness)
731    && ntohs(h->ancount) == 0                    /* no answer records */
732    && ntohs(h->nscount) >= 1)                   /* authority records */
733   {
734   DEBUG(D_dns) debug_printf_indent("faking res_search(%s) response length as %d\n",
735     dns_text_type(type), (int)sizeof(dnsa->answer));
736   dnsa->answerlen = sizeof(dnsa->answer);
737   return TRUE;
738   }
739 DEBUG(D_dns) debug_printf_indent("DNS: couldn't fake dnsa len\n");
740 /* Maybe we should just do a second lookup for an SOA? */
741 return FALSE;
742 }
743
744
745 /* Return the TTL suitable for an NXDOMAIN result, which is given
746 in the SOA.  We hope that one was returned in the lookup, and do not
747 bother doing a separate lookup; if not found return a forever TTL.
748 */
749
750 time_t
751 dns_expire_from_soa(dns_answer * dnsa, int type)
752 {
753 dns_scan dnss;
754
755 if (fake_dnsa_len_for_fail(dnsa, type))
756   for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_AUTHORITY);
757        rr; rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)
758       ) if (rr->type == T_SOA)
759     {
760     const uschar * p = rr->data;
761     uschar discard_buf[256];
762     int len;
763     unsigned long ttl;
764
765     /* Skip the mname & rname strings */
766
767     if ((len = dn_expand(dnsa->answer, dnsa->answer + dnsa->answerlen,
768         p, (DN_EXPAND_ARG4_TYPE)discard_buf, sizeof(discard_buf))) < 0)
769       break;
770     p += len;
771     if ((len = dn_expand(dnsa->answer, dnsa->answer + dnsa->answerlen,
772         p, (DN_EXPAND_ARG4_TYPE)discard_buf, sizeof(discard_buf))) < 0)
773       break;
774     p += len;
775
776     /* Skip the SOA serial, refresh, retry & expire.  Grab the TTL */
777
778     if (dnsa_bad_ptr(dnsa, p + 5 * INT32SZ))
779       break;
780     p += 4 * INT32SZ;
781     GETLONG(ttl, p);
782
783     return time(NULL) + ttl;
784     }
785
786 DEBUG(D_dns) debug_printf_indent("DNS: no SOA record found for neg-TTL\n");
787 return 0;
788 }
789
790
791 /*************************************************
792 *              Do basic DNS lookup               *
793 *************************************************/
794
795 /* Call the resolver to look up the given domain name, using the given type,
796 and check the result. The error code TRY_AGAIN is documented as meaning "non-
797 Authoritative Host not found, or SERVERFAIL". Sometimes there are badly set
798 up nameservers that produce this error continually, so there is the option of
799 providing a list of domains for which this is treated as a non-existent
800 host.
801
802 The dns_answer structure is pretty big; enough to hold a max-sized DNS message
803 - so best allocated from fast-release memory.  As of writing, all our callers
804 use a stack-auto variable.
805
806 Arguments:
807   dnsa      pointer to dns_answer structure
808   name      name to look up
809   type      type of DNS record required (T_A, T_MX, etc)
810
811 Returns:    DNS_SUCCEED   successful lookup
812             DNS_NOMATCH   name not found (NXDOMAIN)
813                           or name contains illegal characters (if checking)
814                           or name is an IP address (for IP address lookup)
815             DNS_NODATA    domain exists, but no data for this type (NODATA)
816             DNS_AGAIN     soft failure, try again later
817             DNS_FAIL      DNS failure
818 */
819
820 int
821 dns_basic_lookup(dns_answer * dnsa, const uschar * name, int type)
822 {
823 int rc;
824 #ifndef STAND_ALONE
825 const uschar * save_domain;
826 static BOOL try_again_recursion = FALSE;
827 #endif
828
829 /* DNS lookup failures of any kind are cached in a tree. This is mainly so that
830 a timeout on one domain doesn't happen time and time again for messages that
831 have many addresses in the same domain. We rely on the resolver and name server
832 caching for successful lookups.
833 */
834
835 if ((rc = dns_fail_cache_hit(name, type)) > 0)
836   {
837   dnsa->answerlen = -1;
838   return rc;
839   }
840
841 #ifdef SUPPORT_I18N
842 /* Convert all names to a-label form before doing lookup */
843   {
844   uschar * alabel;
845   uschar * errstr = NULL;
846   DEBUG(D_dns) if (string_is_utf8(name))
847     debug_printf_indent("convert utf8 '%s' to alabel for for lookup\n", name);
848   if ((alabel = string_domain_utf8_to_alabel(name, &errstr)), errstr)
849     {
850     DEBUG(D_dns)
851       debug_printf_indent("DNS name '%s' utf8 conversion to alabel failed: %s\n", name,
852         errstr);
853     f.host_find_failed_syntax = TRUE;
854     return DNS_NOMATCH;
855     }
856   name = alabel;
857   }
858 #endif
859
860 /* If configured, check the hygiene of the name passed to lookup. Otherwise,
861 although DNS lookups may give REFUSED at the lower level, some resolvers
862 turn this into TRY_AGAIN, which is silly. Give a NOMATCH return, since such
863 domains cannot be in the DNS. The check is now done by a regular expression;
864 give it space for substring storage to save it having to get its own if the
865 regex has substrings that are used - the default uses a conditional.
866
867 This test is omitted for PTR records. These occur only in calls from the dnsdb
868 lookup, which constructs the names itself, so they should be OK. Besides,
869 bitstring labels don't conform to normal name syntax. (But they aren't used any
870 more.) */
871
872 #ifndef STAND_ALONE   /* Omit this for stand-alone tests */
873
874 if (check_dns_names_pattern[0] != 0 && type != T_PTR && type != T_TXT)
875   {
876   dns_pattern_init();
877   if (!regex_match(regex_check_dns_names, name, -1, NULL))
878     {
879     DEBUG(D_dns)
880       debug_printf_indent("DNS name syntax check failed: %s (%s)\n", name,
881         dns_text_type(type));
882     f.host_find_failed_syntax = TRUE;
883     return DNS_NOMATCH;
884     }
885   }
886
887 #endif /* STAND_ALONE */
888
889 /* Call the resolver; for an overlong response, res_search() will return the
890 number of bytes the message would need, so we need to check for this case. The
891 effect is to truncate overlong data.
892
893 On some systems, res_search() will recognize "A-for-A" queries and return
894 the IP address instead of returning -1 with h_error=HOST_NOT_FOUND. Some
895 nameservers are also believed to do this. It is, of course, contrary to the
896 specification of the DNS, so we lock it out. */
897
898 if ((type == T_A || type == T_AAAA) && string_is_ip_address(name, NULL) != 0)
899   return DNS_NOMATCH;
900
901 /* If we are running in the test harness, instead of calling the normal resolver
902 (res_search), we call fakens_search(), which recognizes certain special
903 domains, and interfaces to a fake nameserver for certain special zones. */
904
905 h_errno = 0;
906 dnsa->answerlen = f.running_in_test_harness
907   ? fakens_search(name, type, dnsa->answer, sizeof(dnsa->answer))
908   : res_search(CCS name, C_IN, type, dnsa->answer, sizeof(dnsa->answer));
909
910 if (dnsa->answerlen > (int) sizeof(dnsa->answer))
911   {
912   DEBUG(D_dns) debug_printf_indent("DNS lookup of %s (%s) resulted in overlong packet"
913     " (size %d), truncating to %u.\n",
914     name, dns_text_type(type), dnsa->answerlen, (unsigned int) sizeof(dnsa->answer));
915   dnsa->answerlen = sizeof(dnsa->answer);
916   }
917
918 if (dnsa->answerlen < 0) switch (h_errno)
919   {
920   case HOST_NOT_FOUND:
921     DEBUG(D_dns) debug_printf_indent("DNS lookup of %s (%s) gave HOST_NOT_FOUND\n"
922       "returning DNS_NOMATCH\n", name, dns_text_type(type));
923     return dns_fail_return(name, type, dns_expire_from_soa(dnsa, type), DNS_NOMATCH);
924
925   case TRY_AGAIN:
926     DEBUG(D_dns) debug_printf_indent("DNS lookup of %s (%s) gave TRY_AGAIN\n",
927       name, dns_text_type(type));
928
929     /* Cut this out for various test programs */
930 #ifndef STAND_ALONE
931     /* Permitting dns_again_means nonexist for TLSA lookups breaks the
932     doewngrade resistance of dane, so avoid for those. */
933
934     if (type == T_TLSA)
935       rc = FAIL;
936     else
937       {
938       if (try_again_recursion)
939         {
940         log_write(0, LOG_MAIN|LOG_PANIC,
941           "dns_again_means_nonexist recursion seen for %s"
942           " (assuming nonexist)", name);
943         return dns_fail_return(name, type, dns_expire_from_soa(dnsa, type),
944                               DNS_NOMATCH);
945         }
946
947       try_again_recursion = TRUE;
948       save_domain = deliver_domain;
949       deliver_domain = string_copy(name);  /* set $domain */
950       rc = match_isinlist(name, CUSS &dns_again_means_nonexist, 0,
951         &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL);
952       deliver_domain = save_domain;
953       try_again_recursion = FALSE;
954       }
955
956     if (rc != OK)
957       {
958       DEBUG(D_dns) debug_printf_indent("returning DNS_AGAIN\n");
959       return dns_fail_return(name, type, 0, DNS_AGAIN);
960       }
961     DEBUG(D_dns) debug_printf_indent("%s is in dns_again_means_nonexist: returning "
962       "DNS_NOMATCH\n", name);
963     return dns_fail_return(name, type, dns_expire_from_soa(dnsa, type), DNS_NOMATCH);
964
965 #else   /* For stand-alone tests */
966     return dns_fail_return(name, type, 0, DNS_AGAIN);
967 #endif
968
969   case NO_RECOVERY:
970     DEBUG(D_dns) debug_printf_indent("DNS lookup of %s (%s) gave NO_RECOVERY\n"
971       "returning DNS_FAIL\n", name, dns_text_type(type));
972     return dns_fail_return(name, type, 0, DNS_FAIL);
973
974   case NO_DATA:
975     DEBUG(D_dns) debug_printf_indent("DNS lookup of %s (%s) gave NO_DATA\n"
976       "returning DNS_NODATA\n", name, dns_text_type(type));
977     return dns_fail_return(name, type, dns_expire_from_soa(dnsa, type), DNS_NODATA);
978
979   default:
980     DEBUG(D_dns) debug_printf_indent("DNS lookup of %s (%s) gave unknown DNS error %d\n"
981       "returning DNS_FAIL\n", name, dns_text_type(type), h_errno);
982     return dns_fail_return(name, type, 0, DNS_FAIL);
983   }
984
985 DEBUG(D_dns) debug_printf_indent("DNS lookup of %s (%s) succeeded\n",
986   name, dns_text_type(type));
987
988 return DNS_SUCCEED;
989 }
990
991
992
993
994 /************************************************
995 *        Do a DNS lookup and handle CNAMES      *
996 ************************************************/
997
998 /* Look up the given domain name, using the given type. Follow CNAMEs if
999 necessary, but only so many times. There aren't supposed to be CNAME chains in
1000 the DNS, but you are supposed to cope with them if you find them.
1001 By default, follow one CNAME since a resolver has been seen, faced with
1002 an MX request and a CNAME (to an A) but no MX present, returning the CNAME.
1003
1004 The assumption is made that if the resolver gives back records of the
1005 requested type *and* a CNAME, we don't need to make another call to look up
1006 the CNAME. I can't see how it could return only some of the right records. If
1007 it's done a CNAME lookup in the past, it will have all of them; if not, it
1008 won't return any.
1009
1010 If fully_qualified_name is not NULL, set it to point to the full name
1011 returned by the resolver, if this is different to what it is given, unless
1012 the returned name starts with "*" as some nameservers seem to be returning
1013 wildcards in this form.  In international mode "different" means "a-label
1014 forms are different".
1015
1016 Arguments:
1017   dnsa                  pointer to dns_answer structure
1018   name                  domain name to look up
1019   type                  DNS record type (T_A, T_MX, etc)
1020   fully_qualified_name  if not NULL, return the returned name here if its
1021                           contents are different (i.e. it must be preset)
1022
1023 Returns:                DNS_SUCCEED   successful lookup
1024                         DNS_NOMATCH   name not found
1025                         DNS_NODATA    no data found
1026                         DNS_AGAIN     soft failure, try again later
1027                         DNS_FAIL      DNS failure
1028 */
1029
1030 int
1031 dns_lookup(dns_answer * dnsa, const uschar * name, int type,
1032   const uschar ** fully_qualified_name)
1033 {
1034 const uschar * orig_name = name;
1035 BOOL secure_so_far = TRUE;
1036 int rc = DNS_FAIL;
1037 const uschar * errstr = NULL;
1038
1039 /* By default, assume the resolver follows CNAME chains (and returns NODATA for
1040 an unterminated one). If it also does that for a CNAME loop, fine; if it returns
1041 a CNAME (maybe the last?) whine about it.  However, retain the coding for dumb
1042 resolvers hiding behind a config variable. Loop to follow CNAME chains so far,
1043 but no further...  The testsuite tests the latter case, mostly assuming that the
1044 former will work. */
1045
1046 for (int i = 0; i <= dns_cname_loops; i++)
1047   {
1048   uschar * data;
1049   dns_record cname_rr, type_rr;
1050   dns_scan dnss;
1051
1052   /* DNS lookup failures get passed straight back. */
1053
1054   if ((rc = dns_basic_lookup(dnsa, name, type)) != DNS_SUCCEED)
1055     goto not_good;
1056
1057   /* We should have either records of the required type, or a CNAME record,
1058   or both. We need to know whether both exist for getting the fully qualified
1059   name, but avoid scanning more than necessary. Note that we must copy the
1060   contents of any rr blocks returned by dns_next_rr() as they use the same
1061   area in the dnsa block. */
1062
1063   cname_rr.data = type_rr.data = NULL;
1064   for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS);
1065        rr; rr = dns_next_rr(dnsa, &dnss, RESET_NEXT))
1066     if (rr->type == type)
1067       {
1068       if (type_rr.data == NULL) type_rr = *rr;
1069       if (cname_rr.data != NULL) break;
1070       }
1071     else if (rr->type == T_CNAME)
1072       cname_rr = *rr;
1073
1074   /* For the first time round this loop, if a CNAME was found, take the fully
1075   qualified name from it; otherwise from the first data record, if present. */
1076
1077   if (i == 0 && fully_qualified_name)
1078     {
1079     uschar * rr_name = cname_rr.data
1080       ? cname_rr.name : type_rr.data ? type_rr.name : NULL;
1081     if (  rr_name
1082        && Ustrcmp(rr_name, *fully_qualified_name) != 0
1083        && rr_name[0] != '*'
1084 #ifdef SUPPORT_I18N
1085        && (  !string_is_utf8(*fully_qualified_name)
1086           || Ustrcmp(rr_name,
1087                string_domain_utf8_to_alabel(*fully_qualified_name, NULL)) != 0
1088           )
1089 #endif
1090        )
1091         *fully_qualified_name = string_copy_dnsdomain(rr_name);
1092     }
1093
1094   /* If any data records of the correct type were found, we are done. */
1095
1096   if (type_rr.data)
1097     {
1098     if (!secure_so_far) /* mark insecure if any element of CNAME chain was */
1099       dns_set_insecure(dnsa);
1100     return DNS_SUCCEED;
1101     }
1102
1103   /* If there are no data records, we need to re-scan the DNS using the
1104   domain given in the CNAME record, which should exist (otherwise we should
1105   have had a failure from dns_lookup). However code against the possibility of
1106   its not existing. */
1107
1108   if (!cname_rr.data)
1109     {
1110     errstr = US"no_hit_yet_no_cname";
1111     goto not_good;
1112     }
1113
1114   /* DNS data comes from the outside, hence tainted */
1115   data = store_get(256, GET_TAINTED);
1116   if (dn_expand(dnsa->answer, dnsa->answer + dnsa->answerlen,
1117       cname_rr.data, (DN_EXPAND_ARG4_TYPE)data, 256) < 0)
1118     {
1119     errstr = US"bad_expand";
1120     goto not_good;
1121     }
1122   name = data;
1123
1124   if (!dns_is_secure(dnsa))
1125     secure_so_far = FALSE;
1126
1127   DEBUG(D_dns) debug_printf_indent("CNAME found: change to %s\n", name);
1128   }       /* Loop back to do another lookup */
1129
1130 /* Control reaches here after 10 times round the CNAME loop. Something isn't
1131 right... */
1132
1133 log_write(0, LOG_MAIN, "CNAME loop for %s encountered", orig_name);
1134 errstr = US"cname_loop";
1135
1136 not_good:
1137   {
1138 #ifndef DISABLE_EVENTS
1139   const uschar * s = NULL;
1140   BOOL save_flag = f.search_find_defer;
1141   uschar * save_serr = search_error_message;
1142
1143   if (!transport_name)
1144     s = event_action;
1145   else
1146     for(transport_instance * tp = transports; tp; tp = tp->next)
1147       if (Ustrcmp(tp->name, transport_name) == 0)
1148         { s = tp->event_action; break; }
1149
1150   if (s)
1151     {
1152     if (Ustrchr(name, ':'))     /* unlikely, but may as well bugproof */
1153       {
1154       gstring * g = NULL;
1155       while (*name)
1156         {
1157         if (*name == ':') g = string_catn(g, name, 1);
1158         g = string_catn(g, name++, 1);
1159         }
1160       name = string_from_gstring(g);
1161       }
1162     event_raise(s, US"dns:fail",
1163       string_sprintf("%s:%s:%s",
1164         errstr ? errstr : dns_rc_names[rc], name, dns_text_type(type)),
1165       NULL);
1166     }
1167
1168   /*XXX what other state could an expansion in the eventhandler mess up? */
1169   search_error_message = save_serr;
1170   f.search_find_defer = save_flag;
1171 #endif  /*EVENTS*/
1172   return rc;
1173   }
1174 }
1175
1176
1177
1178
1179
1180
1181 /************************************************
1182 *    Do a DNS lookup and handle virtual types   *
1183 ************************************************/
1184
1185 /* This function handles some invented "lookup types" that synthesize features
1186 not available in the basic types. The special types all have negative values.
1187 Positive type values are passed straight on to dns_lookup().
1188
1189 Arguments:
1190   dnsa                  pointer to dns_answer structure
1191   name                  domain name to look up
1192   type                  DNS record type (T_A, T_MX, etc or a "special")
1193   fully_qualified_name  if not NULL, return the returned name here if its
1194                           contents are different (i.e. it must be preset)
1195
1196 Returns:                DNS_SUCCEED   successful lookup
1197                         DNS_NOMATCH   name not found
1198                         DNS_NODATA    no data found
1199                         DNS_AGAIN     soft failure, try again later
1200                         DNS_FAIL      DNS failure
1201 */
1202
1203 int
1204 dns_special_lookup(dns_answer *dnsa, const uschar *name, int type,
1205   const uschar **fully_qualified_name)
1206 {
1207 switch (type)
1208   {
1209   /* The "mx hosts only" type doesn't require any special action here */
1210   case T_MXH:
1211     return dns_lookup(dnsa, name, T_MX, fully_qualified_name);
1212
1213   /* Find nameservers for the domain or the nearest enclosing zone, excluding
1214   the root servers. */
1215   case T_ZNS:
1216     type = T_NS;
1217     /* FALLTHROUGH */
1218   case T_SOA:
1219     {
1220     const uschar *d = name;
1221     while (d)
1222       {
1223       int rc = dns_lookup(dnsa, d, type, fully_qualified_name);
1224       if (rc != DNS_NOMATCH && rc != DNS_NODATA) return rc;
1225       while (*d && *d != '.') d++;
1226       if (!*d++) break;
1227       }
1228     return DNS_NOMATCH;
1229     }
1230
1231   /* Try to look up the Client SMTP Authorization SRV record for the name. If
1232   there isn't one, search from the top downwards for a CSA record in a parent
1233   domain, which might be making assertions about subdomains. If we find a record
1234   we set fully_qualified_name to whichever lookup succeeded, so that the caller
1235   can tell whether to look at the explicit authorization field or the subdomain
1236   assertion field. */
1237   case T_CSA:
1238     {
1239     uschar *srvname, *namesuff, *tld;
1240     int priority, dummy_weight, port;
1241     int limit, rc, i;
1242     BOOL ipv6;
1243     dns_record *rr;
1244     dns_scan dnss;
1245
1246     DEBUG(D_dns) debug_printf_indent("CSA lookup of %s\n", name);
1247
1248     srvname = string_sprintf("_client._smtp.%s", name);
1249     rc = dns_lookup(dnsa, srvname, T_SRV, NULL);
1250     if (rc == DNS_SUCCEED || rc == DNS_AGAIN)
1251       {
1252       if (rc == DNS_SUCCEED) *fully_qualified_name = string_copy(name);
1253       return rc;
1254       }
1255
1256     /* Search for CSA subdomain assertion SRV records from the top downwards,
1257     starting with the 2nd level domain. This order maximizes cache-friendliness.
1258     We skip the top level domains to avoid loading their nameservers and because
1259     we know they'll never have CSA SRV records. */
1260
1261     namesuff = Ustrrchr(name, '.');
1262     if (namesuff == NULL) return DNS_NOMATCH;
1263     tld = namesuff + 1;
1264     ipv6 = FALSE;
1265     limit = dns_csa_search_limit;
1266
1267     /* Use more appropriate search parameters if we are in the reverse DNS. */
1268
1269     if (strcmpic(namesuff, US".arpa") == 0)
1270       if (namesuff - 8 > name && strcmpic(namesuff - 8, US".in-addr.arpa") == 0)
1271         {
1272         namesuff -= 8;
1273         tld = namesuff + 1;
1274         limit = 3;
1275         }
1276       else if (namesuff - 4 > name && strcmpic(namesuff - 4, US".ip6.arpa") == 0)
1277         {
1278         namesuff -= 4;
1279         tld = namesuff + 1;
1280         ipv6 = TRUE;
1281         limit = 3;
1282         }
1283
1284     DEBUG(D_dns) debug_printf_indent("CSA TLD %s\n", tld);
1285
1286     /* Do not perform the search if the top level or 2nd level domains do not
1287     exist. This is quite common, and when it occurs all the search queries would
1288     go to the root or TLD name servers, which is not friendly. So we check the
1289     AUTHORITY section; if it contains the root's SOA record or the TLD's SOA then
1290     the TLD or the 2LD (respectively) doesn't exist and we can skip the search.
1291     If the TLD and the 2LD exist but the explicit CSA record lookup failed, then
1292     the AUTHORITY SOA will be the 2LD's or a subdomain thereof. */
1293
1294     if (rc == DNS_NOMATCH) return DNS_NOMATCH;
1295
1296     for (i = 0; i < limit; i++)
1297       {
1298       if (ipv6)
1299         {
1300         /* Scan through the IPv6 reverse DNS in chunks of 16 bits worth of IP
1301         address, i.e. 4 hex chars and 4 dots, i.e. 8 chars. */
1302         namesuff -= 8;
1303         if (namesuff <= name) return DNS_NOMATCH;
1304         }
1305       else
1306         /* Find the start of the preceding domain name label. */
1307         do
1308           if (--namesuff <= name) return DNS_NOMATCH;
1309         while (*namesuff != '.');
1310
1311       DEBUG(D_dns) debug_printf_indent("CSA parent search at %s\n", namesuff + 1);
1312
1313       srvname = string_sprintf("_client._smtp.%s", namesuff + 1);
1314       rc = dns_lookup(dnsa, srvname, T_SRV, NULL);
1315       if (rc == DNS_AGAIN) return rc;
1316       if (rc != DNS_SUCCEED) continue;
1317
1318       /* Check that the SRV record we have found is worth returning. We don't
1319       just return the first one we find, because some lower level SRV record
1320       might make stricter assertions than its parent domain. */
1321
1322       for (rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS);
1323            rr; rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)) if (rr->type == T_SRV)
1324         {
1325         const uschar * p = rr->data;
1326
1327         /* Extract the numerical SRV fields (p is incremented) */
1328         if (rr_bad_size(rr, 3 * sizeof(uint16_t))) continue;
1329         GETSHORT(priority, p);
1330         GETSHORT(dummy_weight, p);
1331         GETSHORT(port, p);
1332
1333         /* Check the CSA version number */
1334         if (priority != 1) continue;
1335
1336         /* If it's making an interesting assertion, return this response. */
1337         if (port & 1)
1338           {
1339           *fully_qualified_name = namesuff + 1;
1340           return DNS_SUCCEED;
1341           }
1342         }
1343       }
1344     return DNS_NOMATCH;
1345     }
1346
1347   default:
1348     if (type >= 0)
1349       return dns_lookup(dnsa, name, type, fully_qualified_name);
1350   }
1351
1352 /* Control should never reach here */
1353
1354 return DNS_FAIL;
1355 }
1356
1357
1358
1359
1360
1361 /*************************************************
1362 *          Get address(es) from DNS record       *
1363 *************************************************/
1364
1365 /* The record type is either T_A for an IPv4 address or T_AAAA for an IPv6 address.
1366
1367 Argument:
1368   dnsa       the DNS answer block
1369   rr         the RR
1370
1371 Returns:     pointer to a chain of dns_address items; NULL when the dnsa was overrun
1372 */
1373
1374 dns_address *
1375 dns_address_from_rr(dns_answer *dnsa, dns_record *rr)
1376 {
1377 dns_address * yield = NULL;
1378 uschar * dnsa_lim = dnsa->answer + dnsa->answerlen;
1379
1380 if (rr->type == T_A)
1381   {
1382   uschar *p = US rr->data;
1383   if (p + 4 <= dnsa_lim)
1384     {
1385     /* the IP is not regarded as tainted */
1386     yield = store_get(sizeof(dns_address) + 20, GET_UNTAINTED);
1387     (void)sprintf(CS yield->address, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
1388     yield->next = NULL;
1389     }
1390   }
1391
1392 #if HAVE_IPV6
1393
1394 else
1395   {
1396   if (rr->data + 16 <= dnsa_lim)
1397     {
1398     struct in6_addr in6;
1399     for (int i = 0; i < 16; i++) in6.s6_addr[i] = rr->data[i];
1400     yield = store_get(sizeof(dns_address) + 50, GET_UNTAINTED);
1401     inet_ntop(AF_INET6, &in6, CS yield->address, 50);
1402     yield->next = NULL;
1403     }
1404   }
1405 #endif  /* HAVE_IPV6 */
1406
1407 return yield;
1408 }
1409
1410
1411
1412 void
1413 dns_pattern_init(void)
1414 {
1415 if (check_dns_names_pattern[0] != 0 && !regex_check_dns_names)
1416   regex_check_dns_names =
1417     regex_must_compile(check_dns_names_pattern, MCS_NOFLAGS, TRUE);
1418 }
1419
1420 /* vi: aw ai sw=2
1421 */
1422 /* End of dns.c */