initial sketch of the implementation

This commit is contained in:
Luca 2023-01-12 09:48:33 +01:00
parent 24c149a39e
commit 7d67ce7050
No known key found for this signature in database
GPG Key ID: 3133FC373370010F
3 changed files with 86 additions and 26 deletions

38
Cargo.lock generated
View File

@ -2200,13 +2200,15 @@ dependencies = [
[[package]]
name = "ldap3_proto"
version = "0.2.3"
source = "git+https://github.com/nitnelave/ldap3_server/?rev=7b50b2b82c383f5f70e02e11072bb916629ed2bc#7b50b2b82c383f5f70e02e11072bb916629ed2bc"
version = "0.3.0"
source = "git+https://github.com/kanidm/ldap3#b3c7653471916e803dc8f24d2163fd2710dfb161"
dependencies = [
"bytes",
"lber",
"peg",
"tokio-util 0.7.3",
"tracing",
"uuid 1.2.2",
]
[[package]]
@ -2880,6 +2882,33 @@ dependencies = [
"syn",
]
[[package]]
name = "peg"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a07f2cafdc3babeebc087e499118343442b742cc7c31b4d054682cc598508554"
dependencies = [
"peg-macros",
"peg-runtime",
]
[[package]]
name = "peg-macros"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a90084dc05cf0428428e3d12399f39faad19b0909f64fb9170c9fdd6d9cd49b"
dependencies = [
"peg-runtime",
"proc-macro2",
"quote",
]
[[package]]
name = "peg-runtime"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fa00462b37ead6d11a82c9d568b26682d78e0477dc02d1966c013af80969739"
[[package]]
name = "pem-rfc7468"
version = "0.3.1"
@ -5006,3 +5035,8 @@ dependencies = [
"cc",
"libc",
]
[[patch.unused]]
name = "ldap3_proto"
version = "0.2.3"
source = "git+https://github.com/nitnelave/ldap3_server/?rev=7b50b2b82c383f5f70e02e11072bb916629ed2bc#7b50b2b82c383f5f70e02e11072bb916629ed2bc"

View File

@ -28,7 +28,7 @@ itertools = "0.10.1"
juniper = "0.15.10"
juniper_actix = "0.4.0"
jwt = "0.13"
ldap3_proto = "*"
ldap3_proto = { git = "https://github.com/kanidm/ldap3", package = "ldap3_proto" }
log = "*"
orion = "0.16"
rustls = "0.20"

View File

@ -16,10 +16,10 @@ use crate::{
};
use anyhow::Result;
use ldap3_proto::proto::{
LdapAddRequest, LdapBindCred, LdapBindRequest, LdapBindResponse, LdapExtendedRequest,
LdapExtendedResponse, LdapFilter, LdapOp, LdapPartialAttribute, LdapPasswordModifyRequest,
LdapResult as LdapResultOp, LdapResultCode, LdapSearchRequest, LdapSearchResultEntry,
LdapSearchScope,
LdapAddRequest, LdapBindCred, LdapBindRequest, LdapBindResponse, LdapCompareRequest,
LdapDerefAliases, LdapExtendedRequest, LdapExtendedResponse, LdapFilter, LdapOp,
LdapPartialAttribute, LdapPasswordModifyRequest, LdapResult as LdapResultOp, LdapResultCode,
LdapSearchRequest, LdapSearchResultEntry, LdapSearchScope,
};
use std::collections::HashMap;
use tracing::{debug, instrument, warn};
@ -38,6 +38,23 @@ enum SearchScope {
Invalid,
}
fn make_search_request<S: Into<String>>(
base: &str,
filter: LdapFilter,
attrs: Vec<S>,
) -> LdapSearchRequest {
LdapSearchRequest {
base: base.to_string(),
scope: LdapSearchScope::Base,
aliases: LdapDerefAliases::Never,
sizelimit: 0,
timelimit: 0,
typesonly: false,
filter,
attrs: attrs.into_iter().map(Into::into).collect(),
}
}
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) {
@ -527,6 +544,29 @@ impl<Backend: BackendHandler + LoginHandler + OpaqueHandler> LdapHandler<Backend
Ok(vec![make_add_error(LdapResultCode::Success, String::new())])
}
async fn do_compare(&mut self, request: LdapCompareRequest) -> LdapResult<Vec<LdapOp>> {
let req = make_search_request::<String>(
&self.ldap_info.base_dn_str,
LdapFilter::And(vec![LdapFilter::Equality("dn".to_string(), request.dn)]),
vec![],
);
let res = self.do_search_or_dse(&req).await?;
let entry = res.first().ok_or(LdapError {
code: LdapResultCode::OperationsError,
message: "Search request returned nothing".to_string(),
})?;
match entry {
LdapOp::SearchResultEntry(entry) => {
println!("res:{:?}", entry);
Ok(vec![])
}
_ => Err(LdapError {
code: LdapResultCode::NoSuchObject,
message: "".to_string(),
}),
}
}
pub async fn handle_ldap_message(&mut self, ldap_op: LdapOp) -> Option<Vec<LdapOp>> {
Some(match ldap_op {
LdapOp::BindRequest(request) => {
@ -555,6 +595,10 @@ impl<Backend: BackendHandler + LoginHandler + OpaqueHandler> LdapHandler<Backend
.do_create_user(request)
.await
.unwrap_or_else(|e: LdapError| vec![make_add_error(e.code, e.message)]),
LdapOp::CompareRequest(request) => self
.do_compare(request)
.await
.unwrap_or_else(|e: LdapError| vec![make_search_error(e.code, e.message)]),
op => vec![make_extended_response(
LdapResultCode::UnwillingToPerform,
format!("Unsupported operation: {:#?}", op),
@ -572,7 +616,7 @@ mod tests {
};
use async_trait::async_trait;
use chrono::TimeZone;
use ldap3_proto::proto::{LdapDerefAliases, LdapSearchScope};
use ldap3_proto::proto::LdapSearchScope;
use mockall::predicate::eq;
use std::collections::HashSet;
use tokio;
@ -625,23 +669,6 @@ mod tests {
}
}
fn make_search_request<S: Into<String>>(
base: &str,
filter: LdapFilter,
attrs: Vec<S>,
) -> LdapSearchRequest {
LdapSearchRequest {
base: base.to_string(),
scope: LdapSearchScope::Base,
aliases: LdapDerefAliases::Never,
sizelimit: 0,
timelimit: 0,
typesonly: false,
filter,
attrs: attrs.into_iter().map(Into::into).collect(),
}
}
fn make_user_search_request<S: Into<String>>(
filter: LdapFilter,
attrs: Vec<S>,
@ -995,7 +1022,6 @@ mod tests {
uuid: uuid!("698e1d5f-7a40-3151-8745-b9b8a37839da"),
..Default::default()
},
groups: None,
},
UserAndGroups {
user: User {