The branch, master has been updated
       via  576ea40 samba-tool: allow dbcheck to correct the 
originating_change_time of the deleted object container
       via  85af1ed s4-dsdb: initialize correctly the value of 
originating_change_time for the Deleted Object Container
       via  b8a0772 s4-drs: check if we have a domain level >= 2k8r2 as before 
the isRecycled do not exists and so is always False
       via  a6686b9 samba-tool: dbcheck avoid problems with deleted objects
      from  691fb36 s4: Simple test script to create lots of contacts to stress 
the LDB

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


- Log -----------------------------------------------------------------
commit 576ea40ece6adb156b4de23c737ada5e80b7946a
Author: Matthieu Patou <m...@matws.net>
Date:   Sun Nov 13 14:09:24 2011 +0100

    samba-tool: allow dbcheck to correct the originating_change_time of the 
deleted object container
    
    Autobuild-User: Matthieu Patou <m...@samba.org>
    Autobuild-Date: Sun Nov 13 15:47:53 CET 2011 on sn-devel-104

commit 85af1ed9b8e5593b91fd5efb5e97c5abbc9feddc
Author: Matthieu Patou <m...@matws.net>
Date:   Sun Nov 13 14:08:32 2011 +0100

    s4-dsdb: initialize correctly the value of originating_change_time for the 
Deleted Object Container

commit b8a077296ac666cf45cafe7e86edc390dce0e511
Author: Matthieu Patou <m...@matws.net>
Date:   Wed Oct 5 16:23:37 2011 +0200

    s4-drs: check if we have a domain level >= 2k8r2 as before the isRecycled 
do not exists and so is always False
    
    Having a false value cause the link on removed attribute to be always
    returned which is what we try to avoid.

commit a6686b9f9893c67534c7eec73a6c301f1ebe41da
Author: Matthieu Patou <m...@matws.net>
Date:   Sun Nov 13 13:15:47 2011 +0100

    samba-tool: dbcheck avoid problems with deleted objects
    
    We have to search for deleted objects as well as the previous search
    might have been done with the show_deleted control. If not samba-tool
    fails with no such DN error while fetching the object.

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

Summary of changes:
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c |   54 ++++++++++++++++++++++-
 source4/rpc_server/drsuapi/getncchanges.c       |   31 ++++++++++---
 source4/scripting/python/samba/dbchecker.py     |   36 +++++++++++++++-
 3 files changed, 111 insertions(+), 10 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c 
b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index 194498e..b7a6a70 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -50,6 +50,7 @@
 #include "lib/util/binsearch.h"
 #include "lib/util/tsort.h"
 
