From bd90a3a426d8a2466311a7a712113624fc7b5986 Mon Sep 17 00:00:00 2001 From: Valentin Tolmer Date: Fri, 29 Apr 2022 09:46:46 +0200 Subject: [PATCH] ldap: return actual "cn" value instead of "uid" in LDAP messages --- example_configs/authelia_config.yml | 2 +- example_configs/bookstack.env.example | 4 ++-- example_configs/dolibarr.md | 25 ++++++++++++------------ example_configs/jellyfin.md | 14 +++++++++++++- example_configs/jitsi_meet.conf | 2 +- example_configs/keycloak.md | 2 +- server/src/infra/ldap_handler.rs | 28 +++++++++++++++------------ 7 files changed, 46 insertions(+), 31 deletions(-) diff --git a/example_configs/authelia_config.yml b/example_configs/authelia_config.yml index 7855bbe..7e6da0a 100644 --- a/example_configs/authelia_config.yml +++ b/example_configs/authelia_config.yml @@ -42,6 +42,6 @@ authentication_backend: display_name_attribute: displayName # The username and password of the admin user. # "admin" should be the admin username you set in the LLDAP configuration - user: cn=admin,ou=people,dc=example,dc=com + user: uid=admin,ou=people,dc=example,dc=com # Password can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html password: 'REPLACE_ME' diff --git a/example_configs/bookstack.env.example b/example_configs/bookstack.env.example index 530ad39..aabfd03 100644 --- a/example_configs/bookstack.env.example +++ b/example_configs/bookstack.env.example @@ -16,13 +16,13 @@ LDAP_BASE_DN=ou=people,dc=example,dc=com # The full DN and password of the user used to search the server # Can both be left as false to bind anonymously -LDAP_DN=cn=admin,ou=people,dc=example,dc=com +LDAP_DN=uid=admin,ou=people,dc=example,dc=com LDAP_PASS=YOUR-ADMIN-PASSWORD-HERE # A filter to use when searching for users # The user-provided user-name used to replace any occurrences of '${user}' # If you're setting this option via other means, such as within a docker-compose.yml, -# you may need escape the $, often using $$ or \$ instead. +# you may need escape the $, often using $$ or \$ instead. LDAP_USER_FILTER=(&(uid=${user})) # Set the LDAP version to use when connecting to the server diff --git a/example_configs/dolibarr.md b/example_configs/dolibarr.md index 2f4047d..619c59f 100644 --- a/example_configs/dolibarr.md +++ b/example_configs/dolibarr.md @@ -4,7 +4,7 @@ This example will help you to create user in dolibarr from your users in your ll ## To connect ldap->dolibarr -In Dolibarr, install the LDAP module from Home -> Modules/Applications +In Dolibarr, install the LDAP module from `Home` -> `Modules/Applications` Go to the configuration of this module and fill it like this: @@ -17,24 +17,23 @@ Go to the configuration of this module and fill it like this: - Server port: port `3890` - Server DN: `dc=example,dc=com` - Use TLS: `No` - - Administrator DN: `cn=admin,ou=people,dc=example,dc=com` + - Administrator DN: `uid=admin,ou=people,dc=example,dc=com` - Administrator password: `secret` Click on modify then "TEST LDAP CONNECTION". You should get this result on the bottom: ``` TCP connect to LDAP server successful (Server=ldap://example.com, Port=389) -Connect/Authenticate to LDAP server successful (Server=ldap://example.com, Port=389, Admin=cn=admin,ou=people,dc=example,dc=com, Password=**********) +Connect/Authenticate to LDAP server successful (Server=ldap://example.com, Port=389, Admin=uid=admin,ou=people,dc=example,dc=com, Password=**********) LDAP server configured for version 3 ``` -And two new tabs will appear on the top: -Users and Groups +And two new tabs will appear on the top: `Users` and `Groups`. -We will use only Users in this example to get the users we want to import. -The tab Groups would be to import groups. +We will use only `Users` in this example to get the users we want to import. +The tab `Groups` would be to import groups. -Click on the Users tab and fill it like this: +Click on the `Users` tab and fill it like this: - Users' DN: `ou=people,dc=example,dc=com` - List of objectClass: `person` - Search filter: `memberOf=cn=yournamegroup,ou=groups,dc=example,dc=com` @@ -47,20 +46,20 @@ Click on the Users tab and fill it like this: - Login `uid` - Email address `mail` -Click on "MODIFY" and then on "TEST A LDAP SEARCH" +Click on "MODIFY" and then on "TEST A LDAP SEARCH". You should get the number of users in the group or all users if you didn't use a filter. ## To import ldap users into the dolibarr database (needed to login with those users): -Navigate to Users & Groups -> New Users +Navigate to `Users & Groups` -> `New Users`. Click on the blank form "Users in LDAP database", you will get the list of the users in the group filled above. With the "GET" button, you will import the selected user. ## To enable LDAP login: -Modify your `conf.php` in your dolibarr folder in `htdocs/conf` +Modify your `conf.php` in your dolibarr folder in `htdocs/conf`. Replace ``` // Authentication settings @@ -76,9 +75,9 @@ $dolibarr_main_auth_ldap_host='ldap://127.0.0.1:3890'; $dolibarr_main_auth_ldap_port='3890'; $dolibarr_main_auth_ldap_version='3'; $dolibarr_main_auth_ldap_servertype='openldap'; -$dolibarr_main_auth_ldap_login_attribute='cn'; +$dolibarr_main_auth_ldap_login_attribute='uid'; $dolibarr_main_auth_ldap_dn='ou=people,dc=example,dc=com'; -$dolibarr_main_auth_ldap_admin_login='cn=admin,ou=people,dc=example,dc=com'; +$dolibarr_main_auth_ldap_admin_login='uid=admin,ou=people,dc=example,dc=com'; $dolibarr_main_auth_ldap_admin_pass='secret'; ``` diff --git a/example_configs/jellyfin.md b/example_configs/jellyfin.md index ca01dab..6b43064 100644 --- a/example_configs/jellyfin.md +++ b/example_configs/jellyfin.md @@ -4,7 +4,7 @@ Replace `dc=example,dc=com` with your LLDAP configured domain. ### LDAP Bind User ``` -cn=admin,ou=people,dc=example,dc=com +uid=admin,ou=people,dc=example,dc=com ``` ### LDAP Base DN for searches @@ -12,6 +12,18 @@ cn=admin,ou=people,dc=example,dc=com ou=people,dc=example,dc=com ``` +### LDAP Attributes + +``` +uid, mail +``` + +### LDAP Name Attribute + +``` +uid +``` + ### User Filter If you have a `media` group, you can use: diff --git a/example_configs/jitsi_meet.conf b/example_configs/jitsi_meet.conf index 30f4b83..415d8d2 100644 --- a/example_configs/jitsi_meet.conf +++ b/example_configs/jitsi_meet.conf @@ -18,7 +18,7 @@ LDAP_URL=ldap://IP:3890 LDAP_BASE=ou=people,dc=example,dc=com # LDAP user DN. -LDAP_BINDDN=cn=admin,ou=people,dc=example,dc=com +LDAP_BINDDN=uid=admin,ou=people,dc=example,dc=com # LLDAP admin password. LDAP_BINDPW=password diff --git a/example_configs/keycloak.md b/example_configs/keycloak.md index bb1f39e..e1fc753 100644 --- a/example_configs/keycloak.md +++ b/example_configs/keycloak.md @@ -25,7 +25,7 @@ The key settings are: - Connection URL: `ldap://:3890` - Users DN: `ou=people,dc=example,dc=com` (or whatever `dc` you have) - Bind Type: `simple` - - Bind DN: `cn=admin,ou=people,dc=example,dc=com` (replace with your admin user and `dc`) + - Bind DN: `uid=admin,ou=people,dc=example,dc=com` (replace with your admin user and `dc`) - Bind Credential: your LLDAP admin password Test the connection and authentication, it should work. diff --git a/server/src/infra/ldap_handler.rs b/server/src/infra/ldap_handler.rs index 406b64c..c5038b2 100644 --- a/server/src/infra/ldap_handler.rs +++ b/server/src/infra/ldap_handler.rs @@ -85,7 +85,7 @@ fn get_user_id_from_distinguished_name( || (parts[0].0 != "cn" && parts[0].0 != "uid") { bail!( - r#"Unexpected user DN format. Got "{}", expected: "cn=username,ou=people,{}""#, + r#"Unexpected user DN format. Got "{}", expected: "uid=username,ou=people,{}""#, dn, base_dn_str ); @@ -93,7 +93,7 @@ fn get_user_id_from_distinguished_name( Ok(UserId::new(&parts[0].1)) } else { bail!( - r#"Unexpected user DN format. Got "{}", expected: "cn=username,ou=people,{}""#, + r#"Unexpected user DN format. Got "{}", expected: "uid=username,ou=people,{}""#, dn, base_dn_str ); @@ -125,7 +125,11 @@ fn make_ldap_search_user_result_entry( base_dn_str: &str, attributes: &[String], ) -> Result { - let dn = format!("cn={},ou=people,{}", user.user_id.as_str(), base_dn_str); + let dn = format!( + "cn={},ou=people,{}", + user.display_name.as_str(), + base_dn_str + ); Ok(LdapSearchResultEntry { dn: dn.clone(), attributes: attributes @@ -864,7 +868,7 @@ mod tests { .times(1) .return_once(|_| { Ok(vec![User { - user_id: UserId::new("test"), + display_name: "test".to_string(), ..Default::default() }]) }); @@ -1009,7 +1013,7 @@ mod tests { ldap_handler.do_search(&request).await, vec![ LdapOp::SearchResultEntry(LdapSearchResultEntry { - dn: "cn=bob_1,ou=people,dc=example,dc=com".to_string(), + dn: "cn=Bôb Böbberson,ou=people,dc=example,dc=com".to_string(), attributes: vec![ LdapPartialAttribute { atype: "objectClass".to_string(), @@ -1022,7 +1026,7 @@ mod tests { }, LdapPartialAttribute { atype: "dn".to_string(), - vals: vec!["cn=bob_1,ou=people,dc=example,dc=com".to_string()] + vals: vec!["cn=Bôb Böbberson,ou=people,dc=example,dc=com".to_string()] }, LdapPartialAttribute { atype: "uid".to_string(), @@ -1051,7 +1055,7 @@ mod tests { ], }), LdapOp::SearchResultEntry(LdapSearchResultEntry { - dn: "cn=jim,ou=people,dc=example,dc=com".to_string(), + dn: "cn=Jimminy Cricket,ou=people,dc=example,dc=com".to_string(), attributes: vec![ LdapPartialAttribute { atype: "objectClass".to_string(), @@ -1064,7 +1068,7 @@ mod tests { }, LdapPartialAttribute { atype: "dn".to_string(), - vals: vec!["cn=jim,ou=people,dc=example,dc=com".to_string()] + vals: vec!["cn=Jimminy Cricket,ou=people,dc=example,dc=com".to_string()] }, LdapPartialAttribute { atype: "uid".to_string(), @@ -1409,7 +1413,7 @@ mod tests { .times(1) .return_once(|_| { Ok(vec![User { - user_id: UserId::new("bob_1"), + display_name: "bob_1".to_string(), ..Default::default() }]) }); @@ -1473,7 +1477,7 @@ mod tests { ldap_handler.do_search(&request).await, vec![ LdapOp::SearchResultEntry(LdapSearchResultEntry { - dn: "cn=bob_1,ou=people,dc=example,dc=com".to_string(), + dn: "cn=Bôb Böbberson,ou=people,dc=example,dc=com".to_string(), attributes: vec![ LdapPartialAttribute { atype: "objectClass".to_string(), @@ -1486,7 +1490,7 @@ mod tests { }, LdapPartialAttribute { atype: "dn".to_string(), - vals: vec!["cn=bob_1,ou=people,dc=example,dc=com".to_string()] + vals: vec!["cn=Bôb Böbberson,ou=people,dc=example,dc=com".to_string()] }, LdapPartialAttribute { atype: "cn".to_string(), @@ -1623,7 +1627,7 @@ mod tests { ldap_handler.handle_ldap_message(request).await, Some(vec![make_extended_response( LdapResultCode::InvalidDNSyntax, - r#"Invalid username: "Unexpected user DN format. Got \"cn=bob,ou=groups,ou=people,dc=example,dc=com\", expected: \"cn=username,ou=people,dc=example,dc=com\"""#.to_string(), + r#"Invalid username: "Unexpected user DN format. Got \"cn=bob,ou=groups,ou=people,dc=example,dc=com\", expected: \"uid=username,ou=people,dc=example,dc=com\"""#.to_string(), )]) ); let request = LdapOp::ExtendedRequest(LdapExtendedRequest {