dns: always add authority records dns-soa-authority-rr
authorKai Blin <kai@samba.org>
Fri, 17 Jul 2015 13:27:51 +0000 (15:27 +0200)
committerKai Blin <kblin@biosustain.dtu.dk>
Fri, 31 Jul 2015 09:17:19 +0000 (11:17 +0200)
Signed-off-by: Kai Blin <kai@samba.org>
python/samba/tests/dns.py
source4/dns_server/dns_query.c
source4/dns_server/dns_server.c

index 04ac3567ed7dfdce6ed60f2e483cc382dcffe94c..044eaf64e9ffba314c6404f61dd35e20059c5fa8 100644 (file)
@@ -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"
index 8ffe5a514d311c99199b79845f9ca5b504c00e46..f193fbed6ad98a535301a37b106c615b7a0703c2 100644 (file)
@@ -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;
@@ -727,10 +731,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 +746,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;
 }
index 3e18287bfa1b8747c29d6bd852bee9a0f3bf8ec5..66ab738eb43a96c23bac1443160440040beafea8 100644 (file)
@@ -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) {