{"id":4609,"library":"ldaptor","title":"Ldaptor: Twisted LDAP Library","description":"Ldaptor is a pure-Python library built on Twisted, implementing LDAP client logic, BER protocol message parsing, filter generation, and LDIF data generation. It also includes command-line utilities for LDAP interactions. The current version, 21.2.0, was released in February 2021, and the project is in a maintenance phase, focusing on bug fixes and compatibility with newer Python and Twisted releases.","status":"maintenance","version":"21.2.0","language":"en","source_language":"en","source_url":"https://github.com/twisted/ldaptor","tags":["ldap","twisted","networking","authentication","directory-service"],"install":[{"cmd":"pip install ldaptor","lang":"bash","label":"Install Ldaptor"}],"dependencies":[{"reason":"Core asynchronous networking framework dependency for client/server protocols.","package":"Twisted[tls]","optional":false},{"reason":"Used for parsing LDAP filters and other protocol elements.","package":"pyparsing","optional":false},{"reason":"Used for Samba password manipulation; optional if not using Samba features.","package":"passlib","optional":true},{"reason":"Required for registering implementers of Twisted interfaces.","package":"zope.interface","optional":false},{"reason":"Historically used for Python 2/3 compatibility; listed as a dependency in PyPI for 21.2.0.","package":"six","optional":false}],"imports":[{"symbol":"LDAPClientCreator","correct":"from ldaptor.protocols.ldap import ldapconnector"},{"symbol":"LDAPClient","correct":"from ldaptor.protocols.ldap import ldapclient"},{"symbol":"LDAPEntry","correct":"from ldaptor.protocols.ldap import ldapsyntax"},{"symbol":"reactor, defer","correct":"from twisted.internet import reactor, defer"}],"quickstart":{"code":"import os\nfrom twisted.internet import reactor, defer\nfrom ldaptor.protocols.ldap import ldapclient, ldapsyntax, ldapconnector\n\n@defer.inlineCallbacks\ndef example():\n    # Note: For production, load sensitive data securely (e.g., from environment variables).\n    # It is recommended to use byte strings for ldaptor objects.\n    server_ip = os.environ.get('LDAP_SERVER_IP', '127.0.0.1').encode('utf-8')\n    basedn = os.environ.get('LDAP_BASE_DN', 'dc=example,dc=com').encode('utf-8')\n    binddn = os.environ.get('LDAP_BIND_DN', 'cn=admin,dc=example,dc=com').encode('utf-8')\n    bindpw = os.environ.get('LDAP_BIND_PASSWORD', 'secret').encode('utf-8')\n    query = os.environ.get('LDAP_QUERY', '(objectClass=*)').encode('utf-8')\n\n    # Create an LDAP client creator\n    c = ldapconnector.LDAPClientCreator(reactor, ldapclient.LDAPClient)\n    \n    # Define overrides for connecting to the LDAP server\n    overrides = {basedn: (server_ip, 389)}\n\n    # Connect to the LDAP server\n    client = yield c.connect(basedn, overrides=overrides)\n    print(f\"Connected to LDAP server at {server_ip.decode('utf-8')}\")\n\n    # Bind to the LDAP server\n    yield client.bind(binddn, bindpw)\n    print(f\"Bound as {binddn.decode('utf-8')}\")\n\n    # Perform a search\n    o = ldapsyntax.LDAPEntry(client, basedn)\n    results = yield o.search(filterText=query)\n    print(f\"Found {len(results)} entries for query '{query.decode('utf-8')}'\")\n    \n    # Print LDIF for each result\n    for entry in results:\n        print(entry.getLDIF())\n\n    print(\"LDAP operations complete.\")\n\n\nif __name__ == '__main__':\n    df = example()\n    df.addErrback(lambda err: err.printTraceback())\n    df.addCallback(lambda _: reactor.stop())\n    reactor.run()\n","lang":"python","description":"This quickstart demonstrates how to connect to an LDAP server, bind with credentials, and perform a basic search operation using Ldaptor and Twisted's asynchronous reactor. The example uses environment variables for sensitive connection details, falling back to defaults if not set. Remember to replace placeholder values with your actual LDAP server details."},"warnings":[{"fix":"Upgrade to Python 3.6 or newer to use Ldaptor versions beyond 21.2.0.","message":"Ldaptor version 21.2.0 is the last release to officially support Python 3.5. Future versions, starting with 21.2.1, explicitly drop support for Python 3.5.","severity":"breaking","affected_versions":">=21.2.1"},{"fix":"Migrate your application to Python 3 and use Ldaptor versions 20.1.0 or newer.","message":"Support for Python 2 was dropped in Ldaptor version 20.1.0. All subsequent versions require Python 3.x.","severity":"breaking","affected_versions":">=20.1.0"},{"fix":"Ensure all string literals passed to Ldaptor objects are prefixed with `b` for byte strings. Encode string variables to bytes using `.encode('utf-8')`.","message":"When working with Ldaptor objects that represent LDAP strings (like DNs, filters, or server IPs), it is strongly recommended to use byte strings (e.g., `b'dc=example,dc=com'`) rather than unicode strings, especially for compatibility and protocol-level operations.","severity":"gotcha","affected_versions":"All versions"},{"fix":"For consuming Ldaptor, prefer `pip install ldaptor` which uses `whl` distributions. For developers/packagers, adapt build processes away from relying on `setup.py` directly or `sdist`.","message":"The `setup.py` file and `sdist` (source distribution) are deprecated for packaging Ldaptor, with `setup.py` planned for removal in a future release. PyPI releases are now managed via GitHub Actions and built with `pep517` for `whl` packages.","severity":"deprecated","affected_versions":">=20.0.0"},{"fix":"Upgrade to Ldaptor 21.2.0 or newer to resolve `cStringIO`-related import errors.","message":"Prior to version 21.2.0, there were `ModuleNotFoundError` issues related to `cStringIO` in the `ldaptor-ldap2pdns` script, indicating potential compatibility problems with Python 3's `io` module.","severity":"gotcha","affected_versions":"<21.2.0"},{"fix":"When using LDAP proxies or debugging, be aware of this. For proxies, consider subclassing `ldaptor.protocols.ldap.proxybase.ProxyBase` and patching the `__repr__` of `LDAPBindRequest` to mask sensitive information, as shown in Ldaptor's documentation for LDAP proxies.","message":"By default, the `__repr__` method of `ldaptor.protocols.pureldap.LDAPBindRequest` can print the BIND password in logs. This is a security risk for applications logging protocol details.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-12T00:00:00.000Z","next_check":"2026-07-11T00:00:00.000Z"}