samba-tool domain demote: Use dn.add_base/dn.add_child
authorAndrew Bartlett <abartlet@samba.org>
Fri, 23 Oct 2015 00:12:03 +0000 (13:12 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Mon, 26 Oct 2015 04:11:22 +0000 (05:11 +0100)
This is done primarilly to set the pattern that we should manipulate ldb.Dn values
with the helper routines, not just by concatonation via format strings.

We also restrict our exception hadling to only the expected errors, not
all errors.

Andrew Bartlett

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
python/samba/netcmd/domain.py
python/samba/remove_dc.py

index 1d96a563291e3695df29089664acb1031800f933..aeed9c701c216a7b53494831ec1cc14ed0894719 100644 (file)
@@ -826,7 +826,9 @@ class cmd_domain_demote(Command):
             raise CommandError("Error while changing account control", e)
 
         parent = msg.dn.parent()
-        rdn = "%s=%s" % (res[0].dn.get_rdn_name(), res[0].dn.get_rdn_value())
+        dc_name = res[0].dn.get_rdn_value()
+        rdn = "CN=%s" % dc_name
+
         # Let's move to the Computer container
         i = 0
         newrdn = str(rdn)
@@ -916,7 +918,7 @@ class cmd_domain_demote(Command):
             else:
                 raise CommandError("Error while sending a removeDsServer of %s: " % server_dsa_dn, e)
 
-        remove_dc.remove_sysvol_references(remote_samdb, rdn)
+        remove_dc.remove_sysvol_references(remote_samdb, dc_name)
 
         # These are objects under the computer account that should be deleted
         for s in ("CN=Enterprise,CN=NTFRS Subscriptions",
index f2777d3a97d9de46893d38a2558c03b17df3bd34..41b9621e2780048dd5b539e9dc9983a4949993dc 100644 (file)
@@ -31,23 +31,51 @@ class DemoteException(Exception):
         return "DemoteException: " + self.value
 
 
-def remove_sysvol_references(samdb, rdn):
+def remove_sysvol_references(samdb, dc_name):
+    # DNs under the Configuration DN:
     realm = samdb.domain_dns_name()
     for s in ("CN=Enterprise,CN=Microsoft System Volumes,CN=System",
               "CN=%s,CN=Microsoft System Volumes,CN=System" % realm):
+        dn = ldb.Dn(samdb, s)
+
+        # This is verbose, but it is the safe, escape-proof way
+        # to add a base and add an arbitrary RDN.
+        if dn.add_base(samdb.get_config_basedn()) == False:
+            raise DemoteException("Failed constructing DN %s by adding base %s" \
+                                  % (dn, samdb.get_config_basedn()))
+        if dn.add_child("CN=X") == False:
+            raise DemoteException("Failed constructing DN %s by adding child CN=X"\
+                                      % (dn))
+        dn.set_component(0, "CN", dc_name)
         try:
-            samdb.delete(ldb.Dn(samdb,
-                                "%s,%s,%s" % (str(rdn), s, str(samdb.get_config_basedn()))))
-        except ldb.LdbError, l:
-            pass
-
-    for s in ("CN=Topology,CN=Domain System Volume,CN=DFSR-GlobalSettings,CN=System",
-              "CN=Domain System Volumes (SYSVOL share),CN=File Replication Service,CN=System"):
+            samdb.delete(dn)
+        except ldb.LdbError as (enum, estr):
+            if enum == ldb.ERR_NO_SUCH_OBJECT:
+                pass
+            else:
+                raise
+
+    # DNs under the Domain DN:
+    for s in ("CN=Domain System Volumes (SYSVOL share),CN=File Replication Service,CN=System",
+              "CN=Topology,CN=Domain System Volume,CN=DFSR-GlobalSettings,CN=System"):
+        # This is verbose, but it is the safe, escape-proof way
+        # to add a base and add an arbitrary RDN.
+        dn = ldb.Dn(samdb, s)
+        if dn.add_base(samdb.get_default_basedn()) == False:
+            raise DemoteException("Failed constructing DN %s by adding base" % \
+                                  (dn, samdb.get_default_basedn()))
+        if dn.add_child("CN=X") == False:
+            raise DemoteException("Failed constructing DN %s by adding child %s"\
+                                  % (dn, rdn))
+        dn.set_component(0, "CN", dc_name)
         try:
-            samdb.delete(ldb.Dn(samdb,
-                                "%s,%s,%s" % (str(rdn), s, str(samdb.get_default_basedn()))))
-        except ldb.LdbError, l:
-            pass
+            samdb.delete(dn)
+        except ldb.LdbError as (enum, estr):
+            if enum == ldb.ERR_NO_SUCH_OBJECT:
+                pass
+            else:
+                raise
+
 
 def remove_dns_references(samdb, dnsHostName):
 
@@ -84,7 +112,7 @@ def offline_remove_server(samdb, server_dn,
                         scope=ldb.SCOPE_BASE,
                         expression="(objectClass=server)")
     msg = msgs[0]
-    dc_name = msgs[0]["cn"]
+    dc_name = str(msgs[0]["cn"][0])
 
     try:
         computer_dn = ldb.Dn(samdb, msgs[0]["serverReference"][0])
@@ -122,7 +150,7 @@ def offline_remove_server(samdb, server_dn,
         remove_dns_references(samdb, dnsHostName)
 
     if remove_sysvol_obj:
-        remove_sysvol_references(samdb, "CN=%s" % dc_name)
+        remove_sysvol_references(samdb, dc_name)
 
 def offline_remove_ntds_dc(samdb, ntds_dn,
                            remove_computer_obj=False,