5a8c23d62b4234ad9b574d47c87269e4e0ad9b2e
[exim.git] / src / src / dns.c
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 /* Copyright (c) The Exim Maintainers 2020 - 2023 */
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   const uschar * s = NULL;
1139   BOOL save_flag = f.search_find_defer;
1140   uschar * save_serr = search_error_message;
1141
1142   if (!transport_name)
1143     s = event_action;
1144   else
1145     for(transport_instance * tp = transports; tp; tp = tp->next)
1146       if (Ustrcmp(tp->name, transport_name) == 0)
1147         { s = tp->event_action; break; }
1148
1149   if (s)
1150     {
1151     if (Ustrchr(name, ':'))     /* unlikely, but may as well bugproof */
1152       {
1153       gstring * g = NULL;
1154       while (*name)
1155         {
1156         if (*name == ':') g = string_catn(g, name, 1);
1157         g = string_catn(g, name++, 1);
1158         }
1159       name = string_from_gstring(g);
1160       }
1161     event_raise(s, US"dns:fail",
1162       string_sprintf("%s:%s:%s",
1163         errstr ? errstr : dns_rc_names[rc], name, dns_text_type(type)),
1164       NULL);
1165     }
1166
1167   /*XXX what other state could an expansion in the eventhandler mess up? */
1168   search_error_message = save_serr;
1169   f.search_find_defer = save_flag;
1170   return rc;
1171   }
1172 }
1173
1174
1175
1176
1177
1178
1179 /************************************************
1180 *    Do a DNS lookup and handle virtual types   *
1181 ************************************************/
1182
1183 /* This function handles some invented "lookup types" that synthesize features
1184 not available in the basic types. The special types all have negative values.
1185 Positive type values are passed straight on to dns_lookup().
1186
1187 Arguments:
1188   dnsa                  pointer to dns_answer structure
1189   name                  domain name to look up
1190   type                  DNS record type (T_A, T_MX, etc or a "special")
1191   fully_qualified_name  if not NULL, return the returned name here if its
1192                           contents are different (i.e. it must be preset)
1193
1194 Returns:                DNS_SUCCEED   successful lookup
1195                         DNS_NOMATCH   name not found
1196                         DNS_NODATA    no data found
1197                         DNS_AGAIN     soft failure, try again later
1198                         DNS_FAIL      DNS failure
1199 */
1200
1201 int
1202 dns_special_lookup(dns_answer *dnsa, const uschar *name, int type,
1203   const uschar **fully_qualified_name)
1204 {
1205 switch (type)
1206   {
1207   /* The "mx hosts only" type doesn't require any special action here */
1208   case T_MXH:
1209     return dns_lookup(dnsa, name, T_MX, fully_qualified_name);
1210
1211   /* Find nameservers for the domain or the nearest enclosing zone, excluding
1212   the root servers. */
1213   case T_ZNS:
1214     type = T_NS;
1215     /* FALLTHROUGH */
1216   case T_SOA:
1217     {
1218     const uschar *d = name;
1219     while (d)
1220       {
1221       int rc = dns_lookup(dnsa, d, type, fully_qualified_name);
1222       if (rc != DNS_NOMATCH && rc != DNS_NODATA) return rc;
1223       while (*d && *d != '.') d++;
1224       if (!*d++) break;
1225       }
1226     return DNS_NOMATCH;
1227     }
1228
1229   /* Try to look up the Client SMTP Authorization SRV record for the name. If
1230   there isn't one, search from the top downwards for a CSA record in a parent
1231   domain, which might be making assertions about subdomains. If we find a record
1232   we set fully_qualified_name to whichever lookup succeeded, so that the caller
1233   can tell whether to look at the explicit authorization field or the subdomain
1234   assertion field. */
1235   case T_CSA:
1236     {
1237     uschar *srvname, *namesuff, *tld;
1238     int priority, dummy_weight, port;
1239     int limit, rc, i;
1240     BOOL ipv6;
1241     dns_record *rr;
1242     dns_scan dnss;
1243
1244     DEBUG(D_dns) debug_printf_indent("CSA lookup of %s\n", name);
1245
1246     srvname = string_sprintf("_client._smtp.%s", name);
1247     rc = dns_lookup(dnsa, srvname, T_SRV, NULL);
1248     if (rc == DNS_SUCCEED || rc == DNS_AGAIN)
1249       {
1250       if (rc == DNS_SUCCEED) *fully_qualified_name = string_copy(name);
1251       return rc;
1252       }
1253
1254     /* Search for CSA subdomain assertion SRV records from the top downwards,
1255     starting with the 2nd level domain. This order maximizes cache-friendliness.
1256     We skip the top level domains to avoid loading their nameservers and because
1257     we know they'll never have CSA SRV records. */
1258
1259     namesuff = Ustrrchr(name, '.');
1260     if (namesuff == NULL) return DNS_NOMATCH;
1261     tld = namesuff + 1;
1262     ipv6 = FALSE;
1263     limit = dns_csa_search_limit;
1264
1265     /* Use more appropriate search parameters if we are in the reverse DNS. */
1266
1267     if (strcmpic(namesuff, US".arpa") == 0)
1268       if (namesuff - 8 > name && strcmpic(namesuff - 8, US".in-addr.arpa") == 0)
1269         {
1270         namesuff -= 8;
1271         tld = namesuff + 1;
1272         limit = 3;
1273         }
1274       else if (namesuff - 4 > name && strcmpic(namesuff - 4, US".ip6.arpa") == 0)
1275         {
1276         namesuff -= 4;
1277         tld = namesuff + 1;
1278         ipv6 = TRUE;
1279         limit = 3;
1280         }
1281
1282     DEBUG(D_dns) debug_printf_indent("CSA TLD %s\n", tld);
1283
1284     /* Do not perform the search if the top level or 2nd level domains do not
1285     exist. This is quite common, and when it occurs all the search queries would
1286     go to the root or TLD name servers, which is not friendly. So we check the
1287     AUTHORITY section; if it contains the root's SOA record or the TLD's SOA then
1288     the TLD or the 2LD (respectively) doesn't exist and we can skip the search.
1289     If the TLD and the 2LD exist but the explicit CSA record lookup failed, then
1290     the AUTHORITY SOA will be the 2LD's or a subdomain thereof. */
1291
1292     if (rc == DNS_NOMATCH) return DNS_NOMATCH;
1293
1294     for (i = 0; i < limit; i++)
1295       {
1296       if (ipv6)
1297         {
1298         /* Scan through the IPv6 reverse DNS in chunks of 16 bits worth of IP
1299         address, i.e. 4 hex chars and 4 dots, i.e. 8 chars. */
1300         namesuff -= 8;
1301         if (namesuff <= name) return DNS_NOMATCH;
1302         }
1303       else
1304         /* Find the start of the preceding domain name label. */
1305         do
1306           if (--namesuff <= name) return DNS_NOMATCH;
1307         while (*namesuff != '.');
1308
1309       DEBUG(D_dns) debug_printf_indent("CSA parent search at %s\n", namesuff + 1);
1310
1311       srvname = string_sprintf("_client._smtp.%s", namesuff + 1);
1312       rc = dns_lookup(dnsa, srvname, T_SRV, NULL);
1313       if (rc == DNS_AGAIN) return rc;
1314       if (rc != DNS_SUCCEED) continue;
1315
1316       /* Check that the SRV record we have found is worth returning. We don't
1317       just return the first one we find, because some lower level SRV record
1318       might make stricter assertions than its parent domain. */
1319
1320       for (rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS);
1321            rr; rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)) if (rr->type == T_SRV)
1322         {
1323         const uschar * p = rr->data;
1324
1325         /* Extract the numerical SRV fields (p is incremented) */
1326         if (rr_bad_size(rr, 3 * sizeof(uint16_t))) continue;
1327         GETSHORT(priority, p);
1328         GETSHORT(dummy_weight, p);
1329         GETSHORT(port, p);
1330
1331         /* Check the CSA version number */
1332         if (priority != 1) continue;
1333
1334         /* If it's making an interesting assertion, return this response. */
1335         if (port & 1)
1336           {
1337           *fully_qualified_name = namesuff + 1;
1338           return DNS_SUCCEED;
1339           }
1340         }
1341       }
1342     return DNS_NOMATCH;
1343     }
1344
1345   default:
1346     if (type >= 0)
1347       return dns_lookup(dnsa, name, type, fully_qualified_name);
1348   }
1349
1350 /* Control should never reach here */
1351
1352 return DNS_FAIL;
1353 }
1354
1355
1356
1357
1358
1359 /*************************************************
1360 *          Get address(es) from DNS record       *
1361 *************************************************/
1362
1363 /* The record type is either T_A for an IPv4 address or T_AAAA for an IPv6 address.
1364
1365 Argument:
1366   dnsa       the DNS answer block
1367   rr         the RR
1368
1369 Returns:     pointer to a chain of dns_address items; NULL when the dnsa was overrun
1370 */
1371
1372 dns_address *
1373 dns_address_from_rr(dns_answer *dnsa, dns_record *rr)
1374 {
1375 dns_address * yield = NULL;
1376 uschar * dnsa_lim = dnsa->answer + dnsa->answerlen;
1377
1378 if (rr->type == T_A)
1379   {
1380   uschar *p = US rr->data;
1381   if (p + 4 <= dnsa_lim)
1382     {
1383     /* the IP is not regarded as tainted */
1384     yield = store_get(sizeof(dns_address) + 20, GET_UNTAINTED);
1385     (void)sprintf(CS yield->address, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
1386     yield->next = NULL;
1387     }
1388   }
1389
1390 #if HAVE_IPV6
1391
1392 else
1393   {
1394   if (rr->data + 16 <= dnsa_lim)
1395     {
1396     struct in6_addr in6;
1397     for (int i = 0; i < 16; i++) in6.s6_addr[i] = rr->data[i];
1398     yield = store_get(sizeof(dns_address) + 50, GET_UNTAINTED);
1399     inet_ntop(AF_INET6, &in6, CS yield->address, 50);
1400     yield->next = NULL;
1401     }
1402   }
1403 #endif  /* HAVE_IPV6 */
1404
1405 return yield;
1406 }
1407
1408
1409
1410 void
1411 dns_pattern_init(void)
1412 {
1413 if (check_dns_names_pattern[0] != 0 && !regex_check_dns_names)
1414   regex_check_dns_names =
1415     regex_must_compile(check_dns_names_pattern, MCS_NOFLAGS, TRUE);
1416 }
1417
1418 /* vi: aw ai sw=2
1419 */
1420 /* End of dns.c */