This commit is contained in:
2026-10-29 13:28:11 -04:00
parent 7ec64194e5
commit 0bffd7d993
19 changed files with 1750 additions and 7 deletions
+10 -2
View File
@@ -21,11 +21,17 @@ class LDAPServiceBindError(LDAPException):
@contextmanager
def connection():
with _connection(settings.LDAP_BIND_DN, settings.LDAP_BIND_PASSWORD, service=True) as conn:
yield conn
@contextmanager
def _connection(bind_dn, password, *, service=False):
url = urlsplit(settings.LDAP_URL)
if url.scheme not in {"ldap", "ldaps"} or not url.hostname or not settings.LDAP_BIND_DN or not settings.LDAP_BIND_PASSWORD or not settings.LDAP_ACCOUNT_BASE_DN:
if url.scheme not in {"ldap", "ldaps"} or not url.hostname or not bind_dn or not password or not settings.LDAP_ACCOUNT_BASE_DN:
raise ImproperlyConfigured("Configure LDAP URL, service bind, and account base DN.")
server = Server(url.hostname, port=url.port or (636 if url.scheme == "ldaps" else 389), use_ssl=url.scheme == "ldaps", tls=Tls(validate=ssl.CERT_REQUIRED, ca_certs_file=settings.LDAP_CA_CERT_FILE, version=ssl.PROTOCOL_TLS_CLIENT), connect_timeout=5)
conn = Connection(server, user=settings.LDAP_BIND_DN, password=settings.LDAP_BIND_PASSWORD, raise_exceptions=True, receive_timeout=8, auto_referrals=False)
conn = Connection(server, user=bind_dn, password=password, raise_exceptions=True, receive_timeout=8, auto_referrals=False)
try:
conn.open()
# Plaintext requires explicit operator consent; LDAPS is never downgraded.
@@ -34,6 +40,8 @@ def connection():
try:
bound = conn.bind()
except LDAPInvalidCredentialsResult:
if not service:
raise ValueError("Current password could not be verified.") from None
# Do not expose server diagnostics or retry with a user's password.
raise LDAPServiceBindError("Check LDAP_BIND_DN and LDAP_BIND_PASSWORD: use the service account's plaintext password, not its stored hash.") from None
if not bound: