Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorArthur Schiwon <blizzz@owncloud.com>2014-09-18 19:12:35 +0400
committerArthur Schiwon <blizzz@owncloud.com>2014-10-20 14:51:38 +0400
commite46f87fdacb8273675311a8538fc4b47fdb0ac13 (patch)
treeae770714eab7faa8d41dda09652f3634d476d1ad /apps
parent6fc04c2f9129fc55966ad66d2ddca1b7d884f4e9 (diff)
backport of #11494
fix retrievel of group members and cache group members fix changed variable name with several backends, more than limit can be returned make performance less bad. Still far from good, but at least it works add one simple cache test adjust group manager tests Conflicts: apps/user_ldap/group_ldap.php apps/user_ldap/lib/access.php apps/user_ldap/tests/group_ldap.php
Diffstat (limited to 'apps')
-rw-r--r--apps/user_ldap/group_ldap.php66
-rw-r--r--apps/user_ldap/lib/access.php2
2 files changed, 53 insertions, 15 deletions
diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php
index 30217412611..dafb29e901c 100644
--- a/apps/user_ldap/group_ldap.php
+++ b/apps/user_ldap/group_ldap.php
@@ -29,6 +29,11 @@ use OCA\user_ldap\lib\BackendUtility;
class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
protected $enabled = false;
+ /**
+ * @var string[] $cachedGroupMembers array of users with gid as key
+ */
+ protected $cachedGroupMembers = array();
+
public function __construct(Access $access) {
parent::__construct($access);
$filter = $this->access->connection->ldapGroupFilter;
@@ -55,6 +60,21 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
}
$dn_user = $this->access->username2dn($uid);
$dn_group = $this->access->groupname2dn($gid);
+
+ if(isset($this->cachedGroupMembers[$gid])) {
+ $isInGroup = in_array($dn_user, $this->cachedGroupMembers[$gid]);
+ return $isInGroup;
+ }
+
+ $cacheKeyMembers = 'inGroup-members:'.$gid;
+ if($this->access->connection->isCached($cacheKeyMembers)) {
+ $members = $this->access->connection->getFromCache($cacheKeyMembers);
+ $this->cachedGroupMembers[$gid] = $members;
+ $isInGroup = in_array($dn_user, $members);
+ $this->access->connection->writeToCache($cacheKey, $isInGroup);
+ return $isInGroup;
+ }
+
// just in case
if(!$dn_group || !$dn_user) {
$this->access->connection->writeToCache('inGroup'.$uid.':'.$gid, false);
@@ -62,29 +82,42 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
}
//usually, LDAP attributes are said to be case insensitive. But there are exceptions of course.
$members = $this->access->readAttribute($dn_group,
- $this->access->connection->ldapGroupMemberAssocAttr);
- if(!$members) {
+ $this->access->connection->ldapGroupMemberAssocAttr);
+ if(!is_array($members) || count($members) === 0) {
$this->access->connection->writeToCache('inGroup'.$uid.':'.$gid, false);
return false;
}
//extra work if we don't get back user DNs
- //TODO: this can be done with one LDAP query
if(strtolower($this->access->connection->ldapGroupMemberAssocAttr) === 'memberuid') {
$dns = array();
+ $filterParts = array();
+ $bytes = 0;
foreach($members as $mid) {
$filter = str_replace('%uid', $mid, $this->access->connection->ldapLoginFilter);
- $ldap_users = $this->access->fetchListOfUsers($filter, 'dn');
- if(count($ldap_users) < 1) {
- continue;
+ $filterParts[] = $filter;
+ $bytes += strlen($filter);
+ if($bytes >= 9000000) {
+ // AD has a default input buffer of 10 MB, we do not want
+ // to take even the chance to exceed it
+ $filter = $this->access->combineFilterWithOr($filterParts);
+ $bytes = 0;
+ $filterParts = array();
+ $users = $this->access->fetchListOfUsers($filter, 'dn', count($filterParts));
+ $dns = array_merge($dns, $users);
}
- $dns[] = $ldap_users[0];
+ }
+ if(count($filterParts) > 0) {
+ $filter = $this->access->combineFilterWithOr($filterParts);
+ $users = $this->access->fetchListOfUsers($filter, 'dn', count($filterParts));
+ $dns = array_merge($dns, $users);
}
$members = $dns;
}
-
$isInGroup = in_array($dn_user, $members);
$this->access->connection->writeToCache('inGroup'.$uid.':'.$gid, $isInGroup);
+ $this->access->connection->writeToCache($cacheKeyMembers, $members);
+ $this->cachedGroupMembers[$gid] = $members;
return $isInGroup;
}
@@ -123,13 +156,18 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
// just in case
$uid = $userDN;
}
+
+ if(isset($this->cachedGroupsByMember[$uid])) {
+ $groups = $this->cachedGroupsByMember[$uid];
+ } else {
+ $filter = $this->access->combineFilterWithAnd(array(
+ $this->access->connection->ldapGroupFilter,
+ $this->access->connection->ldapGroupMemberAssocAttr.'='.$uid
+ ));
+ $groups = $this->access->fetchListOfGroups($filter,
+ array($this->access->connection->ldapGroupDisplayName, 'dn'));
+ }
- $filter = $this->access->combineFilterWithAnd(array(
- $this->access->connection->ldapGroupFilter,
- $this->access->connection->ldapGroupMemberAssocAttr.'='.$uid
- ));
- $groups = $this->access->fetchListOfGroups($filter,
- array($this->access->connection->ldapGroupDisplayName, 'dn'));
$groups = array_unique($this->access->ownCloudGroupNames($groups), SORT_LOCALE_STRING);
$this->access->connection->writeToCache($cacheKey, $groups);
diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php
index 06d700afb02..8bde04faed3 100644
--- a/apps/user_ldap/lib/access.php
+++ b/apps/user_ldap/lib/access.php
@@ -1250,7 +1250,7 @@ class Access extends LDAPUtility {
* @param $bases array containing the allowed base DN or DNs
* @returns Boolean
*/
- private function isDNPartOfBase($dn, $bases) {
+ public function isDNPartOfBase($dn, $bases) {
$bases = $this->sanitizeDN($bases);
foreach($bases as $base) {
$belongsToBase = true;