diff --git a/src/db/interface.rs b/src/db/interface.rs index 74ce9ee..f8ca052 100644 --- a/src/db/interface.rs +++ b/src/db/interface.rs @@ -14,8 +14,8 @@ impl DatabaseInterface for Database { } } -pub trait DatabaseInterface { - async fn get_user(&self, user: &UserRef) -> Result, BoxedError>; +pub trait DatabaseInterface: Clone + Send + Sync + 'static { + fn get_user(&self, user: &UserRef) -> impl std::future::Future, BoxedError>> + Send; async fn create_user( &mut self, user: User, diff --git a/src/ldap/handler.rs b/src/ldap/handler.rs index 32d2ac0..c8af21e 100644 --- a/src/ldap/handler.rs +++ b/src/ldap/handler.rs @@ -2,9 +2,30 @@ use ldap3_proto::LdapMsg; use ldap3_proto::proto::LdapOp; use crate::db::{Database, DatabaseInterface}; +use crate::error::GlobalError; use crate::ldap::{ LdapClientState, LdapStream, LdapStreamError, op_bind, op_ext, search_by_mail_filter, }; +use crate::listener::Listener; + +pub async fn ldap_listen(listener: Listener, db: Database) { + // If the connection is None, it's because the client aborted early + // so there's nothing to do about it. + loop { + match listener.accept_ldap().await { + Ok(Some(stream)) => { + let db = db.clone(); + tokio::spawn(ldap_handler(stream, db)); + } + Ok(None) => { + panic!("LDAP listener closed"); + } + Err(e) => { + panic!("Failed to listen on LDAP listener"); + } + } + } +} #[tracing::instrument(name = "ldap", skip(stream, db), fields(session = %stream.session))] pub async fn ldap_handler(mut stream: LdapStream, mut db: Database) { diff --git a/src/ldap/mod.rs b/src/ldap/mod.rs index d72d094..dc33d6c 100644 --- a/src/ldap/mod.rs +++ b/src/ldap/mod.rs @@ -5,7 +5,7 @@ pub use dn::{Dn, MalformedDn}; mod filter; mod handler; mod op; -pub use handler::ldap_handler; +pub use handler::ldap_listen; pub use op::bind::{BindDn, op_bind}; pub use op::ext::op_ext; pub use op::search::search_by_mail_filter; diff --git a/src/ldap/op/search.rs b/src/ldap/op/search.rs index 3255298..b65b160 100644 --- a/src/ldap/op/search.rs +++ b/src/ldap/op/search.rs @@ -153,7 +153,7 @@ fn search_entry_from_user(user: &User, req_attrs: &[String]) -> LdapSearchResult for attr in req_attrs { if let Some(attr_value) = match attr.as_str() { "uid" => Some(user.username.clone()), - "cn"|"mail" => Some(user.mail.clone()), + "cn" | "mail" => Some(user.mail.clone()), _ => { tracing::warn!("Ignoring unknown attr in search query: {attr}"); None diff --git a/src/main.rs b/src/main.rs index 1bcde2c..3cd41f9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,7 +10,7 @@ mod stream; use cli::CliArgs; use db::{Database, DatabaseInterface, MemoryDatabase, User}; use error::GlobalError; -use ldap::ldap_handler; +use ldap::ldap_listen; use listener::ListenerPath; async fn create_dummy_users(db: &mut Database) { @@ -44,12 +44,8 @@ async fn main() -> Result<(), GlobalError> { let mut db = MemoryDatabase::new(); create_dummy_users(&mut db).await; - // If the connection is None, it's because the client aborted early - // so there's nothing to do about it. - while let Some(stream) = listener.accept_ldap().await? { - let db = db.clone(); - tokio::spawn(ldap_handler(stream, db)); - } + let ldap_db = db.clone(); + tokio::spawn(ldap_listen(listener, ldap_db)); Ok(()) }