import urllib
import string
import tempfile
+import samba.dsdb
import ldb
DEFAULT_POLICY_GUID = "31B2F340-016D-11D2-945F-00C04FB984F9"
-DEFAULT_DC_POLICY_GUID = "6AC1786C-016F-11D2-945F-00C04fB984F9"
+DEFAULT_DC_POLICY_GUID = "6AC1786C-016F-11D2-945F-00C04FB984F9"
DEFAULTSITE = "Default-First-Site-Name"
LAST_PROVISION_USN_ATTRIBUTE = "lastProvisionUSN"
self.hostname = None
self.sitename = None
self.smbconf = None
+ self.domainsid = None
+ self.forestsid = None
+ self.domainguid = None
self.name_map = {}
# dns hostname and server dn
res4 = samdb.search(expression="(CN=%s)" % names.netbiosname,
- base="OU=Domain Controllers,%s" % basedn,
- scope=ldb.SCOPE_ONELEVEL, attrs=["dNSHostName"])
+ base="OU=Domain Controllers,%s" % basedn,
+ scope=ldb.SCOPE_ONELEVEL, attrs=["dNSHostName"])
+ if len(res4) == 0:
+ raise ProvisioningError("Unable to find DC called CN=%s under OU=Domain Controllers,%s" % (names.netbiosname, basedn))
+
names.hostname = str(res4[0]["dNSHostName"]).replace("." + names.dnsdomain, "")
server_res = samdb.search(expression="serverReference=%s" % res4[0].dn,
"objectSid","msDS-Behavior-Version" ])
names.domainguid = str(ndr_unpack(misc.GUID, res6[0]["objectGUID"][0]))
names.domainsid = ndr_unpack( security.dom_sid, res6[0]["objectSid"][0])
+ names.forestsid = ndr_unpack( security.dom_sid, res6[0]["objectSid"][0])
if res6[0].get("msDS-Behavior-Version") is None or \
int(res6[0]["msDS-Behavior-Version"][0]) < DS_DOMAIN_FUNCTION_2000:
names.domainlevel = DS_DOMAIN_FUNCTION_2000
names.domainlevel = int(res6[0]["msDS-Behavior-Version"][0])
# policy guid
- res7 = samdb.search(expression="(displayName=Default Domain Policy)",
+ res7 = samdb.search(expression="(name={%s})" % DEFAULT_POLICY_GUID,
base="CN=Policies,CN=System," + basedn,
scope=ldb.SCOPE_ONELEVEL, attrs=["cn","displayName"])
names.policyid = str(res7[0]["cn"]).replace("{","").replace("}","")
# dc policy guid
- res8 = samdb.search(expression="(displayName=Default Domain Controllers"
- " Policy)",
- base="CN=Policies,CN=System," + basedn,
- scope=ldb.SCOPE_ONELEVEL,
- attrs=["cn","displayName"])
+ res8 = samdb.search(expression="(name={%s})" % DEFAULT_DC_POLICY_GUID,
+ base="CN=Policies,CN=System," + basedn,
+ scope=ldb.SCOPE_ONELEVEL,
+ attrs=["cn","displayName"])
if len(res8) == 1:
names.policyid_dc = str(res8[0]["cn"]).replace("{","").replace("}","")
else:
def setup_samdb_partitions(samdb_path, logger, lp, session_info,
- provision_backend, names, schema, serverrole,
+ provision_backend, names, serverrole,
erase=False):
"""Setup the partitions for the SAM database.
msg["msDS-KeyVersionNumber"] = [str(key_version_number)]
msg["privateKeytab"] = ["secrets.keytab"]
- msg["secret"] = [machinepass]
+ msg["secret"] = [machinepass.encode('utf-8')]
msg["samAccountName"] = ["%s$" % netbiosname]
msg["secureChannelType"] = [str(secure_channel_type)]
if domainsid is not None:
def setup_secretsdb(paths, session_info, backend_credentials, lp):
"""Setup the secrets database.
- :note: This function does not handle exceptions and transaction on purpose,
+ :note: This function does not handle exceptions and transaction on purpose,
it's up to the caller to do this job.
:param path: Path to the secrets database.
# Also wipes the database
setup_samdb_partitions(path, logger=logger, lp=lp,
provision_backend=provision_backend, session_info=session_info,
- names=names, serverrole=serverrole, schema=schema)
+ names=names, serverrole=serverrole)
# Load the database, but don's load the global schema and don't connect
# quite yet
# And now we can connect to the DB - the schema won't be loaded from the
# DB
- samdb.connect(path)
+ try:
+ samdb.connect(path)
+ except ldb.LdbError, (num, string_error):
+ if (num == ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS):
+ raise ProvisioningError("Permission denied connecting to %s, are you running as root?" % path)
+ else:
+ raise
# But we have to give it one more kick to have it use the schema
# during provision - it needs, now that it is connected, to write
return samdb
-def fill_samdb(samdb, lp, names, logger, domainsid, domainguid, policyguid,
+def fill_samdb(samdb, lp, names, logger, policyguid,
policyguid_dc, fill, adminpass, krbtgtpass, machinepass, dns_backend,
dnspass, invocationid, ntdsguid, serverrole, am_rodc=False,
dom_for_fun_level=None, schema=None, next_rid=None, dc_rid=None):
domainControllerFunctionality = DS_DOMAIN_FUNCTION_2008_R2
if dom_for_fun_level is None:
- dom_for_fun_level = DS_DOMAIN_FUNCTION_2003
+ dom_for_fun_level = DS_DOMAIN_FUNCTION_2008_R2
if dom_for_fun_level > domainControllerFunctionality:
raise ProvisioningError("You want to run SAMBA 4 on a domain and forest function level which itself is higher than its actual DC function level (2008_R2). This won't work!")
# before the provisioned tree exists and we connect
samdb.set_ntds_settings_dn("CN=NTDS Settings,%s" % names.serverdn)
- samdb.transaction_start()
- try:
- # Set the domain functionality levels onto the database.
- # Various module (the password_hash module in particular) need
- # to know what level of AD we are emulating.
-
- # These will be fixed into the database via the database
- # modifictions below, but we need them set from the start.
- samdb.set_opaque_integer("domainFunctionality", domainFunctionality)
- samdb.set_opaque_integer("forestFunctionality", forestFunctionality)
- samdb.set_opaque_integer("domainControllerFunctionality",
- domainControllerFunctionality)
-
- samdb.set_domain_sid(str(domainsid))
- samdb.set_invocation_id(invocationid)
-
- logger.info("Adding DomainDN: %s" % names.domaindn)
-
- # impersonate domain admin
- admin_session_info = admin_session(lp, str(domainsid))
- samdb.set_session_info(admin_session_info)
- if domainguid is not None:
- domainguid_line = "objectGUID: %s\n-" % domainguid
- else:
- domainguid_line = ""
+ # Set the domain functionality levels onto the database.
+ # Various module (the password_hash module in particular) need
+ # to know what level of AD we are emulating.
- descr = b64encode(get_domain_descriptor(domainsid))
- setup_add_ldif(samdb, setup_path("provision_basedn.ldif"), {
- "DOMAINDN": names.domaindn,
- "DOMAINSID": str(domainsid),
- "DESCRIPTOR": descr,
- "DOMAINGUID": domainguid_line
- })
+ # These will be fixed into the database via the database
+ # modifictions below, but we need them set from the start.
+ samdb.set_opaque_integer("domainFunctionality", domainFunctionality)
+ samdb.set_opaque_integer("forestFunctionality", forestFunctionality)
+ samdb.set_opaque_integer("domainControllerFunctionality",
+ domainControllerFunctionality)
- setup_modify_ldif(samdb, setup_path("provision_basedn_modify.ldif"), {
- "DOMAINDN": names.domaindn,
- "CREATTIME": str(samba.unix2nttime(int(time.time()))),
- "NEXTRID": str(next_rid),
- "DEFAULTSITE": names.sitename,
- "CONFIGDN": names.configdn,
- "POLICYGUID": policyguid,
- "DOMAIN_FUNCTIONALITY": str(domainFunctionality),
- "SAMBA_VERSION_STRING": version
- })
+ samdb.set_domain_sid(str(names.domainsid))
+ samdb.set_invocation_id(invocationid)
- # If we are setting up a subdomain, then this has been replicated in, so we don't need to add it
- if fill == FILL_FULL:
- logger.info("Adding configuration container")
- descr = b64encode(get_config_descriptor(domainsid))
- setup_add_ldif(samdb, setup_path("provision_configuration_basedn.ldif"), {
- "CONFIGDN": names.configdn,
- "DESCRIPTOR": descr,
- })
-
- # The LDIF here was created when the Schema object was constructed
- logger.info("Setting up sam.ldb schema")
- samdb.add_ldif(schema.schema_dn_add, controls=["relax:0"])
- samdb.modify_ldif(schema.schema_dn_modify)
- samdb.write_prefixes_from_schema()
- samdb.add_ldif(schema.schema_data, controls=["relax:0"])
- setup_add_ldif(samdb, setup_path("aggregate_schema.ldif"),
- {"SCHEMADN": names.schemadn})
-
- # Now register this container in the root of the forest
- msg = ldb.Message(ldb.Dn(samdb, names.domaindn))
- msg["subRefs"] = ldb.MessageElement(names.configdn , ldb.FLAG_MOD_ADD,
- "subRefs")
+ logger.info("Adding DomainDN: %s" % names.domaindn)
- except:
- samdb.transaction_cancel()
- raise
+ # impersonate domain admin
+ admin_session_info = admin_session(lp, str(names.domainsid))
+ samdb.set_session_info(admin_session_info)
+ if names.domainguid is not None:
+ domainguid_line = "objectGUID: %s\n-" % names.domainguid
else:
- samdb.transaction_commit()
+ domainguid_line = ""
- samdb.transaction_start()
- try:
- samdb.invocation_id = invocationid
-
- # If we are setting up a subdomain, then this has been replicated in, so we don't need to add it
- if fill == FILL_FULL:
- logger.info("Setting up sam.ldb configuration data")
-
- partitions_descr = b64encode(get_config_partitions_descriptor(domainsid))
- sites_descr = b64encode(get_config_sites_descriptor(domainsid))
- ntdsquotas_descr = b64encode(get_config_ntds_quotas_descriptor(domainsid))
- protected1_descr = b64encode(get_config_delete_protected1_descriptor(domainsid))
- protected1wd_descr = b64encode(get_config_delete_protected1wd_descriptor(domainsid))
- protected2_descr = b64encode(get_config_delete_protected2_descriptor(domainsid))
-
- setup_add_ldif(samdb, setup_path("provision_configuration.ldif"), {
- "CONFIGDN": names.configdn,
- "NETBIOSNAME": names.netbiosname,
- "DEFAULTSITE": names.sitename,
- "DNSDOMAIN": names.dnsdomain,
- "DOMAIN": names.domain,
- "SCHEMADN": names.schemadn,
- "DOMAINDN": names.domaindn,
- "SERVERDN": names.serverdn,
- "FOREST_FUNCTIONALITY": str(forestFunctionality),
- "DOMAIN_FUNCTIONALITY": str(domainFunctionality),
- "NTDSQUOTAS_DESCRIPTOR": ntdsquotas_descr,
- "LOSTANDFOUND_DESCRIPTOR": protected1wd_descr,
- "SERVICES_DESCRIPTOR": protected1_descr,
- "PHYSICALLOCATIONS_DESCRIPTOR": protected1wd_descr,
- "FORESTUPDATES_DESCRIPTOR": protected1wd_descr,
- "EXTENDEDRIGHTS_DESCRIPTOR": protected2_descr,
- "PARTITIONS_DESCRIPTOR": partitions_descr,
- "SITES_DESCRIPTOR": sites_descr,
- })
-
- logger.info("Setting up display specifiers")
- display_specifiers_ldif = read_ms_ldif(
- setup_path('display-specifiers/DisplaySpecifiers-Win2k8R2.txt'))
- display_specifiers_ldif = substitute_var(display_specifiers_ldif,
- {"CONFIGDN": names.configdn})
- check_all_substituted(display_specifiers_ldif)
- samdb.add_ldif(display_specifiers_ldif)
-
- logger.info("Modifying display specifiers")
- setup_modify_ldif(samdb,
- setup_path("provision_configuration_modify.ldif"), {
+ descr = b64encode(get_domain_descriptor(names.domainsid))
+ setup_add_ldif(samdb, setup_path("provision_basedn.ldif"), {
+ "DOMAINDN": names.domaindn,
+ "DOMAINSID": str(names.domainsid),
+ "DESCRIPTOR": descr,
+ "DOMAINGUID": domainguid_line
+ })
+
+ setup_modify_ldif(samdb, setup_path("provision_basedn_modify.ldif"), {
+ "DOMAINDN": names.domaindn,
+ "CREATTIME": str(samba.unix2nttime(int(time.time()))),
+ "NEXTRID": str(next_rid),
+ "DEFAULTSITE": names.sitename,
+ "CONFIGDN": names.configdn,
+ "POLICYGUID": policyguid,
+ "DOMAIN_FUNCTIONALITY": str(domainFunctionality),
+ "SAMBA_VERSION_STRING": version
+ })
+
+ # If we are setting up a subdomain, then this has been replicated in, so we don't need to add it
+ if fill == FILL_FULL:
+ logger.info("Adding configuration container")
+ descr = b64encode(get_config_descriptor(names.domainsid))
+ setup_add_ldif(samdb, setup_path("provision_configuration_basedn.ldif"), {
"CONFIGDN": names.configdn,
- "DISPLAYSPECIFIERS_DESCRIPTOR": protected2_descr
+ "DESCRIPTOR": descr,
})
- logger.info("Adding users container")
- users_desc = b64encode(get_domain_users_descriptor(domainsid))
- setup_add_ldif(samdb, setup_path("provision_users_add.ldif"), {
- "DOMAINDN": names.domaindn,
- "USERS_DESCRIPTOR": users_desc
- })
- logger.info("Modifying users container")
- setup_modify_ldif(samdb, setup_path("provision_users_modify.ldif"), {
- "DOMAINDN": names.domaindn})
- logger.info("Adding computers container")
- computers_desc = b64encode(get_domain_computers_descriptor(domainsid))
- setup_add_ldif(samdb, setup_path("provision_computers_add.ldif"), {
+ # The LDIF here was created when the Schema object was constructed
+ ignore_checks_oid = "local_oid:%s:0" % samba.dsdb.DSDB_CONTROL_SKIP_DUPLICATES_CHECK_OID
+ logger.info("Setting up sam.ldb schema")
+ samdb.add_ldif(schema.schema_dn_add,
+ controls=["relax:0", ignore_checks_oid])
+ samdb.modify_ldif(schema.schema_dn_modify,
+ controls=[ignore_checks_oid])
+ samdb.write_prefixes_from_schema()
+ samdb.add_ldif(schema.schema_data, controls=["relax:0", ignore_checks_oid])
+ setup_add_ldif(samdb, setup_path("aggregate_schema.ldif"),
+ {"SCHEMADN": names.schemadn},
+ controls=["relax:0", ignore_checks_oid])
+
+ # Now register this container in the root of the forest
+ msg = ldb.Message(ldb.Dn(samdb, names.domaindn))
+ msg["subRefs"] = ldb.MessageElement(names.configdn , ldb.FLAG_MOD_ADD,
+ "subRefs")
+
+ samdb.invocation_id = invocationid
+
+ # If we are setting up a subdomain, then this has been replicated in, so we don't need to add it
+ if fill == FILL_FULL:
+ logger.info("Setting up sam.ldb configuration data")
+
+ partitions_descr = b64encode(get_config_partitions_descriptor(names.domainsid))
+ sites_descr = b64encode(get_config_sites_descriptor(names.domainsid))
+ ntdsquotas_descr = b64encode(get_config_ntds_quotas_descriptor(names.domainsid))
+ protected1_descr = b64encode(get_config_delete_protected1_descriptor(names.domainsid))
+ protected1wd_descr = b64encode(get_config_delete_protected1wd_descriptor(names.domainsid))
+ protected2_descr = b64encode(get_config_delete_protected2_descriptor(names.domainsid))
+
+ setup_add_ldif(samdb, setup_path("provision_configuration.ldif"), {
+ "CONFIGDN": names.configdn,
+ "NETBIOSNAME": names.netbiosname,
+ "DEFAULTSITE": names.sitename,
+ "DNSDOMAIN": names.dnsdomain,
+ "DOMAIN": names.domain,
+ "SCHEMADN": names.schemadn,
"DOMAINDN": names.domaindn,
- "COMPUTERS_DESCRIPTOR": computers_desc
+ "SERVERDN": names.serverdn,
+ "FOREST_FUNCTIONALITY": str(forestFunctionality),
+ "DOMAIN_FUNCTIONALITY": str(domainFunctionality),
+ "NTDSQUOTAS_DESCRIPTOR": ntdsquotas_descr,
+ "LOSTANDFOUND_DESCRIPTOR": protected1wd_descr,
+ "SERVICES_DESCRIPTOR": protected1_descr,
+ "PHYSICALLOCATIONS_DESCRIPTOR": protected1wd_descr,
+ "FORESTUPDATES_DESCRIPTOR": protected1wd_descr,
+ "EXTENDEDRIGHTS_DESCRIPTOR": protected2_descr,
+ "PARTITIONS_DESCRIPTOR": partitions_descr,
+ "SITES_DESCRIPTOR": sites_descr,
})
- logger.info("Modifying computers container")
+
+ logger.info("Setting up display specifiers")
+ display_specifiers_ldif = read_ms_ldif(
+ setup_path('display-specifiers/DisplaySpecifiers-Win2k8R2.txt'))
+ display_specifiers_ldif = substitute_var(display_specifiers_ldif,
+ {"CONFIGDN": names.configdn})
+ check_all_substituted(display_specifiers_ldif)
+ samdb.add_ldif(display_specifiers_ldif)
+
+ logger.info("Modifying display specifiers")
setup_modify_ldif(samdb,
- setup_path("provision_computers_modify.ldif"), {
- "DOMAINDN": names.domaindn})
- logger.info("Setting up sam.ldb data")
- infrastructure_desc = b64encode(get_domain_infrastructure_descriptor(domainsid))
- lostandfound_desc = b64encode(get_domain_delete_protected2_descriptor(domainsid))
- system_desc = b64encode(get_domain_delete_protected1_descriptor(domainsid))
- builtin_desc = b64encode(get_domain_builtin_descriptor(domainsid))
- controllers_desc = b64encode(get_domain_controllers_descriptor(domainsid))
- setup_add_ldif(samdb, setup_path("provision.ldif"), {
- "CREATTIME": str(samba.unix2nttime(int(time.time()))),
- "DOMAINDN": names.domaindn,
- "NETBIOSNAME": names.netbiosname,
- "DEFAULTSITE": names.sitename,
+ setup_path("provision_configuration_modify.ldif"), {
"CONFIGDN": names.configdn,
- "SERVERDN": names.serverdn,
- "RIDAVAILABLESTART": str(next_rid + 600),
- "POLICYGUID_DC": policyguid_dc,
- "INFRASTRUCTURE_DESCRIPTOR": infrastructure_desc,
- "LOSTANDFOUND_DESCRIPTOR": lostandfound_desc,
- "SYSTEM_DESCRIPTOR": system_desc,
- "BUILTIN_DESCRIPTOR": builtin_desc,
- "DOMAIN_CONTROLLERS_DESCRIPTOR": controllers_desc,
+ "DISPLAYSPECIFIERS_DESCRIPTOR": protected2_descr
})
- # If we are setting up a subdomain, then this has been replicated in, so we don't need to add it
- if fill == FILL_FULL:
- setup_modify_ldif(samdb,
- setup_path("provision_configuration_references.ldif"), {
- "CONFIGDN": names.configdn,
- "SCHEMADN": names.schemadn})
+ logger.info("Adding users container")
+ users_desc = b64encode(get_domain_users_descriptor(names.domainsid))
+ setup_add_ldif(samdb, setup_path("provision_users_add.ldif"), {
+ "DOMAINDN": names.domaindn,
+ "USERS_DESCRIPTOR": users_desc
+ })
+ logger.info("Modifying users container")
+ setup_modify_ldif(samdb, setup_path("provision_users_modify.ldif"), {
+ "DOMAINDN": names.domaindn})
+ logger.info("Adding computers container")
+ computers_desc = b64encode(get_domain_computers_descriptor(names.domainsid))
+ setup_add_ldif(samdb, setup_path("provision_computers_add.ldif"), {
+ "DOMAINDN": names.domaindn,
+ "COMPUTERS_DESCRIPTOR": computers_desc
+ })
+ logger.info("Modifying computers container")
+ setup_modify_ldif(samdb,
+ setup_path("provision_computers_modify.ldif"), {
+ "DOMAINDN": names.domaindn})
+ logger.info("Setting up sam.ldb data")
+ infrastructure_desc = b64encode(get_domain_infrastructure_descriptor(names.domainsid))
+ lostandfound_desc = b64encode(get_domain_delete_protected2_descriptor(names.domainsid))
+ system_desc = b64encode(get_domain_delete_protected1_descriptor(names.domainsid))
+ builtin_desc = b64encode(get_domain_builtin_descriptor(names.domainsid))
+ controllers_desc = b64encode(get_domain_controllers_descriptor(names.domainsid))
+ setup_add_ldif(samdb, setup_path("provision.ldif"), {
+ "CREATTIME": str(samba.unix2nttime(int(time.time()))),
+ "DOMAINDN": names.domaindn,
+ "NETBIOSNAME": names.netbiosname,
+ "DEFAULTSITE": names.sitename,
+ "CONFIGDN": names.configdn,
+ "SERVERDN": names.serverdn,
+ "RIDAVAILABLESTART": str(next_rid + 600),
+ "POLICYGUID_DC": policyguid_dc,
+ "INFRASTRUCTURE_DESCRIPTOR": infrastructure_desc,
+ "LOSTANDFOUND_DESCRIPTOR": lostandfound_desc,
+ "SYSTEM_DESCRIPTOR": system_desc,
+ "BUILTIN_DESCRIPTOR": builtin_desc,
+ "DOMAIN_CONTROLLERS_DESCRIPTOR": controllers_desc,
+ })
- logger.info("Setting up well known security principals")
- protected1wd_descr = b64encode(get_config_delete_protected1wd_descriptor(domainsid))
- setup_add_ldif(samdb, setup_path("provision_well_known_sec_princ.ldif"), {
+ # If we are setting up a subdomain, then this has been replicated in, so we don't need to add it
+ if fill == FILL_FULL:
+ setup_modify_ldif(samdb,
+ setup_path("provision_configuration_references.ldif"), {
"CONFIGDN": names.configdn,
- "WELLKNOWNPRINCIPALS_DESCRIPTOR": protected1wd_descr,
- })
+ "SCHEMADN": names.schemadn})
- if fill == FILL_FULL or fill == FILL_SUBDOMAIN:
- setup_modify_ldif(samdb,
- setup_path("provision_basedn_references.ldif"),
- {"DOMAINDN": names.domaindn})
+ logger.info("Setting up well known security principals")
+ protected1wd_descr = b64encode(get_config_delete_protected1wd_descriptor(names.domainsid))
+ setup_add_ldif(samdb, setup_path("provision_well_known_sec_princ.ldif"), {
+ "CONFIGDN": names.configdn,
+ "WELLKNOWNPRINCIPALS_DESCRIPTOR": protected1wd_descr,
+ })
- logger.info("Setting up sam.ldb users and groups")
- setup_add_ldif(samdb, setup_path("provision_users.ldif"), {
- "DOMAINDN": names.domaindn,
- "DOMAINSID": str(domainsid),
- "ADMINPASS_B64": b64encode(adminpass.encode('utf-16-le')),
- "KRBTGTPASS_B64": b64encode(krbtgtpass.encode('utf-16-le'))
- })
+ if fill == FILL_FULL or fill == FILL_SUBDOMAIN:
+ setup_modify_ldif(samdb,
+ setup_path("provision_basedn_references.ldif"),
+ {"DOMAINDN": names.domaindn})
- logger.info("Setting up self join")
- setup_self_join(samdb, admin_session_info, names=names, fill=fill,
- invocationid=invocationid,
- dns_backend=dns_backend,
- dnspass=dnspass,
- machinepass=machinepass,
- domainsid=domainsid,
- next_rid=next_rid,
- dc_rid=dc_rid,
- policyguid=policyguid,
- policyguid_dc=policyguid_dc,
- domainControllerFunctionality=domainControllerFunctionality,
- ntdsguid=ntdsguid)
-
- ntds_dn = "CN=NTDS Settings,%s" % names.serverdn
- names.ntdsguid = samdb.searchone(basedn=ntds_dn,
- attribute="objectGUID", expression="", scope=ldb.SCOPE_BASE)
- assert isinstance(names.ntdsguid, str)
- except:
- samdb.transaction_cancel()
- raise
- else:
- samdb.transaction_commit()
- return samdb
+ logger.info("Setting up sam.ldb users and groups")
+ setup_add_ldif(samdb, setup_path("provision_users.ldif"), {
+ "DOMAINDN": names.domaindn,
+ "DOMAINSID": str(names.domainsid),
+ "ADMINPASS_B64": b64encode(adminpass.encode('utf-16-le')),
+ "KRBTGTPASS_B64": b64encode(krbtgtpass.encode('utf-16-le'))
+ })
+
+ logger.info("Setting up self join")
+ setup_self_join(samdb, admin_session_info, names=names, fill=fill,
+ invocationid=invocationid,
+ dns_backend=dns_backend,
+ dnspass=dnspass,
+ machinepass=machinepass,
+ domainsid=names.domainsid,
+ next_rid=next_rid,
+ dc_rid=dc_rid,
+ policyguid=policyguid,
+ policyguid_dc=policyguid_dc,
+ domainControllerFunctionality=domainControllerFunctionality,
+ ntdsguid=ntdsguid)
+
+ ntds_dn = "CN=NTDS Settings,%s" % names.serverdn
+ names.ntdsguid = samdb.searchone(basedn=ntds_dn,
+ attribute="objectGUID", expression="", scope=ldb.SCOPE_BASE)
+ assert isinstance(names.ntdsguid, str)
+
+ return samdb
SYSVOL_ACL = "O:LAG:BAD:P(A;OICI;0x001f01ff;;;BA)(A;OICI;0x001200a9;;;SO)(A;OICI;0x001f01ff;;;SY)(A;OICI;0x001200a9;;;AU)"
s4_passdb = None
if not use_ntvfs:
+ s3conf = s3param.get_context()
+ s3conf.load(lp.configfile)
+
+ file = tempfile.NamedTemporaryFile(dir=os.path.abspath(sysvol))
+ try:
+ try:
+ smbd.set_simple_acl(file.name, 0755, gid)
+ except OSError:
+ if not smbd.have_posix_acls():
+ # This clue is only strictly correct for RPM and
+ # Debian-like Linux systems, but hopefully other users
+ # will get enough clue from it.
+ raise ProvisioningError("Samba was compiled without the posix ACL support that s3fs requires. "
+ "Try installing libacl1-dev or libacl-devel, then re-run configure and make.")
+
+ raise ProvisioningError("Your filesystem or build does not support posix ACLs, which s3fs requires. "
+ "Try the mounting the filesystem with the 'acl' option.")
+ try:
+ smbd.chown(file.name, uid, gid)
+ except OSError:
+ raise ProvisioningError("Unable to chown a file on your filesystem. "
+ "You may not be running provision as root.")
+ finally:
+ file.close()
+
# This will ensure that the smbd code we are running when setting ACLs
# is initialised with the smb.conf
s3conf = s3param.get_context()
def provision_fill(samdb, secrets_ldb, logger, names, paths,
- domainsid, schema=None,
+ schema=None,
targetdir=None, samdb_fill=FILL_FULL,
hostip=None, hostip6=None,
next_rid=1000, dc_rid=None, adminpass=None, krbtgtpass=None,
invocationid = str(uuid.uuid4())
if krbtgtpass is None:
- krbtgtpass = samba.generate_random_password(128, 255)
+ krbtgtpass = samba.generate_random_machine_password(128, 255)
if machinepass is None:
- machinepass = samba.generate_random_password(128, 255)
+ machinepass = samba.generate_random_machine_password(128, 255)
if dnspass is None:
dnspass = samba.generate_random_password(128, 255)
- samdb = fill_samdb(samdb, lp, names, logger=logger,
- domainsid=domainsid, schema=schema, domainguid=domainguid,
- policyguid=policyguid, policyguid_dc=policyguid_dc,
- fill=samdb_fill, adminpass=adminpass, krbtgtpass=krbtgtpass,
- invocationid=invocationid, machinepass=machinepass,
- dns_backend=dns_backend, dnspass=dnspass,
- ntdsguid=ntdsguid, serverrole=serverrole,
- dom_for_fun_level=dom_for_fun_level, am_rodc=am_rodc,
- next_rid=next_rid, dc_rid=dc_rid)
-
- if serverrole == "active directory domain controller":
+ samdb.transaction_start()
+ try:
+ samdb = fill_samdb(samdb, lp, names, logger=logger,
+ schema=schema,
+ policyguid=policyguid, policyguid_dc=policyguid_dc,
+ fill=samdb_fill, adminpass=adminpass, krbtgtpass=krbtgtpass,
+ invocationid=invocationid, machinepass=machinepass,
+ dns_backend=dns_backend, dnspass=dnspass,
+ ntdsguid=ntdsguid, serverrole=serverrole,
+ dom_for_fun_level=dom_for_fun_level, am_rodc=am_rodc,
+ next_rid=next_rid, dc_rid=dc_rid)
# Set up group policies (domain policy and domain controller
# policy)
- create_default_gpo(paths.sysvol, names.dnsdomain, policyguid,
- policyguid_dc)
+ if serverrole == "active directory domain controller":
+ create_default_gpo(paths.sysvol, names.dnsdomain, policyguid,
+ policyguid_dc)
+ except:
+ samdb.transaction_cancel()
+ raise
+ else:
+ samdb.transaction_commit()
+
+ if serverrole == "active directory domain controller":
+ # Continue setting up sysvol for GPO. This appears to require being
+ # outside a transaction.
if not skip_sysvolacl:
setsysvolacl(samdb, paths.netlogon, paths.sysvol, paths.root_uid,
- paths.root_gid, domainsid, names.dnsdomain,
+ paths.root_gid, names.domainsid, names.dnsdomain,
names.domaindn, lp, use_ntvfs)
else:
logger.info("Setting acl on sysvol skipped")
secretsdb_self_join(secrets_ldb, domain=names.domain,
realm=names.realm, dnsdomain=names.dnsdomain,
- netbiosname=names.netbiosname, domainsid=domainsid,
+ netbiosname=names.netbiosname, domainsid=names.domainsid,
machinepass=machinepass, secure_channel_type=SEC_CHAN_BDC)
# Now set up the right msDS-SupportedEncryptionTypes into the DB
# It might be that this attribute does not exist in this schema
raise
- setup_ad_dns(samdb, secrets_ldb, domainsid, names, paths, lp, logger,
+ setup_ad_dns(samdb, secrets_ldb, names, paths, lp, logger,
hostip=hostip, hostip6=hostip6, dns_backend=dns_backend,
dnspass=dnspass, os_level=dom_for_fun_level,
- targetdir=targetdir, site=DEFAULTSITE, fill_level=samdb_fill)
+ targetdir=targetdir, fill_level=samdb_fill)
domainguid = samdb.searchone(basedn=samdb.get_default_basedn(),
attribute="objectGUID")
'ipsecISAKMPReference',
'ipsecNegotiationPolicyReference',
'ipsecNFAReference'])
+ if chk.check_database(DN=names.schemadn, scope=ldb.SCOPE_SUBTREE,
+ attrs=['attributeId', 'governsId']) != 0:
+ raise ProvisioningError("Duplicate attributeId or governsId in schema. Must be fixed manually!!")
except:
samdb.transaction_cancel()
raise
if domainsid is None:
domainsid = security.random_sid()
- else:
- domainsid = security.dom_sid(domainsid)
root_uid = findnss_uid([root or "root"])
nobody_uid = findnss_uid([nobody or "nobody"])
names.hostip = hostip
names.hostip6 = hostip6
+ names.domainguid = domainguid
+ names.domainsid = domainsid
+ names.forestsid = domainsid
if serverrole is None:
serverrole = lp.get("server role")
if paths.sysvol and not os.path.exists(paths.sysvol):
os.makedirs(paths.sysvol, 0775)
- if not use_ntvfs and serverrole == "active directory domain controller":
- s3conf = s3param.get_context()
- s3conf.load(lp.configfile)
-
- if paths.sysvol is None:
- raise MissingShareError("sysvol", paths.smbconf)
-
- file = tempfile.NamedTemporaryFile(dir=os.path.abspath(paths.sysvol))
- try:
- try:
- smbd.set_simple_acl(file.name, 0755, root_gid)
- except Exception:
- if not smbd.have_posix_acls():
- # This clue is only strictly correct for RPM and
- # Debian-like Linux systems, but hopefully other users
- # will get enough clue from it.
- raise ProvisioningError("Samba was compiled without the posix ACL support that s3fs requires. Try installing libacl1-dev or libacl-devel, then re-run configure and make.")
-
- raise ProvisioningError("Your filesystem or build does not support posix ACLs, which s3fs requires. Try the mounting the filesystem with the 'acl' option.")
- try:
- smbd.chown(file.name, root_uid, root_gid)
- except Exception:
- raise ProvisioningError("Unable to chown a file on your filesystem. You may not be running provision as root.")
- finally:
- file.close()
-
ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="")
schema = Schema(domainsid, invocationid=invocationid,
if samdb_fill == FILL_FULL:
provision_fill(samdb, secrets_ldb, logger, names, paths,
schema=schema, targetdir=targetdir, samdb_fill=samdb_fill,
- hostip=hostip, hostip6=hostip6, domainsid=domainsid,
+ hostip=hostip, hostip6=hostip6,
next_rid=next_rid, dc_rid=dc_rid, adminpass=adminpass,
- krbtgtpass=krbtgtpass, domainguid=domainguid,
+ krbtgtpass=krbtgtpass,
policyguid=policyguid, policyguid_dc=policyguid_dc,
invocationid=invocationid, machinepass=machinepass,
ntdsguid=ntdsguid, dns_backend=dns_backend,
create_krb5_conf(paths.krb5conf,
dnsdomain=names.dnsdomain, hostname=names.hostname,
realm=names.realm)
- logger.info("A Kerberos configuration suitable for Samba 4 has been "
+ logger.info("A Kerberos configuration suitable for Samba AD has been "
"generated at %s", paths.krb5conf)
if serverrole == "active directory domain controller":