diff --git a/book/src/integrations/ldap.md b/book/src/integrations/ldap.md index 854efad62..000c46f5a 100644 --- a/book/src/integrations/ldap.md +++ b/book/src/integrations/ldap.md @@ -124,6 +124,15 @@ ldapsearch ... -x '(name=admin)' cn objectClass displayname memberof Group membership is defined in rfc2307bis or Active Directory style. This means groups are determined from the "memberof" attribute which contains a DN to a group. +## People Accounts + +Persons can bind (authenticate) to the LDAP server if they are configured as a posix account and +have a valid posix password set. + +When a person is bound to the directory, they inherit the permissions of anonymous - not their +account. This is because a posix password as single factor authentication is not as secure and +should not grant the same privileges as the accounts standard credentials. + ## Service Accounts If you have @@ -197,7 +206,9 @@ objectclass: account objectclass: memberof objectclass: object objectclass: person +objectclass: posixaccount displayname: Test User +gidnumber: 12345 memberof: spn=group240@idm.example.com,dc=idm,dc=example,dc=com name: test1 spn: test1@idm.example.com @@ -205,7 +216,7 @@ entryuuid: 22a65b6c-80c8-4e1a-9b76-3f3afdff8400 ``` LDAP binds can use any unique identifier of the account. The following are all valid bind DNs for -the object listed above (if it was a POSIX account, that is). +the object listed above. ```bash ldapwhoami ... -x -D 'name=test1' @@ -243,3 +254,4 @@ This is despite the fact: - The third is an incorrect port. To diagnose errors like this, you may need to add "-d 1" to your LDAP commands or client. + diff --git a/server/lib/src/idm/server.rs b/server/lib/src/idm/server.rs index 57ed299c7..3711f63c4 100644 --- a/server/lib/src/idm/server.rs +++ b/server/lib/src/idm/server.rs @@ -1297,57 +1297,63 @@ impl<'a> IdmServerAuthTransaction<'a> { slock } }; - Some(slock_ref) + Ok(slock_ref) } - None => None, + None => Err(false), }; - let maybe_slock = if let Some(s) = maybe_slock_ref.as_ref() { - Some(s.lock().await) - } else { - None + let maybe_slock = match maybe_slock_ref.as_ref() { + Ok(s) => Ok(s.lock().await), + Err(cred_state) => Err(cred_state), }; - let maybe_valid = if let Some(mut slock) = maybe_slock { - // Apply the current time. - slock.apply_time_step(ct); - // Now check the results - if slock.is_valid() { - Some(slock) - } else { - None + let maybe_valid = match maybe_slock { + Ok(mut slock) => { + // Apply the current time. + slock.apply_time_step(ct); + // Now check the results + if slock.is_valid() { + Ok(slock) + } else { + Err(true) + } } - } else { - None + Err(cred_state) => Err(*cred_state), }; - if let Some(mut slock) = maybe_valid { - if account - .verify_unix_credential(lae.cleartext.as_str(), &self.async_tx, ct)? - .is_some() - { - let session_id = Uuid::new_v4(); - security_info!( - "Starting session {} for {} {}", - session_id, - account.spn, - account.uuid - ); + match maybe_valid { + Ok(mut slock) => { + if account + .verify_unix_credential(lae.cleartext.as_str(), &self.async_tx, ct)? + .is_some() + { + let session_id = Uuid::new_v4(); + security_info!( + "Starting session {} for {} {}", + session_id, + account.spn, + account.uuid + ); - Ok(Some(LdapBoundToken { - spn: account.spn, - session_id, - effective_session: LdapSession::UnixBind(account.uuid), - })) - } else { - // PW failure, update softlock. - slock.record_failure(ct); + Ok(Some(LdapBoundToken { + spn: account.spn, + session_id, + effective_session: LdapSession::UnixBind(account.uuid), + })) + } else { + // PW failure, update softlock. + slock.record_failure(ct); + Ok(None) + } + } + Err(true) => { + security_info!("Account is softlocked."); + Ok(None) + } + Err(false) => { + security_info!("Account does not have a configured posix password."); Ok(None) } - } else { - // Account is slocked! - security_info!("Account is softlocked."); - Ok(None) } } }