Merge branch 'v4-0-test' of git://git.samba.org/samba into 4-0-local
[samba.git] / source4 / scripting / python / samba / provision.py
index 4f52d36167b690735dbf3c215db2cdc05fd75629..37c4c5b082da136d5375d03d845d37dd6f744cf7 100644 (file)
@@ -32,6 +32,7 @@ from socket import gethostname, gethostbyname
 import param
 import registry
 import samba
+from auth import system_session
 from samba import Ldb, substitute_var, valid_netbios_name, check_all_substituted
 from samba.samdb import SamDB
 import security
@@ -59,11 +60,13 @@ class ProvisionPaths:
         self.hkpd = None
         self.hkpt = None
         self.samdb = None
+        self.idmapdb = None
         self.secrets = None
         self.keytab = None
         self.dns_keytab = None
         self.dns = None
         self.winsdb = None
+        self.private_dir = None
 
 
 def check_install(lp, session_info, credentials):
@@ -196,19 +199,20 @@ def provision_paths_from_lp(lp, dnsdomain):
     :param dnsdomain: DNS Domain name
     """
     paths = ProvisionPaths()
-    private_dir = lp.get("private dir")
+    paths.private_dir = lp.get("private dir")
     paths.keytab = "secrets.keytab"
     paths.dns_keytab = "dns.keytab"
 
-    paths.shareconf = os.path.join(private_dir, "share.ldb")
-    paths.samdb = os.path.join(private_dir, lp.get("sam database") or "samdb.ldb")
-    paths.secrets = os.path.join(private_dir, lp.get("secrets database") or "secrets.ldb")
-    paths.templates = os.path.join(private_dir, "templates.ldb")
-    paths.dns = os.path.join(private_dir, dnsdomain + ".zone")
-    paths.winsdb = os.path.join(private_dir, "wins.ldb")
-    paths.s4_ldapi_path = os.path.join(private_dir, "ldapi")
-    paths.smbconf = os.path.join(private_dir, "smb.conf")
-    paths.phpldapadminconfig = os.path.join(private_dir, 
+    paths.shareconf = os.path.join(paths.private_dir, "share.ldb")
+    paths.samdb = os.path.join(paths.private_dir, lp.get("sam database") or "samdb.ldb")
+    paths.idmapdb = os.path.join(paths.private_dir, lp.get("idmap database") or "idmap.ldb")
+    paths.secrets = os.path.join(paths.private_dir, lp.get("secrets database") or "secrets.ldb")
+    paths.templates = os.path.join(paths.private_dir, "templates.ldb")
+    paths.dns = os.path.join(paths.private_dir, dnsdomain + ".zone")
+    paths.winsdb = os.path.join(paths.private_dir, "wins.ldb")
+    paths.s4_ldapi_path = os.path.join(paths.private_dir, "ldapi")
+    paths.smbconf = os.path.join(paths.private_dir, "smb.conf")
+    paths.phpldapadminconfig = os.path.join(paths.private_dir, 
                                             "phpldapadmin-config.php")
     paths.hklm = "hklm.ldb"
     paths.hkcr = "hkcr.ldb"
@@ -271,14 +275,12 @@ def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users,
 def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, 
                            credentials, configdn, schemadn, domaindn, 
                            hostname, netbiosname, dnsdomain, realm, 
-                           rootdn, serverrole, ldap_backend=None, 
+                           rootdn, serverrole, sitename, ldap_backend=None, 
                            ldap_backend_type=None, erase=False):
     """Setup the partitions for the SAM database. 
     
     Alternatively, provision() may call this, and then populate the database.
     
-    :param erase: Remove the existing data present in the database.
-     
     :note: This will wipe the Sam Database!
     
     :note: This function always removes the local SAM LDB file. The erase 
@@ -287,10 +289,15 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
     """
     assert session_info is not None
 
-    if os.path.exists(samdb_path):
+    samdb = SamDB(samdb_path, session_info=session_info, 
+                  credentials=credentials, lp=lp)
+
+    # Wipes the database
+    try:
+        samdb.erase()
+    except:
         os.unlink(samdb_path)
 
-    # Also wipes the database
     samdb = SamDB(samdb_path, session_info=session_info, 
                   credentials=credentials, lp=lp)
 
@@ -311,9 +318,9 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
                     "server_sort",
                     "extended_dn",
                     "asq",
-                    "samldb",
                     "rdn_name",
                     "objectclass",
+                    "samldb",
                     "kludge_acl",
                     "operational"]
     tdb_modules_list = [
@@ -332,17 +339,25 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
     schemadn_ldb = "schema.ldb"
     if ldap_backend is not None:
         schema_ldb = ldap_backend
-    
        schemadn_ldb = ldap_backend
        
     if ldap_backend_type == "fedora-ds":
-        backend_modules = ["nsuniqueid","paged_searches"]
+        backend_modules = ["nsuniqueid", "paged_searches"]
+        # We can handle linked attributes here, as we don't have directory-side subtree operations
+        tdb_modules_list = ["linked_attributes"]
     elif ldap_backend_type == "openldap":
-        backend_modules = ["normalise","entryuuid","paged_searches"]
+        backend_modules = ["normalise", "entryuuid", "paged_searches"]
+        # OpenLDAP handles subtree renames, so we don't want to do any of these things
+        tdb_modules_list = None
     elif serverrole == "domain controller":
         backend_modules = ["repl_meta_data"]
     else:
         backend_modules = ["objectguid"]
+
+    if tdb_modules_list is None:
+        tdb_modules_list_as_string = ""
+    else:
+        tdb_modules_list_as_string = ","+",".join(tdb_modules_list)
         
     samdb.transaction_start()
     try:
@@ -358,7 +373,7 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
                 "CONFIGDN_MOD": "naming_fsmo,instancetype",
                 "DOMAINDN_MOD": "pdc_fsmo,password_hash,instancetype",
                 "MODULES_LIST": ",".join(modules_list),
-                "TDB_MODULES_LIST": ","+",".join(tdb_modules_list),
+                "TDB_MODULES_LIST": tdb_modules_list_as_string,
                 "MODULES_LIST2": ",".join(modules_list2),
                 "BACKEND_MOD": ",".join(backend_modules),
         })
@@ -379,7 +394,8 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
 
         message("Setting up sam.ldb rootDSE")
         setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, 
-                            dnsdomain, realm, rootdn, configdn, netbiosname)
+                            dnsdomain, realm, rootdn, configdn, netbiosname,
+                            sitename)
 
         if erase:
             message("Erasing data from partitions")
@@ -471,9 +487,28 @@ def setup_registry(path, setup_path, session_info, credentials, lp):
     assert os.path.exists(provision_reg)
     reg.diff_apply(provision_reg)
 
+def setup_idmapdb(path, setup_path, session_info, credentials, lp):
+    """Setup the idmap database.
+
+    :param path: path to the idmap database
+    :param setup_path: Function that returns a path to a setup file
+    :param session_info: Session information
+    :param credentials: Credentials
+    :param lp: Loadparm context
+    """
+    if os.path.exists(path):
+        os.unlink(path)
+
+    idmap_ldb = Ldb(path, session_info=session_info, credentials=credentials,
+                    lp=lp)
+
+    idmap_ldb.erase()
+    idmap_ldb.load_ldif_file_add(setup_path("idmap_init.ldif"))
+    return idmap_ldb
 
 def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, 
-                        dnsdomain, realm, rootdn, configdn, netbiosname):
+                        dnsdomain, realm, rootdn, configdn, netbiosname,
+                        sitename):
     """Setup the SamDB rootdse.
 
     :param samdb: Sam Database handle
@@ -483,7 +518,7 @@ def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname,
         "SCHEMADN": schemadn, 
         "NETBIOSNAME": netbiosname,
         "DNSDOMAIN": dnsdomain,
-        "DEFAULTSITE": DEFAULTSITE,
+        "DEFAULTSITE": sitename,
         "REALM": realm,
         "DNSNAME": "%s.%s" % (hostname, dnsdomain),
         "DOMAINDN": domaindn,
@@ -496,7 +531,7 @@ def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname,
 def setup_self_join(samdb, configdn, schemadn, domaindn, 
                     netbiosname, hostname, dnsdomain, machinepass, dnspass, 
                     realm, domainname, domainsid, invocationid, setup_path,
-                    policyguid, hostguid=None):
+                    policyguid, sitename, hostguid=None):
     """Join a host to its own domain."""
     if hostguid is not None:
         hostguid_add = "objectGUID: %s" % hostguid
