From 93c5aa213f40d240686f72f6f9c8f1655fecae34 Mon Sep 17 00:00:00 2001 From: David Coutadeur Date: Wed, 18 Sep 2024 17:15:03 +0200 Subject: [PATCH] add page size parameter in search function (#30) --- src/Ltb/Ldap.php | 54 +++++++++++++++++++++++++++++++++++------- tests/Ltb/LdapTest.php | 10 ++++---- 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/src/Ltb/Ldap.php b/src/Ltb/Ldap.php index 28f62c4..24c310d 100644 --- a/src/Ltb/Ldap.php +++ b/src/Ltb/Ldap.php @@ -15,6 +15,7 @@ class Ldap { public $ldap_user_base = null; public $ldap_size_limit = null; public $ldap_krb5ccname = null; + public $ldap_page_size = 0; public function __construct( $ldap_url, @@ -24,7 +25,8 @@ public function __construct( $ldap_network_timeout, $ldap_user_base, $ldap_size_limit, - $ldap_krb5ccname + $ldap_krb5ccname, + $ldap_page_size = 0 ) { $this->ldap_url = $ldap_url; @@ -35,6 +37,7 @@ public function __construct( $this->ldap_user_base = $ldap_user_base; $this->ldap_size_limit = $ldap_size_limit; $this->ldap_krb5ccname = $ldap_krb5ccname; + $this->ldap_page_size = $ldap_page_size; } @@ -125,10 +128,47 @@ function search($ldap_filter,$attributes, $attributes_map, $search_result_title, $attributes[] = $attributes_map[$search_result_title]['attribute']; $attributes[] = $attributes_map[$search_result_sortby]['attribute']; - # Search for users - $search = $this->search_with_scope($search_scope, $this->ldap_user_base, $ldap_filter, $attributes, 0, $this->ldap_size_limit); - - $errno = \Ltb\PhpLDAP::ldap_errno($this->ldap); + $cookie = ""; + do { + $controls = null; + if($this->ldap_page_size != 0) + { + $controls = [[ + 'oid' => LDAP_CONTROL_PAGEDRESULTS, + 'value' => [ + 'size' => $this->ldap_page_size, + 'cookie' => $cookie] + ]]; + } + + # Search for users + $search = $this->search_with_scope($search_scope, + $this->ldap_user_base, + $ldap_filter, + $attributes, + 0, + $this->ldap_size_limit, + -1, + LDAP_DEREF_NEVER, + $controls ); + + $errno = null; + $matcheddn = null; + $errmsg = null; + $referrals = null; + \Ltb\PhpLDAP::ldap_parse_result($this->ldap, $search, $errno, $matcheddn, $errmsg, $referrals, $controls); + + if($errno != 0) + { + # if any error occurs, stop the search loop and treat error + break; + } + + $nb_entries += \Ltb\PhpLDAP::ldap_count_entries($this->ldap, $search); + $entries = array_merge($entries, \Ltb\PhpLDAP::ldap_get_entries($this->ldap, $search)); + $entries["count"] = $nb_entries; + + } while (!empty($cookie) && $this->ldap_page_size != 0); if ( $errno == 4) { $size_limit_reached = true; @@ -138,13 +178,9 @@ function search($ldap_filter,$attributes, $attributes_map, $search_result_title, error_log("LDAP - Search error $errno (".\Ltb\PhpLDAP::ldap_error($this->ldap).")"); } else { - # Get search results - $nb_entries = \Ltb\PhpLDAP::ldap_count_entries($this->ldap, $search); - if ($nb_entries === 0) { $result = "noentriesfound"; } else { - $entries = \Ltb\PhpLDAP::ldap_get_entries($this->ldap, $search); # Sort entries if (isset($search_result_sortby)) { diff --git a/tests/Ltb/LdapTest.php b/tests/Ltb/LdapTest.php index 35ffd2f..76e680e 100644 --- a/tests/Ltb/LdapTest.php +++ b/tests/Ltb/LdapTest.php @@ -168,13 +168,15 @@ public function test_search(): void "(objectClass=inetOrgPerson)", [0 => 'cn', 1 => 'sn', 2 => 'uid', 3 => 'mail', 4 => 'mobile', 5 => 'cn', 6 => 'sn'], 0, - $this->ldap_size_limit + $this->ldap_size_limit, + -1, + 0, + null ) ->andReturn("ldap_search_result"); - $phpLDAPMock->shouldreceive('ldap_errno') - ->with("ldap_connection") - ->andReturn(0); + $phpLDAPMock->shouldreceive('ldap_parse_result') + ->with("ldap_connection", "ldap_search_result", null, null, null, null, null); $phpLDAPMock->shouldreceive('ldap_count_entries') ->with("ldap_connection", "ldap_search_result")