74c5a58c538df86abf3c37ea78d9db5462185313
[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("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("fakens returned PASS_ON\n");
109     }
110   }
111 else
112   {
113   DEBUG(D_dns) debug_printf("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("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("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("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("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("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("Unable to %sset DNSSEC without resolver support.\n",
206         dns_dnssec_ok ? "" : "un");
207 if (use_dnssec)
208   DEBUG(D_resolver)
209     debug_printf("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("%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("%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("%s: additional\n", __FUNCTION__);
384     dnss->rrcount += ntohs(h->nscount);
385     TRACE debug_printf("%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("%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("%s: reset (%s rrcount %d)\n", __FUNCTION__,
413       reset == RESET_AUTHORITY ? "NS" : "AR", dnss->rrcount);
414     }
415   TRACE debug_printf("%s: %d RRs to read\n", __FUNCTION__, dnss->rrcount);
416   }
417 else
418   TRACE debug_printf("%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("%s: return %s\n", __FUNCTION__, dns_text_type(dnss->srr.type));
462 return &dnss->srr;
463
464 null_return:
465   TRACE debug_printf("%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("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("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(" %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("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("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("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("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("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("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("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("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("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("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("returning DNS_AGAIN\n");
959       return dns_fail_return(name, type, 0, DNS_AGAIN);
960       }
961     DEBUG(D_dns) debug_printf("%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("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("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("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("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 "alabel
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
1037 /* By default, assume the resolver follows CNAME chains (and returns NODATA for
1038 an unterminated one). If it also does that for a CNAME loop, fine; if it returns
1039 a CNAME (maybe the last?) whine about it.  However, retain the coding for dumb
1040 resolvers hiding behind a config variable. Loop to follow CNAME chains so far,
1041 but no further...  The testsuite tests the latter case, mostly assuming that the
1042 former will work. */
1043
1044 for (int i = 0; i <= dns_cname_loops; i++)
1045   {
1046   uschar * data;
1047   dns_record cname_rr, type_rr;
1048   dns_scan dnss;
1049   int rc;
1050
1051   /* DNS lookup failures get passed straight back. */
1052
1053   if ((rc = dns_basic_lookup(dnsa, name, type)) != DNS_SUCCEED)
1054     return rc;
1055
1056   /* We should have either records of the required type, or a CNAME record,
1057   or both. We need to know whether both exist for getting the fully qualified
1058   name, but avoid scanning more than necessary. Note that we must copy the
1059   contents of any rr blocks returned by dns_next_rr() as they use the same
1060   area in the dnsa block. */
1061
1062   cname_rr.data = type_rr.data = NULL;
1063   for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS);
1064        rr; rr = dns_next_rr(dnsa, &dnss, RESET_NEXT))
1065     if (rr->type == type)
1066       {
1067       if (type_rr.data == NULL) type_rr = *rr;
1068       if (cname_rr.data != NULL) break;
1069       }
1070     else if (rr->type == T_CNAME)
1071       cname_rr = *rr;
1072
1073   /* For the first time round this loop, if a CNAME was found, take the fully
1074   qualified name from it; otherwise from the first data record, if present. */
1075
1076   if (i == 0 && fully_qualified_name)
1077     {
1078     uschar * rr_name = cname_rr.data
1079       ? cname_rr.name : type_rr.data ? type_rr.name : NULL;
1080     if (  rr_name
1081        && Ustrcmp(rr_name, *fully_qualified_name) != 0
1082        && rr_name[0] != '*'
1083 #ifdef SUPPORT_I18N
1084        && (  !string_is_utf8(*fully_qualified_name)
1085           || Ustrcmp(rr_name,
1086                string_domain_utf8_to_alabel(*fully_qualified_name, NULL)) != 0
1087           )
1088 #endif
1089        )
1090         *fully_qualified_name = string_copy_dnsdomain(rr_name);
1091     }
1092
1093   /* If any data records of the correct type were found, we are done. */
1094
1095   if (type_rr.data)
1096     {
1097     if (!secure_so_far) /* mark insecure if any element of CNAME chain was */
1098       dns_set_insecure(dnsa);
1099     return DNS_SUCCEED;
1100     }
1101
1102   /* If there are no data records, we need to re-scan the DNS using the
1103   domain given in the CNAME record, which should exist (otherwise we should
1104   have had a failure from dns_lookup). However code against the possibility of
1105   its not existing. */
1106
1107   if (!cname_rr.data)
1108     return DNS_FAIL;
1109
1110   /* DNS data comes from the outside, hence tainted */
1111   data = store_get(256, GET_TAINTED);
1112   if (dn_expand(dnsa->answer, dnsa->answer + dnsa->answerlen,
1113       cname_rr.data, (DN_EXPAND_ARG4_TYPE)data, 256) < 0)
1114     return DNS_FAIL;
1115   name = data;
1116
1117   if (!dns_is_secure(dnsa))
1118     secure_so_far = FALSE;
1119
1120   DEBUG(D_dns) debug_printf("CNAME found: change to %s\n", name);
1121   }       /* Loop back to do another lookup */
1122
1123 /*Control reaches here after 10 times round the CNAME loop. Something isn't
1124 right... */
1125
1126 log_write(0, LOG_MAIN, "CNAME loop for %s encountered", orig_name);
1127 return DNS_FAIL;
1128 }
1129
1130
1131
1132
1133
1134
1135 /************************************************
1136 *    Do a DNS lookup and handle virtual types   *
1137 ************************************************/
1138
1139 /* This function handles some invented "lookup types" that synthesize features
1140 not available in the basic types. The special types all have negative values.
1141 Positive type values are passed straight on to dns_lookup().
1142
1143 Arguments:
1144   dnsa                  pointer to dns_answer structure
1145   name                  domain name to look up
1146   type                  DNS record type (T_A, T_MX, etc or a "special")
1147   fully_qualified_name  if not NULL, return the returned name here if its
1148                           contents are different (i.e. it must be preset)
1149
1150 Returns:                DNS_SUCCEED   successful lookup
1151                         DNS_NOMATCH   name not found
1152                         DNS_NODATA    no data found
1153                         DNS_AGAIN     soft failure, try again later
1154                         DNS_FAIL      DNS failure
1155 */
1156
1157 int
1158 dns_special_lookup(dns_answer *dnsa, const uschar *name, int type,
1159   const uschar **fully_qualified_name)
1160 {
1161 switch (type)
1162   {
1163   /* The "mx hosts only" type doesn't require any special action here */
1164   case T_MXH:
1165     return dns_lookup(dnsa, name, T_MX, fully_qualified_name);
1166
1167   /* Find nameservers for the domain or the nearest enclosing zone, excluding
1168   the root servers. */
1169   case T_ZNS:
1170     type = T_NS;
1171     /* FALLTHROUGH */
1172   case T_SOA:
1173     {
1174     const uschar *d = name;
1175     while (d != 0)
1176       {
1177       int rc = dns_lookup(dnsa, d, type, fully_qualified_name);
1178       if (rc != DNS_NOMATCH && rc != DNS_NODATA) return rc;
1179       while (*d != 0 && *d != '.') d++;
1180       if (*d++ == 0) break;
1181       }
1182     return DNS_NOMATCH;
1183     }
1184
1185   /* Try to look up the Client SMTP Authorization SRV record for the name. If
1186   there isn't one, search from the top downwards for a CSA record in a parent
1187   domain, which might be making assertions about subdomains. If we find a record
1188   we set fully_qualified_name to whichever lookup succeeded, so that the caller
1189   can tell whether to look at the explicit authorization field or the subdomain
1190   assertion field. */
1191   case T_CSA:
1192     {
1193     uschar *srvname, *namesuff, *tld;
1194     int priority, dummy_weight, port;
1195     int limit, rc, i;
1196     BOOL ipv6;
1197     dns_record *rr;
1198     dns_scan dnss;
1199
1200     DEBUG(D_dns) debug_printf("CSA lookup of %s\n", name);
1201
1202     srvname = string_sprintf("_client._smtp.%s", name);
1203     rc = dns_lookup(dnsa, srvname, T_SRV, NULL);
1204     if (rc == DNS_SUCCEED || rc == DNS_AGAIN)
1205       {
1206       if (rc == DNS_SUCCEED) *fully_qualified_name = string_copy(name);
1207       return rc;
1208       }
1209
1210     /* Search for CSA subdomain assertion SRV records from the top downwards,
1211     starting with the 2nd level domain. This order maximizes cache-friendliness.
1212     We skip the top level domains to avoid loading their nameservers and because
1213     we know they'll never have CSA SRV records. */
1214
1215     namesuff = Ustrrchr(name, '.');
1216     if (namesuff == NULL) return DNS_NOMATCH;
1217     tld = namesuff + 1;
1218     ipv6 = FALSE;
1219     limit = dns_csa_search_limit;
1220
1221     /* Use more appropriate search parameters if we are in the reverse DNS. */
1222
1223     if (strcmpic(namesuff, US".arpa") == 0)
1224       if (namesuff - 8 > name && strcmpic(namesuff - 8, US".in-addr.arpa") == 0)
1225         {
1226         namesuff -= 8;
1227         tld = namesuff + 1;
1228         limit = 3;
1229         }
1230       else if (namesuff - 4 > name && strcmpic(namesuff - 4, US".ip6.arpa") == 0)
1231         {
1232         namesuff -= 4;
1233         tld = namesuff + 1;
1234         ipv6 = TRUE;
1235         limit = 3;
1236         }
1237
1238     DEBUG(D_dns) debug_printf("CSA TLD %s\n", tld);
1239
1240     /* Do not perform the search if the top level or 2nd level domains do not
1241     exist. This is quite common, and when it occurs all the search queries would
1242     go to the root or TLD name servers, which is not friendly. So we check the
1243     AUTHORITY section; if it contains the root's SOA record or the TLD's SOA then
1244     the TLD or the 2LD (respectively) doesn't exist and we can skip the search.
1245     If the TLD and the 2LD exist but the explicit CSA record lookup failed, then
1246     the AUTHORITY SOA will be the 2LD's or a subdomain thereof. */
1247
1248     if (rc == DNS_NOMATCH) return DNS_NOMATCH;
1249
1250     for (i = 0; i < limit; i++)
1251       {
1252       if (ipv6)
1253         {
1254         /* Scan through the IPv6 reverse DNS in chunks of 16 bits worth of IP
1255         address, i.e. 4 hex chars and 4 dots, i.e. 8 chars. */
1256         namesuff -= 8;
1257         if (namesuff <= name) return DNS_NOMATCH;
1258         }
1259       else
1260         /* Find the start of the preceding domain name label. */
1261         do
1262           if (--namesuff <= name) return DNS_NOMATCH;
1263         while (*namesuff != '.');
1264
1265       DEBUG(D_dns) debug_printf("CSA parent search at %s\n", namesuff + 1);
1266
1267       srvname = string_sprintf("_client._smtp.%s", namesuff + 1);
1268       rc = dns_lookup(dnsa, srvname, T_SRV, NULL);
1269       if (rc == DNS_AGAIN) return rc;
1270       if (rc != DNS_SUCCEED) continue;
1271
1272       /* Check that the SRV record we have found is worth returning. We don't
1273       just return the first one we find, because some lower level SRV record
1274       might make stricter assertions than its parent domain. */
1275
1276       for (rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS);
1277            rr; rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)) if (rr->type == T_SRV)
1278         {
1279         const uschar * p = rr->data;
1280
1281         /* Extract the numerical SRV fields (p is incremented) */
1282         if (rr_bad_size(rr, 3 * sizeof(uint16_t))) continue;
1283         GETSHORT(priority, p);
1284         GETSHORT(dummy_weight, p);
1285         GETSHORT(port, p);
1286
1287         /* Check the CSA version number */
1288         if (priority != 1) continue;
1289
1290         /* If it's making an interesting assertion, return this response. */
1291         if (port & 1)
1292           {
1293           *fully_qualified_name = namesuff + 1;
1294           return DNS_SUCCEED;
1295           }
1296         }
1297       }
1298     return DNS_NOMATCH;
1299     }
1300
1301   default:
1302     if (type >= 0)
1303       return dns_lookup(dnsa, name, type, fully_qualified_name);
1304   }
1305
1306 /* Control should never reach here */
1307
1308 return DNS_FAIL;
1309 }
1310
1311
1312
1313
1314
1315 /*************************************************
1316 *          Get address(es) from DNS record       *
1317 *************************************************/
1318
1319 /* The record type is either T_A for an IPv4 address or T_AAAA for an IPv6 address.
1320
1321 Argument:
1322   dnsa       the DNS answer block
1323   rr         the RR
1324
1325 Returns:     pointer to a chain of dns_address items; NULL when the dnsa was overrun
1326 */
1327
1328 dns_address *
1329 dns_address_from_rr(dns_answer *dnsa, dns_record *rr)
1330 {
1331 dns_address * yield = NULL;
1332 uschar * dnsa_lim = dnsa->answer + dnsa->answerlen;
1333
1334 if (rr->type == T_A)
1335   {
1336   uschar *p = US rr->data;
1337   if (p + 4 <= dnsa_lim)
1338     {
1339     /* the IP is not regarded as tainted */
1340     yield = store_get(sizeof(dns_address) + 20, GET_UNTAINTED);
1341     (void)sprintf(CS yield->address, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
1342     yield->next = NULL;
1343     }
1344   }
1345
1346 #if HAVE_IPV6
1347
1348 else
1349   {
1350   if (rr->data + 16 <= dnsa_lim)
1351     {
1352     struct in6_addr in6;
1353     for (int i = 0; i < 16; i++) in6.s6_addr[i] = rr->data[i];
1354     yield = store_get(sizeof(dns_address) + 50, GET_UNTAINTED);
1355     inet_ntop(AF_INET6, &in6, CS yield->address, 50);
1356     yield->next = NULL;
1357     }
1358   }
1359 #endif  /* HAVE_IPV6 */
1360
1361 return yield;
1362 }
1363
1364
1365
1366 void
1367 dns_pattern_init(void)
1368 {
1369 if (check_dns_names_pattern[0] != 0 && !regex_check_dns_names)
1370   regex_check_dns_names =
1371     regex_must_compile(check_dns_names_pattern, MCS_NOFLAGS, TRUE);
1372 }
1373
1374 /* vi: aw ai sw=2
1375 */
1376 /* End of dns.c */