mirror of
https://github.com/nitnelave/lldap.git
synced 2023-04-12 14:25:13 +00:00
handle wildcards being given as ldap attribute params
fix wildcard expansion address some pr comments Move ldap attribute expansion lists to constants As per: https://github.com/nitnelave/lldap/pull/164#discussion_r867348971 lldap *+ expansion: remove unneccesary cloning https://github.com/nitnelave/lldap/pull/164#discussion_r867349805 ldap attribute wildcard handling: remove duplicated wildcards https://github.com/nitnelave/lldap/pull/164#issuecomment-1120211031 ldap wildcard expansion: refactor ldap attribute handlers: handle '+' by ignoring, '*' and unmatched by warning and ignoring attribute wildcard expansion: refactor, don't remove '+'
This commit is contained in:
parent
875c59758b
commit
e5c80b9f17
@ -6,6 +6,7 @@ use crate::domain::{
|
||||
opaque_handler::OpaqueHandler,
|
||||
};
|
||||
use anyhow::{bail, Context, Result};
|
||||
use itertools::Itertools;
|
||||
use ldap3_server::proto::{
|
||||
LdapBindCred, LdapBindRequest, LdapBindResponse, LdapExtendedRequest, LdapExtendedResponse,
|
||||
LdapFilter, LdapOp, LdapPartialAttribute, LdapPasswordModifyRequest, LdapResult,
|
||||
@ -116,19 +117,60 @@ fn get_user_attribute(user: &User, attribute: &str, dn: &str) -> Result<Option<V
|
||||
"cn" | "displayname" => vec![user.display_name.clone()],
|
||||
"createtimestamp" | "modifytimestamp" => vec![user.creation_date.to_rfc3339()],
|
||||
"1.1" => return Ok(None),
|
||||
_ => bail!("Unsupported user attribute: {}", attribute),
|
||||
// We ignore the operational attribute wildcard
|
||||
"+" => return Ok(None),
|
||||
"*" => {
|
||||
warn!(
|
||||
"Matched {}, * should have been expanded into attribute list and * removed",
|
||||
attribute
|
||||
);
|
||||
return Ok(None);
|
||||
}
|
||||
_ => {
|
||||
warn!("Ignoring unrecognized group attribute: {}", attribute);
|
||||
return Ok(None);
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
fn expand_attribute_wildcards(attributes: &[String], all_attribute_keys: &[&str]) -> Vec<String> {
|
||||
let mut attributes_out = attributes.to_owned();
|
||||
|
||||
if attributes_out.iter().any(|x| x == "*") || attributes_out.is_empty() {
|
||||
debug!(r#"Expanding * / empty attrs:"#);
|
||||
// Remove occurrences of '*'
|
||||
attributes_out.retain(|x| x != "*");
|
||||
// Splice in all non-operational attributes
|
||||
attributes_out.extend(all_attribute_keys.iter().map(|s| s.to_string()));
|
||||
}
|
||||
|
||||
debug!(r#"Expanded: "{:?}""#, &attributes_out);
|
||||
|
||||
// Deduplicate, preserving order
|
||||
attributes_out.into_iter().unique().collect_vec()
|
||||
}
|
||||
const ALL_USER_ATTRIBUTE_KEYS: &[&str] = &[
|
||||
"objectclass",
|
||||
"dn",
|
||||
"uid",
|
||||
"mail",
|
||||
"givenname",
|
||||
"sn",
|
||||
"cn",
|
||||
"createtimestamp",
|
||||
];
|
||||
|
||||
fn make_ldap_search_user_result_entry(
|
||||
user: User,
|
||||
base_dn_str: &str,
|
||||
attributes: &[String],
|
||||
) -> Result<LdapSearchResultEntry> {
|
||||
let dn = format!("uid={},ou=people,{}", user.user_id.as_str(), base_dn_str);
|
||||
|
||||
let expanded_attributes = expand_attribute_wildcards(attributes, ALL_USER_ATTRIBUTE_KEYS);
|
||||
Ok(LdapSearchResultEntry {
|
||||
dn: dn.clone(),
|
||||
attributes: attributes
|
||||
attributes: expanded_attributes
|
||||
.iter()
|
||||
.filter_map(|a| {
|
||||
let values = match get_user_attribute(&user, a, &dn) {
|
||||
@ -164,19 +206,36 @@ fn get_group_attribute(
|
||||
.map(|u| format!("uid={},ou=people,{}", u, base_dn_str))
|
||||
.collect(),
|
||||
"1.1" => return Ok(None),
|
||||
_ => bail!("Unsupported group attribute: {}", attribute),
|
||||
// We ignore the operational attribute wildcard
|
||||
"+" => return Ok(None),
|
||||
"*" => {
|
||||
warn!(
|
||||
"Matched {}, * should have been expanded into attribute list and * removed",
|
||||
attribute
|
||||
);
|
||||
return Ok(None);
|
||||
}
|
||||
_ => {
|
||||
warn!("Ignoring unrecognized group attribute: {}", attribute);
|
||||
return Ok(None);
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
const ALL_GROUP_ATTRIBUTE_KEYS: &[&str] =
|
||||
&["objectclass", "dn", "uid", "cn", "member", "uniquemember"];
|
||||
|
||||
fn make_ldap_search_group_result_entry(
|
||||
group: Group,
|
||||
base_dn_str: &str,
|
||||
attributes: &[String],
|
||||
user_filter: &Option<&UserId>,
|
||||
) -> Result<LdapSearchResultEntry> {
|
||||
let expanded_attributes = expand_attribute_wildcards(attributes, ALL_GROUP_ATTRIBUTE_KEYS);
|
||||
|
||||
Ok(LdapSearchResultEntry {
|
||||
dn: format!("cn={},ou=groups,{}", group.display_name, base_dn_str),
|
||||
attributes: attributes
|
||||
attributes: expanded_attributes
|
||||
.iter()
|
||||
.filter_map(|a| {
|
||||
let values = match get_group_attribute(&group, base_dn_str, a, user_filter) {
|
||||
|
Loading…
Reference in New Issue
Block a user