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
|
.binddnre
|
||||||
.captures(dn)
|
.captures(dn)
|
||||||
.and_then(|caps| caps.name("val").map(|v| v.as_str().to_string()))
|
.and_then(|caps| caps.name("val"))
|
||||||
{
|
.map(|v| v.as_str().to_string())
|
||||||
Some(r) => r,
|
.ok_or(OperationError::NoMatchingEntries)?;
|
||||||
None => return Err(OperationError::NoMatchingEntries),
|
|
||||||
};
|
|
||||||
|
|
||||||
trace!(?rdn, "relative dn");
|
trace!(?rdn, "relative dn");
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ use crate::schema::{
|
||||||
Schema, SchemaAttribute, SchemaClass, SchemaReadTransaction, SchemaTransaction,
|
Schema, SchemaAttribute, SchemaClass, SchemaReadTransaction, SchemaTransaction,
|
||||||
SchemaWriteTransaction,
|
SchemaWriteTransaction,
|
||||||
};
|
};
|
||||||
|
use crate::value::EXTRACT_VAL_DN;
|
||||||
use crate::valueset::uuid_to_proto_string;
|
use crate::valueset::uuid_to_proto_string;
|
||||||
|
|
||||||
pub mod access;
|
pub mod access;
|
||||||
|
@ -265,11 +266,25 @@ pub trait QueryServerTransaction<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name_to_uuid(&mut self, name: &str) -> Result<Uuid, OperationError> {
|
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?
|
// Is it just a uuid?
|
||||||
Uuid::parse_str(name).or_else(|_| {
|
Uuid::parse_str(&work).or_else(|_| {
|
||||||
let lname = name.to_lowercase();
|
|
||||||
self.get_be_txn()
|
self.get_be_txn()
|
||||||
.name2uuid(lname.as_str())?
|
.name2uuid(&work)?
|
||||||
.ok_or(OperationError::NoMatchingEntries)
|
.ok_or(OperationError::NoMatchingEntries)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1503,6 +1518,12 @@ mod tests {
|
||||||
// Name is not syntax normalised (but exists)
|
// Name is not syntax normalised (but exists)
|
||||||
let r4 = server_txn.name_to_uuid("tEsTpErSoN1");
|
let r4 = server_txn.name_to_uuid("tEsTpErSoN1");
|
||||||
assert!(r4 == Ok(t_uuid));
|
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]
|
#[qs_test]
|
||||||
|
|
|
@ -40,6 +40,7 @@ lazy_static! {
|
||||||
#[allow(clippy::expect_used)]
|
#[allow(clippy::expect_used)]
|
||||||
Regex::new("(?P<name>[^@]+)@(?P<realm>[^@]+)").expect("Invalid SPN regex found")
|
Regex::new("(?P<name>[^@]+)@(?P<realm>[^@]+)").expect("Invalid SPN regex found")
|
||||||
};
|
};
|
||||||
|
|
||||||
pub static ref DISALLOWED_NAMES: HashSet<&'static str> = {
|
pub static ref DISALLOWED_NAMES: HashSet<&'static str> = {
|
||||||
let mut m = HashSet::with_capacity(16);
|
let mut m = HashSet::with_capacity(16);
|
||||||
m.insert("root");
|
m.insert("root");
|
||||||
|
@ -61,6 +62,13 @@ lazy_static! {
|
||||||
#[allow(clippy::expect_used)]
|
#[allow(clippy::expect_used)]
|
||||||
Regex::new("^[a-z][a-z0-9-_\\.]+$").expect("Invalid Iname regex found")
|
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 = {
|
pub static ref NSUNIQUEID_RE: Regex = {
|
||||||
#[allow(clippy::expect_used)]
|
#[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")
|
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