summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Hazel <ph10@hermes.cam.ac.uk>2004-11-19 09:45:54 +0000
committerPhilip Hazel <ph10@hermes.cam.ac.uk>2004-11-19 09:45:54 +0000
commit33397d198607bb789306b1856a9a38aaf9aa9561 (patch)
treeb9952496fabb09f62f8338485c8649b8d3070181
parent6f0c9a4f0114289a94a6001c23049f382c3176f3 (diff)
downloadexim4-33397d198607bb789306b1856a9a38aaf9aa9561.tar.gz
Implement the pseudo dns lookup type "zns" for ${dnsdb lookups.
-rw-r--r--doc/doc-txt/ChangeLog12
-rw-r--r--doc/doc-txt/NewStuff23
-rw-r--r--src/src/dns.c74
-rw-r--r--src/src/exim.h7
-rw-r--r--src/src/functions.h3
-rw-r--r--src/src/lookups/dnsdb.c16
6 files changed, 118 insertions, 17 deletions
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 8a8f552f4..5e213d772 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.33 2004/11/18 11:17:33 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.34 2004/11/19 09:45:54 ph10 Exp $
Change log file for Exim from version 4.21
-------------------------------------------
@@ -142,6 +142,16 @@ Exim version 4.44
canonical form (fully expanded) before being placed in
$sender_host_address.
+36. The table in the code that translates DNS record types into text (T_A to
+ "A" for instance) was missing entries for NS and CNAME. It is just possible
+ that this could have caused confusion if both these types were looked up
+ for the same domain, because the text type is used as part of Exim's
+ per-process caching. But the chance of anyone hitting this buglet seems
+ very small.
+
+37. The dnsdb lookup has a new type, "zns", which walks up the domain tree
+ until it finds some nameserver records. It should be used with care.
+
Exim version 4.43
-----------------
diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff
index d5d340713..ee9f55c31 100644
--- a/doc/doc-txt/NewStuff
+++ b/doc/doc-txt/NewStuff
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/NewStuff,v 1.11 2004/11/17 16:12:26 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/NewStuff,v 1.12 2004/11/19 09:45:54 ph10 Exp $
New Features in Exim
--------------------
@@ -108,6 +108,27 @@ Version 4.44
Previously this was a syntax error.
+12. There is now a new "record type" that can be specified in dnsdb lookups. It
+ is "zns" (for "zone NS"). It performs a lookup for NS records on the given
+ domain, but if none are found, it removes the first component of the domain
+ name, and tries again. This process continues until NS records are found
+ or there are no more components left (or there's a DNS error). In other
+ words, it may return the name servers for a top-level domain, but it never
+ returns the root name servers. If there are no NS records for the top-level
+ domain, the lookup fails.
+
+ For example, ${lookup dnsdb{zns=xxx.quercite.com}} returns the name
+ servers for quercite.com, whereas ${lookup dnsdb{zns=xxx.edu}} returns
+ the name servers for edu, assuming in each case that there are no NS
+ records for the full domain name.
+
+ You should be careful about how you use this lookup because, unless the
+ top-level domain does not exist, the lookup will always return some host
+ names. The sort of use to which this might be put is for seeing if the name
+ servers for a given domain are on a blacklist. You can probably assume that
+ the name servers for the high-level domains such as .com or .co.uk are not
+ going to be on such a list.
+
Version 4.43
------------
diff --git a/src/src/dns.c b/src/src/dns.c
index 237b734a6..a5a154741 100644
--- a/src/src/dns.c
+++ b/src/src/dns.c
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/dns.c,v 1.1 2004/10/07 10:39:01 ph10 Exp $ */
+/* $Cambridge: exim/src/src/dns.c,v 1.2 2004/11/19 09:45:54 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -258,14 +258,16 @@ dns_text_type(int t)
{
switch(t)
{
- case T_A: return US"A";
- case T_MX: return US"MX";
- case T_AAAA: return US"AAAA";
- case T_A6: return US"A6";
- case T_TXT: return US"TXT";
- case T_PTR: return US"PTR";
- case T_SRV: return US"SRV";
- default: return US"?";
+ case T_A: return US"A";
+ case T_MX: return US"MX";
+ case T_AAAA: return US"AAAA";
+ case T_A6: return US"A6";
+ case T_TXT: return US"TXT";
+ case T_PTR: return US"PTR";
+ case T_SRV: return US"SRV";
+ case T_NS: return US"NS";
+ case T_CNAME: return US"CNAME";
+ default: return US"?";
}
}
@@ -617,6 +619,60 @@ return DNS_FAIL;
+
+
+
+/************************************************
+* Do a DNS lookup and handle virtual types *
+************************************************/
+
+/* This function handles some invented "lookup types" that synthesize feature
+not available in the basic types. The special types all have negative values.
+Positive type values are passed straight on to dns_lookup().
+
+Arguments:
+ dnsa pointer to dns_answer structure
+ name domain name to look up
+ type DNS record type (T_A, T_MX, etc or a "special")
+ fully_qualified_name if not NULL, return the returned name here if its
+ contents are different (i.e. it must be preset)
+
+Returns: DNS_SUCCEED successful lookup
+ DNS_NOMATCH name not found
+ DNS_NODATA no data found
+ DNS_AGAIN soft failure, try again later
+ DNS_FAIL DNS failure
+*/
+
+int
+dns_special_lookup(dns_answer *dnsa, uschar *name, int type,
+ uschar **fully_qualified_name)
+{
+if (type >= 0) return dns_lookup(dnsa, name, type, fully_qualified_name);
+
+/* Find nameservers for the domain or the nearest enclosing zone, excluding the
+root servers. */
+
+if (type == T_ZNS)
+ {
+ uschar *d = name;
+ while (d != 0)
+ {
+ int rc = dns_lookup(dnsa, d, T_NS, fully_qualified_name);
+ if (rc != DNS_NOMATCH && rc != DNS_NODATA) return rc;
+ while (*d != 0 && *d != '.') d++;
+ if (*d++ == 0) break;
+ }
+ return DNS_NOMATCH;
+ }
+
+/* Control should never reach here */
+
+return DNS_FAIL;
+}
+
+
+
/* Support for A6 records has been commented out since they were demoted to
experimental status at IETF 51. */
diff --git a/src/src/exim.h b/src/src/exim.h
index 96d634efe..998adc3ea 100644
--- a/src/src/exim.h
+++ b/src/src/exim.h
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/exim.h,v 1.1 2004/10/07 10:39:01 ph10 Exp $ */
+/* $Cambridge: exim/src/src/exim.h,v 1.2 2004/11/19 09:45:54 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -278,6 +278,11 @@ header files. I don't suppose they have T_SRV either. */
#define T_SRV 33
#endif
+/* We use the private type T_ZNS for retrieving the nameservers for the
+enclosing zone of a domain. */
+
+#define T_ZNS (-1)
+
/* The resolv.h header defines __P(x) on some Solaris 2.5.1 systems (without
checking that it is already defined, in fact). This conflicts with other
headers that behave likewise (see below), leading to compiler warnings. Arrange
diff --git a/src/src/functions.h b/src/src/functions.h
index 493575d36..8b9f3bbe9 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/functions.h,v 1.4 2004/11/18 11:17:33 ph10 Exp $ */
+/* $Cambridge: exim/src/src/functions.h,v 1.5 2004/11/19 09:45:54 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -74,6 +74,7 @@ extern void dns_build_reverse(uschar *, uschar *);
extern void dns_init(BOOL, BOOL);
extern int dns_basic_lookup(dns_answer *, uschar *, int);
extern int dns_lookup(dns_answer *, uschar *, int, uschar **);
+extern int dns_special_lookup(dns_answer *, uschar *, int, uschar **);
extern dns_record *dns_next_rr(dns_answer *, dns_scan *, int);
extern uschar *dns_text_type(int);
diff --git a/src/src/lookups/dnsdb.c b/src/src/lookups/dnsdb.c
index 14fdc5a2e..492e53574 100644
--- a/src/src/lookups/dnsdb.c
+++ b/src/src/lookups/dnsdb.c
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/lookups/dnsdb.c,v 1.1 2004/10/07 13:10:01 ph10 Exp $ */
+/* $Cambridge: exim/src/src/lookups/dnsdb.c,v 1.2 2004/11/19 09:45:54 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -35,7 +35,9 @@ static char *type_names[] = {
"ns",
"ptr",
"srv",
- "txt" };
+ "txt",
+ "zns"
+};
static int type_values[] = {
T_A,
@@ -50,7 +52,9 @@ static int type_values[] = {
T_NS,
T_PTR,
T_SRV,
- T_TXT };
+ T_TXT,
+ T_ZNS /* Private type for "zone nameservers" */
+};
/*************************************************
@@ -139,11 +143,15 @@ DEBUG(D_lookup) debug_printf("dnsdb key: %s\n", keystring);
in this run. Then do the lookup and sort out the result. */
dns_init(FALSE, FALSE);
-rc = dns_lookup(&dnsa, keystring, type, NULL);
+rc = dns_special_lookup(&dnsa, keystring, type, NULL);
if (rc == DNS_NOMATCH || rc == DNS_NODATA) return FAIL;
if (rc != DNS_SUCCEED) return DEFER;
+/* If the lookup was a pseudo-type, change it to the correct type for searching
+the returned records; then search for them. */
+
+if (type == T_ZNS) type = T_NS;
for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
rr != NULL;
rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))