Server: CopyRecursiveException when deleting file from shared folder

Created on 15 Nov 2017  路  10Comments  路  Source: nextcloud/server

Steps to reproduce

  1. Login with user-1, create a directory "share-1" and share it with user-2
  2. Login with user-2, open "share-1" and create a directory "share-2" within "share-1" and share it with user-3
  3. Login with user-3, open "share-2", upload a file "testfile.exe" within "share-2" and delete it afterwards

Expected behaviour

The file should get deleted smoothly.

Actual behaviour

  • An error notification gets displayed in the header: Error deleting file "testfile.exe"
  • The file "testfile.exe" is still displayed in the file list
  • After reloading the page the file is removed from the file list
  • Error in log: CopyRecursiveException (see full stacktrace below)

Further details

  • It doesn't make any difference if I use local users or LDAP/AD users.
  • The strange thing about this: I wasn't able to reproduce this error in a second nextCloud instance with a similar configuration. In this second nextCloud instance the deleted file is available after deletion in the trashbin of both users (user-1 and user-3). In the "problematic" nextCloud instance the deleted file is only available in the trashbin of user-1. I guess this error occurs when copying the file to the trashbin of user-3.
  • When I disable the app "Deleted files" the error doesn't occur.

General server configuration

Operating system: Ubuntu 16.04.3 LTS

Web server: Apache/2.4.18

Database: MySQL 5.7.20

PHP version: 7.0.22


PHP-modules loaded

 - Core
 - date
 - libxml
 - openssl
 - pcre
 - zlib
 - filter
 - hash
 - Reflection
 - SPL
 - session
 - standard
 - apache2handler
 - mysqlnd
 - PDO
 - xml
 - apcu
 - calendar
 - ctype
 - curl
 - dom
 - mbstring
 - fileinfo
 - ftp
 - gd
 - gettext
 - iconv
 - json
 - ldap
 - exif
 - mcrypt
 - mysqli
 - pdo_mysql
 - Phar
 - posix
 - readline
 - shmop
 - SimpleXML
 - sockets
 - sysvmsg
 - sysvsem
 - sysvshm
 - tokenizer
 - wddx
 - xmlreader
 - xmlwriter
 - xsl
 - zip
 - Zend OPcache

Nextcloud configuration

Nextcloud version: 12.0.3

Updated from an older Nextcloud/ownCloud or fresh install: Updated from v11.0.3

Are you using external storage, if yes which one: files_external is disabled

Are you using encryption: no

Are you using an external user-backend, if yes which one: LDAP/ActiveDirectory


Enabled apps

 - activity: 2.5.2
 - admin_audit: 1.2.0
 - bruteforcesettings: 1.0.2
 - calendar: 1.5.6
 - comments: 1.2.0
 - contacts: 2.0.1
 - dav: 1.3.0
 - federatedfilesharing: 1.2.0
 - files: 1.7.2
 - files_accesscontrol: 1.2.5
 - files_antivirus: 1.1.0
 - files_trashbin: 1.2.0
 - files_pdfviewer: 1.1.1
 - files_retention: 1.1.2
 - files_sharing: 1.4.0
 - files_texteditor: 2.4.1
 - files_versions: 1.5.0
 - files_videoplayer: 1.1.0
 - gallery: 17.0.0
 - issuetemplate: 0.2.2
 - logreader: 2.0.0
 - lookup_server_connector: 1.0.0
 - notifications: 2.0.0
 - oauth2: 1.0.5
 - password_policy: 1.2.2
 - provisioning_api: 1.2.0
 - serverinfo: 1.2.0
 - systemtags: 1.2.0
 - twofactor_backupcodes: 1.1.1
 - updatenotification: 1.2.0
 - user_ldap: 1.2.1
 - weemailtemplate: 0.0.1
 - workflowengine: 1.2.0


Disabled apps

 - encryption
 - federation
 - files_automatedtagging
 - files_external
 - firstrunwizard
 - nextcloud_announcements
 - sharebymail
 - survey_client
 - theming
 - user_external


Content of config/config.php

