The branch, master has been updated
       via  42f38fe dns: always add authority records
       via  d9a3f19 dns: Add a SOA record to error replies
       via  bda1a73 dns: Also pass nsrecs to handle_question()
       via  0e11c08 dns: Just pass the name to create_response_rr
       via  d7a54f3 dns: Add dns_get_authoritative_zone helper function
      from  54cbecb script/librelease.sh: this is replaced by script/release.sh 
now

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 42f38fe8d9a34a9d3710dcddfe642257f41ece87
Author: Kai Blin <[email protected]>
Date:   Fri Jul 17 15:27:51 2015 +0200

    dns: always add authority records
    
    Signed-off-by: Kai Blin <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>
    
    Autobuild-User(master): Kai Blin <[email protected]>
    Autobuild-Date(master): Thu Aug  6 14:06:52 CEST 2015 on sn-devel-104

commit d9a3f197495951f2b85e042f1bc4525bab389879
Author: Kai Blin <[email protected]>
Date:   Wed Oct 29 13:41:53 2014 +0100

    dns: Add a SOA record to error replies
    
    Signed-off-by: Kai Blin <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

commit bda1a7320f72049cf7aad2233899eaf2a55d6973
Author: Kai Blin <[email protected]>
Date:   Wed Oct 29 13:39:16 2014 +0100

    dns: Also pass nsrecs to handle_question()
    
    Signed-off-by: Kai Blin <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

commit 0e11c08d3e11c83b21e1366e9e91b6d841fbbd6c
Author: Kai Blin <[email protected]>
Date:   Wed Oct 29 13:36:58 2014 +0100

    dns: Just pass the name to create_response_rr
    
    Signed-off-by: Kai Blin <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

commit d7a54f33ef5d4f45127c9264f0c4f16a2a8a6541
Author: Kai Blin <[email protected]>
Date:   Wed Oct 29 13:35:36 2014 +0100

    dns: Add dns_get_authoritative_zone helper function
    
    Signed-off-by: Kai Blin <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

-----------------------------------------------------------------------

Summary of changes:
 python/samba/tests/dns.py       | 34 +++++++--------
 source4/dns_server/dns_query.c  | 96 ++++++++++++++++++++++++++++++++++-------
 source4/dns_server/dns_server.c |  6 ++-
 source4/dns_server/dns_server.h |  2 +
 source4/dns_server/dns_utils.c  | 16 +++++++
 5 files changed, 121 insertions(+), 33 deletions(-)


Changeset truncated at 500 lines:

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 3cafc23..94f5d49 100644
--- a/source4/dns_server/dns_query.c
+++ b/source4/dns_server/dns_query.c
@@ -40,7 +40,7 @@
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_DNS
 
-static WERROR create_response_rr(const struct dns_name_question *question,
+static WERROR create_response_rr(const char *name,
                                 const struct dnsp_DnssrvRpcRecord *rec,
                                 struct dns_res_rec **answers, uint16_t 
*ancount)
 {
@@ -116,7 +116,7 @@ static WERROR create_response_rr(const struct 
dns_name_question *question,
                return DNS_ERR(NOT_IMPLEMENTED);
        }
 
-       ans[ai].name = talloc_strdup(ans, question->name);
+       ans[ai].name = talloc_strdup(ans, name);
        W_ERROR_HAVE_NO_MEMORY(ans[ai].name);
        ans[ai].rr_type = rec->wType;
        ans[ai].rr_class = DNS_QCLASS_IN;
@@ -253,23 +253,76 @@ static WERROR ask_forwarder_recv(
        return WERR_OK;
 }
 
+static WERROR add_zone_authority_record(struct dns_server *dns,
+                                       TALLOC_CTX *mem_ctx,
+                                       const struct dns_name_question 
*question,
+                                       struct dns_res_rec **nsrecs, uint16_t 
*nscount)
+{
+       const char *zone = NULL;
+       struct dnsp_DnssrvRpcRecord *recs;
+       struct dns_res_rec *ns = *nsrecs;
+       uint16_t rec_count, ni = *nscount;
+       struct ldb_dn *dn = NULL;
+       unsigned int ri;
+       WERROR werror;
+
+       zone = dns_get_authoritative_zone(dns, question->name);
+       DEBUG(10, ("Creating zone authority record for '%s'\n", zone));
+
+       werror = dns_name2dn(dns, mem_ctx, zone, &dn);
+       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)) {
+               return werror;
+       }
+
+       ns = talloc_realloc(mem_ctx, ns, struct dns_res_rec, rec_count + ni);
+       if (ns == NULL) {
+               return WERR_NOMEM;
+       }
+       for (ri = 0; ri < rec_count; ri++) {
+               if (recs[ri].wType == DNS_TYPE_SOA) {
+                       werror = create_response_rr(zone, &recs[ri], &ns, &ni);
+                       if (!W_ERROR_IS_OK(werror)) {
+                               return werror;
+                       }
+               }
+       }
+
+       *nscount = ni;
+       *nsrecs = ns;
+
+       return WERR_OK;
+}
+
+
 static WERROR handle_question(struct dns_server *dns,
                              TALLOC_CTX *mem_ctx,
                              const struct dns_name_question *question,
-                             struct dns_res_rec **answers, uint16_t *ancount)
+                             struct dns_res_rec **answers, uint16_t *ancount,
+                             struct dns_res_rec **nsrecs, uint16_t *nscount)
 {
        struct dns_res_rec *ans = *answers;
+       struct dns_res_rec *ns = *nsrecs;
        WERROR werror, werror_return;
        unsigned int ri;
        struct dnsp_DnssrvRpcRecord *recs;
-       uint16_t rec_count, ai = *ancount;
+       uint16_t rec_count, ai = *ancount, ni = *nscount;
        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);
