1
0
Fork 0
mirror of https://github.com/Kozea/Radicale.git synced 2025-09-15 20:36:55 +00:00

Merge pull request #1861 from marschap/ldap-group-search

LDAP auth: group memberships based on separate search
This commit is contained in:
Peter Bieringer 2025-09-09 07:33:51 +02:00 committed by GitHub
commit 126b1a13d2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 296 additions and 118 deletions

View file

@ -987,7 +987,8 @@ Default: `Radicale - Password Required`
_(>= 3.3.0)_ _(>= 3.3.0)_
The URI to the ldap server URI to the LDAP server.
Mandatory for auth type `ldap`.
Default: `ldap://localhost` Default: `ldap://localhost`
@ -995,39 +996,44 @@ Default: `ldap://localhost`
_(>= 3.3.0)_ _(>= 3.3.0)_
LDAP base DN of the ldap server. This parameter must be provided if auth type is ldap. Base DN of the LDAP server.
Mandatory for auth type `ldap`.
Default: Default: (unset)
##### ldap_reader_dn ##### ldap_reader_dn
_(>= 3.3.0)_ _(>= 3.3.0)_
The DN of a ldap user with read access to get the user accounts. This parameter must be provided if auth type is ldap. DN of a LDAP user with read access users and - if defined - groups.
Mandatory for auth type `ldap`.
Default: Default: (unset)
##### ldap_secret ##### ldap_secret
_(>= 3.3.0)_ _(>= 3.3.0)_
The password of the ldap_reader_dn. Either this parameter or `ldap_secret_file` must be provided if auth type is ldap. Password of `ldap_reader_dn`.
Mandatory for auth type `ldap` unless `ldap_secret_file` is given.
Default: Default: (unset)
##### ldap_secret_file ##### ldap_secret_file
_(>= 3.3.0)_ _(>= 3.3.0)_
Path of the file containing the password of the ldap_reader_dn. Either this parameter or `ldap_secret` must be provided if auth type is ldap. Path to the file containing the password of `ldap_reader_dn`.
Mandatory for auth type `ldap` unless `ldap_secret` is given.
Default: Default: (unset)
##### ldap_filter ##### ldap_filter
_(>= 3.3.0)_ _(>= 3.3.0)_
The search filter to find the user DN to authenticate by the username. User '{0}' as placeholder for the user name. Filter to search for the LDAP entry of the user to authenticate.
It must contain '{0}' as placeholder for the login name.
Default: `(cn={0})` Default: `(cn={0})`
@ -1035,66 +1041,117 @@ Default: `(cn={0})`
_(>= 3.4.0)_ _(>= 3.4.0)_
The LDAP attribute whose value shall be used as the user name after successful authentication LDAP attribute whose value shall be used as the username after successful authentication.
Default: not set, i.e. the login name given is used directly. If set, you can use flexible logins in `ldap_filter` and still have consolidated usernames,
e.g. to allow login in using mail addresses as an alternative to cn, simply set
```
ldap_filter = (&(objectclass=inetOrgPerson)(|(cn={0})(mail={0})))
ldap_user_attribute = cn
```
Even for simple filter setups, it is recommended to set it in order to get usernames exactly
as they are stored in LDAP and to avoid inconsistencies in the upper-/lower-case spelling of the
login names.
##### ldap_groups_attribute Default: (unset, in which case the login name is directly used as the username)
_(>= 3.4.0)_
The LDAP attribute to read the group memberships from in the authenticated user's LDAP entry.
If set, load the LDAP group memberships from the attribute given
These memberships can be used later on to define rights.
This also gives you access to the group calendars, if they exist.
* The group calendar will be placed under collection_root_folder/GROUPS
* The name of the calendar directory is the base64 encoded group name.
* The group calendar folders will not be created automatically. This must be done manually. In the [LDAP-authentication section of Radicale's wiki](https://github.com/Kozea/Radicale/wiki/LDAP-authentication) you can find a script to create a group calendar.
Use 'memberOf' if you want to load groups on Active Directory and alikes, 'groupMembership' on Novell eDirectory, ...
Default: (unset)
##### ldap_use_ssl ##### ldap_use_ssl
_(>= 3.3.0)_ _(>= 3.3.0)_
Use ssl on the ldap connection (soon to be deprecated, use ldap_security instead) Use ssl on the LDAP connection. **Deprecated**, use `ldap_security` instead**!**
##### ldap_security ##### ldap_security
_(>= 3.5.2)_ _(>= 3.5.2)_
Use encryption on the ldap connection. none, tls, starttls Use encryption on the LDAP connection. One of `none`, `tls`, `starttls`.
Default: none Default: `none`
##### ldap_ssl_verify_mode ##### ldap_ssl_verify_mode
_(>= 3.3.0)_ _(>= 3.3.0)_
The certificate verification mode. Works for tls and starttls. NONE, OPTIONAL or REQUIRED Certificate verification mode for tls and starttls. One of `NONE`, `OPTIONAL`, `REQUIRED`.
Default: REQUIRED Default: `REQUIRED`
##### ldap_ssl_ca_file ##### ldap_ssl_ca_file
_(>= 3.3.0)_ _(>= 3.3.0)_
The path to the CA file in pem format which is used to certificate the server certificate Path to the CA file in PEM format which is used to certify the server certificate
Default: Default: (unset)
##### ldap_groups_attribute
_(>= 3.4.0)_
LDAP attribute in the authenticated user's LDAP entry to read the group memberships from.
E.g. `memberOf` to get groups on Active Directory and alikes, `groupMembership` on Novell eDirectory, ...
If set, get the user's LDAP groups from the attribute given.
For DN-valued attributes, the value of the RDN is used to determine the group names.
The implementation also supports non-DN-valued attributes: their values are taken directly.
The user's group names can be used later on to define rights.
They also give you access to the group calendars, if those exist.
* Group calendars are placed directly under *collection_root_folder*`/GROUPS/`
with the base64-encoded group name as the calendar folder name.
* Group calendar folders are not created automatically.
This must be done manually. In the [LDAP-authentication section of Radicale's wiki](https://github.com/Kozea/Radicale/wiki/LDAP-authentication) you can find a script to create a group calendar.
Default: (unset)
##### ldap_group_members_attribute
_(>= 3.5.6)_
Attribute in the group entries to read the group's members from.
E.g. `member` for groups with objectclass `groupOfNames`.
Using `ldap_group_members_attribute`, `ldap_group_base` and `ldap_group_filter` is an alternative
approach to getting the user's groups. Instead of reading them from `ldap_groups_attribute`
in the user's entry, an additional query is performed to seach for those groups beneath `ldap_group_base`,
that have the user's DN in their `ldap_group_members_attribute` and additionally fulfil `ldap_group_filter`.
As with DN-valued `ldap_groups_attribute`, the value of the RDN is used to determine the group names.
Default: (unset)
##### ldap_group_base
_(>= 3.5.6)_
Base DN to search for groups.
Only necessary if `ldap_group_members_attribute` is set, and if the base DN for groups differs from `ldap_base`.
Default: (unset, in which case `ldap_base` is used as fallback)
##### ldap_group_filter
_(>= 3.5.6)_
Search filter to search for groups having the user DN found as member.
Only necessary `ldap_group_members_attribute` is set, and you want the groups returned to be restricted
instead of all groups the user's DN is in.
Default: (unset)
##### ldap_ignore_attribute_create_modify_timestamp ##### ldap_ignore_attribute_create_modify_timestamp
_(>= 3.5.1)_ _(>= 3.5.1)_
Add modifyTimestamp and createTimestamp to the exclusion list of internal ldap3 client Quirks for Authentik LDAP server, which violates the LDAP RFCs:
so that these schema attributes are not checked. This is needed at least for Authentik add modifyTimestamp and createTimestamp to the exclusion list of internal ldap3 client
LDAP server as not providing these both attributes. so that these schema attributes are not checked.
Default: false Default: `false`
##### dovecot_connection_type = AF_UNIX ##### dovecot_connection_type = AF_UNIX
@ -1177,7 +1234,9 @@ providers like ldap, kerberos
Default: `False` Default: `False`
Note: cannot be enabled together with `uc_username` Notes:
* `lc_username` and `uc_username` are mutually exclusive
* for auth type `ldap` the use of `ldap_user_attribute` is preferred
##### uc_username ##### uc_username
@ -1188,7 +1247,9 @@ providers like ldap, kerberos
Default: `False` Default: `False`
Note: cannot be enabled together with `lc_username` Notes:
* `uc_username` and `lc_username` are mutually exclusive
* for auth type `ldap` the use of `ldap_user_attribute` is preferred
##### strip_domain ##### strip_domain

42
config
View file

@ -75,46 +75,54 @@
## Expiration time of caching failed logins in seconds ## Expiration time of caching failed logins in seconds
#cache_failed_logins_expiry = 90 #cache_failed_logins_expiry = 90
# Ignore modifyTimestamp and createTimestamp attributes. Required e.g. for Authentik LDAP server
#ldap_ignore_attribute_create_modify_timestamp = false
# URI to the LDAP server # URI to the LDAP server
#ldap_uri = ldap://localhost #ldap_uri = ldap://localhost
# The base DN where the user accounts have to be searched # Base DN of the LDAP server to search for user accounts
#ldap_base = ##BASE_DN## #ldap_base = ##BASE_DN##
# The reader DN of the LDAP server # Reader DN of the LDAP server; (needs read access to users and - if defined - groups)
#ldap_reader_dn = CN=ldapreader,CN=Users,##BASE_DN## #ldap_reader_dn = CN=ldapreader,CN=Users,##BASE_DN##
# Password of the reader DN # Password of the reader DN (better: use 'ldap_secret_file'!)
#ldap_secret = ldapreader-secret #ldap_secret = ldapreader-secret
# Path of the file containing password of the reader DN # Path to the file containing the password of the reader DN
#ldap_secret_file = /run/secrets/ldap_password #ldap_secret_file = /run/secrets/ldap_password
# the attribute to read the group memberships from in the user's LDAP entry (default: not set) # Filter to search for the LDAP entry of the user to authenticate. It must contain '{0}' as placeholder for the login name.
#ldap_groups_attribute = memberOf
# The filter to find the DN of the user. This filter must contain a python-style placeholder for the login
#ldap_filter = (&(objectClass=person)(uid={0})) #ldap_filter = (&(objectClass=person)(uid={0}))
# the attribute holding the value to be used as username after authentication # Attribute holding the value to be used as username after authentication
#ldap_user_attribute = cn #ldap_user_attribute = cn
# Use ssl on the ldap connection # Use ssl on the LDAP connection (DEPRECATED - use 'ldap_security'!)
# Soon to be deprecated, use ldap_security instead
#ldap_use_ssl = False #ldap_use_ssl = False
# the encryption mode to be used: tls, starttls, default is none # Encryption mode to be used. Default: none; one of: none, tls, starttls
#ldap_security = none #ldap_security = none
# The certificate verification mode. Works for ssl and starttls. NONE, OPTIONAL, default is REQUIRED # Certificate verification mode for tls & starttls. Default: REQUIRED; one of NONE, OPTIONAL, REQUIRED
#ldap_ssl_verify_mode = REQUIRED #ldap_ssl_verify_mode = REQUIRED
# The path to the CA file in pem format which is used to certificate the server certificate # Path to the CA file in PEM format to certify the server certificate
#ldap_ssl_ca_file = #ldap_ssl_ca_file =
# Attribute in the user's LDAP entry to read the group memberships from; default: not set
#ldap_groups_attribute = memberOf
# Attribute in the group entries to read the group's members from, e.g. member; default: not set
#ldap_group_members_attribute = member
# Base DN to search for groups; only if it differs from 'ldap_base' and if 'ldap_group_members_attribute' is set
#ldap_group_base = ##GROUP_BASE_DN##
# Search filter to search for groups having the user DN found as member; only if 'ldap_group_members_attribute' is set
#ldap_group_filter = (objectclass=groupOfNames)
# Quirks for Authentik LDAP server: ignore modifyTimestamp and createTimestamp attributes
#ldap_ignore_attribute_create_modify_timestamp = false
# Connection type for dovecot authentication (AF_UNIX|AF_INET|AF_INET6) # Connection type for dovecot authentication (AF_UNIX|AF_INET|AF_INET6)
# Note: credentials are transmitted in cleartext # Note: credentials are transmitted in cleartext
#dovecot_connection_type = AF_UNIX #dovecot_connection_type = AF_UNIX

View file

@ -16,20 +16,36 @@
# along with Radicale. If not, see <http://www.gnu.org/licenses/>. # along with Radicale. If not, see <http://www.gnu.org/licenses/>.
""" """
Authentication backend that checks credentials with a LDAP server. Authentication backend that checks credentials with a LDAP server.
Following parameters are needed in the configuration: The following parameters are needed in the configuration:
ldap_uri The LDAP URL to the server like ldap://localhost ldap_uri URI to the LDAP server
ldap_base The baseDN of the LDAP server ldap_base Base DN of the LDAP server
ldap_reader_dn The DN of a LDAP user with read access to get the user accounts ldap_reader_dn DN of an LDAP user with read access to get the user accounts
ldap_secret The password of the ldap_reader_dn ldap_secret Password of the 'ldap_reader_dn'
ldap_secret_file The path of the file containing the password of the ldap_reader_dn Better: use 'ldap_secret_file'!
ldap_filter The search filter to find the user to authenticate by the username ldap_secret_file Path of the file containing the password of the 'ldap_reader_dn'
ldap_user_attribute The attribute to be used as username after authentication ldap_filter Search filter to find the user DN to authenticate
ldap_groups_attribute The attribute containing group memberships in the LDAP user entry The following parameters control TLS connections:
Following parameters controls SSL connections: ldap_use_ssl Use ssl on the ldap connection.
ldap_use_ssl If ssl encryption should be used (to be deprecated) Deprecated, use 'ldap_security' instead!
ldap_security The encryption mode to be used: *none*|tls|starttls ldap_security Encryption mode to be used,
ldap_ssl_verify_mode The certificate verification mode. Works for tls and starttls. NONE, OPTIONAL, default is REQUIRED one of: *none* | tls | starttls
ldap_ssl_ca_file ldap_ssl_verify_mode Certificate verification mode for tls and starttls;
one of: *REQUIRED* | OPTIONAL | NONE
ldap_ssl_ca_file Path to the CA file in PEM format to certify the server certificate
The following parameters are optional:
ldap_user_attribute Attribute to be used as username after authentication, e.g. cn;
if not given, the name used to logon is used.
ldap_groups_attribute Attribute in the user entry to read the user's group memberships from,
e.g. memberof, groupMememberShip. This may even be a non-DN attribute!
ldap_group_base Base DN to search for groups;
only if it differs from 'ldap_base' and if 'ldap_group_members_attribute' is set
ldap_group_filter Search filter to search for groups having the user DN found as member;
only if 'ldap_group_members_attribute' is set
ldap_group_members_attribute Attribute in the group entries to read the group's members from,
e.g. member.
The following parameters are for LDAP servers with oddities
ldap_ignore_attribute_create_modify_timestamp
Ignore modifyTimestamp and createTimestamp attributes. Needed for Authentik LDAP server
""" """
import ssl import ssl
@ -47,7 +63,11 @@ class Auth(auth.BaseAuth):
_ldap_attributes: list[str] = [] _ldap_attributes: list[str] = []
_ldap_user_attr: str _ldap_user_attr: str
_ldap_groups_attr: str _ldap_groups_attr: str
_ldap_group_base: str
_ldap_group_filter: str
_ldap_group_members_attr: str
_ldap_module_version: int = 3 _ldap_module_version: int = 3
_use_encryption: bool = False
_ldap_use_ssl: bool = False _ldap_use_ssl: bool = False
_ldap_security: str = "none" _ldap_security: str = "none"
_ldap_ssl_verify_mode: int = ssl.CERT_REQUIRED _ldap_ssl_verify_mode: int = ssl.CERT_REQUIRED
@ -61,6 +81,7 @@ class Auth(auth.BaseAuth):
except ImportError: except ImportError:
try: try:
import ldap import ldap
import ldap.filter
self._ldap_module_version = 2 self._ldap_module_version = 2
self.ldap = ldap self.ldap = ldap
except ImportError as e: except ImportError as e:
@ -78,6 +99,9 @@ class Auth(auth.BaseAuth):
self._ldap_filter = configuration.get("auth", "ldap_filter") self._ldap_filter = configuration.get("auth", "ldap_filter")
self._ldap_user_attr = configuration.get("auth", "ldap_user_attribute") self._ldap_user_attr = configuration.get("auth", "ldap_user_attribute")
self._ldap_groups_attr = configuration.get("auth", "ldap_groups_attribute") self._ldap_groups_attr = configuration.get("auth", "ldap_groups_attribute")
self._ldap_group_base = configuration.get("auth", "ldap_group_base")
self._ldap_group_filter = configuration.get("auth", "ldap_group_filter")
self._ldap_group_members_attr = configuration.get("auth", "ldap_group_members_attribute")
ldap_secret_file_path = configuration.get("auth", "ldap_secret_file") ldap_secret_file_path = configuration.get("auth", "ldap_secret_file")
if ldap_secret_file_path: if ldap_secret_file_path:
with open(ldap_secret_file_path, 'r') as file: with open(ldap_secret_file_path, 'r') as file:
@ -110,6 +134,19 @@ class Auth(auth.BaseAuth):
logger.info("auth.ldap_groups_attribute: %r" % self._ldap_groups_attr) logger.info("auth.ldap_groups_attribute: %r" % self._ldap_groups_attr)
else: else:
logger.info("auth.ldap_groups_attribute: (not provided)") logger.info("auth.ldap_groups_attribute: (not provided)")
if self._ldap_group_base:
logger.info("auth.ldap_group_base : %r" % self._ldap_group_base)
else:
logger.info("auth.ldap_group_base : (not provided, using ldap_base)")
self._ldap_group_base = self._ldap_base
if self._ldap_group_filter:
logger.info("auth.ldap_group_filter: %r" % self._ldap_group_filter)
else:
logger.info("auth.ldap_group_filter: (not provided)")
if self._ldap_group_members_attr:
logger.info("auth.ldap_group_members_attr: %r" % self._ldap_group_members_attr)
else:
logger.info("auth.ldap_group_members_attr: (not provided)")
if ldap_secret_file_path: if ldap_secret_file_path:
logger.info("auth.ldap_secret_file_path: %r" % ldap_secret_file_path) logger.info("auth.ldap_secret_file_path: %r" % ldap_secret_file_path)
if self._ldap_secret: if self._ldap_secret:
@ -160,6 +197,30 @@ class Auth(auth.BaseAuth):
user_entry = res[0] user_entry = res[0]
user_dn = user_entry[0] user_dn = user_entry[0]
logger.debug(f"_login2 found LDAP user DN {user_dn}") logger.debug(f"_login2 found LDAP user DN {user_dn}")
"""Let's collect the groups of the user."""
groupDNs = []
if self._ldap_groups_attr:
groupDNs = user_entry[1][self._ldap_groups_attr]
"""Search for all groups having the user_dn found as member."""
if self._ldap_group_members_attr:
groupDNs = []
res = conn.search_s(
self._ldap_group_base,
self.ldap.SCOPE_SUBTREE,
filterstr="(&{0}({1}={2}))".format(
self._ldap_group_filter,
self._ldap_group_members_attr,
self.ldap.filter.escape_filter_chars(user_dn)),
attrlist=['1.1']
)
"""Fill groupDNs with DNs of groups found"""
if len(res) > 0:
groupDNs = []
for dn, entry in res:
groupDNs.append(dn)
"""Close LDAP connection""" """Close LDAP connection"""
conn.unbind() conn.unbind()
except Exception as e: except Exception as e:
@ -171,23 +232,26 @@ class Auth(auth.BaseAuth):
conn.protocol_version = 3 conn.protocol_version = 3
conn.set_option(self.ldap.OPT_REFERRALS, 0) conn.set_option(self.ldap.OPT_REFERRALS, 0)
conn.simple_bind_s(user_dn, password) conn.simple_bind_s(user_dn, password)
tmp: list[str] = []
if self._ldap_groups_attr:
tmp = []
for g in user_entry[1][self._ldap_groups_attr]:
"""Get group g's RDN's attribute value"""
try:
rdns = self.ldap.dn.explode_dn(g, notypes=True)
tmp.append(rdns[0])
except Exception:
tmp.append(g.decode('utf8'))
self._ldap_groups = set(tmp)
logger.debug("_login2 LDAP groups of user: %s", ",".join(self._ldap_groups))
if self._ldap_user_attr: if self._ldap_user_attr:
if user_entry[1][self._ldap_user_attr]: if user_entry[1][self._ldap_user_attr]:
tmplogin = user_entry[1][self._ldap_user_attr][0] login = user_entry[1][self._ldap_user_attr][0]
login = tmplogin.decode('utf-8') if isinstance(login, bytes):
login = login.decode('utf-8')
logger.debug(f"_login2 user set to: '{login}'") logger.debug(f"_login2 user set to: '{login}'")
"""Get RDNs of groups' DNs"""
tmp = []
for g in groupDNs:
try:
rdns = self.ldap.dn.explode_dn(g, notypes=True)
tmp.append(rdns[0])
except Exception:
if isinstance(g, bytes):
g = g.decode('utf-8')
tmp.append(g)
self._ldap_groups = set(tmp)
logger.debug("_login2 LDAP groups of user: %s", ",".join(self._ldap_groups))
conn.unbind() conn.unbind()
logger.debug(f"_login2 {login} successfully authenticated") logger.debug(f"_login2 {login} successfully authenticated")
return login return login
@ -249,9 +313,42 @@ class Auth(auth.BaseAuth):
return "" return ""
user_entry = conn.response[0] user_entry = conn.response[0]
conn.unbind()
user_dn = user_entry['dn'] user_dn = user_entry['dn']
logger.debug(f"_login3 found LDAP user DN {user_dn}") logger.debug(f"_login3 found LDAP user DN {user_dn}")
"""Let's collect the groups of the user."""
groupDNs = []
if self._ldap_groups_attr:
if user_entry['attributes'][self._ldap_groups_attr]:
if isinstance(user_entry['attributes'][self._ldap_groups_attr], list):
groupDNs = user_entry['attributes'][self._ldap_groups_attr]
else:
groupDNs.append(user_entry['attributes'][self._ldap_groups_attr])
"""Search for all groups having the user_dn found as member."""
if self._ldap_group_members_attr:
try:
conn.search(
search_base=self._ldap_group_base,
search_filter="(&{0}({1}={2}))".format(
self._ldap_group_filter,
self._ldap_group_members_attr,
self.ldap3.utils.conv.escape_filter_chars(user_dn)),
search_scope=self.ldap3.SUBTREE,
attributes=['1.1']
)
except Exception as e:
"""LDAP search failed: consider it as non-fatal - only groups missing"""
logger.debug(f"_ldap3: LDAP group search failed: {e}")
else:
"""Fill groupDNs with DNs of groups found"""
groupDNs = []
for group in conn.response:
groupDNs.append(group['dn'])
"""Close LDAP connection"""
conn.unbind()
try: try:
"""Try to bind as the user itself""" """Try to bind as the user itself"""
try: try:
@ -264,18 +361,18 @@ class Auth(auth.BaseAuth):
if not conn.bind(read_server_info=False): if not conn.bind(read_server_info=False):
logger.debug(f"_login3 user '{login}' cannot be found") logger.debug(f"_login3 user '{login}' cannot be found")
return "" return ""
tmp: list[str] = []
if self._ldap_groups_attr: """Get RDNs of groups' DNs"""
tmp = [] tmp = []
for g in user_entry['attributes'][self._ldap_groups_attr]: for g in groupDNs:
"""Get group g's RDN's attribute value""" try:
try: rdns = self.ldap3.utils.dn.parse_dn(g)
rdns = self.ldap3.utils.dn.parse_dn(g) tmp.append(rdns[0][1])
tmp.append(rdns[0][1]) except Exception:
except Exception: tmp.append(g)
tmp.append(g) self._ldap_groups = set(tmp)
self._ldap_groups = set(tmp) logger.debug("_login3 LDAP groups of user: %s", ",".join(self._ldap_groups))
logger.debug("_login3 LDAP groups of user: %s", ",".join(self._ldap_groups))
if self._ldap_user_attr: if self._ldap_user_attr:
if user_entry['attributes'][self._ldap_user_attr]: if user_entry['attributes'][self._ldap_user_attr]:
if isinstance(user_entry['attributes'][self._ldap_user_attr], list): if isinstance(user_entry['attributes'][self._ldap_user_attr], list):

View file

@ -261,58 +261,70 @@ DEFAULT_CONFIG_SCHEMA: types.CONFIG_SCHEMA = OrderedDict([
"value": "1", "value": "1",
"help": "incorrect authentication delay", "help": "incorrect authentication delay",
"type": positive_float}), "type": positive_float}),
("ldap_ignore_attribute_create_modify_timestamp", {
"value": "false",
"help": "Ignore modifyTimestamp and createTimestamp attributes. Need if Authentik LDAP server is used.",
"type": bool}),
("ldap_uri", { ("ldap_uri", {
"value": "ldap://localhost", "value": "ldap://localhost",
"help": "URI to the ldap server", "help": "URI to the LDAP server",
"type": str}), "type": str}),
("ldap_base", { ("ldap_base", {
"value": "", "value": "",
"help": "LDAP base DN of the ldap server", "help": "Base DN of the LDAP server",
"type": str}), "type": str}),
("ldap_reader_dn", { ("ldap_reader_dn", {
"value": "", "value": "",
"help": "the DN of a ldap user with read access to get the user accounts", "help": "DN of an LDAP user with read access to users anmd - if defined - groups",
"type": str}), "type": str}),
("ldap_secret", { ("ldap_secret", {
"value": "", "value": "",
"help": "the password of the ldap_reader_dn", "help": "Password of ldap_reader_dn (better: use ldap_secret_file)",
"type": str}), "type": str}),
("ldap_secret_file", { ("ldap_secret_file", {
"value": "", "value": "",
"help": "path of the file containing the password of the ldap_reader_dn", "help": "Path to the file containing the password of ldap_reader_dn",
"type": str}), "type": str}),
("ldap_filter", { ("ldap_filter", {
"value": "(cn={0})", "value": "(cn={0})",
"help": "the search filter to find the user DN to authenticate by the username", "help": "Filter to search for the LDAP entry of the user to authenticate",
"type": str}), "type": str}),
("ldap_user_attribute", { ("ldap_user_attribute", {
"value": "", "value": "",
"help": "the attribute to be used as username after authentication", "help": "Attribute to be used as username after authentication",
"type": str}),
("ldap_groups_attribute", {
"value": "",
"help": "attribute to read the group memberships from",
"type": str}), "type": str}),
("ldap_use_ssl", { ("ldap_use_ssl", {
"value": "False", "value": "False",
"help": "Use ssl on the ldap connection. Soon to be deprecated, use ldap_security instead", "help": "Use ssl on the LDAP connection. Deprecated, use ldap_security instead!",
"type": bool}), "type": bool}),
("ldap_security", { ("ldap_security", {
"value": "none", "value": "none",
"help": "the encryption mode to be used: *none*|tls|starttls", "help": "Encryption mode to be used: *none*|tls|starttls",
"type": str}), "type": str}),
("ldap_ssl_verify_mode", { ("ldap_ssl_verify_mode", {
"value": "REQUIRED", "value": "REQUIRED",
"help": "The certificate verification mode. Works for tls and starttls. NONE, OPTIONAL, default is REQUIRED", "help": "Certificate verification mode for tls and starttls. NONE, OPTIONAL, default is REQUIRED",
"type": str}), "type": str}),
("ldap_ssl_ca_file", { ("ldap_ssl_ca_file", {
"value": "", "value": "",
"help": "The path to the CA file in pem format which is used to certificate the server certificate", "help": "Path to the CA file in PEM format which is used to certify the server certificate",
"type": str}), "type": str}),
("ldap_groups_attribute", {
"value": "",
"help": "Attribute in the user's LDAP entry to read the group memberships from",
"type": str}),
("ldap_group_members_attribute", {
"value": "",
"help": "Attribute in the group entries to read the group's members from",
"type": str}),
("ldap_group_base", {
"value": "",
"help": "Base DN to search for groups. Only if it differs from ldap_base and if ldap_group_members_attribute is set",
"type": str}),
("ldap_group_filter", {
"value": "",
"help": "Search filter to search for groups having the user as member. Only if ldap_group_members_attribute is set",
"type": str}),
("ldap_ignore_attribute_create_modify_timestamp", {
"value": "false",
"help": "Quirk for Authentik LDAP server: ignore modifyTimestamp and createTimestamp attributes.",
"type": bool}),
("imap_host", { ("imap_host", {
"value": "localhost", "value": "localhost",
"help": "IMAP server hostname: address|address:port|[address]:port|*localhost*", "help": "IMAP server hostname: address|address:port|[address]:port|*localhost*",