samba_upgradeprovision: don't reset 'whenCreated' when resetting 'nTSecurityDescriptor'
[metze/samba/wip.git] / source4 / scripting / bin / samba_upgradeprovision
index 54ffbeab1e6cb1d3e6a1b931b81fb63b1e1d890f..9daabe318facd80df6183cd34c55bbd946b1f2ce 100755 (executable)
@@ -46,11 +46,13 @@ from ldb import (SCOPE_SUBTREE, SCOPE_BASE,
 from samba import param, dsdb, Ldb
 from samba.common import confirm
 from samba.provision import (get_domain_descriptor, find_provision_key_parameters,
-                            get_config_descriptor,
+                            get_config_descriptor, get_empty_descriptor,
                             ProvisioningError, get_last_provision_usn,
                             get_max_usn, update_provision_usn, setup_path)
 from samba.schema import get_linked_attributes, Schema, get_schema_descriptor
 from samba.dcerpc import security, drsblobs
+from samba.dcerpc.security import (
+    SECINFO_OWNER, SECINFO_GROUP, SECINFO_DACL, SECINFO_SACL)
 from samba.ndr import ndr_unpack
 from samba.upgradehelpers import (dn_sort, get_paths, newprovision,
                                  get_ldbs, findprovisionrange,
@@ -869,7 +871,7 @@ def checkKeepAttributeOldMtd(delta, att, reference, current,
         else:
             if hashOverwrittenAtt.get(att)&2**msgElt.flags() :
                 continue
-            elif  hashOverwrittenAtt.get(att)==never:
+            elif hashOverwrittenAtt.get(att) == never:
                 delta.remove(att)
                 continue
 
@@ -961,8 +963,8 @@ def checkKeepAttributeWithMetadata(delta, att, message, reference, current,
                 message(CHANGESD, "%ssd are not identical:\n%s" % (txt, diff))
                 txt = ""
                 if attrUSN == -1:
-                    message(CHANGESD, "But the SD has been changed by someonelse "\
-                                    "so it's impossible to know if the difference"\
+                    message(CHANGESD, "But the SD has been changed by someonelse "
+                                    "so it's impossible to know if the difference"
                                     " cames from the modification or from a previous bug")
                     dnNotToRecalculate.append(str(dn))
                 else:
@@ -1032,7 +1034,8 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns):
         raise ProvisioningError(msg)
 
     changed = 0
-    controls = ["search_options:1:2", "sd_flags:1:0"]
+    sd_flags = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL | SECINFO_SACL
+    controls = ["search_options:1:2", "sd_flags:1:%d" % sd_flags]
     if usns is not None:
             message(CHANGE, "Using replPropertyMetadata for change selection")
     for dn in listPresent:
@@ -1342,7 +1345,7 @@ def rebuild_sd(samdb, names):
     listKeys.sort(dn_sort)
 
     if len(dnToRecalculate) != 0:
-        message(CHANGESD, "%d DNs have been marked as needed to be recalculated"\
+        message(CHANGESD, "%d DNs have been marked as needed to be recalculated"
                             ", recalculating %d due to inheritance"
                             % (len(dnToRecalculate), len(listKeys)))
 
@@ -1352,16 +1355,18 @@ def rebuild_sd(samdb, names):
             continue
         delta = Message()
         delta.dn = Dn(samdb, key)
+        sd_flags = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL | SECINFO_SACL
         try:
-            delta["whenCreated"] = MessageElement(hash[key], FLAG_MOD_REPLACE,
-                                                    "whenCreated" )
-            samdb.modify(delta, ["recalculate_sd:0","relax:0"])
+            descr = get_empty_descriptor(names.domainsid)
+            delta["nTSecurityDescriptor"] = MessageElement(descr, FLAG_MOD_REPLACE,
+                                                    "nTSecurityDescriptor")
+            samdb.modify(delta, ["sd_flags:1:%d" % sd_flags,"relax:0"])
         except LdbError, e:
             samdb.transaction_cancel()
-            res = samdb.search(expression="objectClass=*", base=str(names.rootdn),
-                                scope=SCOPE_SUBTREE,
-                                attrs=["dn", "nTSecurityDescriptor"],
-                                controls=["search_options:1:2"])
+            res = samdb.search(expression="objectClass=*", base=str(delta.dn),
+                                scope=SCOPE_BASE,
+                                attrs=["nTSecurityDescriptor"],
+                                controls=["sd_flags:1:%d" % sd_flags])
             badsd = ndr_unpack(security.descriptor,
                         str(res[0]["nTSecurityDescriptor"]))
             message(ERROR, "On %s bad stuff %s" % (str(delta.dn),badsd.as_sddl(names.domainsid)))
@@ -1372,7 +1377,7 @@ def hasATProvision(samdb):
                                 scope=SCOPE_BASE,
                                 attrs=["dn"])
 
-        if entry != None and len(entry) == 1:
+        if entry is not None and len(entry) == 1:
             return True
         else:
             return False
@@ -1695,10 +1700,10 @@ if __name__ == '__main__':
                     v = v + 1
 
             message(CHANGE,
-                "Find last provision USN, %d invocation(s) for a total of %d ranges" % \
+                "Find last provision USN, %d invocation(s) for a total of %d ranges" %
                             (len(lastProvisionUSNs.keys()), v /2 ))
 
-            if lastProvisionUSNs.get("default") != None:
+            if lastProvisionUSNs.get("default") is not None:
                 message(CHANGE, "Old style for usn ranges used")
                 lastProvisionUSNs[str(names.invocation)] = lastProvisionUSNs["default"]
                 del lastProvisionUSNs["default"]
@@ -1709,7 +1714,7 @@ if __name__ == '__main__':
                 minobj = 5
                 (hash_id, nb_obj) = findprovisionrange(ldbs.sam, ldb.Dn(ldbs.sam, str(names.rootdn)))
                 message(SIMPLE, "Here is a list of changes that modified more than %d objects in 1 minute." % minobj)
-                message(SIMPLE, "Usually changes made by provision and upgradeprovision are those who affect a couple"\
+                message(SIMPLE, "Usually changes made by provision and upgradeprovision are those who affect a couple"
                         " of hundred of objects or more")
                 message(SIMPLE, "Total number of objects: %d" % nb_obj)
                 message(SIMPLE, "")