@@ -, +, @@ --- source3/smbd/pysmbd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) --- a/source3/smbd/pysmbd.c +++ a/source3/smbd/pysmbd.c @@ -147,7 +147,7 @@ static NTSTATUS set_nt_acl_conn(const char *fname, fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, 00400); } if (fsp->fh->fd == -1) { - printf("open: error=%d (%s)\n", errno, strerror(errno)); + DBG_WARNING("open: error=%d (%s)\n", errno, strerror(errno)); TALLOC_FREE(frame); umask(saved_umask); return NT_STATUS_UNSUCCESSFUL; @@ -156,10 +156,9 @@ static NTSTATUS set_nt_acl_conn(const char *fname, ret = SMB_VFS_FSTAT(fsp, &smb_fname->st); if (ret == -1) { /* If we have an fd, this stat should succeed. */ - DEBUG(0,("Error doing fstat on open file %s " - "(%s)\n", + DBG_WARNING("Error doing fstat on open file %s (%s)\n", smb_fname_str_dbg(smb_fname), - strerror(errno) )); + strerror(errno)); TALLOC_FREE(frame); umask(saved_umask); return map_nt_error_from_unix(errno); @@ -178,7 +177,8 @@ static NTSTATUS set_nt_acl_conn(const char *fname, status = SMB_VFS_FSET_NT_ACL( fsp, security_info_sent, sd); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("set_nt_acl_no_snum: fset_nt_acl returned %s.\n", nt_errstr(status))); + DBG_WARNING("set_nt_acl_no_snum: fset_nt_acl returned %s.\n", + nt_errstr(status)); } SMB_VFS_CLOSE(fsp); -- --- source3/smbd/pysmbd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- a/source3/smbd/pysmbd.c +++ a/source3/smbd/pysmbd.c @@ -150,7 +150,7 @@ static NTSTATUS set_nt_acl_conn(const char *fname, DBG_WARNING("open: error=%d (%s)\n", errno, strerror(errno)); TALLOC_FREE(frame); umask(saved_umask); - return NT_STATUS_UNSUCCESSFUL; + return map_nt_error_from_unix(errno); } ret = SMB_VFS_FSTAT(fsp, &smb_fname->st); -- --- python/samba/provision/__init__.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) --- a/python/samba/provision/__init__.py +++ a/python/samba/provision/__init__.py @@ -27,6 +27,7 @@ __docformat__ = "restructuredText" from base64 import b64encode +import ctypes import os import re import pwd @@ -50,6 +51,7 @@ from samba.dsdb import DS_DOMAIN_FUNCTION_2000 from samba import ( Ldb, MAX_NETBIOS_NAME_LEN, + NTSTATUSError, check_all_substituted, is_valid_netbios_char, setup_file, @@ -125,6 +127,8 @@ DEFAULT_DC_POLICY_GUID = "6AC1786C-016F-11D2-945F-00C04FB984F9" DEFAULTSITE = "Default-First-Site-Name" LAST_PROVISION_USN_ATTRIBUTE = "lastProvisionUSN" +NT_STATUS_OBJECT_NAME_NOT_FOUND = 0xc0000034 + class ProvisionPaths(object): @@ -1473,6 +1477,25 @@ 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)" SYSVOL_SERVICE="sysvol" +def set_nt_acl_wrapper(lp, file, sddl, domsid, backend=None, eadbfile=None, + use_ntvfs=True, skip_invalid_chown=False, passdb=None, service=None, + logger=None, resume_on_error=False): + """A wrapper around setntacl() that catches NTSTATUSError and only logs + them if a logger is given and resume_on_error is True. + """ + try: + setntacl(lp, file, sddl, domsid, backend=backend, eadbfile=eadbfile, + use_ntvfs=use_ntvfs, skip_invalid_chown=skip_invalid_chown, + passdb=passdb, service=service) + except NTSTATUSError as error: + err_value = ctypes.c_uint32(error[0]).value + only_log = err_value == NT_STATUS_OBJECT_NAME_NOT_FOUND + if resume_on_error and logger and only_log: + logger.warning('Unable to set ACL %s on %s' % (sddl, file)) + else: + raise + + 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()` --- python/samba/netcmd/ntacl.py | 8 ++--- python/samba/provision/__init__.py | 73 +++++++++++++++++++++++++------------- python/samba/upgrade.py | 9 ++--- 3 files changed, 57 insertions(+), 33 deletions(-) --- a/python/samba/netcmd/ntacl.py +++ a/python/samba/netcmd/ntacl.py @@ -233,10 +233,10 @@ class cmd_ntacl_sysvolreset(Command): if use_ntvfs: logger.warning("Please note that POSIX permissions have NOT been changed, only the stored NT ACL") - provision.setsysvolacl(samdb, netlogon, sysvol, - LA_uid, BA_gid, domain_sid, - lp.get("realm").lower(), samdb.domain_dn(), - lp, use_ntvfs=use_ntvfs) + provision.setsysvolacl(samdb, logger, netlogon, sysvol, LA_uid, BA_gid, + domain_sid, lp.get("realm").lower(), + samdb.domain_dn(), lp, use_ntvfs=use_ntvfs, + resume_on_error=False) class cmd_ntacl_sysvolcheck(Command): """Check sysvol ACLs match defaults (including correct ACLs on GPOs).""" --- a/python/samba/provision/__init__.py +++ a/python/samba/provision/__init__.py @@ -1496,33 +1496,45 @@ def set_nt_acl_wrapper(lp, file, sddl, domsid, backend=None, eadbfile=None, raise -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) +def set_dir_acl(path, acl, lp, domsid, use_ntvfs, passdb, service=SYSVOL_SERVICE, logger=None, resume_on_error=False): + set_nt_acl_wrapper(lp, path, acl, domsid, use_ntvfs=use_ntvfs, + skip_invalid_chown=True, passdb=passdb, service=service, + logger=logger, resume_on_error=resume_on_error) 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, skip_invalid_chown=True, passdb=passdb, service=service) + set_nt_acl_wrapper(lp, os.path.join(root, name), acl, domsid, + use_ntvfs=use_ntvfs, skip_invalid_chown=True, + passdb=passdb, service=service, logger=logger, + resume_on_error=resume_on_error) for name in dirs: - setntacl(lp, os.path.join(root, name), acl, domsid, - use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=passdb, service=service) + set_nt_acl_wrapper(lp, os.path.join(root, name), acl, domsid, + use_ntvfs=use_ntvfs, skip_invalid_chown=True, + passdb=passdb, service=service, logger=logger, + resume_on_error=resume_on_error) -def set_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp, use_ntvfs, passdb): +def set_gpos_acl(sysvol, logger, dnsdomain, domainsid, domaindn, samdb, lp, + use_ntvfs, passdb, resume_on_error): """Set ACL on the sysvol//Policies folder and the policy folders beneath. :param sysvol: Physical path for the sysvol folder + :param logger: Logger object :param dnsdomain: The DNS name of the domain :param domainsid: The SID of the domain :param domaindn: The DN of the domain (ie. DC=...) :param samdb: An LDB object on the SAM db :param lp: an LP object + :param resume_on_error: A boolean that indicates if the function should + only log a NTSTATUSError and continue. """ # 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, skip_invalid_chown=True, passdb=passdb, service=SYSVOL_SERVICE) + set_nt_acl_wrapper(lp, root_policy_path, POLICIES_ACL, str(domainsid), + use_ntvfs=use_ntvfs, skip_invalid_chown=True, + passdb=passdb, service=SYSVOL_SERVICE, logger=logger, + resume_on_error=resume_on_error) res = samdb.search(base="CN=Policies,CN=System,%s"%(domaindn), attrs=["cn", "nTSecurityDescriptor"], @@ -1534,14 +1546,16 @@ def set_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp, use_ntvfs, p policy_path = getpolicypath(sysvol, dnsdomain, str(policy["cn"])) set_dir_acl(policy_path, dsacl2fsacl(acl, domainsid), lp, str(domainsid), use_ntvfs, - passdb=passdb) + passdb=passdb, logger=logger, + resume_on_error=resume_on_error) -def setsysvolacl(samdb, netlogon, sysvol, uid, gid, domainsid, dnsdomain, - domaindn, lp, use_ntvfs): +def setsysvolacl(samdb, logger, netlogon, sysvol, uid, gid, domainsid, + dnsdomain, domaindn, lp, use_ntvfs, resume_on_error): """Set the ACL for the sysvol share and the subfolders :param samdb: An LDB object on the SAM db + :param logger: Logger object :param netlogon: Physical path for the netlogon folder :param sysvol: Physical path for the sysvol folder :param uid: The UID of the "Administrator" user @@ -1549,6 +1563,8 @@ def setsysvolacl(samdb, netlogon, sysvol, uid, gid, domainsid, dnsdomain, :param domainsid: The SID of the domain :param dnsdomain: The DNS name of the domain :param domaindn: The DN of the domain (ie. DC=...) + :param resume_on_error: A boolean that indicates if the function should + only log a NTSTATUSError and continue. """ s4_passdb = None @@ -1611,25 +1627,31 @@ def setsysvolacl(samdb, netlogon, sysvol, uid, gid, domainsid, dnsdomain, 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, - skip_invalid_chown=True, passdb=s4_passdb, - service=SYSVOL_SERVICE) + set_nt_acl_wrapper(lp, sysvol, SYSVOL_ACL, str(domainsid), + use_ntvfs=use_ntvfs, skip_invalid_chown=True, + passdb=s4_passdb, service=SYSVOL_SERVICE, logger=logger, + resume_on_error=resume_on_error) 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, skip_invalid_chown=True, - passdb=s4_passdb, service=SYSVOL_SERVICE) + set_nt_acl_wrapper(lp, os.path.join(root, name), SYSVOL_ACL, + str(domainsid), use_ntvfs=use_ntvfs, + skip_invalid_chown=True, passdb=s4_passdb, + service=SYSVOL_SERVICE, logger=logger, + resume_on_error=resume_on_error) 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, skip_invalid_chown=True, - passdb=s4_passdb, service=SYSVOL_SERVICE) + set_nt_acl_wrapper(lp, os.path.join(root, name), SYSVOL_ACL, + str(domainsid), use_ntvfs=use_ntvfs, + skip_invalid_chown=True, passdb=s4_passdb, + service=SYSVOL_SERVICE, logger=logger, + resume_on_error=resume_on_error) # Set acls on Policy folder and policies folders - set_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp, use_ntvfs, passdb=s4_passdb) + set_gpos_acl(sysvol, logger, dnsdomain, domainsid, domaindn, samdb, lp, + use_ntvfs, passdb=s4_passdb, resume_on_error=resume_on_error) def acl_type(direct_db_access): if direct_db_access: @@ -1824,9 +1846,10 @@ def provision_fill(samdb, secrets_ldb, logger, names, paths, # 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, names.domainsid, names.dnsdomain, - names.domaindn, lp, use_ntvfs) + setsysvolacl(samdb, logger, paths.netlogon, paths.sysvol, + paths.root_uid, paths.root_gid, names.domainsid, + names.dnsdomain, names.domaindn, lp, use_ntvfs, + resume_on_error=False) else: logger.info("Setting acl on sysvol skipped") --- a/python/samba/upgrade.py +++ a/python/samba/upgrade.py @@ -847,10 +847,11 @@ Please fix this account before attempting to upgrade again logger.info("Administrator password has been set to password of user '%s'", admin_user) if result.server_role == "active directory domain controller": - setsysvolacl(result.samdb, result.paths.netlogon, result.paths.sysvol, - result.paths.root_uid, result.paths.root_gid, - security.dom_sid(result.domainsid), result.names.dnsdomain, - result.names.domaindn, result.lp, use_ntvfs) + setsysvolacl(result.samdb, logger, result.paths.netlogon, + result.paths.sysvol, result.paths.root_uid, + result.paths.root_gid, security.dom_sid(result.domainsid), + result.names.dnsdomain, result.names.domaindn, result.lp, + use_ntvfs, resume_on_error=False) # FIXME: import_registry(registry.Registry(), samba3.get_registry()) # FIXME: shares -- sysvolreset --- python/samba/netcmd/ntacl.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) --- a/python/samba/netcmd/ntacl.py +++ a/python/samba/netcmd/ntacl.py @@ -183,10 +183,11 @@ class cmd_ntacl_sysvolreset(Command): takes_options = [ Option("--use-ntvfs", help="Set the ACLs for use with the ntvfs file server", action="store_true"), - Option("--use-s3fs", help="Set the ACLs for use with the default s3fs file server", action="store_true") + Option("--use-s3fs", help="Set the ACLs for use with the default s3fs file server", action="store_true"), + Option("--resume-on-error", help="Only log unsuccessful ACL operation and resume", action="store_true"), ] - def run(self, use_ntvfs=False, use_s3fs=False, + def run(self, use_ntvfs=False, use_s3fs=False, resume_on_error=False, credopts=None, sambaopts=None, versionopts=None): lp = sambaopts.get_loadparm() path = lp.private_path("secrets.ldb") @@ -236,7 +237,7 @@ class cmd_ntacl_sysvolreset(Command): provision.setsysvolacl(samdb, logger, netlogon, sysvol, LA_uid, BA_gid, domain_sid, lp.get("realm").lower(), samdb.domain_dn(), lp, use_ntvfs=use_ntvfs, - resume_on_error=False) + resume_on_error=resume_on_error) class cmd_ntacl_sysvolcheck(Command): """Check sysvol ACLs match defaults (including correct ACLs on GPOs).""" --