diff options
author | blizzz <blizzz@arthur-schiwon.de> | 2020-04-23 00:16:12 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-23 00:16:12 +0300 |
commit | 4a8871f5f2bdf1d7085d3980693d06a7a877172a (patch) | |
tree | b4bdf61ee4e2d203bc8622c58845f1ee4174412f | |
parent | 8c5bb22bc1152696e78d662c458a4d03d20de350 (diff) | |
parent | 7f32fe6d506474943ca9be0ad23c84a6fe3c35b0 (diff) |
Merge pull request #19399 from nextcloud/smb-read-acl
Add option to check share ACL's when listing directories
-rw-r--r-- | apps/files_external/lib/Lib/Backend/SMB.php | 4 | ||||
-rw-r--r-- | apps/files_external/lib/Lib/Storage/SMB.php | 34 |
2 files changed, 38 insertions, 0 deletions
diff --git a/apps/files_external/lib/Lib/Backend/SMB.php b/apps/files_external/lib/Lib/Backend/SMB.php index eefeb137bf8..5344bf5f78c 100644 --- a/apps/files_external/lib/Lib/Backend/SMB.php +++ b/apps/files_external/lib/Lib/Backend/SMB.php @@ -56,6 +56,10 @@ class SMB extends Backend { (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) + ->setTooltip($l->t("Check the ACL's of each file or folder inside a directory to filter out items where the user has no read permissions, comes with a performance penalty")), (new DefinitionParameter('timeout', $l->t('Timeout'))) ->setType(DefinitionParameter::VALUE_HIDDEN) ->setFlag(DefinitionParameter::FLAG_OPTIONAL), diff --git a/apps/files_external/lib/Lib/Storage/SMB.php b/apps/files_external/lib/Lib/Storage/SMB.php index 3ff8179c7b4..ce37d556129 100644 --- a/apps/files_external/lib/Lib/Storage/SMB.php +++ b/apps/files_external/lib/Lib/Storage/SMB.php @@ -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; @@ -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'); @@ -126,6 +130,7 @@ class SMB extends Common implements INotifyStorage { $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); @@ -203,6 +208,24 @@ class SMB extends Common implements INotifyStorage { } /** + * 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[] * @throws StorageNotAvailableException @@ -220,6 +243,17 @@ class SMB extends Common implements INotifyStorage { // 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()); } |