[SCM] Samba Shared Repository - branch master updated

Kai Blin kai at samba.org
Wed Jun 6 07:24:05 MDT 2012


The branch, master has been updated
       via  f3df298 s4 dns: Correctly handle A questions for CNAMEs
       via  754c60e s4 dns: Structure tests a bit better
      from  02d9ba6 s3:smbd: change user_struct->vuid to uint64_t

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit f3df2988ba6928cde0bd89da321bbe74fd76f53f
Author: Kai Blin <kai at samba.org>
Date:   Fri Jun 1 08:05:54 2012 +0200

    s4 dns: Correctly handle A questions for CNAMEs
    
    When an A/AAAA lookup is made for a name that actually is a CNAME
    record, we need to return the CNAME record, and then do the A/AAAA
    lookup for the name the CNAME points at.
    
    This still fails for CNAMEs pointing at records for domains we need to
    ask our forwarders for.
    
    Autobuild-User: Kai Blin <kai at samba.org>
    Autobuild-Date: Wed Jun  6 15:23:55 CEST 2012 on sn-devel-104

commit 754c60e4175c8cd077766cd6ea762bd46cdd41af
Author: Kai Blin <kai at samba.org>
Date:   Wed May 30 08:08:53 2012 +0200

    s4 dns: Structure tests a bit better

-----------------------------------------------------------------------

Summary of changes:
 source4/dns_server/dns_query.c              |   61 +++++++++++++++++++--
 source4/scripting/python/samba/tests/dns.py |   79 +++++++++++++++++++++++++++
 2 files changed, 135 insertions(+), 5 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c
