# Which LDAP Library Does Doom Use? A Complete Guide to ldap3 Integration

> Discover which LDAP library Doom uses for Active Directory authentication and directory queries. Explore the pure-Python ldap3 integration in this detailed guide.

- Repository: [000pp/doom](https://github.com/000pp/doom)
- Tags: deep-dive
- Published: 2026-02-22

---

**Doom utilizes the pure-Python `ldap3` library to handle all LDAP and LDAPS connections, importing it in [`src/doom/protocols/ldap.py`](https://github.com/000pp/doom/blob/main/src/doom/protocols/ldap.py) to manage Active Directory authentication and directory queries.**

The open-source Doom project (available at `000pp/doom`) requires robust directory services integration to authenticate users against Active Directory environments. To accomplish this, the project leverages `ldap3` as its primary LDAP library, providing a pure-Python implementation of the LDAP protocol that supports both standard LDAP and secure LDAPS connections.

## Why Doom Uses ldap3 as Its LDAP Library

Doom selects `ldap3` over alternative libraries like `python-ldap` because it offers several critical advantages for Active Directory integration. The library provides native support for **NTLM authentication**, which is essential for Windows domain environments. Additionally, `ldap3` implements comprehensive **TLS/SSL configuration options** through the `ldap3.Tls` class, enabling secure LDAPS connections on port 636 while maintaining fallback compatibility with standard LDAP on port 389.

As a pure-Python implementation, `ldap3` eliminates the need for system-level C library dependencies, making Doom more portable across different operating systems and deployment environments.

## How Doom Implements ldap3 in [`src/doom/protocols/ldap.py`](https://github.com/000pp/doom/blob/main/src/doom/protocols/ldap.py)

The core LDAP functionality resides in [`src/doom/protocols/ldap.py`](https://github.com/000pp/doom/blob/main/src/doom/protocols/ldap.py), where Doom wraps `ldap3` primitives into higher-level helper functions. This abstraction layer handles connection lifecycle management, error handling, and safe attribute retrieval.

### Core Imports and Dependencies

At the module level, Doom imports the essential `ldap3` components alongside Python's built-in `ssl` module for TLS configuration:

```python
import ldap3                     # ← LDAP library

import ssl
from ldap3.core.exceptions import (
    LDAPBindError,
    LDAPInvalidCredentialsResult,
    LDAPCursorAttributeError,
)

```

These imports provide the foundation for creating server definitions, managing encrypted connections, and handling specific LDAP error conditions that occur during authentication failures or attribute retrieval issues.

### Establishing Connections with `get_ldap_connection`

Doom centralizes connection logic in the `get_ldap_connection` function, which orchestrates `ldap3.Server` and `ldap3.Connection` objects to establish authenticated sessions. The function attempts standard LDAP connections first, then automatically falls back to LDAPS if the initial connection fails.

```python
from doom.protocols.ldap import get_ldap_connection

host = "dc.example.com"
username = "jdoe"
password = "Password123"
domain = "EXAMPLE"

conn, base_dn = get_ldap_connection(host, username, password, domain)
print(f"Connected to {conn.server.host} – Base DN: {base_dn}")

```

This wrapper handles the complexity of server discovery, TLS negotiation, and NTLM credential formatting, returning both the active `ldap3.Connection` instance and the discovered Base DN for subsequent queries.

### Safe Attribute Retrieval with `safe_ldap_attr`

When processing LDAP entries, Doom uses the `safe_ldap_attr` helper to safely extract attributes without raising exceptions on missing fields. This function wraps `ldap3` cursor operations to provide default fallback values.

```python
from doom.protocols.ldap import safe_ldap_attr

entry = conn.search(search_base=base_dn,
                    search_filter="(sAMAccountName=jdoe)",
                    attributes=["mail", "displayName"],
                    size_limit=1)

if conn.entries:
    email = safe_ldap_attr(conn.entries[0], "mail", fallback="noemail@example.com")
    print(f"E‑mail: {email}")

```

This approach prevents `LDAPCursorAttributeError` from disrupting execution flow when directory entries contain incomplete attribute sets.

## Working with LDAP and LDAPS in Doom

Doom leverages `ldap3.Tls` to configure custom TLS parameters when connecting to LDAPS servers. This allows fine-grained control over certificate validation, protocol versions, and cipher suites.

```python
import ssl
import ldap3

tls = ldap3.Tls(validate=ssl.CERT_NONE,
                version=ssl.PROTOCOL_TLSv1_2,
                ciphers="ALL:@SECLEVEL=0")
ldaps_server = ldap3.Server("ldaps://dc.example.com",
                            port=636,
                            use_ssl=True,
                            get_info=ldap3.ALL,
                            tls=tls)

```

This configuration demonstrates how Doom handles enterprise environments with custom certificate authorities or specific security policy requirements, utilizing `ldap3`'s comprehensive TLS support.

## Dependency Management: Where ldap3 Is Declared

The `ldap3` library is declared as a runtime dependency in [`pyproject.toml`](https://github.com/000pp/doom/blob/main/pyproject.toml), ensuring it installs automatically when deploying Doom. This dependency specification guarantees that the pure-Python implementation is available across all supported platforms without requiring additional system libraries or compilation steps.

## Summary

- Doom utilizes the **`ldap3`** library as its primary LDAP implementation for Active Directory integration.
- All LDAP operations are centralized in **[`src/doom/protocols/ldap.py`](https://github.com/000pp/doom/blob/main/src/doom/protocols/ldap.py)**, which wraps `ldap3.Server` and `ldap3.Connection` classes.
- The library supports both **standard LDAP (port 389)** and **LDAPS (port 636)** with customizable TLS configurations via `ldap3.Tls`.
- Helper functions **`get_ldap_connection`** and **`safe_ldap_attr`** abstract connection management and safe attribute retrieval.
- `ldap3` is listed as a runtime dependency in **[`pyproject.toml`](https://github.com/000pp/doom/blob/main/pyproject.toml)**, providing cross-platform compatibility through its pure-Python implementation.

## Frequently Asked Questions

### What LDAP library does Doom use?

Doom uses the **`ldap3`** Python package, a pure-Python implementation of the LDAP protocol. This library is imported in [`src/doom/protocols/ldap.py`](https://github.com/000pp/doom/blob/main/src/doom/protocols/ldap.py) and provides the `Server`, `Connection`, and `Tls` classes that Doom uses to establish authenticated connections with Active Directory servers.

### Does Doom support LDAPS connections?

Yes, Doom fully supports LDAPS (LDAP over SSL) on port 636. The implementation uses `ldap3.Tls` to configure TLS parameters, allowing customization of certificate validation, protocol versions, and cipher suites. The `get_ldap_connection` function automatically attempts LDAPS fallback when standard LDAP connections fail.

### Where is the LDAP configuration handled in Doom?

All LDAP functionality is centralized in **[`src/doom/protocols/ldap.py`](https://github.com/000pp/doom/blob/main/src/doom/protocols/ldap.py)**. This module contains the core helper functions `get_ldap_connection` for establishing server connections and `safe_ldap_attr` for retrieving entry attributes safely. The module handles TLS configuration, NTLM authentication formatting, and exception handling for the entire application.

### Is the ldap3 library a pure Python implementation?

Yes, `ldap3` is a **pure-Python** implementation of the LDAP protocol. This design choice eliminates dependencies on system-level C libraries (unlike `python-ldap`), making Doom more portable across Windows, Linux, and macOS environments. The pure-Python nature is confirmed by the package's declaration in [`pyproject.toml`](https://github.com/000pp/doom/blob/main/pyproject.toml) as a standard runtime dependency.