summaryrefslogtreecommitdiff
path: root/source4/scripting
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2009-10-30 13:16:10 +1100
committerAndrew Bartlett <abartlet@samba.org>2009-11-02 16:36:54 +1100
commit350e96354543943b5e7249d517596ddfaf29c47e (patch)
tree8be988da856b6a6c731348a711dfdb5ae5d77750 /source4/scripting
parente035433bab87cb5f2f12def900e194da877e6925 (diff)
downloadsamba-350e96354543943b5e7249d517596ddfaf29c47e.tar.gz
samba-350e96354543943b5e7249d517596ddfaf29c47e.tar.bz2
samba-350e96354543943b5e7249d517596ddfaf29c47e.zip
s4:provision Rework provision to always have a ProvisionBackend
Rather than treat the LDAP backend as a special case, treat all backends the same, with different callbacks. Andrew Bartlett
Diffstat (limited to 'source4/scripting')
-rw-r--r--source4/scripting/python/samba/provision.py353
1 files changed, 188 insertions, 165 deletions
diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py
index 6c00127bc6..7558ad3d7c 100644
--- a/source4/scripting/python/samba/provision.py
+++ b/source4/scripting/python/samba/provision.py
@@ -184,7 +184,7 @@ class ProvisionResult(object):
class Schema(object):
def __init__(self, setup_path, domain_sid, schemadn=None,
- serverdn=None, sambadn=None, ldap_backend_type=None):
+ serverdn=None, sambadn=None):
"""Load schema for the SamDB from the AD schema files and samba4_schema.ldif
:param samdb: Load a schema into a SamDB.
@@ -604,8 +604,8 @@ def setup_name_mappings(samdb, idmap, sid, domaindn, root_uid, nobody_uid,
idmap.setup_name_mapping(sid + "-513", idmap.TYPE_GID, users_gid)
def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
- credentials, names, schema,
- serverrole, ldap_backend=None,
+ provision_backend, names, schema,
+ serverrole,
erase=False):
"""Setup the partitions for the SAM database.
@@ -628,7 +628,7 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
try:
samdb = Ldb(url=samdb_path, session_info=session_info,
- credentials=credentials, lp=lp, options=["modules:"])
+ lp=lp, options=["modules:"])
res = samdb.search(base="@PARTITION", scope=SCOPE_BASE, attrs=["partition"], expression="partition=*")
if len(res) == 1:
try:
@@ -651,7 +651,7 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
except LdbError:
os.unlink(samdb_path)
samdb = Ldb(url=samdb_path, session_info=session_info,
- credentials=credentials, lp=lp, options=["modules:"])
+ lp=lp, options=["modules:"])
# Wipes the database
samdb.erase_except_schema_controlled()
@@ -693,11 +693,12 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
"schema_load",
"new_partition",
"partition"]
+
ldap_backend_line = "# No LDAP backend"
- if ldap_backend is not None:
- ldap_backend_line = "ldapBackend: %s" % ldap_backend.ldapi_uri
+ if provision_backend.type is not "ldb":
+ ldap_backend_line = "ldapBackend: %s" % provision_backend.ldapi_uri
- if ldap_backend.ldap_backend_type == "fedora-ds":
+ if provision_backend.ldap_backend_type == "fedora-ds":
backend_modules = ["nsuniqueid", "paged_searches"]
# We can handle linked attributes here, as we don't have directory-side subtree operations
tdb_modules_list = ["extended_dn_out_fds"]
@@ -837,7 +838,7 @@ def secretsdb_setup_dns(secretsdb, setup_path, realm, dnsdomain,
})
-def setup_secretsdb(path, setup_path, session_info, credentials, lp):
+def setup_secretsdb(path, setup_path, session_info, backend_credentials, lp):
"""Setup the secrets database.
:param path: Path to the secrets database.
@@ -849,26 +850,26 @@ def setup_secretsdb(path, setup_path, session_info, credentials, lp):
"""
if os.path.exists(path):
os.unlink(path)
- secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials,
+ secrets_ldb = Ldb(path, session_info=session_info,
lp=lp)
secrets_ldb.erase()
secrets_ldb.load_ldif_file_add(setup_path("secrets_init.ldif"))
- secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials,
+ secrets_ldb = Ldb(path, session_info=session_info,
lp=lp)
secrets_ldb.transaction_start()
secrets_ldb.load_ldif_file_add(setup_path("secrets.ldif"))
- if credentials is not None and credentials.authentication_requested():
- if credentials.get_bind_dn() is not None:
+ if backend_credentials is not None and backend_credentials.authentication_requested():
+ if backend_credentials.get_bind_dn() is not None:
setup_add_ldif(secrets_ldb, setup_path("secrets_simple_ldap.ldif"), {
- "LDAPMANAGERDN": credentials.get_bind_dn(),
- "LDAPMANAGERPASS_B64": b64encode(credentials.get_password())
+ "LDAPMANAGERDN": backend_credentials.get_bind_dn(),
+ "LDAPMANAGERPASS_B64": b64encode(backend_credentials.get_password())
})
else:
setup_add_ldif(secrets_ldb, setup_path("secrets_sasl_ldap.ldif"), {
- "LDAPADMINUSER": credentials.get_username(),
- "LDAPADMINREALM": credentials.get_realm(),
- "LDAPADMINPASS_B64": b64encode(credentials.get_password())
+ "LDAPADMINUSER": backend_credentials.get_username(),
+ "LDAPADMINREALM": backend_credentials.get_realm(),
+ "LDAPADMINPASS_B64": b64encode(backend_credentials.get_password())
})
return secrets_ldb
@@ -1003,13 +1004,13 @@ def setup_self_join(samdb, names,
})
-def setup_samdb(path, setup_path, session_info, credentials, lp,
+def setup_samdb(path, setup_path, session_info, provision_backend, lp,
names, message,
domainsid, domainguid, policyguid, policyguid_dc,
fill, adminpass, krbtgtpass,
machinepass, invocationid, dnspass, ntdsguid,
serverrole, dom_for_fun_level=None,
- schema=None, ldap_backend=None):
+ schema=None):
"""Setup a complete SAM Database.
:note: This will wipe the main SAM database file!
@@ -1032,17 +1033,17 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
# Also wipes the database
setup_samdb_partitions(path, setup_path, message=message, lp=lp,
- credentials=credentials, session_info=session_info,
- names=names, ldap_backend=ldap_backend,
+ provision_backend=provision_backend, session_info=session_info,
+ names=names,
serverrole=serverrole, schema=schema)
if (schema == None):
schema = Schema(setup_path, domainsid, schemadn=names.schemadn, serverdn=names.serverdn,
- sambadn=names.sambadn, ldap_backend_type=ldap_backend.ldap_backend_type)
+ sambadn=names.sambadn)
# Load the database, but importantly, use Ldb not SamDB as we don't want to load the global schema
samdb = Ldb(session_info=session_info,
- credentials=credentials, lp=lp)
+ credentials=provision_backend.credentials, lp=lp)
message("Pre-loading the Samba 4 and AD schema")
@@ -1222,7 +1223,7 @@ def provision(setup_dir, message, session_info,
dnspass=None, root=None, nobody=None, users=None,
wheel=None, backup=None, aci=None, serverrole=None,
dom_for_fun_level=None,
- ldap_backend_extra_port=None, ldap_backend_type=None,
+ ldap_backend_extra_port=None, backend_type=None,
sitename=None,
ol_mmr_urls=None, ol_olc=None,
setup_ds_path=None, slapd_path=None, nosync=False,
@@ -1260,8 +1261,11 @@ def provision(setup_dir, message, session_info,
#Make a new, random password between Samba and it's LDAP server
ldapadminpass=glue.generate_random_str(12)
+ if backend_type is None:
+ backend_type = "ldb"
+
sid_generator = "internal"
- if ldap_backend_type == "fedora-ds":
+ if backend_type == "fedora-ds":
sid_generator = "backend"
root_uid = findnss_uid([root or "root"])
@@ -1319,44 +1323,34 @@ def provision(setup_dir, message, session_info,
ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="")
schema = Schema(setup_path, domainsid, schemadn=names.schemadn, serverdn=names.serverdn,
- sambadn=names.sambadn, ldap_backend_type=ldap_backend_type)
+ sambadn=names.sambadn)
- secrets_credentials = credentials
- provision_backend = None
- if ldap_backend_type:
- # We only support an LDAP backend over ldapi://
-
- provision_backend = ProvisionBackend(paths=paths, setup_path=setup_path,
- lp=lp, credentials=credentials,
- names=names,
- message=message, hostname=hostname,
- root=root, schema=schema,
- ldap_backend_type=ldap_backend_type,
- ldapadminpass=ldapadminpass,
- ldap_backend_extra_port=ldap_backend_extra_port,
- ol_mmr_urls=ol_mmr_urls,
- slapd_path=slapd_path,
- setup_ds_path=setup_ds_path,
- ldap_dryrun_mode=ldap_dryrun_mode,
- domainsid=domainsid)
-
- # Now use the backend credentials to access the databases
- credentials = provision_backend.credentials
- secrets_credentials = provision_backend.adminCredentials
- ldapi_url = provision_backend.ldapi_uri
+ provision_backend = ProvisionBackend(backend_type,
+ paths=paths, setup_path=setup_path,
+ lp=lp, credentials=credentials,
+ names=names,
+ message=message, hostname=hostname,
+ root=root, schema=schema,
+ ldapadminpass=ldapadminpass,
+ ldap_backend_extra_port=ldap_backend_extra_port,
+ ol_mmr_urls=ol_mmr_urls,
+ slapd_path=slapd_path,
+ setup_ds_path=setup_ds_path,
+ ldap_dryrun_mode=ldap_dryrun_mode,
+ domainsid=domainsid)
# only install a new shares config db if there is none
if not os.path.exists(paths.shareconf):
message("Setting up share.ldb")
share_ldb = Ldb(paths.shareconf, session_info=session_info,
- credentials=credentials, lp=lp)
+ 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,
- credentials=secrets_credentials, lp=lp)
+ backend_credentials=provision_backend.secrets_credentials, lp=lp)
message("Setting up the registry")
setup_registry(paths.hklm, setup_path, session_info,
@@ -1370,9 +1364,9 @@ def provision(setup_dir, message, session_info,
lp=lp)
message("Setting up SAM db")
- samdb = setup_samdb(paths.samdb, setup_path, session_info=session_info,
- credentials=credentials, lp=lp, names=names,
- message=message,
+ samdb = setup_samdb(paths.samdb, setup_path, session_info,
+ provision_backend, lp, names,
+ message,
domainsid=domainsid,
schema=schema, domainguid=domainguid,
policyguid=policyguid, policyguid_dc=policyguid_dc,
@@ -1381,8 +1375,7 @@ def provision(setup_dir, message, session_info,
invocationid=invocationid,
machinepass=machinepass, dnspass=dnspass,
ntdsguid=ntdsguid, serverrole=serverrole,
- dom_for_fun_level=dom_for_fun_level,
- ldap_backend=provision_backend)
+ dom_for_fun_level=dom_for_fun_level)
if serverrole == "domain controller":
if paths.netlogon is None:
@@ -1464,61 +1457,18 @@ def provision(setup_dir, message, session_info,
realm=names.realm)
message("A Kerberos configuration suitable for Samba 4 has been generated at %s" % paths.krb5conf)
- #Now commit the secrets.ldb to disk
- secrets_ldb.transaction_commit()
-
- if provision_backend is not None:
- if ldap_backend_type == "fedora-ds":
- ldapi_db = Ldb(provision_backend.ldapi_uri, lp=lp, credentials=credentials)
-
- # delete default SASL mappings
- res = ldapi_db.search(expression="(!(cn=samba-admin mapping))", base="cn=mapping,cn=sasl,cn=config", scope=SCOPE_ONELEVEL, attrs=["dn"])
-
- # configure in-directory access control on Fedora DS via the aci attribute (over a direct ldapi:// socket)
- for i in range (0, len(res)):
- dn = str(res[i]["dn"])
- ldapi_db.delete(dn)
-
- aci = """(targetattr = "*") (version 3.0;acl "full access to all by samba-admin";allow (all)(userdn = "ldap:///CN=samba-admin,%s");)""" % names.sambadn
-
- m = ldb.Message()
- m["aci"] = ldb.MessageElement([aci], ldb.FLAG_MOD_REPLACE, "aci")
-
- m.dn = ldb.Dn(1, names.domaindn)
- ldapi_db.modify(m)
-
- m.dn = ldb.Dn(1, names.configdn)
- ldapi_db.modify(m)
-
- m.dn = ldb.Dn(1, names.schemadn)
- ldapi_db.modify(m)
-
- # if an LDAP backend is in use, terminate slapd after final provision and check its proper termination
- if provision_backend.slapd.poll() is None:
- #Kill the slapd
- if hasattr(provision_backend.slapd, "terminate"):
- provision_backend.slapd.terminate()
- else:
- # Older python versions don't have .terminate()
- import signal
- os.kill(provision_backend.slapd.pid, signal.SIGTERM)
-
- #and now wait for it to die
- provision_backend.slapd.communicate()
-
- # now display slapd_command_file.txt to show how slapd must be started next time
- message("Use later the following commandline to start slapd, then Samba:")
- slapd_command = "\'" + "\' \'".join(provision_backend.slapd_command) + "\'"
- message(slapd_command)
- message("This slapd-Commandline is also stored under: " + paths.ldapdir + "/ldap_backend_startup.sh")
-
- setup_file(setup_path("ldap_backend_startup.sh"), paths.ldapdir + "/ldap_backend_startup.sh", {
- "SLAPD_COMMAND" : slapd_command})
+ if provision_backend.post_setup is not None:
+ provision_backend.post_setup()
+ if provision_backend.shutdown is not None:
+ provision_backend.shutdown()
create_phpldapadmin_config(paths.phpldapadminconfig, setup_path,
ldapi_url)
+ #Now commit the secrets.ldb to disk
+ secrets_ldb.transaction_commit()
+
message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig)
message("Once the above files are installed, your Samba4 server will be ready to use")
@@ -1529,14 +1479,21 @@ def provision(setup_dir, message, session_info,
message("DOMAIN SID: %s" % str(domainsid))
if samdb_fill == FILL_FULL:
message("Admin password: %s" % adminpass)
- if provision_backend:
+ if provision_backend.type is not "ldb":
if provision_backend.credentials.get_bind_dn() is not None:
message("LDAP Backend Admin DN: %s" % provision_backend.credentials.get_bind_dn())
else:
message("LDAP Admin User: %s" % provision_backend.credentials.get_username())
message("LDAP Admin Password: %s" % provision_backend.credentials.get_password())
-
+
+ if provision_backend.slapd_command_escaped is not None:
+ # now display slapd_command_file.txt to show how slapd must be started next time
+ message("Use later the following commandline to start slapd, then Samba:")
+ message(provision_backend.slapd_command_escaped)
+ message("This slapd-Commandline is also stored under: " + paths.ldapdir + "/ldap_backend_startup.sh")
+
+
result = ProvisionResult()
result.domaindn = domaindn
result.paths = paths
@@ -1586,13 +1543,28 @@ def setup_db_config(setup_path, dbdir):
setup_file(setup_path("DB_CONFIG"), os.path.join(dbdir, "DB_CONFIG"),
{"LDAPDBDIR": dbdir})
-
+
+def ldap_backend_shutdown(self):
+ # if an LDAP backend is in use, terminate slapd after final provision and check its proper termination
+ if self.slapd.poll() is None:
+ #Kill the slapd
+ if hasattr(self.slapd, "terminate"):
+ self.slapd.terminate()
+ else:
+ # Older python versions don't have .terminate()
+ import signal
+ os.kill(self.slapd.pid, signal.SIGTERM)
+
+ #and now wait for it to die
+ self.slapd.communicate()
+
+
class ProvisionBackend(object):
- def __init__(self, paths=None, setup_path=None, lp=None, credentials=None,
+ def __init__(self, backend_type, paths=None, setup_path=None, lp=None, credentials=None,
names=None, message=None,
hostname=None, root=None,
schema=None, ldapadminpass=None,
- ldap_backend_type=None, ldap_backend_extra_port=None,
+ ldap_backend_extra_port=None,
ol_mmr_urls=None,
setup_ds_path=None, slapd_path=None,
nosync=False, ldap_dryrun_mode=False,
@@ -1601,21 +1573,36 @@ class ProvisionBackend(object):
This works for OpenLDAP and Fedora DS
"""
+ self.paths = paths
+ self.slapd_command = None
+ self.slapd_command_escaped = None
+
+ self.type = backend_type
+
+ # Set a default - the code for "existing" below replaces this
+ self.ldap_backend_type = backend_type
+
+ self.post_setup = None
+ self.shutdown = None
+
+ if self.type is "ldb":
+ self.credentials = None
+ self.secrets_credentials = None
+ return
self.ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.ldapdir, "ldapi"), safe="")
- if not os.path.isdir(paths.ldapdir):
- os.makedirs(paths.ldapdir, 0700)
-
- if ldap_backend_type == "existing":
+ if self.type == "existing":
#Check to see that this 'existing' LDAP backend in fact exists
ldapi_db = Ldb(self.ldapi_uri, credentials=credentials)
search_ol_rootdse = ldapi_db.search(base="", scope=SCOPE_BASE,
expression="(objectClass=OpenLDAProotDSE)")
# If we have got here, then we must have a valid connection to the LDAP server, with valid credentials supplied
- # This caused them to be set into the long-term database later in the script.
self.credentials = credentials
+ # This caused them to be set into the long-term database later in the script.
+ self.secrets_credentials = credentials
+
self.ldap_backend_type = "openldap" #For now, assume existing backends at least emulate OpenLDAP
return
@@ -1645,13 +1632,16 @@ class ProvisionBackend(object):
message (slapd_path)
raise ProvisioningError("Warning: Given Path to slapd does not exist!")
+
+ if not os.path.isdir(paths.ldapdir):
+ os.makedirs(paths.ldapdir, 0700)
+
schemadb_path = os.path.join(paths.ldapdir, "schema-tmp.ldb")
try:
os.unlink(schemadb_path)
except OSError:
pass
-
# Put the LDIF of the schema into a database so we can search on
# it to generate schema-dependent configurations in Fedora DS and
# OpenLDAP
@@ -1670,15 +1660,15 @@ class ProvisionBackend(object):
#Kerberos to an ldapi:// backend makes no sense
self.credentials.set_kerberos_state(DONT_USE_KERBEROS)
- self.adminCredentials = Credentials()
- self.adminCredentials.guess(lp)
+ self.secrets_credentials = Credentials()
+ self.secrets_credentials.guess(lp)
#Kerberos to an ldapi:// backend makes no sense
- self.adminCredentials.set_kerberos_state(DONT_USE_KERBEROS)
+ self.secrets_credentials.set_kerberos_state(DONT_USE_KERBEROS)
- self.ldap_backend_type = ldap_backend_type
+ self.shutdown = ldap_backend_shutdown
- if ldap_backend_type == "fedora-ds":
- provision_fds_backend(self, paths=paths, setup_path=setup_path,
+ if self.type == "fedora-ds":
+ provision_fds_backend(self, setup_path=setup_path,
names=names, message=message,
hostname=hostname,
ldapadminpass=ldapadminpass, root=root,
@@ -1690,8 +1680,8 @@ class ProvisionBackend(object):
ldap_dryrun_mode=ldap_dryrun_mode,
domainsid=domainsid)
- elif ldap_backend_type == "openldap":
- provision_openldap_backend(self, paths=paths, setup_path=setup_path,
+ elif self.type == "openldap":
+ provision_openldap_backend(self, setup_path=setup_path,
names=names, message=message,
hostname=hostname,
ldapadminpass=ldapadminpass, root=root,
@@ -1705,8 +1695,12 @@ class ProvisionBackend(object):
raise ProvisioningError("Unknown LDAP backend type selected")
self.credentials.set_password(ldapadminpass)
- self.adminCredentials.set_username("samba-admin")
- self.adminCredentials.set_password(ldapadminpass)
+ self.secrets_credentials.set_username("samba-admin")
+ self.secrets_credentials.set_password(ldapadminpass)
+
+ self.slapd_command_escaped = "\'" + "\' \'".join(self.slapd_command) + "\'"
+ setup_file(setup_path("ldap_backend_startup.sh"), paths.ldapdir + "/ldap_backend_startup.sh", {
+ "SLAPD_COMMAND" : slapd_command})
# Now start the slapd, so we can provision onto it. We keep the
# subprocess context around, to kill this off at the successful
@@ -1728,7 +1722,7 @@ class ProvisionBackend(object):
raise ProvisioningError("slapd died before we could make a connection to it")
-def provision_openldap_backend(result, paths=None, setup_path=None, names=None,
+def provision_openldap_backend(result, setup_path=None, names=None,
message=None,
hostname=None, ldapadminpass=None, root=None,
schema=None,
@@ -1840,15 +1834,15 @@ def provision_openldap_backend(result, paths=None, setup_path=None, names=None,
{ "RID" : str(rid),
"LDAPSERVER" : url})
- setup_file(setup_path("olc_seed.ldif"), paths.olcseedldif,
+ setup_file(setup_path("olc_seed.ldif"), result.paths.olcseedldif,
{"OLC_SERVER_ID_CONF": olc_serverids_config,
"OLC_PW": ldapadminpass,
"OLC_SYNCREPL_CONF": olc_syncrepl_seed_config})
# end olc
- setup_file(setup_path("slapd.conf"), paths.slapdconf,
+ setup_file(setup_path("slapd.conf"), result.paths.slapdconf,
{"DNSDOMAIN": names.dnsdomain,
- "LDAPDIR": paths.ldapdir,
+ "LDAPDIR": result.paths.ldapdir,
"DOMAINDN": names.domaindn,
"CONFIGDN": names.configdn,
"SCHEMADN": names.schemadn,
@@ -1865,26 +1859,26 @@ def provision_openldap_backend(result, paths=None, setup_path=None, names=None,
"INDEX_CONFIG": index_config,
"NOSYNC": nosync_config})
- setup_db_config(setup_path, os.path.join(paths.ldapdir, "db", "user"))
- setup_db_config(setup_path, os.path.join(paths.ldapdir, "db", "config"))
- setup_db_config(setup_path, os.path.join(paths.ldapdir, "db", "schema"))
+ setup_db_config(setup_path, os.path.join(result.paths.ldapdir, "db", "user"))
+ setup_db_config(setup_path, os.path.join(result.paths.ldapdir, "db", "config"))
+ setup_db_config(setup_path, os.path.join(result.paths.ldapdir, "db", "schema"))
- if not os.path.exists(os.path.join(paths.ldapdir, "db", "samba", "cn=samba")):
- os.makedirs(os.path.join(paths.ldapdir, "db", "samba", "cn=samba"), 0700)
+ if not os.path.exists(os.path.join(result.paths.ldapdir, "db", "samba", "cn=samba")):
+ os.makedirs(os.path.join(result.paths.ldapdir, "db", "samba", "cn=samba"), 0700)
setup_file(setup_path("cn=samba.ldif"),
- os.path.join(paths.ldapdir, "db", "samba", "cn=samba.ldif"),
+ os.path.join(result.paths.ldapdir, "db", "samba", "cn=samba.ldif"),
{ "UUID": str(uuid.uuid4()),
"LDAPTIME": timestring(int(time.time()))} )
setup_file(setup_path("cn=samba-admin.ldif"),
- os.path.join(paths.ldapdir, "db", "samba", "cn=samba", "cn=samba-admin.ldif"),
+ os.path.join(result.paths.ldapdir, "db", "samba", "cn=samba", "cn=samba-admin.ldif"),
{"LDAPADMINPASS_B64": b64encode(ldapadminpass),
"UUID": str(uuid.uuid4()),
"LDAPTIME": timestring(int(time.time()))} )
if ol_mmr_urls is not None:
setup_file(setup_path("cn=replicator.ldif"),
- os.path.join(paths.ldapdir, "db", "samba", "cn=samba", "cn=replicator.ldif"),
+ os.path.join(result.paths.ldapdir, "db", "samba", "cn=samba", "cn=replicator.ldif"),
{"MMR_PASSWORD_B64": b64encode(mmr_pass),
"UUID": str(uuid.uuid4()),
"LDAPTIME": timestring(int(time.time()))} )
@@ -1895,7 +1889,7 @@ def provision_openldap_backend(result, paths=None, setup_path=None, names=None,
backend_schema_data = schema.ldb.convert_schema_to_openldap("openldap", open(setup_path(mapping), 'r').read())
assert backend_schema_data is not None
- open(os.path.join(paths.ldapdir, backend_schema), 'w').write(backend_schema_data)
+ open(os.path.join(result.paths.ldapdir, backend_schema), 'w').write(backend_schema_data)
# now we generate the needed strings to start slapd automatically,
# first ldapi_uri...
@@ -1913,7 +1907,7 @@ def provision_openldap_backend(result, paths=None, setup_path=None, names=None,
# Prepare the 'result' information - the commands to return in particular
result.slapd_provision_command = [slapd_path]
- result.slapd_provision_command.append("-F" + paths.olcdir)
+ result.slapd_provision_command.append("-F" + result.paths.olcdir)
result.slapd_provision_command.append("-h")
@@ -1939,10 +1933,10 @@ def provision_openldap_backend(result, paths=None, setup_path=None, names=None,
sys.exit(0)
# Finally, convert the configuration into cn=config style!
- if not os.path.isdir(paths.olcdir):
- os.makedirs(paths.olcdir, 0770)
+ if not os.path.isdir(result.paths.olcdir):
+ os.makedirs(result.paths.olcdir, 0770)
- retcode = subprocess.call([slapd_path, "-Ttest", "-f", paths.slapdconf, "-F", paths.olcdir], close_fds=True, shell=False)
+ retcode = subprocess.call([slapd_path, "-Ttest", "-f", result.paths.slapdconf, "-F", result.paths.olcdir], close_fds=True, shell=False)
# We can't do this, as OpenLDAP is strange. It gives an error
# output to the above, but does the conversion sucessfully...
@@ -1950,14 +1944,14 @@ def provision_openldap_backend(result, paths=None, setup_path=None, names=None,
# if retcode != 0:
# raise ProvisioningError("conversion from slapd.conf to cn=config failed")
- if not os.path.exists(os.path.join(paths.olcdir, "cn=config.ldif")):
+ if not os.path.exists(os.path.join(result.paths.olcdir, "cn=config.ldif")):
raise ProvisioningError("conversion from slapd.conf to cn=config failed")
# Don't confuse the admin by leaving the slapd.conf around
- os.remove(paths.slapdconf)
-
+ os.remove(result.paths.slapdconf)
+
-def provision_fds_backend(result, paths=None, setup_path=None, names=None,
+def provision_fds_backend(result, setup_path=None, names=None,
message=None,
hostname=None, ldapadminpass=None, root=None,
schema=None,
@@ -1973,33 +1967,33 @@ def provision_fds_backend(result, paths=None, setup_path=None, names=None,
else:
serverport = ""
- setup_file(setup_path("fedorads.inf"), paths.fedoradsinf,
+ setup_file(setup_path("fedorads.inf"), result.paths.fedoradsinf,
{"ROOT": root,
"HOSTNAME": hostname,
"DNSDOMAIN": names.dnsdomain,
- "LDAPDIR": paths.ldapdir,
+ "LDAPDIR": result.paths.ldapdir,
"DOMAINDN": names.domaindn,
"LDAPMANAGERDN": names.ldapmanagerdn,
"LDAPMANAGERPASS": ldapadminpass,
"SERVERPORT": serverport})
- setup_file(setup_path("fedorads-partitions.ldif"), paths.fedoradspartitions,
+ setup_file(setup_path("fedorads-partitions.ldif"), result.paths.fedoradspartitions,
{"CONFIGDN": names.configdn,
"SCHEMADN": names.schemadn,
"SAMBADN": names.sambadn,
})
- setup_file(setup_path("fedorads-sasl.ldif"), paths.fedoradssasl,
+ setup_file(setup_path("fedorads-sasl.ldif"), result.paths.fedoradssasl,
{"SAMBADN": names.sambadn,
})
- setup_file(setup_path("fedorads-dna.ldif"), paths.fedoradsdna,
+ setup_file(setup_path("fedorads-dna.ldif"), result.paths.fedoradsdna,
{"DOMAINDN": names.domaindn,
"SAMBADN": names.sambadn,
"DOMAINSID": str(domainsid),
})
- setup_file(setup_path("fedorads-pam.ldif"), paths.fedoradspam)
+ setup_file(setup_path("fedorads-pam.ldif"), result.paths.fedoradspam)
lnkattr = get_linked_attributes(names.schemadn,schema.ldb)
@@ -2020,8 +2014,8 @@ def provision_fds_backend(result, paths=None, setup_path=None, names=None,
{ "ATTR" : attr })
argnum += 1
- open(paths.fedoradsrefint, 'w').write(refint_config)
- open(paths.fedoradslinkedattributes, 'w').write(memberof_config)
+ open(result.paths.fedoradsrefint, 'w').write(refint_config)
+ open(result.paths.fedoradslinkedattributes, 'w').write(memberof_config)
attrs = ["lDAPDisplayName"]
res = schema.ldb.search(expression="(&(objectclass=attributeSchema)(searchFlags:1.2.840.113556.1.4.803:=1))", base=names.schemadn, scope=SCOPE_ONELEVEL, attrs=attrs)
@@ -2035,9 +2029,9 @@ def provision_fds_backend(result, paths=None, setup_path=None, names=None,
index_config += read_and_sub_file(setup_path("fedorads-index.ldif"),
{ "ATTR" : attr })
- open(paths.fedoradsindex, 'w').write(index_config)
+ open(result.paths.fedoradsindex, 'w').write(index_config)
- setup_file(setup_path("fedorads-samba.ldif"), paths.fedoradssamba,
+ setup_file(setup_path("fedorads-samba.ldif"), result.paths.fedoradssamba,
{"SAMBADN": names.sambadn,
"LDAPADMINPASS": ldapadminpass
})
@@ -2048,20 +2042,20 @@ def provision_fds_backend(result, paths=None, setup_path=None, names=None,
# Build a schema file in Fedora DS format
backend_schema_data = schema.ldb.convert_schema_to_openldap("fedora-ds", open(setup_path(mapping), 'r').read())
assert backend_schema_data is not None
- open(os.path.join(paths.ldapdir, backend_schema), 'w').write(backend_schema_data)
+ open(os.path.join(result.paths.ldapdir, backend_schema), 'w').write(backend_schema_data)
result.credentials.set_bind_dn(names.ldapmanagerdn)
# Destory the target directory, or else setup-ds.pl will complain
- fedora_ds_dir = os.path.join(paths.ldapdir, "slapd-samba4")
+ fedora_ds_dir = os.path.join(result.paths.ldapdir, "slapd-samba4")
shutil.rmtree(fedora_ds_dir, True)
- result.slapd_provision_command = [slapd_path, "-D", fedora_ds_dir, "-i", paths.slapdpid];
+ result.slapd_provision_command = [slapd_path, "-D", fedora_ds_dir, "-i", result.paths.slapdpid];
#In the 'provision' command line, stay in the foreground so we can easily kill it
result.slapd_provision_command.append("-d0")
#the command for the final run is the normal script
- result.slapd_command = [os.path.join(paths.ldapdir, "slapd-samba4", "start-slapd")]
+ result.slapd_command = [os.path.join(result.paths.ldapdir, "slapd-samba4", "start-slapd")]
# If we were just looking for crashes up to this point, it's a
# good time to exit before we realise we don't have Fedora DS on
@@ -2076,17 +2070,46 @@ def provision_fds_backend(result, paths=None, setup_path=None, names=None,
raise ProvisioningError("Warning: Given Path to slapd does not exist!")
# Run the Fedora DS setup utility
- retcode = subprocess.call([setup_ds_path, "--silent", "--file", paths.fedoradsinf], close_fds=True, shell=False)
+ retcode = subprocess.call([setup_ds_path, "--silent", "--file", result.paths.fedoradsinf], close_fds=True, shell=False)
if retcode != 0:
raise ProvisioningError("setup-ds failed")
# Load samba-admin
retcode = subprocess.call([
- os.path.join(paths.ldapdir, "slapd-samba4", "ldif2db"), "-s", names.sambadn, "-i", paths.fedoradssamba],
+ os.path.join(result.paths.ldapdir, "slapd-samba4", "ldif2db"), "-s", names.sambadn, "-i", result.paths.fedoradssamba],
close_fds=True, shell=False)
if retcode != 0:
raise("ldib2db failed")
+ # Leave a hook to do the 'post initilisation' setup
+ def fds_post_setup(self):
+ ldapi_db = Ldb(self.ldapi_uri, credentials=self.credentials)
+
+ # delete default SASL mappings
+ res = ldapi_db.search(expression="(!(cn=samba-admin mapping))", base="cn=mapping,cn=sasl,cn=config", scope=SCOPE_ONELEVEL, attrs=["dn"])
+
+ # configure in-directory access control on Fedora DS via the aci attribute (over a direct ldapi:// socket)
+ for i in range (0, len(res)):
+ dn = str(res[i]["dn"])
+ ldapi_db.delete(dn)
+
+ aci = """(targetattr = "*") (version 3.0;acl "full access to all by samba-admin";allow (all)(userdn = "ldap:///CN=samba-admin,%s");)""" % names.sambadn
+
+ m = ldb.Message()
+ m["aci"] = ldb.MessageElement([aci], ldb.FLAG_MOD_REPLACE, "aci")
+
+ m.dn = ldb.Dn(1, names.domaindn)
+ ldapi_db.modify(m)
+
+ m.dn = ldb.Dn(1, names.configdn)
+ ldapi_db.modify(m)
+
+ m.dn = ldb.Dn(1, names.schemadn)
+ ldapi_db.modify(m)
+
+ result.post_setup = fds_post_setup
+
+
def create_phpldapadmin_config(path, setup_path, ldapi_uri):
"""Create a PHP LDAP admin configuration file.