SMB.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-only
  6. */
  7. namespace OCA\Files_External\Lib\Backend;
  8. use Icewind\SMB\BasicAuth;
  9. use Icewind\SMB\KerberosApacheAuth;
  10. use Icewind\SMB\KerberosAuth;
  11. use OCA\Files_External\Lib\Auth\AuthMechanism;
  12. use OCA\Files_External\Lib\Auth\Password\Password;
  13. use OCA\Files_External\Lib\Auth\SMB\KerberosApacheAuth as KerberosApacheAuthMechanism;
  14. use OCA\Files_External\Lib\DefinitionParameter;
  15. use OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException;
  16. use OCA\Files_External\Lib\LegacyDependencyCheckPolyfill;
  17. use OCA\Files_External\Lib\StorageConfig;
  18. use OCP\IL10N;
  19. use OCP\IUser;
  20. class SMB extends Backend {
  21. use LegacyDependencyCheckPolyfill;
  22. public function __construct(IL10N $l, Password $legacyAuth) {
  23. $this
  24. ->setIdentifier('smb')
  25. ->addIdentifierAlias('\OC\Files\Storage\SMB')// legacy compat
  26. ->setStorageClass('\OCA\Files_External\Lib\Storage\SMB')
  27. ->setText($l->t('SMB/CIFS'))
  28. ->addParameters([
  29. new DefinitionParameter('host', $l->t('Host')),
  30. new DefinitionParameter('share', $l->t('Share')),
  31. (new DefinitionParameter('root', $l->t('Remote subfolder')))
  32. ->setFlag(DefinitionParameter::FLAG_OPTIONAL),
  33. (new DefinitionParameter('domain', $l->t('Domain')))
  34. ->setFlag(DefinitionParameter::FLAG_OPTIONAL),
  35. (new DefinitionParameter('show_hidden', $l->t('Show hidden files')))
  36. ->setType(DefinitionParameter::VALUE_BOOLEAN)
  37. ->setFlag(DefinitionParameter::FLAG_OPTIONAL),
  38. (new DefinitionParameter('case_sensitive', $l->t('Case sensitive file system')))
  39. ->setType(DefinitionParameter::VALUE_BOOLEAN)
  40. ->setFlag(DefinitionParameter::FLAG_OPTIONAL)
  41. ->setDefaultValue(true)
  42. ->setTooltip($l->t('Disabling it will allow to use a case insensitive file system, but comes with a performance penalty')),
  43. (new DefinitionParameter('check_acl', $l->t('Verify ACL access when listing files')))
  44. ->setType(DefinitionParameter::VALUE_BOOLEAN)
  45. ->setFlag(DefinitionParameter::FLAG_OPTIONAL)
  46. ->setTooltip($l->t("Check the ACL's of each file or folder inside a directory to filter out items where the account has no read permissions, comes with a performance penalty")),
  47. (new DefinitionParameter('timeout', $l->t('Timeout')))
  48. ->setType(DefinitionParameter::VALUE_HIDDEN)
  49. ->setFlag(DefinitionParameter::FLAG_OPTIONAL),
  50. ])
  51. ->addAuthScheme(AuthMechanism::SCHEME_PASSWORD)
  52. ->addAuthScheme(AuthMechanism::SCHEME_SMB)
  53. ->setLegacyAuthMechanism($legacyAuth);
  54. }
  55. /**
  56. * @return void
  57. */
  58. public function manipulateStorageConfig(StorageConfig &$storage, ?IUser $user = null) {
  59. $auth = $storage->getAuthMechanism();
  60. if ($auth->getScheme() === AuthMechanism::SCHEME_PASSWORD) {
  61. if (!is_string($storage->getBackendOption('user')) || !is_string($storage->getBackendOption('password'))) {
  62. throw new \InvalidArgumentException('user or password is not set');
  63. }
  64. $smbAuth = new BasicAuth(
  65. $storage->getBackendOption('user'),
  66. $storage->getBackendOption('domain'),
  67. $storage->getBackendOption('password')
  68. );
  69. } else {
  70. switch ($auth->getIdentifier()) {
  71. case 'smb::kerberos':
  72. $smbAuth = new KerberosAuth();
  73. break;
  74. case 'smb::kerberosapache':
  75. if (!$auth instanceof KerberosApacheAuthMechanism) {
  76. throw new \InvalidArgumentException('invalid authentication backend');
  77. }
  78. $credentialsStore = $auth->getCredentialsStore();
  79. $kerbAuth = new KerberosApacheAuth();
  80. // check if a kerberos ticket is available, else fallback to session credentials
  81. if ($kerbAuth->checkTicket()) {
  82. $smbAuth = $kerbAuth;
  83. } else {
  84. try {
  85. $credentials = $credentialsStore->getLoginCredentials();
  86. $user = $credentials->getLoginName();
  87. $pass = $credentials->getPassword();
  88. preg_match('/(.*)@(.*)/', $user, $matches);
  89. $realm = $storage->getBackendOption('default_realm');
  90. if (empty($realm)) {
  91. $realm = 'WORKGROUP';
  92. }
  93. if (count($matches) === 0) {
  94. $username = $user;
  95. $workgroup = $realm;
  96. } else {
  97. $username = $matches[1];
  98. $workgroup = $matches[2];
  99. }
  100. $smbAuth = new BasicAuth(
  101. $username,
  102. $workgroup,
  103. $pass
  104. );
  105. } catch (\Exception $e) {
  106. throw new InsufficientDataForMeaningfulAnswerException('No session credentials saved');
  107. }
  108. }
  109. break;
  110. default:
  111. throw new \InvalidArgumentException('unknown authentication backend');
  112. }
  113. }
  114. $storage->setBackendOption('auth', $smbAuth);
  115. }
  116. }