s4-provision Add support for fixing the DC rid to a particular value
authorAndrew Bartlett <abartlet@samba.org>
Sat, 13 Aug 2011 03:32:18 +0000 (13:32 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Sat, 13 Aug 2011 10:18:41 +0000 (20:18 +1000)
This will allow an upgraded DC to keep its SID, while being upgraded
to AD.  We also watch for the highest RID in the existing DB to set
next_rid for other additional users.

Andrew Bartlett

source4/scripting/python/samba/provision/__init__.py
source4/scripting/python/samba/upgrade.py

index 17f8e0f15b60953f4960f060c8206bad8a64d4dd..1b32a4105904ed14fd57b310d068004ab6ee172b 100644 (file)
@@ -1069,13 +1069,17 @@ def setup_samdb_rootdse(samdb, names):
 def setup_self_join(samdb, names, machinepass, dnspass,
                     domainsid, next_rid, invocationid,
                     policyguid, policyguid_dc, domainControllerFunctionality,
 def setup_self_join(samdb, names, machinepass, dnspass,
                     domainsid, next_rid, invocationid,
                     policyguid, policyguid_dc, domainControllerFunctionality,
-                    ntdsguid):
+                    ntdsguid, dc_rid=None):
     """Join a host to its own domain."""
     assert isinstance(invocationid, str)
     if ntdsguid is not None:
         ntdsguid_line = "objectGUID: %s\n"%ntdsguid
     else:
         ntdsguid_line = ""
     """Join a host to its own domain."""
     assert isinstance(invocationid, str)
     if ntdsguid is not None:
         ntdsguid_line = "objectGUID: %s\n"%ntdsguid
     else:
         ntdsguid_line = ""
+
+    if dc_rid is None:
+        dc_rid = next_rid
+
     setup_add_ldif(samdb, setup_path("provision_self_join.ldif"), {
               "CONFIGDN": names.configdn,
               "SCHEMADN": names.schemadn,
     setup_add_ldif(samdb, setup_path("provision_self_join.ldif"), {
               "CONFIGDN": names.configdn,
               "SCHEMADN": names.schemadn,
@@ -1086,7 +1090,7 @@ def setup_self_join(samdb, names, machinepass, dnspass,
               "DNSNAME": "%s.%s" % (names.hostname, names.dnsdomain),
               "MACHINEPASS_B64": b64encode(machinepass.encode('utf-16-le')),
               "DOMAINSID": str(domainsid),
               "DNSNAME": "%s.%s" % (names.hostname, names.dnsdomain),
               "MACHINEPASS_B64": b64encode(machinepass.encode('utf-16-le')),
               "DOMAINSID": str(domainsid),
-              "DCRID": str(next_rid),
+              "DCRID": str(dc_rid),
               "SAMBA_VERSION_STRING": version,
               "NTDSGUID": ntdsguid_line,
               "DOMAIN_CONTROLLER_FUNCTIONALITY": str(
               "SAMBA_VERSION_STRING": version,
               "NTDSGUID": ntdsguid_line,
               "DOMAIN_CONTROLLER_FUNCTIONALITY": str(
@@ -1175,12 +1179,15 @@ def setup_samdb(path, session_info, provision_backend, lp, names,
         logger, domainsid, domainguid, policyguid, policyguid_dc, fill,
         adminpass, krbtgtpass, machinepass, invocationid, dnspass, ntdsguid,
         serverrole, am_rodc=False, dom_for_fun_level=None, schema=None,
         logger, domainsid, domainguid, policyguid, policyguid_dc, fill,
         adminpass, krbtgtpass, machinepass, invocationid, dnspass, ntdsguid,
         serverrole, am_rodc=False, dom_for_fun_level=None, schema=None,
-        next_rid=1000):
+        next_rid=None, dc_rid=None):
     """Setup a complete SAM Database.
 
     :note: This will wipe the main SAM database file!
     """
 
     """Setup a complete SAM Database.
 
     :note: This will wipe the main SAM database file!
     """
 
+    if next_rid is None:
+        next_rid = 1000
+
     # Provision does not make much sense values larger than 1000000000
     # as the upper range of the rIDAvailablePool is 1073741823 and
     # we don't want to create a domain that cannot allocate rids.
     # Provision does not make much sense values larger than 1000000000
     # as the upper range of the rIDAvailablePool is 1073741823 and
     # we don't want to create a domain that cannot allocate rids.
@@ -1386,14 +1393,15 @@ def setup_samdb(path, session_info, provision_backend, lp, names,
 
             logger.info("Setting up self join")
             setup_self_join(samdb, names=names, invocationid=invocationid,
 
             logger.info("Setting up self join")
             setup_self_join(samdb, names=names, invocationid=invocationid,
-                dnspass=dnspass,
-                machinepass=machinepass,
-                domainsid=domainsid,
-                next_rid=next_rid,
-                policyguid=policyguid,
-                policyguid_dc=policyguid_dc,
-                domainControllerFunctionality=domainControllerFunctionality,
-                ntdsguid=ntdsguid)
+                            dnspass=dnspass,
+                            machinepass=machinepass,
+                            domainsid=domainsid,
+                            next_rid=next_rid,
+                            dc_rid=dc_rid,
+                            policyguid=policyguid,
+                            policyguid_dc=policyguid_dc,
+                            domainControllerFunctionality=domainControllerFunctionality,
+                            ntdsguid=ntdsguid)
 
             ntds_dn = "CN=NTDS Settings,%s" % names.serverdn
             names.ntdsguid = samdb.searchone(basedn=ntds_dn,
 
             ntds_dn = "CN=NTDS Settings,%s" % names.serverdn
             names.ntdsguid = samdb.searchone(basedn=ntds_dn,
@@ -1510,7 +1518,7 @@ def provision(logger, session_info, credentials, smbconf=None,
         targetdir=None, samdb_fill=FILL_FULL, realm=None, rootdn=None,
         domaindn=None, schemadn=None, configdn=None, serverdn=None,
         domain=None, hostname=None, hostip=None, hostip6=None, domainsid=None,
         targetdir=None, samdb_fill=FILL_FULL, realm=None, rootdn=None,
         domaindn=None, schemadn=None, configdn=None, serverdn=None,
         domain=None, hostname=None, hostip=None, hostip6=None, domainsid=None,
-        next_rid=1000, adminpass=None, ldapadminpass=None, krbtgtpass=None,
+        next_rid=1000, dc_rid=None, adminpass=None, ldapadminpass=None, krbtgtpass=None,
         domainguid=None, policyguid=None, policyguid_dc=None,
         invocationid=None, machinepass=None, ntdsguid=None, dnspass=None,
         root=None, nobody=None, users=None, wheel=None, backup=None, aci=None,
         domainguid=None, policyguid=None, policyguid_dc=None,
         invocationid=None, machinepass=None, ntdsguid=None, dnspass=None,
         root=None, nobody=None, users=None, wheel=None, backup=None, aci=None,
@@ -1712,7 +1720,7 @@ def provision(logger, session_info, credentials, smbconf=None,
             invocationid=invocationid, machinepass=machinepass,
             dnspass=dnspass, ntdsguid=ntdsguid, serverrole=serverrole,
             dom_for_fun_level=dom_for_fun_level, am_rodc=am_rodc,
             invocationid=invocationid, machinepass=machinepass,
             dnspass=dnspass, ntdsguid=ntdsguid, serverrole=serverrole,
             dom_for_fun_level=dom_for_fun_level, am_rodc=am_rodc,
-            next_rid=next_rid)
+            next_rid=next_rid, dc_rid=dc_rid)
 
         if serverrole == "domain controller":
             if paths.netlogon is None:
 
         if serverrole == "domain controller":
             if paths.netlogon is None:
index e333174d13485ff35d375989474cae83c35740b1..351581c6eecd26ff3ab7596f347e4a0683dc2b9b 100644 (file)
@@ -416,8 +416,9 @@ def upgrade_from_samba3(samba3, logger, session_info, smbconf, targetdir):
 
     # Find machine account and password
     machinepass = None
 
     # Find machine account and password
     machinepass = None
-    machinerid = 2000
+    machinerid = None
     machinesid = None
     machinesid = None
+    next_rid = 1000
 
     try:
         machinepass = secrets_db.get_machine_password(netbiosname)
 
     try:
         machinepass = secrets_db.get_machine_password(netbiosname)
@@ -456,18 +457,22 @@ def upgrade_from_samba3(samba3, logger, session_info, smbconf, targetdir):
     userlist = old_passdb.search_users(0)
     userdata = {}
     for entry in userlist:
     userlist = old_passdb.search_users(0)
     userdata = {}
     for entry in userlist:
-        if machinesid and machinerid == entry['rid']:
+        if machinerid and machinerid == entry['rid']:
             continue
         username = entry['account_name']
         if entry['rid'] < 1000:
             print("Skipping wellknown rid=%d (for username=%s)\n" % (entry['rid'], username))
             continue
             continue
         username = entry['account_name']
         if entry['rid'] < 1000:
             print("Skipping wellknown rid=%d (for username=%s)\n" % (entry['rid'], username))
             continue
+        if entry['rid'] >= next_rid:
+            next_rid = entry['rid'] + 1
+        
         userdata[username] = old_passdb.getsampwnam(username)
 
     # Do full provision
     result = provision(logger, session_info, None,
                        targetdir=targetdir, realm=realm, domain=domainname,
         userdata[username] = old_passdb.getsampwnam(username)
 
     # Do full provision
     result = provision(logger, session_info, None,
                        targetdir=targetdir, realm=realm, domain=domainname,
-                       domainsid=domainsid, next_rid=machinerid,
+                       domainsid=domainsid, next_rid=next_rid,
+                       dc_rid=machinerid,
                        hostname=netbiosname, machinepass=machinepass,
                        serverrole=serverrole, samdb_fill=FILL_FULL)
 
                        hostname=netbiosname, machinepass=machinepass,
                        serverrole=serverrole, samdb_fill=FILL_FULL)