]> source.dussan.org Git - nextcloud-server.git/commitdiff
make performance less bad. Still far from good, but at least it works
authorArthur Schiwon <blizzz@owncloud.com>
Fri, 10 Oct 2014 19:29:11 +0000 (21:29 +0200)
committerArthur Schiwon <blizzz@owncloud.com>
Fri, 17 Oct 2014 18:16:04 +0000 (20:16 +0200)
apps/user_ldap/group_ldap.php
apps/user_ldap/lib/access.php
lib/private/group/manager.php

index 8a6084b6c8f997555a9c9bd672abba5758639963..e8d268d3df2848a680303a20449ccbb6bbef2687 100644 (file)
@@ -34,6 +34,11 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
         */
        protected $cachedGroupMembers = array();
 
+       /**
+        * @var string[] $cachedGroupsByMember array of groups with uid as key
+        */
+       protected $cachedGroupsByMember = array();
+
        public function __construct(Access $access) {
                parent::__construct($access);
                $filter = $this->access->connection->ldapGroupFilter;
@@ -98,16 +103,28 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
                }
 
                //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;
                }
@@ -316,8 +333,13 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
                        $uid = $userDN;
                }
 
-               $groups = array_values($this->getGroupsByMember($uid));
-               $groups = $this->access->ownCloudGroupNames($groups);
+               if(isset($this->cachedGroupsByMember[$uid])) {
+                       $groups = $this->cachedGroupsByMember[$uid];
+               } else {
+                       $groups = array_values($this->getGroupsByMember($uid));
+                       $groups = $this->access->ownCloudGroupNames($groups);
+                       $this->cachedGroupsByMember[$uid] = $groups;
+               }
 
                $primaryGroup = $this->getUserPrimaryGroup($userDN);
                if($primaryGroup !== false) {
index 159b0d7300041e7c1e384d9a468fd8d0399a7137..44162e32d47044e598e1f4d537db5c853c369417 100644 (file)
@@ -1359,7 +1359,7 @@ class Access extends LDAPUtility implements user\IUserTools {
         * @param string[] $bases array containing the allowed base DN or DNs
         * @return bool
         */
-       private function isDNPartOfBase($dn, $bases) {
+       public function isDNPartOfBase($dn, $bases) {
                $belongsToBase = false;
                $bases = $this->sanitizeDN($bases);
 
index 33a1904dddf0b6320364ee8ca891a2e4abb72637..417be79ab30af40beed1cf73dc2684be0f83daa6 100644 (file)
@@ -223,10 +223,9 @@ class Manager extends PublicEmitter implements IGroupManager {
                if(!empty($search)) {
                        // only user backends have the capability to do a complex search for users
                        $searchOffset = 0;
+                       $searchLimit = $limit * 100;
                        if($limit === -1) {
-                               $searchLimit = $group->count('');
-                       } else {
-                               $searchLimit = $limit * 2;
+                               $searchLimit = 500;
                        }
 
                        do {