mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
python/samba/samdb: Only do caching of well known DNs in dbcheck
The fact that get_wellknown_dn() returned a cached DN that could
not be modified safely was unexpected, particularly given that
other similar routines did not do that.
The use case given at the time this was written by
Matthieu Patou in 6122acad0f
was dbcheck, so move the cache there, and name it clearly.
dbcheck is the only case that uses this rotuine in an inner
loop.
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Jo Sutton <josutton@catalyst.net.nz>
This commit is contained in:
parent
5a0fce5865
commit
9a5cc12042
@ -56,6 +56,8 @@ def dump_attr_values(vals):
|
|||||||
class dbcheck(object):
|
class dbcheck(object):
|
||||||
"""check a SAM database for errors"""
|
"""check a SAM database for errors"""
|
||||||
|
|
||||||
|
hash_well_known = {}
|
||||||
|
|
||||||
def __init__(self, samdb, samdb_schema=None, verbose=False, fix=False,
|
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,
|
||||||
quick_membership_checks=False,
|
quick_membership_checks=False,
|
||||||
@ -130,9 +132,9 @@ class dbcheck(object):
|
|||||||
self.link_id_cache = {}
|
self.link_id_cache = {}
|
||||||
self.name_map = {}
|
self.name_map = {}
|
||||||
try:
|
try:
|
||||||
base_dn = "CN=DnsAdmins,%s" % samdb.get_wellknown_dn(
|
base_dn = "CN=DnsAdmins,%s" % self.get_wellknown_dn_cached(
|
||||||
samdb.get_default_basedn(),
|
samdb.get_default_basedn(),
|
||||||
dsdb.DS_GUID_USERS_CONTAINER)
|
dsdb.DS_GUID_USERS_CONTAINER)
|
||||||
res = samdb.search(base=base_dn, scope=ldb.SCOPE_BASE,
|
res = samdb.search(base=base_dn, scope=ldb.SCOPE_BASE,
|
||||||
attrs=["objectSid"])
|
attrs=["objectSid"])
|
||||||
dnsadmins_sid = ndr_unpack(security.dom_sid, res[0]["objectSid"][0])
|
dnsadmins_sid = ndr_unpack(security.dom_sid, res[0]["objectSid"][0])
|
||||||
@ -171,8 +173,8 @@ class dbcheck(object):
|
|||||||
|
|
||||||
for nc in self.ncs:
|
for nc in self.ncs:
|
||||||
try:
|
try:
|
||||||
dn = self.samdb.get_wellknown_dn(ldb.Dn(self.samdb, nc.decode('utf8')),
|
dn = self.get_wellknown_dn_cached(ldb.Dn(self.samdb, nc.decode('utf8')),
|
||||||
dsdb.DS_GUID_DELETED_OBJECTS_CONTAINER)
|
dsdb.DS_GUID_DELETED_OBJECTS_CONTAINER)
|
||||||
self.deleted_objects_containers.append(dn)
|
self.deleted_objects_containers.append(dn)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
self.ncs_lacking_deleted_containers.append(ldb.Dn(self.samdb, nc.decode('utf8')))
|
self.ncs_lacking_deleted_containers.append(ldb.Dn(self.samdb, nc.decode('utf8')))
|
||||||
@ -243,6 +245,21 @@ class dbcheck(object):
|
|||||||
if enum != ldb.ERR_NO_SUCH_OBJECT:
|
if enum != ldb.ERR_NO_SUCH_OBJECT:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
def get_wellknown_dn_cached(self, nc_root, wkguid):
|
||||||
|
h_nc = self.hash_well_known.get(str(nc_root))
|
||||||
|
dn = None
|
||||||
|
if h_nc is not None:
|
||||||
|
dn = h_nc.get(wkguid)
|
||||||
|
if dn is None:
|
||||||
|
dn = self.samdb.get_wellknown_dn(nc_root, wkguid)
|
||||||
|
if dn is None:
|
||||||
|
return dn
|
||||||
|
if h_nc is None:
|
||||||
|
self.hash_well_known[str(nc_root)] = {}
|
||||||
|
h_nc = self.hash_well_known[str(nc_root)]
|
||||||
|
h_nc[wkguid] = dn
|
||||||
|
return dn
|
||||||
|
|
||||||
def check_database(self, DN=None, scope=ldb.SCOPE_SUBTREE, controls=None,
|
def check_database(self, DN=None, scope=ldb.SCOPE_SUBTREE, controls=None,
|
||||||
attrs=None):
|
attrs=None):
|
||||||
"""perform a database check, returning the number of errors found"""
|
"""perform a database check, returning the number of errors found"""
|
||||||
@ -945,7 +962,7 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
|
|||||||
self.samdb.transaction_start()
|
self.samdb.transaction_start()
|
||||||
try:
|
try:
|
||||||
nc_root = self.samdb.get_nc_root(obj.dn)
|
nc_root = self.samdb.get_nc_root(obj.dn)
|
||||||
lost_and_found = self.samdb.get_wellknown_dn(nc_root, dsdb.DS_GUID_LOSTANDFOUND_CONTAINER)
|
lost_and_found = self.get_wellknown_dn_cached(nc_root, dsdb.DS_GUID_LOSTANDFOUND_CONTAINER)
|
||||||
new_dn = ldb.Dn(self.samdb, str(obj.dn))
|
new_dn = ldb.Dn(self.samdb, str(obj.dn))
|
||||||
new_dn.remove_base_components(len(new_dn) - 1)
|
new_dn.remove_base_components(len(new_dn) - 1)
|
||||||
if self.do_rename(obj.dn, new_dn, lost_and_found, ["show_deleted:0", "relax:0"],
|
if self.do_rename(obj.dn, new_dn, lost_and_found, ["show_deleted:0", "relax:0"],
|
||||||
@ -2369,8 +2386,8 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
|
|||||||
|
|
||||||
nc_dn = self.samdb.get_nc_root(obj.dn)
|
nc_dn = self.samdb.get_nc_root(obj.dn)
|
||||||
try:
|
try:
|
||||||
deleted_objects_dn = self.samdb.get_wellknown_dn(nc_dn,
|
deleted_objects_dn = self.get_wellknown_dn_cached(nc_dn,
|
||||||
samba.dsdb.DS_GUID_DELETED_OBJECTS_CONTAINER)
|
samba.dsdb.DS_GUID_DELETED_OBJECTS_CONTAINER)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
# We have no deleted objects DN for schema, and we check for this above for the other
|
# We have no deleted objects DN for schema, and we check for this above for the other
|
||||||
# NCs
|
# NCs
|
||||||
|
@ -53,7 +53,6 @@ class SamDB(samba.Ldb):
|
|||||||
"""The SAM database."""
|
"""The SAM database."""
|
||||||
|
|
||||||
hash_oid_name = {}
|
hash_oid_name = {}
|
||||||
hash_well_known = {}
|
|
||||||
|
|
||||||
class _CleanUpOnError:
|
class _CleanUpOnError:
|
||||||
def __init__(self, samdb, dn):
|
def __init__(self, samdb, dn):
|
||||||
@ -1220,19 +1219,7 @@ schemaUpdateNow: 1
|
|||||||
return dsdb._dsdb_get_nc_root(self, dn)
|
return dsdb._dsdb_get_nc_root(self, dn)
|
||||||
|
|
||||||
def get_wellknown_dn(self, nc_root, wkguid):
|
def get_wellknown_dn(self, nc_root, wkguid):
|
||||||
h_nc = self.hash_well_known.get(str(nc_root))
|
return dsdb._dsdb_get_wellknown_dn(self, nc_root, wkguid)
|
||||||
dn = None
|
|
||||||
if h_nc is not None:
|
|
||||||
dn = h_nc.get(wkguid)
|
|
||||||
if dn is None:
|
|
||||||
dn = dsdb._dsdb_get_wellknown_dn(self, nc_root, wkguid)
|
|
||||||
if dn is None:
|
|
||||||
return dn
|
|
||||||
if h_nc is None:
|
|
||||||
self.hash_well_known[str(nc_root)] = {}
|
|
||||||
h_nc = self.hash_well_known[str(nc_root)]
|
|
||||||
h_nc[wkguid] = dn
|
|
||||||
return dn
|
|
||||||
|
|
||||||
def set_minPwdAge(self, value):
|
def set_minPwdAge(self, value):
|
||||||
if not isinstance(value, bytes):
|
if not isinstance(value, bytes):
|
||||||
|
Loading…
Reference in New Issue
Block a user