upgradeprovision: fix a typo
[samba.git] / source4 / scripting / bin / upgradeprovision
index 857b0b3a510a2438010a06ed7d4f702e132f3347..c7dd4f8ec313741dc6ea93397255fedd94055dc6 100755 (executable)
@@ -88,7 +88,7 @@ hashAttrNotCopied = {   "dn": 1, "whenCreated": 1, "whenChanged": 1,
                         "distinguishedName": 1, "nTMixedDomain": 1,
                         "showInAdvancedViewOnly": 1, "instanceType": 1,
                         "msDS-Behavior-Version":1, "nextRid":1, "cn": 1,
-                        "versionNumber":1, "lmPwdHistory":1, "pwdLastSet": 1,
+                        "lmPwdHistory":1, "pwdLastSet": 1,
                         "ntPwdHistory":1, "unicodePwd":1,"dBCSPwd":1,
                         "supplementalCredentials":1, "gPCUserExtensionNames":1,
                         "gPCMachineExtensionNames":1,"maxPwdAge":1, "secret":1,
@@ -111,8 +111,8 @@ hashOverwrittenAtt = {  "prefixMap": replace, "systemMayContain": replace,
                         "rIDNextRID": add, "rIDUsedPool": never,
                         "defaultSecurityDescriptor": replace + add,
                         "isMemberOfPartialAttributeSet": delete,
-                        "attributeDisplayNames": replace + add}
-
+                        "attributeDisplayNames": replace + add,
+                        "versionNumber": add}
 
 backlinked = []
 forwardlinked = set()
@@ -197,6 +197,7 @@ def check_for_DNS(refprivate, private):
                     provision"""
 
     spnfile = "%s/spn_update_list" % private
+    dnsfile = "%s/dns_update_list" % private
     namedfile = lp.get("dnsupdate:path")
 
     if not namedfile:
@@ -205,6 +206,9 @@ def check_for_DNS(refprivate, private):
     if not os.path.exists(spnfile):
         shutil.copy("%s/spn_update_list" % refprivate, "%s" % spnfile)
 
+    if not os.path.exists(dnsfile):
+        shutil.copy("%s/dns_update_list" % refprivate, "%s" % dnsfile)
+
     destdir = "%s/new_dns" % private
     dnsdir = "%s/dns" % private
 
@@ -452,7 +456,6 @@ def handle_special_add(samdb, dn, names):
         #This entry was misplaced lets remove it if it exists
         dntoremove = "CN=Certificate Service DCOM Access,"\
                      "CN=Users, %s" % names.rootdn
-        print dntoremove
 
     objDn = Dn(samdb, "CN=Cryptographic Operators, CN=Builtin, %s" % names.rootdn)
     if dn == objDn:
@@ -475,14 +478,27 @@ def handle_special_add(samdb, dn, names):
                             base=str(names.rootdn),
                             scope=SCOPE_SUBTREE, attrs=["dn"],
                             controls=["search_options:1:2"])
-        if len(res) > 0:
+
+        res2 = samdb.search(expression="(dn=%s)" % dn,
+                            base=str(names.rootdn),
+                            scope=SCOPE_SUBTREE, attrs=["dn"],
+                            controls=["search_options:1:2"])
+
+        if len(res) > 0 and len(res2) == 0:
             message(CHANGE, "Existing object %s must be replaced by %s,"
                             "Renaming old object" % (str(oldDn), str(dn)))
-            samdb.rename(oldDn, objDn)
+            samdb.rename(oldDn, objDn, ["relax:0"])
 
-        return 1
+        return 0
 
     if dntoremove is not None:
+        res = samdb.search(expression="(cn=RID Set)",
+                            base=str(names.rootdn),
+                            scope=SCOPE_SUBTREE, attrs=["dn"],
+                            controls=["search_options:1:2"])
+
+        if len(res) == 0:
+            return 2
         res = samdb.search(expression="(dn=%s)" % dntoremove,
                             base=str(names.rootdn),
                             scope=SCOPE_SUBTREE, attrs=["dn"],
@@ -491,7 +507,9 @@ def handle_special_add(samdb, dn, names):
             message(CHANGE, "Existing object %s must be replaced by %s,"
                             "removing old object" % (dntoremove, str(dn)))
             samdb.delete(res[0]["dn"])
-    return 0
+            return 0
+
+    return 1
 
 
 def check_dn_nottobecreated(hash, index, listdn):
@@ -538,8 +556,15 @@ def add_missing_object(ref_samdb, samdb, dn, names, basedn, hash, index):
     :param index: Current creation order
     :return: True if the object was created False otherwise"""
 
