Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add an occ command to scan files for legacy file key in use and get r…
…id of those

Signed-off-by: Côme Chilliet <[email protected]>
  • Loading branch information
come-nc committed May 4, 2023
commit 5663f9b31e78f9b1dcfb3de014e623209e1e0b3d
1 change: 1 addition & 0 deletions apps/encryption/appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Please read the documentation to know all implications before you decide to enab
<command>OCA\Encryption\Command\ScanLegacyFormat</command>
<command>OCA\Encryption\Command\FixEncryptedVersion</command>
<command>OCA\Encryption\Command\FixKeyLocation</command>
<command>OCA\Encryption\Command\FixLegacyFileKey</command>
</commands>

<settings>
Expand Down
61 changes: 31 additions & 30 deletions apps/encryption/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,35 @@
$baseDir = $vendorDir;

return array(
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
'OCA\\Encryption\\AppInfo\\Application' => $baseDir . '/../lib/AppInfo/Application.php',
'OCA\\Encryption\\Command\\DisableMasterKey' => $baseDir . '/../lib/Command/DisableMasterKey.php',
'OCA\\Encryption\\Command\\EnableMasterKey' => $baseDir . '/../lib/Command/EnableMasterKey.php',
'OCA\\Encryption\\Command\\FixEncryptedVersion' => $baseDir . '/../lib/Command/FixEncryptedVersion.php',
'OCA\\Encryption\\Command\\FixKeyLocation' => $baseDir . '/../lib/Command/FixKeyLocation.php',
'OCA\\Encryption\\Command\\RecoverUser' => $baseDir . '/../lib/Command/RecoverUser.php',
'OCA\\Encryption\\Command\\ScanLegacyFormat' => $baseDir . '/../lib/Command/ScanLegacyFormat.php',
'OCA\\Encryption\\Controller\\RecoveryController' => $baseDir . '/../lib/Controller/RecoveryController.php',
'OCA\\Encryption\\Controller\\SettingsController' => $baseDir . '/../lib/Controller/SettingsController.php',
'OCA\\Encryption\\Controller\\StatusController' => $baseDir . '/../lib/Controller/StatusController.php',
'OCA\\Encryption\\Crypto\\Crypt' => $baseDir . '/../lib/Crypto/Crypt.php',
'OCA\\Encryption\\Crypto\\DecryptAll' => $baseDir . '/../lib/Crypto/DecryptAll.php',
'OCA\\Encryption\\Crypto\\EncryptAll' => $baseDir . '/../lib/Crypto/EncryptAll.php',
'OCA\\Encryption\\Crypto\\Encryption' => $baseDir . '/../lib/Crypto/Encryption.php',
'OCA\\Encryption\\Exceptions\\MultiKeyDecryptException' => $baseDir . '/../lib/Exceptions/MultiKeyDecryptException.php',
'OCA\\Encryption\\Exceptions\\MultiKeyEncryptException' => $baseDir . '/../lib/Exceptions/MultiKeyEncryptException.php',
'OCA\\Encryption\\Exceptions\\PrivateKeyMissingException' => $baseDir . '/../lib/Exceptions/PrivateKeyMissingException.php',
'OCA\\Encryption\\Exceptions\\PublicKeyMissingException' => $baseDir . '/../lib/Exceptions/PublicKeyMissingException.php',
'OCA\\Encryption\\HookManager' => $baseDir . '/../lib/HookManager.php',
'OCA\\Encryption\\Hooks\\Contracts\\IHook' => $baseDir . '/../lib/Hooks/Contracts/IHook.php',
'OCA\\Encryption\\Hooks\\UserHooks' => $baseDir . '/../lib/Hooks/UserHooks.php',
'OCA\\Encryption\\KeyManager' => $baseDir . '/../lib/KeyManager.php',
'OCA\\Encryption\\Migration\\SetMasterKeyStatus' => $baseDir . '/../lib/Migration/SetMasterKeyStatus.php',
'OCA\\Encryption\\Recovery' => $baseDir . '/../lib/Recovery.php',
'OCA\\Encryption\\Session' => $baseDir . '/../lib/Session.php',
'OCA\\Encryption\\Settings\\Admin' => $baseDir . '/../lib/Settings/Admin.php',
'OCA\\Encryption\\Settings\\Personal' => $baseDir . '/../lib/Settings/Personal.php',
'OCA\\Encryption\\Users\\Setup' => $baseDir . '/../lib/Users/Setup.php',
'OCA\\Encryption\\Util' => $baseDir . '/../lib/Util.php',
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
'OCA\\Encryption\\AppInfo\\Application' => $baseDir . '/../lib/AppInfo/Application.php',
'OCA\\Encryption\\Command\\DisableMasterKey' => $baseDir . '/../lib/Command/DisableMasterKey.php',
'OCA\\Encryption\\Command\\EnableMasterKey' => $baseDir . '/../lib/Command/EnableMasterKey.php',
'OCA\\Encryption\\Command\\FixEncryptedVersion' => $baseDir . '/../lib/Command/FixEncryptedVersion.php',
'OCA\\Encryption\\Command\\FixKeyLocation' => $baseDir . '/../lib/Command/FixKeyLocation.php',
'OCA\\Encryption\\Command\\FixLegacyFileKey' => $baseDir . '/../lib/Command/FixLegacyFileKey.php',
'OCA\\Encryption\\Command\\RecoverUser' => $baseDir . '/../lib/Command/RecoverUser.php',
'OCA\\Encryption\\Command\\ScanLegacyFormat' => $baseDir . '/../lib/Command/ScanLegacyFormat.php',
'OCA\\Encryption\\Controller\\RecoveryController' => $baseDir . '/../lib/Controller/RecoveryController.php',
'OCA\\Encryption\\Controller\\SettingsController' => $baseDir . '/../lib/Controller/SettingsController.php',
'OCA\\Encryption\\Controller\\StatusController' => $baseDir . '/../lib/Controller/StatusController.php',
'OCA\\Encryption\\Crypto\\Crypt' => $baseDir . '/../lib/Crypto/Crypt.php',
'OCA\\Encryption\\Crypto\\DecryptAll' => $baseDir . '/../lib/Crypto/DecryptAll.php',
'OCA\\Encryption\\Crypto\\EncryptAll' => $baseDir . '/../lib/Crypto/EncryptAll.php',
'OCA\\Encryption\\Crypto\\Encryption' => $baseDir . '/../lib/Crypto/Encryption.php',
'OCA\\Encryption\\Exceptions\\MultiKeyDecryptException' => $baseDir . '/../lib/Exceptions/MultiKeyDecryptException.php',
'OCA\\Encryption\\Exceptions\\MultiKeyEncryptException' => $baseDir . '/../lib/Exceptions/MultiKeyEncryptException.php',
'OCA\\Encryption\\Exceptions\\PrivateKeyMissingException' => $baseDir . '/../lib/Exceptions/PrivateKeyMissingException.php',
'OCA\\Encryption\\Exceptions\\PublicKeyMissingException' => $baseDir . '/../lib/Exceptions/PublicKeyMissingException.php',
'OCA\\Encryption\\HookManager' => $baseDir . '/../lib/HookManager.php',
'OCA\\Encryption\\Hooks\\Contracts\\IHook' => $baseDir . '/../lib/Hooks/Contracts/IHook.php',
'OCA\\Encryption\\Hooks\\UserHooks' => $baseDir . '/../lib/Hooks/UserHooks.php',
'OCA\\Encryption\\KeyManager' => $baseDir . '/../lib/KeyManager.php',
'OCA\\Encryption\\Migration\\SetMasterKeyStatus' => $baseDir . '/../lib/Migration/SetMasterKeyStatus.php',
'OCA\\Encryption\\Recovery' => $baseDir . '/../lib/Recovery.php',
'OCA\\Encryption\\Session' => $baseDir . '/../lib/Session.php',
'OCA\\Encryption\\Settings\\Admin' => $baseDir . '/../lib/Settings/Admin.php',
'OCA\\Encryption\\Settings\\Personal' => $baseDir . '/../lib/Settings/Personal.php',
'OCA\\Encryption\\Users\\Setup' => $baseDir . '/../lib/Users/Setup.php',
'OCA\\Encryption\\Util' => $baseDir . '/../lib/Util.php',
);
108 changes: 53 additions & 55 deletions apps/encryption/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,62 +4,60 @@

