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,
|
opaque_handler::OpaqueHandler,
|
||||||
};
|
};
|
||||||
use anyhow::{bail, Context, Result};
|
use anyhow::{bail, Context, Result};
|
||||||
|
use itertools::Itertools;
|
||||||
use ldap3_server::proto::{
|
use ldap3_server::proto::{
|
||||||
LdapBindCred, LdapBindRequest, LdapBindResponse, LdapExtendedRequest, LdapExtendedResponse,
|
LdapBindCred, LdapBindRequest, LdapBindResponse, LdapExtendedRequest, LdapExtendedResponse,
|
||||||
LdapFilter, LdapOp, LdapPartialAttribute, LdapPasswordModifyRequest, LdapResult,
|
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()],
|
"cn" | "displayname" => vec![user.display_name.clone()],
|
||||||
"createtimestamp" | "modifytimestamp" => vec![user.creation_date.to_rfc3339()],
|
"createtimestamp" | "modifytimestamp" => vec![user.creation_date.to_rfc3339()],
|
||||||
"1.1" => return Ok(None),
|
"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(
|
fn make_ldap_search_user_result_entry(
|
||||||
user: User,
|
user: User,
|
||||||
base_dn_str: &str,
|
base_dn_str: &str,
|
||||||
attributes: &[String],
|
attributes: &[String],
|
||||||
) -> Result<LdapSearchResultEntry> {
|
) -> Result<LdapSearchResultEntry> {
|
||||||
let dn = format!("uid={},ou=people,{}", user.user_id.as_str(), base_dn_str);
|
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 {
|
Ok(LdapSearchResultEntry {
|
||||||
dn: dn.clone(),
|
dn: dn.clone(),
|
||||||
attributes: attributes
|
attributes: expanded_attributes
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|a| {
|
.filter_map(|a| {
|
||||||
let values = match get_user_attribute(&user, a, &dn) {
|
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))
|
.map(|u| format!("uid={},ou=people,{}", u, base_dn_str))
|
||||||
.collect(),
|
.collect(),
|
||||||
"1.1" => return Ok(None),
|
"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(
|
fn make_ldap_search_group_result_entry(
|
||||||
group: Group,
|
group: Group,
|
||||||
base_dn_str: &str,
|
base_dn_str: &str,
|
||||||
attributes: &[String],
|
attributes: &[String],
|
||||||
user_filter: &Option<&UserId>,
|
user_filter: &Option<&UserId>,
|
||||||
) -> Result<LdapSearchResultEntry> {
|
) -> Result<LdapSearchResultEntry> {
|
||||||
|
let expanded_attributes = expand_attribute_wildcards(attributes, ALL_GROUP_ATTRIBUTE_KEYS);
|
||||||
|
|
||||||
Ok(LdapSearchResultEntry {
|
Ok(LdapSearchResultEntry {
|
||||||
dn: format!("cn={},ou=groups,{}", group.display_name, base_dn_str),
|
dn: format!("cn={},ou=groups,{}", group.display_name, base_dn_str),
|
||||||
attributes: attributes
|
attributes: expanded_attributes
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|a| {
|
.filter_map(|a| {
|
||||||
let values = match get_group_attribute(&group, base_dn_str, a, user_filter) {
|
let values = match get_group_attribute(&group, base_dn_str, a, user_filter) {
|
||||||
|
Loading…
Reference in New Issue
Block a user