SMB.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. *
  5. * @author Daniel Kesselberg <mail@danielkesselberg.de>
  6. * @author Morris Jobke <hey@morrisjobke.de>
  7. * @author Robin Appelman <robin@icewind.nl>
  8. * @author Robin McCorkell <robin@mccorkell.me.uk>
  9. * @author Roeland Jago Douma <roeland@famdouma.nl>
  10. * @author Valdnet <47037905+Valdnet@users.noreply.github.com>
  11. *
  12. * @license AGPL-3.0
  13. *
  14. * This code is free software: you can redistribute it and/or modify
  15. * it under the terms of the GNU Affero General Public License, version 3,
  16. * as published by the Free Software Foundation.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU Affero General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU Affero General Public License, version 3,
  24. * along with this program. If not, see <http://www.gnu.org/licenses/>
  25. *
  26. */
  27. namespace OCA\Files_External\Lib\Backend;
  28. use Icewind\SMB\BasicAuth;
  29. use Icewind\SMB\KerberosApacheAuth;
  30. use Icewind\SMB\KerberosAuth;
  31. use OCA\Files_External\Lib\Auth\AuthMechanism;
  32. use OCA\Files_External\Lib\Auth\Password\Password;
  33. use OCA\Files_External\Lib\Auth\SMB\KerberosApacheAuth as KerberosApacheAuthMechanism;
  34. use OCA\Files_External\Lib\DefinitionParameter;
  35. use OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException;
  36. use OCA\Files_External\Lib\LegacyDependencyCheckPolyfill;
  37. use OCA\Files_External\Lib\StorageConfig;
  38. use OCP\IL10N;
  39. use OCP\IUser;
  40. class SMB extends Backend {
  41. use LegacyDependencyCheckPolyfill;
  42. public function __construct(IL10N $l, Password $legacyAuth) {
  43. $this
  44. ->setIdentifier('smb')
  45. ->addIdentifierAlias('\OC\Files\Storage\SMB')// legacy compat
  46. ->setStorageClass('\OCA\Files_External\Lib\Storage\SMB')
  47. ->setText($l->t('SMB/CIFS'))
  48. ->addParameters([
  49. new DefinitionParameter('host', $l->t('Host')),
  50. new DefinitionParameter('share', $l->t('Share')),
  51. (new DefinitionParameter('root', $l->t('Remote subfolder')))
  52. ->setFlag(DefinitionParameter::FLAG_OPTIONAL),
  53. (new DefinitionParameter('domain', $l->t('Domain')))
  54. ->setFlag(DefinitionParameter::FLAG_OPTIONAL),
  55. (new DefinitionParameter('show_hidden', $l->t('Show hidden files')))
  56. ->setType(DefinitionParameter::VALUE_BOOLEAN)
  57. ->setFlag(DefinitionParameter::FLAG_OPTIONAL),
  58. (new DefinitionParameter('check_acl', $l->t('Verify ACL access when listing files')))
  59. ->setType(DefinitionParameter::VALUE_BOOLEAN)
  60. ->setFlag(DefinitionParameter::FLAG_OPTIONAL)
  61. ->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")),
  62. (new DefinitionParameter('timeout', $l->t('Timeout')))
  63. ->setType(DefinitionParameter::VALUE_HIDDEN)
  64. ->setFlag(DefinitionParameter::FLAG_OPTIONAL),
  65. ])
  66. ->addAuthScheme(AuthMechanism::SCHEME_PASSWORD)
  67. ->addAuthScheme(AuthMechanism::SCHEME_SMB)
  68. ->setLegacyAuthMechanism($legacyAuth);
  69. }
  70. public function manipulateStorageConfig(StorageConfig &$storage, IUser $user = null) {
  71. $auth = $storage->getAuthMechanism();
  72. if ($auth->getScheme() === AuthMechanism::SCHEME_PASSWORD) {
  73. if (!is_string($storage->getBackendOption('user')) || !is_string($storage->getBackendOption('password'))) {
  74. throw new \InvalidArgumentException('user or password is not set');
  75. }
  76. $smbAuth = new BasicAuth(
  77. $storage->getBackendOption('user'),
  78. $storage->getBackendOption('domain'),
  79. $storage->getBackendOption('password')
  80. );
  81. } else {
  82. switch ($auth->getIdentifier()) {
  83. case 'smb::kerberos':
  84. $smbAuth = new KerberosAuth();
  85. break;
  86. case 'smb::kerberosapache':
  87. if (!$auth instanceof KerberosApacheAuthMechanism) {
  88. throw new \InvalidArgumentException('invalid authentication backend');
  89. }
  90. $credentialsStore = $auth->getCredentialsStore();
  91. $kerbAuth = new KerberosApacheAuth();
  92. // check if a kerberos ticket is available, else fallback to session credentials
  93. if ($kerbAuth->checkTicket()) {
  94. $smbAuth = $kerbAuth;
  95. } else {
  96. try {
  97. $credentials = $credentialsStore->getLoginCredentials();
  98. $user = $credentials->getLoginName();
  99. $pass = $credentials->getPassword();
  100. preg_match('/(.*)@(.*)/', $user, $matches);
  101. $realm = $storage->getBackendOption('default_realm');
  102. if (empty($realm)) {
  103. $realm = 'WORKGROUP';
  104. }
  105. if (count($matches) === 0) {
  106. $username = $user;
  107. $workgroup = $realm;
  108. } else {
  109. $username = $matches[1];
  110. $workgroup = $matches[2];
  111. }
  112. $smbAuth = new BasicAuth(
  113. $username,
  114. $workgroup,
  115. $pass
  116. );
  117. } catch (\Exception $e) {
  118. throw new InsufficientDataForMeaningfulAnswerException('No session credentials saved');
  119. }
  120. }
  121. break;
  122. default:
  123. throw new \InvalidArgumentException('unknown authentication backend');
  124. }
  125. }
  126. $storage->setBackendOption('auth', $smbAuth);
  127. }
  128. }