namespace Composer\Autoload;

class ComposerStaticInitEncryption
{
public static $prefixLengthsPsr4 = array (
'O' =>
array (
'OCA\\Encryption\\' => 15,
),
);
class ComposerStaticInitEncryption {
public static $prefixLengthsPsr4 = array(
'O' =>
array(
'OCA\\Encryption\\' => 15,
),
);

public static $prefixDirsPsr4 = array (
'OCA\\Encryption\\' =>
array (
0 => __DIR__ . '/..' . '/../lib',
),
);
public static $prefixDirsPsr4 = array(
'OCA\\Encryption\\' =>
array(
0 => __DIR__ . '/..' . '/../lib',
),
);

public static $classMap = array (
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
'OCA\\Encryption\\AppInfo\\Application' => __DIR__ . '/..' . '/../lib/AppInfo/Application.php',
'OCA\\Encryption\\Command\\DisableMasterKey' => __DIR__ . '/..' . '/../lib/Command/DisableMasterKey.php',
'OCA\\Encryption\\Command\\EnableMasterKey' => __DIR__ . '/..' . '/../lib/Command/EnableMasterKey.php',
'OCA\\Encryption\\Command\\FixEncryptedVersion' => __DIR__ . '/..' . '/../lib/Command/FixEncryptedVersion.php',
'OCA\\Encryption\\Command\\FixKeyLocation' => __DIR__ . '/..' . '/../lib/Command/FixKeyLocation.php',
'OCA\\Encryption\\Command\\RecoverUser' => __DIR__ . '/..' . '/../lib/Command/RecoverUser.php',
'OCA\\Encryption\\Command\\ScanLegacyFormat' => __DIR__ . '/..' . '/../lib/Command/ScanLegacyFormat.php',
'OCA\\Encryption\\Controller\\RecoveryController' => __DIR__ . '/..' . '/../lib/Controller/RecoveryController.php',
'OCA\\Encryption\\Controller\\SettingsController' => __DIR__ . '/..' . '/../lib/Controller/SettingsController.php',
'OCA\\Encryption\\Controller\\StatusController' => __DIR__ . '/..' . '/../lib/Controller/StatusController.php',
'OCA\\Encryption\\Crypto\\Crypt' => __DIR__ . '/..' . '/../lib/Crypto/Crypt.php',
'OCA\\Encryption\\Crypto\\DecryptAll' => __DIR__ . '/..' . '/../lib/Crypto/DecryptAll.php',
'OCA\\Encryption\\Crypto\\EncryptAll' => __DIR__ . '/..' . '/../lib/Crypto/EncryptAll.php',
'OCA\\Encryption\\Crypto\\Encryption' => __DIR__ . '/..' . '/../lib/Crypto/Encryption.php',
'OCA\\Encryption\\Exceptions\\MultiKeyDecryptException' => __DIR__ . '/..' . '/../lib/Exceptions/MultiKeyDecryptException.php',
'OCA\\Encryption\\Exceptions\\MultiKeyEncryptException' => __DIR__ . '/..' . '/../lib/Exceptions/MultiKeyEncryptException.php',
'OCA\\Encryption\\Exceptions\\PrivateKeyMissingException' => __DIR__ . '/..' . '/../lib/Exceptions/PrivateKeyMissingException.php',
'OCA\\Encryption\\Exceptions\\PublicKeyMissingException' => __DIR__ . '/..' . '/../lib/Exceptions/PublicKeyMissingException.php',
'OCA\\Encryption\\HookManager' => __DIR__ . '/..' . '/../lib/HookManager.php',
'OCA\\Encryption\\Hooks\\Contracts\\IHook' => __DIR__ . '/..' . '/../lib/Hooks/Contracts/IHook.php',
'OCA\\Encryption\\Hooks\\UserHooks' => __DIR__ . '/..' . '/../lib/Hooks/UserHooks.php',
'OCA\\Encryption\\KeyManager' => __DIR__ . '/..' . '/../lib/KeyManager.php',
'OCA\\Encryption\\Migration\\SetMasterKeyStatus' => __DIR__ . '/..' . '/../lib/Migration/SetMasterKeyStatus.php',
'OCA\\Encryption\\Recovery' => __DIR__ . '/..' . '/../lib/Recovery.php',
'OCA\\Encryption\\Session' => __DIR__ . '/..' . '/../lib/Session.php',
'OCA\\Encryption\\Settings\\Admin' => __DIR__ . '/..' . '/../lib/Settings/Admin.php',
'OCA\\Encryption\\Settings\\Personal' => __DIR__ . '/..' . '/../lib/Settings/Personal.php',
'OCA\\Encryption\\Users\\Setup' => __DIR__ . '/..' . '/../lib/Users/Setup.php',
'OCA\\Encryption\\Util' => __DIR__ . '/..' . '/../lib/Util.php',
);
public static $classMap = array(
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
'OCA\\Encryption\\AppInfo\\Application' => __DIR__ . '/..' . '/../lib/AppInfo/Application.php',
'OCA\\Encryption\\Command\\DisableMasterKey' => __DIR__ . '/..' . '/../lib/Command/DisableMasterKey.php',
'OCA\\Encryption\\Command\\EnableMasterKey' => __DIR__ . '/..' . '/../lib/Command/EnableMasterKey.php',
'OCA\\Encryption\\Command\\FixEncryptedVersion' => __DIR__ . '/..' . '/../lib/Command/FixEncryptedVersion.php',
'OCA\\Encryption\\Command\\FixKeyLocation' => __DIR__ . '/..' . '/../lib/Command/FixKeyLocation.php',
'OCA\\Encryption\\Command\\FixLegacyFileKey' => __DIR__ . '/..' . '/../lib/Command/FixLegacyFileKey.php',
'OCA\\Encryption\\Command\\RecoverUser' => __DIR__ . '/..' . '/../lib/Command/RecoverUser.php',
'OCA\\Encryption\\Command\\ScanLegacyFormat' => __DIR__ . '/..' . '/../lib/Command/ScanLegacyFormat.php',
'OCA\\Encryption\\Controller\\RecoveryController' => __DIR__ . '/..' . '/../lib/Controller/RecoveryController.php',
'OCA\\Encryption\\Controller\\SettingsController' => __DIR__ . '/..' . '/../lib/Controller/SettingsController.php',
'OCA\\Encryption\\Controller\\StatusController' => __DIR__ . '/..' . '/../lib/Controller/StatusController.php',
'OCA\\Encryption\\Crypto\\Crypt' => __DIR__ . '/..' . '/../lib/Crypto/Crypt.php',
'OCA\\Encryption\\Crypto\\DecryptAll' => __DIR__ . '/..' . '/../lib/Crypto/DecryptAll.php',
'OCA\\Encryption\\Crypto\\EncryptAll' => __DIR__ . '/..' . '/../lib/Crypto/EncryptAll.php',
'OCA\\Encryption\\Crypto\\Encryption' => __DIR__ . '/..' . '/../lib/Crypto/Encryption.php',
'OCA\\Encryption\\Exceptions\\MultiKeyDecryptException' => __DIR__ . '/..' . '/../lib/Exceptions/MultiKeyDecryptException.php',
'OCA\\Encryption\\Exceptions\\MultiKeyEncryptException' => __DIR__ . '/..' . '/../lib/Exceptions/MultiKeyEncryptException.php',
'OCA\\Encryption\\Exceptions\\PrivateKeyMissingException' => __DIR__ . '/..' . '/../lib/Exceptions/PrivateKeyMissingException.php',
'OCA\\Encryption\\Exceptions\\PublicKeyMissingException' => __DIR__ . '/..' . '/../lib/Exceptions/PublicKeyMissingException.php',
'OCA\\Encryption\\HookManager' => __DIR__ . '/..' . '/../lib/HookManager.php',
'OCA\\Encryption\\Hooks\\Contracts\\IHook' => __DIR__ . '/..' . '/../lib/Hooks/Contracts/IHook.php',
'OCA\\Encryption\\Hooks\\UserHooks' => __DIR__ . '/..' . '/../lib/Hooks/UserHooks.php',
'OCA\\Encryption\\KeyManager' => __DIR__ . '/..' . '/../lib/KeyManager.php',
'OCA\\Encryption\\Migration\\SetMasterKeyStatus' => __DIR__ . '/..' . '/../lib/Migration/SetMasterKeyStatus.php',
'OCA\\Encryption\\Recovery' => __DIR__ . '/..' . '/../lib/Recovery.php',
'OCA\\Encryption\\Session' => __DIR__ . '/..' . '/../lib/Session.php',
'OCA\\Encryption\\Settings\\Admin' => __DIR__ . '/..' . '/../lib/Settings/Admin.php',
'OCA\\Encryption\\Settings\\Personal' => __DIR__ . '/..' . '/../lib/Settings/Personal.php',
'OCA\\Encryption\\Users\\Setup' => __DIR__ . '/..' . '/../lib/Users/Setup.php',
'OCA\\Encryption\\Util' => __DIR__ . '/..' . '/../lib/Util.php',
);

public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInitEncryption::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitEncryption::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitEncryption::$classMap;

}, null, ClassLoader::class);
}
public static function getInitializer(ClassLoader $loader) {
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInitEncryption::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitEncryption::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitEncryption::$classMap;
}, null, ClassLoader::class);
}
}
46 changes: 24 additions & 22 deletions apps/encryption/composer/composer/installed.php
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
<?php return array(
'root' => array(
'name' => '__root__',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => 'dd3d689e04a5e1d558da937ca72980e0e2c7c404',
'type' => 'library',
'install_path' => __DIR__ . '/../',
'aliases' => array(),
'dev' => false,
),
'versions' => array(
'__root__' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => 'dd3d689e04a5e1d558da937ca72980e0e2c7c404',
'type' => 'library',
'install_path' => __DIR__ . '/../',
'aliases' => array(),
'dev_requirement' => false,
),
),
<?php

