bug #10471: Don't respond with NXDOMAIN to records that exist with another type
authorKai Blin <kai@samba.org>
Thu, 27 Feb 2014 22:49:24 +0000 (23:49 +0100)
committerKai Blin <kai@samba.org>
Tue, 4 Mar 2014 12:46:34 +0000 (13:46 +0100)
DNS queries for records with the wrong type need to trigger an empty
response with RCODE_OK instead of returning NXDOMAIN.

This adds a test and fixes bug #10471

Signed-off-by: Kai Blin <kai@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
python/samba/tests/dns.py
source4/dns_server/dns_query.c

index 0ac9cf4b8b49480edf421ff498efc11a65d73105..bac8deabddcb44dc90884b86d5be5251d316c4a9 100644 (file)
@@ -171,6 +171,22 @@ class TestSimpleQueries(DNSTest):
         self.assertEquals(response.answers[0].rdata,
                           os.getenv('SERVER_IP'))
 
+    def test_one_mx_query(self):
+        "create a query packet causing an empty RCODE_OK answer"
+        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_MX, 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, 0)
+
     def test_two_queries(self):
         "create a query packet containing two query records"
         p = self.make_name_packet(dns.DNS_OPCODE_QUERY)
index 5414e1d9ee40adec7c944620a5d081da0308efa1..77f797bf5b256689039284a8cff2561fd354556d 100644 (file)
@@ -258,7 +258,7 @@ static WERROR handle_question(struct dns_server *dns,
                              struct dns_res_rec **answers, uint16_t *ancount)
 {
        struct dns_res_rec *ans = *answers;
-       WERROR werror;
+       WERROR werror, werror_return;
        unsigned int ri;
        struct dnsp_DnssrvRpcRecord *recs;
        uint16_t rec_count, ai = *ancount;
@@ -275,6 +275,9 @@ static WERROR handle_question(struct dns_server *dns,
                return WERR_NOMEM;
        }
 
+       /* Set up for an NXDOMAIN reply if no match is found */
+       werror_return = DNS_ERR(NAME_ERROR);
+
        for (ri = 0; ri < rec_count; ri++) {
                if ((recs[ri].wType == DNS_TYPE_CNAME) &&
                    ((question->question_type == DNS_QTYPE_A) ||
@@ -319,28 +322,27 @@ static WERROR handle_question(struct dns_server *dns,
                        if (!W_ERROR_IS_OK(werror)) {
                                return werror;
                        }
+                       werror_return = WERR_OK;
 
 
                        continue;
                }
                if ((question->question_type != DNS_QTYPE_ALL) &&
                    (recs[ri].wType != question->question_type)) {
+                       werror_return = WERR_OK;
                        continue;
                }
                werror = create_response_rr(question, &recs[ri], &ans, &ai);
                if (!W_ERROR_IS_OK(werror)) {
                        return werror;
                }
-       }
-
-       if (ai == 0) {
-               return DNS_ERR(NAME_ERROR);
+               werror_return = WERR_OK;
        }
 
        *ancount = ai;
        *answers = ans;
 
-       return WERR_OK;
+       return werror_return;
 }
 
 static NTSTATUS create_tkey(struct dns_server *dns,