]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
dns scavenging: ensure usual ownership of element values
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Mon, 29 Mar 2021 00:11:01 +0000 (13:11 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Sun, 20 Jun 2021 23:26:32 +0000 (23:26 +0000)
An ldb message, its elements, and their values usually all share a
little talloc sub-tree with each other and nobody else. It is
conceivable that somewhere we rely on that.

In this case we were sharing an out-of-subtree values array across
multiple messages, which seems to be asking for trouble.

Also, add a comment explaining what we want.

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source4/dsdb/kcc/scavenge_dns_records.c

index c64580717c91e4ed1a202f13908346d1bc3afadd..322ab6bcd01a16627a4d8d714d3552ea550b074f 100644 (file)
@@ -229,9 +229,30 @@ NTSTATUS dns_tombstone_records_zone(TALLOC_CTX *mem_ctx,
                        continue;
                }
 
-               /* If everything was expired, we tombstone the node. */
+               /*
+                * If everything was expired, we tombstone the node, which
+                * involves adding a tombstone dnsRecord and a 'dnsTombstoned:
+                * TRUE' attribute. That is, we want to end up with this:
+                *
+                *  objectClass: dnsNode
+                *  dnsRecord:  { .wType = DNSTYPE_TOMBSTONE,
+                *                .data.EntombedTime = <now> }
+                *  dnsTombstoned: TRUE
+                *
+                * and no other dnsRecords.
+                */
                if (el->num_values == 0) {
-                       el->values = tombstone_blob;
+                       struct ldb_val *vals = talloc_realloc(new_msg->elements,
+                                                             el->values,
+                                                             struct ldb_val,
+                                                             1);
+                       if (!vals) {
+                               TALLOC_FREE(old_msg);
+                               TALLOC_FREE(new_msg);
+                               return NT_STATUS_INTERNAL_ERROR;
+                       }
+                       el->values = vals;
+                       el->values[0] = *tombstone_blob;
                        el->num_values = 1;
 
                        tombstone_el = ldb_msg_find_element(new_msg,
@@ -248,8 +269,22 @@ NTSTATUS dns_tombstone_records_zone(TALLOC_CTX *mem_ctx,
                                }
                                tombstone_el->flags = LDB_FLAG_MOD_ADD;
                        } else {
+                               if (tombstone_el->num_values != 1) {
+                                       vals = talloc_realloc(
+                                               new_msg->elements,
+                                               tombstone_el->values,
+                                               struct ldb_val,
+                                               1);
+                                       if (!vals) {
+                                               TALLOC_FREE(old_msg);
+                                               TALLOC_FREE(new_msg);
+                                               return NT_STATUS_INTERNAL_ERROR;
+                                       }
+                                       tombstone_el->values = vals;
+                                       tombstone_el->num_values = 1;
+                               }
                                tombstone_el->flags = LDB_FLAG_MOD_REPLACE;
-                               tombstone_el->values = true_struct;
+                               tombstone_el->values[0] = *true_struct;
                        }
                        tombstone_el->num_values = 1;
                } else {