summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Mueller <thomas.mueller@tmit.eu>2013-02-13 11:18:59 +0100
committerThomas Mueller <thomas.mueller@tmit.eu>2013-02-13 11:18:59 +0100
commit2e65dc6cb03a17b77cb2ba5665599dc153535282 (patch)
tree098367fca5ecd3e38fc9a44852f40d79682b11bb
parent2e819d6edd0d8f14a8752f5de0a850a04131fa2d (diff)
downloadnextcloud-server-2e65dc6cb03a17b77cb2ba5665599dc153535282.tar.gz
nextcloud-server-2e65dc6cb03a17b77cb2ba5665599dc153535282.zip
backport of #1654, #1636 and https://github.com/owncloud/3rdparty/pull/12
-rw-r--r--3rdparty/smb4php/smb.php126
-rw-r--r--apps/files_external/lib/smb.php7
2 files changed, 75 insertions, 58 deletions
diff --git a/3rdparty/smb4php/smb.php b/3rdparty/smb4php/smb.php
index 6222563271a..2c2ae759531 100644
--- a/3rdparty/smb4php/smb.php
+++ b/3rdparty/smb4php/smb.php
@@ -29,7 +29,7 @@ define ('SMB4PHP_VERSION', '0.8');
define ('SMB4PHP_SMBCLIENT', 'smbclient');
define ('SMB4PHP_SMBOPTIONS', 'TCP_NODELAY IPTOS_LOWDELAY SO_KEEPALIVE SO_RCVBUF=8192 SO_SNDBUF=8192');
-define ('SMB4PHP_AUTHMODE', 'arg'); # set to 'env' to use USER enviroment variable
+define ('SMB4PHP_AUTHMODE', 'arg'); # set to 'env' to use USER environment variable
###################################################################
# SMB - commands that does not need an instance
@@ -41,16 +41,26 @@ class smb {
function parse_url ($url) {
$pu = parse_url (trim($url));
- foreach (array ('domain', 'user', 'pass', 'host', 'port', 'path') as $i)
- if (! isset($pu[$i])) $pu[$i] = '';
- if (count ($userdomain = explode (';', urldecode ($pu['user']))) > 1)
+ foreach (array ('domain', 'user', 'pass', 'host', 'port', 'path') as $i) {
+ if (! isset($pu[$i])) {
+ $pu[$i] = '';
+ }
+ }
+ if (count ($userdomain = explode (';', urldecode ($pu['user']))) > 1) {
@list ($pu['domain'], $pu['user']) = $userdomain;
+ }
$path = preg_replace (array ('/^\//', '/\/$/'), '', urldecode ($pu['path']));
list ($pu['share'], $pu['path']) = (preg_match ('/^([^\/]+)\/(.*)/', $path, $regs))
- ? array ($regs[1], preg_replace ('/\//', '\\', $regs[2]))
- : array ($path, '');
+ ? array ($regs[1], preg_replace ('/\//', '\\', $regs[2]))
+ : array ($path, '');
$pu['type'] = $pu['path'] ? 'path' : ($pu['share'] ? 'share' : ($pu['host'] ? 'host' : '**error**'));
- if (! ($pu['port'] = intval(@$pu['port']))) $pu['port'] = 139;
+ if (! ($pu['port'] = intval(@$pu['port']))) {
+ $pu['port'] = 139;
+ }
+
+ // decode user and password
+ $pu['user'] = urldecode($pu['user']);
+ $pu['pass'] = urldecode($pu['pass']);
return $pu;
}
@@ -62,43 +72,43 @@ class smb {
function execute ($command, $purl) {
return smb::client ('-d 0 '
- . escapeshellarg ('//' . $purl['host'] . '/' . $purl['share'])
- . ' -c ' . escapeshellarg ($command), $purl
+ . escapeshellarg ('//' . $purl['host'] . '/' . $purl['share'])
+ . ' -c ' . escapeshellarg ($command), $purl
);
}
function client ($params, $purl) {
static $regexp = array (
- '^added interface ip=(.*) bcast=(.*) nmask=(.*)$' => 'skip',
- 'Anonymous login successful' => 'skip',
- '^Domain=\[(.*)\] OS=\[(.*)\] Server=\[(.*)\]$' => 'skip',
- '^\tSharename[ ]+Type[ ]+Comment$' => 'shares',
- '^\t---------[ ]+----[ ]+-------$' => 'skip',
- '^\tServer [ ]+Comment$' => 'servers',
- '^\t---------[ ]+-------$' => 'skip',
- '^\tWorkgroup[ ]+Master$' => 'workg',
- '^\t(.*)[ ]+(Disk|IPC)[ ]+IPC.*$' => 'skip',
- '^\tIPC\\\$(.*)[ ]+IPC' => 'skip',
- '^\t(.*)[ ]+(Disk)[ ]+(.*)$' => 'share',
- '^\t(.*)[ ]+(Printer)[ ]+(.*)$' => 'skip',
- '([0-9]+) blocks of size ([0-9]+)\. ([0-9]+) blocks available' => 'skip',
- 'Got a positive name query response from ' => 'skip',
- '^(session setup failed): (.*)$' => 'error',
- '^(.*): ERRSRV - ERRbadpw' => 'error',
- '^Error returning browse list: (.*)$' => 'error',
- '^tree connect failed: (.*)$' => 'error',
- '^(Connection to .* failed)$' => 'error',
- '^NT_STATUS_(.*) ' => 'error',
- '^NT_STATUS_(.*)\$' => 'error',
- 'ERRDOS - ERRbadpath \((.*).\)' => 'error',
- 'cd (.*): (.*)$' => 'error',
- '^cd (.*): NT_STATUS_(.*)' => 'error',
- '^\t(.*)$' => 'srvorwg',
- '^([0-9]+)[ ]+([0-9]+)[ ]+(.*)$' => 'skip',
- '^Job ([0-9]+) cancelled' => 'skip',
- '^[ ]+(.*)[ ]+([0-9]+)[ ]+(Mon|Tue|Wed|Thu|Fri|Sat|Sun)[ ](Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[ ]+([0-9]+)[ ]+([0-9]{2}:[0-9]{2}:[0-9]{2})[ ]([0-9]{4})$' => 'files',
- '^message start: ERRSRV - (ERRmsgoff)' => 'error'
+ '^added interface ip=(.*) bcast=(.*) nmask=(.*)$' => 'skip',
+ 'Anonymous login successful' => 'skip',
+ '^Domain=\[(.*)\] OS=\[(.*)\] Server=\[(.*)\]$' => 'skip',
+ '^\tSharename[ ]+Type[ ]+Comment$' => 'shares',
+ '^\t---------[ ]+----[ ]+-------$' => 'skip',
+ '^\tServer [ ]+Comment$' => 'servers',
+ '^\t---------[ ]+-------$' => 'skip',
+ '^\tWorkgroup[ ]+Master$' => 'workg',
+ '^\t(.*)[ ]+(Disk|IPC)[ ]+IPC.*$' => 'skip',
+ '^\tIPC\\\$(.*)[ ]+IPC' => 'skip',
+ '^\t(.*)[ ]+(Disk)[ ]+(.*)$' => 'share',
+ '^\t(.*)[ ]+(Printer)[ ]+(.*)$' => 'skip',
+ '([0-9]+) blocks of size ([0-9]+)\. ([0-9]+) blocks available' => 'skip',
+ 'Got a positive name query response from ' => 'skip',
+ '^(session setup failed): (.*)$' => 'error',
+ '^(.*): ERRSRV - ERRbadpw' => 'error',
+ '^Error returning browse list: (.*)$' => 'error',
+ '^tree connect failed: (.*)$' => 'error',
+ '^(Connection to .* failed)$' => 'error',
+ '^NT_STATUS_(.*) ' => 'error',
+ '^NT_STATUS_(.*)\$' => 'error',
+ 'ERRDOS - ERRbadpath \((.*).\)' => 'error',
+ 'cd (.*): (.*)$' => 'error',
+ '^cd (.*): NT_STATUS_(.*)' => 'error',
+ '^\t(.*)$' => 'srvorwg',
+ '^([0-9]+)[ ]+([0-9]+)[ ]+(.*)$' => 'skip',
+ '^Job ([0-9]+) cancelled' => 'skip',
+ '^[ ]+(.*)[ ]+([0-9]+)[ ]+(Mon|Tue|Wed|Thu|Fri|Sat|Sun)[ ](Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[ ]+([0-9]+)[ ]+([0-9]{2}:[0-9]{2}:[0-9]{2})[ ]([0-9]{4})$' => 'files',
+ '^message start: ERRSRV - (ERRmsgoff)' => 'error'
);
if (SMB4PHP_AUTHMODE == 'env') {
@@ -119,6 +129,7 @@ class smb {
$output = popen (SMB4PHP_SMBCLIENT." -N {$auth} {$options} {$port} {$options} {$params} 2>/dev/null", 'r');
$info = array ();
$info['info']= array ();
+ $mode = '';
while ($line = fgets ($output, 4096)) {
list ($tag, $regs, $i) = array ('skip', array (), array ());
reset ($regexp);
@@ -152,7 +163,7 @@ class smb {
? array (trim ($regs2[2]), trim ($regs2[1]))
: array ('', trim ($regs[1]));
list ($his, $im) = array (
- explode(':', $regs[6]), 1 + strpos("JanFebMarAprMayJunJulAugSepOctNovDec", $regs[4]) / 3);
+ explode(':', $regs[6]), 1 + strpos("JanFebMarAprMayJunJulAugSepOctNovDec", $regs[4]) / 3);
$i = ($name <> '.' && $name <> '..')
? array (
$name,
@@ -185,13 +196,14 @@ class smb {
}
pclose($output);
+
// restore previous locale
if ($old_locale===false) {
putenv('LC_ALL');
} else {
putenv('LC_ALL='.$old_locale);
}
-
+
return $info;
}
@@ -199,26 +211,28 @@ class smb {
# stats
function url_stat ($url, $flags = STREAM_URL_STAT_LINK) {
- if ($s = smb::getstatcache($url)) { return $s; }
+ if ($s = smb::getstatcache($url)) {
+ return $s;
+ }
list ($stat, $pu) = array (array (), smb::parse_url ($url));
switch ($pu['type']) {
case 'host':
if ($o = smb::look ($pu))
- $stat = stat ("/tmp");
+ $stat = stat ("/tmp");
else
- trigger_error ("url_stat(): list failed for host '{$host}'", E_USER_WARNING);
+ trigger_error ("url_stat(): list failed for host '{$pu['host']}'", E_USER_WARNING);
break;
case 'share':
if ($o = smb::look ($pu)) {
- $found = FALSE;
- $lshare = strtolower ($pu['share']); # fix by Eric Leung
- foreach ($o['disk'] as $s) if ($lshare == strtolower($s)) {
- $found = TRUE;
- $stat = stat ("/tmp");
- break;
- }
- if (! $found)
- trigger_error ("url_stat(): disk resource '{$share}' not found in '{$host}'", E_USER_WARNING);
+ $found = FALSE;
+ $lshare = strtolower ($pu['share']); # fix by Eric Leung
+ foreach ($o['disk'] as $s) if ($lshare == strtolower($s)) {
+ $found = TRUE;
+ $stat = stat ("/tmp");
+ break;
+ }
+ if (! $found)
+ trigger_error ("url_stat(): disk resource '{$lshare}' not found in '{$pu['host']}'", E_USER_WARNING);
}
break;
case 'path':
@@ -414,15 +428,15 @@ class smb_stream_wrapper extends smb {
case 'rb':
case 'a':
case 'a+': $this->tmpfile = tempnam('/tmp', 'smb.down.');
- smb::execute ('get "'.$pu['path'].'" "'.$this->tmpfile.'"', $pu);
- break;
+ smb::execute ('get "'.$pu['path'].'" "'.$this->tmpfile.'"', $pu);
+ break;
case 'w':
case 'w+':
case 'wb':
case 'x':
case 'x+': $this->cleardircache();
- $this->tmpfile = tempnam('/tmp', 'smb.up.');
- $this->need_flush=true;
+ $this->tmpfile = tempnam('/tmp', 'smb.up.');
+ $this->need_flush=true;
}
$this->stream = fopen ($this->tmpfile, $mode);
return TRUE;
diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/smb.php
index a19ef3b3804..4f6bd1d4ce1 100644
--- a/apps/files_external/lib/smb.php
+++ b/apps/files_external/lib/smb.php
@@ -34,7 +34,7 @@ class OC_FileStorage_SMB extends OC_FileStorage_StreamWrapper{
$this->share=substr($this->share,0,-1);
}
- //create the root folder if necesary
+ //create the root folder if necessary
if(!$this->is_dir('')) {
$this->mkdir('');
}
@@ -44,7 +44,10 @@ class OC_FileStorage_SMB extends OC_FileStorage_StreamWrapper{
if(substr($path,-1)=='/') {
$path=substr($path,0,-1);
}
- return 'smb://'.$this->user.':'.$this->password.'@'.$this->host.$this->share.$this->root.$path;
+ $user = urlencode($this->user);
+ $password = urlencode($this->password);
+ $path = urlencode($path);
+ return 'smb://'.$user.':'.$password.'@'.$this->host.$this->share.$this->root.$path;
}
public function stat($path) {