summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--selftest/target/Samba4.pm3
-rw-r--r--source4/scripting/python/samba/ntacls.py70
-rw-r--r--source4/scripting/python/samba/provision/__init__.py74
3 files changed, 94 insertions, 53 deletions
diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index 248a7259f7..7ac337425b 100644
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -534,6 +534,7 @@ sub provision_raw_prepare($$$$$$$$$$)
push (@provision_options, "--server-role=\"$ctx->{server_role}\"");
push (@provision_options, "--function-level=\"$ctx->{functional_level}\"");
push (@provision_options, "--dns-backend=BIND9_DLZ");
+
if ($use_ntvfs) {
push (@provision_options, "--use-ntvfs");
}
@@ -1205,7 +1206,7 @@ sub provision_fl2000dc($$)
"samba2000.example.com",
"2000",
"locDCpass5",
- undef, "", 1);
+ undef, "", "", 1);
unless($self->add_wins_config("$prefix/private")) {
warn("Unable to add wins configuration");
diff --git a/source4/scripting/python/samba/ntacls.py b/source4/scripting/python/samba/ntacls.py
index e3d24fa365..64dfd17d64 100644
--- a/source4/scripting/python/samba/ntacls.py
+++ b/source4/scripting/python/samba/ntacls.py
@@ -23,6 +23,7 @@ import os
import samba.xattr_native, samba.xattr_tdb, samba.posix_eadb
from samba.dcerpc import security, xattr
from samba.ndr import ndr_pack, ndr_unpack
+from samba.samba3 import smbd
class XattrBackendError(Exception):
"""A generic xattr backend error."""
@@ -55,44 +56,51 @@ def checkset_backend(lp, backend, eadbfile):
def getntacl(lp, file, backend=None, eadbfile=None):
- (backend_obj, dbname) = checkset_backend(lp, backend, eadbfile)
- if dbname is not None:
- try:
- attribute = backend_obj.wrap_getxattr(dbname, file,
- xattr.XATTR_NTACL_NAME)
- except Exception:
- # FIXME: Don't catch all exceptions, just those related to opening
- # xattrdb
- print "Fail to open %s" % dbname
+ if use_ntvfs:
+ (backend_obj, dbname) = checkset_backend(lp, backend, eadbfile)
+ if dbname is not None:
+ try:
+ attribute = backend_obj.wrap_getxattr(dbname, file,
+ xattr.XATTR_NTACL_NAME)
+ except Exception:
+ # FIXME: Don't catch all exceptions, just those related to opening
+ # xattrdb
+ print "Fail to open %s" % dbname
+ attribute = samba.xattr_native.wrap_getxattr(file,
+ xattr.XATTR_NTACL_NAME)
+ else:
attribute = samba.xattr_native.wrap_getxattr(file,
- xattr.XATTR_NTACL_NAME)
+ xattr.XATTR_NTACL_NAME)
+ ntacl = ndr_unpack(xattr.NTACL, attribute)
+ return ntacl
else:
- attribute = samba.xattr_native.wrap_getxattr(file,
- xattr.XATTR_NTACL_NAME)
- ntacl = ndr_unpack(xattr.NTACL, attribute)
- return ntacl
+ return smbd.get_nt_acl(file)
-def setntacl(lp, file, sddl, domsid, backend=None, eadbfile=None):
- (backend_obj, dbname) = checkset_backend(lp, backend, eadbfile)
- ntacl = xattr.NTACL()
- ntacl.version = 1
+def setntacl(lp, file, sddl, domsid, backend=None, eadbfile=None, use_ntvfs=True):
sid = security.dom_sid(domsid)
sd = security.descriptor.from_sddl(sddl, sid)
- ntacl.info = sd
- if dbname is not None:
- try:
- backend_obj.wrap_setxattr(dbname,
- file, xattr.XATTR_NTACL_NAME, ndr_pack(ntacl))
- except Exception:
- # FIXME: Don't catch all exceptions, just those related to opening
- # xattrdb
- print "Fail to open %s" % dbname
- samba.xattr_native.wrap_setxattr(file, xattr.XATTR_NTACL_NAME,
- ndr_pack(ntacl))
+
+ if use_ntvfs:
+ (backend_obj, dbname) = checkset_backend(lp, backend, eadbfile)
+ ntacl = xattr.NTACL()
+ ntacl.version = 1
+ ntacl.info = sd
+ if dbname is not None:
+ try:
+ backend_obj.wrap_setxattr(dbname,
+ file, xattr.XATTR_NTACL_NAME, ndr_pack(ntacl))
+ except Exception:
+ # FIXME: Don't catch all exceptions, just those related to opening
+ # xattrdb
+ print "Fail to open %s" % dbname
+ samba.xattr_native.wrap_setxattr(file, xattr.XATTR_NTACL_NAME,
+ ndr_pack(ntacl))
+ else:
+ samba.xattr_native.wrap_setxattr(file, xattr.XATTR_NTACL_NAME,
+ ndr_pack(ntacl))
else:
- samba.xattr_native.wrap_setxattr(file, xattr.XATTR_NTACL_NAME,
- ndr_pack(ntacl))
+ smbd.set_nt_acl(file, security.SECINFO_OWNER | security.SECINFO_GROUP | security.SECINFO_DACL, sd)
def ldapmask2filemask(ldm):
diff --git a/source4/scripting/python/samba/provision/__init__.py b/source4/scripting/python/samba/provision/__init__.py
index 02ebf68310..fd71631ee7 100644
--- a/source4/scripting/python/samba/provision/__init__.py
+++ b/source4/scripting/python/samba/provision/__init__.py
@@ -44,7 +44,8 @@ import ldb
from samba.auth import system_session, admin_session
import samba
-from samba.samba3 import smbd
+from samba.samba3 import smbd, passdb
+from samba.samba3 import param as s3param
from samba.dsdb import DS_DOMAIN_FUNCTION_2000
from samba import (
Ldb,
@@ -1359,16 +1360,16 @@ SYSVOL_ACL = "O:LAG:BAD:P(A;OICI;0x001f01ff;;;BA)(A;OICI;0x001200a9;;;SO)(A;OICI
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)"
-def set_dir_acl(path, acl, lp, domsid):
- setntacl(lp, path, acl, domsid)
+def set_dir_acl(path, acl, lp, domsid, use_ntvfs):
+ setntacl(lp, path, acl, domsid, use_ntvfs=use_ntvfs)
for root, dirs, files in os.walk(path, topdown=False):
for name in files:
- setntacl(lp, os.path.join(root, name), acl, domsid)
+ setntacl(lp, os.path.join(root, name), acl, domsid, use_ntvfs=use_ntvfs)
for name in dirs:
- setntacl(lp, os.path.join(root, name), acl, domsid)
+ setntacl(lp, os.path.join(root, name), acl, domsid, use_ntvfs=use_ntvfs)
-def set_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp):
+def set_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp, use_ntvfs):
"""Set ACL on the sysvol/<dnsname>/Policies folder and the policy
folders beneath.
@@ -1382,7 +1383,7 @@ def set_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp):
# Set ACL for GPO root folder
root_policy_path = os.path.join(sysvol, dnsdomain, "Policies")
- setntacl(lp, root_policy_path, POLICIES_ACL, str(domainsid))
+ setntacl(lp, root_policy_path, POLICIES_ACL, str(domainsid), use_ntvfs=use_ntvfs)
res = samdb.search(base="CN=Policies,CN=System,%s"%(domaindn),
attrs=["cn", "nTSecurityDescriptor"],
@@ -1393,11 +1394,11 @@ def set_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp):
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))
+ str(domainsid), use_ntvfs)
-def setsysvolacl(samdb, netlogon, sysvol, gid, domainsid, dnsdomain, domaindn,
- lp):
+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
@@ -1409,27 +1410,49 @@ def setsysvolacl(samdb, netlogon, sysvol, gid, domainsid, dnsdomain, domaindn,
:param domaindn: The DN of the domain (ie. DC=...)
"""
+ if not use_ntvfs:
+ # 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 samba4 passdb backend, no matter what
+ s3conf.set("passdb backend", "samba4:%s" % samdb.url)
+ # ensure that we init the samba4 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
+ if passdb.get_global_sam_sid() != domainsid:
+ raise ProvisioningError('SID as seen by smbd [%s] does not match SID as seen by the provision script [%s]!' % (passdb.get_global_sam_sid(), domainsid))
+
+ domain_info = s4_passdb.domain_info()
+ if domain_info["dom_sid"] != domainsid:
+ raise ProvisioningError('SID as seen by pdb_samba4 [%s] does not match SID as seen by the provision script [%s]!' % (domain_info["dom_sid"], domainsid))
+
+ if domain_info["dns_domain"].upper() != dnsdomain.upper():
+ raise ProvisioningError('Realm as seen by pdb_samba4 [%s] does not match Realm as seen by the provision script [%s]!' % (domain_info["dns_domain"].upper(), dnsdomain.upper()))
+
+
try:
- os.chown(sysvol, -1, gid)
+ if use_ntvfs:
+ os.chown(sysvol, -1, gid)
except OSError:
canchown = False
else:
canchown = True
# Set the SYSVOL_ACL on the sysvol folder and subfolder (first level)
- setntacl(lp,sysvol, SYSVOL_ACL, str(domainsid))
+ setntacl(lp,sysvol, SYSVOL_ACL, str(domainsid), use_ntvfs=use_ntvfs)
for root, dirs, files in os.walk(sysvol, topdown=False):
for name in files:
- if canchown:
+ 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))
+ setntacl(lp, os.path.join(root, name), SYSVOL_ACL, str(domainsid), use_ntvfs=use_ntvfs)
for name in dirs:
- if canchown:
+ 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))
+ setntacl(lp, os.path.join(root, name), SYSVOL_ACL, str(domainsid), use_ntvfs=use_ntvfs)
# Set acls on Policy folder and policies folders
- set_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp)
+ set_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp, use_ntvfs)
def interface_ips_v4(lp):
@@ -1460,7 +1483,7 @@ def provision_fill(samdb, secrets_ldb, logger, names, paths,
invocationid=None, machinepass=None, ntdsguid=None,
dns_backend=None, dnspass=None,
serverrole=None, dom_for_fun_level=None,
- am_rodc=False, lp=None):
+ am_rodc=False, lp=None, use_ntvfs=False):
# create/adapt the group policy GUIDs
# Default GUID for default policy are described at
# "How Core Group Policy Works"
@@ -1492,12 +1515,13 @@ def provision_fill(samdb, secrets_ldb, logger, names, paths,
next_rid=next_rid, dc_rid=dc_rid)
if serverrole == "active directory domain controller":
+
# Set up group policies (domain policy and domain controller
# policy)
create_default_gpo(paths.sysvol, names.dnsdomain, policyguid,
policyguid_dc)
- setsysvolacl(samdb, paths.netlogon, paths.sysvol, paths.wheel_gid,
- domainsid, names.dnsdomain, names.domaindn, lp)
+ setsysvolacl(samdb, paths.netlogon, paths.sysvol, paths.root_uid, paths.wheel_gid,
+ domainsid, names.dnsdomain, names.domaindn, lp, use_ntvfs)
secretsdb_self_join(secrets_ldb, domain=names.domain,
realm=names.realm, dnsdomain=names.dnsdomain,
@@ -1719,6 +1743,7 @@ def provision(logger, session_info, credentials, smbconf=None,
paths = provision_paths_from_lp(lp, names.dnsdomain)
paths.bind_gid = bind_gid
+ paths.root_uid = root_uid;
paths.wheel_gid = wheel_gid
if hostip is None:
@@ -1761,6 +1786,9 @@ def provision(logger, session_info, credentials, smbconf=None,
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)
@@ -1776,6 +1804,10 @@ def provision(logger, session_info, credentials, smbconf=None,
smbd.set_simple_acl(file.name, root_uid, wheel_gid)
except Exception:
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)
+ except Exception:
+ raise ProvisioningError("Unable to chown a file on your filesystem. You may not be running provision as root. ")
finally:
file.close()
@@ -1871,7 +1903,7 @@ def provision(logger, session_info, credentials, smbconf=None,
ntdsguid=ntdsguid, dns_backend=dns_backend,
dnspass=dnspass, serverrole=serverrole,
dom_for_fun_level=dom_for_fun_level, am_rodc=am_rodc,
- lp=lp)
+ lp=lp, use_ntvfs=use_ntvfs)
create_krb5_conf(paths.krb5conf,
dnsdomain=names.dnsdomain, hostname=names.hostname,