]> source.dussan.org Git - nextcloud-server.git/commitdiff
Fix permissions when copying from ObjectStorage 29115/head
authorCarl Schwan <carl@carlschwan.eu>
Thu, 7 Oct 2021 09:50:33 +0000 (11:50 +0200)
committerCarl Schwan <carl@carlschwan.eu>
Thu, 28 Oct 2021 11:29:50 +0000 (13:29 +0200)
Make sure that when a user copy a file from a directory they don't have
all permissions to a directory where they have more permissions, the
permissions are correctly set to the one from the parent taget folder.

This was caused by the ObjectStoreStorage::copyFromStorage using
the jailed storage and cache entry instead of the unjailed one like other
storages (the local one).
Steps to reproduce

+ Use object storage
+ Create a groupfolder with one group having full permission and another one
  who can just read files.
+ With an user who is in the second group, copy a file from the groupfolder to
  the home folder of this user.
+ The file in the home folder of the user will be read only and can't be deleted
  even though it is in their home folder and they are the owner. In oc_filecache,
  the permissions stored for this file are 1 (READ)

Signed-off-by: Carl Schwan <carl@carlschwan.eu>
lib/private/Files/Cache/Cache.php
lib/private/Files/ObjectStore/ObjectStoreStorage.php

index aec97d1ad33f91f411b5a71744c8365bf6c4c22e..443a2b554a065f0326637bdd650f5760a5b88aae 100644 (file)
@@ -1009,7 +1009,7 @@ class Cache implements ICache {
         * @param ICache $sourceCache
         * @param ICacheEntry $sourceEntry
         * @param string $targetPath
-        * @return int fileid of copied entry
+        * @return int fileId of copied entry
         */
        public function copyFromCache(ICache $sourceCache, ICacheEntry $sourceEntry, string $targetPath): int {
                if ($sourceEntry->getId() < 0) {
index 4050daddb35a7d03cc5e4534503781db308e3aa3..adb3928b28ab4c1e1b49d1bfd5a913ccbb7987fb 100644 (file)
@@ -539,7 +539,15 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common {
                if ($sourceStorage->instanceOfStorage(ObjectStoreStorage::class)) {
                        /** @var ObjectStoreStorage $sourceStorage */
                        if ($sourceStorage->getObjectStore()->getStorageId() === $this->getObjectStore()->getStorageId()) {
+                               /** @var CacheEntry $sourceEntry */
                                $sourceEntry = $sourceStorage->getCache()->get($sourceInternalPath);
+                               $sourceEntryData = $sourceEntry->getData();
+                               // $sourceEntry['permissions'] here is the permissions from the jailed storage for the current
+                               // user. Instead we use $sourceEntryData['scan_permissions'] that are the permissions from the
+                               // unjailed storage.
+                               if (is_array($sourceEntryData) && array_key_exists('scan_permissions', $sourceEntryData)) {
+                                       $sourceEntry['permissions'] = $sourceEntryData['scan_permissions'];
+                               }
                                $this->copyInner($sourceEntry, $targetInternalPath);
                                return true;
                        }