Package: djbdns-installer
Version: 1.05-11
Severity: normal
Tags: patch

From:
http://homepages.tesco.net./~J.deBoynePollard/FGA/djbdns-problems.html#content-alias-chain-truncation

"According to the algorithm in RFC 1034 ยง 4.3.2, a content DNS server
must search for a "CNAME" resource record for the domain name being
queried, and if it finds one it must substitute the domain name from the
data portion, add the resource record to the answer section of the
response, and restart processing.  tinydns and axfrdns do not do this."
 (plus more good info)

In production authoritative name service for 400,000+ domains, we found
the patch provided by Jonathan de Boyne Pollard at the above site
corrected the CNAME authority issues with tinydns/axfrdns.

A quick example of an erroneous response from an unpatched tinydns
(djbdns-installer_1.05):

$ dig kokopelli.pbandjelly.org @ns.rackspace.com
;kokopelli.pbandjelly.org.      IN      A
kokopelli.pbandjelly.org. 86400 IN      CNAME   kokopelli.homeunix.org.
pbandjelly.org.         86400   IN      NS      ns.rackspace.com.
pbandjelly.org.         86400   IN      NS      ns2.rackspace.com.
;; Received 128 bytes from 69.20.95.4#53(69.20.95.4) in 12 ms

A patched tinydns response as per the algorithm in RFC 1034:

$ dig kokopelli.pbandjelly.org @ns.rackspace.com
;kokopelli.pbandjelly.org.      IN      A
kokopelli.pbandjelly.org. 86400 IN      CNAME   kokopelli.homeunix.org.
;; Received 75 bytes from 69.20.95.4#53(69.20.95.4) in 13 ms

And the resulting recursive resolver response (which picks up the proper
authority from the external CNAME target):

$ dig kokopelli.pbandjelly.org
;kokopelli.pbandjelly.org.      IN      A
kokopelli.pbandjelly.org. 31057 IN      CNAME   kokopelli.homeunix.org.
kokopelli.homeunix.org. 60      IN      A       10.1.100.156
homeunix.org.           11192   IN      NS      ns3.dyndns.org.
homeunix.org.           11192   IN      NS      ns4.dyndns.org.
homeunix.org.           11192   IN      NS      ns5.dyndns.org.
homeunix.org.           11192   IN      NS      ns1.dyndns.org.
homeunix.org.           11192   IN      NS      ns2.dyndns.org.
;; Received 268 bytes from 64.39.2.170#53(64.39.2.170) in 21 ms

Kind Regards,
Michael Shuler
--- djbdns-1.05-original/tdlookup.c	Sun Feb 11 21:11:45 2001
+++ djbdns-1.05/tdlookup.c	Thu Apr  3 11:56:47 2003
@@ -103,12 +103,13 @@
   return response_addname(d1);
 }
 
-static int doit(char *q,char qtype[2])
+static int doit1(char **pqname,char qtype[2])
 {
   unsigned int bpos;
   unsigned int anpos;
   unsigned int aupos;
   unsigned int arpos;
+  char *q;
   char *control;
   char *wild;
   int flaggavesoa;
@@ -122,6 +123,12 @@
   int addrnum;
   uint32 addrttl;
   int i;
+  int loop = 0 ;
+
+RESTART:
+  if (loop++ >= 100) return 0 ;
+
+  q = *pqname ;
 
   anpos = response_len;
 
@@ -136,7 +143,14 @@
       if (byte_equal(type,2,DNS_T_NS)) flagns = 1;
     }
     if (flagns) break;
-    if (!*control) return 0; /* q is not within our bailiwick */
+    if (!*control) { /* q is not within our bailiwick */
+      if (loop <= 1)
+        return 0 ;
+      else {
+        response[2] &= ~4;
+        goto DONE; /* The administrator has issued contradictory instructions */
+      }
+    }
     control += *control;
     control += 1;
   }
@@ -172,8 +186,16 @@
 	continue;
       }
       if (!response_rstart(q,type,ttl)) return 0;
-      if (byte_equal(type,2,DNS_T_NS) || byte_equal(type,2,DNS_T_CNAME) || byte_equal(type,2,DNS_T_PTR)) {
+      if (byte_equal(type,2,DNS_T_NS) || byte_equal(type,2,DNS_T_PTR)) {
+	if (!doname()) return 0;
+      }
+      else if (byte_equal(type,2,DNS_T_CNAME)) {
 	if (!doname()) return 0;
+        if (byte_diff(type,2,qtype)) {
+	  response_rfinish(RESPONSE_ANSWER);
+	  if (!dns_domain_copy(pqname,d1)) return 0 ;
+	  goto RESTART ;
+	}
       }
       else if (byte_equal(type,2,DNS_T_MX)) {
 	if (!dobytes(2)) return 0;
@@ -275,9 +297,21 @@
     }
   }
 
+DONE:
   return 1;
 }
 
+static int doit(char *qname,char qtype[2])
+{
+  int r ;
+  char * q = 0 ;
+
+  if (!dns_domain_copy(&q, qname)) return 0 ;
+  r = doit1(&q, qtype) ;
+  dns_domain_free(&q) ;
+  return r ;
+}
+
 int respond(char *q,char qtype[2],char ip[4])
 {
   int fd;

Reply via email to