1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
|
import ldap,ldap.async
class DeleteLeafs(ldap.async.AsyncSearchHandler):
"""
Class for deleting entries which are results of a search.
DNs of Non-leaf entries are collected in DeleteLeafs.nonLeafEntries.
"""
_entryResultTypes = ldap.async._entryResultTypes
def __init__(self,l):
ldap.async.AsyncSearchHandler.__init__(self,l)
self.nonLeafEntries = []
self.deletedEntries = 0
def startSearch(self,searchRoot,searchScope):
if not searchScope in [ldap.SCOPE_ONELEVEL,ldap.SCOPE_SUBTREE]:
raise ValueError("Parameter searchScope must be either ldap.SCOPE_ONELEVEL or ldap.SCOPE_SUBTREE.")
self.nonLeafEntries = []
self.deletedEntries = 0
ldap.async.AsyncSearchHandler.startSearch(
self,
searchRoot,
searchScope,
filterStr='(objectClass=*)',
attrList=['hasSubordinates','numSubordinates'],
attrsOnly=0,
)
def _processSingleResult(self,resultType,resultItem):
if resultType in self._entryResultTypes:
# Don't process search references
dn,entry = resultItem
hasSubordinates = entry.get(
'hasSubordinates',
entry.get('hassubordinates',['FALSE']
)
)[0]
numSubordinates = entry.get(
'numSubordinates',
entry.get('numsubordinates',['0'])
)[0]
if hasSubordinates=='TRUE' or int(numSubordinates):
self.nonLeafEntries.append(dn)
else:
try:
self._l.delete_s(dn)
except ldap.NOT_ALLOWED_ON_NONLEAF as e:
self.nonLeafEntries.append(dn)
else:
self.deletedEntries = self.deletedEntries+1
def DelTree(l,dn,scope=ldap.SCOPE_ONELEVEL):
"""
Recursively delete entries below or including entry with name dn.
"""
leafs_deleter = DeleteLeafs(l)
leafs_deleter.startSearch(dn,scope)
leafs_deleter.processResults()
deleted_entries = leafs_deleter.deletedEntries
non_leaf_entries = leafs_deleter.nonLeafEntries[:]
while non_leaf_entries:
dn = non_leaf_entries.pop()
print(deleted_entries,len(non_leaf_entries),dn)
leafs_deleter.startSearch(dn,ldap.SCOPE_SUBTREE)
leafs_deleter.processResults()
deleted_entries = deleted_entries+leafs_deleter.deletedEntries
non_leaf_entries.extend(leafs_deleter.nonLeafEntries)
return # DelTree()
# Create LDAPObject instance
l = ldap.initialize('ldap://localhost:1390')
# Try a bind to provoke failure if protocol version is not supported
l.simple_bind_s('cn=Directory Manager,dc=IMC,dc=org','controller')
# Delete all entries *below* the entry dc=Delete,dc=IMC,dc=org
DelTree(l,'dc=Delete,dc=IMC,dc=org',ldap.SCOPE_ONELEVEL)
|