From 5bd81780b3fd176460438956a52c5ea1f7d3c57c Mon Sep 17 00:00:00 2001 From: Simon Broeng Jensen Date: Fri, 6 Oct 2023 13:52:05 +0200 Subject: [PATCH] server: Add basic support for Paged Results Control (RFC 2696) This implements rudimentary support for the Paged Results Control. No actual pagination is performed, and we ignore any requests for specific window sizes for paginated results. Instead, the full list of search results is returned for any searches, and a control is added to the SearchResultsDone message, informing the client that there is no further results available. --- server/src/infra/ldap_server.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/server/src/infra/ldap_server.rs b/server/src/infra/ldap_server.rs index 639c626..47af5e4 100644 --- a/server/src/infra/ldap_server.rs +++ b/server/src/infra/ldap_server.rs @@ -13,7 +13,7 @@ use actix_rt::net::TcpStream; use actix_server::ServerBuilder; use actix_service::{fn_service, ServiceFactoryExt}; use anyhow::{anyhow, Context, Result}; -use ldap3_proto::{proto::LdapMsg, LdapCodec}; +use ldap3_proto::{proto::LdapControl, proto::LdapMsg, proto::LdapOp, LdapCodec}; use rustls::PrivateKey; use tokio_rustls::TlsAcceptor as RustlsTlsAcceptor; use tokio_util::codec::{FramedRead, FramedWrite}; @@ -39,12 +39,21 @@ where if result.is_empty() { debug!("No response"); } + let results: i64 = result.len().try_into().unwrap(); for response in result.into_iter() { debug!(?response); + let controls = if matches!(response, LdapOp::SearchResultDone(_)) { + vec![LdapControl::SimplePagedResults { + size: results - 1, // Avoid counting SearchResultDone as a result + cookie: vec![], + }] + } else { + vec![] + }; resp.send(LdapMsg { msgid: msg.msgid, op: response, - ctrl: vec![], + ctrl: controls, }) .await .context("while sending a response: {:#}")?