__docformat__ = "restructuredText"
from samba.compat import urllib_quote
+from samba.compat import string_types
+from samba.compat import binary_type
from base64 import b64encode
import errno
import os
import time
import uuid
import socket
-import string
import tempfile
import samba.dsdb
from samba.ntacls import setntacl, getntacl, dsacl2fsacl
from samba.ndr import ndr_pack, ndr_unpack
from samba.provision.backend import (
- ExistingBackend,
FDSBackend,
LDBBackend,
OpenLDAPBackend,
# netbiosname
# Get the netbiosname first (could be obtained from smb.conf in theory)
res = secretsdb.search(expression="(flatname=%s)" %
- names.domain,base="CN=Primary Domains",
+ names.domain, base="CN=Primary Domains",
scope=ldb.SCOPE_SUBTREE, attrs=["sAMAccountName"])
- names.netbiosname = str(res[0]["sAMAccountName"]).replace("$","")
+ names.netbiosname = str(res[0]["sAMAccountName"]).replace("$", "")
names.smbconf = smbconf
current = samdb.search(expression="(objectClass=*)",
base="", scope=ldb.SCOPE_BASE,
attrs=["defaultNamingContext", "schemaNamingContext",
- "configurationNamingContext","rootDomainNamingContext",
+ "configurationNamingContext", "rootDomainNamingContext",
"namingContexts"])
- names.configdn = current[0]["configurationNamingContext"][0]
- names.schemadn = current[0]["schemaNamingContext"][0]
+ names.configdn = str(current[0]["configurationNamingContext"][0])
+ names.schemadn = str(current[0]["schemaNamingContext"][0])
if not (ldb.Dn(samdb, basedn) == (ldb.Dn(samdb,
current[0]["defaultNamingContext"][0].decode('utf8')))):
raise ProvisioningError(("basedn in %s (%s) and from %s (%s)"
str(current[0]["defaultNamingContext"][0].decode('utf8')),
paths.smbconf, basedn)))
- names.domaindn = current[0]["defaultNamingContext"][0]
- names.rootdn = current[0]["rootDomainNamingContext"][0]
+ names.domaindn = str(current[0]["defaultNamingContext"][0])
+ names.rootdn = str(current[0]["rootDomainNamingContext"][0])
names.ncs = current[0]["namingContexts"]
names.dnsforestdn = None
names.dnsdomaindn = None
for i in range(0, len(names.ncs)):
- nc = names.ncs[i]
+ nc = str(names.ncs[i])
dnsforestdn = "DC=ForestDnsZones,%s" % (str(names.rootdn))
if nc == dnsforestdn:
# default site name
res3 = samdb.search(expression="(objectClass=site)",
- base="CN=Sites," + names.configdn, scope=ldb.SCOPE_ONELEVEL, attrs=["cn"])
+ base="CN=Sites," + str(names.configdn), scope=ldb.SCOPE_ONELEVEL, attrs=["cn"])
names.sitename = str(res3[0]["cn"])
# dns hostname and server dn
# domain guid/sid
res6 = samdb.search(expression="(objectClass=*)", base=basedn,
scope=ldb.SCOPE_BASE, attrs=["objectGUID",
- "objectSid","msDS-Behavior-Version"])
+ "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])
# policy guid
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("}","")
+ scope=ldb.SCOPE_ONELEVEL, attrs=["cn", "displayName"])
+ names.policyid = str(res7[0]["cn"]).replace("{", "").replace("}", "")
# dc policy guid
res8 = samdb.search(expression="(name={%s})" % DEFAULT_DC_POLICY_GUID,
base="CN=Policies,CN=System," + basedn,
scope=ldb.SCOPE_ONELEVEL,
- attrs=["cn","displayName"])
+ attrs=["cn", "displayName"])
if len(res8) == 1:
- names.policyid_dc = str(res8[0]["cn"]).replace("{","").replace("}","")
+ names.policyid_dc = str(res8[0]["cn"]).replace("{", "").replace("}", "")
else:
names.policyid_dc = None
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]
+ if str(res9[0]["type"][0]) == "ID_TYPE_BOTH":
+ names.root_gid = int(res9[0]["xidNumber"][0])
else:
names.root_gid = pwd.getpwuid(int(res9[0]["xidNumber"][0])).pw_gid
scope=ldb.SCOPE_BASE,
attrs=[LAST_PROVISION_USN_ATTRIBUTE, "dn"])
for e in entry[0][LAST_PROVISION_USN_ATTRIBUTE]:
- if not re.search(';', e):
- e = "%s;%s" % (e, id)
+ if not re.search(';', str(e)):
+ e = "%s;%s" % (str(e), id)
tab.append(str(e))
tab.append("%s-%s;%s" % (low, high, id))
samdb.add(delta)
-def get_max_usn(samdb,basedn):
+def get_max_usn(samdb, basedn):
""" This function return the biggest USN present in the provision
:param samdb: A LDB object pointing to the sam.ldb
(ie. DC=foo, DC=bar)
:return: The biggest USN in the provision"""
- res = samdb.search(expression="objectClass=*",base=basedn,
- scope=ldb.SCOPE_SUBTREE,attrs=["uSNChanged"],
+ res = samdb.search(expression="objectClass=*", base=basedn,
+ scope=ldb.SCOPE_SUBTREE, attrs=["uSNChanged"],
controls=["search_options:1:2",
"server_sort:1:1:uSNChanged",
"paged_results:1:1"])
return findnss(grp.getgrnam, names)[2]
+def get_root_uid(root, logger):
+ try:
+ root_uid = findnss_uid(root)
+ except KeyError as e:
+ logger.info(e)
+ logger.info("Assuming root user has UID zero")
+ root_uid = 0
+ return root_uid
+
+
def provision_paths_from_lp(lp, dnsdomain):
"""Set the default paths for provisioning.
if dnsdomain is None:
dnsdomain = lp.get("realm")
if dnsdomain is None or dnsdomain == "":
- raise ProvisioningError("guess_names: 'realm' not specified in supplied %s!", lp.configfile)
+ raise ProvisioningError(
+ "guess_names: 'realm' not specified in supplied %s!" %
+ lp.configfile)
dnsdomain = dnsdomain.lower()
return names
+
def make_smbconf(smbconf, hostname, domain, realm, targetdir,
serverrole=None, eadb=False, use_ntvfs=False, lp=None,
global_param=None):
if lp is None:
lp = samba.param.LoadParm()
- #Load non-existent file
+ # Load non-existent file
if os.path.exists(smbconf):
lp.load(smbconf)
global_settings["binddns dir"] = os.path.abspath(os.path.join(targetdir, "bind-dns"))
lp.set("lock dir", os.path.abspath(targetdir))
- lp.set("state directory", global_settings["state directory"])
+ lp.set("state directory", global_settings["state directory"])
lp.set("cache directory", global_settings["cache directory"])
lp.set("binddns dir", global_settings["binddns dir"])
"BACKEND_STORE": backend_store_line
})
-
setup_add_ldif(samdb, setup_path("provision_init.ldif"), {
"BACKEND_TYPE": provision_backend.type,
"SERVER_ROLE": serverrole,
if backend_credentials.get_bind_dn() is not None:
setup_add_ldif(secrets_ldb,
setup_path("secrets_simple_ldap.ldif"), {
- "LDAPMANAGERDN": backend_credentials.get_bind_dn(),
- "LDAPMANAGERPASS_B64": b64encode(backend_credentials.get_password()).decode('utf8')
- })
+ "LDAPMANAGERDN": backend_credentials.get_bind_dn(),
+ "LDAPMANAGERPASS_B64": b64encode(backend_credentials.get_password()).decode('utf8')
+ })
else:
setup_add_ldif(secrets_ldb,
setup_path("secrets_sasl_ldap.ldif"), {
- "LDAPADMINUSER": backend_credentials.get_username(),
- "LDAPADMINREALM": backend_credentials.get_realm(),
- "LDAPADMINPASS_B64": b64encode(backend_credentials.get_password()).decode('utf8')
- })
+ "LDAPADMINUSER": backend_credentials.get_username(),
+ "LDAPADMINREALM": backend_credentials.get_realm(),
+ "LDAPADMINPASS_B64": b64encode(backend_credentials.get_password()).decode('utf8')
+ })
except:
secrets_ldb.transaction_cancel()
raise
privilege_ldb.erase()
privilege_ldb.load_ldif_file_add(setup_path("provision_privilege.ldif"))
+
def setup_encrypted_secrets_key(path):
"""Setup the encrypted secrets key file.
finally:
os.umask(umask_original)
- with os.fdopen(fd, 'w') as f:
+ with os.fdopen(fd, 'wb') as f:
key = samba.generate_random_bytes(16)
f.write(key)
"""Join a host to its own domain."""
assert isinstance(invocationid, str)
if ntdsguid is not None:
- ntdsguid_line = "objectGUID: %s\n"%ntdsguid
+ ntdsguid_line = "objectGUID: %s\n" % ntdsguid
else:
ntdsguid_line = ""
"DOMAIN_CONTROLLER_FUNCTIONALITY": str(
domainControllerFunctionality)})
- # Setup fSMORoleOwner entries to point at the newly created DC entry
+ # Setup fSMORoleOwner entries to point at the newly created DC entry
+ setup_modify_ldif(samdb,
+ setup_path("provision_self_join_modify_schema.ldif"), {
+ "SCHEMADN": names.schemadn,
+ "SERVERDN": names.serverdn,
+ },
+ controls=["provision:0", "relax:0"])
setup_modify_ldif(samdb,
setup_path("provision_self_join_modify_config.ldif"), {
- "CONFIGDN": names.configdn,
- "SCHEMADN": names.schemadn,
- "DEFAULTSITE": names.sitename,
- "NETBIOSNAME": names.netbiosname,
- "SERVERDN": names.serverdn,
- })
+ "CONFIGDN": names.configdn,
+ "DEFAULTSITE": names.sitename,
+ "NETBIOSNAME": names.netbiosname,
+ "SERVERDN": names.serverdn,
+ })
system_session_info = system_session()
samdb.set_session_info(system_session_info)
:param policyguid: GUID of the default domain policy
:param policyguid_dc: GUID of the default domain controler policy
"""
- policy_path = getpolicypath(sysvolpath,dnsdomain,policyguid)
+ policy_path = getpolicypath(sysvolpath, dnsdomain, policyguid)
create_gpo_struct(policy_path)
- policy_path = getpolicypath(sysvolpath,dnsdomain,policyguid_dc)
+ policy_path = getpolicypath(sysvolpath, dnsdomain, policyguid_dc)
create_gpo_struct(policy_path)
# 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
+ schema_controls = [
+ "provision:0",
+ "relax:0",
+ ignore_checks_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.add_ldif(schema.schema_dn_add, controls=schema_controls)
+ samdb.modify_ldif(schema.schema_dn_modify, controls=schema_controls)
samdb.write_prefixes_from_schema()
- samdb.add_ldif(schema.schema_data, controls=["relax:0", ignore_checks_oid])
+ samdb.add_ldif(schema.schema_data, controls=schema_controls)
setup_add_ldif(samdb, setup_path("aggregate_schema.ldif"),
{"SCHEMADN": names.schemadn},
- controls=["relax:0", ignore_checks_oid])
+ controls=schema_controls)
# Now register this container in the root of the forest
msg = ldb.Message(ldb.Dn(samdb, names.domaindn))
setup_add_ldif(samdb, setup_path("extended-rights.ldif"), {
"CONFIGDN": names.configdn,
- "INC2012" : incl_2012,
+ "INC2012": incl_2012,
})
logger.info("Setting up display specifiers")
logger.info("Modifying display specifiers and extended rights")
setup_modify_ldif(samdb,
setup_path("provision_configuration_modify.ldif"), {
- "CONFIGDN": names.configdn,
- "DISPLAYSPECIFIERS_DESCRIPTOR": protected2_descr
- })
+ "CONFIGDN": names.configdn,
+ "DISPLAYSPECIFIERS_DESCRIPTOR": protected2_descr
+ })
logger.info("Adding users container")
users_desc = b64encode(get_domain_users_descriptor(names.domainsid)).decode('utf8')
logger.info("Modifying computers container")
setup_modify_ldif(samdb,
setup_path("provision_computers_modify.ldif"), {
- "DOMAINDN": names.domaindn})
+ "DOMAINDN": names.domaindn})
logger.info("Setting up sam.ldb data")
infrastructure_desc = b64encode(get_domain_infrastructure_descriptor(names.domainsid)).decode('utf8')
lostandfound_desc = b64encode(get_domain_delete_protected2_descriptor(names.domainsid)).decode('utf8')
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)
+ attribute="objectGUID", expression="", scope=ldb.SCOPE_BASE).decode('utf8')
+ assert isinstance(names.ntdsguid, string_types)
return samdb
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, 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):
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),
+ res = samdb.search(base="CN=Policies,CN=System,%s" %(domaindn),
attrs=["cn", "nTSecurityDescriptor"],
expression="", scope=ldb.SCOPE_ONELEVEL)
for policy in res:
acl = ndr_unpack(security.descriptor,
- str(policy["nTSecurityDescriptor"])).as_sddl()
+ policy["nTSecurityDescriptor"][0]).as_sddl()
policy_path = getpolicypath(sysvol, dnsdomain, str(policy["cn"]))
set_dir_acl(policy_path, dsacl2fsacl(acl, domainsid), lp,
str(domainsid), use_ntvfs,
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()))
-
try:
if use_ntvfs:
os.chown(sysvol, -1, gid)
# Set acls on Policy folder and policies folders
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 "DB"
else:
return "VFS"
+
def check_dir_acl(path, acl, lp, domainsid, direct_db_access):
fsacl = getntacl(lp, path, direct_db_access=direct_db_access, service=SYSVOL_SERVICE)
fsacl_sddl = fsacl.as_sddl(domainsid)
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)))
+ raise ProvisioningError('%s ACL on GPO file %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_sddl, acl))
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)))
+ raise ProvisioningError('%s ACL on GPO directory %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_sddl, acl))
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), root_policy_path, fsacl_sddl, fsacl))
- res = samdb.search(base="CN=Policies,CN=System,%s"%(domaindn),
+ res = samdb.search(base="CN=Policies,CN=System,%s" %(domaindn),
attrs=["cn", "nTSecurityDescriptor"],
expression="", scope=ldb.SCOPE_ONELEVEL)
for policy in res:
acl = ndr_unpack(security.descriptor,
- str(policy["nTSecurityDescriptor"])).as_sddl()
+ policy["nTSecurityDescriptor"][0]).as_sddl()
policy_path = getpolicypath(sysvol, dnsdomain, str(policy["cn"]))
check_dir_acl(policy_path, dsacl2fsacl(acl, domainsid), lp,
domainsid, direct_db_access)
direct_db_access)
-def interface_ips_v4(lp):
+def interface_ips_v4(lp, all_interfaces=False):
"""return only IPv4 IPs"""
- ips = samba.interface_ips(lp, False)
+ ips = samba.interface_ips(lp, all_interfaces)
ret = []
for i in ips:
if i.find(':') == -1:
backend_store=backend_store)
domainguid = samdb.searchone(basedn=samdb.get_default_basedn(),
- attribute="objectGUID")
- assert isinstance(domainguid, str)
+ attribute="objectGUID").decode('utf8')
+ assert isinstance(domainguid, string_types)
lastProvisionUSNs = get_last_provision_usn(samdb)
maxUSN = get_max_usn(samdb, str(names.rootdn))
else:
samdb.transaction_commit()
+
def directory_create_or_exists(path, mode=0o755):
if not os.path.exists(path):
try:
else:
raise ProvisioningError("Failed to create directory %s: %s" % (path, e.strerror))
+
def determine_host_ip(logger, lp, hostip=None):
if hostip is None:
logger.info("Looking up IPv4 addresses")
return hostip
+
def determine_host_ip6(logger, lp, hostip6=None):
if hostip6 is None:
logger.info("Looking up IPv6 addresses")
return hostip6
+
def provision(logger, session_info, smbconf=None,
targetdir=None, samdb_fill=FILL_FULL, realm=None, rootdn=None,
domaindn=None, schemadn=None, configdn=None, serverdn=None,
if domainsid is None:
domainsid = security.random_sid()
- root_uid = findnss_uid([root or "root"])
+ root_uid = get_root_uid([root or "root"], logger)
nobody_uid = findnss_uid([nobody or "nobody"])
users_gid = findnss_gid([users or "users", 'users', 'other', 'staff'])
root_gid = pwd.getpwuid(root_uid).pw_gid
paths = provision_paths_from_lp(lp, names.dnsdomain)
paths.bind_gid = bind_gid
- paths.root_uid = root_uid;
+ paths.root_uid = root_uid
paths.root_gid = root_gid
hostip = determine_host_ip(logger, lp, hostip)
provision_backend = LDBBackend(backend_type, paths=paths,
lp=lp,
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
- provision_backend = ExistingBackend(backend_type, paths=paths,
- lp=lp,
- names=names, logger=logger,
- ldap_backend_forced_uri=ldap_backend_forced_uri)
elif backend_type == "fedora-ds":
provision_backend = FDSBackend(backend_type, paths=paths,
lp=lp,
adminpass = samba.generate_random_password(12, 32)
adminpass_generated = True
else:
- adminpass = unicode(adminpass, 'utf-8')
+ if isinstance(adminpass, binary_type):
+ adminpass = adminpass.decode('utf-8')
adminpass_generated = False
if samdb_fill == FILL_FULL: