LdapTree.py
3.26 KB
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import ldap
import pygraphviz as pgv
class LdapTree(object):
def __init__(self, hosturi, binddn, basedn, password, use_gssapi):
#ldap.set_option(ldap.OPT_DEBUG_LEVEL, 1)
self._ldap = ldap.initialize(hosturi)
"""
Setting ldap.OPT_REFERRALS to 0 was neccessary to query a samba4
active directory... Currently I don't know if it is a good idea
to keep it generally here.
"""
self._ldap.set_option(ldap.OPT_REFERRALS, 0)
if use_gssapi:
sasl_auth = ldap.sasl.sasl({},'GSSAPI')
self._ldap.sasl_interactive_bind_s("", sasl_auth)
else:
self._ldap.bind(binddn, password, ldap.AUTH_SIMPLE)
self._basedn = basedn
self._ldap_result = []
def text(self, filename = None):
"""
Returns a text representing the directory.
If filename is given it will be written in that file.
"""
if filename:
with open(filename, "w") as text_file:
text_file.write(self._text(self._basedn, 0))
else:
return self._text(self._basedn, 0)
def graph(self, filename = None):
"""
Returns an svg representing the directory.
If filename is given it will be written in that file.
"""
graph = pgv.AGraph(
directed=True, charset='utf-8', fixedsize='true', ranksep=0.1)
graph.node_attr.update(
style='rounded,filled', width='0', height='0', shape='box',
fillcolor='#E5E5E5', concentrate='true', fontsize='8.0',
fontname='Arial', margin='0.03')
graph.edge_attr.update(arrowsize='0.55')
self._graph(graph, self._basedn)
graph.layout(prog='dot')
if filename:
graph.draw(path=filename, format='svg')
return None
else:
return graph.draw(format='svg')
def _text(self, dn, level):
"""
Recursive function that returns a string representation of the
directory where each depth is indicated by a dash.
"""
result = self._ldap.search_s(dn, ldap.SCOPE_ONELEVEL)
indent = '-' * level
text = indent + dn + "\n"
for entry in (entry[0] for entry in result):
if entry:
text += self._text(entry, level + 1)
return text
def _graph(self, graph, dn):
"""
Recursive function creating a graphviz graph from the directory.
"""
result = self._ldap.search_s(dn, ldap.SCOPE_ONELEVEL)
minlen = thislen = 1
edge_start = dn
for entry in (entry[0] for entry in result):
if entry:
point = entry + '_p'
sub = graph.add_subgraph()
sub.graph_attr['rank'] = 'same'
sub.add_node(
point, shape='circle', fixedsize='true', width='0.04',
label='', fillcolor='transparent')
sub.add_node(entry)
graph.add_edge(edge_start, point, arrowhead='none',
minlen=str(minlen))
graph.add_edge(point, entry)
edge_start = point
minlen = self._graph(graph, entry)
thislen += minlen
return thislen