From ec5f3b5517e589fcf511641db00143079fc008ac Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Wed, 29 Oct 2014 13:35:36 +0100 Subject: [PATCH 1/4] dns: Add dns_get_authoritative_zone helper function Signed-off-by: Kai Blin --- source4/dns_server/dns_server.h | 2 ++ source4/dns_server/dns_utils.c | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) 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, -- 1.9.1 From 223ebb87abefd5e503591b648de5131c6f87aa6b Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Wed, 29 Oct 2014 13:36:58 +0100 Subject: [PATCH 2/4] dns: Just pass the name to create_response_rr Signed-off-by: Kai Blin --- source4/dns_server/dns_query.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c index 4e3c6cc..901d6b9 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) { @@ -115,7 +115,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; @@ -298,7 +298,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; } @@ -332,7 +332,7 @@ 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; } -- 1.9.1 From f976bda6915304bf11ff988de84fde56fc2b15ef Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Wed, 29 Oct 2014 13:39:16 +0100 Subject: [PATCH 3/4] dns: Also pass nsrecs to handle_question() Signed-off-by: Kai Blin --- source4/dns_server/dns_query.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c index 901d6b9..7355650 100644 --- a/source4/dns_server/dns_query.c +++ b/source4/dns_server/dns_query.c @@ -255,13 +255,15 @@ static WERROR ask_forwarder_recv( 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); @@ -318,7 +320,7 @@ 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; } @@ -339,8 +341,11 @@ static WERROR handle_question(struct dns_server *dns, werror_return = WERR_OK; } +done: *ancount = ai; *answers = ans; + *nscount = ni; + *nsrecs = ns; return werror_return; } @@ -615,7 +620,8 @@ 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); } -- 1.9.1 From 911944f9e363aa678ac727473d12ba37d3b5dcea Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Wed, 29 Oct 2014 13:41:53 +0100 Subject: [PATCH 4/4] dns: Add a SOA record to error replies Signed-off-by: Kai Blin --- source4/dns_server/dns_query.c | 52 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c index 7355650..8ffe5a5 100644 --- a/source4/dns_server/dns_query.c +++ b/source4/dns_server/dns_query.c @@ -252,6 +252,52 @@ 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, @@ -270,7 +316,11 @@ static WERROR handle_question(struct dns_server *dns, W_ERROR_NOT_OK_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; + add_zone_authority_record(dns, mem_ctx, question, &ns, &ni); + goto done; + } ans = talloc_realloc(mem_ctx, ans, struct dns_res_rec, rec_count + ai); if (ans == NULL) { -- 1.9.1