mirror of
https://github.com/samba-team/samba.git
synced 2025-07-29 15:42:04 +03:00
s4:python Push some helper functions from SamDB into samba.Ldb
This makes it possible to do a bit more of the provision with Samba helpers, but without some of the otherwise useful things (such as loading in the global schema) that SamDB does. Rewrite provision_erase to use a recursive search, rather than a looping subtree search. This is much more efficient, particularly now we have one-level indexes enabled. Delete the @INDEX and similar records *after* deleting all other visible records, this hopefully also assists performance. Andrew Bartlett
This commit is contained in:
@ -121,17 +121,8 @@ class Ldb(ldb.Ldb):
|
|||||||
|
|
||||||
def erase(self):
|
def erase(self):
|
||||||
"""Erase this ldb, removing all records."""
|
"""Erase this ldb, removing all records."""
|
||||||
# delete the specials
|
|
||||||
for attr in ["@INDEXLIST", "@ATTRIBUTES", "@SUBCLASSES", "@MODULES",
|
|
||||||
"@OPTIONS", "@PARTITION", "@KLUDGEACL"]:
|
|
||||||
try:
|
|
||||||
self.delete(attr)
|
|
||||||
except ldb.LdbError, (ldb.ERR_NO_SUCH_OBJECT, _):
|
|
||||||
# Ignore missing dn errors
|
|
||||||
pass
|
|
||||||
|
|
||||||
basedn = ""
|
basedn = ""
|
||||||
# and the rest
|
# Delete the 'visible' records
|
||||||
for msg in self.search(basedn, ldb.SCOPE_SUBTREE,
|
for msg in self.search(basedn, ldb.SCOPE_SUBTREE,
|
||||||
"(&(|(objectclass=*)(distinguishedName=*))(!(distinguishedName=@BASEINFO)))",
|
"(&(|(objectclass=*)(distinguishedName=*))(!(distinguishedName=@BASEINFO)))",
|
||||||
["distinguishedName"]):
|
["distinguishedName"]):
|
||||||
@ -144,37 +135,39 @@ class Ldb(ldb.Ldb):
|
|||||||
res = self.search(basedn, ldb.SCOPE_SUBTREE, "(&(|(objectclass=*)(distinguishedName=*))(!(distinguishedName=@BASEINFO)))", ["distinguishedName"])
|
res = self.search(basedn, ldb.SCOPE_SUBTREE, "(&(|(objectclass=*)(distinguishedName=*))(!(distinguishedName=@BASEINFO)))", ["distinguishedName"])
|
||||||
assert len(res) == 0
|
assert len(res) == 0
|
||||||
|
|
||||||
|
# delete the specials
|
||||||
|
for attr in ["@INDEXLIST", "@ATTRIBUTES", "@SUBCLASSES", "@MODULES",
|
||||||
|
"@OPTIONS", "@PARTITION", "@KLUDGEACL"]:
|
||||||
|
try:
|
||||||
|
self.delete(attr)
|
||||||
|
except ldb.LdbError, (ldb.ERR_NO_SUCH_OBJECT, _):
|
||||||
|
# Ignore missing dn errors
|
||||||
|
pass
|
||||||
|
|
||||||
def erase_partitions(self):
|
def erase_partitions(self):
|
||||||
"""Erase an ldb, removing all records."""
|
"""Erase an ldb, removing all records."""
|
||||||
|
|
||||||
|
def erase_recursive(self, dn):
|
||||||
|
try:
|
||||||
|
res = self.search(base=dn, scope=ldb.SCOPE_ONELEVEL, attrs=[])
|
||||||
|
except ldb.LdbError, (ldb.ERR_NO_SUCH_OBJECT, _):
|
||||||
|
# Ignore no such object errors
|
||||||
|
return
|
||||||
|
pass
|
||||||
|
|
||||||
|
for msg in res:
|
||||||
|
erase_recursive(self, msg.dn)
|
||||||
|
|
||||||
|
self.delete(dn)
|
||||||
|
|
||||||
res = self.search("", ldb.SCOPE_BASE, "(objectClass=*)",
|
res = self.search("", ldb.SCOPE_BASE, "(objectClass=*)",
|
||||||
["namingContexts"])
|
["namingContexts"])
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
if not "namingContexts" in res[0]:
|
if not "namingContexts" in res[0]:
|
||||||
return
|
return
|
||||||
for basedn in res[0]["namingContexts"]:
|
for basedn in res[0]["namingContexts"]:
|
||||||
previous_remaining = 1
|
# Try and erase from the bottom-up in the tree
|
||||||
current_remaining = 0
|
erase_recursive(self, basedn)
|
||||||
|
|
||||||
k = 0
|
|
||||||
while ++k < 10 and (previous_remaining != current_remaining):
|
|
||||||
# and the rest
|
|
||||||
try:
|
|
||||||
res2 = self.search(basedn, ldb.SCOPE_SUBTREE, "(|(objectclass=*)(distinguishedName=*))", ["distinguishedName"])
|
|
||||||
except ldb.LdbError, (ldb.ERR_NO_SUCH_OBJECT, _):
|
|
||||||
# Ignore missing dn errors
|
|
||||||
return
|
|
||||||
|
|
||||||
previous_remaining = current_remaining
|
|
||||||
current_remaining = len(res2)
|
|
||||||
for msg in res2:
|
|
||||||
try:
|
|
||||||
self.delete(msg.dn)
|
|
||||||
# Ignore no such object errors
|
|
||||||
except ldb.LdbError, (ldb.ERR_NO_SUCH_OBJECT, _):
|
|
||||||
pass
|
|
||||||
# Ignore not allowed on non leaf errors
|
|
||||||
except ldb.LdbError, (ldb.ERR_NOT_ALLOWED_ON_NON_LEAF, _):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def load_ldif_file_add(self, ldif_path):
|
def load_ldif_file_add(self, ldif_path):
|
||||||
"""Load a LDIF file.
|
"""Load a LDIF file.
|
||||||
@ -200,6 +193,37 @@ class Ldb(ldb.Ldb):
|
|||||||
for changetype, msg in self.parse_ldif(ldif):
|
for changetype, msg in self.parse_ldif(ldif):
|
||||||
self.modify(msg)
|
self.modify(msg)
|
||||||
|
|
||||||
|
def set_domain_sid(self, sid):
|
||||||
|
"""Change the domain SID used by this LDB.
|
||||||
|
|
||||||
|
:param sid: The new domain sid to use.
|
||||||
|
"""
|
||||||
|
glue.samdb_set_domain_sid(self, sid)
|
||||||
|
|
||||||
|
def set_schema_from_ldif(self, pf, df):
|
||||||
|
glue.dsdb_set_schema_from_ldif(self, pf, df)
|
||||||
|
|
||||||
|
def set_schema_from_ldb(self, ldb):
|
||||||
|
glue.dsdb_set_schema_from_ldb(self, ldb)
|
||||||
|
|
||||||
|
def convert_schema_to_openldap(self, target, mapping):
|
||||||
|
return glue.dsdb_convert_schema_to_openldap(self, target, mapping)
|
||||||
|
|
||||||
|
def set_invocation_id(self, invocation_id):
|
||||||
|
"""Set the invocation id for this SamDB handle.
|
||||||
|
|
||||||
|
:param invocation_id: GUID of the invocation id.
|
||||||
|
"""
|
||||||
|
glue.dsdb_set_ntds_invocation_id(self, invocation_id)
|
||||||
|
|
||||||
|
def set_opaque_integer(self, name, value):
|
||||||
|
"""Set an integer as an opaque (a flag or other value) value on the database
|
||||||
|
|
||||||
|
:param name: The name for the opaque value
|
||||||
|
:param value: The integer value
|
||||||
|
"""
|
||||||
|
glue.dsdb_set_opaque_integer(self, name, value)
|
||||||
|
|
||||||
|
|
||||||
def substitute_var(text, values):
|
def substitute_var(text, values):
|
||||||
"""substitute strings of the form ${NAME} in str, replacing
|
"""substitute strings of the form ${NAME} in str, replacing
|
||||||
|
@ -209,37 +209,6 @@ userPassword:: %s
|
|||||||
raise
|
raise
|
||||||
self.transaction_commit()
|
self.transaction_commit()
|
||||||
|
|
||||||
def set_domain_sid(self, sid):
|
|
||||||
"""Change the domain SID used by this SamDB.
|
|
||||||
|
|
||||||
:param sid: The new domain sid to use.
|
|
||||||
"""
|
|
||||||
glue.samdb_set_domain_sid(self, sid)
|
|
||||||
|
|
||||||
def set_schema_from_ldif(self, pf, df):
|
|
||||||
glue.dsdb_set_schema_from_ldif(self, pf, df)
|
|
||||||
|
|
||||||
def set_schema_from_ldb(self, ldb):
|
|
||||||
glue.dsdb_set_schema_from_ldb(self, ldb)
|
|
||||||
|
|
||||||
def convert_schema_to_openldap(self, target, mapping):
|
|
||||||
return glue.dsdb_convert_schema_to_openldap(self, target, mapping)
|
|
||||||
|
|
||||||
def set_invocation_id(self, invocation_id):
|
|
||||||
"""Set the invocation id for this SamDB handle.
|
|
||||||
|
|
||||||
:param invocation_id: GUID of the invocation id.
|
|
||||||
"""
|
|
||||||
glue.dsdb_set_ntds_invocation_id(self, invocation_id)
|
|
||||||
|
|
||||||
def set_opaque_integer(self, name, value):
|
|
||||||
"""Set an integer as an opaque (a flag or other value) value on the database
|
|
||||||
|
|
||||||
:param name: The name for the opaque value
|
|
||||||
:param value: The integer value
|
|
||||||
"""
|
|
||||||
glue.dsdb_set_opaque_integer(self, name, value)
|
|
||||||
|
|
||||||
def setexpiry(self, user, expiry_seconds, noexpiry):
|
def setexpiry(self, user, expiry_seconds, noexpiry):
|
||||||
"""Set the account expiry for a user
|
"""Set the account expiry for a user
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user