From 066e3770bbfbf59a3b0d1a83ddb11361c57df10d Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Fri, 9 Oct 2015 11:57:10 +0200 Subject: [PATCH 1/4] Make sure that permissions stay in sync for share_type 2 When a file/folder is shared with a group and one of the group members moves this file/folder an extra entry is created in the share table. When the permission of the group share is updated we used to only sometimes update the shares for individual users. * Added intergration tests --- apps/files_sharing/tests/sharedmount.php | 135 +++++++++++++++++++++++ lib/private/share/share.php | 127 +++++++++++++-------- 2 files changed, 213 insertions(+), 49 deletions(-) diff --git a/apps/files_sharing/tests/sharedmount.php b/apps/files_sharing/tests/sharedmount.php index 7b256588f9..5b625585eb 100644 --- a/apps/files_sharing/tests/sharedmount.php +++ b/apps/files_sharing/tests/sharedmount.php @@ -237,6 +237,141 @@ class Test_Files_Sharing_Mount extends OCA\Files_sharing\Tests\TestCase { ); } + function dataPermissionMovedGroupShare() { + $data = []; + + $powerset = function($permissions) { + $results = [\OCP\Constants::PERMISSION_READ]; + + foreach ($permissions as $permission) { + foreach ($results as $combination) { + $results[] = $permission | $combination; + } + } + return $results; + }; + + //Generate file permissions + $permissions = [ + \OCP\Constants::PERMISSION_UPDATE, + \OCP\Constants::PERMISSION_CREATE, + \OCP\Constants::PERMISSION_SHARE, + ]; + + $allPermissions = $powerset($permissions); + + foreach ($allPermissions as $before) { + foreach ($allPermissions as $after) { + if ($before === $after) { continue; } + + $data[] = [ + 'file', + $before, + $after, + ]; + } + } + + //Generate folder permissions + $permissions = [ + \OCP\Constants::PERMISSION_UPDATE, + \OCP\Constants::PERMISSION_CREATE, + \OCP\Constants::PERMISSION_SHARE, + \OCP\Constants::PERMISSION_DELETE + ]; + + $allPermissions = $powerset($permissions); + + foreach ($allPermissions as $before) { + foreach ($allPermissions as $after) { + if ($before === $after) { continue; } + + $data[] = [ + 'folder', + $before, + $after, + ]; + } + } + + return $data; + } + + + + /** + * moved mountpoints of a group share should keep the same permission as their parent group share. + * See #15253 + * + * @dataProvider dataPermissionMovedGroupShare + */ + function testPermissionMovedGroupShare($type, $beforePerm, $afterPerm) { + + if ($type === 'file') { + $path = $this->filename; + } else if ($type === 'folder') { + $path = $this->folder; + } + + \OC_Group::createGroup('testGroup'); + \OC_Group::addToGroup(self::TEST_FILES_SHARING_API_USER1, 'testGroup'); + \OC_Group::addToGroup(self::TEST_FILES_SHARING_API_USER2, 'testGroup'); + \OC_Group::addToGroup(self::TEST_FILES_SHARING_API_USER3, 'testGroup'); + + // Share item with group + $fileinfo = $this->view->getFileInfo($path); + $this->assertTrue( + \OCP\Share::shareItem($type, $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, "testGroup", $beforePerm) + ); + + // Login as user 2 and verify the item exists + self::loginHelper(self::TEST_FILES_SHARING_API_USER2); + $this->assertTrue(\OC\Files\Filesystem::file_exists($path)); + $result = \OCP\Share::getItemSharedWithBySource($type, $fileinfo['fileid']); + $this->assertNotEmpty($result); + $this->assertEquals($beforePerm, $result['permissions']); + + // Now move the item forcing a new entry in the share table + \OC\Files\Filesystem::rename($path, "newPath"); + $this->assertTrue(\OC\Files\Filesystem::file_exists('newPath')); + $this->assertFalse(\OC\Files\Filesystem::file_exists($path)); + + // Login as user 1 again and change permissions + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + $this->assertTrue( + \OCP\Share::setPermissions($type, $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, "testGroup", $afterPerm) + ); + + // Login as user 3 and verify that the permissions are changed + self::loginHelper(self::TEST_FILES_SHARING_API_USER3); + $result = \OCP\Share::getItemSharedWithBySource($type, $fileinfo['fileid']); + $this->assertNotEmpty($result); + $this->assertEquals($afterPerm, $result['permissions']); + $groupShareId = $result['id']; + + // Login as user 2 and verify that the permissions are changed + self::loginHelper(self::TEST_FILES_SHARING_API_USER2); + $result = \OCP\Share::getItemSharedWithBySource($type, $fileinfo['fileid']); + $this->assertNotEmpty($result); + $this->assertEquals($afterPerm, $result['permissions']); + $this->assertNotEquals($groupShareId, $result['id']); + + // Also verify in the DB + $statement = "SELECT `permissions` FROM `*PREFIX*share` WHERE `id`=?"; + $query = \OCP\DB::prepare($statement); + $result = $query->execute([$result['id']]); + $shares = $result->fetchAll(); + $this->assertCount(1, $shares); + $this->assertEquals($afterPerm, $shares[0]['permissions']); + + //cleanup + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + \OCP\Share::unshare($type, $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, 'testGroup'); + \OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER1, 'testGroup'); + \OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER2, 'testGroup'); + \OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER3, 'testGroup'); + } + } class DummyTestClassSharedMount extends \OCA\Files_Sharing\SharedMount { diff --git a/lib/private/share/share.php b/lib/private/share/share.php index db27fa6a89..7e6b06ade9 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -1100,13 +1100,13 @@ class Share extends Constants { */ public static function setPermissions($itemType, $itemSource, $shareType, $shareWith, $permissions) { $l = \OC::$server->getL10N('lib'); - if ($item = self::getItems($itemType, $itemSource, $shareType, $shareWith, + if ($rootItem = self::getItems($itemType, $itemSource, $shareType, $shareWith, \OC_User::getUser(), self::FORMAT_NONE, null, 1, false)) { // Check if this item is a reshare and verify that the permissions // granted don't exceed the parent shared item - if (isset($item['parent'])) { + if (isset($rootItem['parent'])) { $query = \OC_DB::prepare('SELECT `permissions` FROM `*PREFIX*share` WHERE `id` = ?', 1); - $result = $query->execute(array($item['parent']))->fetchRow(); + $result = $query->execute([$rootItem['parent']])->fetchRow(); if (~(int)$result['permissions'] & $permissions) { $message = 'Setting permissions for %s failed,' .' because the permissions exceed permissions granted to %s'; @@ -1116,7 +1116,7 @@ class Share extends Constants { } } $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `permissions` = ? WHERE `id` = ?'); - $query->execute(array($permissions, $item['id'])); + $query->execute([$permissions, $rootItem['id']]); if ($itemType === 'file' || $itemType === 'folder') { \OC_Hook::emit('OCP\Share', 'post_update_permissions', array( 'itemType' => $itemType, @@ -1125,56 +1125,85 @@ class Share extends Constants { 'shareWith' => $shareWith, 'uidOwner' => \OC_User::getUser(), 'permissions' => $permissions, - 'path' => $item['path'], - 'share' => $item + 'path' => $rootItem['path'], + 'share' => $rootItem )); } - // Check if permissions were removed - if ($item['permissions'] & ~$permissions) { - // If share permission is removed all reshares must be deleted - if (($item['permissions'] & \OCP\Constants::PERMISSION_SHARE) && (~$permissions & \OCP\Constants::PERMISSION_SHARE)) { - // delete all shares, keep parent and group children - Helper::delete($item['id'], true, null, null, true); - } else { - $ids = array(); - $items = []; - $parents = array($item['id']); - while (!empty($parents)) { - $parents = "'".implode("','", $parents)."'"; - $query = \OC_DB::prepare('SELECT `id`, `permissions`, `item_type` FROM `*PREFIX*share`' - .' WHERE `parent` IN ('.$parents.')'); - $result = $query->execute(); - // Reset parents array, only go through loop again if - // items are found that need permissions removed - $parents = array(); - while ($item = $result->fetchRow()) { - $items[] = $item; - // Check if permissions need to be removed - if ($item['permissions'] & ~$permissions) { - // Add to list of items that need permissions removed - $ids[] = $item['id']; - $parents[] = $item['id']; - } - } - } - // Remove the permissions for all reshares of this item - if (!empty($ids)) { - $ids = "'".implode("','", $ids)."'"; - // TODO this should be done with Doctrine platform objects - if (\OC::$server->getConfig()->getSystemValue("dbtype") === 'oci') { - $andOp = 'BITAND(`permissions`, ?)'; - } else { - $andOp = '`permissions` & ?'; - } - $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `permissions` = '.$andOp - .' WHERE `id` IN ('.$ids.')'); - $query->execute(array($permissions)); - } - foreach ($items as $item) { - \OC_Hook::emit('OCP\Share', 'post_update_permissions', ['share' => $item]); + // Share id's to update with the new permissions + $ids = []; + $items = []; + + // Check if permissions were removed + if ((int)$rootItem['permissions'] & ~$permissions) { + // If share permission is removed all reshares must be deleted + if (($rootItem['permissions'] & \OCP\Constants::PERMISSION_SHARE) && (~$permissions & \OCP\Constants::PERMISSION_SHARE)) { + // delete all shares, keep parent and group children + Helper::delete($rootItem['id'], true, null, null, true); + } + + // Remove permission from all children + $parents = [$rootItem['id']]; + while (!empty($parents)) { + $parents = "'".implode("','", $parents)."'"; + $query = \OC_DB::prepare('SELECT `id`, `permissions`, `item_type` FROM `*PREFIX*share`' + .' WHERE `parent` IN ('.$parents.')'); + $result = $query->execute(); + // Reset parents array, only go through loop again if + // items are found that need permissions removed + $parents = array(); + while ($item = $result->fetchRow()) { + $items[] = $item; + // Check if permissions need to be removed + if ($item['permissions'] & ~$permissions) { + // Add to list of items that need permissions removed + $ids[] = $item['id']; + $parents[] = $item['id']; + } } } + + // Remove the permissions for all reshares of this item + if (!empty($ids)) { + $ids = "'".implode("','", $ids)."'"; + // TODO this should be done with Doctrine platform objects + if (\OC::$server->getConfig()->getSystemValue("dbtype") === 'oci') { + $andOp = 'BITAND(`permissions`, ?)'; + } else { + $andOp = '`permissions` & ?'; + } + $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `permissions` = '.$andOp + .' WHERE `id` IN ('.$ids.')'); + $query->execute(array($permissions)); + } + + } + + /* + * Permissions were added + * Update all USERGROUP shares. (So group shares where the user moved his mountpoint). + */ + if ($permissions & ~(int)$rootItem['permissions']) { + $query = \OC_DB::prepare('SELECT `id`, `permissions`, `item_type` FROM `*PREFIX*share`' + .' WHERE `parent` = ? AND `share_type` = ?'); + $result = $query->execute([$rootItem['id'], 2]); + + $ids = []; + while ($item = $result->fetchRow()) { + $items[] = $item; + $ids[] = $item['id']; + } + + // Add permssions for all USERGROUP shares of this item + if (!empty($ids)) { + $ids = "'".implode("','", $ids)."'"; + $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `permissions` = ? WHERE `id` IN ('.$ids.')'); + $query->execute(array($permissions)); + } + } + + foreach ($items as $item) { + \OC_Hook::emit('OCP\Share', 'post_update_permissions', ['share' => $item]); } return true; From c882d46e5f3ccdfb7beb062c219ba3f9a3a83b8f Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Thu, 15 Oct 2015 10:19:25 +0200 Subject: [PATCH 2/4] Moved to the query builder Anything to keep Lukas happy --- lib/private/share/share.php | 73 ++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 17 deletions(-) diff --git a/lib/private/share/share.php b/lib/private/share/share.php index 7e6b06ade9..e7f83909cb 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -1100,13 +1100,32 @@ class Share extends Constants { */ public static function setPermissions($itemType, $itemSource, $shareType, $shareWith, $permissions) { $l = \OC::$server->getL10N('lib'); + $connection = \OC::$server->getDatabaseConnection(); + + $intArrayToLiteralArray = function($intArray, $eb) { + return array_map(function($int) use ($eb) { + return $eb->literal((int)$int, 'integer'); + }, $intArray); + }; + $sanitizeItem = function($item) { + $item['id'] = (int)$item['id']; + $item['premissions'] = (int)$item['permissions']; + return $item; + }; + if ($rootItem = self::getItems($itemType, $itemSource, $shareType, $shareWith, \OC_User::getUser(), self::FORMAT_NONE, null, 1, false)) { // Check if this item is a reshare and verify that the permissions // granted don't exceed the parent shared item if (isset($rootItem['parent'])) { - $query = \OC_DB::prepare('SELECT `permissions` FROM `*PREFIX*share` WHERE `id` = ?', 1); - $result = $query->execute([$rootItem['parent']])->fetchRow(); + $qb = $connection->getQueryBuilder(); + $qb->select('permissions') + ->from('share') + ->where($qb->expr()->eq('id', $qb->createParameter('id'))) + ->setParameter(':id', $rootItem['parent']); + $result = $qb->execute(); + + $result = $result->fetch(); if (~(int)$result['permissions'] & $permissions) { $message = 'Setting permissions for %s failed,' .' because the permissions exceed permissions granted to %s'; @@ -1115,8 +1134,13 @@ class Share extends Constants { throw new \Exception($message_t); } } - $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `permissions` = ? WHERE `id` = ?'); - $query->execute([$permissions, $rootItem['id']]); + $qb = $connection->getQueryBuilder(); + $qb->update('share') + ->set('permissions', $qb->createParameter('permissions')) + ->where($qb->expr()->eq('id', $qb->createParameter('id'))) + ->setParameter(':id', $rootItem['id']) + ->setParameter(':permissions', $permissions); + $qb->execute(); if ($itemType === 'file' || $itemType === 'folder') { \OC_Hook::emit('OCP\Share', 'post_update_permissions', array( 'itemType' => $itemType, @@ -1145,14 +1169,18 @@ class Share extends Constants { // Remove permission from all children $parents = [$rootItem['id']]; while (!empty($parents)) { - $parents = "'".implode("','", $parents)."'"; - $query = \OC_DB::prepare('SELECT `id`, `permissions`, `item_type` FROM `*PREFIX*share`' - .' WHERE `parent` IN ('.$parents.')'); - $result = $query->execute(); + $parents = $intArrayToLiteralArray($parents, $qb->expr()); + $qb = $connection->getQueryBuilder(); + $qb->select('id', 'permissions', 'item_type') + ->from('share') + ->where($qb->expr()->in('parent', $parents)); + $result = $qb->execute(); // Reset parents array, only go through loop again if // items are found that need permissions removed - $parents = array(); - while ($item = $result->fetchRow()) { + $parents = []; + while ($item = $result->fetch()) { + $item = $sanitizeItem($item); + $items[] = $item; // Check if permissions need to be removed if ($item['permissions'] & ~$permissions) { @@ -1184,21 +1212,32 @@ class Share extends Constants { * Update all USERGROUP shares. (So group shares where the user moved his mountpoint). */ if ($permissions & ~(int)$rootItem['permissions']) { - $query = \OC_DB::prepare('SELECT `id`, `permissions`, `item_type` FROM `*PREFIX*share`' - .' WHERE `parent` = ? AND `share_type` = ?'); - $result = $query->execute([$rootItem['id'], 2]); + $qb = $connection->getQueryBuilder(); + $qb->select('id', 'permissions', 'item_type') + ->from('share') + ->where($qb->expr()->eq('parent', $qb->createParameter('parent'))) + ->andWhere($qb->expr()->eq('share_type', $qb->createParameter('share_type'))) + ->setParameter(':parent', (int)$rootItem['id']) + ->setParameter(':share_type', 2); + $result = $qb->execute(); $ids = []; - while ($item = $result->fetchRow()) { + while ($item = $result->fetch()) { + $item = $sanitizeItem($item); $items[] = $item; $ids[] = $item['id']; } // Add permssions for all USERGROUP shares of this item if (!empty($ids)) { - $ids = "'".implode("','", $ids)."'"; - $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `permissions` = ? WHERE `id` IN ('.$ids.')'); - $query->execute(array($permissions)); + $ids = $intArrayToLiteralArray($ids, $qb->expr()); + + $qb = $connection->getQueryBuilder(); + $qb->update('share') + ->set('permissions', $qb->createParameter('permissions')) + ->where($qb->expr()->in('id', $ids)) + ->setParameter(':permissions', $permissions); + $qb->execute(); } } From 629bac22fd724ac8bcde6401782d9d2517556137 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Fri, 23 Oct 2015 13:57:09 +0200 Subject: [PATCH 3/4] Make sure to respect deleted group shares by user --- apps/files_sharing/tests/sharedmount.php | 79 ++++++++++++++++++++++++ lib/private/share/share.php | 4 +- 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/apps/files_sharing/tests/sharedmount.php b/apps/files_sharing/tests/sharedmount.php index 5b625585eb..21c98625e6 100644 --- a/apps/files_sharing/tests/sharedmount.php +++ b/apps/files_sharing/tests/sharedmount.php @@ -372,6 +372,85 @@ class Test_Files_Sharing_Mount extends OCA\Files_sharing\Tests\TestCase { \OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER3, 'testGroup'); } + /** + * If the permissions on a group share are upgraded be sure to still respect + * removed shares by a member of that group + */ + function testPermissionUpgradeOnUserDeletedGroupShare() { + \OC_Group::createGroup('testGroup'); + \OC_Group::addToGroup(self::TEST_FILES_SHARING_API_USER1, 'testGroup'); + \OC_Group::addToGroup(self::TEST_FILES_SHARING_API_USER2, 'testGroup'); + \OC_Group::addToGroup(self::TEST_FILES_SHARING_API_USER3, 'testGroup'); + + $connection = \OC::$server->getDatabaseConnection(); + + // Share item with group + $fileinfo = $this->view->getFileInfo($this->folder); + $this->assertTrue( + \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, "testGroup", \OCP\Constants::PERMISSION_READ) + ); + + // Login as user 2 and verify the item exists + self::loginHelper(self::TEST_FILES_SHARING_API_USER2); + $this->assertTrue(\OC\Files\Filesystem::file_exists($this->folder)); + $result = \OCP\Share::getItemSharedWithBySource('folder', $fileinfo['fileid']); + $this->assertNotEmpty($result); + $this->assertEquals(\OCP\Constants::PERMISSION_READ, $result['permissions']); + + // Delete the share + $this->assertTrue(\OC\Files\Filesystem::rmdir($this->folder)); + $this->assertFalse(\OC\Files\Filesystem::file_exists($this->folder)); + + // Verify we do not get a share + $result = \OCP\Share::getItemSharedWithBySource('folder', $fileinfo['fileid']); + $this->assertEmpty($result); + + // Verify that the permission is correct in the DB + $qb = $connection->getQueryBuilder(); + $qb->select('*') + ->from('share') + ->where($qb->expr()->eq('file_source', $qb->createParameter('fileSource'))) + ->andWhere($qb->expr()->eq('share_type', $qb->createParameter('shareType'))) + ->setParameter(':fileSource', $fileinfo['fileid']) + ->setParameter(':shareType', 2); + $res = $qb->execute()->fetchAll(); + + $this->assertCount(1, $res); + $this->assertEquals(0, $res[0]['permissions']); + + // Login as user 1 again and change permissions + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + $this->assertTrue( + \OCP\Share::setPermissions('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, "testGroup", \OCP\Constants::PERMISSION_ALL) + ); + + // Login as user 2 and verify + self::loginHelper(self::TEST_FILES_SHARING_API_USER2); + $this->assertFalse(\OC\Files\Filesystem::file_exists($this->folder)); + $result = \OCP\Share::getItemSharedWithBySource('folder', $fileinfo['fileid']); + $this->assertEmpty($result); + + $connection = \OC::$server->getDatabaseConnection(); + $qb = $connection->getQueryBuilder(); + $qb->select('*') + ->from('share') + ->where($qb->expr()->eq('file_source', $qb->createParameter('fileSource'))) + ->andWhere($qb->expr()->eq('share_type', $qb->createParameter('shareType'))) + ->setParameter(':fileSource', $fileinfo['fileid']) + ->setParameter(':shareType', 2); + $res = $qb->execute()->fetchAll(); + + $this->assertCount(1, $res); + $this->assertEquals(0, $res[0]['permissions']); + + //cleanup + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, 'testGroup'); + \OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER1, 'testGroup'); + \OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER2, 'testGroup'); + \OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER3, 'testGroup'); + } + } class DummyTestClassSharedMount extends \OCA\Files_Sharing\SharedMount { diff --git a/lib/private/share/share.php b/lib/private/share/share.php index e7f83909cb..f02b2e9c77 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -1217,8 +1217,10 @@ class Share extends Constants { ->from('share') ->where($qb->expr()->eq('parent', $qb->createParameter('parent'))) ->andWhere($qb->expr()->eq('share_type', $qb->createParameter('share_type'))) + ->andWhere($qb->expr()->neq('permissions', $qb->createParameter('shareDeleted'))) ->setParameter(':parent', (int)$rootItem['id']) - ->setParameter(':share_type', 2); + ->setParameter(':share_type', 2) + ->setParameter(':shareDeleted', 0); $result = $qb->execute(); $ids = []; From 17a066c18e6d855895bb4604988d5ed40a423dc8 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Tue, 27 Oct 2015 10:22:59 +0100 Subject: [PATCH 4/4] Properly close db cursors --- apps/files_sharing/tests/sharedmount.php | 2 +- lib/private/share/share.php | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/apps/files_sharing/tests/sharedmount.php b/apps/files_sharing/tests/sharedmount.php index 21c98625e6..15ebc7caf7 100644 --- a/apps/files_sharing/tests/sharedmount.php +++ b/apps/files_sharing/tests/sharedmount.php @@ -277,7 +277,7 @@ class Test_Files_Sharing_Mount extends OCA\Files_sharing\Tests\TestCase { \OCP\Constants::PERMISSION_UPDATE, \OCP\Constants::PERMISSION_CREATE, \OCP\Constants::PERMISSION_SHARE, - \OCP\Constants::PERMISSION_DELETE + \OCP\Constants::PERMISSION_DELETE, ]; $allPermissions = $powerset($permissions); diff --git a/lib/private/share/share.php b/lib/private/share/share.php index f02b2e9c77..63639461f0 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -1123,9 +1123,10 @@ class Share extends Constants { ->from('share') ->where($qb->expr()->eq('id', $qb->createParameter('id'))) ->setParameter(':id', $rootItem['parent']); - $result = $qb->execute(); + $dbresult = $qb->execute(); - $result = $result->fetch(); + $result = $dbresult->fetch(); + $dbresult->closeCursor(); if (~(int)$result['permissions'] & $permissions) { $message = 'Setting permissions for %s failed,' .' because the permissions exceed permissions granted to %s'; @@ -1189,6 +1190,7 @@ class Share extends Constants { $parents[] = $item['id']; } } + $result->closeCursor(); } // Remove the permissions for all reshares of this item @@ -1209,7 +1211,7 @@ class Share extends Constants { /* * Permissions were added - * Update all USERGROUP shares. (So group shares where the user moved his mountpoint). + * Update all USERGROUP shares. (So group shares where the user moved their mountpoint). */ if ($permissions & ~(int)$rootItem['permissions']) { $qb = $connection->getQueryBuilder(); @@ -1229,6 +1231,7 @@ class Share extends Constants { $items[] = $item; $ids[] = $item['id']; } + $result->closeCursor(); // Add permssions for all USERGROUP shares of this item if (!empty($ids)) {