spurious compiler warning of unused var fix
[exim.git] / src / src / dns.c
CommitLineData
059ec3d9
PH
1/*************************************************
2* Exim - an Internet mail transport agent *
3*************************************************/
4
0a49a7a4 5/* Copyright (c) University of Cambridge 1995 - 2009 */
059ec3d9
PH
6/* See the file NOTICE for conditions of use and distribution. */
7
8/* Functions for interfacing with the DNS. */
9
10#include "exim.h"
11
12
13/* Function declaration needed for mutual recursion when A6 records
14are supported. */
15
16#if HAVE_IPV6
17#ifdef SUPPORT_A6
18static void dns_complete_a6(dns_address ***, dns_answer *, dns_record *,
19 int, uschar *);
20#endif
21#endif
22
23
bef5a11f
PH
24/*************************************************
25* Fake DNS resolver *
26*************************************************/
27
28/* This function is called instead of res_search() when Exim is running in its
29test harness. It recognizes some special domain names, and uses them to force
433a2980
PH
30failure and retry responses (optionally with a delay). Otherwise, it calls an
31external utility that mocks-up a nameserver, if it can find the utility.
32If not, it passes its arguments on to res_search(). The fake nameserver may
33also return a code specifying that the name should be passed on.
bef5a11f
PH
34
35Background: the original test suite required a real nameserver to carry the
e7726cbf
PH
36test zones, whereas the new test suit has the fake server for portability. This
37code supports both.
bef5a11f
PH
38
39Arguments:
e7726cbf 40 domain the domain name
bef5a11f
PH
41 type the DNS record type
42 answerptr where to put the answer
43 size size of the answer area
44
45Returns: length of returned data, or -1 on error (h_errno set)
46*/
47
48static int
e7726cbf 49fakens_search(uschar *domain, int type, uschar *answerptr, int size)
bef5a11f 50{
e7726cbf 51int len = Ustrlen(domain);
433a2980 52int asize = size; /* Locally modified */
e7726cbf
PH
53uschar *endname;
54uschar name[256];
433a2980
PH
55uschar utilname[256];
56uschar *aptr = answerptr; /* Locally modified */
57struct stat statbuf;
58
59/* Remove terminating dot. */
e7726cbf
PH
60
61if (domain[len - 1] == '.') len--;
62Ustrncpy(name, domain, len);
63name[len] = 0;
64endname = name + len;
bef5a11f 65
433a2980
PH
66/* This code, for forcing TRY_AGAIN and NO_RECOVERY, is here so that it works
67for the old test suite that uses a real nameserver. When the old test suite is
68eventually abandoned, this code could be moved into the fakens utility. */
69
bef5a11f
PH
70if (len >= 14 && Ustrcmp(endname - 14, "test.again.dns") == 0)
71 {
72 int delay = Uatoi(name); /* digits at the start of the name */
73 DEBUG(D_dns) debug_printf("Return from DNS lookup of %s (%s) faked for testing\n",
74 name, dns_text_type(type));
75 if (delay > 0)
76 {
77 DEBUG(D_dns) debug_printf("delaying %d seconds\n", delay);
78 sleep(delay);
79 }
80 h_errno = TRY_AGAIN;
81 return -1;
82 }
83
84if (len >= 13 && Ustrcmp(endname - 13, "test.fail.dns") == 0)
85 {
86 DEBUG(D_dns) debug_printf("Return from DNS lookup of %s (%s) faked for testing\n",
87 name, dns_text_type(type));
88 h_errno = NO_RECOVERY;
89 return -1;
90 }
91
433a2980
PH
92/* Look for the fakens utility, and if it exists, call it. */
93
94(void)string_format(utilname, sizeof(utilname), "%s/../bin/fakens",
95 spool_directory);
96
97if (stat(CS utilname, &statbuf) >= 0)
bef5a11f 98 {
433a2980
PH
99 pid_t pid;
100 int infd, outfd, rc;
101 uschar *argv[5];
102
103 DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) using fakens\n",
104 name, dns_text_type(type));
105
106 argv[0] = utilname;
107 argv[1] = spool_directory;
108 argv[2] = name;
109 argv[3] = dns_text_type(type);
110 argv[4] = NULL;
111
112 pid = child_open(argv, NULL, 0000, &infd, &outfd, FALSE);
113 if (pid < 0)
114 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to run fakens: %s",
115 strerror(errno));
116
117 len = 0;
118 rc = -1;
119 while (asize > 0 && (rc = read(outfd, aptr, asize)) > 0)
120 {
121 len += rc;
122 aptr += rc; /* Don't modify the actual arguments, because they */
123 asize -= rc; /* may need to be passed on to res_search(). */
124 }
bef5a11f 125
433a2980
PH
126 if (rc < 0)
127 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "read from fakens failed: %s",
128 strerror(errno));
bef5a11f 129
433a2980 130 switch(child_close(pid, 0))
bef5a11f 131 {
433a2980
PH
132 case 0: return len;
133 case 1: h_errno = HOST_NOT_FOUND; return -1;
134 case 2: h_errno = TRY_AGAIN; return -1;
135 default:
136 case 3: h_errno = NO_RECOVERY; return -1;
137 case 4: h_errno = NO_DATA; return -1;
138 case 5: /* Pass on to res_search() */
139 DEBUG(D_dns) debug_printf("fakens returned PASS_ON\n");
bef5a11f
PH
140 }
141 }
142
433a2980 143/* fakens utility not found, or it returned "pass on" */
bef5a11f 144
433a2980 145DEBUG(D_dns) debug_printf("passing %s on to res_search()\n", domain);
e7726cbf
PH
146
147return res_search(CS domain, C_IN, type, answerptr, size);
bef5a11f
PH
148}
149
150
059ec3d9
PH
151
152/*************************************************
153* Initialize and configure resolver *
154*************************************************/
155
156/* Initialize the resolver and the storage for holding DNS answers if this is
157the first time we have been here, and set the resolver options.
158
159Arguments:
160 qualify_single TRUE to set the RES_DEFNAMES option
161 search_parents TRUE to set the RES_DNSRCH option
162
163Returns: nothing
164*/
165
166void
167dns_init(BOOL qualify_single, BOOL search_parents)
168{
169if ((_res.options & RES_INIT) == 0)
170 {
171 DEBUG(D_resolver) _res.options |= RES_DEBUG; /* For Cygwin */
172 res_init();
173 DEBUG(D_resolver) _res.options |= RES_DEBUG;
174 }
175
176_res.options &= ~(RES_DNSRCH | RES_DEFNAMES);
177_res.options |= (qualify_single? RES_DEFNAMES : 0) |
178 (search_parents? RES_DNSRCH : 0);
179if (dns_retrans > 0) _res.retrans = dns_retrans;
180if (dns_retry > 0) _res.retry = dns_retry;
e97d1f08
PP
181
182#ifdef RES_USE_EDNS0
183if (dns_use_edns0 >= 0)
184 {
185 if (dns_use_edns0)
186 _res.options |= RES_USE_EDNS0;
187 else
188 _res.options &= ~RES_USE_EDNS0;
189 DEBUG(D_resolver)
190 debug_printf("Coerced resolver EDNS0 support %s.\n",
191 dns_use_edns0 ? "on" : "off");
192 }
193#else
194if (dns_use_edns0 >= 0)
195 DEBUG(D_resolver)
196 debug_printf("Unable to %sset EDNS0 without resolver support.\n",
197 dns_use_edns0 ? "" : "un");
198#endif
059ec3d9
PH
199}
200
201
202
203/*************************************************
204* Build key name for PTR records *
205*************************************************/
206
207/* This function inverts an IP address and adds the relevant domain, to produce
208a name that can be used to look up PTR records.
209
210Arguments:
211 string the IP address as a string
212 buffer a suitable buffer, long enough to hold the result
213
214Returns: nothing
215*/
216
217void
218dns_build_reverse(uschar *string, uschar *buffer)
219{
220uschar *p = string + Ustrlen(string);
221uschar *pp = buffer;
222
223/* Handle IPv4 address */
224
225#if HAVE_IPV6
226if (Ustrchr(string, ':') == NULL)
227#endif
228 {
229 int i;
230 for (i = 0; i < 4; i++)
231 {
232 uschar *ppp = p;
233 while (ppp > string && ppp[-1] != '.') ppp--;
234 Ustrncpy(pp, ppp, p - ppp);
235 pp += p - ppp;
236 *pp++ = '.';
237 p = ppp - 1;
238 }
239 Ustrcpy(pp, "in-addr.arpa");
240 }
241
242/* Handle IPv6 address; convert to binary so as to fill out any
243abbreviation in the textual form. */
244
245#if HAVE_IPV6
246else
247 {
248 int i;
249 int v6[4];
250 (void)host_aton(string, v6);
251
252 /* The original specification for IPv6 reverse lookup was to invert each
253 nibble, and look in the ip6.int domain. The domain was subsequently
254 changed to ip6.arpa. */
255
256 for (i = 3; i >= 0; i--)
257 {
258 int j;
259 for (j = 0; j < 32; j += 4)
260 {
261 sprintf(CS pp, "%x.", (v6[i] >> j) & 15);
262 pp += 2;
263 }
264 }
265 Ustrcpy(pp, "ip6.arpa.");
266
267 /* Another way of doing IPv6 reverse lookups was proposed in conjunction
268 with A6 records. However, it fell out of favour when they did. The
269 alternative was to construct a binary key, and look in ip6.arpa. I tried
270 to make this code do that, but I could not make it work on Solaris 8. The
271 resolver seems to lose the initial backslash somehow. However, now that
272 this style of reverse lookup has been dropped, it doesn't matter. These
273 lines are left here purely for historical interest. */
274
275 /**************************************************
276 Ustrcpy(pp, "\\[x");
277 pp += 3;
278
279 for (i = 0; i < 4; i++)
280 {
281 sprintf(pp, "%08X", v6[i]);
282 pp += 8;
283 }
284 Ustrcpy(pp, "].ip6.arpa.");
285 **************************************************/
286
287 }
288#endif
289}
290
291
292
293
294/*************************************************
295* Get next DNS record from answer block *
296*************************************************/
297
298/* Call this with reset == RESET_ANSWERS to scan the answer block, reset ==
e5a9dba6
PH
299RESET_AUTHORITY to scan the authority records, reset == RESET_ADDITIONAL to
300scan the additional records, and reset == RESET_NEXT to get the next record.
301The result is in static storage which must be copied if it is to be preserved.
059ec3d9
PH
302
303Arguments:
304 dnsa pointer to dns answer block
305 dnss pointer to dns scan block
306 reset option specifing what portion to scan, as described above
307
308Returns: next dns record, or NULL when no more
309*/
310
311dns_record *
312dns_next_rr(dns_answer *dnsa, dns_scan *dnss, int reset)
313{
314HEADER *h = (HEADER *)dnsa->answer;
315int namelen;
316
317/* Reset the saved data when requested to, and skip to the first required RR */
318
319if (reset != RESET_NEXT)
320 {
321 dnss->rrcount = ntohs(h->qdcount);
322 dnss->aptr = dnsa->answer + sizeof(HEADER);
323
324 /* Skip over questions; failure to expand the name just gives up */
325
326 while (dnss->rrcount-- > 0)
327 {
328 namelen = dn_expand(dnsa->answer, dnsa->answer + dnsa->answerlen,
329 dnss->aptr, (DN_EXPAND_ARG4_TYPE) &(dnss->srr.name), DNS_MAXNAME);
330 if (namelen < 0) { dnss->rrcount = 0; return NULL; }
331 dnss->aptr += namelen + 4; /* skip name & type & class */
332 }
333
334 /* Get the number of answer records. */
335
336 dnss->rrcount = ntohs(h->ancount);
337
e5a9dba6
PH
338 /* Skip over answers if we want to look at the authority section. Also skip
339 the NS records (i.e. authority section) if wanting to look at the additional
059ec3d9
PH
340 records. */
341
e5a9dba6
PH
342 if (reset == RESET_ADDITIONAL) dnss->rrcount += ntohs(h->nscount);
343
344 if (reset == RESET_AUTHORITY || reset == RESET_ADDITIONAL)
059ec3d9 345 {
059ec3d9
PH
346 while (dnss->rrcount-- > 0)
347 {
348 namelen = dn_expand(dnsa->answer, dnsa->answer + dnsa->answerlen,
349 dnss->aptr, (DN_EXPAND_ARG4_TYPE) &(dnss->srr.name), DNS_MAXNAME);
350 if (namelen < 0) { dnss->rrcount = 0; return NULL; }
351 dnss->aptr += namelen + 8; /* skip name, type, class & TTL */
352 GETSHORT(dnss->srr.size, dnss->aptr); /* size of data portion */
353 dnss->aptr += dnss->srr.size; /* skip over it */
354 }
e5a9dba6
PH
355 dnss->rrcount = (reset == RESET_AUTHORITY)
356 ? ntohs(h->nscount) : ntohs(h->arcount);
059ec3d9
PH
357 }
358 }
359
059ec3d9
PH
360/* The variable dnss->aptr is now pointing at the next RR, and dnss->rrcount
361contains the number of RR records left. */
362
363if (dnss->rrcount-- <= 0) return NULL;
364
365/* If expanding the RR domain name fails, behave as if no more records
366(something safe). */
367
368namelen = dn_expand(dnsa->answer, dnsa->answer + dnsa->answerlen, dnss->aptr,
369 (DN_EXPAND_ARG4_TYPE) &(dnss->srr.name), DNS_MAXNAME);
370if (namelen < 0) { dnss->rrcount = 0; return NULL; }
371
372/* Move the pointer past the name and fill in the rest of the data structure
373from the following bytes. */
374
375dnss->aptr += namelen;
376GETSHORT(dnss->srr.type, dnss->aptr); /* Record type */
377dnss->aptr += 6; /* Don't want class or TTL */
378GETSHORT(dnss->srr.size, dnss->aptr); /* Size of data portion */
379dnss->srr.data = dnss->aptr; /* The record's data follows */
380dnss->aptr += dnss->srr.size; /* Advance to next RR */
381
382/* Return a pointer to the dns_record structure within the dns_answer. This is
383for convenience so that the scans can use nice-looking for loops. */
384
385return &(dnss->srr);
386}
387
388
389
390
391/*************************************************
392* Turn DNS type into text *
393*************************************************/
394
885ccd3e
PH
395/* Turn the coded record type into a string for printing. All those that Exim
396uses should be included here.
059ec3d9
PH
397
398Argument: record type
399Returns: pointer to string
400*/
401
402uschar *
403dns_text_type(int t)
404{
405switch(t)
406 {
33397d19
PH
407 case T_A: return US"A";
408 case T_MX: return US"MX";
409 case T_AAAA: return US"AAAA";
410 case T_A6: return US"A6";
411 case T_TXT: return US"TXT";
412 case T_PTR: return US"PTR";
885ccd3e 413 case T_SOA: return US"SOA";
33397d19
PH
414 case T_SRV: return US"SRV";
415 case T_NS: return US"NS";
8e669ac1 416 case T_CNAME: return US"CNAME";
33397d19 417 default: return US"?";
059ec3d9
PH
418 }
419}
420
421
422
423/*************************************************
424* Cache a failed DNS lookup result *
425*************************************************/
426
427/* We cache failed lookup results so as not to experience timeouts many
428times for the same domain. We need to retain the resolver options because they
429may change. For successful lookups, we rely on resolver and/or name server
430caching.
431
432Arguments:
433 name the domain name
434 type the lookup type
435 rc the return code
436
437Returns: the return code
438*/
439
440static int
441dns_return(uschar *name, int type, int rc)
442{
443tree_node *node = store_get_perm(sizeof(tree_node) + 290);
444sprintf(CS node->name, "%.255s-%s-%lx", name, dns_text_type(type),
445 _res.options);
446node->data.val = rc;
447(void)tree_insertnode(&tree_dns_fails, node);
448return rc;
449}
450
451
452
453/*************************************************
454* Do basic DNS lookup *
455*************************************************/
456
457/* Call the resolver to look up the given domain name, using the given type,
458and check the result. The error code TRY_AGAIN is documented as meaning "non-
459Authoritive Host not found, or SERVERFAIL". Sometimes there are badly set
460up nameservers that produce this error continually, so there is the option of
461providing a list of domains for which this is treated as a non-existent
462host.
463
464Arguments:
465 dnsa pointer to dns_answer structure
466 name name to look up
467 type type of DNS record required (T_A, T_MX, etc)
468
469Returns: DNS_SUCCEED successful lookup
470 DNS_NOMATCH name not found (NXDOMAIN)
471 or name contains illegal characters (if checking)
30e18802 472 or name is an IP address (for IP address lookup)
059ec3d9
PH
473 DNS_NODATA domain exists, but no data for this type (NODATA)
474 DNS_AGAIN soft failure, try again later
475 DNS_FAIL DNS failure
476*/
477
478int
479dns_basic_lookup(dns_answer *dnsa, uschar *name, int type)
480{
481#ifndef STAND_ALONE
7156b1ef 482int rc = -1;
059ec3d9
PH
483uschar *save;
484#endif
485
486tree_node *previous;
487uschar node_name[290];
488
489/* DNS lookup failures of any kind are cached in a tree. This is mainly so that
490a timeout on one domain doesn't happen time and time again for messages that
491have many addresses in the same domain. We rely on the resolver and name server
492caching for successful lookups. */
493
494sprintf(CS node_name, "%.255s-%s-%lx", name, dns_text_type(type),
495 _res.options);
496previous = tree_search(tree_dns_fails, node_name);
497if (previous != NULL)
498 {
499 DEBUG(D_dns) debug_printf("DNS lookup of %.255s-%s: using cached value %s\n",
500 name, dns_text_type(type),
501 (previous->data.val == DNS_NOMATCH)? "DNS_NOMATCH" :
502 (previous->data.val == DNS_NODATA)? "DNS_NODATA" :
503 (previous->data.val == DNS_AGAIN)? "DNS_AGAIN" :
504 (previous->data.val == DNS_FAIL)? "DNS_FAIL" : "??");
505 return previous->data.val;
506 }
507
059ec3d9
PH
508/* If configured, check the hygene of the name passed to lookup. Otherwise,
509although DNS lookups may give REFUSED at the lower level, some resolvers
510turn this into TRY_AGAIN, which is silly. Give a NOMATCH return, since such
511domains cannot be in the DNS. The check is now done by a regular expression;
512give it space for substring storage to save it having to get its own if the
513regex has substrings that are used - the default uses a conditional.
514
515This test is omitted for PTR records. These occur only in calls from the dnsdb
516lookup, which constructs the names itself, so they should be OK. Besides,
517bitstring labels don't conform to normal name syntax. (But the aren't used any
518more.)
519
520For SRV records, we omit the initial _smtp._tcp. components at the start. */
521
522#ifndef STAND_ALONE /* Omit this for stand-alone tests */
523
482d1455 524if (check_dns_names_pattern[0] != 0 && type != T_PTR && type != T_TXT)
059ec3d9
PH
525 {
526 uschar *checkname = name;
527 int ovector[3*(EXPAND_MAXN+1)];
528
529 if (regex_check_dns_names == NULL)
530 regex_check_dns_names =
531 regex_must_compile(check_dns_names_pattern, FALSE, TRUE);
532
533 /* For an SRV lookup, skip over the first two components (the service and
534 protocol names, which both start with an underscore). */
535
536 if (type == T_SRV)
537 {
538 while (*checkname++ != '.');
539 while (*checkname++ != '.');
540 }
541
542 if (pcre_exec(regex_check_dns_names, NULL, CS checkname, Ustrlen(checkname),
543 0, PCRE_EOPT, ovector, sizeof(ovector)/sizeof(int)) < 0)
544 {
545 DEBUG(D_dns)
546 debug_printf("DNS name syntax check failed: %s (%s)\n", name,
547 dns_text_type(type));
548 host_find_failed_syntax = TRUE;
549 return DNS_NOMATCH;
550 }
551 }
552
553#endif /* STAND_ALONE */
554
555/* Call the resolver; for an overlong response, res_search() will return the
bef5a11f
PH
556number of bytes the message would need, so we need to check for this case. The
557effect is to truncate overlong data.
558
30e18802
PH
559On some systems, res_search() will recognize "A-for-A" queries and return
560the IP address instead of returning -1 with h_error=HOST_NOT_FOUND. Some
561nameservers are also believed to do this. It is, of course, contrary to the
562specification of the DNS, so we lock it out. */
563
564if ((
565 #ifdef SUPPORT_A6
566 type == T_A6 ||
567 #endif
568 type == T_A || type == T_AAAA) &&
569 string_is_ip_address(name, NULL) != 0)
570 return DNS_NOMATCH;
571
572/* If we are running in the test harness, instead of calling the normal resolver
bef5a11f
PH
573(res_search), we call fakens_search(), which recognizes certain special
574domains, and interfaces to a fake nameserver for certain special zones. */
575
576if (running_in_test_harness)
577 dnsa->answerlen = fakens_search(name, type, dnsa->answer, MAXPACKET);
578else
579 dnsa->answerlen = res_search(CS name, C_IN, type, dnsa->answer, MAXPACKET);
059ec3d9 580
80a47a2c
TK
581if (dnsa->answerlen > MAXPACKET)
582 {
583 DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) resulted in overlong packet (size %d), truncating to %d.\n",
584 name, dns_text_type(type), dnsa->answerlen, MAXPACKET);
585 dnsa->answerlen = MAXPACKET;
586 }
059ec3d9
PH
587
588if (dnsa->answerlen < 0) switch (h_errno)
589 {
590 case HOST_NOT_FOUND:
591 DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave HOST_NOT_FOUND\n"
592 "returning DNS_NOMATCH\n", name, dns_text_type(type));
593 return dns_return(name, type, DNS_NOMATCH);
594
595 case TRY_AGAIN:
596 DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave TRY_AGAIN\n",
597 name, dns_text_type(type));
598
599 /* Cut this out for various test programs */
600 #ifndef STAND_ALONE
601 save = deliver_domain;
602 deliver_domain = name; /* set $domain */
603 rc = match_isinlist(name, &dns_again_means_nonexist, 0, NULL, NULL,
604 MCL_DOMAIN, TRUE, NULL);
605 deliver_domain = save;
606 if (rc != OK)
607 {
608 DEBUG(D_dns) debug_printf("returning DNS_AGAIN\n");
609 return dns_return(name, type, DNS_AGAIN);
610 }
611 DEBUG(D_dns) debug_printf("%s is in dns_again_means_nonexist: returning "
612 "DNS_NOMATCH\n", name);
613 return dns_return(name, type, DNS_NOMATCH);
614
615 #else /* For stand-alone tests */
616 return dns_return(name, type, DNS_AGAIN);
617 #endif
618
619 case NO_RECOVERY:
620 DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave NO_RECOVERY\n"
621 "returning DNS_FAIL\n", name, dns_text_type(type));
622 return dns_return(name, type, DNS_FAIL);
623
624 case NO_DATA:
625 DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave NO_DATA\n"
626 "returning DNS_NODATA\n", name, dns_text_type(type));
627 return dns_return(name, type, DNS_NODATA);
628
629 default:
630 DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave unknown DNS error %d\n"
631 "returning DNS_FAIL\n", name, dns_text_type(type), h_errno);
632 return dns_return(name, type, DNS_FAIL);
633 }
634
635DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) succeeded\n",
636 name, dns_text_type(type));
637
638return DNS_SUCCEED;
639}
640
641
642
643
644/************************************************
645* Do a DNS lookup and handle CNAMES *
646************************************************/
647
648/* Look up the given domain name, using the given type. Follow CNAMEs if
649necessary, but only so many times. There aren't supposed to be CNAME chains in
650the DNS, but you are supposed to cope with them if you find them.
651
652The assumption is made that if the resolver gives back records of the
653requested type *and* a CNAME, we don't need to make another call to look up
654the CNAME. I can't see how it could return only some of the right records. If
655it's done a CNAME lookup in the past, it will have all of them; if not, it
656won't return any.
657
658If fully_qualified_name is not NULL, set it to point to the full name
659returned by the resolver, if this is different to what it is given, unless
660the returned name starts with "*" as some nameservers seem to be returning
661wildcards in this form.
662
663Arguments:
664 dnsa pointer to dns_answer structure
665 name domain name to look up
666 type DNS record type (T_A, T_MX, etc)
667 fully_qualified_name if not NULL, return the returned name here if its
668 contents are different (i.e. it must be preset)
669
670Returns: DNS_SUCCEED successful lookup
671 DNS_NOMATCH name not found
672 DNS_NODATA no data found
673 DNS_AGAIN soft failure, try again later
674 DNS_FAIL DNS failure
675*/
676
677int
678dns_lookup(dns_answer *dnsa, uschar *name, int type, uschar **fully_qualified_name)
679{
680int i;
681uschar *orig_name = name;
682
683/* Loop to follow CNAME chains so far, but no further... */
684
685for (i = 0; i < 10; i++)
686 {
687 uschar data[256];
688 dns_record *rr, cname_rr, type_rr;
689 dns_scan dnss;
690 int datalen, rc;
691
692 /* DNS lookup failures get passed straight back. */
693
694 if ((rc = dns_basic_lookup(dnsa, name, type)) != DNS_SUCCEED) return rc;
695
696 /* We should have either records of the required type, or a CNAME record,
697 or both. We need to know whether both exist for getting the fully qualified
698 name, but avoid scanning more than necessary. Note that we must copy the
699 contents of any rr blocks returned by dns_next_rr() as they use the same
700 area in the dnsa block. */
701
702 cname_rr.data = type_rr.data = NULL;
703 for (rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS);
704 rr != NULL;
705 rr = dns_next_rr(dnsa, &dnss, RESET_NEXT))
706 {
707 if (rr->type == type)
708 {
709 if (type_rr.data == NULL) type_rr = *rr;
710 if (cname_rr.data != NULL) break;
711 }
712 else if (rr->type == T_CNAME) cname_rr = *rr;
713 }
714
a2042e78
PH
715 /* For the first time round this loop, if a CNAME was found, take the fully
716 qualified name from it; otherwise from the first data record, if present. */
059ec3d9 717
a2042e78 718 if (i == 0 && fully_qualified_name != NULL)
059ec3d9
PH
719 {
720 if (cname_rr.data != NULL)
721 {
722 if (Ustrcmp(cname_rr.name, *fully_qualified_name) != 0 &&
723 cname_rr.name[0] != '*')
724 *fully_qualified_name = string_copy_dnsdomain(cname_rr.name);
725 }
726 else if (type_rr.data != NULL)
727 {
75e0e026
PH
728 if (Ustrcmp(type_rr.name, *fully_qualified_name) != 0 &&
729 type_rr.name[0] != '*')
730 *fully_qualified_name = string_copy_dnsdomain(type_rr.name);
059ec3d9
PH
731 }
732 }
733
734 /* If any data records of the correct type were found, we are done. */
735
736 if (type_rr.data != NULL) return DNS_SUCCEED;
737
738 /* If there are no data records, we need to re-scan the DNS using the
739 domain given in the CNAME record, which should exist (otherwise we should
740 have had a failure from dns_lookup). However code against the possibility of
741 its not existing. */
742
743 if (cname_rr.data == NULL) return DNS_FAIL;
744 datalen = dn_expand(dnsa->answer, dnsa->answer + dnsa->answerlen,
745 cname_rr.data, (DN_EXPAND_ARG4_TYPE)data, 256);
746 if (datalen < 0) return DNS_FAIL;
747 name = data;
a2042e78
PH
748
749 DEBUG(D_dns) debug_printf("CNAME found: change to %s\n", name);
059ec3d9
PH
750 } /* Loop back to do another lookup */
751
752/*Control reaches here after 10 times round the CNAME loop. Something isn't
753right... */
754
755log_write(0, LOG_MAIN, "CNAME loop for %s encountered", orig_name);
756return DNS_FAIL;
757}
758
759
760
33397d19
PH
761
762
763
764/************************************************
765* Do a DNS lookup and handle virtual types *
766************************************************/
767
8e669ac1
PH
768/* This function handles some invented "lookup types" that synthesize feature
769not available in the basic types. The special types all have negative values.
33397d19
PH
770Positive type values are passed straight on to dns_lookup().
771
772Arguments:
773 dnsa pointer to dns_answer structure
774 name domain name to look up
775 type DNS record type (T_A, T_MX, etc or a "special")
776 fully_qualified_name if not NULL, return the returned name here if its
777 contents are different (i.e. it must be preset)
778
779Returns: DNS_SUCCEED successful lookup
780 DNS_NOMATCH name not found
781 DNS_NODATA no data found
782 DNS_AGAIN soft failure, try again later
783 DNS_FAIL DNS failure
784*/
785
786int
8e669ac1 787dns_special_lookup(dns_answer *dnsa, uschar *name, int type,
33397d19
PH
788 uschar **fully_qualified_name)
789{
790if (type >= 0) return dns_lookup(dnsa, name, type, fully_qualified_name);
791
ea3bc19b
PH
792/* The "mx hosts only" type doesn't require any special action here */
793
794if (type == T_MXH) return dns_lookup(dnsa, name, T_MX, fully_qualified_name);
795
8e669ac1 796/* Find nameservers for the domain or the nearest enclosing zone, excluding the
33397d19
PH
797root servers. */
798
799if (type == T_ZNS)
800 {
801 uschar *d = name;
802 while (d != 0)
803 {
804 int rc = dns_lookup(dnsa, d, T_NS, fully_qualified_name);
805 if (rc != DNS_NOMATCH && rc != DNS_NODATA) return rc;
806 while (*d != 0 && *d != '.') d++;
8e669ac1 807 if (*d++ == 0) break;
33397d19 808 }
8e669ac1
PH
809 return DNS_NOMATCH;
810 }
33397d19 811
e5a9dba6
PH
812/* Try to look up the Client SMTP Authorization SRV record for the name. If
813there isn't one, search from the top downwards for a CSA record in a parent
814domain, which might be making assertions about subdomains. If we find a record
815we set fully_qualified_name to whichever lookup succeeded, so that the caller
816can tell whether to look at the explicit authorization field or the subdomain
817assertion field. */
818
819if (type == T_CSA)
820 {
821 uschar *srvname, *namesuff, *tld, *p;
822 int priority, weight, port;
823 int limit, rc, i;
824 BOOL ipv6;
825 dns_record *rr;
826 dns_scan dnss;
827
828 DEBUG(D_dns) debug_printf("CSA lookup of %s\n", name);
829
830 srvname = string_sprintf("_client._smtp.%s", name);
831 rc = dns_lookup(dnsa, srvname, T_SRV, NULL);
832 if (rc == DNS_SUCCEED || rc == DNS_AGAIN)
833 {
834 if (rc == DNS_SUCCEED) *fully_qualified_name = name;
835 return rc;
836 }
837
838 /* Search for CSA subdomain assertion SRV records from the top downwards,
839 starting with the 2nd level domain. This order maximizes cache-friendliness.
840 We skip the top level domains to avoid loading their nameservers and because
841 we know they'll never have CSA SRV records. */
842
843 namesuff = Ustrrchr(name, '.');
844 if (namesuff == NULL) return DNS_NOMATCH;
845 tld = namesuff + 1;
846 ipv6 = FALSE;
847 limit = dns_csa_search_limit;
848
849 /* Use more appropriate search parameters if we are in the reverse DNS. */
850
851 if (strcmpic(namesuff, US".arpa") == 0)
852 {
853 if (namesuff - 8 > name && strcmpic(namesuff - 8, US".in-addr.arpa") == 0)
854 {
855 namesuff -= 8;
856 tld = namesuff + 1;
857 limit = 3;
858 }
859 else if (namesuff - 4 > name && strcmpic(namesuff - 4, US".ip6.arpa") == 0)
860 {
861 namesuff -= 4;
862 tld = namesuff + 1;
863 ipv6 = TRUE;
864 limit = 3;
865 }
866 }
867
868 DEBUG(D_dns) debug_printf("CSA TLD %s\n", tld);
869
870 /* Do not perform the search if the top level or 2nd level domains do not
871 exist. This is quite common, and when it occurs all the search queries would
872 go to the root or TLD name servers, which is not friendly. So we check the
873 AUTHORITY section; if it contains the root's SOA record or the TLD's SOA then
874 the TLD or the 2LD (respectively) doesn't exist and we can skip the search.
875 If the TLD and the 2LD exist but the explicit CSA record lookup failed, then
876 the AUTHORITY SOA will be the 2LD's or a subdomain thereof. */
877
878 if (rc == DNS_NOMATCH)
879 {
880 /* This is really gross. The successful return value from res_search() is
881 the packet length, which is stored in dnsa->answerlen. If we get a
882 negative DNS reply then res_search() returns -1, which causes the bounds
883 checks for name decompression to fail when it is treated as a packet
884 length, which in turn causes the authority search to fail. The correct
885 packet length has been lost inside libresolv, so we have to guess a
886 replacement value. (The only way to fix this properly would be to
887 re-implement res_search() and res_query() so that they don't muddle their
888 success and packet length return values.) For added safety we only reset
889 the packet length if the packet header looks plausible. */
890
891 HEADER *h = (HEADER *)dnsa->answer;
892 if (h->qr == 1 && h->opcode == QUERY && h->tc == 0
893 && (h->rcode == NOERROR || h->rcode == NXDOMAIN)
894 && ntohs(h->qdcount) == 1 && ntohs(h->ancount) == 0
895 && ntohs(h->nscount) >= 1)
896 dnsa->answerlen = MAXPACKET;
897
898 for (rr = dns_next_rr(dnsa, &dnss, RESET_AUTHORITY);
899 rr != NULL;
900 rr = dns_next_rr(dnsa, &dnss, RESET_NEXT))
901 if (rr->type != T_SOA) continue;
902 else if (strcmpic(rr->name, US"") == 0 ||
903 strcmpic(rr->name, tld) == 0) return DNS_NOMATCH;
904 else break;
905 }
906
907 for (i = 0; i < limit; i++)
908 {
909 if (ipv6)
910 {
911 /* Scan through the IPv6 reverse DNS in chunks of 16 bits worth of IP
912 address, i.e. 4 hex chars and 4 dots, i.e. 8 chars. */
913 namesuff -= 8;
914 if (namesuff <= name) return DNS_NOMATCH;
915 }
916 else
917 /* Find the start of the preceding domain name label. */
918 do
919 if (--namesuff <= name) return DNS_NOMATCH;
920 while (*namesuff != '.');
921
922 DEBUG(D_dns) debug_printf("CSA parent search at %s\n", namesuff + 1);
923
924 srvname = string_sprintf("_client._smtp.%s", namesuff + 1);
925 rc = dns_lookup(dnsa, srvname, T_SRV, NULL);
926 if (rc == DNS_AGAIN) return rc;
927 if (rc != DNS_SUCCEED) continue;
928
929 /* Check that the SRV record we have found is worth returning. We don't
930 just return the first one we find, because some lower level SRV record
931 might make stricter assertions than its parent domain. */
932
933 for (rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS);
934 rr != NULL;
935 rr = dns_next_rr(dnsa, &dnss, RESET_NEXT))
936 {
937 if (rr->type != T_SRV) continue;
938
939 /* Extract the numerical SRV fields (p is incremented) */
940 p = rr->data;
941 GETSHORT(priority, p);
942 GETSHORT(weight, p);
943 GETSHORT(port, p);
944
945 /* Check the CSA version number */
946 if (priority != 1) continue;
947
948 /* If it's making an interesting assertion, return this response. */
949 if (port & 1)
950 {
951 *fully_qualified_name = namesuff + 1;
952 return DNS_SUCCEED;
953 }
954 }
955 }
956 return DNS_NOMATCH;
957 }
958
33397d19
PH
959/* Control should never reach here */
960
961return DNS_FAIL;
962}
963
964
965
059ec3d9
PH
966/* Support for A6 records has been commented out since they were demoted to
967experimental status at IETF 51. */
968
969#if HAVE_IPV6 && defined(SUPPORT_A6)
970
971/*************************************************
972* Search DNS block for prefix RRs *
973*************************************************/
974
975/* Called from dns_complete_a6() to search an additional section or a main
976answer section for required prefix records to complete an IPv6 address obtained
977from an A6 record. For each prefix record, a recursive call to dns_complete_a6
978is made, with a new copy of the address so far.
979
980Arguments:
981 dnsa the DNS answer block
982 which RESET_ADDITIONAL or RESET_ANSWERS
983 name name of prefix record
984 yptrptr pointer to the pointer that points to where to hang the next
985 dns_address structure
986 bits number of bits we have already got
987 bitvec the bits we have already got
988
989Returns: TRUE if any records were found
990*/
991
992static BOOL
993dns_find_prefix(dns_answer *dnsa, int which, uschar *name, dns_address
994 ***yptrptr, int bits, uschar *bitvec)
995{
996BOOL yield = FALSE;
997dns_record *rr;
998dns_scan dnss;
999
1000for (rr = dns_next_rr(dnsa, &dnss, which);
1001 rr != NULL;
1002 rr = dns_next_rr(dnsa, &dnss, RESET_NEXT))
1003 {
1004 uschar cbitvec[16];
1005 if (rr->type != T_A6 || strcmpic(rr->name, name) != 0) continue;
1006 yield = TRUE;
1007 memcpy(cbitvec, bitvec, sizeof(cbitvec));
1008 dns_complete_a6(yptrptr, dnsa, rr, bits, cbitvec);
1009 }
1010
1011return yield;
1012}
1013
1014
1015
1016/*************************************************
1017* Follow chains of A6 records *
1018*************************************************/
1019
1020/* A6 records may be incomplete, with pointers to other records containing more
1021bits of the address. There can be a tree structure, leading to a number of
1022addresses originating from a single initial A6 record.
1023
1024Arguments:
1025 yptrptr pointer to the pointer that points to where to hang the next
1026 dns_address structure
1027 dnsa the current DNS answer block
1028 rr the RR we have at present
1029 bits number of bits we have already got
1030 bitvec the bits we have already got
1031
1032Returns: nothing
1033*/
1034
1035static void
1036dns_complete_a6(dns_address ***yptrptr, dns_answer *dnsa, dns_record *rr,
1037 int bits, uschar *bitvec)
1038{
1039static uschar bitmask[] = { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80 };
1040uschar *p = (uschar *)(rr->data);
1041int prefix_len, suffix_len;
1042int i, j, k;
1043uschar *chainptr;
1044uschar chain[264];
1045dns_answer cdnsa;
1046
1047/* The prefix length is the first byte. It defines the prefix which is missing
1048from the data in this record as a number of bits. Zero means this is the end of
1049a chain. The suffix is the data in this record; only sufficient bytes to hold
1050it are supplied. There may be zero bytes. We have to ignore trailing bits that
1051we have already obtained from earlier RRs in the chain. */
1052
1053prefix_len = *p++; /* bits */
1054suffix_len = (128 - prefix_len + 7)/8; /* bytes */
1055
1056/* If the prefix in this record is greater than the prefix in the previous
1057record in the chain, we have to ignore the record (RFC 2874). */
1058
1059if (prefix_len > 128 - bits) return;
1060
1061/* In this little loop, the number of bits up to and including the current byte
1062is held in k. If we have none of the bits in this byte, we can just or it into
1063the current data. If we have all of the bits in this byte, we skip it.
1064Otherwise, some masking has to be done. */
1065
1066for (i = suffix_len - 1, j = 15, k = 8; i >= 0; i--)
1067 {
1068 int required = k - bits;
1069 if (required >= 8) bitvec[j] |= p[i];
1070 else if (required > 0) bitvec[j] |= p[i] & bitmask[required];
1071 j--; /* I tried putting these in the "for" statement, but gcc muttered */
1072 k += 8; /* about computed values not being used. */
1073 }
1074
1075/* If the prefix_length is zero, we are at the end of a chain. Build a
1076dns_address item with the current data, hang it onto the end of the chain,
1077adjust the hanging pointer, and we are done. */
1078
1079if (prefix_len == 0)
1080 {
1081 dns_address *new = store_get(sizeof(dns_address) + 50);
1082 inet_ntop(AF_INET6, bitvec, CS new->address, 50);
1083 new->next = NULL;
1084 **yptrptr = new;
1085 *yptrptr = &(new->next);
1086 return;
1087 }
1088
1089/* Prefix length is not zero. Reset the number of bits that we have collected
1090so far, and extract the chain name. */
1091
1092bits = 128 - prefix_len;
1093p += suffix_len;
1094
1095chainptr = chain;
1096while ((i = *p++) != 0)
1097 {
1098 if (chainptr != chain) *chainptr++ = '.';
1099 memcpy(chainptr, p, i);
1100 chainptr += i;
1101 p += i;
1102 }
1103*chainptr = 0;
1104chainptr = chain;
1105
1106/* Now scan the current DNS response record to see if the additional section
1107contains the records we want. This processing can be cut out for testing
1108purposes. */
1109
1110if (dns_find_prefix(dnsa, RESET_ADDITIONAL, chainptr, yptrptr, bits, bitvec))
1111 return;
1112
1113/* No chain records were found in the current DNS response block. Do a new DNS
1114lookup to try to find these records. This opens up the possibility of DNS
1115failures. We ignore them at this point; if all branches of the tree fail, there
1116will be no addresses at the end. */
1117
1118if (dns_lookup(&cdnsa, chainptr, T_A6, NULL) == DNS_SUCCEED)
1119 (void)dns_find_prefix(&cdnsa, RESET_ANSWERS, chainptr, yptrptr, bits, bitvec);
1120}
1121#endif /* HAVE_IPV6 && defined(SUPPORT_A6) */
1122
1123
1124
1125
1126/*************************************************
1127* Get address(es) from DNS record *
1128*************************************************/
1129
1130/* The record type is either T_A for an IPv4 address or T_AAAA (or T_A6 when
1131supported) for an IPv6 address. In the A6 case, there may be several addresses,
1132generated by following chains. A recursive function does all the hard work. A6
1133records now look like passing into history, so the code is only included when
1134explicitly asked for.
1135
1136Argument:
1137 dnsa the DNS answer block
1138 rr the RR
1139
1140Returns: pointer a chain of dns_address items
1141*/
1142
1143dns_address *
1144dns_address_from_rr(dns_answer *dnsa, dns_record *rr)
1145{
1146dns_address *yield = NULL;
1147
1148#if HAVE_IPV6 && defined(SUPPORT_A6)
1149dns_address **yieldptr = &yield;
1150uschar bitvec[16];
1151#else
1152dnsa = dnsa; /* Stop picky compilers warning */
1153#endif
1154
1155if (rr->type == T_A)
1156 {
1157 uschar *p = (uschar *)(rr->data);
1158 yield = store_get(sizeof(dns_address) + 20);
1159 (void)sprintf(CS yield->address, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
1160 yield->next = NULL;
1161 }
1162
1163#if HAVE_IPV6
1164
1165#ifdef SUPPORT_A6
1166else if (rr->type == T_A6)
1167 {
1168 memset(bitvec, 0, sizeof(bitvec));
1169 dns_complete_a6(&yieldptr, dnsa, rr, 0, bitvec);
1170 }
1171#endif /* SUPPORT_A6 */
1172
1173else
1174 {
1175 yield = store_get(sizeof(dns_address) + 50);
1176 inet_ntop(AF_INET6, (uschar *)(rr->data), CS yield->address, 50);
1177 yield->next = NULL;
1178 }
1179#endif /* HAVE_IPV6 */
1180
1181return yield;
1182}
1183
1184/* End of dns.c */