dns: Always return SOA record for records we should know
authorSamuel Cabrero <scabrero@samba.org>
Tue, 8 Oct 2019 11:30:18 +0000 (13:30 +0200)
committerSamuel Cabrero <scabrero@sn-devel-184>
Fri, 8 Nov 2019 12:31:29 +0000 (12:31 +0000)
Regression introduced by commit 4b54e14b7cf456e327b176b365e8471e0899210b,
where the number of returned records is not set by talloc_array_length
when the record is not found.

Found by DELL EMC at SDC SMB3 plugfest trying to perform a secure DNS
update.

Signed-off-by: Samuel Cabrero <scabrero@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Autobuild-User(master): Samuel Cabrero <scabrero@samba.org>
Autobuild-Date(master): Fri Nov  8 12:31:30 UTC 2019 on sn-devel-184

source4/dns_server/dns_query.c

index b75fabe7e827591ada313365509991db9c773a70..762bcca6fb6503257bc77b4d73d8f4c641655a92 100644 (file)
@@ -645,20 +645,12 @@ static void handle_authoritative_done(struct tevent_req *subreq)
 
 static WERROR handle_authoritative_recv(struct tevent_req *req)
 {
-       struct handle_authoritative_state *state = tevent_req_data(
-               req, struct handle_authoritative_state);
        WERROR werr;
 
        if (tevent_req_is_werror(req, &werr)) {
                return werr;
        }
 
-       werr = add_zone_authority_record(state->dns, state, state->question,
-                                        state->nsrecs);
-       if (!W_ERROR_IS_OK(werr)) {
-               return werr;
-       }
-
        return WERR_OK;
 }
 
@@ -1091,6 +1083,7 @@ static void dns_server_process_query_got_auth(struct tevent_req *subreq)
        struct dns_server_process_query_state *state = tevent_req_data(
                req, struct dns_server_process_query_state);
        WERROR werr;
+       WERROR werr2;
 
        werr = handle_authoritative_recv(subreq);
        TALLOC_FREE(subreq);
@@ -1103,6 +1096,20 @@ static void dns_server_process_query_got_auth(struct tevent_req *subreq)
 
                /* If you have run out of forwarders, simply finish */
                if (state->forwarders == NULL) {
+                       werr2 = add_zone_authority_record(state->dns,
+                                                         state,
+                                                         state->question,
+                                                         &state->nsrecs);
+                       if (tevent_req_werror(req, werr2)) {
+                               DBG_WARNING("Failed to add SOA record: %s\n",
+                                           win_errstr(werr2));
+                               return;
+                       }
+
+                       state->ancount = talloc_array_length(state->answers);
+                       state->nscount = talloc_array_length(state->nsrecs);
+                       state->arcount = talloc_array_length(state->additional);
+
                        tevent_req_werror(req, werr);
                        return;
                }
@@ -1125,6 +1132,16 @@ static void dns_server_process_query_got_auth(struct tevent_req *subreq)
                return;
        }
 
+       werr2 = add_zone_authority_record(state->dns,
+                                         state,
+                                         state->question,
+                                         &state->nsrecs);
+       if (tevent_req_werror(req, werr2)) {
+               DBG_WARNING("Failed to add SOA record: %s\n",
+                               win_errstr(werr2));
+               return;
+       }
+
        state->ancount = talloc_array_length(state->answers);
        state->nscount = talloc_array_length(state->nsrecs);
        state->arcount = talloc_array_length(state->additional);