The branch, master has been updated
       via  e697151 copyright: Add the missing notices for garbage collect 
tombstones
       via  2dfedff dsdb: refactor part of garbage_collect_tombstones into new 
function
      from  e0ef054 script/release.sh: use 8 byte gpg key ids

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit e69715138fe14d8dc51f65cf5986b178c98f40a2
Author: Bob Campbell <bobcampb...@catalyst.net.nz>
Date:   Mon Sep 5 11:24:19 2016 +1200

    copyright: Add the missing notices for garbage collect tombstones
    
    Signed-off-by: Bob Campbell <bobcampb...@catalyst.net.nz>
    Signed-off-by: Garming Sam <garm...@catalyst.net.nz>
    
    Reviewed-by: Andrew Bartlett <abart...@samba.org>
    
    Autobuild-User(master): Garming Sam <garm...@samba.org>
    Autobuild-Date(master): Mon Sep  5 08:14:26 CEST 2016 on sn-devel-144

commit 2dfedffb740ecfe898945a9fc47b24e3c8328d7e
Author: Bob Campbell <bobcampb...@catalyst.net.nz>
Date:   Mon Sep 5 10:48:13 2016 +1200

    dsdb: refactor part of garbage_collect_tombstones into new function
    
    Pair-programmed-with: Garming Sam <garm...@catalyst.net.nz>
    
    Signed-off-by: Bob Campbell <bobcampb...@catalyst.net.nz>
    Signed-off-by: Garming Sam <garm...@catalyst.net.nz>
    
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source4/dsdb/kcc/garbage_collect_tombstones.c | 387 +++++++++++++++-----------
 1 file changed, 218 insertions(+), 169 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/kcc/garbage_collect_tombstones.c 
b/source4/dsdb/kcc/garbage_collect_tombstones.c
index 8d2ea8b..ad14d5e 100644
--- a/source4/dsdb/kcc/garbage_collect_tombstones.c
+++ b/source4/dsdb/kcc/garbage_collect_tombstones.c
@@ -4,6 +4,8 @@
    handle removal of deleted objects
 
    Copyright (C) 2009 Andrew Tridgell
+   Copyright (C) 2016 Andrew Bartlett
+   Copyright (C) 2016 Catalyst.NET Ltd
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -33,6 +35,209 @@
 #include "lib/ldb-samba/ldb_matching_rules.h"
 #include "lib/util/time.h"
 
