-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
new SMB storage backend #4770
Closed
Closed
new SMB storage backend #4770
Changes from all commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
bc276ae
new smb storage backend
icewind1991 a85d38d
Merge branch 'master' into smb
icewind1991 aad2304
smb: fix stat behaviour
icewind1991 a77119f
disable external storage tests
icewind1991 37f4c55
merge master into smb
icewind1991 88e5712
add smb wrapper to 3rdparty
icewind1991 a73d058
smb: fix share mtime
icewind1991 8a8110b
use ===
icewind1991 1db7e7b
fix accidental comment
icewind1991 1770fdc
fixing typo
DeepDiver1975 5141028
merge master into smb
icewind1991 5c4eb85
Merge branch 'master' into smb
icewind1991 5812a5b
Update SMB streamwrapper
icewind1991 8631534
Fix rename not returning a result, unlink not working on folders and …
icewind1991 bd781d7
Merge branch 'smb' of github.com:owncloud/core into smb
icewind1991 8079a9c
check if the file exists for isReadable and isUpdatable
icewind1991 a2764ab
Merge branch 'master' into smb
icewind1991 be3a5c6
Merge branch 'master' into smb
icewind1991 d7f160c
Merge branch 'master' into smb
icewind1991 6beee91
merge 3rdparty submodule
icewind1991 d515aa2
merge master into smb
icewind1991 d7fdbc8
Merge branch 'master' into smb
icewind1991 538961f
Fix parsing smb dir result
icewind1991 a674726
Merge branch 'master' into smb
icewind1991 80f4e68
update smb library
icewind1991 48e8e8a
merge master into smb
icewind1991 8cd05d7
merge master into smb
icewind1991 5baec0f
use PSR style autoloading for smb
icewind1991 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
86 changes: 86 additions & 0 deletions
86
apps/files_external/3rdparty/smb/Icewind/SMB/Connection.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
<?php | ||
/** | ||
* Copyright (c) 2013 Robin Appelman <[email protected]> | ||
* This file is licensed under the Affero General Public License version 3 or | ||
* later. | ||
* See the COPYING-README file. | ||
*/ | ||
|
||
namespace Icewind\SMB; | ||
|
||
class Connection extends RawConnection { | ||
const DELIMITER = 'smb:'; | ||
|
||
/** | ||
* send input to smbclient | ||
* | ||
* @param string $input | ||
*/ | ||
public function write($input) { | ||
parent::write($input . PHP_EOL); | ||
} | ||
|
||
/** | ||
* get all unprocessed output from smbclient until the next prompt | ||
* | ||
* @throws ConnectionError | ||
* @return string | ||
*/ | ||
public function read() { | ||
if (!$this->isValid()) { | ||
throw new ConnectionError(); | ||
} | ||
$line = $this->readLine(); //first line is prompt | ||
$this->checkConnectionError($line); | ||
|
||
$output = array(); | ||
$line = $this->readLine(); | ||
$length = strlen(self::DELIMITER); | ||
while (substr($line, 0, $length) !== self::DELIMITER) { //next prompt functions as delimiter | ||
$output[] .= $line; | ||
$line = parent::read(); | ||
} | ||
return $output; | ||
} | ||
|
||
/** | ||
* read a single line of unprocessed output | ||
* | ||
* @return string | ||
*/ | ||
public function readLine() { | ||
return parent::read(); | ||
} | ||
|
||
/** | ||
* check if the first line holds a connection failure | ||
* | ||
* @param $line | ||
* @throws AuthenticationException | ||
* @throws InvalidHostException | ||
*/ | ||
private function checkConnectionError($line) { | ||
$line = rtrim($line, ')'); | ||
if (substr($line, -23) === ErrorCodes::LogonFailure) { | ||
throw new AuthenticationException(); | ||
} | ||
if (substr($line, -26) === ErrorCodes::BadHostName) { | ||
throw new InvalidHostException(); | ||
} | ||
if (substr($line, -22) === ErrorCodes::Unsuccessful) { | ||
throw new InvalidHostException(); | ||
} | ||
if (substr($line, -28) === ErrorCodes::ConnectionRefused) { | ||
throw new InvalidHostException(); | ||
} | ||
} | ||
|
||
public function close() { | ||
$this->write('close' . PHP_EOL); | ||
} | ||
|
||
public function __destruct() { | ||
$this->close(); | ||
parent::__destruct(); | ||
} | ||
} |
52 changes: 52 additions & 0 deletions
52
apps/files_external/3rdparty/smb/Icewind/SMB/ErrorCodes.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
<?php | ||
/** | ||
* Copyright (c) 2012 Robin Appelman <[email protected]> | ||
* This file is licensed under the Affero General Public License version 3 or | ||
* later. | ||
* See the COPYING-README file. | ||
*/ | ||
|
||
namespace Icewind\SMB; | ||
|
||
class NotFoundException extends \Exception { | ||
} | ||
|
||
class AlreadyExistsException extends \Exception { | ||
} | ||
|
||
class NotEmptyException extends \Exception { | ||
} | ||
|
||
class ConnectionError extends \Exception { | ||
} | ||
|
||
class AuthenticationException extends \Exception { | ||
} | ||
|
||
class InvalidHostException extends \Exception { | ||
} | ||
|
||
class AccessDeniedException extends \Exception { | ||
} | ||
|
||
class InvalidTypeException extends \Exception { | ||
} | ||
|
||
class ErrorCodes { | ||
/** | ||
* connection errors | ||
*/ | ||
const LogonFailure = 'NT_STATUS_LOGON_FAILURE'; | ||
const BadHostName = 'NT_STATUS_BAD_NETWORK_NAME'; | ||
const Unsuccessful = 'NT_STATUS_UNSUCCESSFUL'; | ||
const ConnectionRefused = 'NT_STATUS_CONNECTION_REFUSED'; | ||
|
||
const PathNotFound = 'NT_STATUS_OBJECT_PATH_NOT_FOUND'; | ||
const NoSuchFile = 'NT_STATUS_NO_SUCH_FILE'; | ||
const ObjectNotFound = 'NT_STATUS_OBJECT_NAME_NOT_FOUND'; | ||
const NameCollision = 'NT_STATUS_OBJECT_NAME_COLLISION'; | ||
const AccessDenied = 'NT_STATUS_ACCESS_DENIED'; | ||
const DirectoryNotEmpty = 'NT_STATUS_DIRECTORY_NOT_EMPTY'; | ||
const FileIsADirectory = 'NT_STATUS_FILE_IS_A_DIRECTORY'; | ||
const NotADirectory = 'NT_STATUS_NOT_A_DIRECTORY'; | ||
} |
92 changes: 92 additions & 0 deletions
92
apps/files_external/3rdparty/smb/Icewind/SMB/RawConnection.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
<?php | ||
/** | ||
* Copyright (c) 2013 Robin Appelman <[email protected]> | ||
* This file is licensed under the Affero General Public License version 3 or | ||
* later. | ||
* See the COPYING-README file. | ||
*/ | ||
|
||
namespace Icewind\SMB; | ||
|
||
class RawConnection { | ||
/** | ||
* @var resource[] $pipes | ||
* | ||
* $pipes[0] holds STDIN for smbclient | ||
* $pipes[1] holds STDOUT for smbclient | ||
*/ | ||
private $pipes; | ||
|
||
/** | ||
* @var resource $process | ||
*/ | ||
private $process; | ||
|
||
|
||
public function __construct($command) { | ||
$descriptorSpec = array( | ||
0 => array("pipe", "r"), | ||
1 => array("pipe", "w"), | ||
2 => array('file', '/dev/null', 'w') | ||
); | ||
setlocale(LC_ALL, Server::LOCALE); | ||
$this->process = proc_open($command, $descriptorSpec, $this->pipes, null, array( | ||
'CLI_FORCE_INTERACTIVE' => 'y', // Needed or the prompt isn't displayed!! | ||
'LC_ALL' => Server::LOCALE | ||
)); | ||
if (!$this->isValid()) { | ||
throw new ConnectionError(); | ||
} | ||
} | ||
|
||
/** | ||
* check if the connection is still active | ||
* | ||
* @return bool | ||
*/ | ||
public function isValid() { | ||
if (is_resource($this->process)) { | ||
$status = proc_get_status($this->process); | ||
return $status['running']; | ||
} else { | ||
return false; | ||
} | ||
} | ||
|
||
/** | ||
* send input to the process | ||
* | ||
* @param string $input | ||
*/ | ||
public function write($input) { | ||
fwrite($this->pipes[0], $input); | ||
fflush($this->pipes[0]); | ||
} | ||
|
||
/** | ||
* read a line of output | ||
* | ||
* @return string | ||
*/ | ||
public function read() { | ||
return trim(fgets($this->pipes[1])); | ||
} | ||
|
||
/** | ||
* get all output until the process closes | ||
* | ||
* @return array | ||
*/ | ||
public function readAll() { | ||
$output = array(); | ||
while ($line = $this->read()) { | ||
$output[] = $line; | ||
} | ||
return $output; | ||
} | ||
|
||
public function __destruct() { | ||
proc_terminate($this->process); | ||
proc_close($this->process); | ||
} | ||
} |
134 changes: 134 additions & 0 deletions
134
apps/files_external/3rdparty/smb/Icewind/SMB/Server.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
<?php | ||
/** | ||
* Copyright (c) 2013 Robin Appelman <[email protected]> | ||
* This file is licensed under the Affero General Public License version 3 or | ||
* later. | ||
* See the COPYING-README file. | ||
*/ | ||
|
||
namespace Icewind\SMB; | ||
|
||
class Server { | ||
const CLIENT = 'smbclient'; | ||
const LOCALE = 'en_US.UTF-8'; | ||
|
||
/** | ||
* @var string $host | ||
*/ | ||
private $host; | ||
|
||
/** | ||
* @var string $user | ||
*/ | ||
private $user; | ||
|
||
/** | ||
* @var string $password | ||
*/ | ||
private $password; | ||
|
||
/** | ||
* @param string $host | ||
* @param string $user | ||
* @param string $password | ||
*/ | ||
public function __construct($host, $user, $password) { | ||
$this->host = $host; | ||
$this->user = $user; | ||
$this->password = $password; | ||
} | ||
|
||
/** | ||
* @return string | ||
*/ | ||
public function getAuthString() { | ||
return $this->user . '%' . $this->password; | ||
} | ||
|
||
/** | ||
* @return string | ||
*/ | ||
public function getUser() { | ||
return $this->user; | ||
} | ||
|
||
/** | ||
* @return string | ||
*/ | ||
public function getPassword() { | ||
return $this->password; | ||
} | ||
|
||
/** | ||
* return string | ||
*/ | ||
public function getHost() { | ||
return $this->host; | ||
} | ||
|
||
/** | ||
* @return Share[] | ||
* @throws \Icewind\SMB\AuthenticationException | ||
* @throws \Icewind\SMB\InvalidHostException | ||
*/ | ||
public function listShares() { | ||
$user = escapeshellarg($this->getUser()); | ||
$command = self::CLIENT . ' -U ' . $user . ' ' . '-gL ' . escapeshellarg($this->getHost()); | ||
$connection = new RawConnection($command); | ||
$connection->write($this->getPassword() . PHP_EOL); | ||
$output = $connection->readAll(); | ||
|
||
$line = $output[0]; | ||
|
||
// disregard password prompt | ||
if (substr($line, 0, 6) == 'Enter ' and count($output) > 1) { | ||
$line = $output[1]; | ||
} | ||
|
||
$line = rtrim($line, ')'); | ||
if (substr($line, -23) === ErrorCodes::LogonFailure) { | ||
throw new AuthenticationException(); | ||
} | ||
if (substr($line, -26) === ErrorCodes::BadHostName) { | ||
throw new InvalidHostException(); | ||
} | ||
if (substr($line, -22) === ErrorCodes::Unsuccessful) { | ||
throw new InvalidHostException(); | ||
} | ||
if (substr($line, -28) === ErrorCodes::ConnectionRefused) { | ||
throw new InvalidHostException(); | ||
} | ||
|
||
$shareNames = array(); | ||
foreach ($output as $line) { | ||
if (strpos($line, '|')) { | ||
list($type, $name, $description) = explode('|', $line); | ||
if (strtolower($type) === 'disk') { | ||
$shareNames[$name] = $description; | ||
} | ||
} | ||
} | ||
|
||
$shares = array(); | ||
foreach ($shareNames as $name => $description) { | ||
$shares[] = $this->getShare($name); | ||
} | ||
return $shares; | ||
} | ||
|
||
/** | ||
* @param string $name | ||
* @return Share | ||
*/ | ||
public function getShare($name) { | ||
return new Share($this, $name); | ||
} | ||
|
||
/** | ||
* @return string | ||
*/ | ||
public function getTimeZone() { | ||
$command = 'net time zone -S ' . escapeshellarg($this->getHost()); | ||
return exec($command); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. trim() on binary data?