{
    "instanceid": "***REMOVED SENSITIVE VALUE***",
    "dbtype": "mysql",
    "dbname": "***REMOVED SENSITIVE VALUE***",
    "dbuser": "***REMOVED SENSITIVE VALUE***",
    "dbpassword": "***REMOVED SENSITIVE VALUE***",
    "dbhost": "localhost",
    "dbtableprefix": "oc_",
    "passwordsalt": "***REMOVED SENSITIVE VALUE***",
    "secret": "***REMOVED SENSITIVE VALUE***",
    "trusted_proxies": [
        "***REMOVED SENSITIVE VALUE***",
        "***REMOVED SENSITIVE VALUE***"
    ],
    "forwarded_for_headers": [
        "HTTP_X_FORWARDED_FOR"
    ],
    "trusted_domains": [
        "***REMOVED SENSITIVE VALUE***",
        "***REMOVED SENSITIVE VALUE***"
    ],
    "datadirectory": "***REMOVED SENSITIVE VALUE***",
    "overwriteprotocol": "https",
    "version": "12.0.3.3",
    "logtimezone": "***REMOVED SENSITIVE VALUE***",
    "installed": true,
    "theme": "***REMOVED SENSITIVE VALUE***",
    "ldapIgnoreNamingRules": false,
    "mail_smtpmode": "smtp",
    "mail_from_address": "***REMOVED SENSITIVE VALUE***",
    "mail_domain": "***REMOVED SENSITIVE VALUE***",
    "mail_smtphost": "***REMOVED SENSITIVE VALUE***",
    "mail_smtpport": "25",
    "loglevel": 1,
    "log_type": "owncloud",
    "log_rotate_size": 10485760,
    "log_authfailip": true,
    "updatechecker": true,
    "maintenance": false,
    "preview_libreoffice_path": "\/usr\/bin\/libreoffice",
    "default_language": "en",
    "appstore.experimental.enabled": false,
    "memcache.local": "\\OC\\Memcache\\APCu",
    "skeletondirectory": "",
    "ldapProviderFactory": "\\OCA\\User_LDAP\\LDAPProviderFactory",
    "appstoreenabled": true,
    "updater.release.channel": "stable",
    "singleuser": false,
    "mail_template_class": "***REMOVED SENSITIVE VALUE***",
    "htaccess.RewriteBase": "\/",
    "overwrite.cli.url": "***REMOVED SENSITIVE VALUE***",
    "lost_password_link": "disabled"
}

Client configuration

Browser: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0

Logs


Nextcloud log (data/nextcloud.log)

Fatal   webdav  OCA\Files_Trashbin\Exceptions\CopyRecursiveException: 

    /path/to/nextcloud/apps/files_trashbin/lib/Trashbin.php - line 188: OCA\Files_Trashbin\Trashbin copy_recursive('user-1/files_tra...', 'user-3/files_tra...', Object(OC\Files\View))
    /path/to/nextcloud/apps/files_trashbin/lib/Trashbin.php - line 284: OCA\Files_Trashbin\Trashbin copyFilesToUser('/share-1/share-2/...', 'user-1', 'share-2...', 'user-3', 1510735616)
    /path/to/nextcloud/apps/files_trashbin/lib/Storage.php - line 247: OCA\Files_Trashbin\Trashbin move2trash('share-2/...', false)
    /path/to/nextcloud/apps/files_trashbin/lib/Storage.php - line 163: OCA\Files_Trashbin\Storage->doDelete('testfile.exe', 'unlink')
    /path/to/nextcloud/lib/private/Files/View.php - line 1136: OCA\Files_Trashbin\Storage->unlink('testfile.exe')
    /path/to/nextcloud/lib/private/Files/View.php - line 701: OC\Files\View->basicOperation('unlink', '/share-2/...', Array)
    /path/to/nextcloud/apps/dav/lib/Connector/Sabre/File.php - line 344: OC\Files\View->unlink('/share-2/...')
    /path/to/nextcloud/3rdparty/sabre/dav/lib/DAV/Tree.php - line 179: OCA\DAV\Connector\Sabre\File->delete()
    /path/to/nextcloud/3rdparty/sabre/dav/lib/DAV/CorePlugin.php - line 287: Sabre\DAV\Tree->delete('share-2/...')
    [internal function] Sabre\DAV\CorePlugin->httpDelete(Object(Sabre\HTTP\Request), Object(Sabre\HTTP\Response))
    /path/to/nextcloud/3rdparty/sabre/event/lib/EventEmitterTrait.php - line 105: call_user_func_array(Array, Array)
    /path/to/nextcloud/3rdparty/sabre/dav/lib/DAV/Server.php - line 479: Sabre\Event\EventEmitter->emit('method DELETE', Array)
    /path/to/nextcloud/3rdparty/sabre/dav/lib/DAV/Server.php - line 254: Sabre\DAV\Server->invokeMethod(Object(Sabre\HTTP\Request), Object(Sabre\HTTP\Response))
    /path/to/nextcloud/apps/dav/appinfo/v1/webdav.php - line 76: Sabre\DAV\Server->exec()
    /path/to/nextcloud/remote.php - line 162: require_once('/path/to/nextc...')
    {main}

