1
0
mirror of https://github.com/samba-team/samba.git synced 2025-07-22 16:59:09 +03:00

python/provision: Reconcile code partitions-only provisioning and generic provisioning, some other minor refactoring of the provisioning.

Pair-programmed by Andrew and me using obby :-)
(This used to be commit 688adcbb63)
This commit is contained in:
Jelmer Vernooij
2008-01-25 01:02:13 +01:00
parent 8afcbdcfe7
commit 37f35d2a03
6 changed files with 314 additions and 251 deletions

View File

@ -1,10 +1,25 @@
#
# backend code for provisioning a Samba4 server
# Released under the GNU GPL v3 or later
# Copyright Jelmer Vernooij 2007
# Unix SMB/CIFS implementation.
# backend code for provisioning a Samba4 server
# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2008
# Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008
#
# Based on the original in EJS:
# Copyright Andrew Tridgell 2005
# Copyright (C) Andrew Tridgell <tridge@samba.org> 2005
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from base64 import b64encode
@ -17,9 +32,10 @@ from socket import gethostname, gethostbyname
import param
import registry
import samba
from samba import Ldb, substitute_var, valid_netbios_name
from samba import Ldb, substitute_var, valid_netbios_name, check_all_substituted
from samba.samdb import SamDB
import security
import urllib
from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \
LDB_ERR_NO_SUCH_OBJECT, timestring, CHANGETYPE_MODIFY, CHANGETYPE_NONE
@ -53,7 +69,7 @@ class ProvisionPaths:
self.ldap_schema_basedn_ldif = None
def install_ok(lp, session_info, credentials):
def check_install(lp, session_info, credentials):
"""Check whether the current install seems ok.
:param lp: Loadparm context
@ -61,12 +77,11 @@ def install_ok(lp, session_info, credentials):
:param credentials: Credentials
"""
if lp.get("realm") == "":
return False
raise Error("Realm empty")
ldb = Ldb(lp.get("sam database"), session_info=session_info,
credentials=credentials, lp=lp)
if len(ldb.search("(cn=Administrator)")) != 1:
return False
return True
raise "No administrator account found"
def findnss(nssfn, *names):
@ -112,7 +127,7 @@ def setup_add_ldif(ldb, ldif_path, subst_vars=None):
if subst_vars is not None:
data = substitute_var(data, subst_vars)
assert "${" not in data
check_all_substituted(data)
ldb.add_ldif(data)
@ -128,7 +143,7 @@ def setup_modify_ldif(ldb, ldif_path, substvars=None):
if substvars is not None:
data = substitute_var(data, substvars)
assert "${" not in data
check_all_substituted(data)
ldb.modify_ldif(data)
@ -159,19 +174,20 @@ def setup_file(template, fname, substvars):
data = open(template, 'r').read()
if substvars:
data = substitute_var(data, substvars)
assert not "${" in data
check_all_substituted(data)
open(f, 'w').write(data)
def provision_paths_from_lp(lp, dnsdomain):
def provision_paths_from_lp(lp, dnsdomain, private_dir=None):
"""Set the default paths for provisioning.
:param lp: Loadparm context.
:param dnsdomain: DNS Domain name
"""
paths = ProvisionPaths()
private_dir = lp.get("private dir")
if private_dir is None:
private_dir = lp.get("private dir")
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")
@ -235,57 +251,144 @@ def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users,
ldb.setup_name_mapping(domaindn, sid + "-520", wheel)
def provision_become_dc(setup_dir, message, paths, lp, session_info,
credentials):
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,
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.
:param
:note: This will wipe the Sam Database!
:note: This function always removes the local SAM LDB file. The erase
parameter controls whether to erase the existing data, which
may not be stored locally but in LDAP.
"""
assert session_info is not None
erase = False
def setup_path(file):
return os.path.join(setup_dir, file)
os.path.unlink(paths.samdb)
message("Setting up templates db")
setup_templatesdb(paths.templates, setup_path, session_info=session_info,
credentials=credentials, lp=lp)
if os.path.exists(samdb_path):
os.unlink(samdb_path)
# Also wipes the database
message("Setting up sam.ldb")
samdb = SamDB(paths.samdb, session_info=session_info,
samdb = SamDB(samdb_path, session_info=session_info,
credentials=credentials, lp=lp)
message("Setting up sam.ldb partitions")
setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn)
#Add modules to the list to activate them by default
#beware often order is important
#
# Some Known ordering constraints:
# - rootdse must be first, as it makes redirects from "" -> cn=rootdse
# - objectclass must be before password_hash, because password_hash checks
# that the objectclass is of type person (filled in by objectclass
# module when expanding the objectclass list)
# - partition must be last
# - each partition has its own module list then
modules_list = ["rootdse",
"paged_results",
"ranged_results",
"anr",
"server_sort",
"extended_dn",
"asq",
"samldb",
"rdn_name",
"objectclass",
"kludge_acl",
"operational"]
tdb_modules_list = [
"subtree_rename",
"subtree_delete",
"linked_attributes"]
modules_list2 = ["show_deleted",
"partition"]
domaindn_ldb = "users.ldb"
if ldap_backend is not None:
domaindn_ldb = ldap_backend
configdn_ldb = "configuration.ldb"
if ldap_backend is not None:
configdn_ldb = ldap_backend
schema_ldb = "schema.ldb"
if ldap_backend is not None:
schema_ldb = ldap_backend
if ldap_backend_type == "fedora-ds":
backend_modules = ["nsuniqueid","paged_searches"]
elif ldap_backend_type == "openldap":
backend_modules = ["normalise","entryuuid","paged_searches"]
elif serverrole == "domain controller":
backend_modules = ["repl_meta_data"]
else:
backend_modules = ["objectguid"]
setup_add_ldif(samdb, setup_path("provision_partitions.ldif"), {
"SCHEMADN": schemadn,
"SCHEMADN_LDB": "schema.ldb",
"SCHEMADN_MOD2": ",objectguid",
"CONFIGDN": configdn,
"CONFIGDN_LDB": "configuration.ldb",
"DOMAINDN": domaindn,
"DOMAINDN_LDB": "users.ldb",
"SCHEMADN_MOD": "schema_fsmo,instancetype",
"CONFIGDN_MOD": "naming_fsmo,instancetype",
"DOMAINDN_MOD": "pdc_fsmo,password_hash,instancetype",
"MODULES_LIST": ",".join(modules_list),
"TDB_MODULES_LIST": ","+",".join(tdb_modules_list),
"MODULES_LIST2": ",".join(modules_list2),
"BACKEND_MOD": ",".join(backend_modules),
})
samdb = SamDB(paths.samdb, session_info=session_info,
samdb = SamDB(samdb_path, session_info=session_info,
credentials=credentials, lp=lp)
ldb.transaction_start()
samdb.transaction_start()
try:
message("Setting up sam.ldb attributes")
samdb.load_ldif_file_add(setup_path("provision_init.ldif"))
message("Setting up sam.ldb rootDSE")
setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn,
hostname, dnsdomain, realm, rootdn, configdn,
netbiosname)
setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname,
dnsdomain, realm, rootdn, configdn, netbiosname)
if erase:
message("Erasing data from partitions")
samdb.erase_partitions()
message("Setting up sam.ldb indexes")
samdb.load_ldif_file_add(setup_path("provision_index.ldif"))
except:
samdb.transaction_cancel()
raise
samdb.transaction_commit()
return samdb
message("Setting up %s" % paths.secrets)
secrets_ldb = setup_secretsdb(paths.secrets, setup_path, session_info,
credentials, lp)
setup_ldb(secrets_ldb, setup_path("secrets_dc.ldif"),
{ "MACHINEPASS_B64": b64encode(machinepass) })
def secretsdb_become_dc(secretsdb, setup_path, domain, realm, dnsdomain,
netbiosname, domainsid, keytab_path, samdb_url,
dns_keytab_path, dnspass, machinepass):
"""Add DC-specific bits to a secrets database.
:param secretsdb: Ldb Handle to the secrets database
:param setup_path: Setup path function
:param machinepass: Machine password
"""
setup_ldb(secretsdb, setup_path("secrets_dc.ldif"), {
"MACHINEPASS_B64": b64encode(machinepass),
"DOMAIN": domain,
"REALM": realm,
"DNSDOMAIN": dnsdomain,
"DOMAINSID": str(domainsid),
"SECRETS_KEYTAB": keytab_path,
"NETBIOSNAME": netbiosname,
"SAM_LDB": samdb_url,
"DNS_KEYTAB": dns_keytab_path,
"DNSPASS_B64": b64encode(dnspass),
})
def setup_secretsdb(path, setup_path, session_info, credentials, lp):
@ -296,10 +399,12 @@ def setup_secretsdb(path, setup_path, session_info, credentials, lp):
:param session_info: Session info.
:param credentials: Credentials
:param lp: Loadparm context
:return: LDB handle for the created secrets database
"""
if os.path.exists(path):
os.unlink(path)
secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials, lp=lp)
secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials,
lp=lp)
secrets_ldb.erase()
secrets_ldb.load_ldif_file_add(setup_path("secrets_init.ldif"))
secrets_ldb.load_ldif_file_add(setup_path("secrets.ldif"))
@ -316,7 +421,7 @@ def setup_templatesdb(path, setup_path, session_info, credentials, lp):
:param lp: Loadparm context
"""
templates_ldb = SamDB(path, session_info=session_info,
credentials=credentials, lp=lp)
credentials=credentials, lp=lp)
templates_ldb.erase()
templates_ldb.load_ldif_file_add(setup_path("provision_templates.ldif"))
@ -359,69 +464,13 @@ def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname,
"CONFIGDN": configdn,
"VERSION": samba.version(),
})
def setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn):
"""Setup SAM database partitions.
:param samdb: Sam Database handle
:param setup_path: Setup path function
:param schemadn: Schema DN.
:param configdn: Configuration DN.
:param domaindn: Domain DN.
"""
#Add modules to the list to activate them by default
#beware often order is important
#
# Some Known ordering constraints:
# - rootdse must be first, as it makes redirects from "" -> cn=rootdse
# - objectclass must be before password_hash, because password_hash checks
# that the objectclass is of type person (filled in by objectclass
# module when expanding the objectclass list)
# - partition must be last
# - each partition has its own module list then
modules_list = ["rootdse",
"paged_results",
"ranged_results",
"anr",
"server_sort",
"extended_dn",
"asq",
"samldb",
"rdn_name",
"objectclass",
"kludge_acl",
"operational"]
tdb_modules_list = [
"subtree_rename",
"subtree_delete",
"linked_attributes"]
modules_list2 = ["show_deleted",
"partition"]
setup_add_ldif(samdb, setup_path("provision_partitions.ldif"), {
"SCHEMADN": schemadn,
"SCHEMADN_LDB": "schema.ldb",
"SCHEMADN_MOD2": ",objectguid",
"CONFIGDN": configdn,
"CONFIGDN_LDB": "configuration.ldb",
"DOMAINDN": domaindn,
"DOMAINDN_LDB": "users.ldb",
"SCHEMADN_MOD": "schema_fsmo",
"CONFIGDN_MOD": "naming_fsmo",
"CONFIGDN_MOD2": ",objectguid",
"DOMAINDN_MOD": "pdc_fsmo,password_hash",
"DOMAINDN_MOD2": ",objectguid",
"MODULES_LIST": ",".join(modules_list),
"TDB_MODULES_LIST": ","+",".join(tdb_modules_list),
"MODULES_LIST2": ",".join(modules_list2),
})
def setup_self_join(samdb, configdn, schemadn, domaindn,
netbiosname, hostname, dnsdomain, machinepass, dnspass,
realm, domainname, domainsid, invocationid, setup_path,
policyguid, hostguid=None):
"""Join a host to its own domain."""
if hostguid is not None:
hostguid_add = "objectGUID: %s" % hostguid
else:
@ -451,43 +500,39 @@ 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,
domainsid, aci, rdn_dc, domainguid, policyguid,
domainname, blank, adminpass, krbtgtpass,
machinepass, hostguid, invocationid, dnspass):
domainsid, aci, domainguid, policyguid,
domainname, fill, adminpass, krbtgtpass,
machinepass, hostguid, invocationid, dnspass,
serverrole, ldap_backend=None, ldap_backend_type=None):
"""Setup a complete SAM Database.
"""
# Also wipes the database
message("Setting up sam.ldb")
samdb = SamDB(path, session_info=session_info,
credentials=credentials, lp=lp)
message("Setting up sam.ldb partitions")
setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn)
setup_samdb_partitions(path, setup_path, schemadn=schemadn, configdn=configdn,
domaindn=domaindn, message=message, lp=lp,
credentials=credentials, session_info=session_info,
hostname=hostname, netbiosname=netbiosname,
dnsdomain=dnsdomain, realm=realm, rootdn=rootdn,
ldap_backend=ldap_backend, serverrole=serverrole,
ldap_backend_type=ldap_backend_type, erase=erase)
samdb = SamDB(path, session_info=session_info,
credentials=credentials, lp=lp)
samdb.transaction_start()
try:
message("Setting up sam.ldb attributes")
samdb.load_ldif_file_add(setup_path("provision_init.ldif"))
message("Setting up sam.ldb rootDSE")
setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn,
hostname, dnsdomain, realm, rootdn, configdn,
netbiosname)
if erase:
message("Erasing data from partitions")
samdb.erase_partitions()
except:
samdb.transaction_cancel()
raise
samdb.transaction_commit()
if fill == FILL_DRS:
# We want to finish here, but setup the index before we do so
message("Setting up sam.ldb index")
samdb.load_ldif_file_add(setup_path("provision_index.ldif"))
return samdb
message("Pre-loading the Samba 4 and AD schema")
samdb = SamDB(path, session_info=session_info,
credentials=credentials, lp=lp)
samdb.set_domain_sid(domainsid)
if lp.get("server role") == "domain controller":
samdb.set_invocation_id(invocationid)
load_schema(setup_path, samdb, schemadn, netbiosname, configdn)
samdb.transaction_start()
@ -497,7 +542,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
setup_add_ldif(samdb, setup_path("provision_basedn.ldif"), {
"DOMAINDN": domaindn,
"ACI": aci,
"RDN_DC": rdn_dc,
})
message("Modifying DomainDN: " + domaindn + "")
@ -507,7 +551,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
domainguid_mod = ""
setup_modify_ldif(samdb, setup_path("provision_basedn_modify.ldif"), {
"RDN_DC": rdn_dc,
"LDAPTIME": timestring(int(time.time())),
"DOMAINSID": str(domainsid),
"SCHEMADN": schemadn,
@ -538,7 +581,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
"EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb"
})
message("Modifying schema container")
setup_modify_ldif(samdb, setup_path("provision_schema_basedn_modify.ldif"), {
setup_modify_ldif(samdb,
setup_path("provision_schema_basedn_modify.ldif"), {
"SCHEMADN": schemadn,
"NETBIOSNAME": netbiosname,
"DEFAULTSITE": DEFAULTSITE,
@ -587,7 +631,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
"CONFIGDN": configdn,
})
if not blank:
if fill == FILL_FULL:
message("Setting up sam.ldb users and groups")
setup_add_ldif(samdb, setup_path("provision_users.ldif"), {
"DOMAINDN": domaindn,
@ -608,11 +652,9 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
hostname=hostname, hostguid=hostguid,
setup_path=setup_path)
#We want to setup the index last, as adds are faster unindexed
message("Setting up sam.ldb index")
samdb.load_ldif_file_add(setup_path("provision_index.ldif"))
message("Setting up sam.ldb rootDSE marking as synchronized")
setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif"))
except:
samdb.transaction_cancel()
raise
@ -620,14 +662,18 @@ 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, blank, paths, session_info,
credentials, ldapbackend, realm=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):
def provision(lp, setup_dir, message, paths, session_info,
credentials, ldapbackend, samdb_fill=FILL_FULL, realm=None, rootdn=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):
"""Provision samba4
:note: caution, this wipes all existing data!
@ -636,14 +682,10 @@ def provision(lp, setup_dir, message, blank, paths, session_info,
def setup_path(file):
return os.path.join(setup_dir, file)
erase = False
if domainsid is None:
domainsid = security.random_sid()
if policyguid is None:
policyguid = uuid.random()
if invocationid is None:
invocationid = uuid.random()
if adminpass is None:
adminpass = misc.random_password(12)
if krbtgtpass is None:
@ -669,29 +711,25 @@ def provision(lp, setup_dir, message, blank, paths, session_info,
aci = "# no aci for local ldb"
if serverrole is None:
serverrole = lp.get("server role")
if invocationid is None and serverrole == "domain controller":
invocationid = uuid.random()
if realm is None:
realm = lp.get("realm")
else:
if lp.get("realm").upper() != realm.upper():
raise Exception("realm '%s' in smb.conf must match chosen realm '%s'\n" %
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)
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"))
assert realm is not None
realm = realm.upper()
if domain is None:
domain = lp.get("workgroup")
else:
if lp.get("workgroup").upper() != domain.upper():
raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'\n",
lp.get("workgroup"), domain)
assert domain is not None
domain = domain.upper()
if not valid_netbios_name(domain):
raise InvalidNetbiosName(domain)
if hostname is None:
hostname = gethostname().split(".")[0].lower()
@ -703,13 +741,30 @@ def provision(lp, setup_dir, message, blank, paths, session_info,
raise InvalidNetbiosName(netbiosname)
dnsdomain = realm.lower()
domaindn = "DC=" + dnsdomain.replace(".", ",DC=")
rootdn = domaindn
if serverrole == "domain controller":
domaindn = "DC=" + dnsdomain.replace(".", ",DC=")
if domain is None:
domain = lp.get("workgroup")
if lp.get("workgroup").upper() != domain.upper():
raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'",
lp.get("workgroup"), domain)
assert domain is not None
domain = domain.upper()
if not valid_netbios_name(domain):
raise InvalidNetbiosName(domain)
else:
domaindn = "CN=" + netbiosname
domain = netbiosname
if rootdn is None:
rootdn = domaindn
configdn = "CN=Configuration," + rootdn
schemadn = "CN=Schema," + configdn
rdn_dc = domaindn.split(",")[0][len("DC="):]
message("set DOMAIN SID: %s" % str(domainsid))
message("Provisioning for %s in realm %s" % (domain, realm))
message("Using administrator password: %s" % adminpass)
@ -725,7 +780,8 @@ def provision(lp, setup_dir, message, blank, paths, session_info,
smbconfsuffix = "member"
else:
assert "Invalid server role setting: %s" % serverrole
setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), paths.smbconf, {
setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix),
paths.smbconf, {
"HOSTNAME": hostname,
"DOMAIN_CONF": domain,
"REALM_CONF": realm,
@ -742,6 +798,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info,
credentials=credentials, lp=lp)
share_ldb.load_ldif_file_add(setup_path("share.ldif"))
message("Setting up secrets.ldb")
secrets_ldb = setup_secretsdb(paths.secrets, setup_path,
session_info=session_info,
@ -755,44 +812,47 @@ def provision(lp, setup_dir, message, blank, paths, session_info,
setup_templatesdb(paths.templates, 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, aci=aci,
rdn_dc=rdn_dc, domainguid=domainguid, policyguid=policyguid,
domainname=domain, blank=blank, adminpass=adminpass, krbtgtpass=krbtgtpass,
hostguid=hostguid, invocationid=invocationid, machinepass=machinepass,
dnspass=dnspass)
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,
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)
if lp.get("server role") == "domain controller":
os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}"), 0755)
os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}", "Machine"), 0755)
os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}", "User"), 0755)
if not os.path.isdir(paths.netlogon):
policy_path = os.path.join(paths.sysvol, dnsdomain, "Policies",
"{" + policyguid + "}")
os.makedirs(policy_path, 0755)
os.makedirs(os.path.join(policy_path, "Machine"), 0755)
os.makedirs(os.path.join(policy_path, "User"), 0755)
if not os.path.isdir(paths.netlogon):
os.makedirs(paths.netlogon, 0755)
secrets_ldb = Ldb(paths.secrets, session_info=session_info, credentials=credentials, lp=lp)
setup_ldb(secrets_ldb, setup_path("secrets_dc.ldif"), {
"MACHINEPASS_B64": b64encode(machinepass),
"DOMAIN": domain,
"REALM": realm,
"LDAPTIME": timestring(int(time.time())),
"DNSDOMAIN": dnsdomain,
"DOMAINSID": str(domainsid),
"SECRETS_KEYTAB": paths.keytab,
"NETBIOSNAME": netbiosname,
"SAM_LDB": paths.samdb,
"DNS_KEYTAB": paths.dns_keytab,
"DNSPASS_B64": b64encode(dnspass),
})
secrets_ldb = Ldb(paths.secrets, session_info=session_info,
credentials=credentials, lp=lp)
secretsdb_become_dc(secrets_ldb, setup_path, domain=domain, realm=realm,
netbiosname=netbiosname, domainsid=domainsid,
keytab_path=paths.keytab, samdb_url=paths.samdb,
dns_keytab_path=paths.dns_keytab, dnspass=dnspass,
machinepass=machinepass, dnsdomain=dnsdomain)
if not blank:
setup_name_mappings(samdb, str(domainsid),
domaindn, root=root, nobody=nobody,
nogroup=nogroup, wheel=wheel, users=users,
backup=backup)
if samdb_fill == FILL_FULL:
setup_name_mappings(samdb, str(domainsid), domaindn, root=root,
nobody=nobody, nogroup=nogroup, wheel=wheel,
users=users, backup=backup)
message("Setting up sam.ldb rootDSE marking as synchronized")
setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif"))
message("Setting up phpLDAPadmin configuration")
create_phplpapdadmin_config(paths.phpldapadminconfig, setup_path, paths.s4_ldapi_path)
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)
@ -816,15 +876,15 @@ def provision(lp, setup_dir, message, blank, paths, session_info,
return domaindn
def create_phplpapdadmin_config(path, setup_path, s4_ldapi_path):
def create_phpldapadmin_config(path, setup_path, ldap_backend):
"""Create a PHP LDAP admin configuration file.
:param path: Path to write the configuration to.
:param setup_path: Function to generate setup paths.
:param s4_ldapi_path: Path to Samba 4 LDAPI socket.
"""
setup_file(setup_path("phpldapadmin-config.php"),
path, {"S4_LDAPI_URI": "ldapi://%s" % s4_ldapi_path.replace("/", "%2F")})
setup_file(setup_path("phpldapadmin-config.php"), path,
{"S4_LDAPI_URI": ldap_backend})
def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn,
@ -874,6 +934,7 @@ def load_schema(setup_path, samdb, schemadn, netbiosname, configdn):
"SCHEMADN": schemadn,
"NETBIOSNAME": netbiosname,
"CONFIGDN": configdn,
"DEFAULTSITE": DEFAULTSITE})
"DEFAULTSITE": DEFAULTSITE
})
samdb.attach_schema_from_ldif(head_data, schema_data)