-    if handle_special_add(samdb, dn, names):
-        return
+    ret = handle_special_add(samdb, dn, names)
+
+    if ret == 2:
+        return False
+
+    if ret == 0:
+        return True
+
+
     reference = ref_samdb.search(expression="dn=%s" % (str(dn)), base=basedn,
                     scope=SCOPE_SUBTREE, controls=["search_options:1:2"])
     empty = Message()
@@ -683,8 +708,9 @@ def add_missing_entries(ref_samdb, samdb, names, basedn, list):
                 # DN can't be created because it depends on some
                 # other DN in the list
                 listDefered.append(dn)
+
     if len(listDefered) != 0:
-        raise ProvisioningError("Unable to insert missing elements:" \
+        raise ProvisioningError("Unable to insert missing elements:"
                                 "circular references")
 
 def handle_links(samdb, att, basedn, dn, value, ref_value, delta):
@@ -787,7 +813,7 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid):
             identic_rename(samdb, reference[0].dn)
             current = samdb.search(expression="dn=%s" % (str(dn)), base=basedn,
                                     scope=SCOPE_SUBTREE,
-                                    controls=["search_options:1:2"])
+                                    controls=controls)
 
         delta = samdb.msg_diff(current[0], reference[0])
 
@@ -826,8 +852,17 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid):
                 # We have updated by provision usn information so let's exploit
                 # replMetadataProperties
                 if att in forwardlinked:
+                    if current[0].get():
+                        curval = current[0][att]
+                    else:
+                        curval = ()
+                    if reference[0].get():
+                        refval = reference[0][att]
+                    else:
+                        refval = ()
                     handle_links(samdb, att, basedn, current[0]["dn"],
-                                    current[0][att], reference[0][att], delta)
+                                    curval, refval, delta)
+                    continue
 
                 if isFirst == 0 and len(delta.items())>1:
                     isFirst = 1
@@ -862,7 +897,18 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid):
                 if  attrUSN is None:
                     delta.remove(att)
                     continue
-
+                if att == "nTSecurityDescriptor":
+                    cursd = ndr_unpack(security.descriptor,
+                        str(current[0]["nTSecurityDescriptor"]))
+                    cursddl = cursd.as_sddl(names.domainsid)
+                    refsd = ndr_unpack(security.descriptor,
+                        str(reference[0]["nTSecurityDescriptor"]))
+                    refsddl = cursd.as_sddl(names.domainsid)
+
+                    if get_diff_sddls(refsddl, cursddl) == "":
+                       message(CHANGE, "sd are identical")
+                    else:
+                       message(CHANGE, "sd are not identical")
                 if attrUSN == -1:
                     # This attribute was last modified by another DC forget
                     # about it
@@ -886,7 +932,7 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid):
                     if attrUSN:
                         message(CHANGE, "%sAttribute: %s will be modified"
                                         "/deleted it was last modified"
-                                        "during a provision, current usn:"
+                                        " during a provision, current usn:"
                                         "%d" % (txt, att,  attrUSN))
                         txt = ""
                     else:
@@ -1631,15 +1677,16 @@ if __name__ == '__main__':
             doit = False
             if deltaattr is not None and len(deltaattr) > 1:
                 doit = True
-            deltaattr.remove("dn")
-            for att in deltaattr:
-                if att.lower() == "dn":
-                    continue
-                if deltaattr.get(att) is not None \
-                    and deltaattr.get(att).flags() != FLAG_MOD_ADD:
-                    doit = False
-                elif deltaattr.get(att) is None:
-                    doit = False
+            if doit:
+                deltaattr.remove("dn")
+                for att in deltaattr:
+                    if att.lower() == "dn":
+                        continue
+                    if deltaattr.get(att) is not None \
+                        and deltaattr.get(att).flags() != FLAG_MOD_ADD:
+                        doit = False
+                    elif deltaattr.get(att) is None:
+                        doit = False
             if doit:
                 message(CHANGE, "Applying delta to @ATTRIBUTES")
                 deltaattr.dn = ldb.Dn(basesam, "@ATTRIBUTES")
@@ -1749,3 +1796,4 @@ if __name__ == '__main__':
         if opts.debugall or opts.debugchange:
             (typ, val, tb) = sys.exc_info()
             traceback.print_exception(typ, val, tb)
+        sys.exit(1)