@@ -509,7 +544,7 @@ def setup_self_join(samdb, configdn, schemadn, domaindn,
               "DOMAINDN": domaindn,
               "INVOCATIONID": invocationid,
               "NETBIOSNAME": netbiosname,
-              "DEFAULTSITE": DEFAULTSITE,
+              "DEFAULTSITE": sitename,
               "DNSNAME": "%s.%s" % (hostname, dnsdomain),
               "MACHINEPASS_B64": b64encode(machinepass),
               "DNSPASS_B64": b64encode(dnspass),
@@ -526,16 +561,21 @@ def setup_self_join(samdb, configdn, schemadn, domaindn,
 
 def setup_samdb(path, setup_path, session_info, credentials, lp, 
                 schemadn, configdn, domaindn, dnsdomain, realm, 
-                netbiosname, message, hostname, rootdn, erase, 
+                netbiosname, message, hostname, rootdn, 
                 domainsid, aci, domainguid, policyguid, 
                 domainname, fill, adminpass, krbtgtpass, 
                 machinepass, hostguid, invocationid, dnspass,
-                serverrole, ldap_backend=None, ldap_backend_type=None):
+                serverrole, sitename, ldap_backend=None, 
+                ldap_backend_type=None):
     """Setup a complete SAM Database.
     
     :note: This will wipe the main SAM database file!
     """
 
+    assert serverrole in ("domain controller", "member server")
+
+    erase = (fill != FILL_DRS)    
+
     # Also wipes the database
     setup_samdb_partitions(path, setup_path, schemadn=schemadn, configdn=configdn, 
                            domaindn=domaindn, message=message, lp=lp,
@@ -543,7 +583,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
                            hostname=hostname, netbiosname=netbiosname, 
                            dnsdomain=dnsdomain, realm=realm, rootdn=rootdn,
                            ldap_backend=ldap_backend, serverrole=serverrole,
-                           ldap_backend_type=ldap_backend_type, erase=erase)
+                           ldap_backend_type=ldap_backend_type, erase=erase,
+                           sitename=sitename)
 
     samdb = SamDB(path, session_info=session_info, 
                   credentials=credentials, lp=lp)
@@ -558,10 +599,10 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
     samdb = SamDB(path, session_info=session_info, 
                   credentials=credentials, lp=lp)
     samdb.set_domain_sid(domainsid)
-    if lp.get("server role") == "domain controller":
+    if serverrole == "domain controller":
         samdb.set_invocation_id(invocationid)
 
-    load_schema(setup_path, samdb, schemadn, netbiosname, configdn)
+    load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename)
 
     samdb.transaction_start()
         
@@ -583,7 +624,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
             "DOMAINSID": str(domainsid),
             "SCHEMADN": schemadn, 
             "NETBIOSNAME": netbiosname,
-            "DEFAULTSITE": DEFAULTSITE,
+            "DEFAULTSITE": sitename,
             "CONFIGDN": configdn,
             "POLICYGUID": policyguid,
             "DOMAINDN": domaindn,
@@ -613,7 +654,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
             setup_path("provision_schema_basedn_modify.ldif"), {
             "SCHEMADN": schemadn,
             "NETBIOSNAME": netbiosname,
-            "DEFAULTSITE": DEFAULTSITE,
+            "DEFAULTSITE": sitename,
             "CONFIGDN": configdn,
             })
 
@@ -628,7 +669,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
         setup_add_ldif(samdb, setup_path("provision_configuration.ldif"), {
             "CONFIGDN": configdn,
             "NETBIOSNAME": netbiosname,
-            "DEFAULTSITE": DEFAULTSITE,
+            "DEFAULTSITE": sitename,
             "DNSDOMAIN": dnsdomain,
             "DOMAIN": domainname,
             "SCHEMADN": schemadn,
@@ -655,7 +696,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
         setup_add_ldif(samdb, setup_path("provision.ldif"), {
             "DOMAINDN": domaindn,
             "NETBIOSNAME": netbiosname,
-            "DEFAULTSITE": DEFAULTSITE,
+            "DEFAULTSITE": sitename,
             "CONFIGDN": configdn,
             })
 
@@ -669,7 +710,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
                 "KRBTGTPASS_B64": b64encode(krbtgtpass),
                 })
 
-            if lp.get("server role") == "domain controller":
+            if serverrole == "domain controller":
                 message("Setting up self join")
                 setup_self_join(samdb, configdn=configdn, schemadn=schemadn, 
                                 domaindn=domaindn, invocationid=invocationid, 
@@ -678,7 +719,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
                                 machinepass=machinepass, domainname=domainname, 
                                 domainsid=domainsid, policyguid=policyguid,
                                 hostname=hostname, hostguid=hostguid, 
-                                setup_path=setup_path)
+                                setup_path=setup_path, sitename=sitename)
 
     #We want to setup the index last, as adds are faster unindexed
         message("Setting up sam.ldb index")
@@ -690,18 +731,20 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
     samdb.transaction_commit()
     return samdb
 
+
 FILL_FULL = "FULL"
 FILL_NT4SYNC = "NT4SYNC"
 FILL_DRS = "DRS"
 
-def provision(lp, setup_dir, message, paths, session_info, 
-              credentials, samdb_fill=FILL_FULL, realm=None, rootdn=None,
+def provision(setup_dir, message, session_info, 
+              credentials, smbconf=None, targetdir=None, samdb_fill=FILL_FULL, realm=None, 
+              rootdn=None, domaindn=None, schemadn=None, configdn=None,
               domain=None, hostname=None, hostip=None, domainsid=None, 
               hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None, 
               policyguid=None, invocationid=None, machinepass=None, 
               dnspass=None, root=None, nobody=None, nogroup=None, users=None, 
-              wheel=None, backup=None, aci=None, serverrole=None, erase=False,
-              ldap_backend=None, ldap_backend_type=None):
+              wheel=None, backup=None, aci=None, serverrole=None, 
+              ldap_backend=None, ldap_backend_type=None, sitename=DEFAULTSITE):
     """Provision samba4
     
     :note: caution, this wipes all existing data!
@@ -737,6 +780,65 @@ def provision(lp, setup_dir, message, paths, session_info,
         backup = findnss(grp.getgrnam, ["backup", "wheel", "root", "staff"])[0]
     if aci is None:
         aci = "# no aci for local ldb"
+    if hostname is None:
+        hostname = gethostname().split(".")[0].lower()
+
+    if hostip is None:
+        hostip = gethostbyname(hostname)
+
+    netbiosname = hostname.upper()
+    if not valid_netbios_name(netbiosname):
+        raise InvalidNetbiosName(netbiosname)
+
+    if targetdir is not None:
+        if not os.path.exists(targetdir):
+            os.mkdir(targetdir)
+        if not os.path.exists(os.path.join(targetdir, "etc")):
+           os.mkdir(os.path.join(targetdir, "etc"))
+
+        if smbconf is None:
+            smbconf = os.path.join(targetdir, os.path.join("etc", "smb.conf"))
+
+    # only install a new smb.conf if there isn't one there already
+    if not os.path.exists(smbconf):
+        message("Setting up smb.conf")
+        assert serverrole is not None
+        if serverrole == "domain controller":
+            smbconfsuffix = "dc"
+        elif serverrole == "member server":
+            smbconfsuffix = "member"
+
+        assert domain is not None
+        assert realm is not None
+
+        default_lp = param.LoadParm()
+        #Load non-existant file
+        default_lp.load(smbconf)
+        
+        if targetdir is not None:
+            privatedir_line = "private dir = " + os.path.abspath(os.path.join(targetdir, "private"))
+            lockdir_line = "lock dir = " + os.path.abspath(targetdir)
+
+            default_lp.set("lock dir", os.path.abspath(targetdir))
+            
+        sysvol = os.path.join(default_lp.get("lock dir"), "sysvol")
+        netlogon = os.path.join(os.path.join(sysvol, "scripts"))
+
+        setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), 
+                   smbconf, {
+                "HOSTNAME": hostname,
+                "DOMAIN_CONF": domain,
+                "REALM_CONF": realm,
+                "SERVERROLE": serverrole,
+                "NETLOGONPATH": netlogon,
+                "SYSVOLPATH": sysvol,
+                "PRIVATEDIR_LINE": privatedir_line,
+                "LOCKDIR_LINE": lockdir_line
+                })
+
+    lp = param.LoadParm()
+    lp.load(smbconf)
+
     if serverrole is None:
         serverrole = lp.get("server role")
     assert serverrole in ("domain controller", "member server")
@@ -746,32 +848,26 @@ def provision(lp, setup_dir, message, paths, session_info,
     if realm is None:
         realm = lp.get("realm")
 
-    if lp.get("realm").upper() != realm.upper():
-        raise Exception("realm '%s' in smb.conf must match chosen realm '%s'" %
-                (lp.get("realm"), realm))
-
-    ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="")
-    
-    if ldap_backend == "ldapi":
-        # provision-backend will set this path suggested slapd command line / fedorads.inf
-        ldap_backend = "ldapi://" % urllib.quote(os.path.join(lp.get("private dir"), "ldap", "ldapi"), safe="")
-
     assert realm is not None
     realm = realm.upper()
 
-    if hostname is None:
-        hostname = gethostname().split(".")[0].lower()
+    dnsdomain = realm.lower()
 
-    if hostip is None:
-        hostip = gethostbyname(hostname)
+    paths = provision_paths_from_lp(lp, dnsdomain)
 
-    netbiosname = hostname.upper()
-    if not valid_netbios_name(netbiosname):
-        raise InvalidNetbiosName(netbiosname)
+    if targetdir is not None:
+        if not os.path.exists(paths.private_dir):
+            os.mkdir(paths.private_dir)
+
+    ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="")
+    
+    if ldap_backend == "ldapi":
+        # provision-backend will set this path suggested slapd command line / fedorads.inf
+        ldap_backend = "ldapi://" % urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="")
 
-    dnsdomain = realm.lower()
     if serverrole == "domain controller":
-        domaindn = "DC=" + dnsdomain.replace(".", ",DC=")
+        if domaindn is None:
+            domaindn = "DC=" + dnsdomain.replace(".", ",DC=")
         if domain is None:
             domain = lp.get("workgroup")
     
@@ -784,38 +880,25 @@ def provision(lp, setup_dir, message, paths, session_info,
         if not valid_netbios_name(domain):
             raise InvalidNetbiosName(domain)
     else:
-        domaindn = "CN=" + netbiosname
+        if domaindn is None:
+            domaindn = "CN=" + netbiosname
         domain = netbiosname
     
     if rootdn is None:
        rootdn = domaindn
        
-    configdn = "CN=Configuration," + rootdn
-    schemadn = "CN=Schema," + configdn
+    if configdn is None:
+        configdn = "CN=Configuration," + rootdn
+    if schemadn is None:
+        schemadn = "CN=Schema," + configdn
 
     message("set DOMAIN SID: %s" % str(domainsid))
     message("Provisioning for %s in realm %s" % (domain, realm))
     message("Using administrator password: %s" % adminpass)
 
-    assert paths.smbconf is not None
-
-    # only install a new smb.conf if there isn't one there already
-    if not os.path.exists(paths.smbconf):
-        message("Setting up smb.conf")
-        if serverrole == "domain controller":
-            smbconfsuffix = "dc"
-        elif serverrole == "member":
-            smbconfsuffix = "member"
-        setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), 
-                   paths.smbconf, {
-            "HOSTNAME": hostname,
-            "DOMAIN_CONF": domain,
-            "REALM_CONF": realm,
-            "SERVERROLE": serverrole,
-            "NETLOGONPATH": paths.netlogon,
-            "SYSVOLPATH": paths.sysvol,
-            })
-        lp.load(paths.smbconf)
+    if lp.get("realm").upper() != realm.upper():
+        raise Exception("realm '%s' in smb.conf must match chosen realm '%s'" %
+                        (lp.get("realm"), realm))
 
     # only install a new shares config db if there is none
     if not os.path.exists(paths.shareconf):
@@ -838,19 +921,23 @@ def provision(lp, setup_dir, message, paths, session_info,
     setup_templatesdb(paths.templates, setup_path, session_info=session_info, 
                       credentials=credentials, lp=lp)
 
+    message("Setting up idmap db")
+    setup_idmapdb(paths.idmapdb, setup_path, session_info=session_info,
+                  credentials=credentials, lp=lp)
+
     samdb = setup_samdb(paths.samdb, setup_path, session_info=session_info, 
                         credentials=credentials, lp=lp, schemadn=schemadn, 
                         configdn=configdn, domaindn=domaindn,
                         dnsdomain=dnsdomain, netbiosname=netbiosname, 
                         realm=realm, message=message, hostname=hostname, 
-                        rootdn=rootdn, erase=erase, domainsid=domainsid, 
+                        rootdn=rootdn, domainsid=domainsid, 
                         aci=aci, domainguid=domainguid, policyguid=policyguid, 
                         domainname=domain, fill=samdb_fill, 
                         adminpass=adminpass, krbtgtpass=krbtgtpass,
                         hostguid=hostguid, invocationid=invocationid, 
                         machinepass=machinepass, dnspass=dnspass,
                         serverrole=serverrole, ldap_backend=ldap_backend, 
-                        ldap_backend_type=ldap_backend_type)
+                        ldap_backend_type=ldap_backend_type, sitename=sitename)
 
     if lp.get("server role") == "domain controller":
        policy_path = os.path.join(paths.sysvol, dnsdomain, "Policies", 
@@ -876,32 +963,52 @@ def provision(lp, setup_dir, message, paths, session_info,
         message("Setting up sam.ldb rootDSE marking as synchronized")
         setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif"))
 
+        # Only make a zone file on the first DC, it should be replicated with DNS replication
+        if serverrole == "domain controller":
+            samdb = SamDB(paths.samdb, session_info=session_info, 
+                      credentials=credentials, lp=lp)
+
+            domainguid = samdb.searchone(basedn=domaindn, attribute="objectGUID")
+            assert isinstance(domainguid, str)
+            hostguid = samdb.searchone(basedn=domaindn, attribute="objectGUID",
+                                       expression="(&(objectClass=computer)(cn=%s))" % hostname,
+                                       scope=SCOPE_SUBTREE)
+            assert isinstance(hostguid, str)
+            
+            message("Setting up DNS zone: %s" % dnsdomain)
+            create_zone_file(paths.dns, setup_path, samdb, 
+                             hostname=hostname, hostip=hostip, dnsdomain=dnsdomain,
+                             domaindn=domaindn, dnspass=dnspass, realm=realm, 
+                             domainguid=domainguid, hostguid=hostguid)
+            message("Please install the zone located in %s into your DNS server" % paths.dns)
+            
     message("Setting up phpLDAPadmin configuration")
     create_phpldapadmin_config(paths.phpldapadminconfig, setup_path, 
                                ldapi_url)
 
     message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig)
 
-    if lp.get("server role") == "domain controller":
-        samdb = SamDB(paths.samdb, session_info=session_info, 
-                      credentials=credentials, lp=lp)
-
-        domainguid = samdb.searchone(basedn=domaindn, attribute="objectGUID")
-        assert isinstance(domainguid, str)
-        hostguid = samdb.searchone(basedn=domaindn, attribute="objectGUID",
-                expression="(&(objectClass=computer)(cn=%s))" % hostname,
-                scope=SCOPE_SUBTREE)
-        assert isinstance(hostguid, str)
-
-        message("Setting up DNS zone: %s" % dnsdomain)
-        create_zone_file(paths.dns, setup_path, samdb, 
-                      hostname=hostname, hostip=hostip, dnsdomain=dnsdomain,
-                      domaindn=domaindn, dnspass=dnspass, realm=realm, 
-                      domainguid=domainguid, hostguid=hostguid)
-        message("Please install the zone located in %s into your DNS server" % paths.dns)
-
     return domaindn
 
+def provision_become_dc(setup_dir=None,
+                        smbconf=None, targetdir=None, realm=None, 
+                        rootdn=None, domaindn=None, schemadn=None, configdn=None,
+                        domain=None, hostname=None, domainsid=None, 
+                        hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None, 
+                        policyguid=None, invocationid=None, machinepass=None, 
+                        dnspass=None, root=None, nobody=None, nogroup=None, users=None, 
+                        wheel=None, backup=None, aci=None, serverrole=None, 
+                        ldap_backend=None, ldap_backend_type=None, sitename=DEFAULTSITE):
+
+    def message(text):
+       """print a message if quiet is not set."""
+        print text
+
+    provision(setup_dir, message, system_session(), None,
+              smbconf=smbconf, targetdir=targetdir, samdb_fill=FILL_DRS, realm=realm, 
+              rootdn=rootdn, domaindn=domaindn, schemadn=schemadn, configdn=configdn, 
+              domain=domain, hostname=hostname, hostip="127.0.0.1", domainsid=domainsid, machinepass=machinepass, serverrole="domain controller", sitename=sitename);
+    
 
 def create_phpldapadmin_config(path, setup_path, ldapi_uri):
     """Create a PHP LDAP admin configuration file.
@@ -943,8 +1050,7 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn,
             "HOSTGUID": hostguid,
         })
 
-
-def load_schema(setup_path, samdb, schemadn, netbiosname, configdn):
+def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename):
     """Load schema for the SamDB.
     
     :param samdb: Load a schema into a SamDB.
@@ -961,7 +1067,7 @@ def load_schema(setup_path, samdb, schemadn, netbiosname, configdn):
                     "SCHEMADN": schemadn,
                     "NETBIOSNAME": netbiosname,
                     "CONFIGDN": configdn,
-                    "DEFAULTSITE": DEFAULTSITE
+                    "DEFAULTSITE":sitename 
     })
     samdb.attach_schema_from_ldif(head_data, schema_data)