diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index ec41848a..632c477a 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -987,7 +987,8 @@ Default: `Radicale - Password Required` _(>= 3.3.0)_ -The URI to the ldap server +URI to the LDAP server. +Mandatory for auth type `ldap`. Default: `ldap://localhost` @@ -995,39 +996,44 @@ Default: `ldap://localhost` _(>= 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 _(>= 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 _(>= 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 _(>= 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 _(>= 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})` @@ -1035,66 +1041,117 @@ Default: `(cn={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 - -_(>= 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) +Default: (unset, in which case the login name is directly used as the username) ##### ldap_use_ssl _(>= 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 _(>= 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 _(>= 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 _(>= 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 _(>= 3.5.1)_ -Add modifyTimestamp and createTimestamp to the exclusion list of internal ldap3 client -so that these schema attributes are not checked. This is needed at least for Authentik -LDAP server as not providing these both attributes. +Quirks for Authentik LDAP server, which violates the LDAP RFCs: +add modifyTimestamp and createTimestamp to the exclusion list of internal ldap3 client +so that these schema attributes are not checked. -Default: false +Default: `false` ##### dovecot_connection_type = AF_UNIX @@ -1177,7 +1234,9 @@ providers like ldap, kerberos 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 @@ -1188,7 +1247,9 @@ providers like ldap, kerberos 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 diff --git a/config b/config index 0e08659b..b51c5dfc 100644 --- a/config +++ b/config @@ -75,46 +75,54 @@ ## Expiration time of caching failed logins in seconds #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 #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## -# 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## -# Password of the reader DN +# Password of the reader DN (better: use 'ldap_secret_file'!) #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 -# the attribute to read the group memberships from in the user's LDAP entry (default: not set) -#ldap_groups_attribute = memberOf - -# The filter to find the DN of the user. This filter must contain a python-style placeholder for the login +# Filter to search for the LDAP entry of the user to authenticate. It must contain '{0}' as placeholder for the login name. #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 -# Use ssl on the ldap connection -# Soon to be deprecated, use ldap_security instead +# Use ssl on the LDAP connection (DEPRECATED - use 'ldap_security'!) #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 -# 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 -# 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 = +# 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) # Note: credentials are transmitted in cleartext #dovecot_connection_type = AF_UNIX diff --git a/radicale/config.py b/radicale/config.py index 77fcb04e..adab9567 100644 --- a/radicale/config.py +++ b/radicale/config.py @@ -261,41 +261,53 @@ DEFAULT_CONFIG_SCHEMA: types.CONFIG_SCHEMA = OrderedDict([ "value": "1", "help": "incorrect authentication delay", "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", { "value": "ldap://localhost", - "help": "URI to the ldap server", + "help": "URI to the LDAP server", "type": str}), ("ldap_base", { "value": "", - "help": "LDAP base DN of the ldap server", + "help": "Base DN of the LDAP server", "type": str}), ("ldap_reader_dn", { "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}), ("ldap_secret", { "value": "", - "help": "the password of the ldap_reader_dn", + "help": "Password of ldap_reader_dn (better: use ldap_secret_file)", "type": str}), ("ldap_secret_file", { "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}), ("ldap_filter", { "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}), ("ldap_user_attribute", { "value": "", - "help": "the attribute to be used as username after authentication", + "help": "Attribute to be used as username after authentication", + "type": str}), + ("ldap_use_ssl", { + "value": "False", + "help": "Use ssl on the LDAP connection. Deprecated, use ldap_security instead!", + "type": bool}), + ("ldap_security", { + "value": "none", + "help": "Encryption mode to be used: *none*|tls|starttls", + "type": str}), + ("ldap_ssl_verify_mode", { + "value": "REQUIRED", + "help": "Certificate verification mode for tls and starttls. NONE, OPTIONAL, default is REQUIRED", + "type": str}), + ("ldap_ssl_ca_file", { + "value": "", + "help": "Path to the CA file in PEM format which is used to certify the server certificate", "type": str}), ("ldap_groups_attribute", { "value": "", - "help": "attribute to read the group memberships from", + "help": "Attribute in the user's LDAP entry to read the group memberships from", "type": str}), ("ldap_group_members_attribute", { "value": "", @@ -309,22 +321,10 @@ DEFAULT_CONFIG_SCHEMA: types.CONFIG_SCHEMA = OrderedDict([ "value": "", "help": "Search filter to search for groups having the user as member. Only if ldap_group_members_attribute is set", "type": str}), - ("ldap_use_ssl", { - "value": "False", - "help": "Use ssl on the ldap connection. Soon to be deprecated, use ldap_security instead", + ("ldap_ignore_attribute_create_modify_timestamp", { + "value": "false", + "help": "Quirk for Authentik LDAP server: ignore modifyTimestamp and createTimestamp attributes.", "type": bool}), - ("ldap_security", { - "value": "none", - "help": "the encryption mode to be used: *none*|tls|starttls", - "type": str}), - ("ldap_ssl_verify_mode", { - "value": "REQUIRED", - "help": "The certificate verification mode. Works for tls and starttls. NONE, OPTIONAL, default is REQUIRED", - "type": str}), - ("ldap_ssl_ca_file", { - "value": "", - "help": "The path to the CA file in pem format which is used to certificate the server certificate", - "type": str}), ("imap_host", { "value": "localhost", "help": "IMAP server hostname: address|address:port|[address]:port|*localhost*",