0. Needs triage bug filesystem sharing

Most helpful comment

Same here. The Problem with quota==0 is: if the file is shared and the user with quota==0 is not the owner, he is not allowed to get a _copy_, which is the case when Nextcloud deletes files: They get copied to the trash of the owner _and_ the one who deletes the file.
(Yes, if you delete files the content actually get multiplied; you can increase storage space of Nextcloud by deleting files!)

I've patched our Nextcloud sources as a workaround:

diff -rupN nextcloud-13.0.3.ori/apps/files_trashbin/lib/Storage.php nextcloud-13.0.3.delete_with_quota0/apps/files_trashbin/lib/Storage.php
--- nextcloud-13.0.3.ori/apps/files_trashbin/lib/Storage.php    2018-06-07 11:44:33.000000000 +0200
+++ nextcloud-13.0.3.delete_with_quota0/apps/files_trashbin/lib/Storage.php 2018-06-13 09:00:18.881584479 +0200
@@ -178,6 +178,8 @@ class Storage extends Wrapper {
            if (isset(self::$moveOutOfSharedFolder[$this->mountPoint . $path])) {
                $result = $this->doDelete($path, 'unlink', true);
                unset(self::$moveOutOfSharedFolder[$this->mountPoint . $path]);
+           } else if (\OC_Util::getUserQuota(\OCP\User::getUser()) == 0) {
+               $result = $this->doDelete($path, 'unlink', true);
            } else {
                $result = $this->doDelete($path, 'unlink');
            }

This way it moves the deleted files to the owners trash only and not also to the user with quota==0.
(Btw: It's some time ago we did these, I hadn't the time to post here back then; I don't know if it's still needed.)

All 10 comments

same Problem, same system here

cc @schiessle @nextcloud/sharing @icewind1991

I can reproduce it only on LDAP-Users. All of them have a 0 Byte Quota, because they should only work inside the shared Folders. Standard-Users can delete without error.

/var/www/vhosts/myInstall/httpdocs/apps/files_trashbin/lib/Trashbin.php - line 188: OCA\Files_Trashbin\Trashbin copy_recursive('intra/files_trash...', '1F75B60F-51BE-4...', Object(OC\Files\View))
/var/www/vhosts/myInstall/httpdocs/apps/files_trashbin/lib/Trashbin.php - line 284: OCA\Files_Trashbin\Trashbin copyFilesToUser('/INTRANET/R...', 'intra', '01 Finanzbuchha...', '1F75B60F-51BE-4...', 1510759092)
/var/www/vhosts/myInstall/httpdocs/apps/files_trashbin/lib/Storage.php - line 247: OCA\Files_Trashbin\Trashbin move2trash('01 Finanzbuchha...', false)
/var/www/vhosts/myInstall/httpdocs/apps/files_trashbin/lib/Storage.php - line 163: OCA\Files_Trashbin\Storage->doDelete('Testordner/intr...', 'unlink')
/var/www/vhosts/myInstall/httpdocs/lib/private/Files/View.php - line 1136: OCA\Files_Trashbin\Storage->unlink('Testordner/intr...')
/var/www/vhosts/myInstall/httpdocs/lib/private/Files/View.php - line 701: OC\Files\View->basicOperation('unlink', '/01 Finanzbuchh...', Array)
/var/www/vhosts/myInstall/httpdocs/apps/dav/lib/Connector/Sabre/File.php - line 344: OC\Files\View->unlink('/01 Finanzbuchh...')
/var/www/vhosts/myInstall/httpdocs/3rdparty/sabre/dav/lib/DAV/Tree.php - line 179: OCA\DAV\Connector\Sabre\File->delete()
/var/www/vhosts/myInstall/httpdocs/3rdparty/sabre/dav/lib/DAV/CorePlugin.php - line 287: Sabre\DAV\Tree->delete('01 Finanzbuchha...')
[internal function] Sabre\DAV\CorePlugin->httpDelete(Object(Sabre\HTTP\Request), Object(Sabre\HTTP\Response))
/var/www/vhosts/myInstall/httpdocs/3rdparty/sabre/event/lib/EventEmitterTrait.php - line 105: call_user_func_array(Array, Array)
/var/www/vhosts/myInstall/httpdocs/3rdparty/sabre/dav/lib/DAV/Server.php - line 479: Sabre\Event\EventEmitter->emit('method DELETE', Array)
/var/www/vhosts/myInstall/httpdocs/3rdparty/sabre/dav/lib/DAV/Server.php - line 254: Sabre\DAV\Server->invokeMethod(Object(Sabre\HTTP\Request), Object(Sabre\HTTP\Response))
/var/www/vhosts/myInstall/httpdocs/apps/dav/appinfo/v1/webdav.php - line 76: Sabre\DAV\Server->exec()
/var/www/vhosts/myInstall/httpdocs/remote.php - line 162: require_once('/var/www/vhosts...')
{main}

@skerbis: Thanks for the hint, I didn't mention that in my issue's description: we have a similar scenario. Our users have a 5 MB quota because they should also work mostly inside shared folders.

I just did a second test: the error only occurs if the filesize is greater than the quota of 5 MB. This is really strange, isn't it? Uploading and deleting files in a shared folder shouldn't affect the personal quota of a user, or I'm wrong?

I see the same log messages.

Nextcloud and LDAP-users work together in a shared folder.

The Nextcloud users should only work inside the shared folder, so the quota is set to 0 B.

Edit: The LDAP users have 2 GB and the user who shared the folder is a local user with 5 GB
Edit 2: Running NC12.0.5

OS: CentOS 7
NextCloud 12.0.5
PHP 5.6.33
MySQL 5.5.56

Same problem here.
Local User share folder to LDAP ( Microsoft AD) User with create, edit, delete rights.
LDAP User try to delete file, but got error: " Error deleting file "testfile.jpg", but file is deleted anyway and its not sent to deleted files.
LDAP User have 0 B quota. After setting quota to 50 MB ( larger than file i want to delete) file is deleted without error and sent to deleted files.

So i use set quota fix, but i want to limit user to use only shared folder so please fix this bug.

EDIT1: When you think a little bit, this behavior is logical.
If user have Quota 0 B, by default when you delete file, file is transferred to Trash bin.... so, for trash bin you need some space ( quota ).
But if user have 0 B quota, then file is deleted immediately so, there is nothing in Trash bin and we get that error.
So, fix for that error could be to check if Quota is 0 B, or Quota is lower then file that you want to delete, then don't show warning.
Or show confirmation dialog where should write something like " You don't have enough quota and files will be deleted permanently. Are you sure: Yes or No?

Alternative could be a only shared role

Same here. The Problem with quota==0 is: if the file is shared and the user with quota==0 is not the owner, he is not allowed to get a _copy_, which is the case when Nextcloud deletes files: They get copied to the trash of the owner _and_ the one who deletes the file.
(Yes, if you delete files the content actually get multiplied; you can increase storage space of Nextcloud by deleting files!)

I've patched our Nextcloud sources as a workaround:

diff -rupN nextcloud-13.0.3.ori/apps/files_trashbin/lib/Storage.php nextcloud-13.0.3.delete_with_quota0/apps/files_trashbin/lib/Storage.php
--- nextcloud-13.0.3.ori/apps/files_trashbin/lib/Storage.php    2018-06-07 11:44:33.000000000 +0200
+++ nextcloud-13.0.3.delete_with_quota0/apps/files_trashbin/lib/Storage.php 2018-06-13 09:00:18.881584479 +0200
@@ -178,6 +178,8 @@ class Storage extends Wrapper {
            if (isset(self::$moveOutOfSharedFolder[$this->mountPoint . $path])) {
                $result = $this->doDelete($path, 'unlink', true);
                unset(self::$moveOutOfSharedFolder[$this->mountPoint . $path]);
+           } else if (\OC_Util::getUserQuota(\OCP\User::getUser()) == 0) {
+               $result = $this->doDelete($path, 'unlink', true);
            } else {
                $result = $this->doDelete($path, 'unlink');
            }

This way it moves the deleted files to the owners trash only and not also to the user with quota==0.
(Btw: It's some time ago we did these, I hadn't the time to post here back then; I don't know if it's still needed.)

Does anyone know if this bug is still present in 14.0.4?

As I cannot reproduce the original issue anymore, I will close this ticket. If this is still happening please make sure to upgrade to the latest version. After that, feel free to reopen.

Was this page helpful?
0 / 5 - 0 ratings