mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 20:47:01 +01:00
Filter rdns and dns for ldap filters (#1576)
This commit is contained in:
parent
850a985692
commit
1974d27dd8
|
@ -419,14 +419,12 @@ impl LdapServer {
|
|||
});
|
||||
};
|
||||
|
||||
let rdn = match self
|
||||
let rdn = self
|
||||
.binddnre
|
||||
.captures(dn)
|
||||
.and_then(|caps| caps.name("val").map(|v| v.as_str().to_string()))
|
||||
{
|
||||
Some(r) => r,
|
||||
None => return Err(OperationError::NoMatchingEntries),
|
||||
};
|
||||
.and_then(|caps| caps.name("val"))
|
||||
.map(|v| v.as_str().to_string())
|
||||
.ok_or(OperationError::NoMatchingEntries)?;
|
||||
|
||||
trace!(?rdn, "relative dn");
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ use crate::schema::{
|
|||
Schema, SchemaAttribute, SchemaClass, SchemaReadTransaction, SchemaTransaction,
|
||||
SchemaWriteTransaction,
|
||||
};
|
||||
use crate::value::EXTRACT_VAL_DN;
|
||||
use crate::valueset::uuid_to_proto_string;
|
||||
|
||||
pub mod access;
|
||||
|
@ -265,11 +266,25 @@ pub trait QueryServerTransaction<'a> {
|
|||
}
|
||||
|
||||
fn name_to_uuid(&mut self, name: &str) -> Result<Uuid, OperationError> {
|
||||
// There are some contexts where we will be passed an rdn or dn. We need
|
||||
// to remove these elements if they exist.
|
||||
//
|
||||
// Why is it okay to ignore the attr and dn here? In Kani spn and name are
|
||||
// always unique and absolutes, so even if the dn/rdn are not expected, there
|
||||
// is only a single correct answer that *can* match these values. This also
|
||||
// hugely simplifies the process of matching when we have app based searches
|
||||
// in future too.
|
||||
|
||||
let work = EXTRACT_VAL_DN
|
||||
.captures(name)
|
||||
.and_then(|caps| caps.name("val"))
|
||||
.map(|v| v.as_str().to_lowercase())
|
||||
.ok_or(OperationError::InvalidValueState)?;
|
||||
|
||||
// Is it just a uuid?
|
||||
Uuid::parse_str(name).or_else(|_| {
|
||||
let lname = name.to_lowercase();
|
||||
Uuid::parse_str(&work).or_else(|_| {
|
||||
self.get_be_txn()
|
||||
.name2uuid(lname.as_str())?
|
||||
.name2uuid(&work)?
|
||||
.ok_or(OperationError::NoMatchingEntries)
|
||||
})
|
||||
}
|
||||
|
@ -1503,6 +1518,12 @@ mod tests {
|
|||
// Name is not syntax normalised (but exists)
|
||||
let r4 = server_txn.name_to_uuid("tEsTpErSoN1");
|
||||
assert!(r4 == Ok(t_uuid));
|
||||
// Name is an rdn
|
||||
let r5 = server_txn.name_to_uuid("name=testperson1");
|
||||
assert!(r5 == Ok(t_uuid));
|
||||
// Name is a dn
|
||||
let r6 = server_txn.name_to_uuid("name=testperson1,o=example");
|
||||
assert!(r6 == Ok(t_uuid));
|
||||
}
|
||||
|
||||
#[qs_test]
|
||||
|
|
|
@ -40,6 +40,7 @@ lazy_static! {
|
|||
#[allow(clippy::expect_used)]
|
||||
Regex::new("(?P<name>[^@]+)@(?P<realm>[^@]+)").expect("Invalid SPN regex found")
|
||||
};
|
||||
|
||||
pub static ref DISALLOWED_NAMES: HashSet<&'static str> = {
|
||||
let mut m = HashSet::with_capacity(16);
|
||||
m.insert("root");
|
||||
|
@ -61,6 +62,13 @@ lazy_static! {
|
|||
#[allow(clippy::expect_used)]
|
||||
Regex::new("^[a-z][a-z0-9-_\\.]+$").expect("Invalid Iname regex found")
|
||||
};
|
||||
|
||||
pub static ref EXTRACT_VAL_DN: Regex = {
|
||||
#[allow(clippy::expect_used)]
|
||||
Regex::new("^(([^=,]+)=)?(?P<val>[^=,]+)").expect("extract val from dn regex")
|
||||
// Regex::new("^(([^=,]+)=)?(?P<val>[^=,]+)(,.*)?$").expect("Invalid Iname regex found")
|
||||
};
|
||||
|
||||
pub static ref NSUNIQUEID_RE: Regex = {
|
||||
#[allow(clippy::expect_used)]
|
||||
Regex::new("^[0-9a-fA-F]{8}-[0-9a-fA-F]{8}-[0-9a-fA-F]{8}-[0-9a-fA-F]{8}$").expect("Invalid Nsunique regex found")
|
||||
|
|
Loading…
Reference in a new issue