diff --git a/apps/files/lib/Command/Scan.php b/apps/files/lib/Command/Scan.php index 6a8697a5eaf2e..62867afe46460 100644 --- a/apps/files/lib/Command/Scan.php +++ b/apps/files/lib/Command/Scan.php @@ -157,6 +157,7 @@ protected function scanFiles($user, $path, OutputInterface $output, $backgroundS } } catch (ForbiddenException $e) { $output->writeln("Home storage for user $user not writable"); + $output->writeln(' ' . $e->getMessage()); $output->writeln('Make sure you\'re running the scan command only as the user the web server runs as'); } catch (InterruptedException $e) { # exit the function if ctrl-c has been pressed diff --git a/lib/private/Files/Utils/Scanner.php b/lib/private/Files/Utils/Scanner.php index 72a7084f40d3f..377e138d5da4b 100644 --- a/lib/private/Files/Utils/Scanner.php +++ b/lib/private/Files/Utils/Scanner.php @@ -27,11 +27,13 @@ * along with this program. If not, see * */ + namespace OC\Files\Utils; use OC\Files\Cache\Cache; use OC\Files\Filesystem; use OC\Files\Storage\FailedStorage; +use OC\Files\Storage\Home; use OC\ForbiddenException; use OC\Hooks\PublicEmitter; use OC\Lock\DBLockingProvider; @@ -214,13 +216,23 @@ public function scan($dir = '', $recursive = \OC\Files\Cache\Scanner::SCAN_RECUR } // if the home storage isn't writable then the scanner is run as the wrong user - if ($storage->instanceOfStorage('\OC\Files\Storage\Home') and - (!$storage->isCreatable('') or !$storage->isCreatable('files')) - ) { - if ($storage->file_exists('') or $storage->getCache()->inCache('')) { - throw new ForbiddenException(); - } else {// if the root exists in neither the cache nor the storage the user isn't setup yet - break; + if ($storage->instanceOfStorage(Home::class)) { + /** @var Home $storage */ + foreach (['', 'files'] as $path) { + if (!$storage->isCreatable($path)) { + $fullPath = $storage->getSourcePath($path); + if (!$storage->file_exists($path) && $storage->getCache()->inCache($path)) { + throw new NotFoundException("User folder $fullPath exists in cache but not on disk"); + } elseif ($storage->file_exists($path) || $storage->getCache()->inCache($path)) { + $ownerUid = fileowner($fullPath); + $owner = posix_getpwuid($ownerUid); + $owner = $owner ? $owner['name'] : $ownerUid; + $permissions = decoct(fileperms($fullPath)); + throw new ForbiddenException("User folder $fullPath is not writable, folders is owned by $owner and has mode $permissions"); + } else {// if the root exists in neither the cache nor the storage the user isn't setup yet + break 2; + } + } } }