From f23aa6faad241de9adc477be6045289ba43c97d7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 31 Jul 2014 09:35:26 +0200 Subject: [PATCH] s4:dns_server: handle tombstones in handle_one_update() Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam Reviewed-by: Andrew Bartlett (cherry picked from commit 491715399ff7e1ab788fec5e254581dc312e2cef) --- source4/dns_server/dns_update.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/source4/dns_server/dns_update.c b/source4/dns_server/dns_update.c index 4ff82b4c097..04e7d9adff7 100644 --- a/source4/dns_server/dns_update.c +++ b/source4/dns_server/dns_update.c @@ -400,7 +400,9 @@ static WERROR handle_one_update(struct dns_server *dns, uint16_t rcount = 0; struct ldb_dn *dn; uint16_t i; + uint16_t first = 0; WERROR werror; + bool tombstoned = false; bool needs_add = false; DEBUG(2, ("Looking at record: \n")); @@ -428,23 +430,29 @@ static WERROR handle_one_update(struct dns_server *dns, werror = dns_name2dn(dns, mem_ctx, update->name, &dn); W_ERROR_NOT_OK_RETURN(werror); - werror = dns_lookup_records(dns, mem_ctx, dn, &recs, &rcount); + werror = dns_common_lookup(dns->samdb, mem_ctx, dn, + &recs, &rcount, &tombstoned); if (W_ERROR_EQUAL(werror, WERR_DNS_ERROR_NAME_DOES_NOT_EXIST)) { needs_add = true; werror = WERR_OK; } - if (W_ERROR_EQUAL(werror, DNS_ERR(NAME_ERROR))) { - werror = WERR_OK; - } W_ERROR_NOT_OK_RETURN(werror); + if (tombstoned) { + /* + * we need to keep the existing tombstone record + * and ignore it + */ + first = rcount; + } + if (update->rr_class == zone->question_class) { if (update->rr_type == DNS_QTYPE_CNAME) { /* * If there is a record in the directory * that's not a CNAME, ignore update */ - for (i = 0; i < rcount; i++) { + for (i = first; i < rcount; i++) { if (recs[i].wType != DNS_TYPE_CNAME) { DEBUG(5, ("Skipping update\n")); return WERR_OK; @@ -457,13 +465,14 @@ static WERROR handle_one_update(struct dns_server *dns, * per name, so replace everything with the new CNAME */ - rcount = 1; + rcount = first; recs = talloc_realloc(mem_ctx, recs, - struct dnsp_DnssrvRpcRecord, rcount); + struct dnsp_DnssrvRpcRecord, rcount + 1); W_ERROR_HAVE_NO_MEMORY(recs); - werror = dns_rr_to_dnsp(recs, update, &recs[0]); + werror = dns_rr_to_dnsp(recs, update, &recs[rcount]); W_ERROR_NOT_OK_RETURN(werror); + rcount += 1; werror = dns_replace_records(dns, mem_ctx, dn, needs_add, recs, rcount); @@ -475,7 +484,7 @@ static WERROR handle_one_update(struct dns_server *dns, * If there is a CNAME record for this name, * ignore update */ - for (i = 0; i < rcount; i++) { + for (i = first; i < rcount; i++) { if (recs[i].wType == DNS_TYPE_CNAME) { DEBUG(5, ("Skipping update\n")); return WERR_OK; @@ -490,7 +499,7 @@ static WERROR handle_one_update(struct dns_server *dns, * serial number is smaller than existing SOA's, * ignore update */ - for (i = 0; i < rcount; i++) { + for (i = first; i < rcount; i++) { if (recs[i].wType == DNS_TYPE_SOA) { uint16_t n, o; @@ -540,7 +549,7 @@ static WERROR handle_one_update(struct dns_server *dns, werror = dns_rr_to_dnsp(recs, update, &recs[rcount]); W_ERROR_NOT_OK_RETURN(werror); - for (i = 0; i < rcount; i++) { + for (i = first; i < rcount; i++) { if (!dns_records_match(&recs[i], &recs[rcount])) { continue; } @@ -562,7 +571,7 @@ static WERROR handle_one_update(struct dns_server *dns, } else if (update->rr_class == DNS_QCLASS_ANY) { if (update->rr_type == DNS_QTYPE_ALL) { if (dns_name_equal(update->name, zone->name)) { - for (i = 0; i < rcount; i++) { + for (i = first; i < rcount; i++) { if (recs[i].wType == DNS_TYPE_SOA) { continue; @@ -578,7 +587,7 @@ static WERROR handle_one_update(struct dns_server *dns, } } else { - for (i = 0; i < rcount; i++) { + for (i = first; i < rcount; i++) { recs[i] = (struct dnsp_DnssrvRpcRecord) { .wType = DNS_TYPE_TOMBSTONE, }; @@ -595,7 +604,7 @@ static WERROR handle_one_update(struct dns_server *dns, return WERR_OK; } } - for (i = 0; i < rcount; i++) { + for (i = first; i < rcount; i++) { if (recs[i].wType == update->rr_type) { recs[i] = (struct dnsp_DnssrvRpcRecord) { .wType = DNS_TYPE_TOMBSTONE, @@ -624,7 +633,7 @@ static WERROR handle_one_update(struct dns_server *dns, werror = dns_rr_to_dnsp(ns_rec, update, ns_rec); W_ERROR_NOT_OK_RETURN(werror); - for (i = 0; i < rcount; i++) { + for (i = first; i < rcount; i++) { if (dns_records_match(ns_rec, &recs[i])) { found = true; break; @@ -641,7 +650,7 @@ static WERROR handle_one_update(struct dns_server *dns, werror = dns_rr_to_dnsp(del_rec, update, del_rec); W_ERROR_NOT_OK_RETURN(werror); - for (i = 0; i < rcount; i++) { + for (i = first; i < rcount; i++) { if (dns_records_match(del_rec, &recs[i])) { recs[i] = (struct dnsp_DnssrvRpcRecord) { .wType = DNS_TYPE_TOMBSTONE, -- 2.11.4.GIT