diff --git a/apps/files_external/3rdparty/smb4php/smb.php b/apps/files_external/3rdparty/smb4php/smb.php index 656930514f..e325506fa1 100644 --- a/apps/files_external/3rdparty/smb4php/smb.php +++ b/apps/files_external/3rdparty/smb4php/smb.php @@ -8,6 +8,8 @@ # Homepage: http://www.phpclasses.org/smb4php # # Copyright (c) 2007 Victor M. Varela +# Copyright (c) 2012 Frank Karlitschek +# Copyright (c) 2014 Robin McCorkell # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -19,8 +21,6 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # -# Addition 17/12/2012 Frank Karlitschek (frank@owncloud.org) -# Addition 17/03/2014 Robin McCorkell (rmccorkell@karoshi.org.uk) # On the official website http://www.phpclasses.org/smb4php the # license is listed as LGPL so we assume that this is # dual-licensed GPL/LGPL @@ -44,6 +44,42 @@ $GLOBALS['__smb_cache'] = array ('stat' => array (), 'dir' => array ()); class smb { + private 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-connect', + '^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' + ); + + function getRegexp() { + return self::$regexp; + } + function parse_url ($url) { $pu = parse_url (trim($url)); foreach (array ('domain', 'user', 'pass', 'host', 'port', 'path') as $i) { @@ -75,46 +111,16 @@ class smb { } - function execute ($command, $purl) { + function execute ($command, $purl, $regexp = NULL) { return smb::client ('-d 0 ' . escapeshellarg ('//' . $purl['host'] . '/' . $purl['share']) - . ' -c ' . escapeshellarg ($command), $purl + . ' -c ' . escapeshellarg ($command), $purl, $regexp ); } - function client ($params, $purl) { + function client ($params, $purl, $regexp = NULL) { - 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-connect', - '^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 ($regexp === NULL) $regexp = smb::$regexp; if (SMB4PHP_AUTHMODE == 'env') { putenv("USER={$purl['user']}%{$purl['pass']}"); diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index af37a05cae..043265d898 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -319,7 +319,7 @@ class OC_Mount_Config { 'backend' => $backends[$mount['class']]['backend'], 'options' => $mount['options'], 'applicable' => array('groups' => array($group), 'users' => array()), - 'status' => self::getBackendStatus($mount['class'], $mount['options']) + 'status' => self::getBackendStatus($mount['class'], $mount['options'], false) ); $hash = self::makeConfigHash($config); // If an existing config exists (with same class, mountpoint and options) @@ -349,7 +349,7 @@ class OC_Mount_Config { 'backend' => $backends[$mount['class']]['backend'], 'options' => $mount['options'], 'applicable' => array('groups' => array(), 'users' => array($user)), - 'status' => self::getBackendStatus($mount['class'], $mount['options']) + 'status' => self::getBackendStatus($mount['class'], $mount['options'], true) ); $hash = self::makeConfigHash($config); // If an existing config exists (with same class, mountpoint and options) @@ -389,7 +389,7 @@ class OC_Mount_Config { 'mountpoint' => substr($mountPoint, strlen($uid) + 8), 'backend' => $backends[$mount['class']]['backend'], 'options' => $mount['options'], - 'status' => self::getBackendStatus($mount['class'], $mount['options']) + 'status' => self::getBackendStatus($mount['class'], $mount['options'], true) ); } } @@ -402,7 +402,7 @@ class OC_Mount_Config { * @param array $options backend configuration options * @return bool true if the connection succeeded, false otherwise */ - private static function getBackendStatus($class, $options) { + private static function getBackendStatus($class, $options, $isPersonal) { if (self::$skipTest) { return true; } @@ -412,7 +412,7 @@ class OC_Mount_Config { if (class_exists($class)) { try { $storage = new $class($options); - return $storage->test(); + return $storage->test($isPersonal); } catch (Exception $exception) { \OCP\Util::logException('files_external', $exception); return false; @@ -479,7 +479,7 @@ class OC_Mount_Config { $mountPoints[$mountType] = $mount; } self::writeData($isPersonal, $mountPoints); - return self::getBackendStatus($class, $classOptions); + return self::getBackendStatus($class, $classOptions, $isPersonal); } /** diff --git a/apps/files_external/lib/smb_oc.php b/apps/files_external/lib/smb_oc.php index a62a2c0153..ac325cd4fb 100644 --- a/apps/files_external/lib/smb_oc.php +++ b/apps/files_external/lib/smb_oc.php @@ -8,11 +8,15 @@ namespace OC\Files\Storage; +require_once __DIR__ . '/../3rdparty/smb4php/smb.php'; + class SMB_OC extends \OC\Files\Storage\SMB { + private $username_as_share; + public function __construct($params) { if (isset($params['host']) && \OC::$session->exists('smb-credentials')) { $host=$params['host']; - $username_as_share = ($params['username_as_share'] === 'true'); + $this->username_as_share = ($params['username_as_share'] === 'true'); $params_auth = \OC::$session->get('smb-credentials'); $user = \OC::$session->get('loginname'); @@ -21,7 +25,7 @@ class SMB_OC extends \OC\Files\Storage\SMB { $root=isset($params['root'])?$params['root']:'/'; $share = ''; - if ($username_as_share) { + if ($this->username_as_share) { $share = '/'.$user; } elseif (isset($params['share'])) { $share = $params['share']; @@ -47,4 +51,39 @@ class SMB_OC extends \OC\Files\Storage\SMB { public function isSharable($path) { return false; } + + public function test($isPersonal = true) { + if ($isPersonal) { + if ($this->stat('')) + return true; + return false; + } else { + $smb = new \smb(); + $pu = $smb->parse_url($this->constructUrl('')); + + // Attempt to connect anonymously + $pu['user'] = ''; + $pu['pass'] = ''; + + // Share cannot be checked if dynamic + if ($this->username_as_share) { + if ($smb->look($pu)) + return true; + else + return false; + } + if (!$pu['share']) + return false; + + // The following error messages are expected due to anonymous login + $regexp = array( + '(NT_STATUS_ACCESS_DENIED)' => 'skip' + ) + $smb->getRegexp(); + + if ($smb->client("-d 0 " . escapeshellarg('//' . $pu['host'] . '/' . $pu['share']) . " -c exit", $pu, $regexp)) + return true; + else + return false; + } + } }