-       W_ERROR_NOT_OK_RETURN(werror);
+       if (!W_ERROR_IS_OK(werror)) {
+               werror_return = werror;
+               goto done;
+       }
 
        ans = talloc_realloc(mem_ctx, ans, struct dns_res_rec, rec_count + ai);
        if (ans == NULL) {
@@ -299,7 +352,7 @@ static WERROR handle_question(struct dns_server *dns,
                        }
 
                        /* First put in the CNAME record */
-                       werror = create_response_rr(question, &recs[ri], &ans, 
&ai);
+                       werror = create_response_rr(question->name, &recs[ri], 
&ans, &ai);
                        if (!W_ERROR_IS_OK(werror)) {
                                return werror;
                        }
@@ -315,9 +368,9 @@ static WERROR handle_question(struct dns_server *dns,
                                return WERR_NOMEM;
                        }
                        /* and then call the lookup again */
-                       werror = handle_question(dns, mem_ctx, new_q, &ans, 
&ai);
+                       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;
 
@@ -329,15 +382,21 @@ static WERROR handle_question(struct dns_server *dns,
                        werror_return = WERR_OK;
                        continue;
                }
-               werror = create_response_rr(question, &recs[ri], &ans, &ai);
+               werror = create_response_rr(question->name, &recs[ri], &ans, 
&ai);
                if (!W_ERROR_IS_OK(werror)) {
                        return werror;
                }
                werror_return = WERR_OK;
        }
 
+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;
+       *nsrecs = ns;
 
        return werror_return;
 }
@@ -612,9 +671,12 @@ struct tevent_req *dns_server_process_query_send(
 
                req_state->flags |= DNS_FLAG_AUTHORITATIVE;
                err = handle_question(dns, state, &in->questions[0],
-                                     &state->answers, &state->ancount);
+                                     &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);
@@ -668,10 +730,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;
@@ -679,5 +745,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) {
diff --git a/source4/dns_server/dns_server.h b/source4/dns_server/dns_server.h
index 3423ee0..64b716a 100644
--- a/source4/dns_server/dns_server.h
+++ b/source4/dns_server/dns_server.h
@@ -93,6 +93,8 @@ bool dns_records_match(struct dnsp_DnssrvRpcRecord *rec1,
                       struct dnsp_DnssrvRpcRecord *rec2);
 bool dns_authorative_for_zone(struct dns_server *dns,
                              const char *name);
+const char *dns_get_authoritative_zone(struct dns_server *dns,
+                                      const char *name);
 WERROR dns_lookup_records(struct dns_server *dns,
                          TALLOC_CTX *mem_ctx,
                          struct ldb_dn *dn,
diff --git a/source4/dns_server/dns_utils.c b/source4/dns_server/dns_utils.c
index c757c15..28412eb 100644
--- a/source4/dns_server/dns_utils.c
+++ b/source4/dns_server/dns_utils.c
@@ -199,6 +199,22 @@ bool dns_authorative_for_zone(struct dns_server *dns,
        return true;
 }
 
+const char *dns_get_authoritative_zone(struct dns_server *dns,
+                                      const char *name)
+{
+       const struct dns_server_zone *z;
+       size_t host_part_len = 0;
+
+       for (z = dns->zones; z != NULL; z = z->next) {
+               bool match;
+               match = dns_name_match(z->name, name, &host_part_len);
+               if (match) {
+                       return z->name;
+               }
+       }
+       return NULL;
+}
+
 WERROR dns_name2dn(struct dns_server *dns,
                   TALLOC_CTX *mem_ctx,
                   const char *name,


-- 
Samba Shared Repository

Reply via email to