diff --git a/apps/files_external/lib/Lib/Backend/SMB.php b/apps/files_external/lib/Lib/Backend/SMB.php index bf73c5b40f844..6c87967608876 100644 --- a/apps/files_external/lib/Lib/Backend/SMB.php +++ b/apps/files_external/lib/Lib/Backend/SMB.php @@ -59,6 +59,11 @@ 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('case_sensitive', $l->t('Case sensitive file system'))) + ->setType(DefinitionParameter::VALUE_BOOLEAN) + ->setFlag(DefinitionParameter::FLAG_OPTIONAL) + ->setDefaultValue(true) + ->setTooltip($l->t('Disabling it will allow to use a case insentive file system, but comes with a performance penalty')), (new DefinitionParameter('check_acl', $l->t('Verify ACL access when listing files'))) ->setType(DefinitionParameter::VALUE_BOOLEAN) ->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 c3ccc106239cf..2c0a412d341e8 100644 --- a/apps/files_external/lib/Lib/Storage/SMB.php +++ b/apps/files_external/lib/Lib/Storage/SMB.php @@ -93,6 +93,8 @@ class SMB extends Common implements INotifyStorage { /** @var bool */ protected $showHidden; + private bool $caseSensitive; + /** @var bool */ protected $checkAcl; @@ -139,6 +141,7 @@ public function __construct($params) { $this->root = rtrim($this->root, '/') . '/'; $this->showHidden = isset($params['show_hidden']) && $params['show_hidden']; + $this->caseSensitive = (bool) ($params['case_sensitive'] ?? true); $this->checkAcl = isset($params['check_acl']) && $params['check_acl']; $this->statCache = new CappedMemoryCache(); @@ -325,6 +328,12 @@ public function rename($source, $target, $retry = true): bool { if ($this->isRootDir($source) || $this->isRootDir($target)) { return false; } + if ($this->caseSensitive === false + && mb_strtolower($target) === mb_strtolower($source) + ) { + // Forbid changing case only on case-insensitive file system + return false; + } $absoluteSource = $this->buildPath($source); $absoluteTarget = $this->buildPath($target); @@ -674,6 +683,16 @@ public function mkdir($path) { public function file_exists($path) { try { + if ($this->caseSensitive === false) { + $filename = basename($path); + $siblings = $this->getDirectoryContent(dirname($this->buildPath($path))); + foreach ($siblings as $sibling) { + if ($sibling['name'] === $filename) { + return true; + } + } + return false; + } $this->getFileInfo($path); return true; } catch (\OCP\Files\NotFoundException $e) {