You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
3.3 KiB
96 lines
3.3 KiB
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
|