From ab5f7bf0153c768c46c6369ebe29091b699a9b12 Mon Sep 17 00:00:00 2001 From: Douglas Bagnall Date: Thu, 29 Nov 2018 16:20:43 +1300 Subject: [PATCH] WIP patch that counts CNAMEs explicitly --- source4/dns_server/dns_query.c | 52 +++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c index 65faeac3b6a..db5fcd01c96 100644 --- a/source4/dns_server/dns_query.c +++ b/source4/dns_server/dns_query.c @@ -49,7 +49,8 @@ struct forwarder_string { static WERROR add_response_rr(const char *name, const struct dnsp_DnssrvRpcRecord *rec, - struct dns_res_rec **answers) + struct dns_res_rec **answers, + uint *cname_count) { struct dns_res_rec *ans = *answers; uint16_t ai = talloc_array_length(ans); @@ -73,6 +74,7 @@ static WERROR add_response_rr(const char *name, case DNS_QTYPE_CNAME: ans[ai].rdata.cname_record = talloc_strdup(ans, rec->data.cname); W_ERROR_HAVE_NO_MEMORY(ans[ai].rdata.cname_record); + (*cname_count)++; break; case DNS_QTYPE_A: ans[ai].rdata.ipv4_record = talloc_strdup(ans, rec->data.ipv4); @@ -356,6 +358,7 @@ static WERROR add_zone_authority_record(struct dns_server *dns, struct ldb_dn *dn = NULL; unsigned int ri; WERROR werror; + uint cname_count = 0; zone = dns_get_authoritative_zone(dns, question->name); DEBUG(10, ("Creating zone authority record for '%s'\n", zone)); @@ -372,7 +375,8 @@ static WERROR add_zone_authority_record(struct dns_server *dns, for (ri = 0; ri < rec_count; ri++) { if (recs[ri].wType == DNS_TYPE_SOA) { - werror = add_response_rr(zone, &recs[ri], &ns); + werror = add_response_rr(zone, &recs[ri], &ns, + &cname_count); if (!W_ERROR_IS_OK(werror)) { return werror; } @@ -388,12 +392,14 @@ static struct tevent_req *handle_authoritative_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct dns_server *dns, const char *forwarder, struct dns_name_question *question, - struct dns_res_rec **answers, struct dns_res_rec **nsrecs); + struct dns_res_rec **answers, struct dns_res_rec **nsrecs, + uint *cname_count); static WERROR handle_authoritative_recv(struct tevent_req *req); struct handle_dnsrpcrec_state { struct dns_res_rec **answers; struct dns_res_rec **nsrecs; + uint *cname_count; }; static void handle_dnsrpcrec_gotauth(struct tevent_req *subreq); @@ -404,7 +410,8 @@ static struct tevent_req *handle_dnsrpcrec_send( struct dns_server *dns, const char *forwarder, const struct dns_name_question *question, struct dnsp_DnssrvRpcRecord *rec, - struct dns_res_rec **answers, struct dns_res_rec **nsrecs) + struct dns_res_rec **answers, struct dns_res_rec **nsrecs, + uint *cname_count) { struct tevent_req *req, *subreq; struct handle_dnsrpcrec_state *state; @@ -419,11 +426,7 @@ static struct tevent_req *handle_dnsrpcrec_send( } state->answers = answers; state->nsrecs = nsrecs; - - if (talloc_array_length(*answers) >= MAX_Q_RECURSION_DEPTH) { - tevent_req_done(req); - return tevent_req_post(req, ev); - } + state->cname_count = cname_count; resolve_cname = ((rec->wType == DNS_TYPE_CNAME) && ((question->question_type == DNS_QTYPE_A) || @@ -437,7 +440,7 @@ static struct tevent_req *handle_dnsrpcrec_send( return tevent_req_post(req, ev); } - werr = add_response_rr(question->name, rec, state->answers); + werr = add_response_rr(question->name, rec, state->answers, NULL); if (tevent_req_werror(req, werr)) { return tevent_req_post(req, ev); } @@ -446,10 +449,15 @@ static struct tevent_req *handle_dnsrpcrec_send( return tevent_req_post(req, ev); } - werr = add_response_rr(question->name, rec, state->answers); + werr = add_response_rr(question->name, rec, state->answers, + cname_count); if (tevent_req_werror(req, werr)) { return tevent_req_post(req, ev); } + if (*cname_count >= MAX_Q_RECURSION_DEPTH) { + tevent_req_done(req); + return tevent_req_post(req, ev); + } new_q = talloc(state, struct dns_name_question); if (tevent_req_nomem(new_q, req)) { @@ -465,7 +473,8 @@ static struct tevent_req *handle_dnsrpcrec_send( if (dns_authoritative_for_zone(dns, new_q->name)) { subreq = handle_authoritative_send( state, ev, dns, forwarder, new_q, - state->answers, state->nsrecs); + state->answers, state->nsrecs, + state->cname_count); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } @@ -549,6 +558,7 @@ struct handle_authoritative_state { struct dns_res_rec **answers; struct dns_res_rec **nsrecs; + uint cname_count; }; static void handle_authoritative_done(struct tevent_req *subreq); @@ -557,7 +567,8 @@ static struct tevent_req *handle_authoritative_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct dns_server *dns, const char *forwarder, struct dns_name_question *question, - struct dns_res_rec **answers, struct dns_res_rec **nsrecs) + struct dns_res_rec **answers, struct dns_res_rec **nsrecs, + uint *cname_count) { struct tevent_req *req, *subreq; struct handle_authoritative_state *state; @@ -575,6 +586,7 @@ static struct tevent_req *handle_authoritative_send( state->forwarder = forwarder; state->answers = answers; state->nsrecs = nsrecs; + state->cname_count = *cname_count; werr = dns_name2dn(dns, state, question->name, &dn); if (tevent_req_werror(req, werr)) { @@ -595,7 +607,8 @@ static struct tevent_req *handle_authoritative_send( subreq = handle_dnsrpcrec_send( state, state->ev, state->dns, state->forwarder, state->question, &state->recs[state->recs_done], - state->answers, state->nsrecs); + state->answers, state->nsrecs, + cname_count); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } @@ -627,7 +640,8 @@ static void handle_authoritative_done(struct tevent_req *subreq) subreq = handle_dnsrpcrec_send( state, state->ev, state->dns, state->forwarder, state->question, &state->recs[state->recs_done], - state->answers, state->nsrecs); + state->answers, state->nsrecs, + &state->cname_count); if (tevent_req_nomem(subreq, req)) { return; } @@ -925,6 +939,7 @@ struct dns_server_process_query_state { struct dns_res_rec *additional; uint16_t arcount; struct forwarder_string *forwarders; + uint cname_count; }; static void dns_server_process_query_got_auth(struct tevent_req *subreq); @@ -997,10 +1012,12 @@ struct tevent_req *dns_server_process_query_send( if (tevent_req_nomem(state->nsrecs, req)) { return tevent_req_post(req, ev); } + state->cname_count = 0; subreq = handle_authoritative_send( state, ev, dns, (forwarders == NULL ? NULL : forwarders[0]), - &in->questions[0], &state->answers, &state->nsrecs); + &in->questions[0], &state->answers, &state->nsrecs, + &state->cname_count); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } @@ -1102,7 +1119,8 @@ static void dns_server_process_query_got_auth(struct tevent_req *subreq) subreq = handle_authoritative_send(state, state->ev, state->dns, state->forwarders->forwarder, state->question, &state->answers, - &state->nsrecs); + &state->nsrecs, + &state->cname_count); if (tevent_req_nomem(subreq, req)) { return; -- 2.17.1