[PATCH 5/5] dns: always add authority records
Kai Blin
kai at samba.org
Thu Jul 30 09:53:24 UTC 2015
For some reason this breaks when we don't have an error code to return.
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 | 7 +++++--
3 files changed, 39 insertions(+), 26 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..8c2f99e 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..2c447dd 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) {
@@ -364,7 +368,6 @@ static void dns_tcp_call_process_done(struct tevent_req *subreq)
err = dns_process_recv(subreq, call, &call->out);
TALLOC_FREE(subreq);
if (!W_ERROR_IS_OK(err)) {
- DEBUG(1, ("dns_process returned %s\n", win_errstr(err)));
dns_tcp_terminate_connection(dns_conn,
"dns_tcp_call_loop: process function failed");
return;
--
1.9.1
More information about the samba-technical
mailing list