Skip to content

Commit

Permalink
Add option to check share ACL's when listing directories
Browse files Browse the repository at this point in the history
If a file or folder in a directory doesn't have read permissions they
will not be shown

Note that enabling this option incurs a performance penalty additional
requests need to be made to get all the acl.

Additionally the acl resolving logic is fairly primitive at the moment
and might not work correctly in all setups (it should error to showing
the entry)

Signed-off-by: Robin Appelman <robin@icewind.nl>
  • Loading branch information
icewind1991 committed Apr 21, 2020
1 parent 8f650fe commit 23e2bae
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 0 deletions.
3 changes: 3 additions & 0 deletions apps/files_external/lib/Lib/Backend/SMB.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ public function __construct(IL10N $l, Password $legacyAuth) {
(new DefinitionParameter('show_hidden', $l->t('Show hidden files')))
->setType(DefinitionParameter::VALUE_BOOLEAN)
->setFlag(DefinitionParameter::FLAG_OPTIONAL),
(new DefinitionParameter('check_acl', $l->t('Verify ACL access when listing files')))
->setType(DefinitionParameter::VALUE_BOOLEAN)
->setFlag(DefinitionParameter::FLAG_OPTIONAL),
(new DefinitionParameter('timeout', $l->t('Timeout')))
->setType(DefinitionParameter::VALUE_HIDDEN)
->setFlag(DefinitionParameter::FLAG_OPTIONAL),
Expand Down
34 changes: 34 additions & 0 deletions apps/files_external/lib/Lib/Storage/SMB.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@

namespace OCA\Files_External\Lib\Storage;

use Icewind\SMB\ACL;
use Icewind\SMB\BasicAuth;
use Icewind\SMB\Exception\AlreadyExistsException;
use Icewind\SMB\Exception\ConnectException;
Expand Down Expand Up @@ -90,6 +91,9 @@ class SMB extends Common implements INotifyStorage {
/** @var bool */
protected $showHidden;

/** @var bool */
protected $checkAcl;

public function __construct($params) {
if (!isset($params['host'])) {
throw new \Exception('Invalid configuration, no host provided');
Expand Down Expand Up @@ -126,6 +130,7 @@ public function __construct($params) {
$this->root = rtrim($this->root, '/') . '/';

$this->showHidden = isset($params['show_hidden']) && $params['show_hidden'];
$this->checkAcl = isset($params['check_acl']) && $params['check_acl'];

$this->statCache = new CappedMemoryCache();
parent::__construct($params);
Expand Down Expand Up @@ -202,6 +207,24 @@ protected function throwUnavailable(\Exception $e) {
throw new StorageAuthException($e->getMessage(), $e);
}

/**
* get the acl from fileinfo that is relevant for the configured user
*
* @param IFileInfo $file
* @return ACL|null
*/
private function getACL(IFileInfo $file): ?ACL {
$acls = $file->getAcls();
foreach ($acls as $user => $acl) {
[, $user] = explode('\\', $user); // strip domain
if ($user === $this->server->getAuth()->getUsername()) {
return $acl;
}
}

return null;
}

/**
* @param string $path
* @return \Icewind\SMB\IFileInfo[]
Expand All @@ -220,6 +243,17 @@ protected function getFolderContents($path): iterable {
// the isHidden check is done before checking the config boolean to ensure that the metadata is always fetch
// so we trigger the below exceptions where applicable
$hide = $file->isHidden() && !$this->showHidden;

if ($this->checkAcl && $acl = $this->getACL($file)) {
// if there is no explicit deny, we assume it's allowed
// this doesn't take inheritance fully into account but if read permissions is denied for a parent we wouldn't be in this folder
// additionally, it's better to have false negatives here then false positives
if ($acl->denies(ACL::MASK_READ) || $acl->denies(ACL::MASK_EXECUTE)) {
$this->logger->debug('Hiding non readable entry ' . $file->getName());
return false;
}
}

if ($hide) {
$this->logger->debug('hiding hidden file ' . $file->getName());
}
Expand Down

0 comments on commit 23e2bae

Please sign in to comment.