from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError
from ms_display_specifiers import read_ms_ldif
from schema import Schema
-from provisionbackend import ProvisionBackend
+from provisionbackend import LDBBackend, ExistingBackend, FDSBackend, OpenLDAPBackend
+from provisionexceptions import ProvisioningError, InvalidNetbiosName
from signal import SIGTERM
from dcerpc.misc import SEC_CHAN_BDC, SEC_CHAN_WKSTA
"(OA;;CR;89e95b76-444d-4c62-991a-0facbeda640c;;ED)" \
"(OA;;CR;1131f6ad-9c07-11d1-f79f-00c04fc2dcd2;;BA)" \
"(OA;;CR;89e95b76-444d-4c62-991a-0facbeda640c;;BA)" \
- "(OA;;CR;1131f6aa-9c07-11d1-f79f-00c04fc2dcd2;;S-1-5-21-3191434175-1265308384-3577286990-498)" \
+ "(OA;;CR;1131f6aa-9c07-11d1-f79f-00c04fc2dcd2;;ER)" \
"S:(AU;SA;WPWOWD;;;WD)(AU;SA;CR;;;BA)(AU;SA;CR;;;DU)" \
"(OU;SA;CR;45ec5156-db7e-47bb-b53f-dbeb2d03c40f;;WD)"
sec = security.descriptor.from_sddl(sddl, domain_sid)
"(OA;CIIO;RP;59ba2f42-79a2-11d0-9020-00c04fc2d3cf;bf967aba-0de6-11d0-a285-00aa003049e2;RU)" \
"(OA;CIIO;RP;037088f8-0ae1-11d2-b422-00a0c968f939;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU)" \
"(OA;CIIO;RP;037088f8-0ae1-11d2-b422-00a0c968f939;bf967aba-0de6-11d0-a285-00aa003049e2;RU)" \
- "(OA;;CR;1131f6aa-9c07-11d1-f79f-00c04fc2dcd2;;S-1-5-21-832762594-175224951-1765713900-498)" \
+ "(OA;;CR;1131f6aa-9c07-11d1-f79f-00c04fc2dcd2;;ER)" \
"(OA;;CR;1131f6ad-9c07-11d1-f79f-00c04fc2dcd2;;DD)" \
"(OA;CIIO;RP;b7c69e6d-2cc7-11d2-854e-00a0c983f608;bf967a86-0de6-11d0-a285-00aa003049e2;ED)" \
"(OA;CIIO;RP;b7c69e6d-2cc7-11d2-854e-00a0c983f608;bf967a9c-0de6-11d0-a285-00aa003049e2;ED)" \
"(OA;;CR;1131f6ac-9c07-11d1-f79f-00c04fc2dcd2;;BA)" \
"(OA;;CR;1131f6ad-9c07-11d1-f79f-00c04fc2dcd2;;BA)" \
"(OA;;CR;1131f6ae-9c07-11d1-f79f-00c04fc2dcd2;;BA)" \
- "(OA;;CR;e2a36dc9-ae17-47c3-b58b-be34c55ba633;;S-1-5-32-557)" \
+ "(OA;;CR;e2a36dc9-ae17-47c3-b58b-be34c55ba633;;IF)" \
"(OA;;RP;c7407360-20bf-11d0-a768-00aa006e0529;;RU)" \
"(OA;;RP;b8119fd0-04f6-4762-ab7a-4986c76b3f9a;;RU)" \
"(OA;CIIO;RPLCLORC;;4828cc14-1437-45bc-9b07-ad6f015e5f28;RU)" \
# Exception classes
-class ProvisioningError(Exception):
- """A generic provision error."""
-
-class InvalidNetbiosName(Exception):
- """A specified name was not a valid NetBIOS name."""
- def __init__(self, name):
- super(InvalidNetbiosName, self).__init__("The name '%r' is not a valid NetBIOS name" % name)
-
-
class ProvisionPaths(object):
def __init__(self):
self.shareconf = None
self.slapdconf = None
self.modulesconf = None
self.memberofconf = None
- self.fedoradsinf = None
- self.fedoradspartitions = None
- self.fedoradssasl = None
- self.fedoradsdna = None
- self.fedoradspam = None
- self.fedoradsrefint = None
- self.fedoradslinkedattributes = None
- self.fedoradsindex = None
- self.fedoradssamba = None
self.olmmron = None
self.olmmrserveridsconf = None
self.olmmrsyncreplconf = None
self.domaindn = None
self.configdn = None
self.schemadn = None
- self.sambadn = None
self.ldapmanagerdn = None
self.dnsdomain = None
self.realm = None
"modules.conf")
paths.memberofconf = os.path.join(paths.ldapdir,
"memberof.conf")
- paths.fedoradsinf = os.path.join(paths.ldapdir,
- "fedorads.inf")
- paths.fedoradspartitions = os.path.join(paths.ldapdir,
- "fedorads-partitions.ldif")
- paths.fedoradssasl = os.path.join(paths.ldapdir,
- "fedorads-sasl.ldif")
- paths.fedoradsdna = os.path.join(paths.ldapdir,
- "fedorads-dna.ldif")
- paths.fedoradspam = os.path.join(paths.ldapdir,
- "fedorads-pam.ldif")
- paths.fedoradsrefint = os.path.join(paths.ldapdir,
- "fedorads-refint.ldif")
- paths.fedoradslinkedattributes = os.path.join(paths.ldapdir,
- "fedorads-linked-attributes.ldif")
- paths.fedoradsindex = os.path.join(paths.ldapdir,
- "fedorads-index.ldif")
- paths.fedoradssamba = os.path.join(paths.ldapdir,
- "fedorads-samba.ldif")
paths.olmmrserveridsconf = os.path.join(paths.ldapdir,
"mmr_serverids.conf")
paths.olmmrsyncreplconf = os.path.join(paths.ldapdir,
def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None,
serverrole=None, rootdn=None, domaindn=None, configdn=None,
- schemadn=None, serverdn=None, sitename=None, sambadn=None):
+ schemadn=None, serverdn=None, sitename=None):
"""Guess configuration settings to use."""
if hostname is None:
configdn = "CN=Configuration," + rootdn
if schemadn is None:
schemadn = "CN=Schema," + configdn
- if sambadn is None:
- sambadn = "CN=Samba"
if sitename is None:
sitename=DEFAULTSITE
names.domaindn = domaindn
names.configdn = configdn
names.schemadn = schemadn
- names.sambadn = sambadn
names.ldapmanagerdn = "CN=Manager," + rootdn
names.dnsdomain = dnsdomain
names.domain = domain
samdb = Ldb(url=samdb_path, session_info=session_info,
lp=lp, options=["modules:"])
- #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 = ["resolve_oids",
- "rootdse",
- "lazy_commit",
- "acl",
- "paged_results",
- "ranged_results",
- "anr",
- "server_sort",
- "asq",
- "extended_dn_store",
- "extended_dn_in",
- "rdn_name",
- "objectclass",
- "descriptor",
- "samldb",
- "password_hash",
- "operational",
- "kludge_acl",
- "instancetype"]
- tdb_modules_list = [
- "subtree_rename",
- "subtree_delete",
- "linked_attributes",
- "extended_dn_out_ldb"]
- modules_list2 = ["show_deleted",
- "schema_load",
- "new_partition",
- "partition"]
-
ldap_backend_line = "# No LDAP backend"
if provision_backend.type is not "ldb":
ldap_backend_line = "ldapBackend: %s" % provision_backend.ldapi_uri
-
- 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"]
- elif ldap_backend.ldap_backend_type == "openldap":
- backend_modules = ["entryuuid", "paged_searches"]
- # OpenLDAP handles subtree renames, so we don't want to do any of these things
- tdb_modules_list = ["extended_dn_out_openldap"]
-
- elif serverrole == "domain controller":
- tdb_modules_list.insert(0, "repl_meta_data")
- backend_modules = []
- 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:
message("Setting up sam.ldb partitions and settings")
setup_add_ldif(samdb, setup_path("provision_partitions.ldif"), {
"SCHEMADN": ldb.Dn(schema.ldb, names.schemadn).get_casefold(),
- "SCHEMADN_MOD2": ",objectguid",
"CONFIGDN": ldb.Dn(schema.ldb, names.configdn).get_casefold(),
"DOMAINDN": ldb.Dn(schema.ldb, names.domaindn).get_casefold(),
- "SCHEMADN_MOD": "schema_data",
- "CONFIGDN_MOD": "naming_fsmo",
- "DOMAINDN_MOD": "pdc_fsmo",
- "MODULES_LIST": ",".join(modules_list),
- "TDB_MODULES_LIST": tdb_modules_list_as_string,
- "MODULES_LIST2": ",".join(modules_list2),
- "BACKEND_MOD": ",".join(backend_modules),
"LDAP_BACKEND_LINE": ldap_backend_line,
})
- samdb.load_ldif_file_add(setup_path("provision_init.ldif"))
+ setup_add_ldif(samdb, setup_path("provision_init.ldif"), {
+ "BACKEND_TYPE": provision_backend.type,
+ "SERVER_ROLE": serverrole
+ })
message("Setting up sam.ldb rootDSE")
setup_samdb_rootdse(samdb, setup_path, names)
def secretsdb_self_join(secretsdb, domain,
- netbiosname, domainsid, machinepass,
+ netbiosname, machinepass, domainsid=None,
realm=None, dnsdomain=None,
keytab_path=None,
key_version_number=1,
msg["secret"] = [machinepass]
msg["samAccountName"] = ["%s$" % netbiosname]
msg["secureChannelType"] = [str(secure_channel_type)]
- msg["objectSid"] = [ndr_pack(domainsid)]
+ if domainsid is not None:
+ msg["objectSid"] = [ndr_pack(domainsid)]
res = secretsdb.search(base="cn=Primary Domains",
attrs=attrs,
serverrole=serverrole, schema=schema)
if (schema == None):
- schema = Schema(setup_path, domainsid, schemadn=names.schemadn, serverdn=names.serverdn,
- sambadn=names.sambadn)
+ schema = Schema(setup_path, domainsid, schemadn=names.schemadn, serverdn=names.serverdn)
# 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,
"CONFIGDN": names.configdn,
"DESCRIPTOR": descr,
})
- message("Modifying configuration container")
- setup_modify_ldif(samdb, setup_path("provision_configuration_basedn_modify.ldif"), {
- "CONFIGDN": names.configdn,
- "SCHEMADN": names.schemadn,
- })
# The LDIF here was created when the Schema object was constructed
message("Setting up sam.ldb schema")
"POLICYGUID_DC": policyguid_dc
})
+ setup_modify_ldif(samdb, setup_path("provision_basedn_references.ldif"), {
+ "DOMAINDN": names.domaindn})
+
+ setup_modify_ldif(samdb, setup_path("provision_configuration_references.ldif"), {
+ "CONFIGDN": names.configdn,
+ "SCHEMADN": names.schemadn})
if fill == FILL_FULL:
message("Setting up sam.ldb users and groups")
setup_add_ldif(samdb, setup_path("provision_users.ldif"), {
if not os.path.exists(paths.private_dir):
os.mkdir(paths.private_dir)
+ if not os.path.exists(os.path.join(paths.private_dir,"tls")):
+ os.mkdir(os.path.join(paths.private_dir,"tls"))
ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="")
+
+ schema = Schema(setup_path, domainsid, schemadn=names.schemadn, serverdn=names.serverdn)
- schema = Schema(setup_path, domainsid, schemadn=names.schemadn, serverdn=names.serverdn,
- sambadn=names.sambadn)
-
- provision_backend = ProvisionBackend(backend_type,
+ if backend_type == "ldb":
+ provision_backend = LDBBackend(backend_type,
paths=paths, setup_path=setup_path,
lp=lp, credentials=credentials,
names=names,
- message=message, hostname=hostname,
- root=root, schema=schema,
+ 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)
+ elif backend_type == "fedora-ds":
+ provision_backend = FDSBackend(backend_type,
+ paths=paths, setup_path=setup_path,
+ lp=lp, credentials=credentials,
+ names=names,
+ message=message,
+ domainsid=domainsid,
+ schema=schema,
+ hostname=hostname,
ldapadminpass=ldapadminpass,
+ slapd_path=slapd_path,
ldap_backend_extra_port=ldap_backend_extra_port,
- ol_mmr_urls=ol_mmr_urls,
+ ldap_dryrun_mode=ldap_dryrun_mode,
+ root=root,
+ setup_ds_path=setup_ds_path)
+ elif backend_type == "openldap":
+ provision_backend = OpenLDAPBackend(backend_type,
+ paths=paths, setup_path=setup_path,
+ lp=lp, credentials=credentials,
+ names=names,
+ message=message,
+ domainsid=domainsid,
+ schema=schema,
+ hostname=hostname,
+ ldapadminpass=ldapadminpass,
slapd_path=slapd_path,
- setup_ds_path=setup_ds_path,
+ ldap_backend_extra_port=ldap_backend_extra_port,
ldap_dryrun_mode=ldap_dryrun_mode,
- domainsid=domainsid)
+ ol_mmr_urls=ol_mmr_urls,
+ nosync=nosync)
+ else:
+ raise ProvisioningError("Unknown LDAP backend type selected")
+
+ provision_backend.init()
+ provision_backend.start()
# only install a new shares config db if there is none
if not os.path.exists(paths.shareconf):
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":
- secretsdb_self_join(secrets_ldb, domain=domain,
- realm=names.realm,
- dnsdomain=names.dnsdomain,
- netbiosname=names.netbiosname,
- domainsid=domainsid,
- machinepass=machinepass,
- secure_channel_type=SEC_CHAN_BDC)
+ secretsdb_self_join(secrets_ldb, domain=names.domain,
+ realm=names.realm,
+ dnsdomain=names.dnsdomain,
+ netbiosname=names.netbiosname,
+ domainsid=domainsid,
+ machinepass=machinepass,
+ secure_channel_type=SEC_CHAN_BDC)
+ if serverrole == "domain controller":
secretsdb_setup_dns(secrets_ldb, setup_path,
realm=names.realm, dnsdomain=names.dnsdomain,
dns_keytab_path=paths.dns_keytab,
domainguid = samdb.searchone(basedn=domaindn, attribute="objectGUID")
assert isinstance(domainguid, str)
+ # Only make a zone file on the first DC, it should be replicated
+ # with DNS replication
create_zone_file(paths.dns, setup_path, dnsdomain=names.dnsdomain,
hostip=hostip,
hostip6=hostip6, hostname=names.hostname,
realm=names.realm)
message("A Kerberos configuration suitable for Samba 4 has been generated at %s" % paths.krb5conf)
- if provision_backend.post_setup is not None:
- provision_backend.post_setup()
-
- if provision_backend.shutdown is not None:
- provision_backend.shutdown()
+ provision_backend.post_setup()
+ provision_backend.shutdown()
create_phpldapadmin_config(paths.phpldapadminconfig, setup_path,
ldapi_url)
message("DNS Domain: %s" % names.dnsdomain)
message("DOMAIN SID: %s" % str(domainsid))
if samdb_fill == FILL_FULL:
- message("Admin password: %s" % adminpass)
+ message("Admin password: %s" % adminpass)
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())