return array(
'root' => array(
'name' => '__root__',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '527de8ac9d989baf30144e8f9bc0381226d4aee9',
'type' => 'library',
'install_path' => __DIR__ . '/../',
'aliases' => array(),
'dev' => false,
),
'versions' => array(
'__root__' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '527de8ac9d989baf30144e8f9bc0381226d4aee9',
'type' => 'library',
'install_path' => __DIR__ . '/../',
'aliases' => array(),
'dev_requirement' => false,
),
),
);
136 changes: 136 additions & 0 deletions apps/encryption/lib/Command/FixLegacyFileKey.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
<?php

declare(strict_types=1);

/**
* @copyright Copyright (c) 2023, Côme Chilliet <[email protected]>
*
* @author Côme Chilliet <[email protected]>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

namespace OCA\Encryption\Command;

use OC\Files\View;
use OCA\Encryption\KeyManager;
use OCP\Encryption\Exceptions\GenericEncryptionException;
use OCP\IUserManager;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class FixLegacyFileKey extends Command {
private View $rootView;

public function __construct(
private IUserManager $userManager,
private KeyManager $keyManager,
) {
parent::__construct();

$this->rootView = new View();
}

protected function configure(): void {
$this
->setName('encryption:fix-legacy-filekey')
->setDescription('Scan the files for the legacy filekey format using RC4 and get rid of it (if master key is enabled)');
}

protected function execute(InputInterface $input, OutputInterface $output): int {
$result = true;

$output->writeln('<info>Scanning all files for legacy filekey</info>');

foreach ($this->userManager->getBackends() as $backend) {
$limit = 500;
$offset = 0;
do {
$users = $backend->getUsers('', $limit, $offset);
foreach ($users as $user) {
$output->writeln('Scanning all files for ' . $user);
$this->setupUserFS($user);
$result = $result && $this->scanFolder($output, '/' . $user);
}
$offset += $limit;
} while (count($users) >= $limit);
}

if ($result) {
$output->writeln('All scanned files are properly encrypted. You can disable the legacy compatibility mode.');
return 0;
}

return 1;
}

private function scanFolder(OutputInterface $output, string $folder): bool {
$clean = true;

foreach ($this->rootView->getDirectoryContent($folder) as $item) {
$path = $folder . '/' . $item['name'];
if ($this->rootView->is_dir($path)) {
if ($this->scanFolder($output, $path) === false) {
$clean = false;
}
} else {
if (!$item->isEncrypted()) {
// ignore
continue;
}

$stats = $this->rootView->stat($path);
if (!isset($stats['hasHeader']) || $stats['hasHeader'] === false) {
$clean = false;
$output->writeln('<error>' . $path . ' does not have a proper header</error>');
} else {
try {
$legacyFileKey = $this->keyManager->getFileKey($path, null, true);
if ($legacyFileKey === '') {
$output->writeln('Got an empty legacy filekey for ' . $path . ', continuing', OutputInterface::VERBOSITY_VERBOSE);
continue;
}
} catch (GenericEncryptionException $e) {
$output->writeln('Got a decryption error for legacy filekey for ' . $path . ', continuing', OutputInterface::VERBOSITY_VERBOSE);
continue;
}
/* If that did not throw and filekey is not empty, a legacy filekey is used */
$clean = false;
$output->writeln($path . ' is using a legacy filekey, migrating');
$file = $this->rootView->fopen($path, 'w+');
if ($file) {
fwrite($file, '');
fclose($file);
} else {
$output->writeln('<error>failed to open' . $path . '</error>');
}
}
}
}

return $clean;
}

/**
* setup user file system
*/
protected function setupUserFS(string $uid): void {
\OC_Util::tearDownFS();
\OC_Util::setupFS($uid);
}
}
3 changes: 1 addition & 2 deletions apps/encryption/lib/Command/ScanLegacyFormat.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
use Symfony\Component\Console\Output\OutputInterface;

class ScanLegacyFormat extends Command {

/** @var Util */
protected $util;

Expand Down Expand Up @@ -89,7 +88,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
foreach ($users as $user) {
$output->writeln('Scanning all files for ' . $user);
$this->setupUserFS($user);
$result &= $this->scanFolder($output, '/' . $user);
$result = $result && $this->scanFolder($output, '/' . $user);
}
$offset += $limit;
} while (count($users) >= $limit);
Expand Down