Skip to content

Instantly share code, notes, and snippets.

@rechner
Last active June 19, 2024 18:38
Show Gist options
  • Save rechner/57c123d243b8adb83ccb1dc94c80847f to your computer and use it in GitHub Desktop.
Save rechner/57c123d243b8adb83ccb1dc94c80847f to your computer and use it in GitHub Desktop.
LDAP Auth script for HomeAssistant
import os
from ldap3 import Server, Connection, ALL, core
# XXX: Update these with settings apropriate to your environment:
# (I use FreeIPA and an homeassistant group assignment)
SERVER = "ipa.example.com"
USERDN = "uid={},cn=users,cn=accounts,dc=example,dc=com"
TIMEOUT = 3
BASEDN = USERDN
SCOPE = "base"
FILTER = "(&(objectClass=person)(memberOf=cn=homeassistant,cn=groups,cn=accounts,dc=example,dc=com))"
ATTRS = ""
def escape_dn_chars(s):
"""
Escape all DN special characters found in s
with a back-slash (see RFC 4514, section 2.4)
"""
if s:
s = s.replace('\\','\\\\')
s = s.replace(',' ,'\\,')
s = s.replace('+' ,'\\+')
s = s.replace('"' ,'\\"')
s = s.replace('<' ,'\\<')
s = s.replace('>' ,'\\>')
s = s.replace(';' ,'\\;')
s = s.replace('=' ,'\\=')
s = s.replace('\000' ,'\\\000')
if s[-1]==' ':
s = ''.join((s[:-1],'\\ '))
if s[0]=='#' or s[0]==' ':
s = ''.join(('\\',s))
return s
if 'username' not in os.environ and 'password' not in os.environ:
print("Need username and password environment variables!")
exit()
USERDN = USERDN.format(escape_dn_chars(os.environ['username']))
BASEDN = BASEDN.format(escape_dn_chars(os.environ['username']))
server = Server(SERVER, get_info=ALL)
try:
conn = Connection(server, USERDN, password=os.environ['password'], auto_bind=True)
print("whoami: {}".format(conn.extend.standard.who_am_i()))
search = conn.search(BASEDN, FILTER)
if search:
print("Search success: {}".format(conn.entries))
exit(0)
else:
print("LDAP bind succeded, but search yielded empty result")
exit(1)
except core.exceptions.LDAPBindError as e:
print(e)
exit(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment