[PATCH v2 5/5] dns: always add authority records

Kai Blin kai at samba.org
Thu Jul 30 10:19:14 UTC 2015


Signed-off-by: Kai Blin <kai at samba.org>
---
 python/samba/tests/dns.py       | 34 +++++++++++++++++-----------------
 source4/dns_server/dns_query.c  | 24 +++++++++++++++++-------
 source4/dns_server/dns_server.c |  6 +++++-
 3 files changed, 39 insertions(+), 25 deletions(-)

diff --git a/python/samba/tests/dns.py b/python/samba/tests/dns.py
index 04ac356..044eaf6 100644
--- a/python/samba/tests/dns.py
+++ b/python/samba/tests/dns.py
@@ -247,23 +247,23 @@ class TestSimpleQueries(DNSTest):
         response = self.dns_transaction_udp(p)
         self.assert_dns_rcode_equals(response, dns.DNS_RCODE_NOTIMP)
 
-# Only returns an authority section entry in BIND and Win DNS
-# FIXME: Enable one Samba implements this feature
-#    def test_soa_hostname_query(self):
-#        "create a SOA query for a hostname"
-#        p = self.make_name_packet(dns.DNS_OPCODE_QUERY)
-#        questions = []
-#
-#        name = "%s.%s" % (os.getenv('SERVER'), self.get_dns_domain())
-#        q = self.make_name_question(name, dns.DNS_QTYPE_SOA, dns.DNS_QCLASS_IN)
-#        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)
-#        # We don't get SOA records for single hosts
-#        self.assertEquals(response.ancount, 0)
+    def test_soa_hostname_query(self):
+        "create a SOA query for a hostname"
+        p = self.make_name_packet(dns.DNS_OPCODE_QUERY)
+        questions = []
+
+        name = "%s.%s" % (os.getenv('SERVER'), self.get_dns_domain())
+        q = self.make_name_question(name, dns.DNS_QTYPE_SOA, dns.DNS_QCLASS_IN)
+        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)
+        # We don't get SOA records for single hosts
+        self.assertEquals(response.ancount, 0)
+        # But we do respond with an authority section
+        self.assertEqual(response.nscount, 1)
 
     def test_soa_domain_query(self):
         "create a SOA query for a domain"
diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c
index 8ffe5a5..4516452 100644
--- a/source4/dns_server/dns_query.c
+++ b/source4/dns_server/dns_query.c
@@ -313,12 +313,13 @@ static WERROR handle_question(struct dns_server *dns,
 	struct ldb_dn *dn = NULL;
 
 	werror = dns_name2dn(dns, mem_ctx, question->name, &dn);
-	W_ERROR_NOT_OK_RETURN(werror);
+	if (!W_ERROR_IS_OK(werror)) {
+		return werror;
+	}
 
 	werror = dns_lookup_records(dns, mem_ctx, dn, &recs, &rec_count);
 	if (!W_ERROR_IS_OK(werror)) {
 		werror_return = werror;
-		add_zone_authority_record(dns, mem_ctx, question, &ns, &ni);
 		goto done;
 	}
 
@@ -372,7 +373,7 @@ static WERROR handle_question(struct dns_server *dns,
 			/* and then call the lookup again */
 			werror = handle_question(dns, mem_ctx, new_q, &ans, &ai, &ns, &ni);
 			if (!W_ERROR_IS_OK(werror)) {
-				return werror;
+				goto done;
 			}
 			werror_return = WERR_OK;
 
@@ -392,6 +393,9 @@ static WERROR handle_question(struct dns_server *dns,
 	}
 
 done:
+	/* Always add an authority record to replies we should know about */
+	add_zone_authority_record(dns, mem_ctx, question, &ns, &ni);
+
 	*ancount = ai;
 	*answers = ans;
 	*nscount = ni;
@@ -673,7 +677,9 @@ struct tevent_req *dns_server_process_query_send(
 				      &state->answers, &state->ancount,
 				      &state->nsrecs, &state->nscount);
 		if (tevent_req_werror(req, err)) {
-			return tevent_req_post(req, ev);
+			if (!W_ERROR_EQUAL(err, DNS_ERR(NAME_ERROR))) {
+				return tevent_req_post(req, ev);
+			}
 		}
 		tevent_req_done(req);
 		return tevent_req_post(req, ev);
@@ -727,10 +733,14 @@ WERROR dns_server_process_query_recv(
 {
 	struct dns_server_process_query_state *state = tevent_req_data(
 		req, struct dns_server_process_query_state);
-	WERROR err;
+	WERROR err = WERR_OK;
 
 	if (tevent_req_is_werror(req, &err)) {
-		return err;
+
+		if ((!W_ERROR_EQUAL(err, DNS_ERR(NAME_ERROR))) &&
+		    (!W_ERROR_EQUAL(err, WERR_DNS_ERROR_NAME_DOES_NOT_EXIST))) {
+			return err;
+		}
 	}
 	*answers = talloc_move(mem_ctx, &state->answers);
 	*ancount = state->ancount;
@@ -738,5 +748,5 @@ WERROR dns_server_process_query_recv(
 	*nscount = state->nscount;
 	*additional = talloc_move(mem_ctx, &state->additional);
 	*arcount = state->arcount;
-	return WERR_OK;
+	return err;
 }
diff --git a/source4/dns_server/dns_server.c b/source4/dns_server/dns_server.c
index 3e18287..66ab738 100644
--- a/source4/dns_server/dns_server.c
+++ b/source4/dns_server/dns_server.c
@@ -234,9 +234,13 @@ static WERROR dns_process_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
 	if (tevent_req_is_werror(req, &ret)) {
 		return ret;
 	}
-	if (state->dns_err != DNS_RCODE_OK) {
+	if ((state->dns_err != DNS_RCODE_OK) &&
+	    (state->dns_err != DNS_RCODE_NXDOMAIN)) {
 		goto drop;
 	}
+	if (state->dns_err != DNS_RCODE_OK) {
+		state->out_packet.operation |= state->dns_err;
+	}
 	state->out_packet.operation |= state->state.flags;
 
 	if (state->state.sign) {
-- 
1.9.1




More information about the samba-technical mailing list