From 12b779a662df8a513454abf4193c944a3101fd83 Mon Sep 17 00:00:00 2001 From: ralf Date: Thu, 25 Apr 2024 10:39:50 +0200 Subject: [PATCH] * AD/LDAP Import: import could potentially deactivate or delete users if the connection to LDAP server failed --- api/src/Accounts/Ads.php | 2 ++ api/src/Accounts/LdapVlvSortRequestTrait.php | 15 ++++++++++----- api/src/Contacts/Ldap.php | 12 ++++++++---- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/api/src/Accounts/Ads.php b/api/src/Accounts/Ads.php index 85d8a81294..b2eea7daca 100644 --- a/api/src/Accounts/Ads.php +++ b/api/src/Accounts/Ads.php @@ -611,6 +611,7 @@ class Ads * * @param array $group with values for keys account_id and account_dn * @return array + * @throws \Exception on error */ public function getMembers(array $group) { @@ -1263,6 +1264,7 @@ class Ads * @param int $num_rows number of rows to return if isset($start) * @param ?int $total on return total number of rows * @return array account_id => account_lid or values for $attrs pairs + * @throws \Exception on error */ protected function filter($attr_filter, $account_type=null, array $attrs=null, array $accounts=array(), $filter_expired=false, $order_by=null, &$start=null, $num_rows=null, &$total=null) { diff --git a/api/src/Accounts/LdapVlvSortRequestTrait.php b/api/src/Accounts/LdapVlvSortRequestTrait.php index 0734ebfa56..a43ac16fd6 100644 --- a/api/src/Accounts/LdapVlvSortRequestTrait.php +++ b/api/src/Accounts/LdapVlvSortRequestTrait.php @@ -81,7 +81,8 @@ trait LdapVlvSortRequestTrait * @param ?int& $start on return null, if result sorted and limited by server * @param int $num_rows number of rows to return if isset($start) * @param ?int $total on return total number of rows - * @return array|false result of ldap_get_entries with key 'count' unset + * @return array result of ldap_get_entries with key 'count' unset + * @throws \Exception on error with ldap_error() as message */ protected function vlvSortQuery(string $context, string $filter, array $attrs, string $order_by=null, int &$start=null, int$num_rows=null, int &$total=null) { @@ -123,14 +124,14 @@ trait LdapVlvSortRequestTrait $attrs, null, null, null, null, $control); } - if ($sri && ($allValues = ldap_get_entries($ds, $sri))) + if ($sri && ($allValues = ldap_get_entries($ds, $sri)) !== false) { // check if given controls succeeded if ($control && ldap_parse_result($ds, $sri, $errcode, $matcheddn, $errmsg, $referrals, $serverctrls) && (isset($serverctrls[LDAP_CONTROL_VLVRESPONSE]['value']['count']))) { $total = $serverctrls[LDAP_CONTROL_VLVRESPONSE]['value']['count']; - $start = null; // so caller does NOT run it's own limit + $start = null; // so caller does NOT run its own limit } else { @@ -138,9 +139,13 @@ trait LdapVlvSortRequestTrait } unset($allValues['count']); } - else error_log(__METHOD__."() ldap_search(\$ds, '$context', '$filter') returned ".array2string($sri)." allValues=".array2string($allValues)); + else + { + error_log(__METHOD__."() ldap_search(\$ds, '$context', '$filter') returned ".array2string($sri)." allValues=".array2string($allValues)); + throw new \Exception(ldap_error($ds) ?: 'Unable to retrieve LDAP result', ldap_errno($ds)); + } //error_log(date('Y-m-d H:i:s ').__METHOD__."('$context', '$filter', ".json_encode($attrs).", order_by=$order_by, start=$start, num_rows=$num_rows) ldap_search($ds, '$context', '$filter')\n==> returning ".count($allValues)."/$total ".substr(array2string($allValues), 0, 1024)."\n--> ".function_backtrace()."\n\n", 3, '/var/lib/egroupware/ads.log'); - return $allValues ?? false; + return $allValues; } } \ No newline at end of file diff --git a/api/src/Contacts/Ldap.php b/api/src/Contacts/Ldap.php index ea3d222f06..b3a892ac6d 100644 --- a/api/src/Contacts/Ldap.php +++ b/api/src/Contacts/Ldap.php @@ -1210,13 +1210,14 @@ class Ldap * @param string $_filter * @param array $_attributes * @param int $_addressbooktype - * @param array $_skipPlugins =null schema-plugins to skip + * @param ?array $_skipPlugins =null schema-plugins to skip * @param string $order_by sql order string eg. "contact_email ASC" * @param null|int|array $start [$start, $num_rows], on return null, if result sorted and limited by server * @param bool $read_photo true: return the binary content of the image, false: return true or false if there is an image or not - * @return array/boolean with eGW contacts or false on error + * @return array with contacts + * @throws \Exception on error with LDAP error message */ - function _searchLDAP($_ldapContext, $_filter, $_attributes, $_addressbooktype, array $_skipPlugins=null, $order_by=null, &$start=null, bool $read_photo=false) + function _searchLDAP($_ldapContext, $_filter, $_attributes, $_addressbooktype, ?array $_skipPlugins=null, $order_by=null, &$start=null, bool $read_photo=false) { $_attributes[] = 'entryUUID'; $_attributes[] = 'objectClass'; @@ -1280,7 +1281,10 @@ class Ldap { $result = ldap_list($this->ds, $_ldapContext, $_filter, $_attributes, null, null, null, null, $control); } - if(!$result || !$entries = ldap_get_entries($this->ds, $result)) return array(); + if(!$result || ($entries = ldap_get_entries($this->ds, $result)) === false) + { + throw new \Exception(ldap_error($this->ds) ?: 'Unable to retrieve LDAP result', ldap_errno($this->ds)); + } $this->total += $entries['count']; //error_log(__METHOD__."('$_ldapContext', '$_filter', ".array2string($_attributes).", $_addressbooktype) result of $entries[count]");