1+ """
2+ Code from https://ldaptor.readthedocs.io/en/latest/quickstart.html#ldap-server-quick-start
3+
4+ """
5+
6+ import sys
7+
8+ try :
9+ from cStringIO import StringIO as BytesIO
10+ except ImportError :
11+ from io import BytesIO
12+
13+ from twisted .application import service
14+ from twisted .internet .endpoints import serverFromString
15+ from twisted .internet .protocol import ServerFactory
16+ from twisted .python .components import registerAdapter
17+ from twisted .python import log
18+ from ldaptor .inmemory import fromLDIFFile
19+ from ldaptor .interfaces import IConnectedLDAPEntry
20+ from ldaptor .protocols .ldap .ldapserver import LDAPServer
21+
22+ LDIF = b"""\
23+ dn: o=ReactOS Website
24+ objectClass: organization
25+ o: ReactOS Website
26+
27+ dn: ou=People,o=ReactOS Website
28+ objectClass: organizationalUnit
29+ ou: People
30+
31+ dn: ou=Groups,o=ReactOS Website
32+ objectClass: organizationalUnit
33+ ou: Groups
34+
35+ dn: cn=Moderators,ou=Groups,o=ReactOS Website
36+ objectClass: groupOfNames
37+ cn: Moderators
38+ member: cn=testmod,ou=People,o=ReactOS Website
39+ member: cn=testadmin,ou=People,o=ReactOS Website
40+
41+ dn: cu=Administrators,ou=Groups,o=ReactOS Website
42+ objectClass: groupOfNames
43+ cn: Administrators
44+ member: cn=testadmin,ou=People,o=ReactOS Website
45+
46+ dn: ou=Service Accounts,o=ReactOS Website
47+ objectClass: organizationalUnit
48+ ou: Service Accounts
49+
50+ dn: uid=roslogin,ou=Service Accounts,o=ReactOS Website
51+ objectClass: account
52+ objectClass: simpleSecurityObject
53+ uid: roslogin
54+ userPassword: test
55+
56+ # Users:
57+ dn: cn=test,ou=People,o=ReactOS Website
58+ objectClass: inetOrgPerson
59+ cn: test
60+ sn: test
61+ 62+ displayName: test
63+ userPassword: test12
64+
65+ dn: cn=test2,ou=People,o=ReactOS Website
66+ objectClass: inetOrgPerson
67+ cn: test2
68+ sn: test2
69+ 70+ displayName: test 2
71+ userPassword: test12
72+
73+ dn: cn=test3,ou=People,o=ReactOS Website
74+ objectClass: inetOrgPerson
75+ cn: test3
76+ sn: test3
77+ 78+ displayName: test3
79+ userPassword: test12
80+
81+ dn: cn=test_banned1,ou=People,o=ReactOS Website
82+ objectClass: inetOrgPerson
83+ cn: test_banned1
84+ sn: test_banned1
85+ 86+ displayName: test banned1
87+ userPassword: test12
88+
89+ dn: cn=test_banned2,ou=People,o=ReactOS Website
90+ objectClass: inetOrgPerson
91+ cn: test_banned2
92+ sn: test_banned2
93+ 94+ displayName: test banned2
95+ userPassword: test12
96+
97+ dn: cn=testmod,ou=People,o=ReactOS Website
98+ objectClass: inetOrgPerson
99+ cn: testmod
100+ sn: testmod
101+ 102+ displayName: test mod
103+ userPassword: test12
104+ memberOf: cn=Moderators,ou=Groups,o=ReactOS Website
105+
106+ dn: cn=testadmin,ou=People,o=ReactOS Website
107+ objectClass: inetOrgPerson
108+ cn: testadmin
109+ sn: testadmin
110+ 111+ displayName: test admin
112+ userPassword: test12
113+ memberOf: cn=Moderators,ou=Groups,o=ReactOS Website
114+ memberOf: cn=Administrators,ou=Groups,o=ReactOS Website
115+
116+ """
117+
118+ class Tree :
119+ def __init__ (self ):
120+ global LDIF
121+ self .f = BytesIO (LDIF )
122+ d = fromLDIFFile (self .f )
123+ d .addCallback (self .ldifRead )
124+
125+ def ldifRead (self , result ):
126+ self .f .close ()
127+ self .db = result
128+
129+
130+ class LDAPServerFactory (ServerFactory ):
131+ protocol = LDAPServer
132+
133+ def __init__ (self , root ):
134+ self .root = root
135+
136+ def buildProtocol (self , addr ):
137+ proto = self .protocol ()
138+ proto .debug = self .debug
139+ proto .factory = self
140+ return proto
141+
142+
143+ if __name__ == "__main__" :
144+ from twisted .internet import reactor
145+
146+ if len (sys .argv ) == 2 :
147+ port = int (sys .argv [1 ])
148+ else :
149+ port = 389
150+ # First of all, to show logging info in stdout :
151+ log .startLogging (sys .stderr )
152+ # We initialize our tree
153+ tree = Tree ()
154+ # When the LDAP Server protocol wants to manipulate the DIT, it invokes
155+ # `root = interfaces.IConnectedLDAPEntry(self.factory)` to get the root
156+ # of the DIT. The factory that creates the protocol must therefore
157+ # be adapted to the IConnectedLDAPEntry interface.
158+ registerAdapter (lambda x : x .root , LDAPServerFactory , IConnectedLDAPEntry )
159+ factory = LDAPServerFactory (tree .db )
160+ factory .debug = True
161+ application = service .Application ("ldaptor-server" )
162+ myService = service .IServiceCollection (application )
163+ serverEndpointStr = "tcp:{}" .format (port )
164+ e = serverFromString (reactor , serverEndpointStr )
165+ d = e .listen (factory )
166+ reactor .run ()
0 commit comments