Skip to content

Instantly share code, notes, and snippets.

@Ferenc-
Created March 27, 2017 12:46
Show Gist options
  • Save Ferenc-/d2c0b28247b114746a14b2d1ef08d9e0 to your computer and use it in GitHub Desktop.
Save Ferenc-/d2c0b28247b114746a14b2d1ef08d9e0 to your computer and use it in GitHub Desktop.
Minimal ldaptor
#!/usr/bin/env python2
import ldaptor.interfaces
import ldaptor.protocols.ldap.ldapserver
import ldaptor.protocols.ldap.ldaperrors
from ldaptor import inmemory
import twisted.python
import twisted.internet
import threading
import time
# TODO: Toggle the commenting in lines 17-19 to test:
# https://github.com/studio-ousia/mprpc/issues/33
from gevent.server import StreamServer
from mprpc import RPCServer
# import msgpackrpc
class LDAPConnectionListener(twisted.internet.protocol.ServerFactory):
def __init__(self, port, root):
self.__port = port
self.root = root
self.protocol = ldaptor.protocols.ldap.ldapserver.LDAPServer
twisted.internet.reactor.callFromThread(self.__start)
def connectionMade(self, connection):
twisted.python.log.msg(
self.__port, ': New connection accepted. Connection ID =')
def connectionLost(self, connection):
twisted.python.log.msg(
self.__port, ': Connection lost. Connection ID =')
def stop(self):
twisted.internet.reactor.callFromThread(self.__stop)
def __start(self):
self.__listener = twisted.internet.reactor.listenTCP(
port=self.__port, factory=self, interface='::0')
def __stop(self):
twisted.internet.defer.maybeDeferred(
self.__listener.stopListening)
twisted.python.components.registerAdapter(
lambda ldapServerFactory: ldapServerFactory.root,
LDAPConnectionListener, ldaptor.interfaces.IConnectedLDAPEntry)
# TODO: Toggle the commenting in lines 56-57 to test:
# https://github.com/studio-ousia/mprpc/issues/33
class LDAPServer(RPCServer):
# class LDAPServer(object):
def __init__(self):
self.__listeners_for_ports = {}
def initiate_starting_ldap_server(self, port):
twisted.python.log.msg(
'Starting ldap server(' + str(port) + ')')
root = inmemory.ReadOnlyInMemoryLDAPEntry(
'dc=local', {'dc': ['local'],
'objectClass': ['top',
'organizationalUnit']})
root.addChild(
'uid=user', {'uid': ['user'],
'objectClass': ['person',
'organizationalPerson',
'inetOrgPerson'],
'userPassword': ['passwordSecret']})
self.__listeners_for_ports[port] = LDAPConnectionListener(port, root)
def initiate_stopping_ldap_server(self, port):
twisted.python.log.msg('Stopping LDAP server(', port, ')')
self.__listeners_for_ports[port].stop()
def get_forwarded_names(self):
return [name for name in dir(self) if name[0] != '_']
class TwistedThread(object):
def __init__(self):
self.__should_stop = threading.Event()
self.__should_stop.clear()
self.__thread = threading.Thread(target=self._setup)
self.__thread.start()
def _setup(self):
def stopOnCondition(flag):
if flag.is_set():
twisted.internet.reactor.stop()
loop = twisted.internet.task.LoopingCall(stopOnCondition,
self.__should_stop)
loop.start(0.1)
twisted.internet.reactor.run(installSignalHandlers=0)
def shutdown_reactor(self):
self.__should_stop.set()
if self.__thread is not None:
self.__thread.join()
if __name__ == '__main__':
import argparse
import sys
parser = argparse.ArgumentParser(description='Ldaptor based LDAP server.')
parser.add_argument(
'-b', '--background', action='store_true', help='Start in background.')
args = parser.parse_args()
try:
twisted_thread = TwistedThread()
ldapServer = LDAPServer()
if not args.background:
twisted.python.log.startLogging(sys.stderr)
ldapServer.initiate_starting_ldap_server(10389)
if args.background:
# TODO: Toggle the commenting in lines 131-136 to test:
# https://github.com/studio-ousia/mprpc/issues/33
# server = msgpackrpc.Server(ldapServer)
# server.listen(msgpackrpc.Address('127.0.0.1', 6666))
# server.start()
stream_server = StreamServer(
('127.0.0.1', 6666), ldapServer)
stream_server.serve_forever()
else:
while True:
time.sleep(365 * 24 * 60 * 60)
except KeyboardInterrupt:
pass
finally:
twisted_thread.shutdown_reactor()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment