aboutsummaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorRoeland Jago Douma <rullzer@users.noreply.github.com>2021-01-08 08:25:03 +0100
committerGitHub <noreply@github.com>2021-01-08 08:25:03 +0100
commit741e5e273bd91ccf2c11b255cd0fee37d3832ec5 (patch)
tree7102a7e20ea4f8c0ab5a88db9395325865fba088 /apps
parent645e3e6d7e89edb9ea2e56b7438fe5b4e4ea0e8d (diff)
parent6eca8d6ae158e613547b7eba1f0dda141a008ee0 (diff)
downloadnextcloud-server-741e5e273bd91ccf2c11b255cd0fee37d3832ec5.tar.gz
nextcloud-server-741e5e273bd91ccf2c11b255cd0fee37d3832ec5.zip
Merge pull request #25020 from nextcloud/fix/noid/limitied-allowed-items-db-in
(LDAP) respect DB limits of arguments in an IN statement
Diffstat (limited to 'apps')
-rw-r--r--apps/user_ldap/lib/Mapping/AbstractMapping.php22
-rw-r--r--apps/user_ldap/tests/Mapping/AbstractMappingTest.php19
2 files changed, 36 insertions, 5 deletions
diff --git a/apps/user_ldap/lib/Mapping/AbstractMapping.php b/apps/user_ldap/lib/Mapping/AbstractMapping.php
index 15f95744cd0..64973d7d7cc 100644
--- a/apps/user_ldap/lib/Mapping/AbstractMapping.php
+++ b/apps/user_ldap/lib/Mapping/AbstractMapping.php
@@ -190,18 +190,30 @@ abstract class AbstractMapping {
}
public function getListOfIdsByDn(array $fdns): array {
+ $fdnsSlice = count($fdns) > 1000 ? array_slice($fdns, 0, 1000) : $fdns;
$qb = $this->dbc->getQueryBuilder();
$qb->select('owncloud_name', 'ldap_dn')
->from($this->getTableName(false))
- ->where($qb->expr()->in('ldap_dn', $qb->createNamedParameter($fdns, QueryBuilder::PARAM_STR_ARRAY)));
- $stmt = $qb->execute();
+ ->where($qb->expr()->in('ldap_dn', $qb->createNamedParameter($fdnsSlice, QueryBuilder::PARAM_STR_ARRAY)));
+
+ $slice = 1;
+ while (isset($fdnsSlice[999])) {
+ // Oracle does not allow more than 1000 values in the IN list,
+ // but allows slicing
+ $fdnsSlice = array_slice($fdns, 1000 * $slice, 1000);
+ if (!empty($fdnsSlice)) {
+ $qb->orWhere($qb->expr()->in('ldap_dn', $qb->createNamedParameter($fdnsSlice, QueryBuilder::PARAM_STR_ARRAY)));
+ }
+ $slice++;
+ }
- $results = $stmt->fetchAll(\Doctrine\DBAL\FetchMode::ASSOCIATIVE);
- foreach ($results as $key => $entry) {
- unset($results[$key]);
+ $stmt = $qb->execute();
+ $results = [];
+ while ($entry = $stmt->fetch(\Doctrine\DBAL\FetchMode::ASSOCIATIVE)) {
$results[$entry['ldap_dn']] = $entry['owncloud_name'];
$this->cache[$entry['ldap_dn']] = $entry['owncloud_name'];
}
+ $stmt->closeCursor();
return $results;
}
diff --git a/apps/user_ldap/tests/Mapping/AbstractMappingTest.php b/apps/user_ldap/tests/Mapping/AbstractMappingTest.php
index 079c2e21b10..dd322d58a8e 100644
--- a/apps/user_ldap/tests/Mapping/AbstractMappingTest.php
+++ b/apps/user_ldap/tests/Mapping/AbstractMappingTest.php
@@ -281,4 +281,23 @@ abstract class AbstractMappingTest extends \Test\TestCase {
$results = $mapper->getList(1, 1);
$this->assertSame(1, count($results));
}
+
+ public function testGetListOfIdsByDn() {
+ /** @var AbstractMapping $mapper */
+ list($mapper,) = $this->initTest();
+
+ $listOfDNs = [];
+ for ($i = 0; $i < 65640; $i++) {
+ // Postgres has a limit of 65535 values in a single IN list
+ $name = 'as_' . $i;
+ $dn = 'uid=' . $name . ',dc=example,dc=org';
+ $listOfDNs[] = $dn;
+ if ($i % 20 === 0) {
+ $mapper->map($dn, $name, 'fake-uuid-' . $i);
+ }
+ }
+
+ $result = $mapper->getListOfIdsByDn($listOfDNs);
+ $this->assertSame(65640 / 20, count($result));
+ }
}