Batch 3: SQL Databases LDAP YAML ← Full TOC

← LDAP Index

🐍 Python LDAP — python-ldap and ldap3 — search, add, modify entries

Python connects to LDAP using python-ldap (binds to C library) or ldap3 (pure Python, easier to install). Both support all LDAP operations. ldap3 is recommended for new projects.

📋 Reference

ItemSyntax / ValueDescription
ldap3.ServerServer('ldap.example.com', port=389, use_ssl=False)Define LDAP server
ldap3.ConnectionConnection(server, user=dn, password=pw, auto_bind=True)Create connection and bind
conn.searchconn.search(base_dn, filter, attributes=['*'])Search directory
conn.entriesconn.entriesList of Entry objects from last search
entry.attributeentry.cn.value / entry.mail.valuesAccess attribute value(s)
conn.addconn.add(dn, object_class, attributes={})Add new entry
conn.modifyconn.modify(dn, {'attr': [(MODIFY_REPLACE, ['val'])]})Modify entry
conn.deleteconn.delete(dn)Delete entry
conn.modify_dnconn.modify_dn(dn, new_rdn)Rename or move entry
MODIFY_ADDldap3.MODIFY_ADDAdd attribute value
MODIFY_REPLACEldap3.MODIFY_REPLACEReplace attribute value(s)
MODIFY_DELETEldap3.MODIFY_DELETEDelete attribute value(s)
SUBTREEldap3.SUBTREESearch scope: subtree
LEVELldap3.LEVELSearch scope: one level (direct children)
BASEldap3.BASESearch scope: base entry only
ALL_ATTRIBUTESldap3.ALL_ATTRIBUTESReturn all user attributes
ALL_OPERATIONAL_ATTRIBUTESldap3.ALL_OPERATIONAL_ATTRIBUTESReturn operational attributes
conn.resultconn.resultResult dict from last operation
conn.responseconn.responseRaw response from last search
paged_searchconn.extend.standard.paged_search(...)Handle large result sets with pagination
start_tlsconn.start_tls()Upgrade to TLS after connecting
ldap3.SAFE_SYNCConnection(..., client_strategy=SAFE_SYNC)Thread-safe strategy
Authenticateconn.bind() with user credentialsVerify username/password against LDAP

💡 Example

# pip install ldap3

from ldap3 import Server, Connection, ALL, MODIFY_REPLACE, MODIFY_ADD, MODIFY_DELETE, SUBTREE

LDAP_HOST     = "ldap://localhost"
BASE_DN       = "dc=mywebuniversity,dc=com"
ADMIN_DN      = "cn=admin,dc=mywebuniversity,dc=com"
ADMIN_PW      = "admin_password"
USERS_OU      = f"ou=users,{BASE_DN}"
GROUPS_OU     = f"ou=groups,{BASE_DN}"

# ── 1. Connect ────────────────────────────────────────────────
server = Server(LDAP_HOST, get_info=ALL)
conn   = Connection(server, user=ADMIN_DN, password=ADMIN_PW, auto_bind=True)
print("Connected:", conn.bound)
print("Server info:", server.info.vendor_name if server.info else "OpenLDAP")

# ── 2. Search users ───────────────────────────────────────────
print("\n=== All Users ===")
conn.search(
    search_base   = USERS_OU,
    search_filter = "(objectClass=inetOrgPerson)",
    attributes    = ["uid", "cn", "mail", "title", "departmentNumber"]
)
for entry in conn.entries:
    dept  = entry.departmentNumber.value if entry.departmentNumber else "N/A"
    title = entry.title.value if entry.title else "N/A"
    print(f"  {str(entry.uid):12} {str(entry.cn):20} {str(entry.mail):30} {title}")

# ── 3. Find specific user ─────────────────────────────────────
conn.search(USERS_OU, "(uid=alice)", attributes=["*"])
if conn.entries:
    alice = conn.entries[0]
    print(f"\nAlice's DN: {alice.entry_dn}")
    print(f"Email: {alice.mail.value}")

# ── 4. Authenticate user (check password) ─────────────────────
def authenticate_user(username, password):
    user_dn = f"uid={username},{USERS_OU}"
    try:
        test_conn = Connection(server, user=user_dn, password=password, auto_bind=True)
        test_conn.unbind()
        return True
    except Exception:
        return False

print("\nAuth alice/correct:", authenticate_user("alice", "correct_password"))
print("Auth alice/wrong:  ", authenticate_user("alice", "wrong_password"))

# ── 5. Add new user ───────────────────────────────────────────
new_user_dn = f"uid=eve,{USERS_OU}"
conn.add(new_user_dn,
    object_class = ["top","person","organizationalPerson","inetOrgPerson","posixAccount"],
    attributes   = {
        "uid":          "eve",
        "cn":           "Eve Martinez",
        "sn":           "Martinez",
        "givenName":    "Eve",
        "mail":         "eve@mywebuniversity.com",
        "title":        "Data Scientist",
        "uidNumber":    "10005",
        "gidNumber":    "5000",
        "homeDirectory":"/home/eve",
        "loginShell":   "/bin/bash",
    }
)
print("\nAdd result:", conn.result["description"])

# ── 6. Modify entry ───────────────────────────────────────────
conn.modify(new_user_dn, {
    "telephoneNumber": [(MODIFY_ADD, ["+1-555-0105"])],
    "title":           [(MODIFY_REPLACE, ["Senior Data Scientist"])],
})
print("Modify result:", conn.result["description"])

# ── 7. Add to group ───────────────────────────────────────────
group_dn = f"cn=developers,{GROUPS_OU}"
conn.modify(group_dn, {
    "member": [(MODIFY_ADD, [new_user_dn])]
})
print("Add to group:", conn.result["description"])

# ── 8. Delete user ────────────────────────────────────────────
# Remove from group first
conn.modify(group_dn, {"member": [(MODIFY_DELETE, [new_user_dn])]})
conn.delete(new_user_dn)
print("Delete result:", conn.result["description"])

conn.unbind()
print("\nDisconnected.")
# python3 ldap_demo.py  (requires running OpenLDAP server)

← ldapsearch & CLI  |  🏠 Index  |  Active Directory →