+static NTSTATUS garbage_collect_tombstones_part(TALLOC_CTX *mem_ctx,
+                                               struct ldb_context *samdb,
+                                               struct dsdb_ldb_dn_list_node 
*part,
+                                               char *filter,
+                                               unsigned int *num_links_removed,
+                                               unsigned int 
*num_objects_removed,
+                                               struct dsdb_schema *schema,
+                                               const char **attrs,
+                                               char **error_string,
+                                               NTTIME expunge_time_nttime)
+{
+       int ret;
+       struct ldb_dn *do_dn;
+       struct ldb_result *res;
+       unsigned int i, j, k;
+       uint32_t flags;
+       TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+       if (!tmp_ctx) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       ret = dsdb_get_deleted_objects_dn(samdb, tmp_ctx, part->dn, &do_dn);
+       if (ret != LDB_SUCCESS) {
+               TALLOC_FREE(tmp_ctx);
+               /* some partitions have no Deleted Objects
+                  container */
+               return NT_STATUS_OK;
+       }
+
+       DEBUG(1, ("Doing a full scan on %s and looking for deleted objects\n",
+                 ldb_dn_get_linearized(part->dn)));
+
+       flags = DSDB_SEARCH_SHOW_RECYCLED |
+               DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT |
+               DSDB_SEARCH_REVEAL_INTERNALS;
+       ret = dsdb_search(samdb, tmp_ctx, &res, part->dn, LDB_SCOPE_SUBTREE,
+                         attrs, flags, "%s", filter);
+
+       if (ret != LDB_SUCCESS) {
+               *error_string = talloc_asprintf(mem_ctx,
+                                               "Failed to search for deleted "
+                                               "objects in %s: %s",
+                                               ldb_dn_get_linearized(do_dn),
+                                               ldb_errstring(samdb));
+               TALLOC_FREE(tmp_ctx);
+               return NT_STATUS_INTERNAL_ERROR;
+       }
+
+       for (i=0; i<res->count; i++) {
+               struct ldb_message *cleanup_msg = NULL;
+               unsigned int num_modified = 0;
+
+               bool isDeleted = ldb_msg_find_attr_as_bool(res->msgs[i],
+                                                          "isDeleted", false);
+               if (isDeleted) {
+                       if (ldb_dn_compare(do_dn, res->msgs[i]->dn) == 0) {
+                               /* Skip the Deleted Object Container */
+                               continue;
+                       }
+
+                       ret = dsdb_delete(samdb, res->msgs[i]->dn,
+                                         DSDB_SEARCH_SHOW_RECYCLED
+                                         |DSDB_MODIFY_RELAX);
+                       if (ret != LDB_SUCCESS) {
+                               DEBUG(1,(__location__ ": Failed to remove "
+                                        "deleted object %s\n",
+                                        ldb_dn_get_linearized(res->
+                                                              msgs[i]->dn)));
+                       } else {
+                               DEBUG(4,("Removed deleted object %s\n",
+                                        ldb_dn_get_linearized(res->
+                                                              msgs[i]->dn)));
+                               (*num_objects_removed)++;
+                       }
+                       continue;
+               }
+
+               /* This must have a linked attribute */
+
+               /*
+                * From MS-ADTS 3.1.1.1.9 DCs, usn Counters, and
+                * the Originating Update Stamp
+                *
+                * "A link value r is deleted, but exists as a
+                *  tombstone, if r.stamp.timeDeleted ≠ 0. When
+                *  the current time minus r.stamp.timeDeleted
+                *  exceeds the tombstone lifetime, the link
+                *  value r is garbage-collected; that is,
+                *  removed from its containing forward link
+                *  attribute. "
+                */
+
+               for (j=0; j < res->msgs[i]->num_elements; j++) {
+                       struct ldb_message_element *element = NULL;
+                       /* TODO this is O(log n) per attribute with deleted 
values */
+                       const struct dsdb_attribute *attrib = NULL;
+
+                       element = &res->msgs[i]->elements[j];
+                       attrib = dsdb_attribute_by_lDAPDisplayName(schema,
+                                                                  
element->name);
+
+                       /* This avoids parsing isDeleted as a link */
+                       if (attrib->linkID == 0 || ((attrib->linkID & 1) == 1)) 
{
+                               continue;
+                       }
+
+                       for (k = 0; k < element->num_values; k++) {
+                               struct ldb_val *value = &element->values[k];
+                               uint64_t whenChanged = 0;
+                               NTSTATUS status;
+                               struct dsdb_dn *dn;
+                               struct ldb_message_element *cleanup_elem = NULL;
+                               char *guid_search_str = NULL;
+                               char *guid_buf_str = NULL;
+                               struct ldb_val cleanup_val;
+                               struct GUID_txt_buf buf_guid;
+                               struct GUID guid;
+                               const struct ldb_val *guid_blob;
+
+                               if (dsdb_dn_is_deleted_val(value) == false) {
+                                       continue;
+                               }
+
+                               dn = dsdb_dn_parse(tmp_ctx, samdb,
+                                                  &element->values[k],
+                                                  attrib->syntax->ldap_oid);
+                               if (dn == NULL) {
+                                       DEBUG(1, ("Failed to parse linked 
attribute blob of "
+                                                 "%s on %s while expunging 
expired links\n",
+                                                 element->name,
+                                                 
ldb_dn_get_linearized(res->msgs[i]->dn)));
+                                       continue;
+                               }
+
+                               status = dsdb_get_extended_dn_uint64(dn->dn,
+                                                                    
&whenChanged,
+                                                                    
"RMD_CHANGETIME");
+                               if (!NT_STATUS_IS_OK(status)) {
+                                       DEBUG(1, ("Error: RMD_CHANGETIME is 
missing on a forward link.\n"));
+                                       talloc_free(dn);
+                                       continue;
+                               }
+
+                               if (whenChanged >= expunge_time_nttime) {
+                                       talloc_free(dn);
+                                       continue;
+                               }
+
+                               guid_blob = 
ldb_dn_get_extended_component(dn->dn, "GUID");
+                               status = GUID_from_ndr_blob(guid_blob, &guid);
+                               if (!NT_STATUS_IS_OK(status)) {
+                                       DEBUG(1, ("Error: Invalid GUID on link 
target.\n"));
+                                       talloc_free(dn);
+                                       continue;
+                               }
+
+                               guid_buf_str = GUID_buf_string(&guid, 
&buf_guid);
+                               guid_search_str = talloc_asprintf(mem_ctx,
+                                                                 "<GUID=%s>",
+                                                                 guid_buf_str);
+                               cleanup_val = 
data_blob_string_const(guid_search_str);
+
+                               talloc_free(dn);
+
+                               if (cleanup_msg == NULL) {
+                                       cleanup_msg = ldb_msg_new(mem_ctx);
+                                       if (cleanup_msg == NULL) {
+                                               return NT_STATUS_NO_MEMORY;
+                                       }
+                                       cleanup_msg->dn = res->msgs[i]->dn;
+                               }
+
+                               ret = ldb_msg_add_value(cleanup_msg,
+                                                       element->name,
+                                                       &cleanup_val,
+                                                       &cleanup_elem);
+                               if (ret != LDB_SUCCESS) {
+                                       return NT_STATUS_NO_MEMORY;
+                               }
+                               cleanup_elem->flags = LDB_FLAG_MOD_DELETE;
+                               num_modified++;
+                       }
+               }
+
+               if (num_modified > 0) {
+                       ret = dsdb_modify(samdb, cleanup_msg,
+                                         DSDB_REPLMD_VANISH_LINKS);
+                       if (ret != LDB_SUCCESS) {
+                               DEBUG(1,(__location__ ": Failed to remove 
deleted object %s\n",
+                                        
ldb_dn_get_linearized(res->msgs[i]->dn)));
+                       } else {
+                               DEBUG(4,("Removed deleted object %s\n",
+                                        
ldb_dn_get_linearized(res->msgs[i]->dn)));
+                               *num_links_removed = *num_links_removed + 
num_modified;
+                       }
+
+               }
+       }
+
+       TALLOC_FREE(tmp_ctx);
+       return NT_STATUS_OK;
+}
+
 /*
  * Per MS-ADTS 3.1.1.5.5 Delete Operation
  *
@@ -58,11 +263,9 @@ NTSTATUS dsdb_garbage_collect_tombstones(TALLOC_CTX 
*mem_ctx,
                                         unsigned int *num_links_removed,
                                         char **error_string)
 {
-       int ret;
-
        const char **attrs = NULL;
        char *filter = NULL;
-
+       NTSTATUS status;
        unsigned int i;
        struct dsdb_attribute *next_attr;
        unsigned int num_link_attrs;
@@ -117,178 +320,24 @@ NTSTATUS dsdb_garbage_collect_tombstones(TALLOC_CTX 
*mem_ctx,
        attrs[i] = "isDeleted";
        attrs[i+1] = NULL;
 
-       filter = talloc_asprintf_append(filter, 
"(&(isDeleted=TRUE)(whenChanged<=%s)))", expunge_time_string);
+       filter = talloc_asprintf_append(filter,
+                                       "(&(isDeleted=TRUE)(whenChanged<=%s)))",
+                                       expunge_time_string);
        if (filter == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       schema = dsdb_get_schema(samdb, mem_ctx);
-
        for (; part != NULL; part = part->next) {
-               struct ldb_dn *do_dn;
-               struct ldb_result *res;
-               unsigned int j, k;
-               uint32_t flags;
-               TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
-               if (!tmp_ctx) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-
-               ret = dsdb_get_deleted_objects_dn(samdb, tmp_ctx, part->dn, 
&do_dn);
-               if (ret != LDB_SUCCESS) {
-                       TALLOC_FREE(tmp_ctx);
-                       /* some partitions have no Deleted Objects
-                          container */
-                       continue;
-               }
-
-               DEBUG(1, ("Doing a full scan on %s and looking for deleted 
objects\n",
-                         ldb_dn_get_linearized(part->dn)));
-
-               flags = DSDB_SEARCH_SHOW_RECYCLED |
-                       DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT |
-                       DSDB_SEARCH_REVEAL_INTERNALS;
-               ret = dsdb_search(samdb, tmp_ctx, &res, part->dn, 
LDB_SCOPE_SUBTREE,
-                                 attrs, flags, "%s", filter);
-
-               if (ret != LDB_SUCCESS) {
-                       *error_string = talloc_asprintf(mem_ctx, "Failed to 
search for deleted objects in %s: %s",
-                                                       
ldb_dn_get_linearized(do_dn),
-                                                       ldb_errstring(samdb));
-                       TALLOC_FREE(tmp_ctx);
-                       return NT_STATUS_INTERNAL_ERROR;
+               status = garbage_collect_tombstones_part(mem_ctx, samdb, part,
+                                                        filter,
+                                                        num_links_removed,
+                                                        num_objects_removed,
+                                                        schema, attrs,
+                                                        error_string,
+                                                        expunge_time_nttime);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
                }
-
-               for (i=0; i<res->count; i++) {
-                       struct ldb_message *cleanup_msg = NULL;
-                       unsigned int num_modified = 0;
-
-                       bool isDeleted = 
ldb_msg_find_attr_as_bool(res->msgs[i], "isDeleted", false);
-                       if (isDeleted) {
-                               if (ldb_dn_compare(do_dn, res->msgs[i]->dn) == 
0) {
-                                       /* Skip the Deleted Object Container */
-                                       continue;
-                               }
-
-                               ret = dsdb_delete(samdb, res->msgs[i]->dn, 
DSDB_SEARCH_SHOW_RECYCLED|DSDB_MODIFY_RELAX);
-                               if (ret != LDB_SUCCESS) {
-                                       DEBUG(1,(__location__ ": Failed to 
remove deleted object %s\n",
-                                                
ldb_dn_get_linearized(res->msgs[i]->dn)));
-                               } else {
-                                       DEBUG(4,("Removed deleted object %s\n",
-                                                
ldb_dn_get_linearized(res->msgs[i]->dn)));
-                                       (*num_objects_removed)++;
-                               }
-                               continue;
-                       }
-
-                       /* This must have a linked attribute */
-
-                       /*
-                        * From MS-ADTS 3.1.1.1.9 DCs, usn Counters, and the 
Originating Update Stamp
-                        *
-                        * "A link value r is deleted, but exists as a
-                        *  tombstone, if r.stamp.timeDeleted ≠ 0. When
-                        *  the current time minus r.stamp.timeDeleted
-                        *  exceeds the tombstone lifetime, the link
-                        *  value r is garbage-collected; that is,
-                        *  removed from its containing forward link
-                        *  attribute. "
-                        */
-
-                       for (j=0; j < res->msgs[i]->num_elements; j++) {
-                               struct ldb_message_element *element = 
&res->msgs[i]->elements[j];
-                               /* TODO this is O(log n) per attribute with 
deleted values */
-                               const struct dsdb_attribute *attrib
-                                       = 
dsdb_attribute_by_lDAPDisplayName(schema, element->name);
-
-                               /* This avoids parsing isDeleted as a link */
-                               if (attrib->linkID == 0 || ((attrib->linkID & 
1) == 1)) {
-                                       continue;
-                               }
-
-                               for (k = 0; k < element->num_values; k++) {
-                                       struct ldb_val *value = 
&element->values[k];
-                                       uint64_t whenChanged = 0;
-                                       NTSTATUS status;
-                                       struct dsdb_dn *dn;
-                                       struct ldb_message_element 
*cleanup_elem = NULL;
-                                       char *guid_search_str = NULL, 
*guid_buf_str = NULL;
-                                       struct ldb_val cleanup_val;
-                                       struct GUID_txt_buf buf_guid;
-                                       struct GUID guid;
-                                       const struct ldb_val *guid_blob;
-
-                                       if (dsdb_dn_is_deleted_val(value) == 
false) {
-                                               continue;
-                                       }
-
-                                       dn = dsdb_dn_parse(tmp_ctx, samdb, 
&element->values[k],
-                                                          
attrib->syntax->ldap_oid);
-                                       if (dn == NULL) {
-                                               DEBUG(1, ("Failed to parse 
linked attribute blob of %s on %s while expunging expired links\n", 
element->name,
-                                                         
ldb_dn_get_linearized(res->msgs[i]->dn)));
-                                               continue;
-                                       }
-
-                                       status = 
dsdb_get_extended_dn_uint64(dn->dn, &whenChanged, "RMD_CHANGETIME");
-                                       if (!NT_STATUS_IS_OK(status)) {
-                                               DEBUG(1, ("Error: 
RMD_CHANGETIME is missing on a forward link.\n"));
-                                               talloc_free(dn);
-                                               continue;
-                                       }
-
-                                       if (whenChanged >= expunge_time_nttime) 
{
-                                               talloc_free(dn);
-                                               continue;
-                                       }
-
-                                       guid_blob = 
ldb_dn_get_extended_component(dn->dn, "GUID");
-                                       status = GUID_from_ndr_blob(guid_blob, 
&guid);
-                                       if (!NT_STATUS_IS_OK(status)) {
-                                               DEBUG(1, ("Error: Invalid GUID 
on link target.\n"));
-                                               talloc_free(dn);
-                                               continue;
-                                       }
-
-                                       guid_buf_str = GUID_buf_string(&guid, 
&buf_guid);
-                                       guid_search_str = 
talloc_asprintf(mem_ctx, "<GUID=%s>", guid_buf_str);
-                                       cleanup_val = 
data_blob_string_const(guid_search_str);
-
-                                       talloc_free(dn);
-
-                                       if (cleanup_msg == NULL) {
-                                               cleanup_msg = 
ldb_msg_new(mem_ctx);
-                                               if (cleanup_msg == NULL) {
-                                                       return 
NT_STATUS_NO_MEMORY;
-                                               }
-                                               cleanup_msg->dn = 
res->msgs[i]->dn;
-                                       }
-
-                                       ret = ldb_msg_add_value(cleanup_msg, 
element->name, &cleanup_val, &cleanup_elem);
-                                       if (ret != LDB_SUCCESS) {
-                                               return NT_STATUS_NO_MEMORY;
-                                       }
-                                       cleanup_elem->flags = 
LDB_FLAG_MOD_DELETE;
-                                       num_modified++;
-                               }
-                       }
-
-                       if (num_modified > 0) {
-                               ret = dsdb_modify(samdb, cleanup_msg, 
DSDB_REPLMD_VANISH_LINKS);
-                               if (ret != LDB_SUCCESS) {
-                                       DEBUG(1,(__location__ ": Failed to 
remove deleted object %s\n",
-                                                
ldb_dn_get_linearized(res->msgs[i]->dn)));
-                               } else {
-                                       DEBUG(4,("Removed deleted object %s\n",
-                                                
ldb_dn_get_linearized(res->msgs[i]->dn)));
-                                       *num_links_removed = *num_links_removed 
+ num_modified;
-                               }
-
-                       }
-               }
-               TALLOC_FREE(tmp_ctx);
-
        }
 
        return NT_STATUS_OK;


-- 
Samba Shared Repository

Reply via email to