-
# Unix SMB/CIFS implementation.
# backend code for provisioning a Samba4 server
OpenLDAPBackend,
)
from samba.provision.descriptor import (
+ get_empty_descriptor,
get_config_descriptor,
- get_domain_descriptor
+ get_config_partitions_descriptor,
+ get_config_sites_descriptor,
+ get_config_delete_protected1_descriptor,
+ get_config_delete_protected1wd_descriptor,
+ get_config_delete_protected2_descriptor,
+ get_domain_descriptor,
+ get_domain_infrastructure_descriptor,
+ get_domain_builtin_descriptor,
+ get_domain_computers_descriptor,
+ get_domain_users_descriptor,
+ get_domain_controllers_descriptor,
+ get_domain_delete_protected1_descriptor,
+ get_domain_delete_protected2_descriptor,
+ get_dns_partition_descriptor,
)
from samba.provision.common import (
setup_path,
self.winsdb = None
self.private_dir = None
self.state_dir = None
- self.phpldapadminconfig = None
class ProvisionNames(object):
def __init__(self):
+ self.ncs = None
self.rootdn = None
self.domaindn = None
self.configdn = None
self.schemadn = None
+ self.dnsforestdn = None
+ self.dnsdomaindn = None
self.ldapmanagerdn = None
self.dnsdomain = None
self.realm = None
self.sitename = None
self.smbconf = None
-def find_provision_key_parameters(samdb, secretsdb, idmapdb, paths, smbconf, lp):
+
+def find_provision_key_parameters(samdb, secretsdb, idmapdb, paths, smbconf,
+ lp):
"""Get key provision parameters (realm, domain, ...) from a given provision
:param samdb: An LDB object connected to the sam.ldb file
current = samdb.search(expression="(objectClass=*)",
base="", scope=ldb.SCOPE_BASE,
attrs=["defaultNamingContext", "schemaNamingContext",
- "configurationNamingContext","rootDomainNamingContext"])
+ "configurationNamingContext","rootDomainNamingContext",
+ "namingContexts"])
names.configdn = current[0]["configurationNamingContext"]
configdn = str(names.configdn)
names.domaindn=current[0]["defaultNamingContext"]
names.rootdn=current[0]["rootDomainNamingContext"]
+ names.ncs=current[0]["namingContexts"]
+ names.dnsforestdn = None
+ names.dnsdomaindn = None
+
+ for i in range(0, len(names.ncs)):
+ nc = names.ncs[i]
+
+ dnsforestdn = "DC=ForestDnsZones,%s" % (str(names.rootdn))
+ if nc == dnsforestdn:
+ names.dnsforestdn = dnsforestdn
+ continue
+
+ dnsdomaindn = "DC=DomainDnsZones,%s" % (str(names.domaindn))
+ if nc == dnsdomaindn:
+ names.dnsdomaindn = dnsdomaindn
+ continue
+
# default site name
res3 = samdb.search(expression="(objectClass=site)",
base="CN=Sites," + configdn, scope=ldb.SCOPE_ONELEVEL, attrs=["cn"])
res4 = samdb.search(expression="(CN=%s)" % names.netbiosname,
base="OU=Domain Controllers,%s" % basedn,
scope=ldb.SCOPE_ONELEVEL, attrs=["dNSHostName"])
- names.hostname = str(res4[0]["dNSHostName"]).replace("." + names.dnsdomain,"")
+ names.hostname = str(res4[0]["dNSHostName"]).replace("." + names.dnsdomain, "")
server_res = samdb.search(expression="serverReference=%s" % res4[0].dn,
attrs=[], base=configdn)
# invocation id/objectguid
res5 = samdb.search(expression="(objectClass=*)",
- base="CN=NTDS Settings,%s" % str(names.serverdn), scope=ldb.SCOPE_BASE,
+ base="CN=NTDS Settings,%s" % str(names.serverdn),
+ scope=ldb.SCOPE_BASE,
attrs=["invocationID", "objectGUID"])
names.invocation = str(ndr_unpack(misc.GUID, res5[0]["invocationId"][0]))
names.ntdsguid = str(ndr_unpack(misc.GUID, res5[0]["objectGUID"][0]))
res8 = samdb.search(expression="(displayName=Default Domain Controllers"
" Policy)",
base="CN=Policies,CN=System," + basedn,
- scope=ldb.SCOPE_ONELEVEL, attrs=["cn","displayName"])
+ scope=ldb.SCOPE_ONELEVEL,
+ attrs=["cn","displayName"])
if len(res8) == 1:
names.policyid_dc = str(res8[0]["cn"]).replace("{","").replace("}","")
else:
names.policyid_dc = None
- res9 = idmapdb.search(expression="(cn=%s)" %
- (security.SID_BUILTIN_ADMINISTRATORS),
- attrs=["xidNumber"])
- if len(res9) == 1:
- names.wheel_gid = res9[0]["xidNumber"]
+
+ res9 = idmapdb.search(expression="(cn=%s-%s)" %
+ (str(names.domainsid), security.DOMAIN_RID_ADMINISTRATOR),
+ attrs=["xidNumber", "type"])
+ if len(res9) != 1:
+ raise ProvisioningError("Unable to find uid/gid for Domain Admins rid (%s-%s" % (str(names.domainsid), security.DOMAIN_RID_ADMINISTRATOR))
+ if res9[0]["type"][0] == "ID_TYPE_BOTH":
+ names.root_gid = res9[0]["xidNumber"][0]
else:
- raise ProvisioningError("Unable to find uid/gid for Domain Admins rid")
+ names.root_gid = pwd.getpwuid(int(res9[0]["xidNumber"][0])).pw_gid
return names
"""Get USNs ranges modified by a provision or an upgradeprovision
:param sam: An LDB object pointing to the sam.ldb
- :return: a dictionnary which keys are invocation id and values are an array
+ :return: a dictionary which keys are invocation id and values are an array
of integer representing the different ranges
"""
try:
entry = sam.search(expression="%s=*" % LAST_PROVISION_USN_ATTRIBUTE,
- base="@PROVISION", scope=ldb.SCOPE_BASE,
- attrs=[LAST_PROVISION_USN_ATTRIBUTE, "provisionnerID"])
+ base="@PROVISION", scope=ldb.SCOPE_BASE,
+ attrs=[LAST_PROVISION_USN_ATTRIBUTE, "provisionnerID"])
except ldb.LdbError, (ecode, emsg):
if ecode == ldb.ERR_NO_SUCH_OBJECT:
return None
raise
- if len(entry):
+ if len(entry) > 0:
myids = []
range = {}
p = re.compile(r'-')
if (len(myids) > 0 and id not in myids):
continue
tab2 = p.split(tab1[0])
- if range.get(id) == None:
+ if range.get(id) is None:
range[id] = []
range[id].append(tab2[0])
range[id].append(tab2[1])
logger.info("DNS Domain: %s", self.names.dnsdomain)
logger.info("DOMAIN SID: %s", self.domainsid)
- if self.paths.phpldapadminconfig is not None:
- logger.info(
- "A phpLDAPadmin configuration file suitable for administering "
- "the Samba 4 LDAP server has been created in %s.",
- self.paths.phpldapadminconfig)
-
if self.backend_result:
self.backend_result.report_logger(logger)
paths.krb5conf = os.path.join(paths.private_dir, "krb5.conf")
paths.winsdb = os.path.join(paths.private_dir, "wins.ldb")
paths.s4_ldapi_path = os.path.join(paths.private_dir, "ldapi")
- paths.phpldapadminconfig = os.path.join(paths.private_dir,
- "phpldapadmin-config.php")
paths.hklm = "hklm.ldb"
paths.hkcr = "hkcr.ldb"
paths.hkcu = "hkcu.ldb"
def setup_name_mappings(idmap, sid, root_uid, nobody_uid,
- users_gid, wheel_gid):
+ users_gid, root_gid):
"""setup reasonable name mappings for sam names to unix names.
:param samdb: SamDB object.
:param root_uid: uid of the UNIX root user.
:param nobody_uid: uid of the UNIX nobody user.
:param users_gid: gid of the UNIX users group.
- :param wheel_gid: gid of the UNIX wheel group.
+ :param root_gid: gid of the UNIX root group.
"""
idmap.setup_name_mapping("S-1-5-7", idmap.TYPE_UID, nobody_uid)
- idmap.setup_name_mapping("S-1-5-32-544", idmap.TYPE_GID, wheel_gid)
idmap.setup_name_mapping(sid + "-500", idmap.TYPE_UID, root_uid)
idmap.setup_name_mapping(sid + "-513", idmap.TYPE_GID, users_gid)
def setup_self_join(samdb, admin_session_info, names, fill, machinepass,
- dnspass, domainsid, next_rid, invocationid, policyguid, policyguid_dc,
+ dns_backend, dnspass, domainsid, next_rid, invocationid,
+ policyguid, policyguid_dc,
domainControllerFunctionality, ntdsguid=None, dc_rid=None):
"""Join a host to its own domain."""
assert isinstance(invocationid, str)
samdb.set_session_info(admin_session_info)
- # This is Samba4 specific and should be replaced by the correct
- # DNS AD-style setup
- setup_add_ldif(samdb, setup_path("provision_dns_add_samba.ldif"), {
+ if dns_backend != "SAMBA_INTERNAL":
+ # This is Samba4 specific and should be replaced by the correct
+ # DNS AD-style setup
+ setup_add_ldif(samdb, setup_path("provision_dns_add_samba.ldif"), {
"DNSDOMAIN": names.dnsdomain,
"DOMAINDN": names.domaindn,
"DNSPASS_B64": b64encode(dnspass.encode('utf-16-le')),
return samdb
-def fill_samdb(samdb, lp, names,
- logger, domainsid, domainguid, policyguid, policyguid_dc, fill,
- adminpass, krbtgtpass, machinepass, invocationid, dnspass, ntdsguid,
- serverrole, am_rodc=False, dom_for_fun_level=None, schema=None,
- next_rid=None, dc_rid=None):
+def fill_samdb(samdb, lp, names, logger, domainsid, domainguid, 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):
if next_rid is None:
next_rid = 1000
# 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))
setup_add_ldif(samdb, setup_path("provision_configuration.ldif"), {
"CONFIGDN": names.configdn,
"NETBIOSNAME": names.netbiosname,
"SERVERDN": names.serverdn,
"FOREST_FUNCTIONALITY": str(forestFunctionality),
"DOMAIN_FUNCTIONALITY": str(domainFunctionality),
+ "PARTITIONS_DESCRIPTOR": partitions_descr,
+ "SITES_DESCRIPTOR": sites_descr,
})
logger.info("Setting up display specifiers")
samdb.add_ldif(display_specifiers_ldif)
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})
+ "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"), {
- "DOMAINDN": names.domaindn})
+ "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(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,
"CONFIGDN": names.configdn,
"SERVERDN": names.serverdn,
"RIDAVAILABLESTART": str(next_rid + 600),
- "POLICYGUID_DC": policyguid_dc
+ "POLICYGUID_DC": policyguid_dc,
+ "INFRASTRUCTURE_DESCRIPTOR": infrastructure_desc,
+ "BUILTIN_DESCRIPTOR": builtin_desc,
+ "DOMAIN_CONTROLLERS_DESCRIPTOR": controllers_desc,
})
# If we are setting up a subdomain, then this has been replicated in, so we don't need to add it
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,
FILL_DRS = "DRS"
SYSVOL_ACL = "O:LAG:BAD:P(A;OICI;0x001f01ff;;;BA)(A;OICI;0x001200a9;;;SO)(A;OICI;0x001f01ff;;;SY)(A;OICI;0x001200a9;;;AU)"
POLICIES_ACL = "O:LAG:BAD:P(A;OICI;0x001f01ff;;;BA)(A;OICI;0x001200a9;;;SO)(A;OICI;0x001f01ff;;;SY)(A;OICI;0x001200a9;;;AU)(A;OICI;0x001301bf;;;PA)"
+SYSVOL_SERVICE="sysvol"
-
-def set_dir_acl(path, acl, lp, domsid, use_ntvfs):
- setntacl(lp, path, acl, domsid, use_ntvfs=use_ntvfs)
+def set_dir_acl(path, acl, lp, domsid, use_ntvfs, passdb, service=SYSVOL_SERVICE):
+ setntacl(lp, path, acl, domsid, use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=passdb, service=service)
for root, dirs, files in os.walk(path, topdown=False):
for name in files:
- setntacl(lp, os.path.join(root, name), acl, domsid, use_ntvfs=use_ntvfs)
+ setntacl(lp, os.path.join(root, name), acl, domsid,
+ use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=passdb, service=service)
for name in dirs:
- setntacl(lp, os.path.join(root, name), acl, domsid, use_ntvfs=use_ntvfs)
+ setntacl(lp, os.path.join(root, name), acl, domsid,
+ use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=passdb, service=service)
-def set_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp, use_ntvfs):
+def set_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp, use_ntvfs, passdb):
"""Set ACL on the sysvol/<dnsname>/Policies folder and the policy
folders beneath.
# Set ACL for GPO root folder
root_policy_path = os.path.join(sysvol, dnsdomain, "Policies")
- setntacl(lp, root_policy_path, POLICIES_ACL, str(domainsid), use_ntvfs=use_ntvfs)
+ setntacl(lp, root_policy_path, POLICIES_ACL, str(domainsid),
+ use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=passdb, service=SYSVOL_SERVICE)
res = samdb.search(base="CN=Policies,CN=System,%s"%(domaindn),
attrs=["cn", "nTSecurityDescriptor"],
acl = ndr_unpack(security.descriptor,
str(policy["nTSecurityDescriptor"])).as_sddl()
policy_path = getpolicypath(sysvol, dnsdomain, str(policy["cn"]))
- set_dir_acl(policy_path, dsacl2fsacl(acl, str(domainsid)), lp,
- str(domainsid), use_ntvfs)
+ set_dir_acl(policy_path, dsacl2fsacl(acl, domainsid), lp,
+ str(domainsid), use_ntvfs,
+ passdb=passdb)
-def setsysvolacl(samdb, netlogon, sysvol, uid, gid, domainsid, dnsdomain, domaindn,
- lp, use_ntvfs):
+def setsysvolacl(samdb, netlogon, sysvol, uid, gid, domainsid, dnsdomain,
+ domaindn, lp, use_ntvfs):
"""Set the ACL for the sysvol share and the subfolders
:param samdb: An LDB object on the SAM db
:param dnsdomain: The DNS name of the domain
:param domaindn: The DN of the domain (ie. DC=...)
"""
+ s4_passdb = None
if not use_ntvfs:
- # This will ensure that the smbd code we are running when setting ACLs is initialised with the smb.conf
+ # This will ensure that the smbd code we are running when setting ACLs
+ # is initialised with the smb.conf
s3conf = s3param.get_context()
s3conf.load(lp.configfile)
# ensure we are using the right samba_dsdb passdb backend, no matter what
s3conf.set("passdb backend", "samba_dsdb:%s" % samdb.url)
passdb.reload_static_pdb()
- # ensure that we init the samba_dsdb backend, so the domain sid is marked in secrets.tdb
+ # ensure that we init the samba_dsdb backend, so the domain sid is
+ # marked in secrets.tdb
s4_passdb = passdb.PDB(s3conf.get("passdb backend"))
# now ensure everything matches correctly, to avoid wierd issues
canchown = True
# Set the SYSVOL_ACL on the sysvol folder and subfolder (first level)
- setntacl(lp,sysvol, SYSVOL_ACL, str(domainsid), use_ntvfs=use_ntvfs)
+ setntacl(lp,sysvol, SYSVOL_ACL, str(domainsid), use_ntvfs=use_ntvfs,
+ skip_invalid_chown=True, passdb=s4_passdb,
+ service=SYSVOL_SERVICE)
for root, dirs, files in os.walk(sysvol, topdown=False):
for name in files:
if use_ntvfs and canchown:
os.chown(os.path.join(root, name), -1, gid)
- setntacl(lp, os.path.join(root, name), SYSVOL_ACL, str(domainsid), use_ntvfs=use_ntvfs)
+ setntacl(lp, os.path.join(root, name), SYSVOL_ACL, str(domainsid),
+ use_ntvfs=use_ntvfs, skip_invalid_chown=True,
+ passdb=s4_passdb, service=SYSVOL_SERVICE)
for name in dirs:
if use_ntvfs and canchown:
os.chown(os.path.join(root, name), -1, gid)
- setntacl(lp, os.path.join(root, name), SYSVOL_ACL, str(domainsid), use_ntvfs=use_ntvfs)
+ setntacl(lp, os.path.join(root, name), SYSVOL_ACL, str(domainsid),
+ use_ntvfs=use_ntvfs, skip_invalid_chown=True,
+ passdb=s4_passdb, service=SYSVOL_SERVICE)
# Set acls on Policy folder and policies folders
- set_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp, use_ntvfs)
+ set_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp, use_ntvfs, passdb=s4_passdb)
def acl_type(direct_db_access):
if direct_db_access:
return "VFS"
def check_dir_acl(path, acl, lp, domainsid, direct_db_access):
- fsacl = getntacl(lp, path, direct_db_access=direct_db_access)
+ fsacl = getntacl(lp, path, direct_db_access=direct_db_access, service=SYSVOL_SERVICE)
fsacl_sddl = fsacl.as_sddl(domainsid)
if fsacl_sddl != acl:
raise ProvisioningError('%s ACL on GPO directory %s %s does not match expected value %s from GPO object' % (acl_type(direct_db_access), path, fsacl_sddl, acl))
-
+
for root, dirs, files in os.walk(path, topdown=False):
for name in files:
- fsacl = getntacl(lp, os.path.join(root, name), direct_db_access=direct_db_access)
+ fsacl = getntacl(lp, os.path.join(root, name),
+ direct_db_access=direct_db_access, service=SYSVOL_SERVICE)
if fsacl is None:
raise ProvisioningError('%s ACL on GPO file %s %s not found!' % (acl_type(direct_db_access), os.path.join(root, name)))
fsacl_sddl = fsacl.as_sddl(domainsid)
if fsacl_sddl != acl:
- raise ProvisioningError('%s ACL on GPO file %s %s does not match expected value %s from GPO object' % (acl_type(direct_db_access), os.path.join(root, name), fsacl, acl))
+ raise ProvisioningError('%s ACL on GPO file %s %s does not match expected value %s from GPO object' % (acl_type(direct_db_access), os.path.join(root, name), fsacl_sddl, acl))
- for name in files:
- fsacl = getntacl(lp, os.path.join(root, name), direct_db_access=direct_db_access)
+ for name in dirs:
+ fsacl = getntacl(lp, os.path.join(root, name),
+ direct_db_access=direct_db_access, service=SYSVOL_SERVICE)
if fsacl is None:
raise ProvisioningError('%s ACL on GPO directory %s %s not found!' % (acl_type(direct_db_access), os.path.join(root, name)))
fsacl_sddl = fsacl.as_sddl(domainsid)
if fsacl_sddl != acl:
- raise ProvisioningError('%s ACL on GPO directory %s %s does not match expected value %s from GPO object' % (acl_type(direct_db_access), os.path.join(root, name), fsacl, acl))
+ raise ProvisioningError('%s ACL on GPO directory %s %s does not match expected value %s from GPO object' % (acl_type(direct_db_access), os.path.join(root, name), fsacl_sddl, acl))
-def check_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp, direct_db_access):
+def check_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp,
+ direct_db_access):
"""Set ACL on the sysvol/<dnsname>/Policies folder and the policy
folders beneath.
# Set ACL for GPO root folder
root_policy_path = os.path.join(sysvol, dnsdomain, "Policies")
- fsacl = getntacl(lp, root_policy_path, direct_db_access=direct_db_access)
+ fsacl = getntacl(lp, root_policy_path,
+ direct_db_access=direct_db_access, service=SYSVOL_SERVICE)
if fsacl is None:
raise ProvisioningError('DB ACL on policy root %s %s not found!' % (acl_type(direct_db_access), root_policy_path))
fsacl_sddl = fsacl.as_sddl(domainsid)
if fsacl_sddl != POLICIES_ACL:
- raise ProvisioningError('%s ACL on policy root %s %s does not match expected value %s from provision' % (acl_type(direct_db_access), policy_root, fsacl_sddl, acl))
+ raise ProvisioningError('%s ACL on policy root %s %s does not match expected value %s from provision' % (acl_type(direct_db_access), root_policy_path, fsacl_sddl, fsacl))
res = samdb.search(base="CN=Policies,CN=System,%s"%(domaindn),
attrs=["cn", "nTSecurityDescriptor"],
expression="", scope=ldb.SCOPE_ONELEVEL)
acl = ndr_unpack(security.descriptor,
str(policy["nTSecurityDescriptor"])).as_sddl()
policy_path = getpolicypath(sysvol, dnsdomain, str(policy["cn"]))
- check_dir_acl(policy_path, dsacl2fsacl(acl, str(domainsid)), lp,
+ check_dir_acl(policy_path, dsacl2fsacl(acl, domainsid), lp,
domainsid, direct_db_access)
if domain_info["dns_domain"].upper() != dnsdomain.upper():
raise ProvisioningError('Realm as seen by pdb_samba_dsdb [%s] does not match Realm as seen by the provision script [%s]!' % (domain_info["dns_domain"].upper(), dnsdomain.upper()))
- # Set the SYSVOL_ACL on the sysvol folder and subfolder (first level)
+ # Ensure we can read this directly, and via the smbd VFS
for direct_db_access in [True, False]:
+ # Check the SYSVOL_ACL on the sysvol folder and subfolder (first level)
for dir_path in [os.path.join(sysvol, dnsdomain), netlogon]:
- fsacl = getntacl(lp, dir_path, direct_db_access=direct_db_access)
+ fsacl = getntacl(lp, dir_path, direct_db_access=direct_db_access, service=SYSVOL_SERVICE)
if fsacl is None:
raise ProvisioningError('%s ACL on sysvol directory %s not found!' % (acl_type(direct_db_access), dir_path))
fsacl_sddl = fsacl.as_sddl(domainsid)
raise ProvisioningError('%s ACL on sysvol directory %s %s does not match expected value %s from provision' % (acl_type(direct_db_access), dir_path, fsacl_sddl, SYSVOL_ACL))
# Check acls on Policy folder and policies folders
- check_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp, direct_db_access)
+ check_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp,
+ direct_db_access)
def interface_ips_v4(lp):
- '''return only IPv4 IPs'''
+ """return only IPv4 IPs"""
ips = samba.interface_ips(lp, False)
ret = []
for i in ips:
ret.append(i)
return ret
+
def interface_ips_v6(lp, linklocal=False):
- '''return only IPv6 IPs'''
+ """return only IPv6 IPs"""
ips = samba.interface_ips(lp, False)
ret = []
for i in ips:
invocationid=None, machinepass=None, ntdsguid=None,
dns_backend=None, dnspass=None,
serverrole=None, dom_for_fun_level=None,
- am_rodc=False, lp=None, use_ntvfs=False, skip_sysvolacl=True):
+ am_rodc=False, lp=None, use_ntvfs=False, skip_sysvolacl=False):
# create/adapt the group policy GUIDs
# Default GUID for default policy are described at
# "How Core Group Policy Works"
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,
- 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)
+ 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":
create_default_gpo(paths.sysvol, names.dnsdomain, policyguid,
policyguid_dc)
if not skip_sysvolacl:
- setsysvolacl(samdb, paths.netlogon, paths.sysvol, paths.root_uid, paths.wheel_gid,
- domainsid, names.dnsdomain, names.domaindn, lp, use_ntvfs)
+ setsysvolacl(samdb, paths.netlogon, paths.sysvol, paths.root_uid,
+ paths.root_gid, 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,
- machinepass=machinepass, secure_channel_type=SEC_CHAN_BDC)
+ realm=names.realm, dnsdomain=names.dnsdomain,
+ netbiosname=names.netbiosname, domainsid=domainsid,
+ machinepass=machinepass, secure_channel_type=SEC_CHAN_BDC)
# Now set up the right msDS-SupportedEncryptionTypes into the DB
# In future, this might be determined from some configuration
# provision code
for schema_obj in ['CN=Domain', 'CN=Organizational-Person', 'CN=Contact', 'CN=inetOrgPerson']:
chk.check_database(DN="%s,%s" % (schema_obj, names.schemadn),
- scope=ldb.SCOPE_BASE, attrs=['defaultObjectCategory'])
+ scope=ldb.SCOPE_BASE,
+ attrs=['defaultObjectCategory'])
chk.check_database(DN="CN=IP Security,CN=System,%s" % names.domaindn,
scope=ldb.SCOPE_ONELEVEL,
attrs=['ipsecOwnersReference',
"active directory domain controller", "standalone server")
"""
try:
- return _ROLES_MAP[role]
+ return _ROLES_MAP[role]
except KeyError:
raise ValueError(role)
-def provision_fake_ypserver(logger, samdb, domaindn, netbiosname, nisdomain, maxuid, maxgid):
- """Creates AD entries for the fake ypserver
- needed for being able to manipulate posix attrs via ADUC
+
+def provision_fake_ypserver(logger, samdb, domaindn, netbiosname, nisdomain,
+ maxuid, maxgid):
+ """Create AD entries for the fake ypserver.
+
+ This is needed for being able to manipulate posix attrs via ADUC.
"""
samdb.transaction_start()
try:
"NETBIOSNAME": netbiosname,
"NISDOMAIN": nisdomain,
})
- except Exception:
+ except:
samdb.transaction_cancel()
raise
else:
samdb.transaction_commit()
- if maxuid != None:
- pass
- if maxgid != None:
- pass
+
def provision(logger, session_info, credentials, smbconf=None,
targetdir=None, samdb_fill=FILL_FULL, realm=None, rootdn=None,
domaindn=None, schemadn=None, configdn=None, serverdn=None,
domain=None, hostname=None, hostip=None, hostip6=None, domainsid=None,
- next_rid=1000, dc_rid=None, adminpass=None, ldapadminpass=None, krbtgtpass=None,
- domainguid=None, policyguid=None, policyguid_dc=None,
- dns_backend=None, dnspass=None,
+ next_rid=1000, dc_rid=None, adminpass=None, ldapadminpass=None,
+ krbtgtpass=None, domainguid=None, policyguid=None, policyguid_dc=None,
+ dns_backend=None, dns_forwarder=None, dnspass=None,
invocationid=None, machinepass=None, ntdsguid=None,
- root=None, nobody=None, users=None, wheel=None, backup=None, aci=None,
- serverrole=None, dom_for_fun_level=None,
- backend_type=None, sitename=None,
- ol_mmr_urls=None, ol_olc=None, slapd_path="/bin/false",
- useeadb=False, am_rodc=False,
- lp=None, use_ntvfs=False,
- use_rfc2307=False, maxuid=None, maxgid=None,
- skip_sysvolacl=True):
+ root=None, nobody=None, users=None, backup=None, aci=None,
+ serverrole=None, dom_for_fun_level=None, backend_type=None,
+ sitename=None, ol_mmr_urls=None, ol_olc=None, slapd_path="/bin/false",
+ useeadb=False, am_rodc=False, lp=None, use_ntvfs=False,
+ use_rfc2307=False, maxuid=None, maxgid=None, skip_sysvolacl=True):
"""Provision samba4
:note: caution, this wipes all existing data!
root_uid = findnss_uid([root or "root"])
nobody_uid = findnss_uid([nobody or "nobody"])
users_gid = findnss_gid([users or "users", 'users', 'other', 'staff'])
- if wheel is None:
- wheel_gid = findnss_gid(["wheel", "adm"])
- else:
- wheel_gid = findnss_gid([wheel])
+ root_gid = pwd.getpwuid(root_uid).pw_gid
+
try:
bind_gid = findnss_gid(["bind", "named"])
except KeyError:
if use_rfc2307:
global_param["idmap_ldb:use rfc2307"] = ["yes"]
- if dns_backend == "SAMBA_INTERNAL":
- server_services.append("+dns")
+ if dns_backend != "SAMBA_INTERNAL":
+ server_services.append("-dns")
+ else:
+ if dns_forwarder is not None:
+ global_param["dns forwarder"] = [dns_forwarder]
if use_ntvfs:
server_services.append("+smb")
paths.bind_gid = bind_gid
paths.root_uid = root_uid;
- paths.wheel_gid = wheel_gid
+ paths.root_gid = root_gid
if hostip is None:
logger.info("Looking up IPv4 addresses")
if paths.sysvol is None:
raise MissingShareError("sysvol", paths.smbconf)
- 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.")
-
file = tempfile.NamedTemporaryFile(dir=os.path.abspath(paths.sysvol))
try:
try:
- smbd.set_simple_acl(file.name, 0755, wheel_gid)
+ 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, wheel_gid)
+ 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. ")
+ raise ProvisioningError("Unable to chown a file on your filesystem. You may not be running provision as root.")
finally:
file.close()
lp=lp, credentials=credentials,
names=names, logger=logger)
elif backend_type == "existing":
- # If support for this is ever added back, then the URI will need to be specified again
+ # If support for this is ever added back, then the URI will need to be
+ # specified again
provision_backend = ExistingBackend(backend_type, paths=paths,
lp=lp, credentials=credentials,
names=names, logger=logger,
setup_name_mappings(idmap, sid=str(domainsid),
root_uid=root_uid, nobody_uid=nobody_uid,
- users_gid=users_gid, wheel_gid=wheel_gid)
+ users_gid=users_gid, root_gid=root_gid)
logger.info("Setting up SAM db")
samdb = setup_samdb(paths.samdb, session_info,
backend_result = provision_backend.post_setup()
provision_backend.shutdown()
- create_phpldapadmin_config(paths.phpldapadminconfig,
- ldapi_url)
except:
secrets_ldb.transaction_cancel()
raise
result.backend_result = backend_result
if use_rfc2307:
- provision_fake_ypserver(logger=logger, samdb=samdb, domaindn=names.domaindn, netbiosname=names.netbiosname,
- nisdomain=(names.domain).lower(), maxuid=maxuid, maxgid=maxgid)
+ provision_fake_ypserver(logger=logger, samdb=samdb,
+ domaindn=names.domaindn, netbiosname=names.netbiosname,
+ nisdomain=names.domain.lower(), maxuid=maxuid, maxgid=maxgid)
return result
serverdn=None, domain=None, hostname=None, domainsid=None,
adminpass=None, krbtgtpass=None, domainguid=None, policyguid=None,
policyguid_dc=None, invocationid=None, machinepass=None, dnspass=None,
- dns_backend=None, root=None, nobody=None, users=None, wheel=None,
+ dns_backend=None, root=None, nobody=None, users=None,
backup=None, serverrole=None, ldap_backend=None,
ldap_backend_type=None, sitename=None, debuglevel=1, use_ntvfs=False):
realm=realm, rootdn=rootdn, domaindn=domaindn, schemadn=schemadn,
configdn=configdn, serverdn=serverdn, domain=domain,
hostname=hostname, hostip=None, domainsid=domainsid,
- machinepass=machinepass, serverrole="active directory domain controller",
- sitename=sitename, dns_backend=dns_backend, dnspass=dnspass, use_ntvfs=use_ntvfs)
+ machinepass=machinepass,
+ serverrole="active directory domain controller",
+ sitename=sitename, dns_backend=dns_backend, dnspass=dnspass,
+ use_ntvfs=use_ntvfs)
res.lp.set("debuglevel", str(debuglevel))
return res
-def create_phpldapadmin_config(path, ldapi_uri):
- """Create a PHP LDAP admin configuration file.
-
- :param path: Path to write the configuration to.
- """
- setup_file(setup_path("phpldapadmin-config.php"), path,
- {"S4_LDAPI_URI": ldapi_uri})
-
-
def create_krb5_conf(path, dnsdomain, hostname, realm):
"""Write out a file containing zone statements suitable for inclusion in a
named.conf file (including GSS-TSIG configuration).