[PATCH 7/7] s4:provision - Added support for external LDAP server.
Endi S. Dewata
edewata at redhat.com
Sat Jan 30 06:09:27 MST 2010
---
source4/scripting/python/samba/provision.py | 91 ++++++------
source4/scripting/python/samba/provisionbackend.py | 154 ++++++++++++--------
source4/setup/fedorads-dna-modify.ldif | 14 ++
source4/setup/provision | 5 +-
source4/setup/slapd.conf | 4 +
5 files changed, 166 insertions(+), 102 deletions(-)
create mode 100644 source4/setup/fedorads-dna-modify.ldif
diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py
index 2d7978d..c4a790f 100644
--- a/source4/scripting/python/samba/provision.py
+++ b/source4/scripting/python/samba/provision.py
@@ -50,7 +50,7 @@ from samba.ndr import ndr_pack,ndr_unpack
from samba.schema import Schema
from ms_display_specifiers import read_ms_ldif
from samba.provisionutil import setup_add_ldif, setup_modify_ldif
-from samba.provisionbackend import LDBBackend, ExistingBackend, FDSBackend, OpenLDAPBackend
+from samba.provisionbackend import LDBBackend, FDSBackend, OpenLDAPBackend
from provisionexceptions import ProvisioningError, InvalidNetbiosName
__docformat__ = "restructuredText"
@@ -1060,7 +1060,8 @@ 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, backend_type=None, ldap_dir=None, ldap_uri=None,
+ ldap_backend_extra_port=None, backend_type=None,
+ ldap_action=None, ldap_dir=None, ldap_uri=None,
sitename=None,
ol_mmr_urls=None, ol_olc=None,
setup_ds_path=None, slapd_path=None, nosync=False,
@@ -1163,13 +1164,6 @@ def provision(setup_dir, message, session_info,
lp=lp, credentials=credentials,
names=names,
message=message)
- elif backend_type == "existing":
- provision_backend = ExistingBackend(backend_type,
- paths=paths, setup_path=setup_path,
- lp=lp, credentials=credentials,
- names=names,
- message=message,
- ldapi_url=ldapi_url)
elif backend_type == "fedora-ds":
provision_backend = FDSBackend(backend_type,
paths=paths, setup_path=setup_path,
@@ -1207,43 +1201,56 @@ def provision(setup_dir, message, session_info,
else:
raise ProvisioningError("Unknown LDAP backend type selected")
- provision_backend.init()
- provision_backend.start()
-
- provision_samba(result=result, paths=paths, message=message,
- session_info=session_info, lp=lp, names=names, setup_path=setup_path,
- provision_backend=provision_backend,
- domainsid=domainsid, schema=schema, domainguid=domainguid,
- policyguid=policyguid, policyguid_dc=policyguid_dc,
- samdb_fill=samdb_fill,
- adminpass=adminpass, krbtgtpass=krbtgtpass,
- invocationid=invocationid,
- machinepass=machinepass, dnspass=dnspass,
- ntdsguid=ntdsguid, serverrole=serverrole,
- dom_for_fun_level=dom_for_fun_level,
- root=root, nobody=nobody, users=users, wheel=wheel,
- domaindn=domaindn, hostip=hostip, hostip6=hostip6)
-
- provision_backend.post_setup()
- provision_backend.shutdown()
-
- create_phpldapadmin_config(paths.phpldapadminconfig, setup_path,
+ if ldap_action is None or ldap_action == "create":
+ provision_backend.create()
+
+ if ldap_action is None:
+ provision_backend.start()
+
+ if ldap_action == "setup":
+ provision_backend.reset()
+
+ if ldap_action is None or ldap_action == "setup":
+ provision_samba(result=result, paths=paths, message=message,
+ session_info=session_info, lp=lp, names=names, setup_path=setup_path,
+ provision_backend=provision_backend,
+ domainsid=domainsid, schema=schema, domainguid=domainguid,
+ policyguid=policyguid, policyguid_dc=policyguid_dc,
+ samdb_fill=samdb_fill,
+ adminpass=adminpass, krbtgtpass=krbtgtpass,
+ invocationid=invocationid,
+ machinepass=machinepass, dnspass=dnspass,
+ ntdsguid=ntdsguid, serverrole=serverrole,
+ dom_for_fun_level=dom_for_fun_level,
+ root=root, nobody=nobody, users=users, wheel=wheel,
+ domaindn=domaindn, hostip=hostip, hostip6=hostip6)
+
+ provision_backend.post_setup()
+
+ if ldap_action is None:
+ provision_backend.shutdown()
+
+ if ldap_action == "create":
+ message("An empty LDAP server has been created in %s" % provision_backend.ldapdir)
+ message("Please provision Samba using LDAP URI %s" % provision_backend.ldap_uri)
+ else:
+ create_phpldapadmin_config(paths.phpldapadminconfig, setup_path,
ldapi_url)
- #Now commit the secrets.ldb to disk
- result.secrets_ldb.transaction_commit()
+ #Now commit the secrets.ldb to disk
+ result.secrets_ldb.transaction_commit()
- message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig)
+ 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")
- message("Server Role: %s" % serverrole)
- message("Hostname: %s" % names.hostname)
- message("NetBIOS Domain: %s" % names.domain)
- message("DNS Domain: %s" % names.dnsdomain)
- message("DOMAIN SID: %s" % str(domainsid))
+ message("Once the above files are installed, your Samba4 server will be ready to use")
+ message("Server Role: %s" % serverrole)
+ message("Hostname: %s" % names.hostname)
+ message("NetBIOS Domain: %s" % names.domain)
+ message("DNS Domain: %s" % names.dnsdomain)
+ message("DOMAIN SID: %s" % str(domainsid))
- if samdb_fill == FILL_FULL:
- message("Admin password: %s" % adminpass)
+ if samdb_fill == FILL_FULL:
+ message("Admin password: %s" % adminpass)
if provision_backend.type is not "ldb":
if provision_backend.credentials.get_bind_dn() is not None:
@@ -1253,7 +1260,7 @@ def provision(setup_dir, message, session_info,
message("LDAP Admin Password: %s" % provision_backend.credentials.get_password())
- if provision_backend.slapd_command_escaped is not None:
+ if (ldap_action is None or ldap_action == "create") and 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)
diff --git a/source4/scripting/python/samba/provisionbackend.py b/source4/scripting/python/samba/provisionbackend.py
index db9436d..22b1eed 100644
--- a/source4/scripting/python/samba/provisionbackend.py
+++ b/source4/scripting/python/samba/provisionbackend.py
@@ -40,6 +40,7 @@ from ldb import SCOPE_BASE, SCOPE_ONELEVEL, LdbError, timestring
from samba import Ldb, read_and_sub_file, setup_file
from samba.credentials import Credentials, DONT_USE_KERBEROS
from samba.schema import Schema
+from samba.provisionutil import setup_add_ldif, setup_modify_ldif
from samba.provisionexceptions import ProvisioningError
class ProvisionBackend(object):
@@ -58,7 +59,7 @@ class ProvisionBackend(object):
# Set a default - the code for "existing" below replaces this
self.ldap_backend_type = backend_type
- def init(self):
+ def create(self):
pass
def start(self):
@@ -67,6 +68,9 @@ class ProvisionBackend(object):
def shutdown(self):
pass
+ def reset(self):
+ pass
+
def post_setup(self):
pass
@@ -82,7 +86,7 @@ class LDBBackend(ProvisionBackend):
names=names,
message=message)
- def init(self):
+ def create(self):
self.credentials = None
self.secrets_credentials = None
@@ -90,33 +94,6 @@ class LDBBackend(ProvisionBackend):
shutil.rmtree(self.paths.samdb + ".d", True)
-class ExistingBackend(ProvisionBackend):
- def __init__(self, backend_type, paths=None, setup_path=None, lp=None, credentials=None,
- names=None, message=None,
- ldap_uri=None):
-
- super(ExistingBackend, self).__init__(
- backend_type=backend_type,
- paths=paths, setup_path=setup_path,
- lp=lp, credentials=credentials,
- names=names,
- message=message)
-
- self.ldap_uri = ldap_uri
-
- def init(self):
- #Check to see that this 'existing' LDAP backend in fact exists
- ldapi_db = Ldb(self.ldap_uri, credentials=self.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.secrets_credentials = self.credentials
-
- self.ldap_backend_type = "openldap" #For now, assume existing backends at least emulate OpenLDAP
-
-
class LDAPBackend(ProvisionBackend):
def __init__(self, backend_type, paths=None, setup_path=None, lp=None, credentials=None,
names=None, message=None,
@@ -164,13 +141,27 @@ class LDAPBackend(ProvisionBackend):
self.ldap_backend_extra_port = ldap_backend_extra_port
self.ldap_dryrun_mode = ldap_dryrun_mode
- def init(self):
+ # Credentials for provisioning
+ self.credentials = Credentials()
+ self.credentials.guess(self.lp)
+ #Kerberos to an ldapi:// backend makes no sense
+ self.credentials.set_kerberos_state(DONT_USE_KERBEROS)
+ self.credentials.set_password(self.ldapadminpass)
+
+ # Credentials for Samba
+ self.secrets_credentials = Credentials()
+ self.secrets_credentials.guess(self.lp)
+ #Kerberos to an ldapi:// backend makes no sense
+ self.secrets_credentials.set_kerberos_state(DONT_USE_KERBEROS)
+ self.secrets_credentials.set_username("samba-admin")
+ self.secrets_credentials.set_password(self.ldapadminpass)
+
+ def create(self):
# we will shortly start slapd with ldapi for final provisioning. first check with ldapsearch -> rootDSE via self.ldap_uri
# if another instance of slapd is already running
try:
ldapi_db = Ldb(self.ldap_uri)
- search_ol_rootdse = ldapi_db.search(base="", scope=SCOPE_BASE,
- expression="(objectClass=OpenLDAProotDSE)");
+ search_rootdse = ldapi_db.search(base="", scope=SCOPE_BASE)
try:
f = open(self.slapd_pid, "r")
p = f.read()
@@ -206,24 +197,6 @@ class LDAPBackend(ProvisionBackend):
self.schema.write_to_tmp_ldb(schemadb_path);
- self.credentials = Credentials()
- self.credentials.guess(self.lp)
- #Kerberos to an ldapi:// backend makes no sense
- self.credentials.set_kerberos_state(DONT_USE_KERBEROS)
- self.credentials.set_password(self.ldapadminpass)
-
- self.secrets_credentials = Credentials()
- self.secrets_credentials.guess(self.lp)
- #Kerberos to an ldapi:// backend makes no sense
- self.secrets_credentials.set_kerberos_state(DONT_USE_KERBEROS)
- self.secrets_credentials.set_username("samba-admin")
- self.secrets_credentials.set_password(self.ldapadminpass)
-
- self.provision()
-
- def provision(self):
- pass
-
def start(self):
self.slapd_command_escaped = "\'" + "\' \'".join(self.slapd_command) + "\'"
open(self.ldapdir + "/ldap_backend_startup.sh", 'w').write("#!/bin/sh\n" + self.slapd_command_escaped + "\n")
@@ -237,8 +210,7 @@ class LDAPBackend(ProvisionBackend):
# Wait until the socket appears
try:
ldapi_db = Ldb(self.ldap_uri, lp=self.lp, credentials=self.credentials)
- search_ol_rootdse = ldapi_db.search(base="", scope=SCOPE_BASE,
- expression="(objectClass=OpenLDAProotDSE)")
+ search_rootdse = ldapi_db.search(base="", scope=SCOPE_BASE)
# If we have got here, then we must have a valid connection to the LDAP server!
return
except LdbError, e:
@@ -261,6 +233,25 @@ class LDAPBackend(ProvisionBackend):
#and now wait for it to die
self.slapd.communicate()
+ def delete(self, ldap_db, dn):
+
+ self.deleteChildren(ldap_db, dn)
+
+ try:
+ ldap_db.delete(dn)
+ except ldb.LdbError, (ldb.ERR_NO_SUCH_OBJECT, _):
+ pass
+
+ def deleteChildren(self, ldap_db, dn):
+
+ try:
+ res = ldap_db.search(base=dn, scope=ldb.SCOPE_ONELEVEL, attrs=[])
+ except ldb.LdbError, (ldb.ERR_NO_SUCH_OBJECT, _):
+ return
+
+ for msg in res:
+ self.delete(ldap_db, msg.dn)
+
class OpenLDAPBackend(LDAPBackend):
def __init__(self, backend_type, paths=None, setup_path=None, lp=None, credentials=None,
@@ -311,6 +302,8 @@ class OpenLDAPBackend(LDAPBackend):
serverdn=self.names.serverdn,
files=[setup_path("schema_samba4.ldif")]);
+ self.credentials.set_username("samba-admin")
+
def setup_db_config(self, dbdir):
"""Setup a Berkeley database.
@@ -324,7 +317,11 @@ class OpenLDAPBackend(LDAPBackend):
setup_file(self.setup_path("DB_CONFIG"), os.path.join(dbdir, "DB_CONFIG"),
{"LDAPDBDIR": dbdir})
- def provision(self):
+ def create(self):
+
+ super(OpenLDAPBackend, self).create()
+
+
# Wipe the directories so we can start
shutil.rmtree(os.path.join(self.ldapdir, "db"), True)
@@ -440,6 +437,7 @@ class OpenLDAPBackend(LDAPBackend):
setup_file(self.setup_path("slapd.conf"), self.slapdconf,
{"DNSDOMAIN": self.names.dnsdomain,
"LDAPDIR": self.ldapdir,
+ "LDAPADMINPASS": self.ldapadminpass,
"DOMAINDN": self.names.domaindn,
"CONFIGDN": self.names.configdn,
"SCHEMADN": self.names.schemadn,
@@ -520,9 +518,6 @@ class OpenLDAPBackend(LDAPBackend):
self.slapd_command.append(uris)
- # Set the username - done here because Fedora DS still uses the admin DN and simple bind
- self.credentials.set_username("samba-admin")
-
# 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 OpenLDAP on
# this system
@@ -547,6 +542,22 @@ class OpenLDAPBackend(LDAPBackend):
# Don't confuse the admin by leaving the slapd.conf around
os.remove(self.slapdconf)
+ def reset(self):
+
+ # Delete each partition as partition's Manager
+ for basedn in [self.names.schemadn, self.names.configdn, self.names.domaindn]:
+
+ self.message("Erasing " + basedn)
+
+ credentials = Credentials()
+ credentials.set_kerberos_state(DONT_USE_KERBEROS)
+ credentials.set_bind_dn("CN=Manager," + basedn)
+ credentials.set_password(self.ldapadminpass)
+
+ ldap_db = Ldb(self.ldap_uri, lp=self.lp, credentials=credentials)
+
+ self.delete(ldap_db, basedn)
+
class FDSBackend(LDAPBackend):
def __init__(self, backend_type, paths=None, setup_path=None, lp=None, credentials=None,
@@ -584,6 +595,8 @@ class FDSBackend(LDAPBackend):
self.ldap_instance = self.names.netbiosname.lower()
self.sambadn = "CN=Samba"
+ self.dnadn = "cn=Samba SIDs,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config"
+ self.rangesdn = "cn=Samba SIDs,ou=Ranges," + self.sambadn
self.fedoradsinf = os.path.join(self.ldapdir, "fedorads.inf")
self.partitions_ldif = os.path.join(self.ldapdir, "fedorads-partitions.ldif")
@@ -615,7 +628,12 @@ class FDSBackend(LDAPBackend):
files=[setup_path("schema_samba4.ldif"), self.samba3_ldif],
prefixmap=["1000:1.3.6.1.4.1.7165.2.1", "1001:1.3.6.1.4.1.7165.2.2"])
- def provision(self):
+ self.credentials.set_bind_dn(self.names.ldapmanagerdn)
+
+ def create(self):
+
+ super(FDSBackend, self).create()
+
if self.ldap_backend_extra_port is not None:
serverport = "ServerPort=%d" % self.ldap_backend_extra_port
else:
@@ -699,8 +717,6 @@ class FDSBackend(LDAPBackend):
assert backend_schema_data is not None
open(os.path.join(self.ldapdir, backend_schema), 'w').write(backend_schema_data)
- self.credentials.set_bind_dn(self.names.ldapmanagerdn)
-
# Destory the target directory, or else setup-ds.pl will complain
fedora_ds_dir = os.path.join(self.ldapdir, "slapd-" + self.ldap_instance)
shutil.rmtree(fedora_ds_dir, True)
@@ -736,6 +752,26 @@ class FDSBackend(LDAPBackend):
if retcode != 0:
raise ProvisioningError("ldif2db failed")
+ def reset(self):
+
+ self.ldap_db = Ldb(self.ldap_uri, lp=self.lp, credentials=self.credentials)
+
+ # Erasing all partitions
+ for basedn in [self.names.schemadn, self.names.configdn, self.names.domaindn]:
+
+ self.message("Erasing " + basedn)
+ self.delete(self.ldap_db, basedn)
+
+ self.message("Erasing " + self.rangesdn)
+ self.deleteChildren(self.ldap_db, self.rangesdn)
+
+ # Updating DNA configuration
+ setup_modify_ldif(self.ldap_db, self.setup_path("fedorads-dna-modify.ldif"),
+ {"DOMAINDN": self.names.domaindn,
+ "SAMBADN": self.sambadn,
+ "DOMAINSID": str(self.domainsid),
+ })
+
def post_setup(self):
ldapi_db = Ldb(self.ldap_uri, credentials=self.credentials)
diff --git a/source4/setup/fedorads-dna-modify.ldif b/source4/setup/fedorads-dna-modify.ldif
new file mode 100644
index 0000000..52281a7
--- /dev/null
+++ b/source4/setup/fedorads-dna-modify.ldif
@@ -0,0 +1,14 @@
+dn: cn=Samba SIDs,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config
+changetype: modify
+replace: dnaScope
+dnaScope: ${DOMAINDN}
+-
+replace: dnaNextValue
+dnaNextValue: 1000
+-
+replace: dnaSharedCfgDn
+dnaSharedCfgDn: cn=Samba SIDs,ou=Ranges,${SAMBADN}
+-
+replace: dnaPrefix
+dnaPrefix: ${DOMAINSID}-
+-
diff --git a/source4/setup/provision b/source4/setup/provision
index 5377a2e..80f3153 100755
--- a/source4/setup/provision
+++ b/source4/setup/provision
@@ -95,6 +95,9 @@ parser.add_option("--ldap-backend-extra-port", type="int", metavar="LDAP-BACKEND
parser.add_option("--ldap-backend-type", type="choice", metavar="LDAP-BACKEND-TYPE",
help="LDAP backend type (fedora-ds or openldap)",
choices=["fedora-ds", "openldap"])
+parser.add_option("--ldap-action", type="choice", metavar="LDAP-ACTION",
+ help="LDAP backend action (create or setup)",
+ choices=["create", "setup"])
parser.add_option("--ldap-dir", type="string", metavar="LDAP-DIR",
help="LDAP backend directory")
parser.add_option("--ldap-uri", type="string", metavar="LDAP-URI",
@@ -243,7 +246,7 @@ provision(setup_dir, message,
serverrole=server_role, dom_for_fun_level=dom_for_fun_level,
ldap_backend_extra_port=opts.ldap_backend_extra_port,
backend_type=opts.ldap_backend_type,
- ldap_dir=opts.ldap_dir, ldap_uri=opts.ldap_uri,
+ ldap_action=opts.ldap_action, ldap_dir=opts.ldap_dir, ldap_uri=opts.ldap_uri,
ldapadminpass=opts.ldapadminpass, ol_mmr_urls=opts.ol_mmr_urls,
slapd_path=opts.slapd_path, setup_ds_path=opts.setup_ds_path,
nosync=opts.nosync,ldap_dryrun_mode=opts.ldap_dryrun_mode,useeadb=eadb)
diff --git a/source4/setup/slapd.conf b/source4/setup/slapd.conf
index 0077a22..70cec60 100644
--- a/source4/setup/slapd.conf
+++ b/source4/setup/slapd.conf
@@ -58,6 +58,7 @@ database ldif
suffix cn=Samba
directory ${LDAPDIR}/db/samba
rootdn cn=Manager,cn=Samba
+rootpw ${LDAPADMINPASS}
########################################
## olc - configuration ###
@@ -77,6 +78,7 @@ access to dn.sub="cn=config"
database hdb
suffix ${SCHEMADN}
rootdn cn=Manager,${SCHEMADN}
+rootpw ${LDAPADMINPASS}
directory ${LDAPDIR}/db/schema
${NOSYNC}
${INDEX_CONFIG}
@@ -97,6 +99,7 @@ ${MIRRORMODE}
database hdb
suffix ${CONFIGDN}
rootdn cn=Manager,${CONFIGDN}
+rootpw ${LDAPADMINPASS}
directory ${LDAPDIR}/db/config
${NOSYNC}
${INDEX_CONFIG}
@@ -116,6 +119,7 @@ ${MIRRORMODE}
database hdb
suffix ${DOMAINDN}
rootdn cn=Manager,${DOMAINDN}
+rootpw ${LDAPADMINPASS}
directory ${LDAPDIR}/db/user
${NOSYNC}
${INDEX_CONFIG}
--
1.6.6
------=_Part_68415_58125355.1265837901273--
More information about the samba-technical
mailing list