diff --git a/server/src/infra/ldap_handler.rs b/server/src/infra/ldap_handler.rs index 1ffe061..0291448 100644 --- a/server/src/infra/ldap_handler.rs +++ b/server/src/infra/ldap_handler.rs @@ -48,6 +48,49 @@ fn parse_distinguished_name(dn: &str) -> Result> { .collect() } +#[derive(Debug)] +enum SearchScope { + Global, + Users, + Groups, + User(LdapFilter), + Group(LdapFilter), + Unknown, + Invalid, +} +fn get_search_scope(base_dn: &[(String, String)], dn_parts: &[(String, String)]) -> SearchScope { + let base_dn_len = base_dn.len(); + if !is_subtree(dn_parts, base_dn) { + SearchScope::Invalid + } else if dn_parts.len() == base_dn_len { + SearchScope::Global + } else if dn_parts.len() == base_dn_len + 1 + && dn_parts[0] == ("ou".to_string(), "people".to_string()) + { + SearchScope::Users + } else if dn_parts.len() == base_dn_len + 1 + && dn_parts[0] == ("ou".to_string(), "groups".to_string()) + { + SearchScope::Groups + } else if dn_parts.len() == base_dn_len + 2 + && dn_parts[1] == ("ou".to_string(), "people".to_string()) + { + SearchScope::User(LdapFilter::Equality( + dn_parts[0].0.clone(), + dn_parts[0].1.clone(), + )) + } else if dn_parts.len() == base_dn_len + 2 + && dn_parts[1] == ("ou".to_string(), "groups".to_string()) + { + SearchScope::Group(LdapFilter::Equality( + dn_parts[0].0.clone(), + dn_parts[0].1.clone(), + )) + } else { + SearchScope::Unknown + } +} + fn get_group_id_from_distinguished_name( dn: &str, base_tree: &[(String, String)], @@ -582,36 +625,50 @@ impl LdapHandler { + let mut results = Vec::new(); + results.extend(get_user_list().await); + results.extend(get_group_list().await); + results + } + SearchScope::Users => get_user_list().await, + SearchScope::Groups => get_group_list().await, + SearchScope::User(filter) => { + let filter = LdapFilter::And(vec![request.filter.clone(), filter]); + self.get_user_list(&filter, &request.attrs, &request.base, &user_filter) + .await + } + SearchScope::Group(filter) => { + let filter = LdapFilter::And(vec![request.filter.clone(), filter]); + self.get_groups_list(&filter, &request.attrs, &request.base, &user_filter) + .await + } + SearchScope::Unknown => { + warn!( + r#"The requested search tree "{}" matches neither the user subtree "ou=people,{}" nor the group subtree "ou=groups,{}""#, + &request.base, &self.base_dn_str, &self.base_dn_str + ); + Vec::new() + } + SearchScope::Invalid => { + // Search path is not in our tree, just return an empty success. + warn!( + "The specified search tree {:?} is not under the common subtree {:?}", + &dn_parts, &self.base_dn + ); + Vec::new() + } + }; if results.is_empty() || matches!(results[results.len() - 1], LdapOp::SearchResultEntry(_)) { results.push(make_search_success()); @@ -621,10 +678,12 @@ impl LdapHandler, ) -> Vec { - let filters = match self.convert_user_filter(&request.filter) { + let filters = match self.convert_user_filter(filter) { Ok(f) => f, Err(e) => { return vec![make_search_error( @@ -639,8 +698,7 @@ impl LdapHandler LdapHandler { return vec![make_search_error( LdapResultCode::Other, - format!(r#"Error during searching user "{}": {:#}"#, request.base, e), + format!(r#"Error while searching user "{}": {:#}"#, base, e), )] } }; @@ -681,10 +739,12 @@ impl LdapHandler, ) -> Vec { - let filter = match self.convert_group_filter(&request.filter) { + let filter = match self.convert_group_filter(filter) { Ok(f) => f, Err(e) => { return vec![make_search_error( @@ -705,7 +765,7 @@ impl LdapHandler { return vec![make_search_error( LdapResultCode::Other, - format!(r#"Error while listing groups "{}": {:#}"#, request.base, e), + format!(r#"Error while listing groups "{}": {:#}"#, base, e), )] } }; @@ -716,7 +776,7 @@ impl LdapHandler