From 2fbb9b9ce1b55257c3aad6a43df8f0c08456db2f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 31 Jul 2014 08:54:17 +0200 Subject: [PATCH] s4:dns_server: make sure dns_common_lookup() doesn't return tombstones 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 a0a81ab01cb1d509b04f9af25177c8e0941b43aa) --- source4/dns_server/dns_utils.c | 3 +- source4/dns_server/dnsserver_common.c | 53 ++++++++++++++++++++++++++++++++--- source4/dns_server/dnsserver_common.h | 3 +- 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/source4/dns_server/dns_utils.c b/source4/dns_server/dns_utils.c index c3a27fea5bb..c757c157626 100644 --- a/source4/dns_server/dns_utils.c +++ b/source4/dns_server/dns_utils.c @@ -154,7 +154,8 @@ WERROR dns_lookup_records(struct dns_server *dns, struct dnsp_DnssrvRpcRecord **records, uint16_t *rec_count) { - return dns_common_lookup(dns->samdb, mem_ctx, dn, records, rec_count); + return dns_common_lookup(dns->samdb, mem_ctx, dn, + records, rec_count, NULL); } WERROR dns_replace_records(struct dns_server *dns, diff --git a/source4/dns_server/dnsserver_common.c b/source4/dns_server/dnsserver_common.c index 3a777e5c1eb..28667343471 100644 --- a/source4/dns_server/dnsserver_common.c +++ b/source4/dns_server/dnsserver_common.c @@ -104,10 +104,12 @@ WERROR dns_common_lookup(struct ldb_context *samdb, TALLOC_CTX *mem_ctx, struct ldb_dn *dn, struct dnsp_DnssrvRpcRecord **records, - uint16_t *num_records) + uint16_t *num_records, + bool *tombstoned) { static const char * const attrs[] = { "dnsRecord", + "dNSTombstoned", NULL }; int ret; @@ -118,9 +120,16 @@ WERROR dns_common_lookup(struct ldb_context *samdb, *records = NULL; *num_records = 0; - ret = dsdb_search_one(samdb, mem_ctx, &msg, dn, - LDB_SCOPE_BASE, attrs, 0, - "(objectClass=dnsNode)"); + if (tombstoned != NULL) { + *tombstoned = false; + ret = dsdb_search_one(samdb, mem_ctx, &msg, dn, + LDB_SCOPE_BASE, attrs, 0, + "(objectClass=dnsNode)"); + } else { + ret = dsdb_search_one(samdb, mem_ctx, &msg, dn, + LDB_SCOPE_BASE, attrs, 0, + "(&(objectClass=dnsNode)(!(dNSTombstoned=TRUE)))"); + } if (ret == LDB_ERR_NO_SUCH_OBJECT) { return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST; } @@ -130,9 +139,45 @@ WERROR dns_common_lookup(struct ldb_context *samdb, return DNS_ERR(NAME_ERROR); } + if (tombstoned != NULL) { + *tombstoned = ldb_msg_find_attr_as_bool(msg, + "dNSTombstoned", false); + } + el = ldb_msg_find_element(msg, "dnsRecord"); if (el == NULL) { TALLOC_FREE(msg); + if (tombstoned != NULL) { + struct dnsp_DnssrvRpcRecord *recs; + /* + * records produced by older Samba releases + * keep dnsNode objects without dnsRecord and + * without setting dNSTombstoned=TRUE. + * + * We just pretend they're tombstones. + */ + recs = talloc_array(mem_ctx, + struct dnsp_DnssrvRpcRecord, + 1); + if (recs == NULL) { + return WERR_NOMEM; + } + recs[0] = (struct dnsp_DnssrvRpcRecord) { + .wType = DNS_TYPE_TOMBSTONE, + /* + * A value of timestamp != 0 + * indicated that the object was already + * a tombstone, this will be used + * in dns_common_replace() + */ + .data.timestamp = 1, + }; + + *tombstoned = true; + *records = recs; + *num_records = 1; + return WERR_OK; + } return DNS_ERR(NAME_ERROR); } diff --git a/source4/dns_server/dnsserver_common.h b/source4/dns_server/dnsserver_common.h index 1117ad11910..becd243f6a9 100644 --- a/source4/dns_server/dnsserver_common.h +++ b/source4/dns_server/dnsserver_common.h @@ -36,7 +36,8 @@ WERROR dns_common_lookup(struct ldb_context *samdb, TALLOC_CTX *mem_ctx, struct ldb_dn *dn, struct dnsp_DnssrvRpcRecord **records, - uint16_t *num_records); + uint16_t *num_records, + bool *tombstoned); WERROR dns_common_replace(struct ldb_context *samdb, TALLOC_CTX *mem_ctx, -- 2.11.4.GIT