From 9a935ea30587f4103a8765fb7b78010cfab917c8 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Thu, 27 Feb 2014 23:49:24 +0100 Subject: [PATCH 1/2] bug #10471: Don't respond with NXDOMAIN to records that exist with another type 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 Reviewed-by: Andrew Bartlett (cherry picked from commit d9829df13317b38677d92a499134727ab31fbb0e) --- python/samba/tests/dns.py | 16 ++++++++++++++++ source4/dns_server/dns_query.c | 14 ++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/python/samba/tests/dns.py b/python/samba/tests/dns.py index 0ac9cf4..bac8dea 100644 --- a/python/samba/tests/dns.py +++ b/python/samba/tests/dns.py @@ -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) diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c index 5414e1d..77f797b 100644 --- a/source4/dns_server/dns_query.c +++ b/source4/dns_server/dns_query.c @@ -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, -- 1.9.0 From a269a517e320320a632f3afb54b482d71e034056 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Fri, 28 Feb 2014 10:35:07 +0100 Subject: [PATCH 2/2] dns: Extend tests for records with another type Add another check to the one added for bug #10471, for added paranoia Signed-off-by: Kai Blin Reviewed-by: Andrew Bartlett Autobuild-User(master): Kai Blin Autobuild-Date(master): Tue Mar 4 15:47:10 CET 2014 on sn-devel-104 (cherry picked from commit 5bd47bb563c3736b9de1a3a93bdf46a498928643) --- python/samba/tests/dns.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/python/samba/tests/dns.py b/python/samba/tests/dns.py index bac8dea..f2c5685 100644 --- a/python/samba/tests/dns.py +++ b/python/samba/tests/dns.py @@ -187,6 +187,20 @@ class TestSimpleQueries(DNSTest): self.assert_dns_opcode_equals(response, dns.DNS_OPCODE_QUERY) self.assertEquals(response.ancount, 0) + p = self.make_name_packet(dns.DNS_OPCODE_QUERY) + questions = [] + + name = "invalid-%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_NXDOMAIN) + 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) -- 1.9.0