Browse Source

Unfold call to ldap_parse_result. Handle cookie outside of adapter.

Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
tags/v26.0.0beta1
Côme Chilliet 1 year ago
parent
commit
d10dfa84db
No account linked to committer's email address

+ 13
- 14
apps/user_ldap/lib/Access.php View File

@@ -95,8 +95,7 @@ class Access extends LDAPUtility {
private $ncUserManager;
/** @var LoggerInterface */
private $logger;
/** @var string */
private $lastCookie = '';
private string $lastCookie = '';

public function __construct(
Connection $connection,
@@ -1910,7 +1909,7 @@ class Access extends LDAPUtility {
* @return bool
*/
public function hasMoreResults() {
if (empty($this->lastCookie) && $this->lastCookie !== '0') {
if ($this->lastCookie === '') {
// as in RFC 2696, when all results are returned, the cookie will
// be empty.
return false;
@@ -1962,8 +1961,8 @@ class Access extends LDAPUtility {
'offset' => $offset
]
);
//get the cookie from the search for the previous search, required by LDAP
if (empty($this->lastCookie) && $this->lastCookie !== "0" && ($offset > 0)) {
// Get the cookie from the search for the previous search, required by LDAP
if (($this->lastCookie === '') && ($offset > 0)) {
// no cookie known from a potential previous search. We need
// to start from 0 to come to the desired page. cookie value
// of '0' is valid, because 389ds
@@ -1980,15 +1979,15 @@ class Access extends LDAPUtility {
$this->abandonPagedSearch();
}
$pagedSearchOK = true;
$this->invokeLDAPMethod('controlPagedResult', $limit, false);
$this->invokeLDAPMethod('controlPagedResult', $limit, false, $this->lastCookie);
$this->logger->debug('Ready for a paged search', ['app' => 'user_ldap']);
/* ++ Fixing RHDS searches with pages with zero results ++
* We couldn't get paged searches working with our RHDS for login ($limit = 0),
* due to pages with zero results.
* So we added "&& !empty($this->lastCookie)" to this test to ignore pagination
* if we don't have a previous paged search.
*/
} elseif (!empty($this->lastCookie)) {
/* ++ Fixing RHDS searches with pages with zero results ++
* We couldn't get paged searches working with our RHDS for login ($limit = 0),
* due to pages with zero results.
* So we added "&& !empty($this->lastCookie)" to this test to ignore pagination
* if we don't have a previous paged search.
*/
} elseif ($this->lastCookie !== '') {
// a search without limit was requested. However, if we do use
// Paged Search once, we always must do it. This requires us to
// initialize it with the configured page size.
@@ -1997,7 +1996,7 @@ class Access extends LDAPUtility {
// be returned.
$pageSize = (int)$this->connection->ldapPagingSize > 0 ? (int)$this->connection->ldapPagingSize : 500;
$pagedSearchOK = true;
$this->invokeLDAPMethod('controlPagedResult', $pageSize, false);
$this->invokeLDAPMethod('controlPagedResult', $pageSize, false, $this->lastCookie);
}

return $pagedSearchOK;

+ 17
- 13
apps/user_ldap/lib/LDAP.php View File

@@ -87,19 +87,23 @@ class LDAP implements ILDAPWrapper {
* {@inheritDoc}
*/
public function controlPagedResultResponse($link, $result, &$cookie): bool {
$this->preFunctionCall(
$this->pagedResultsAdapter->getResponseCallFunc(),
$this->pagedResultsAdapter->getResponseCallArgs([$link, $result, &$cookie])
);

$result = $this->pagedResultsAdapter->responseCall($link);
$cookie = $this->pagedResultsAdapter->getCookie($link);

if ($this->isResultFalse($result)) {
$this->postFunctionCall();
}

return $result;
$errorCode = 0;
$errorMessage = '';
$controls = [];
$matchedDn = null;
$referrals = [];
$success = $this->invokeLDAPMethod('parse_result', $link, $result,
$errorCode,
$matchedDn,
$errorMessage,
$referrals,
$controls);

$cookie = $controls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'] ?? '';

// TODO do not ignore error code and message

return $success;
}

/**

+ 1
- 33
apps/user_ldap/lib/PagedResults/IAdapter.php View File

@@ -35,31 +35,7 @@ interface IAdapter {
* The adapter receives paged result parameters from the client. It may
* store the parameters for later use.
*/
public function setRequestParameters($link, int $pageSize, bool $isCritical): void;

/**
* The adapter shall report which PHP function will be called to process
* the paged results call
*
* It will used by the callee for diagnosis and error handling.
*/
public function getResponseCallFunc(): string;

/**
* The adapter shall report with arguments will be provided to the LDAP
* function it will call
*
* It will used by the callee for diagnosis and error handling.
*/
public function getResponseCallArgs(array $originalArgs): array;

/**
* the adapter should do its LDAP function call and return success state
*
* @param resource|\LDAP\Connection $link LDAP resource
* @return bool
*/
public function responseCall($link): bool;
public function setRequestParameters($link, int $pageSize, bool $isCritical, string $cookie = ''): void;

/**
* The adapter receives the parameters that were passed to a search
@@ -80,12 +56,4 @@ interface IAdapter {
* ldap_search function.
*/
public function getSearchArgs($link): array;

/**
* Returns the current paged results cookie
*
* @param resource|\LDAP\Connection $link LDAP resource
* @return string
*/
public function getCookie($link): string;
}

+ 5
- 55
apps/user_ldap/lib/PagedResults/Php73.php View File

@@ -39,55 +39,7 @@ class Php73 implements IAdapter {
/** @var array */
protected $linkData = [];

public function getResponseCallFunc(): string {
return 'ldap_parse_result';
}

public function responseCall($link): bool {
$linkId = $this->getLinkId($link);
return ldap_parse_result(...$this->linkData[$linkId]['responseArgs']);
}

public function getResponseCallArgs(array $originalArgs): array {
$link = array_shift($originalArgs);
$linkId = $this->getLinkId($link);

if (!isset($this->linkData[$linkId])) {
$this->linkData[$linkId] = [];
}

$this->linkData[$linkId]['responseErrorCode'] = 0;
$this->linkData[$linkId]['responseErrorMessage'] = '';
$this->linkData[$linkId]['serverControls'] = [];
$matchedDn = null;
$referrals = [];

$this->linkData[$linkId]['responseArgs'] = [
$link,
array_shift($originalArgs),
&$this->linkData[$linkId]['responseErrorCode'],
$matchedDn,
&$this->linkData[$linkId]['responseErrorMessage'],
$referrals,
&$this->linkData[$linkId]['serverControls']
];


return $this->linkData[$linkId]['responseArgs'];
}

public function getCookie($link): string {
$linkId = $this->getLinkId($link);
return $this->linkData[$linkId]['serverControls'][LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'] ?? '';
}

private function resetCookie(int $linkId): void {
if (isset($this->linkData[$linkId]['serverControls'][LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'])) {
$this->linkData[$linkId]['serverControls'][LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'] = '';
}
}

public function setRequestParameters($link, int $pageSize, bool $isCritical): void {
public function setRequestParameters($link, int $pageSize, bool $isCritical, string $cookie = ''): void {
$linkId = $this->getLinkId($link);
if (!isset($this->linkData[$linkId])) {
$this->linkData[$linkId] = [];
@@ -95,10 +47,7 @@ class Php73 implements IAdapter {
$this->linkData[$linkId]['requestArgs'] = [];
$this->linkData[$linkId]['requestArgs']['pageSize'] = $pageSize;
$this->linkData[$linkId]['requestArgs']['isCritical'] = $isCritical;

if ($pageSize === 0) {
$this->resetCookie($linkId);
}
$this->linkData[$linkId]['requestArgs']['cookie'] = $cookie;
}

public function setSearchArgs(
@@ -132,8 +81,9 @@ class Php73 implements IAdapter {
'oid' => LDAP_CONTROL_PAGEDRESULTS,
'value' => [
'size' => $this->linkData[$linkId]['requestArgs']['pageSize'],
'cookie' => $this->linkData[$linkId]['serverControls'][LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'] ?? '',
]
'cookie' => $this->linkData[$linkId]['requestArgs']['cookie'],
],
'iscritical' => $this->linkData[$linkId]['requestArgs']['isCritical'],
]];

$this->linkData[$linkId][$methodKey][] = -1; // timelimit

Loading…
Cancel
Save