s4:dns_server: make sure dns_common_lookup() doesn't return tombstones
authorStefan Metzmacher <metze@samba.org>
Thu, 31 Jul 2014 06:54:17 +0000 (08:54 +0200)
committerStefan Metzmacher <metze@samba.org>
Tue, 26 Aug 2014 07:13:06 +0000 (09:13 +0200)
Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Michael Adam <obnox@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source4/dns_server/dns_utils.c
source4/dns_server/dnsserver_common.c
source4/dns_server/dnsserver_common.h

index c3a27fea5bbe400d096e047294a3049ab2a1382e..c757c1576266929335892c54666244ba008f12e0 100644 (file)
@@ -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,
index 3a777e5c1ebd503b34bac708536679de5e9f96dd..286673434711588b24aa479ac65689e7d7a3079a 100644 (file)
@@ -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);
        }
 
index 1117ad119102a1195558e7be5800f59b3ceadd3e..becd243f6a9e244528f4b32ed805257baddb1197 100644 (file)
@@ -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,