2 * Copyright (c) 1998-2004, 2006, 2010, 2020-2023 Proofpoint, Inc. and its suppliers.
4 * Copyright (c) 1986, 1995-1997 Eric P. Allman. All rights reserved.
5 * Copyright (c) 1988, 1993
6 * The Regents of the University of California. All rights reserved.
8 * By using this file, you agree to the terms and conditions set
9 * forth in the LICENSE file which can be found at the top level of
10 * the sendmail distribution.
18 SM_RCSID("@(#)$Id: domain.c,v 8.205 2013-11-22 20:51:55 ca Exp $ (with name server)")
20 SM_RCSID("@(#)$Id: domain.c,v 8.205 2013-11-22 20:51:55 ca Exp $ (without name server)")
23 #include <sm/sendmail.h>
26 # include <arpa/inet.h>
27 # include "sm_resolve.h"
31 # define SM_NEG_TTL 60 /* "negative" TTL */
36 #include <unicode/uidna.h>
40 # ifndef MXHOSTBUFSIZE
41 # define MXHOSTBUFSIZE (128 * MAXMXHOSTS)
44 static char MXHostBuf[MXHOSTBUFSIZE];
45 # if (MXHOSTBUFSIZE < 2) || (MXHOSTBUFSIZE >= INT_MAX/2)
46 ERROR: _MXHOSTBUFSIZE is out of range
50 # define MAXDNSRCH 6 /* number of possible domains to search */
53 # ifndef RES_DNSRCH_VARIABLE
54 # define RES_DNSRCH_VARIABLE _res.dnsrch
58 # define HFIXEDSZ 12 /* sizeof(HEADER) */
61 # define MAXCNAMEDEPTH 10 /* maximum depth of CNAME recursion */
63 # if defined(__RES) && (__RES >= 19940415)
64 # define RES_UNC_T char *
66 # define RES_UNC_T unsigned char *
69 static int mxrand __P((char *));
70 static int fallbackmxrr __P((int, unsigned short *, char **));
74 static void tlsa_rr_print __P((const unsigned char *, unsigned int));
77 tlsa_rr_print(rr, len)
78 const unsigned char *rr;
86 sm_dprintf("len=%u, %02x-%02x-%02x",
87 len, (int)rr[0], (int)rr[1], (int)rr[2]);
88 l = tTd(8, 8) ? len : 4;
89 for (i = 3; i < l; i++)
90 sm_dprintf(":%02X", (int)rr[i]);
95 ** TLSA_RR_CMP -- Compare two TLSA RRs
98 ** rr1 -- TLSA RR (entry to be added)
99 ** l1 -- length of rr1
101 ** l2 -- length of rr2
105 ** 1: rr1 is unsupported
108 static int tlsa_rr_cmp __P((unsigned char *, int, unsigned char *, int));
111 tlsa_rr_cmp(rr1, l1, rr2, l2)
117 /* temporary #if while investigating the implications of the alternative */
119 unsigned char r1, r2;
121 #endif /* FULL_COMPARE */
123 SM_REQUIRE(NULL != rr1);
124 SM_REQUIRE(NULL != rr2);
131 ** 3: cert/fp must match
132 ** 2: cert/fp must be trust anchor
135 /* preference[]: lower value: higher preference */
140 int preference[] = { 3, 2, 1, 0 };
142 SM_ASSERT(r1 <= SM_ARRAY_SIZE(preference));
143 SM_ASSERT(r2 <= SM_ARRAY_SIZE(preference));
144 return preference[r1] - preference[r2];
157 int preference[] = { 1, 0 };
159 SM_ASSERT(r1 <= SM_ARRAY_SIZE(preference));
160 SM_ASSERT(r2 <= SM_ARRAY_SIZE(preference));
161 return preference[r1] - preference[r2];
175 int preference[] = { 2, 0, 1 };
177 SM_ASSERT(r1 <= SM_ARRAY_SIZE(preference));
178 SM_ASSERT(r2 <= SM_ARRAY_SIZE(preference));
179 return preference[r1] - preference[r2];
182 /* not the same length despite the same type? */
185 cmp = memcmp(rr1, rr2, l1);
189 #else /* FULL_COMPARE */
191 if (l1 == l2 && 0 == memcmp(rr1, rr2, l1))
194 /* new entry is unsupported? -> append */
195 if (TLSA_UNSUPP == dane_tlsa_chk(rr1, l1, "", false))
197 /* current entry is unsupported? -> insert new one */
198 if (TLSA_UNSUPP == dane_tlsa_chk(rr2, l2, "", false))
201 /* default: preserve order */
203 #endif /* FULL_COMPARE */
207 ** TLSAINSERT -- Insert a TLSA RR
210 ** dane_tlsa -- dane_tlsa entry
212 ** pn -- (point to) number of entries
215 ** SM_SUCCESS: rr inserted
216 ** SM_NOTDONE: rr not inserted: exists
217 ** SM_FULL: rr not inserted: no space left
220 static int tlsainsert __P((dane_tlsa_P, RESOURCE_RECORD_T *, int *));
223 tlsainsert(dane_tlsa, rr, pn)
224 dane_tlsa_P dane_tlsa;
225 RESOURCE_RECORD_T *rr;
231 SM_ASSERT(pn != NULL);
232 SM_ASSERT(*pn <= MAX_TLSA_RR);
233 r1 = rr->rr_u.rr_data;
237 for (i = 0; i < *pn; i++)
241 r = tlsa_rr_cmp(r1, l1, dane_tlsa->dane_tlsa_rr[i],
242 dane_tlsa->dane_tlsa_len[i]);
247 sm_dprintf("func=tlsainsert, i=%d, n=%d, status=exists\n", i, *pn);
254 if (*pn + 1 >= MAX_TLSA_RR)
257 SM_FREE(dane_tlsa->dane_tlsa_rr[j]);
258 dane_tlsa->dane_tlsa_len[j] = 0;
263 for (j = MAX_TLSA_RR - 2; j >= i; j--)
265 dane_tlsa->dane_tlsa_rr[j + 1] = dane_tlsa->dane_tlsa_rr[j];
266 dane_tlsa->dane_tlsa_len[j + 1] = dane_tlsa->dane_tlsa_len[j];
268 SM_ASSERT(i < MAX_TLSA_RR);
269 dane_tlsa->dane_tlsa_rr[i] = r1;
270 dane_tlsa->dane_tlsa_len[i] = l1;
272 sm_dprintf("func=tlsainsert, i=%d, n=%d, status=inserted\n", i, *pn);
276 if (*pn + 1 <= MAX_TLSA_RR)
278 dane_tlsa->dane_tlsa_rr[*pn] = r1;
279 dane_tlsa->dane_tlsa_len[*pn] = l1;
282 sm_dprintf("func=tlsainsert, n=%d, status=appended\n", *pn);
287 sm_dprintf("func=tlsainsert, n=%d, status=full\n", *pn);
292 /* hack: instead of copying the data, just "take it over" */
293 rr->rr_u.rr_data = NULL;
299 ** TLSAADD -- add TLSA records to dane_tlsa entry
302 ** name -- key for stab entry (for debugging output)
304 ** dane_tlsa -- dane_tlsa entry
305 ** dnsrc -- DNS lookup return code (h_errno)
306 ** nr -- current number of TLSA records in dane_tlsa entry
307 ** pttl -- (pointer to) TTL (in/out)
308 ** level -- recursion level (CNAMEs)
311 ** new number of TLSA records
313 ** NOTE: the array for TLSA RRs could be "full" which is not
314 ** handled well (yet).
317 static int tlsaadd __P((const char *, DNS_REPLY_T *, dane_tlsa_P, int, int,
318 unsigned int *, int));
321 tlsaadd(name, dr, dane_tlsa, dnsrc, nr, pttl, level)
324 dane_tlsa_P dane_tlsa;
330 RESOURCE_RECORD_T *rr;
337 sm_dprintf("tlsaadd, name=%s, prev=%d, dnsrc=%d\n",
338 name, dane_tlsa->dane_tlsa_dnsrc, dnsrc);
340 /* check previous error and keep the "most important" one? */
341 dane_tlsa->dane_tlsa_dnsrc = dnsrc;
344 *pttl = tTdlevel(8)-110; /* how to make this an option? */
347 /* "else" in #if code above */
353 if (dr->dns_r_h.ad != 1 && Dane == DANE_SECURE) /* not secure? */
357 /* first: try to find TLSA records */
359 for (rr = dr->dns_r_head; rr != NULL; rr = rr->rr_next)
363 if (rr->rr_type != T_TLSA)
365 if (rr->rr_type != T_CNAME && tTd(8, 8))
366 sm_dprintf("tlsaadd: name=%s, type=%s\n", name,
367 dns_type_to_string(rr->rr_type));
370 tlsa_chk = dane_tlsa_chk(rr->rr_u.rr_data, rr->rr_size, name,
372 if (TLSA_UNSUPP == tlsa_chk)
373 TLSA_SET_FL(dane_tlsa, TLSAFLUNS);
374 if (!TLSA_IS_VALID(tlsa_chk))
376 if (TLSA_IS_SUPPORTED(tlsa_chk))
377 TLSA_SET_FL(dane_tlsa, TLSAFLSUP);
380 ** Note: rr_u.rr_data might be NULL after tlsainsert()
381 ** for nice debug output: print the data into a string
382 ** and then use it after tlsainsert().
387 sm_dprintf("tlsaadd: name=%s, nr=%d, ", name, nr);
388 tlsa_rr_print(rr->rr_u.rr_data, rr->rr_size);
390 r = tlsainsert(dane_tlsa, rr, &nr);
392 TLSA_SET_FL(dane_tlsa, TLSAFL2MANY);
394 sm_dprintf("tlsainsert=%d, nr=%d\n", r, nr);
396 /* require some minimum TTL? */
397 if (ttl > rr->rr_ttl && rr->rr_ttl > 0)
405 SM_ASSERT(nr <= MAX_TLSA_RR);
406 for (ui = 0; ui < (unsigned int)nr; ui++)
408 sm_dprintf("tlsaadd: name=%s, ui=%u, ", name, ui);
409 tlsa_rr_print(dane_tlsa->dane_tlsa_rr[ui],
410 dane_tlsa->dane_tlsa_len[ui]);
414 if (TLSA_IS_FL(dane_tlsa, TLSAFL2MANY))
417 sm_dprintf("tlsaadd: name=%s, rr=%p, nr=%d, toomany=%d\n", name, rr, nr, TLSA_IS_FL(dane_tlsa, TLSAFL2MANY));
420 /* second: check for CNAME records, but only if no TLSA RR was added */
421 for (rr = dr->dns_r_head; rr != NULL && nprev == nr; rr = rr->rr_next)
426 if (rr->rr_type != T_CNAME)
431 sm_dprintf("tlsaadd: name=%s, CNAME=%s, level=%d\n",
432 name, rr->rr_u.rr_txt, level);
436 drc = dns_lookup_int(rr->rr_u.rr_txt, C_IN, T_TLSA, 0, 0,
437 Dane == DANE_SECURE ? SM_RES_DNSSEC : 0,
438 RR_RAW, &err, &herr);
441 sm_dprintf("tlsaadd: name=%s, CNAME=%s, level=%d, dr=%p, ad=%d, err=%d, herr=%d\n",
442 name, rr->rr_u.rr_txt, level,
443 (void *)drc, drc != NULL ? drc->dns_r_h.ad : -1,
445 nprev = nr = tlsaadd(name, drc, dane_tlsa, herr, nr, pttl,
451 if (TLSA_IS_FL(dane_tlsa, TLSAFLUNS) &&
452 !TLSA_IS_FL(dane_tlsa, TLSAFLSUP) && LogLevel > 9)
454 sm_syslog(LOG_NOTICE, NOQID,
455 "TLSA=%s, records=%d%s",
456 name, nr, ONLYUNSUPTLSARR);
463 ** GETTLSA -- get TLSA records for named host using DNS
467 ** name -- name for stab entry key (if NULL: host)
468 ** pste -- (pointer to) stab entry (output)
470 ** mxttl -- TTL of MX (or host)
471 ** port -- port number used in TLSA queries (_PORT._tcp.)
474 ** The number of TLSA records found.
475 ** <0 if there is an internal failure.
478 ** Enters TLSA RRs into stab().
479 ** If the DNS lookup fails temporarily, an "empty" entry is
480 ** created with that DNS error code.
484 gettlsa(host, name, pste, flags, mxttl, port)
493 dane_tlsa_P dane_tlsa;
497 int n_rrs, len, err, herr;
498 bool isrname, expired;
502 SM_REQUIRE(host != NULL);
509 isrname = NULL == name;
514 ** If host->MX lookup was not secure then do not look up TLSA RRs.
515 ** Note: this is currently a hack: TLSAFLADMX is used as input flag,
516 ** it is (SHOULD!) NOT stored in dane_tlsa->dane_tlsa_flags
519 if (DANE_SECURE == Dane && 0 == (TLSAFLADMX & flags) &&
520 0 != (TLSAFLNEW & flags))
523 sm_dprintf("gettlsa: host=%s, flags=%#lx, no ad but Dane=Secure\n",
533 if (len > 1 && name[len - 1] == '.')
540 if (0 == port || tTd(66, 101))
542 (void) sm_snprintf(key, sizeof(key), "_%u.%s", port, name);
543 ste = stab(key, ST_TLSA_RR, ST_FIND);
545 sm_dprintf("gettlsa: host=%s, %s, ste=%p, pste=%p, flags=%#lx, port=%d\n",
546 host, isrname ? "" : name, (void *)ste, (void *)pste,
550 dane_tlsa = ste->s_tlsa;
553 // /* Do not reload TLSA RRs if the MX RRs were not securely retrieved. */
555 // && dane_tlsa != NULL && TLSA_IS_FL(dane_tlsa, TLSAFLNOADMX)
556 // && DANE_SECURE == Dane)
561 SM_ASSERT(dane_tlsa != NULL);
564 sm_dprintf("gettlsa: host=%s, found-ste=%p, ste_flags=%#lx, expired=%d\n", host, ste, ste->s_tlsa->dane_tlsa_flags, dane_tlsa->dane_tlsa_exp <= now);
565 if (dane_tlsa->dane_tlsa_exp <= now
566 && 0 == (TLSAFLNOEXP & flags))
568 dane_tlsa_clr(dane_tlsa);
573 n_rrs = dane_tlsa->dane_tlsa_n;
578 /* get entries if none exist yet? */
579 if ((0 == (TLSAFLNEW & flags)) && !expired)
582 if (dane_tlsa == NULL)
584 dane_tlsa = (dane_tlsa_P) sm_malloc(sizeof(*dane_tlsa));
585 if (dane_tlsa == NULL)
590 memset(dane_tlsa, '\0', sizeof(*dane_tlsa));
593 /* There are flags to store -- just set those, do nothing else. */
594 if (TLSA_STORE_FL(flags))
596 dane_tlsa->dane_tlsa_flags = flags;
597 ttl = mxttl > 0 ? mxttl: SM_DEFAULT_TTL;
601 (void) sm_snprintf(nbuf, sizeof(nbuf), "_%u._tcp.%s", port, host);
602 dr = dns_lookup_int(nbuf, C_IN, T_TLSA, 0, 0,
603 (TLSAFLADMX & flags) ? SM_RES_DNSSEC : 0,
604 RR_RAW, &err, &herr);
608 /* disabled -- what to do with these two counters? log them "somewhere"? */
609 // if (NULL != dr && tTd(8, 12))
611 // RESOURCE_RECORD_T *rr;
612 // unsigned int ntlsarrs, usable;
614 // ntlsarrs = usable = 0;
615 // for (rr = dr->dns_r_head; rr != NULL; rr = rr->rr_next)
619 // if (rr->rr_type != T_TLSA)
622 // tlsa_chk = dane_tlsa_chk(rr->rr_u.rr_data,
623 // rr->rr_size, name, false);
624 // if (TLSA_IS_SUPPORTED(tlsa_chk))
628 // sm_dprintf("gettlsa: host=%s, ntlsarrs=%u, usable\%u\n", host, ntlsarrs, usable);
631 sm_dprintf("gettlsa: host=%s, dr=%p, ad=%d, err=%d, herr=%d\n",
633 dr != NULL ? dr->dns_r_h.ad : -1, err, herr);
636 n_rrs = tlsaadd(key, dr, dane_tlsa, herr, n_rrs, &ttl, 0);
638 /* no valid entries found? */
639 if (n_rrs == 0 && !TLSA_RR_TEMPFAIL(dane_tlsa))
642 sm_dprintf("gettlsa: host=%s, n_rrs=%d, herr=%d, status=NOT_ADDED\n",
643 host, n_rrs, dane_tlsa->dane_tlsa_dnsrc);
648 dane_tlsa->dane_tlsa_n = n_rrs;
651 SM_FREE(dane_tlsa->dane_tlsa_sni);
652 dane_tlsa->dane_tlsa_sni = sm_strdup(host);
656 ste = stab(key, ST_TLSA_RR, ST_ENTER);
660 ste->s_tlsa = dane_tlsa;
663 dane_tlsa->dane_tlsa_exp = now + SM_MIN(ttl, SM_DEFAULT_TTL);
670 sm_dprintf("gettlsa: host=%s, key=%s, status=error\n", host, key);
674 dane_tlsa_free(dane_tlsa);
679 if (pste != NULL && ste != NULL)
688 ** GETFALLBACKMXRR -- get MX resource records for fallback MX host.
690 ** We have to initialize this once before doing anything else.
691 ** Moreover, we have to repeat this from time to time to avoid
692 ** stale data, e.g., in persistent queue runners.
693 ** This should be done in a parent process so the child
694 ** processes have the right data.
697 ** host -- the name of the fallback MX host.
700 ** number of MX records.
703 ** Populates NumFallbackMXHosts and fbhosts.
704 ** Sets renewal time (based on TTL).
707 int NumFallbackMXHosts = 0; /* Number of fallback MX hosts (after MX expansion) */
708 static char *fbhosts[MAXMXHOSTS + 1];
711 getfallbackmxrr(host)
716 static time_t renew = 0;
719 /* This is currently done before this function is called. */
720 if (SM_IS_EMPTY(host))
723 if (NumFallbackMXHosts > 0 && renew > curtime())
724 return NumFallbackMXHosts;
727 ** For DANE we need to invoke getmxrr() to get the TLSA RRs.
728 ** Hack: don't do that if its not a FQHN (e.g., [localhost])
729 ** This also triggers for IPv4 addresses, but not IPv6!
732 if (host[0] == '[' && (!Dane || strchr(host, '.') == NULL))
735 NumFallbackMXHosts = 1;
740 for (i = 0; i < NumFallbackMXHosts; i++)
745 ** Note: passing 0 as port is not correct but we cannot
746 ** determine the port number as there is no mailer.
749 NumFallbackMXHosts = getmxrr(host, fbhosts, NULL,
751 (DANE_SECURE == Dane) ? ISAD :
753 0, &rcode, &ttl, 0, NULL);
754 renew = curtime() + ttl;
755 for (i = 0; i < NumFallbackMXHosts; i++)
756 fbhosts[i] = newstr(fbhosts[i]);
758 if (NumFallbackMXHosts == NULLMX)
759 NumFallbackMXHosts = 0;
760 return NumFallbackMXHosts;
764 ** FALLBACKMXRR -- add MX resource records for fallback MX host to list.
767 ** nmx -- current number of MX records.
768 ** prefs -- array of preferences.
769 ** mxhosts -- array of MX hosts (maximum size: MAXMXHOSTS)
772 ** new number of MX records.
775 ** If FallbackMX was set, it appends the MX records for
776 ** that host to mxhosts (and modifies prefs accordingly).
780 fallbackmxrr(nmx, prefs, mxhosts)
782 unsigned short *prefs;
787 for (i = 0; i < NumFallbackMXHosts && nmx < MAXMXHOSTS; i++)
790 prefs[nmx] = prefs[nmx - 1] + 1;
793 mxhosts[nmx++] = fbhosts[i];
801 ** HN2ALABEL -- convert hostname in U-label format to A-label format
804 ** hostname -- hostname in U-label format
807 ** hostname in A-label format in a local static buffer.
808 ** It must be copied before the function is called again.
813 const char *hostname;
815 UErrorCode error = U_ZERO_ERROR;
816 UIDNAInfo info = UIDNA_INFO_INITIALIZER;
818 static char buf[MAXNAME_I]; /* XXX ??? */
820 if (str_is_print(hostname))
822 idna = uidna_openUTS46(UIDNA_NONTRANSITIONAL_TO_ASCII, &error);
823 (void) uidna_nameToASCII_UTF8(idna, hostname, strlen(hostname),
824 buf, sizeof(buf) - 1,
829 # endif /* USE_EAI */
832 ** GETMXRR -- get MX resource records for a domain
835 ** host -- the name of the host to MX [must be x]
836 ** mxhosts -- a pointer to a return buffer of MX records.
837 ** mxprefs -- a pointer to a return buffer of MX preferences.
838 ** If NULL, don't try to populate.
840 ** DROPLOCALHOST -- If true, all MX records less preferred
841 ** than the local host (as determined by $=w) will
843 ** TRYFALLBACK -- add also fallback MX host?
844 ** ISAD -- host lookup was secure?
845 ** rcode -- a pointer to an EX_ status code.
846 ** pttl -- pointer to return TTL (can be NULL).
847 ** port -- port number used in TLSA queries (_PORT._tcp.)
848 ** pad -- (output parameter, pointer to) AD flag (can be NULL)
851 ** The number of MX records found.
852 ** -1 if there is an internal failure.
853 ** If no MX records are found, mxhosts[0] is set to host
854 ** and 1 is returned.
857 ** The entries made for mxhosts point to a static array
858 ** MXHostBuf[MXHOSTBUFSIZE], so the data needs to be copied,
859 ** if it must be preserved across calls to this function.
863 getmxrr(host, mxhosts, mxprefs, flags, rcode, pttl, port, pad)
866 unsigned short *mxprefs;
873 register unsigned char *eom, *cp;
874 register int i, j, n;
879 int ancount, qdcount, buflen;
880 bool seenlocal = false;
881 unsigned short pref, type;
882 unsigned short localpref = 256;
883 char *fallbackMX = FallbackMX;
884 bool trycanon = false;
885 unsigned short *prefs;
886 int (*resfunc) __P((const char *, int, int, u_char *, int));
887 unsigned short prefer[MAXMXHOSTS];
888 int weight[MAXMXHOSTS];
891 bool seennullmx = false;
892 extern int res_query __P((const char *, int, int, u_char *, int));
893 extern int res_search __P((const char *, int, int , u_char *, int));
896 char qname[MAXNAME]; /* EAI: copy of host: ok? */
897 unsigned long old_options = 0;
901 sm_dprintf("getmxrr(%s, droplocalhost=%d, flags=%X, port=%d)\n",
902 host, (flags & DROPLOCALHOST) != 0, flags, port);
903 ad = (flags & ISAD) != 0;
906 *pttl = SM_DEFAULT_TTL;
912 old_options = _res.options;
914 _res.options |= SM_RES_DNSSEC;
917 if ((fallbackMX != NULL && (flags & DROPLOCALHOST) != 0 &&
918 wordinclass(fallbackMX, 'w')) || (flags & TRYFALLBACK) == 0)
920 /* don't use fallback for this pass */
929 /* efficiency hack -- numeric or non-MX lookups */
935 ** NOTE: This only works if nocanonify is used,
936 ** otherwise the name is already rewritten.
939 /* always or only when "needed"? */
940 if (DANE_ALWAYS == Dane || (ad && DANE_SECURE == Dane))
941 (void) sm_strlcpy(qname, host, sizeof(qname));
945 if (!str_is_print(host))
947 /* XXX memory leak? */
948 host = sm_rpool_strdup_x(CurEnv->e_rpool, hn2alabel(host));
950 # endif /* USE_EAI */
953 ** If we don't have MX records in our host switch, don't
954 ** try for MX records. Note that this really isn't "right",
955 ** since we might be set up to try NIS first and then DNS;
956 ** if the host is found in NIS we really shouldn't be doing
957 ** MX lookups. However, that should be a degenerate case.
962 if (HasWildcardMX && ConfigLevel >= 6)
965 resfunc = res_search;
968 resfunc = tstdns_search;
972 hp = (HEADER *)&answer;
973 n = (*resfunc)(host, C_IN, T_MX, (unsigned char *) &answer,
979 sm_dprintf("getmxrr: res_search(%s) failed (errno=%d (%s), h_errno=%d (%s))\n",
980 host, errno, strerror(errno),
981 h_errno, herrno2txt(h_errno));
983 sm_dprintf("getmxrr: res_search(%s) failed, h_errno=%d\n",
993 /* no MX data on this host */
997 # if BROKEN_RES_SEARCH
998 case 0: /* Ultrix resolver returns failure w/ h_errno=0 */
1000 /* host doesn't exist in DNS; might be in /etc/hosts */
1007 /* couldn't connect to the name server */
1008 if (fallbackMX != NULL)
1010 /* name server is hosed -- push to fallback */
1011 nmx = fallbackmxrr(nmx, prefs, mxhosts);
1014 /* it might come up later; better queue it up */
1015 *rcode = EX_TEMPFAIL;
1019 syserr("getmxrr: res_search (%s) failed with impossible h_errno (%d)",
1025 /* irreconcilable differences */
1031 sm_dprintf("getmxrr(%s), hp=%p, ad=%d\n", host, (void*)hp, ad);
1035 /* avoid problems after truncation in tcp packets */
1036 if (n > sizeof(answer))
1039 /* find first satisfactory answer */
1040 cp = (unsigned char *)&answer + HFIXEDSZ;
1041 eom = (unsigned char *)&answer + n;
1043 for (qdcount = ntohs((unsigned short) hp->qdcount);
1047 if ((n = dn_skipname(cp, eom)) < 0)
1051 /* NOTE: see definition of MXHostBuf! */
1052 buflen = sizeof(MXHostBuf) - 1;
1053 SM_ASSERT(buflen > 0);
1055 ancount = ntohs((unsigned short) hp->ancount);
1057 /* See RFC 1035 for layout of RRs. */
1058 /* XXX leave room for FallbackMX ? */
1059 while (--ancount >= 0 && cp < eom && nmx < MAXMXHOSTS - 1)
1061 if ((n = dn_expand((unsigned char *)&answer, eom, cp,
1062 (RES_UNC_T) bp, buflen)) < 0)
1066 cp += INT16SZ; /* skip over class */
1068 GETSHORT(n, cp); /* rdlength */
1070 if (type == T_CNAME)
1075 if ((tTd(8, 8) || _res.options & RES_DEBUG)
1080 sm_dprintf("unexpected answer type %s, size %d\n",
1081 dns_type_to_string(type), n);
1086 if ((n = dn_expand((unsigned char *)&answer, eom, cp,
1087 (RES_UNC_T) bp, buflen)) < 0)
1092 /* Support for RFC7505 "MX 0 ." */
1093 if (pref == 0 && *bp == '\0')
1096 if (wordinclass(bp, 'w'))
1099 sm_dprintf("found localhost (%s) in MX list, pref=%d\n",
1101 if ((flags & DROPLOCALHOST) != 0)
1103 if (!seenlocal || pref < localpref)
1111 weight[nmx] = mxrand(bp);
1113 mxhosts[nmx++] = bp;
1115 if (CHK_DANE(Dane) && port >= 0)
1118 unsigned long flags;
1121 if (pad != NULL && *pad)
1122 flags |= TLSAFLADMX;
1124 sm_dprintf("getmxrr: 1: host=%s, mx=%s, flags=%#lx\n", host, bp, flags);
1125 nrr = gettlsa(bp, NULL, NULL, flags, ttl, port);
1127 /* Only check qname if no TLSA RRs were found */
1128 if (0 == nrr && cname2mx && '\0' != qname[0] &&
1132 sm_dprintf("getmxrr: 2: host=%s, qname=%s, flags=%#lx\n", host, qname, flags);
1133 gettlsa(qname, bp, NULL, flags, ttl, port);
1134 /* XXX is this the right ad flag? */
1140 ** Note: n can be 0 for something like:
1146 if (0 == n || bp[-1] != '.')
1154 /* don't want to wrap buflen */
1160 /* Support for RFC7505 "MX 0 ." */
1161 if (seennullmx && nmx == 1)
1164 sm_dprintf("getmxrr: Null MX record found, domain doesn't accept mail (RFC7505)\n");
1165 *rcode = EX_UNAVAILABLE;
1169 /* return only one TTL entry, that should be sufficient */
1170 if (ttl > 0 && pttl != NULL)
1173 /* sort the records */
1174 for (i = 0; i < nmx; i++)
1176 for (j = i + 1; j < nmx; j++)
1178 if (prefs[i] > prefs[j] ||
1179 (prefs[i] == prefs[j] && weight[i] > weight[j]))
1182 register char *temp1;
1185 prefs[i] = prefs[j];
1188 mxhosts[i] = mxhosts[j];
1191 weight[i] = weight[j];
1195 if (seenlocal && prefs[i] >= localpref)
1197 /* truncate higher preference part of list */
1202 /* delete duplicates from list (yes, some bozos have duplicates) */
1203 for (i = 0; i < nmx - 1; )
1205 if (!SM_STRCASEEQ(mxhosts[i], mxhosts[i + 1]))
1209 /* compress out duplicate */
1210 for (j = i + 1; j < nmx; j++)
1212 mxhosts[j] = mxhosts[j + 1];
1213 prefs[j] = prefs[j + 1];
1224 struct hostent *h = NULL;
1227 ** If we have deleted all MX entries, this is
1228 ** an error -- we should NEVER send to a host that
1229 ** has an MX, and this should have been caught
1230 ** earlier in the config file.
1232 ** Some sites prefer to go ahead and try the
1233 ** A record anyway; that case is handled by
1234 ** setting TryNullMXList. I believe this is a
1235 ** bad idea, but it's up to you....
1242 h = sm_gethostbyname(host, AF_INET);
1245 if (errno == ETIMEDOUT ||
1246 h_errno == TRY_AGAIN ||
1247 (errno == ECONNREFUSED &&
1250 *rcode = EX_TEMPFAIL;
1256 h = sm_gethostbyname(host, AF_INET6);
1258 (errno == ETIMEDOUT ||
1259 h_errno == TRY_AGAIN ||
1260 (errno == ECONNREFUSED &&
1263 *rcode = EX_TEMPFAIL;
1266 # endif /* NETINET6 */
1273 syserr("MX list for %s points back to %s",
1282 if (strlen(host) >= sizeof(MXHostBuf))
1285 syserr("Host name %s too long",
1286 shortenstring(host, MAXSHORTSTR));
1289 (void) sm_strlcpy(MXHostBuf, host, sizeof(MXHostBuf));
1290 mxhosts[0] = MXHostBuf;
1296 struct sockaddr_in6 tmp6;
1299 /* this may be an MX suppression-style address */
1300 p = strchr(MXHostBuf, ']');
1305 if (inet_addr(&MXHostBuf[1]) != INADDR_NONE)
1311 else if (anynet_pton(AF_INET6, &MXHostBuf[1],
1312 &tmp6.sin6_addr) == 1)
1317 # endif /* NETINET6 */
1324 if (!str_is_print(hn))
1328 ahn = hn2alabel(hn);
1329 if (strlen(ahn) >= sizeof(MXHostBuf) - 1)
1332 syserr("Encoded host name %s too long",
1333 shortenstring(ahn, MAXSHORTSTR));
1336 (void) sm_strlcpy(hn, ahn, sizeof(MXHostBuf) - 1);
1338 # endif /* USE_EAI */
1345 (n = getcanonname(mxhosts[0], sizeof(MXHostBuf) - 2, false,
1346 pttl)) != HOST_NOTFOUND)
1348 /* XXX MXHostBuf == "" ? is that possible? */
1349 bp = &MXHostBuf[strlen(MXHostBuf)];
1358 sm_dprintf("getmxrr=%s, getcanonname=%d\n",
1360 if (CHK_DANE(Dane) && port >= 0)
1363 unsigned long flags;
1371 cttl = SM_DEFAULT_TTL;
1374 if (ad && HOST_SECURE == n)
1376 flags |= TLSAFLADMX;
1381 sm_dprintf("getmxrr: 3: host=%s, mx=%s, flags=%#lx, ad=%d\n",
1382 host, mxhosts[0], flags, ad);
1383 nrr = gettlsa(mxhosts[0], NULL, NULL, flags,
1387 ** Only check qname if no TLSA RRs were found
1388 ** XXX: what about (temp) DNS errors?
1391 if (0 == nrr && '\0' != qname[0] &&
1392 strcmp(qname, mxhosts[0]))
1394 gettlsa(qname, mxhosts[0], NULL, flags,
1397 sm_dprintf("getmxrr: 4: host=%s, qname=%s, flags=%#lx\n", host, qname, flags);
1398 /* XXX is this the right ad flag? */
1405 /* if we have a default lowest preference, include that */
1406 if (fallbackMX != NULL && !seenlocal)
1408 /* TODO: DNSSEC status of fallbacks */
1409 nmx = fallbackmxrr(nmx, prefs, mxhosts);
1413 _res.options = old_options;
1419 _res.options = old_options;
1425 ** MXRAND -- create a randomizer for equal MX preferences
1427 ** If two MX hosts have equal preferences we want to randomize
1428 ** the selection. But in order for signatures to be the same,
1429 ** we need to randomize the same way each time. This function
1430 ** computes a pseudo-random hash function from the host name.
1433 ** host -- the name of the host.
1436 ** A random but repeatable value based on the host name.
1441 register char *host;
1444 static unsigned int seed;
1448 seed = (int) curtime() & 0xffff;
1454 sm_dprintf("mxrand(%s)", host);
1457 while (*host != '\0')
1461 if (isascii(c) && isupper(c))
1463 hfunc = ((hfunc << 1) ^ c) % 2003;
1470 sm_dprintf(" = %d\n", hfunc);
1474 ** BESTMX -- find the best MX for a name
1476 ** This is really a hack, but I don't see any obvious way
1477 ** to generalize it at the moment.
1482 bestmx_map_lookup(map, name, av, statp)
1489 int saveopts = _res.options;
1493 char *mxhosts[MAXMXHOSTS + 1];
1494 # if _FFR_BESTMX_BETTER_TRUNCATION
1498 char buf[PSBUFSIZE / 2];
1501 _res.options &= ~(RES_DNSRCH|RES_DEFNAMES);
1502 nmx = getmxrr(name, mxhosts, NULL, 0, statp, NULL, -1, NULL);
1503 _res.options = saveopts;
1506 if (bitset(MF_MATCHONLY, map->map_mflags))
1507 return map_rewrite(map, name, strlen(name), NULL);
1508 if ((map->map_coldelim == '\0') || (nmx == 1))
1509 return map_rewrite(map, mxhosts[0], strlen(mxhosts[0]), av);
1512 ** We were given a -z flag (return all MXs) and there are multiple
1513 ** ones. We need to build them all into a list.
1516 # if _FFR_BESTMX_BETTER_TRUNCATION
1517 for (i = 0; i < nmx; i++)
1519 if (strchr(mxhosts[i], map->map_coldelim) != NULL)
1521 syserr("bestmx_map_lookup: MX host %.64s includes map delimiter character 0x%02X",
1522 mxhosts[i], map->map_coldelim);
1525 len += strlen(mxhosts[i]) + 1;
1528 len -= strlen(mxhosts[i]) + 1;
1532 buf = (char *) sm_malloc(len);
1535 *statp = EX_UNAVAILABLE;
1539 for (i = 0; i < nmx; i++)
1543 end = sm_strlcat(buf, mxhosts[i], len);
1544 if (i != nmx && end + 1 < len)
1546 buf[end] = map->map_coldelim;
1547 buf[end + 1] = '\0';
1551 /* Cleanly truncate for rulesets */
1552 truncate_at_delim(buf, PSBUFSIZE / 2, map->map_coldelim);
1553 # else /* _FFR_BESTMX_BETTER_TRUNCATION */
1555 for (i = 0; i < nmx; i++)
1559 if (strchr(mxhosts[i], map->map_coldelim) != NULL)
1561 syserr("bestmx_map_lookup: MX host %.64s includes map delimiter character 0x%02X",
1562 mxhosts[i], map->map_coldelim);
1565 slen = strlen(mxhosts[i]);
1566 if (len + slen + 2 > sizeof(buf))
1570 *p++ = map->map_coldelim;
1573 (void) sm_strlcpy(p, mxhosts[i], sizeof(buf) - len);
1577 # endif /* _FFR_BESTMX_BETTER_TRUNCATION */
1579 result = map_rewrite(map, buf, len, av);
1580 # if _FFR_BESTMX_BETTER_TRUNCATION
1586 ** DNS_GETCANONNAME -- get the canonical name for named host using DNS
1588 ** This algorithm tries to be smart about wildcard MX records.
1589 ** This is hard to do because DNS doesn't tell is if we matched
1590 ** against a wildcard or a specific MX.
1592 ** We always prefer A & CNAME records, since these are presumed
1595 ** If we match an MX in one pass and lose it in the next, we use
1596 ** the old one. For example, consider an MX matching *.FOO.BAR.COM.
1597 ** A hostname bletch.foo.bar.com will match against this MX, but
1598 ** will stop matching when we try bletch.bar.com -- so we know
1599 ** that bletch.foo.bar.com must have been right. This fails if
1600 ** there was also an MX record matching *.BAR.COM, but there are
1601 ** some things that just can't be fixed.
1604 ** host -- a buffer containing the name of the host.
1605 ** This is a value-result parameter.
1606 ** hbsize -- the size of the host buffer.
1607 ** trymx -- if set, try MX records as well as A and CNAME.
1608 ** statp -- pointer to place to store status.
1609 ** pttl -- pointer to return TTL (can be NULL).
1612 ** >0 -- if the host was found.
1617 dns_getcanonname(host, hbsize, trymx, statp, pttl)
1624 register unsigned char *eom, *ap;
1629 int ancount, qdcount, ret, type, qtype, initial, loopcnt, ttl, sli;
1633 bool amatch, gotmx, ad;
1634 char nbuf[SM_MAX(MAXPACKET, MAXDNAME*2+2)];
1636 # define ADDSL 1 /* NameSearchList may add another entry to searchlist! */
1640 char *searchlist[MAXDNSRCH + 2 + ADDSL];
1641 # define SLSIZE SM_ARRAY_SIZE(searchlist)
1642 int (*resqdomain) __P((const char *, const char *, int, int, unsigned char *, int));
1644 unsigned long old_options = 0;
1651 sm_dprintf("dns_getcanonname(%s, trymx=%d)\n", host, trymx);
1653 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
1655 *statp = EX_UNAVAILABLE;
1656 return HOST_NOTFOUND;
1660 old_options = _res.options;
1661 if (DANE_SECURE == Dane)
1662 _res.options |= SM_RES_DNSSEC;
1666 resqdomain = res_querydomain;
1669 resqdomain = tstdns_querydomain;
1673 ** Initialize domain search list. If there is at least one
1674 ** dot in the name, search the unmodified name first so we
1675 ** find "vse.CS" in Czechoslovakia instead of in the local
1676 ** domain (e.g., vse.CS.Berkeley.EDU). Note that there is no
1677 ** longer a country named Czechoslovakia but this type of problem
1678 ** is still present.
1680 ** Older versions of the resolver could create this
1681 ** list by tearing apart the host name.
1686 /* Check for dots in the name */
1687 for (cp = host, n = 0; *cp != '\0'; cp++)
1692 ** Build the search list.
1693 ** If there is at least one dot in name, start with a null
1694 ** domain to search the unmodified name first.
1695 ** If name does not end with a dot and search up local domain
1696 ** tree desired, append each local domain component to the
1697 ** search list; if name contains no dots and default domain
1698 ** name is desired, append default domain name to search list;
1699 ** else if name ends in a dot, remove that dot.
1704 searchlist[sli++] = "";
1706 if (NameSearchList != NULL)
1708 SM_ASSERT(sli < SLSIZE);
1709 searchlist[sli++] = NameSearchList;
1712 if (n >= 0 && *--cp != '.' && bitset(RES_DNSRCH, _res.options))
1714 /* make sure there are less than MAXDNSRCH domains */
1715 for (domain = RES_DNSRCH_VARIABLE, ret = 0;
1716 *domain != NULL && ret < MAXDNSRCH && sli < SLSIZE;
1718 searchlist[sli++] = *domain++;
1720 else if (n == 0 && bitset(RES_DEFNAMES, _res.options))
1722 SM_ASSERT(sli < SLSIZE);
1723 searchlist[sli++] = _res.defdname;
1725 else if (*cp == '.')
1729 SM_ASSERT(sli < SLSIZE);
1730 searchlist[sli] = NULL;
1733 ** Now loop through the search list, appending each domain in turn
1734 ** name and searching for a match.
1740 if (InetMode == AF_INET6)
1745 for (sli = 0; sli < SLSIZE; )
1747 dp = searchlist[sli];
1750 if (qtype == initial)
1753 sm_dprintf("dns_getcanonname: trying %s.%s (%s)\n",
1756 qtype == T_AAAA ? "AAAA" :
1758 qtype == T_A ? "A" :
1759 qtype == T_MX ? "MX" :
1762 hp = (HEADER *) &answer;
1763 ret = (*resqdomain)(host, dp, C_IN, qtype,
1764 answer.qb2, sizeof(answer.qb2));
1767 int save_errno = errno;
1770 sm_dprintf("\tNO: errno=%d, h_errno=%d\n",
1771 save_errno, h_errno);
1773 if (save_errno == ECONNREFUSED || h_errno == TRY_AGAIN)
1776 ** the name server seems to be down or broken.
1779 SM_SET_H_ERRNO(TRY_AGAIN);
1782 if (*statp == EX_OK)
1783 *statp = EX_TEMPFAIL;
1786 *statp = EX_TEMPFAIL;
1788 if (WorkAroundBrokenAAAA)
1791 ** Only return if not TRY_AGAIN as an
1792 ** attempt with a different qtype may
1793 ** succeed (res_querydomain() calls
1794 ** res_query() calls res_send() which
1795 ** sets errno to ETIMEDOUT if the
1796 ** nameservers could be contacted but
1797 ** didn't give an answer).
1800 if (save_errno != ETIMEDOUT)
1808 if (h_errno != HOST_NOT_FOUND)
1810 /* might have another type of interest */
1812 if (qtype == T_AAAA)
1818 # endif /* NETINET6 */
1819 if (qtype == T_A && !gotmx &&
1820 (trymx || *dp == '\0'))
1827 /* definite no -- try the next domain */
1833 sm_dprintf("\tYES\n");
1835 /* avoid problems after truncation in tcp packets */
1836 if (ret > sizeof(answer))
1837 ret = sizeof(answer);
1838 SM_ASSERT(ret >= 0);
1841 ** Appear to have a match. Confirm it by searching for A or
1842 ** CNAME records. If we don't have a local domain
1843 ** wild card MX record, we will accept MX as well.
1846 ap = (unsigned char *) &answer + HFIXEDSZ;
1847 eom = (unsigned char *) &answer + ret;
1852 /* skip question part of response -- we know what we asked */
1853 for (qdcount = ntohs((unsigned short) hp->qdcount);
1855 ap += ret + QFIXEDSZ)
1857 if ((ret = dn_skipname(ap, eom)) < 0)
1860 sm_dprintf("qdcount failure (%d)\n",
1861 ntohs((unsigned short) hp->qdcount));
1862 *statp = EX_SOFTWARE;
1868 for (ancount = ntohs((unsigned short) hp->ancount);
1869 --ancount >= 0 && ap < eom;
1872 n = dn_expand((unsigned char *) &answer, eom, ap,
1873 (RES_UNC_T) nbuf, sizeof(nbuf));
1878 ap += INT16SZ; /* skip over class */
1880 GETSHORT(n, ap); /* rdlength */
1885 if (*dp != '\0' && HasWildcardMX)
1888 ** If we are using MX matches and have
1889 ** not yet gotten one, save this one
1890 ** but keep searching for an A or
1894 if (trymx && mxmatch == NULL)
1900 ** If we did not append a domain name, this
1901 ** must have been a canonical name to start
1902 ** with. Even if we did append a domain name,
1903 ** in the absence of a wildcard MX this must
1904 ** still be a real MX match.
1905 ** Such MX matches are as good as an A match,
1914 /* Flag that a good match was found */
1917 /* continue in case a CNAME also exists */
1921 if (DontExpandCnames)
1923 /* got CNAME -- guaranteed canonical */
1928 if (loopcnt++ > MAXCNAMEDEPTH)
1930 /*XXX should notify postmaster XXX*/
1931 message("DNS failure: CNAME loop for %s",
1933 if (CurEnv->e_message == NULL)
1937 (void) sm_snprintf(ebuf,
1939 "Deferred: DNS failure: CNAME loop for %.100s",
1943 CurEnv->e_rpool, ebuf);
1945 SM_SET_H_ERRNO(NO_RECOVERY);
1950 /* value points at name */
1951 if ((ret = dn_expand((unsigned char *)&answer,
1952 eom, ap, (RES_UNC_T) nbuf,
1955 (void) sm_strlcpy(host, nbuf, hbsize);
1958 ** RFC 1034 section 3.6 specifies that CNAME
1959 ** should point at the canonical name -- but
1960 ** urges software to try again anyway.
1966 /* not a record of interest */
1974 ** Got a good match -- either an A, CNAME, or an
1975 ** exact MX record. Save it and get out of here.
1983 ** Nothing definitive yet.
1984 ** If this was a T_A query and we haven't yet found a MX
1985 ** match, try T_MX if allowed to do so.
1986 ** Otherwise, try the next domain.
1990 if (qtype == T_AAAA)
1994 if (qtype == T_A && !gotmx && (trymx || *dp == '\0'))
2003 /* if nothing was found, we are done */
2004 if (mxmatch == NULL)
2006 if (*statp == EX_OK)
2012 ** Create canonical name and return.
2013 ** If saved domain name is null, name was already canonical.
2014 ** Otherwise append the saved domain name.
2017 (void) sm_snprintf(nbuf, sizeof(nbuf), "%.*s%s%.*s", MAXDNAME, host,
2018 *mxmatch == '\0' ? "" : ".",
2020 (void) sm_strlcpy(host, nbuf, hbsize);
2022 sm_dprintf("dns_getcanonname: %s\n", host);
2025 /* return only one TTL entry, that should be sufficient */
2026 if (ttl > 0 && pttl != NULL)
2029 _res.options = old_options;
2031 return ad ? HOST_SECURE : HOST_OK;
2035 _res.options = old_options;
2037 return HOST_NOTFOUND;
2040 #endif /* NAMED_BIND */