summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorRobin McCorkell <rmccorkell@karoshi.org.uk>2014-03-26 11:04:13 +0000
committerRobin McCorkell <rmccorkell@karoshi.org.uk>2014-03-26 14:36:45 +0000
commitb077528087fba76add6913563b4c8221ca99aa3f (patch)
tree7b27b4407c1abef80a269e9eb45f48ab3ece0157 /apps
parentcac4aaa8c4dab1b59ab3ba3f155439473ae28250 (diff)
downloadnextcloud-server-b077528087fba76add6913563b4c8221ca99aa3f.tar.gz
nextcloud-server-b077528087fba76add6913563b4c8221ca99aa3f.zip
Perform proper checking for share availability
To check for shares, the code attempts to connect anonymously to the share. In most cases this will fail with NT_STATUS_ACCESS_DENIED, so the regex array used for parsing the output of smbclient in smb4php has been overridden to treat such output as success. The 'test' method for storage classes can now take a single parameter, $isPersonal, which allows the storage to adjust the tests performed based on if they are being configured as personal shares or as system shares.
Diffstat (limited to 'apps')
-rw-r--r--apps/files_external/3rdparty/smb4php/smb.php80
-rwxr-xr-xapps/files_external/lib/config.php12
-rw-r--r--apps/files_external/lib/smb_oc.php43
3 files changed, 90 insertions, 45 deletions
diff --git a/apps/files_external/3rdparty/smb4php/smb.php b/apps/files_external/3rdparty/smb4php/smb.php
index 656930514f0..e325506fa14 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 <vmvarela@gmail.com>
+# Copyright (c) 2012 Frank Karlitschek <frank@owncloud.org>
+# Copyright (c) 2014 Robin McCorkell <rmccorkell@karoshi.org.uk>
#
# 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) {
-
- 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 client ($params, $purl, $regexp = NULL) {
+
+ 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 af37a05cae0..043265d8982 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 a62a2c01533..ac325cd4fbc 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;
+ }
+ }
}