[SCM] Samba Shared Repository - branch master updated
Stefan Metzmacher
metze at samba.org
Mon Mar 25 06:26:02 MDT 2013
The branch, master has been updated
via 30adf0c scripting: Fill the ProvisionNames hash with strings, not ldb.MessageElement or Dn
via 5d42260 samba-tool ldapcmp: Remove the GUID -> name mappings
via 1589e46 selftest: Add tests for samba-tool dbcheck --reset-well-known-acls
via 874a93b scripting: Modify samba.descriptor.get_diff_sds() to cope with a missing reference owner
via 4789a30 samba-tool dbcheck: Allow dbcheck to correct an nTSecurityDescriptor without an owner or group
via 810f8b4 samba-tool dbcheck: Add --reset-well-known-acls
via 9040e26 scripting: Move get_diff_sds from samba.upgradehelpers to samba.descriptor
via a113ddb scripting: Modify samba.descriptor.get_wellknown_sds() use samdb calls only
via 352aff8 scripting: Move samba.provision.descriptor to samba.descriptor
via e81a97d scripting: Make samba.provision.descriptor.get_wellknown_sds() return ldb.Dn objects
via 6df17fe scripting: Fix documentation comment on upgradehelpers.py:get_clean_sd
via 3da89b0 scripting: Move the list of well known SDs to samba.provision.descriptor
via afe9343 build: Do not pass CPP="" to pidl, skip the env variable entirely
via 7dc6dfd build: Remove the forced use of only the first part of the compiler string
from d27f00c vfs-btrfs: Fix build on 32 bit platforms by using long long types
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 30adf0cdbae6d9aaf2e72513d9c33267248f20c0
Author: Andrew Bartlett <abartlet at samba.org>
Date: Fri Mar 22 21:58:25 2013 +1100
scripting: Fill the ProvisionNames hash with strings, not ldb.MessageElement or Dn
This avoids the need to fix it up again in samba_upgradedns.
Andrew Bartlett
Reviewed-by: Stefan Metzmacher <metze at samba.org>
Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
Autobuild-Date(master): Mon Mar 25 13:25:30 CET 2013 on sn-devel-104
commit 5d42260eecfd4f26cc82637ce1bc989083c9eb9d
Author: Andrew Bartlett <abartlet at samba.org>
Date: Fri Mar 22 21:36:49 2013 +1100
samba-tool ldapcmp: Remove the GUID -> name mappings
These mappings are very convenient, however because they are not
one-to-one, they lead to differences being reported when none exist,
dependent only on the order the schema searches return results in.
Sadly the time saved by the names is offset by the time wasted chasing
the 'differences' that don't exist.
This in turn fixes some tests that were previously knownfail
Andrew Bartlett
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 1589e46d11f29551f3598876b62e29fcbad06580
Author: Andrew Bartlett <abartlet at samba.org>
Date: Fri Mar 22 17:12:43 2013 +1100
selftest: Add tests for samba-tool dbcheck --reset-well-known-acls
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 874a93bc1c437543474a6c574b0065b7b953ad38
Author: Andrew Bartlett <abartlet at samba.org>
Date: Fri Mar 22 22:16:03 2013 +1100
scripting: Modify samba.descriptor.get_diff_sds() to cope with a missing reference owner
This allows the reference SD not to have an owner specified, and still
have the comparison with a database SD that does have an owner pass.
(And the same for owning group).
Andrew Bartlett
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 4789a3072a4241841c096115dbdb0c3259968e68
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon Feb 11 14:49:01 2013 +1100
samba-tool dbcheck: Allow dbcheck to correct an nTSecurityDescriptor without an owner or group
This is done by making a modification to the SD, which triggers it to be
filled in if we have the correct session_info established on the DB.
However, we normally want dbcheck running as system, so we wrap
the session_info set around this operation only.
Andrew Bartlett
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 810f8b48d925ea15f3439c4b228741d8fddaccd8
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon Feb 11 14:49:01 2013 +1100
samba-tool dbcheck: Add --reset-well-known-acls
This will allow an upgrade from Samba 4.0.0 without needing to run
samba_upgradeprovision, which for now is not the preferred upgrade
tool.
Andrew Bartlett
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 9040e2684161ce75738e9da0fee191aa34858607
Author: Andrew Bartlett <abartlet at samba.org>
Date: Fri Mar 22 16:19:27 2013 +1100
scripting: Move get_diff_sds from samba.upgradehelpers to samba.descriptor
This helps avoid a dependency loop when we use get_diff_sds in dbcheck.
Andrew Bartlett
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit a113ddbf881c5905bbf7072638c7ba8843eeb85e
Author: Andrew Bartlett <abartlet at samba.org>
Date: Fri Mar 22 11:15:38 2013 +1100
scripting: Modify samba.descriptor.get_wellknown_sds() use samdb calls only
We need this routine not to use the names context as this is tied to
provision, and we end up in a circular dependency if we use that in
dbcheck.
Andrew Bartlett
commit 352aff8ed7e06c14b7a00a56b31c79ffddf71dd4
Author: Andrew Bartlett <abartlet at samba.org>
Date: Thu Mar 21 13:34:26 2013 +1100
scripting: Move samba.provision.descriptor to samba.descriptor
This will allow dbcheck to import it, without a cirucular dependency via
samba.provision importing dbcheck.
Andrew Bartlett
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit e81a97dd6fc2da701f2cbf42513311a7a44adad3
Author: Andrew Bartlett <abartlet at samba.org>
Date: Thu Mar 21 12:49:46 2013 +1100
scripting: Make samba.provision.descriptor.get_wellknown_sds() return ldb.Dn objects
As we look to use this function in more places, it does not make sense to constantly create
Dn objects from the strings.
Andrew Bartlett
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 6df17fe799968ca7e2f92ce9e294e3962ac8cbaf
Author: Andrew Bartlett <abartlet at samba.org>
Date: Wed Mar 20 14:50:55 2013 +1100
scripting: Fix documentation comment on upgradehelpers.py:get_clean_sd
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 3da89b01faebba669434b07db344c203a4521ca2
Author: Andrew Bartlett <abartlet at samba.org>
Date: Wed Mar 20 14:12:26 2013 +1100
scripting: Move the list of well known SDs to samba.provision.descriptor
This will allow us to call this from dbcheck.
Andrew Bartlett
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit afe9343880ee27cf9fe937c6379c469435ef20d6
Author: Andrew Bartlett <abartlet at samba.org>
Date: Fri Mar 22 13:47:46 2013 +1100
build: Do not pass CPP="" to pidl, skip the env variable entirely
This will cause pidl to use $CC -E instead.
Andrew Bartlett
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 7dc6dfd90c5182ed85042b22d4864d3e9b007531
Author: Andrew Bartlett <abartlet at samba.org>
Date: Fri Mar 22 13:06:43 2013 +1100
build: Remove the forced use of only the first part of the compiler string
This corrects parts of 378295c3fe813c70815a14c7de608e4a859bd6cc and
301d59caf2ee6f49e108b748b0e38221dec9bb96. This is seen if CC="ccache
gcc" and CPP isn't used for some reason.
Andrew Bartlett
Reviewed-by: Stefan Metzmacher <metze at samba.org>
-----------------------------------------------------------------------
Summary of changes:
buildtools/wafsamba/samba_pidl.py | 6 +-
python/samba/dbchecker.py | 107 ++++++++++-
python/samba/{provision => }/descriptor.py | 222 +++++++++++++++++++++
python/samba/netcmd/dbcheck.py | 7 +-
python/samba/netcmd/ldapcmp.py | 47 +----
python/samba/provision/__init__.py | 17 +-
python/samba/provision/sambadns.py | 2 +-
python/samba/tests/upgradeprovision.py | 4 +-
python/samba/upgradehelpers.py | 158 ---------------
selftest/knownfail | 7 +-
source4/scripting/bin/samba_upgradedns | 16 +--
source4/scripting/bin/samba_upgradeprovision | 80 +-------
testprogs/blackbox/dbcheck-oldrelease.sh | 64 ++++++-
testprogs/blackbox/dbcheck.sh | 6 +
testprogs/blackbox/upgradeprovision-oldrelease.sh | 10 +
15 files changed, 437 insertions(+), 316 deletions(-)
rename python/samba/{provision => }/descriptor.py (67%)
Changeset truncated at 500 lines:
diff --git a/buildtools/wafsamba/samba_pidl.py b/buildtools/wafsamba/samba_pidl.py
index 4056359..2393c72 100644
--- a/buildtools/wafsamba/samba_pidl.py
+++ b/buildtools/wafsamba/samba_pidl.py
@@ -59,9 +59,9 @@ def SAMBA_PIDL(bld, pname, source,
# the cd .. is needed because pidl currently is sensitive to the directory it is run in
cpp = ""
cc = ""
- if bld.CONFIG_SET("CPP"):
+ if bld.CONFIG_SET("CPP") and bld.CONFIG_GET("CPP") != "":
if isinstance(bld.CONFIG_GET("CPP"), list):
- cpp = 'CPP="%s"' % bld.CONFIG_GET("CPP")[0]
+ cpp = 'CPP="%s"' % " ".join(bld.CONFIG_GET("CPP"))
else:
cpp = 'CPP="%s"' % bld.CONFIG_GET("CPP")
@@ -71,7 +71,7 @@ def SAMBA_PIDL(bld, pname, source,
if bld.CONFIG_SET("CC"):
if isinstance(bld.CONFIG_GET("CC"), list):
- cc = 'CC="%s"' % bld.CONFIG_GET("CC")[0]
+ cc = 'CC="%s"' % " ".join(bld.CONFIG_GET("CC"))
else:
cc = 'CC="%s"' % bld.CONFIG_GET("CC")
diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py
index fd42a78..d0d0ab3 100644
--- a/python/samba/dbchecker.py
+++ b/python/samba/dbchecker.py
@@ -25,13 +25,16 @@ from samba.ndr import ndr_unpack, ndr_pack
from samba.dcerpc import drsblobs
from samba.common import dsdb_Dn
from samba.dcerpc import security
+from samba.descriptor import get_wellknown_sds, get_diff_sds
+from samba.auth import system_session, admin_session
class dbcheck(object):
"""check a SAM database for errors"""
def __init__(self, samdb, samdb_schema=None, verbose=False, fix=False,
- yes=False, quiet=False, in_transaction=False):
+ yes=False, quiet=False, in_transaction=False,
+ reset_well_known_acls=False):
self.samdb = samdb
self.dict_oid_name = None
self.samdb_schema = (samdb_schema or samdb)
@@ -52,9 +55,12 @@ class dbcheck(object):
self.fix_all_orphaned_backlinks = False
self.fix_rmd_flags = False
self.fix_ntsecuritydescriptor = False
+ self.fix_ntsecuritydescriptor_owner_group = False
self.seize_fsmo_role = False
self.move_to_lost_and_found = False
self.fix_instancetype = False
+ self.reset_well_known_acls = reset_well_known_acls
+ self.reset_all_well_known_acls = False
self.in_transaction = in_transaction
self.infrastructure_dn = ldb.Dn(samdb, "CN=Infrastructure," + samdb.domain_dn())
self.naming_dn = ldb.Dn(samdb, "CN=Partitions,%s" % samdb.get_config_basedn())
@@ -62,6 +68,21 @@ class dbcheck(object):
self.rid_dn = ldb.Dn(samdb, "CN=RID Manager$,CN=System," + samdb.domain_dn())
self.ntds_dsa = ldb.Dn(samdb, samdb.get_dsServiceName())
self.class_schemaIDGUID = {}
+ self.wellknown_sds = get_wellknown_sds(self.samdb)
+
+ self.name_map = {}
+ try:
+ res = samdb.search(base="CN=DnsAdmins,CN=Users,%s" % samdb.domain_dn(), scope=ldb.SCOPE_BASE,
+ attrs=["objectSid"])
+ dnsadmins_sid = ndr_unpack(security.dom_sid, res[0]["objectSid"][0])
+ self.name_map['DnsAdmins'] = str(dnsadmins_sid)
+ except ldb.LdbError, (enum, estr):
+ if enum != ldb.ERR_NO_SUCH_OBJECT:
+ raise
+ pass
+
+ self.system_session_info = system_session()
+ self.admin_session_info = admin_session(None, samdb.get_domain_sid())
res = self.samdb.search(base=self.ntds_dsa, scope=ldb.SCOPE_BASE, attrs=['msDS-hasMasterNCs', 'hasMasterNCs'])
if "msDS-hasMasterNCs" in res[0]:
@@ -739,8 +760,61 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
nmsg.dn = dn
nmsg[sd_attr] = ldb.MessageElement(sd_val, ldb.FLAG_MOD_REPLACE, sd_attr)
if self.do_modify(nmsg, ["sd_flags:1:%d" % sd_flags],
+ "Failed to fix attribute %s" % sd_attr):
+ self.report("Fixed attribute '%s' of '%s'\n" % (sd_attr, dn))
+
+ def err_wrong_default_sd(self, dn, sd, sd_old, diff):
+ '''re-write the SD due to not matching the default (optional mode for fixing an incorrect provision)'''
+ sd_attr = "nTSecurityDescriptor"
+ sd_val = ndr_pack(sd)
+ sd_old_val = ndr_pack(sd_old)
+ sd_flags = security.SECINFO_DACL | security.SECINFO_SACL
+ if sd.owner_sid is not None:
+ sd_flags |= security.SECINFO_OWNER
+ if sd.group_sid is not None:
+ sd_flags |= security.SECINFO_GROUP
+
+ if not self.confirm_all('Reset %s on %s back to provision default?\n%s' % (sd_attr, dn, diff), 'reset_all_well_known_acls'):
+ self.report('Not resetting %s on %s\n' % (sd_attr, dn))
+ return
+
+ m = ldb.Message()
+ m.dn = dn
+ m[sd_attr] = ldb.MessageElement(sd_val, ldb.FLAG_MOD_REPLACE, sd_attr)
+ if self.do_modify(m, ["sd_flags:1:%d" % sd_flags],
+ "Failed to reset attribute %s" % sd_attr):
+ self.report("Fixed attribute '%s' of '%s'\n" % (sd_attr, dn))
+
+ def err_missing_sd_owner(self, dn, sd):
+ '''re-write the SD due to a missing owner or group'''
+ sd_attr = "nTSecurityDescriptor"
+ sd_val = ndr_pack(sd)
+ sd_flags = security.SECINFO_OWNER | security.SECINFO_GROUP
+
+ if not self.confirm_all('Fix missing owner or group in %s on %s?' % (sd_attr, dn), 'fix_ntsecuritydescriptor_owner_group'):
+ self.report('Not fixing missing owner or group %s on %s\n' % (sd_attr, dn))
+ return
+
+ nmsg = ldb.Message()
+ nmsg.dn = dn
+ nmsg[sd_attr] = ldb.MessageElement(sd_val, ldb.FLAG_MOD_REPLACE, sd_attr)
+
+ # By setting the session_info to admin_session_info and
+ # setting the security.SECINFO_OWNER | security.SECINFO_GROUP
+ # flags we cause the descriptor module to set the correct
+ # owner and group on the SD, replacing the None/NULL values
+ # for owner_sid and group_sid currently present.
+ #
+ # The admin_session_info matches that used in provision, and
+ # is the best guess we can make for an existing object that
+ # hasn't had something specifically set.
+ #
+ # This is important for the dns related naming contexts.
+ self.samdb.set_session_info(self.admin_session_info)
+ if self.do_modify(nmsg, ["sd_flags:1:%d" % sd_flags],
"Failed to fix metadata for attribute %s" % sd_attr):
self.report("Fixed attribute '%s' of '%s'\n" % (sd_attr, dn))
+ self.samdb.set_session_info(self.system_session_info)
def is_fsmo_role(self, dn):
if dn == self.samdb.domain_dn:
@@ -774,6 +848,16 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
return instancetype
+ def get_wellknown_sd(self, dn):
+ for [sd_dn, descriptor_fn] in self.wellknown_sds:
+ if dn == sd_dn:
+ domain_sid = security.dom_sid(self.samdb.get_domain_sid())
+ return ndr_unpack(security.descriptor,
+ descriptor_fn(domain_sid,
+ name_map=self.name_map))
+
+ raise KeyError
+
def check_object(self, dn, attrs=['*']):
'''check one object'''
if self.verbose:
@@ -826,6 +910,27 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
if sd_broken is not None:
self.err_wrong_sd(dn, sd, sd_broken)
error_count += 1
+ continue
+
+ if sd.owner_sid is None or sd.group_sid is None:
+ self.err_missing_sd_owner(dn, sd)
+ error_count += 1
+ continue
+
+ if self.reset_well_known_acls:
+ try:
+ well_known_sd = self.get_wellknown_sd(dn)
+ except KeyError:
+ continue
+
+ current_sd = ndr_unpack(security.descriptor,
+ str(obj[attrname][0]))
+
+ diff = get_diff_sds(well_known_sd, current_sd, security.dom_sid(self.samdb.get_domain_sid()))
+ if diff != "":
+ self.err_wrong_default_sd(dn, well_known_sd, current_sd, diff)
+ error_count += 1
+ continue
continue
if str(attrname).lower() == 'objectclass':
diff --git a/python/samba/provision/descriptor.py b/python/samba/descriptor.py
similarity index 67%
rename from python/samba/provision/descriptor.py
rename to python/samba/descriptor.py
index 32e91ed..164b0bf 100644
--- a/python/samba/provision/descriptor.py
+++ b/python/samba/descriptor.py
@@ -28,6 +28,9 @@
from samba.dcerpc import security
from samba.ndr import ndr_pack
+from samba.schema import get_schema_descriptor
+import ldb
+import re
# Descriptors of naming contexts and other important objects
@@ -357,3 +360,222 @@ def get_dns_domain_microsoft_dns_descriptor(domain_sid, name_map={}):
"(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)" \
"(A;CI;RPWPCRCCDCLCRCWOWDSDDTSW;;;ED)"
return sddl2binary(sddl, domain_sid, name_map)
+
+def get_wellknown_sds(samdb):
+
+ # Then subcontainers
+ subcontainers = [
+ (ldb.Dn(samdb, "%s" % str(samdb.domain_dn())), get_domain_descriptor),
+ (ldb.Dn(samdb, "CN=LostAndFound,%s" % str(samdb.domain_dn())), get_domain_delete_protected2_descriptor),
+ (ldb.Dn(samdb, "CN=System,%s" % str(samdb.domain_dn())), get_domain_delete_protected1_descriptor),
+ (ldb.Dn(samdb, "CN=Infrastructure,%s" % str(samdb.domain_dn())), get_domain_infrastructure_descriptor),
+ (ldb.Dn(samdb, "CN=Builtin,%s" % str(samdb.domain_dn())), get_domain_builtin_descriptor),
+ (ldb.Dn(samdb, "CN=Computers,%s" % str(samdb.domain_dn())), get_domain_computers_descriptor),
+ (ldb.Dn(samdb, "CN=Users,%s" % str(samdb.domain_dn())), get_domain_users_descriptor),
+ (ldb.Dn(samdb, "OU=Domain Controllers,%s" % str(samdb.domain_dn())), get_domain_controllers_descriptor),
+ (ldb.Dn(samdb, "CN=MicrosoftDNS,CN=System,%s" % str(samdb.domain_dn())), get_dns_domain_microsoft_dns_descriptor),
+
+ (ldb.Dn(samdb, "%s" % str(samdb.get_config_basedn())), get_config_descriptor),
+ (ldb.Dn(samdb, "CN=NTDS Quotas,%s" % str(samdb.get_config_basedn())), get_config_ntds_quotas_descriptor),
+ (ldb.Dn(samdb, "CN=LostAndFoundConfig,%s" % str(samdb.get_config_basedn())), get_config_delete_protected1wd_descriptor),
+ (ldb.Dn(samdb, "CN=Services,%s" % str(samdb.get_config_basedn())), get_config_delete_protected1_descriptor),
+ (ldb.Dn(samdb, "CN=Physical Locations,%s" % str(samdb.get_config_basedn())), get_config_delete_protected1wd_descriptor),
+ (ldb.Dn(samdb, "CN=WellKnown Security Principals,%s" % str(samdb.get_config_basedn())), get_config_delete_protected1wd_descriptor),
+ (ldb.Dn(samdb, "CN=ForestUpdates,%s" % str(samdb.get_config_basedn())), get_config_delete_protected1wd_descriptor),
+ (ldb.Dn(samdb, "CN=DisplaySpecifiers,%s" % str(samdb.get_config_basedn())), get_config_delete_protected2_descriptor),
+ (ldb.Dn(samdb, "CN=Extended-Rights,%s" % str(samdb.get_config_basedn())), get_config_delete_protected2_descriptor),
+ (ldb.Dn(samdb, "CN=Partitions,%s" % str(samdb.get_config_basedn())), get_config_partitions_descriptor),
+ (ldb.Dn(samdb, "CN=Sites,%s" % str(samdb.get_config_basedn())), get_config_sites_descriptor),
+
+ (ldb.Dn(samdb, "%s" % str(samdb.get_schema_basedn())), get_schema_descriptor),
+ ]
+
+ current = samdb.search(expression="(objectClass=*)",
+ base="", scope=ldb.SCOPE_BASE,
+ attrs=["namingContexts"])
+
+ for nc in current[0]["namingContexts"]:
+
+ dnsforestdn = ldb.Dn(samdb, "DC=ForestDnsZones,%s" % (str(samdb.get_root_basedn())))
+ if ldb.Dn(samdb, nc) == dnsforestdn:
+ c = (ldb.Dn(samdb, "%s" % str(dnsforestdn)), get_dns_partition_descriptor)
+ subcontainers.append(c)
+ c = (ldb.Dn(samdb, "CN=Infrastructure,%s" % str(dnsforestdn)),
+ get_domain_delete_protected1_descriptor)
+ subcontainers.append(c)
+ c = (ldb.Dn(samdb, "CN=LostAndFound,%s" % str(dnsforestdn)),
+ get_domain_delete_protected2_descriptor)
+ subcontainers.append(c)
+ c = (ldb.Dn(samdb, "CN=MicrosoftDNS,%s" % str(dnsforestdn)),
+ get_dns_forest_microsoft_dns_descriptor)
+ subcontainers.append(c)
+ continue
+
+ dnsdomaindn = ldb.Dn(samdb, "DC=DomainDnsZones,%s" % (str(samdb.domain_dn())))
+ if ldb.Dn(samdb, nc) == dnsdomaindn:
+ c = (ldb.Dn(samdb, "%s" % str(dnsdomaindn)), get_dns_partition_descriptor)
+ subcontainers.append(c)
+ c = (ldb.Dn(samdb, "CN=Infrastructure,%s" % str(dnsdomaindn)),
+ get_domain_delete_protected1_descriptor)
+ subcontainers.append(c)
+ c = (ldb.Dn(samdb, "CN=LostAndFound,%s" % str(dnsdomaindn)),
+ get_domain_delete_protected2_descriptor)
+ subcontainers.append(c)
+ c = (ldb.Dn(samdb, "CN=MicrosoftDNS,%s" % str(dnsdomaindn)),
+ get_dns_domain_microsoft_dns_descriptor)
+ subcontainers.append(c)
+
+ return subcontainers
+
+
+def chunck_acl(acl):
+ """Return separate ACE of an ACL
+
+ :param acl: A string representing the ACL
+ :return: A hash with different parts
+ """
+
+ p = re.compile(r'(\w+)?(\(.*?\))')
+ tab = p.findall(acl)
+
+ hash = {}
+ hash["aces"] = []
+ for e in tab:
+ if len(e[0]) > 0:
+ hash["flags"] = e[0]
+ hash["aces"].append(e[1])
+
+ return hash
+
+
+def chunck_sddl(sddl):
+ """ Return separate parts of the SDDL (owner, group, ...)
+
+ :param sddl: An string containing the SDDL to chunk
+ :return: A hash with the different chunk
+ """
+
+ p = re.compile(r'([OGDS]:)(.*?)(?=(?:[GDS]:|$))')
+ tab = p.findall(sddl)
+
+ hash = {}
+ for e in tab:
+ if e[0] == "O:":
+ hash["owner"] = e[1]
+ if e[0] == "G:":
+ hash["group"] = e[1]
+ if e[0] == "D:":
+ hash["dacl"] = e[1]
+ if e[0] == "S:":
+ hash["sacl"] = e[1]
+
+ return hash
+
+
+def get_clean_sd(sd):
+ """Get the SD without any inherited ACEs
+
+ :param sd: SD to strip
+ :return: An SD with inherited ACEs stripped
+ """
+
+ sd_clean = security.descriptor()
+ sd_clean.owner_sid = sd.owner_sid
+ sd_clean.group_sid = sd.group_sid
+ sd_clean.type = sd.type
+ sd_clean.revision = sd.revision
+
+ aces = []
+ if sd.sacl is not None:
+ aces = sd.sacl.aces
+ for i in range(0, len(aces)):
+ ace = aces[i]
+
+ if not ace.flags & security.SEC_ACE_FLAG_INHERITED_ACE:
+ sd_clean.sacl_add(ace)
+ continue
+
+ aces = []
+ if sd.dacl is not None:
+ aces = sd.dacl.aces
+ for i in range(0, len(aces)):
+ ace = aces[i]
+
+ if not ace.flags & security.SEC_ACE_FLAG_INHERITED_ACE:
+ sd_clean.dacl_add(ace)
+ continue
+ return sd_clean
+
+
+def get_diff_sds(refsd, cursd, domainsid, checkSacl = True):
+ """Get the difference between 2 sd
+
+ This function split the textual representation of ACL into smaller
+ chunck in order to not to report a simple permutation as a difference
+
+ :param refsddl: First sddl to compare
+ :param cursddl: Second sddl to compare
+ :param checkSacl: If false we skip the sacl checks
+ :return: A string that explain difference between sddls
+ """
+
+ cursddl = get_clean_sd(cursd).as_sddl(domainsid)
+ refsddl = get_clean_sd(refsd).as_sddl(domainsid)
+
+ txt = ""
+ hash_cur = chunck_sddl(cursddl)
+ hash_ref = chunck_sddl(refsddl)
+
+ if not hash_cur.has_key("owner"):
+ txt = "\tNo owner in current SD"
+ elif hash_ref.has_key("owner") and hash_cur["owner"] != hash_ref["owner"]:
+ txt = "\tOwner mismatch: %s (in ref) %s" \
+ "(in current)\n" % (hash_ref["owner"], hash_cur["owner"])
+
+ if not hash_cur.has_key("group"):
+ txt = "%s\tNo group in current SD" % txt
+ elif hash_ref.has_key("group") and hash_cur["group"] != hash_ref["group"]:
+ txt = "%s\tGroup mismatch: %s (in ref) %s" \
+ "(in current)\n" % (txt, hash_ref["group"], hash_cur["group"])
+
+ parts = [ "dacl" ]
+ if checkSacl:
+ parts.append("sacl")
+ for part in parts:
+ if hash_cur.has_key(part) and hash_ref.has_key(part):
+
+ # both are present, check if they contain the same ACE
+ h_cur = set()
+ h_ref = set()
+ c_cur = chunck_acl(hash_cur[part])
+ c_ref = chunck_acl(hash_ref[part])
+
+ for elem in c_cur["aces"]:
+ h_cur.add(elem)
+
+ for elem in c_ref["aces"]:
+ h_ref.add(elem)
+
+ for k in set(h_ref):
+ if k in h_cur:
+ h_cur.remove(k)
+ h_ref.remove(k)
+
+ if len(h_cur) + len(h_ref) > 0:
+ txt = "%s\tPart %s is different between reference" \
+ " and current here is the detail:\n" % (txt, part)
+
+ for item in h_cur:
+ txt = "%s\t\t%s ACE is not present in the" \
+ " reference\n" % (txt, item)
+
+ for item in h_ref:
+ txt = "%s\t\t%s ACE is not present in the" \
+ " current\n" % (txt, item)
+
+ elif hash_cur.has_key(part) and not hash_ref.has_key(part):
+ txt = "%s\tReference ACL hasn't a %s part\n" % (txt, part)
+ elif not hash_cur.has_key(part) and hash_ref.has_key(part):
+ txt = "%s\tCurrent ACL hasn't a %s part\n" % (txt, part)
+
+ return txt
diff --git a/python/samba/netcmd/dbcheck.py b/python/samba/netcmd/dbcheck.py
index 889b0ff..4cc0631 100644
--- a/python/samba/netcmd/dbcheck.py
+++ b/python/samba/netcmd/dbcheck.py
@@ -56,6 +56,7 @@ class cmd_dbcheck(Command):
Option("--attrs", dest="attrs", default=None, help="list of attributes to check (space separated)"),
Option("--reindex", dest="reindex", default=False, action="store_true", help="force database re-index"),
Option("--force-modules", dest="force_modules", default=False, action="store_true", help="force loading of Samba modules and ignore the @MODULES record (for very old databases)"),
+ Option("--reset-well-known-acls", dest="reset_well_known_acls", default=False, action="store_true", help="reset ACLs on objects with well known default ACL values to the default"),
Option("-H", "--URL", help="LDB URL for database or target server (defaults to local SAM database)",
type=str, metavar="URL", dest="H"),
]
@@ -63,7 +64,8 @@ class cmd_dbcheck(Command):
def run(self, DN=None, H=None, verbose=False, fix=False, yes=False,
cross_ncs=False, quiet=False,
scope="SUB", credopts=None, sambaopts=None, versionopts=None,
- attrs=None, reindex=False, force_modules=False):
+ attrs=None, reindex=False, force_modules=False,
+ reset_well_known_acls=False):
lp = sambaopts.get_loadparm()
@@ -114,7 +116,8 @@ class cmd_dbcheck(Command):
started_transaction = True
try:
chk = dbcheck(samdb, samdb_schema=samdb_schema, verbose=verbose,
- fix=fix, yes=yes, quiet=quiet, in_transaction=started_transaction)
+ fix=fix, yes=yes, quiet=quiet, in_transaction=started_transaction,
+ reset_well_known_acls=reset_well_known_acls)
if reindex:
self.outf.write("Re-indexing...\n")
diff --git a/python/samba/netcmd/ldapcmp.py b/python/samba/netcmd/ldapcmp.py
index 6e025a2..7bd118e 100644
--- a/python/samba/netcmd/ldapcmp.py
+++ b/python/samba/netcmd/ldapcmp.py
@@ -80,7 +80,6 @@ class LDAPBase(object):
self.server_names = self.find_servers()
self.domain_name = re.sub("[Dd][Cc]=", "", self.base_dn).replace(",", ".")
self.domain_sid = self.find_domain_sid()
- self.get_guid_map()
self.get_sid_map()
#
# Log some domain controller specific place-holers that are being used
@@ -250,20 +249,6 @@ class LDAPBase(object):
assert index == len(blob)
return res.strip().replace(" ", "-")
- def get_guid_map(self):
- """ Build dictionary that maps GUID to 'name' attribute found in Schema or Extended-Rights.
- """
- self.guid_map = {}
- res = self.ldb.search(base=self.schema_dn,
- expression="(schemaIdGuid=*)", scope=SCOPE_SUBTREE, attrs=["schemaIdGuid", "name"])
- for item in res:
- self.guid_map[self.guid_as_string(item["schemaIdGuid"]).lower()] = item["name"][0]
- #
- res = self.ldb.search(base="cn=extended-rights,%s" % self.config_dn,
- expression="(rightsGuid=*)", scope=SCOPE_SUBTREE, attrs=["rightsGuid", "name"])
- for item in res:
- self.guid_map[str(item["rightsGuid"]).lower()] = item["name"][0]
-
def get_sid_map(self):
""" Build dictionary that maps GUID to 'name' attribute found in Schema or Extended-Rights.
"""
@@ -299,22 +284,6 @@ class Descriptor(object):
return []
return re.findall("(\(.*?\))", res)
- def fix_guid(self, ace):
- res = "%s" % ace
--
Samba Shared Repository
More information about the samba-cvs
mailing list