index 0e63058..40df3a1 100644
--- a/source4/dns_server/dns_query.c
+++ b/source4/dns_server/dns_query.c
@@ -231,11 +231,11 @@ static WERROR handle_question(struct dns_server *dns,
 			      const struct dns_name_question *question,
 			      struct dns_res_rec **answers, uint16_t *ancount)
 {
-	struct dns_res_rec *ans;
+	struct dns_res_rec *ans = *answers;
 	WERROR werror;
 	unsigned int ri;
 	struct dnsp_DnssrvRpcRecord *recs;
-	uint16_t rec_count, ai = 0;
+	uint16_t rec_count, ai = *ancount;
 	struct ldb_dn *dn = NULL;
 
 	werror = dns_name2dn(dns, mem_ctx, question->name, &dn);
@@ -244,16 +244,67 @@ static WERROR handle_question(struct dns_server *dns,
 	werror = dns_lookup_records(dns, mem_ctx, dn, &recs, &rec_count);
 	W_ERROR_NOT_OK_RETURN(werror);
 
-	ans = talloc_zero_array(mem_ctx, struct dns_res_rec, rec_count);
-	W_ERROR_HAVE_NO_MEMORY(ans);
+	ans = talloc_realloc(mem_ctx, ans, struct dns_res_rec, rec_count + ai);
+	if (ans == NULL) {
+		return WERR_NOMEM;
+	}
 
 	for (ri = 0; ri < rec_count; ri++) {
+		if ((recs[ri].wType == DNS_TYPE_CNAME) &&
+		    ((question->question_type == DNS_QTYPE_A) ||
+		     (question->question_type == DNS_QTYPE_AAAA))) {
+			struct dns_name_question *new_q =
+				talloc(mem_ctx, struct dns_name_question);
+
+			if (new_q == NULL) {
+				return WERR_NOMEM;
+			}
+
+			/* We reply with one more record, so grow the array */
+			ans = talloc_realloc(mem_ctx, ans, struct dns_res_rec,
+					     rec_count + 1);
+			if (ans == NULL) {
+				TALLOC_FREE(new_q);
+				return WERR_NOMEM;
+			}
+
+			/* First put in the CNAME record */
+			werror = create_response_rr(question, &recs[ri], &ans, &ai);
+			if (!W_ERROR_IS_OK(werror)) {
+				return werror;
+			}
+
+			/* And then look up the name it points at.. */
+
+			/* First build up the new question */
+			new_q->question_type = question->question_type;
+			new_q->question_class = question->question_class;
+			if (new_q->question_type == DNS_QTYPE_A) {
+				new_q->name = talloc_strdup(new_q, recs[ri].data.ipv4);
+			} else if (new_q->question_type == DNS_QTYPE_AAAA) {
+				new_q->name = talloc_strdup(new_q, recs[ri].data.ipv6);
+			}
+			if (new_q->name == NULL) {
+				TALLOC_FREE(new_q);
+				return WERR_NOMEM;
+			}
+			/* and then call the lookup again */
+			werror = handle_question(dns, mem_ctx, new_q, &ans, &ai);
+			if (!W_ERROR_IS_OK(werror)) {
+				return werror;
+			}
+
+
+			continue;
+		}
 		if ((question->question_type != DNS_QTYPE_ALL) &&
 		    (recs[ri].wType != question->question_type)) {
 			continue;
 		}
 		werror = create_response_rr(question, &recs[ri], &ans, &ai);
-		W_ERROR_NOT_OK_RETURN(werror);
+		if (!W_ERROR_IS_OK(werror)) {
+			return werror;
+		}
 	}
 
 	if (ai == 0) {
diff --git a/source4/scripting/python/samba/tests/dns.py b/source4/scripting/python/samba/tests/dns.py
index b1ea416..aa6a4e6 100644
--- a/source4/scripting/python/samba/tests/dns.py
+++ b/source4/scripting/python/samba/tests/dns.py
@@ -112,6 +112,7 @@ class DNSTest(TestCase):
                 if s is not None:
                     s.close()
 
+class TestSimpleQueries(DNSTest):
     def test_one_a_query(self):
         "create a query packet containing one query record"
         p = self.make_name_packet(dns.DNS_OPCODE_QUERY)
@@ -237,6 +238,8 @@ class DNSTest(TestCase):
         self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY)
         self.assertEquals(response.ancount, 1)
 
+
+class TestDNSUpdates(DNSTest):
     def test_two_updates(self):
         "create two update requests"
         p = self.make_name_packet(dns.DNS_OPCODE_UPDATE)
@@ -466,6 +469,82 @@ class DNSTest(TestCase):
         self.assert_dns_rcode_equals(response, dns.DNS_RCODE_NXDOMAIN)
 
 
+class TestComplexQueries(DNSTest):
+    def setUp(self):
+        super(TestComplexQueries, self).setUp()
+        p = self.make_name_packet(dns.DNS_OPCODE_UPDATE)
+        updates = []
+
+        name = self.get_dns_domain()
+
+        u = self.make_name_question(name, dns.DNS_QTYPE_SOA, dns.DNS_QCLASS_IN)
+        updates.append(u)
+        self.finish_name_packet(p, updates)
+
+        updates = []
+        r = dns.res_rec()
+        r.name = "cname_test.%s" % self.get_dns_domain()
+        r.rr_type = dns.DNS_QTYPE_CNAME
+        r.rr_class = dns.DNS_QCLASS_IN
+        r.ttl = 900
+        r.length = 0xffff
+        r.rdata = "%s.%s" % (os.getenv('DC_SERVER'), self.get_dns_domain())
+        updates.append(r)
+        p.nscount = len(updates)
+        p.nsrecs = updates
+
+        response = self.dns_transaction_udp(p)
+        self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK)
+
+    def tearDown(self):
+        super(TestComplexQueries, self).tearDown()
+        p = self.make_name_packet(dns.DNS_OPCODE_UPDATE)
+        updates = []
+
+        name = self.get_dns_domain()
+
+        u = self.make_name_question(name, dns.DNS_QTYPE_SOA, dns.DNS_QCLASS_IN)
+        updates.append(u)
+        self.finish_name_packet(p, updates)
+
+        updates = []
+        r = dns.res_rec()
+        r.name = "cname_test.%s" % self.get_dns_domain()
+        r.rr_type = dns.DNS_QTYPE_CNAME
+        r.rr_class = dns.DNS_QCLASS_NONE
+        r.ttl = 0
+        r.length = 0xffff
+        r.rdata = "%s.%s" % (os.getenv('DC_SERVER'), self.get_dns_domain())
+        updates.append(r)
+        p.nscount = len(updates)
+        p.nsrecs = updates
+
+        response = self.dns_transaction_udp(p)
+        self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK)
+
+    def test_one_a_query(self):
+        "create a query packet containing one query record"
+        p = self.make_name_packet(dns.DNS_OPCODE_QUERY)
+        questions = []
+
+        name = "cname_test.%s" % self.get_dns_domain()
+        q = self.make_name_question(name, dns.DNS_QTYPE_A, dns.DNS_QCLASS_IN)
+        print "asking for ", q.name
+        questions.append(q)
+
+        self.finish_name_packet(p, questions)
+        response = self.dns_transaction_udp(p)
+        self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK)
+        self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY)
+        self.assertEquals(response.ancount, 2)
+        self.assertEquals(response.answers[0].rr_type, dns.DNS_QTYPE_CNAME)
+        self.assertEquals(response.answers[0].rdata, "%s.%s" %
+                          (os.getenv('DC_SERVER'), self.get_dns_domain()))
+        self.assertEquals(response.answers[1].rr_type, dns.DNS_QTYPE_A)
+        self.assertEquals(response.answers[1].rdata,
+                          os.getenv('DC_SERVER_IP'))
+
+
 if __name__ == "__main__":
     import unittest
     unittest.main()


-- 
Samba Shared Repository


More information about the samba-cvs mailing list