Python Active Directory Client Library
Python-AD is an Active Directory client library designed for Python on UNIX/Linux systems. It provides a programmatic interface for performing various LDAP and Kerberos operations against Microsoft Active Directory domains. The library currently supports Python 3 environments, with its latest stable release being 2.0.1.
Common errors
-
ldap.INVALID_CREDENTIALS: {'info': '80090308: LdapErr: DSID-0C090334, comment: AcceptSecurityContext error, data 52e, vece'cause The most common causes are incorrect username/password, an account locked out, or an issue with LDAP referrals (where the AD server redirects to another DC but the client fails to re-authenticate).fixVerify the username (often UPN format, e.g., 'user@domain.com') and password. Check if the Active Directory account is locked. If the problem persists, try disabling LDAP referrals in your client configuration if the library allows it, or ensure the client can follow referrals correctly. -
LDAPError: SIZE_LIMIT_EXCEEDED
cause You attempted an LDAP search that returned more than 1,000 entries, hitting Active Directory's default maximum page size for unpaged searches.fixModify your search query to be more specific, or implement paged search results. The underlying `python-ldap` library supports `ldap.controls.SimplePagedResultsControl` for handling large result sets. Refer to `python-ldap` documentation for details on implementing paged results if this library doesn't abstract it fully.
Warnings
- breaking Version 2.0 of `python-active-directory` dropped support for Python 2. Projects requiring Python 2 must use an older major version (e.g., 1.x) or migrate to Python 3.
- gotcha Active Directory by default limits LDAP search results to 1,000 entries. Queries exceeding this limit will result in an error or truncated results if not handled with paged results.
- gotcha Incorrect username format (e.g., missing UPN suffix like `@domain.com`) or issues with LDAP referrals can lead to `ldap.INVALID_CREDENTIALS` errors even with correct passwords.
Install
-
pip install python-active-directory
Imports
- Client
from activedirectory import Client
Quickstart
import os
from activedirectory import Client
# Environment variables for sensitive information
AD_SERVER = os.environ.get('AD_SERVER', 'your.ad.domain.com')
AD_USERNAME = os.environ.get('AD_USERNAME', 'username@your.ad.domain.com')
AD_PASSWORD = os.environ.get('AD_PASSWORD', 'your_password')
AD_BASE_DN = os.environ.get('AD_BASE_DN', 'dc=your,dc=ad,dc=domain,dc=com')
try:
# Initialize the client, assuming typical LDAP over SSL (LDAPS) on port 636
# Note: The exact Client constructor might vary; this is an educated guess based on typical AD client libs.
# Consult official documentation or source code for precise constructor arguments.
ad_client = Client(
host=AD_SERVER,
username=AD_USERNAME,
password=AD_PASSWORD,
base_dn=AD_BASE_DN,
use_ssl=True, # Recommended for production
port=636
)
print(f"Successfully connected to AD server: {AD_SERVER}")
# Example: Search for a user (replace 'testuser' with an actual sAMAccountName)
# The library is expected to provide methods for common AD operations.
# This part is illustrative as specific methods are not detailed in public search results for 'theatlantic' fork.
# For a real implementation, you'd call a search_user or find_object method if available.
# For demonstration, let's assume a basic search capability for an object by its sAMAccountName.
# The actual implementation would require diving into the library's available methods.
print(f"\nAttempting to find user with sAMAccountName: {AD_USERNAME.split('@')[0]}")
# In a real scenario, you'd use a dedicated search method like:
# user_found = ad_client.search_user(sAMAccountName=AD_USERNAME.split('@')[0])
# For a simple connection test without specific search methods, we'll just confirm connection.
# To perform actual searches, you would typically use methods exposed by the Client object,
# often involving LDAP filters.
# Example of a generic search (hypothetical method):
# results = ad_client.search(base_dn=AD_BASE_DN, filter=f'(sAMAccountName={AD_USERNAME.split('@')[0]})')
# if results:
# print(f"Found user: {results[0].get('cn')}")
# else:
# print("User not found.")
# If the Client object itself doesn't expose a direct 'search' method for this quickstart,
# we will just confirm the connection was successful.
print("Basic AD client initialized. Further operations depend on specific library methods.")
except Exception as e:
print(f"Error connecting or interacting with Active Directory: {e}")
print("Ensure AD_SERVER, AD_USERNAME, AD_PASSWORD, and AD_BASE_DN are correctly set.")