+static const uint64_t DELETED_OBJECT_CONTAINER_CHANGE_TIME = 253402127999L;
 struct replmd_private {
        TALLOC_CTX *la_ctx;
        struct la_entry *la_list;
@@ -917,7 +918,32 @@ static int replmd_add(struct ldb_module *module, struct 
ldb_request *req)
 
                m->attid                        = sa->attributeID_id;
                m->version                      = 1;
-               m->originating_change_time      = now;
+               if (m->attid == 0x20030) {
+                       const struct ldb_val *rdn_val = 
ldb_dn_get_rdn_val(msg->dn);
+                       const char* rdn;
+
+                       if (rdn_val == NULL) {
+                               ldb_oom(ldb);
+                               talloc_free(ac);
+                               return LDB_ERR_OPERATIONS_ERROR;
+                       }
+
+                       rdn = (const char*)rdn_val->data;
+                       if (strcmp(rdn, "Deleted Objects") == 0) {
+                               /*
+                                * Set the originating_change_time to 
29/12/9999 at 23:59:59
+                                * as specified in MS-ADTS 7.1.1.4.2 Deleted 
Objects Container
+                                */
+                               NTTIME deleted_obj_ts;
+
+                               unix_to_nt_time(&deleted_obj_ts, 
DELETED_OBJECT_CONTAINER_CHANGE_TIME);
+                               m->originating_change_time      = 
deleted_obj_ts;
+                       } else {
+                               m->originating_change_time      = now;
+                       }
+               } else {
+                       m->originating_change_time      = now;
+               }
                m->originating_invocation_id    = *our_invocation_id;
                m->originating_usn              = ac->seq_num;
                m->local_usn                    = ac->seq_num;
@@ -1118,7 +1144,31 @@ static int replmd_update_rpmd_element(struct ldb_context 
*ldb,
        md1 = &omd->ctr.ctr1.array[i];
        md1->version++;
        md1->attid                     = a->attributeID_id;
-       md1->originating_change_time   = now;
+       if (md1->attid == 0x20030) {
+               const struct ldb_val *rdn_val = ldb_dn_get_rdn_val(msg->dn);
+               const char* rdn;
+
+               if (rdn_val == NULL) {
+                       ldb_oom(ldb);
+                       return LDB_ERR_OPERATIONS_ERROR;
+               }
+
+               rdn = (const char*)rdn_val->data;
+               if (strcmp(rdn, "Deleted Objects") == 0) {
+                       /*
+                        * Set the originating_change_time to 29/12/9999 at 
23:59:59
+                        * as specified in MS-ADTS 7.1.1.4.2 Deleted Objects 
Container
+                        */
+                       NTTIME deleted_obj_ts;
+
+                       unix_to_nt_time(&deleted_obj_ts, 
DELETED_OBJECT_CONTAINER_CHANGE_TIME);
+                       md1->originating_change_time    = deleted_obj_ts;
+               } else {
+                       md1->originating_change_time    = now;
+               }
+       } else {
+               md1->originating_change_time    = now;
+       }
        md1->originating_invocation_id = *our_invocation_id;
        md1->originating_usn           = *seq_num;
        md1->local_usn                 = *seq_num;
diff --git a/source4/rpc_server/drsuapi/getncchanges.c 
b/source4/rpc_server/drsuapi/getncchanges.c
index 61a6002..4217e22 100644
--- a/source4/rpc_server/drsuapi/getncchanges.c
+++ b/source4/rpc_server/drsuapi/getncchanges.c
@@ -366,14 +366,31 @@ static WERROR get_nc_changes_add_la(TALLOC_CTX *mem_ctx,
 
                v = ldb_msg_find_attr_as_string(msg, "isDeleted", "false");
                if (strncasecmp(v, "true", 4) == 0) {
-                       v = ldb_msg_find_attr_as_string(msg, "isRecycled", 
"false");
                        /*
-                        * Do not skip link when the object is just deleted 
(isRecycled not present)
-                        * Do it for tomstones or recycled ones
-                        */
-                       if (strncasecmp(v, "true", 4) == 0) {
-                               DEBUG(2, (" object %s is deleted, not returning 
linked attribute !\n",
-                                                       
ldb_dn_get_linearized(msg->dn)));
+                         * Note: we skip the transmition of the deleted link 
even if the other part used to
+                         * know about it because when we transmit the deletion 
of the object, the link will
+                         * be deleted too due to deletion of object where link 
points and Windows do so.
+                         */
+                       if (dsdb_functional_level(sam_ctx) >= 
DS_DOMAIN_FUNCTION_2008_R2) {
+                               v = ldb_msg_find_attr_as_string(msg, 
"isRecycled", "true");
+                               /*
+                                * On Windows 2008R2 isRecycled is always 
present even if FL or DL are < FL 2K8R2
+                                * if it join an existing domain with deleted 
objets, it firsts impose to have a
+                                * schema with the is-Recycled object and for 
all deleted objects it adds the isRecycled
+                                * either during initial replication or after 
the getNCChanges.
+                                * Behavior of samba has been changed to always 
have this attribute if it's present in the schema.
+                                *
+                                * So if FL <2K8R2 isRecycled might be here or 
not but we don't care, it's meaning less.
+                                * If FL >=2K8R2 we are sure that this 
attribute will be here.
+                                * For this kind of forest level we do not 
return the link if the object is recycled
+                                * (isRecycled = true).
+                                */
+                               if (strncasecmp(v, "true", 4) == 0) {
+                                       DEBUG(2, (" object %s is recycled, not 
returning linked attribute !\n",
+                                                               
ldb_dn_get_linearized(msg->dn)));
+                                       return WERR_OK;
+                               }
+                       } else {
                                return WERR_OK;
                        }
                }
diff --git a/source4/scripting/python/samba/dbchecker.py 
b/source4/scripting/python/samba/dbchecker.py
index 7d85adf..6792538 100644
--- a/source4/scripting/python/samba/dbchecker.py
+++ b/source4/scripting/python/samba/dbchecker.py
@@ -45,6 +45,7 @@ class dbcheck(object):
         self.remove_all_deleted_DN_links = False
         self.fix_all_target_mismatch = False
         self.fix_all_metadata = False
+        self.fix_time_metadata = False
         self.fix_all_missing_backlinks = False
         self.fix_all_orphaned_backlinks = False
 
@@ -368,6 +369,22 @@ class dbcheck(object):
         return error_count
 
 
+    def get_originating_time(self, val, attid):
+        '''Read metadata properties and return the originating time for
+           a given attributeId.
+
+           :return: the originating time or 0 if not found
+        '''
+
+        repl = ndr_unpack(drsblobs.replPropertyMetaDataBlob, str(val))
+        obj = repl.ctr
+
+        for o in repl.ctr.array:
+            if o.attid == attid:
+                return o.originating_change_time
+
+        return 0
+
     def process_metadata(self, val):
         '''Read metadata properties and list attributes in it'''
 
@@ -407,7 +424,7 @@ class dbcheck(object):
             attrs.append("replPropertyMetaData")
 
         res = self.samdb.search(base=dn, scope=ldb.SCOPE_BASE,
-                                controls=["extended_dn:1:1", 
"show_recycled:1"],
+                controls=["extended_dn:1:1", "show_recycled:1", 
"show_deleted:1"],
                                 attrs=attrs)
         if len(res) != 1:
             self.report("Object %s disappeared during check" % dn)
@@ -465,6 +482,23 @@ class dbcheck(object):
 
         show_dn = True
         if got_repl_property_meta_data:
+            rdn = (str(dn).split(","))[0]
+            if rdn == "CN=Deleted Objects":
+                isDeletedAttId = 131120
+                # It's 29/12/9999 at 23:59:59 UTC as specified in MS-ADTS 
7.1.1.4.2 Deleted Objects Container
+
+                expectedTimeDo = 2650466015990000000
+                originating = 
self.get_originating_time(obj["replPropertyMetaData"], isDeletedAttId)
+                if originating != expectedTimeDo:
+                    if self.confirm_all("Fix isDeleted originating_change_time 
on '%s'" % str(dn), 'fix_time_metadata'):
+                        nmsg = ldb.Message()
+                        nmsg.dn = dn
+                        nmsg["isDeleted"] = ldb.MessageElement("TRUE", 
ldb.FLAG_MOD_REPLACE, "isDeleted")
+                        error_count += 1
+                        self.samdb.modify(nmsg, controls=["provision:0"])
+
+                    else:
+                        self.report("Not fixing isDeleted 
originating_change_time on '%s'" % str(dn))
             for att in list_attrs_seen:
                 if not att in list_attrs_from_md:
                     if show_dn:


-- 
Samba Shared Repository

Reply via email to