X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/3634fc257bd0667daef14d72005cd87c735bbb24..762ca6f356174af684898457987e31a470a3a903:/src/src/dns.c diff --git a/src/src/dns.c b/src/src/dns.c index f5e8ab738..95db52686 100644 --- a/src/src/dns.c +++ b/src/src/dns.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2009 */ +/* Copyright (c) University of Cambridge 1995 - 2012 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions for interfacing with the DNS. */ @@ -166,26 +166,30 @@ Returns: nothing void dns_init(BOOL qualify_single, BOOL search_parents) { -if ((_res.options & RES_INIT) == 0) +res_state resp = os_get_dns_resolver_res(); + +if ((resp->options & RES_INIT) == 0) { - DEBUG(D_resolver) _res.options |= RES_DEBUG; /* For Cygwin */ + DEBUG(D_resolver) resp->options |= RES_DEBUG; /* For Cygwin */ + os_put_dns_resolver_res(resp); res_init(); - DEBUG(D_resolver) _res.options |= RES_DEBUG; + DEBUG(D_resolver) resp->options |= RES_DEBUG; + os_put_dns_resolver_res(resp); } -_res.options &= ~(RES_DNSRCH | RES_DEFNAMES); -_res.options |= (qualify_single? RES_DEFNAMES : 0) | +resp->options &= ~(RES_DNSRCH | RES_DEFNAMES); +resp->options |= (qualify_single? RES_DEFNAMES : 0) | (search_parents? RES_DNSRCH : 0); -if (dns_retrans > 0) _res.retrans = dns_retrans; -if (dns_retry > 0) _res.retry = dns_retry; +if (dns_retrans > 0) resp->retrans = dns_retrans; +if (dns_retry > 0) resp->retry = dns_retry; #ifdef RES_USE_EDNS0 if (dns_use_edns0 >= 0) { if (dns_use_edns0) - _res.options |= RES_USE_EDNS0; + resp->options |= RES_USE_EDNS0; else - _res.options &= ~RES_USE_EDNS0; + resp->options &= ~RES_USE_EDNS0; DEBUG(D_resolver) debug_printf("Coerced resolver EDNS0 support %s.\n", dns_use_edns0 ? "on" : "off"); @@ -196,6 +200,38 @@ if (dns_use_edns0 >= 0) debug_printf("Unable to %sset EDNS0 without resolver support.\n", dns_use_edns0 ? "" : "un"); #endif + +#ifndef DISABLE_DNSSEC +# ifdef RES_USE_DNSSEC +# ifndef RES_USE_EDNS0 +# error Have RES_USE_DNSSEC but not RES_USE_EDNS0? Something hinky ... +# endif +if (dns_use_dnssec >= 0) + { + if (dns_use_edns0 == 0 && dns_use_dnssec != 0) + { + DEBUG(D_resolver) + debug_printf("CONFLICT: dns_use_edns0 forced false, dns_use_dnssec forced true!\n"); + } + else + { + if (dns_use_dnssec) + resp->options |= RES_USE_DNSSEC; + else + resp->options &= ~RES_USE_DNSSEC; + DEBUG(D_resolver) debug_printf("Coerced resolver DNSSEC support %s.\n", + dns_use_dnssec ? "on" : "off"); + } + } +# else +if (dns_use_dnssec >= 0) + DEBUG(D_resolver) + debug_printf("Unable to %sset DNSSEC without resolver support.\n", + dns_use_dnssec ? "" : "un"); +# endif +#endif /* DISABLE_DNSSEC */ + +os_put_dns_resolver_res(resp); } @@ -388,6 +424,34 @@ return &(dnss->srr); +/************************************************* +* Return whether AD bit set in DNS result * +*************************************************/ + +/* We do not perform DNSSEC work ourselves; if the administrator has installed +a verifying resolver which sets AD as appropriate, though, we'll use that. +(AD = Authentic Data) + +Argument: pointer to dns answer block +Returns: bool indicating presence of AD bit +*/ + +BOOL +dns_is_secure(dns_answer *dnsa) +{ +#ifdef DISABLE_DNSSEC +DEBUG(D_dns) + debug_printf("DNSSEC support disabled at build-time; dns_is_secure() false\n"); +return FALSE; +#else +HEADER *h = (HEADER *)dnsa->answer; +return h->ad ? TRUE : FALSE; +#endif +} + + + + /************************************************* * Turn DNS type into text * *************************************************/ @@ -409,6 +473,7 @@ switch(t) case T_AAAA: return US"AAAA"; case T_A6: return US"A6"; case T_TXT: return US"TXT"; + case T_SPF: return US"SPF"; case T_PTR: return US"PTR"; case T_SOA: return US"SOA"; case T_SRV: return US"SRV"; @@ -440,9 +505,10 @@ Returns: the return code static int dns_return(uschar *name, int type, int rc) { +res_state resp = os_get_dns_resolver_res(); tree_node *node = store_get_perm(sizeof(tree_node) + 290); sprintf(CS node->name, "%.255s-%s-%lx", name, dns_text_type(type), - _res.options); + resp->options); node->data.val = rc; (void)tree_insertnode(&tree_dns_fails, node); return rc; @@ -482,6 +548,7 @@ dns_basic_lookup(dns_answer *dnsa, uschar *name, int type) int rc = -1; uschar *save; #endif +res_state resp = os_get_dns_resolver_res(); tree_node *previous; uschar node_name[290]; @@ -492,7 +559,7 @@ have many addresses in the same domain. We rely on the resolver and name server caching for successful lookups. */ sprintf(CS node_name, "%.255s-%s-%lx", name, dns_text_type(type), - _res.options); + resp->options); previous = tree_search(tree_dns_fails, node_name); if (previous != NULL) {