File: deltree.py

package info (click to toggle)
python-ldap 3.4.4-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,368 kB
  • sloc: python: 9,558; ansic: 3,052; makefile: 139; sh: 79
file content (80 lines) | stat: -rw-r--r-- 2,629 bytes parent folder | download | duplicates (3)
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)