forked from extern/egroupware
* Filemanager/WebDAV: generally deny user to delete directories /, /home, /apps, /templates (last 2 incl. subdirectories)
This commit is contained in:
parent
366a940030
commit
e7ff94a153
@ -708,23 +708,42 @@ class Vfs
|
||||
return $value > (int) substr($argument,1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if given directory is protected (user not allowed to remove or rename)
|
||||
*
|
||||
* Following directorys are protected:
|
||||
* - /
|
||||
* - /apps incl. subdirectories
|
||||
* - /home
|
||||
* - /templates incl. subdirectories
|
||||
*
|
||||
* @param string $dir path or url
|
||||
* @return boolean true for protected dirs, false otherwise
|
||||
*/
|
||||
static function isProtectedDir($dir)
|
||||
{
|
||||
if ($dir[0] != '/') $dir = self::parse_url($dir, PHP_URL_PATH);
|
||||
|
||||
return preg_match('#^/(apps(/[^/]+)?|home|templates(/[^/]+)?)?/*$#', $dir) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursiv remove all given url's, including it's content if they are files
|
||||
*
|
||||
* @param string|array $urls url or array of url's
|
||||
* @param boolean $allow_urls =false allow to use url's, default no only pathes (to stay within the vfs)
|
||||
* @throws Exception\AssertionFailed when trainig to remove /, /apps or /home
|
||||
* @throws Vfs\Exception\ProtectedDirectory if trying to delete a protected directory, see Vfs::isProtected()
|
||||
* @return array
|
||||
*/
|
||||
static function remove($urls,$allow_urls=false)
|
||||
{
|
||||
//error_log(__METHOD__.'('.array2string($urls).')');
|
||||
// some precaution to never allow to (recursivly) remove /, /apps or /home
|
||||
foreach((array)$urls as $url)
|
||||
{
|
||||
if (preg_match('/^\/?(home|apps|)\/*$/',self::parse_url($url,PHP_URL_PATH)))
|
||||
// some precaution to never allow to (recursivly) remove /, /apps or /home, see Vfs::isProtected()
|
||||
if (self::isProtectedDir($url))
|
||||
{
|
||||
throw new Exception\AssertionFailed(__METHOD__.'('.array2string($urls).") Cautiously rejecting to remove folder '$url'!");
|
||||
throw new Vfs\Exception\ProtectedDirectory("Deleting protected directory '$url' rejected!");
|
||||
}
|
||||
}
|
||||
return self::find($urls, array('depth'=>true,'url'=>$allow_urls,'hidden'=>true), __CLASS__.'::_rm_rmdir');
|
||||
|
21
api/src/Vfs/Exception/ProtectedDirectory.php
Normal file
21
api/src/Vfs/Exception/ProtectedDirectory.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* EGroupware API - Exceptions
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @package vfs
|
||||
* @subpackage exception
|
||||
* @access public
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
namespace EGroupware\Api\Vfs\Exception;
|
||||
|
||||
/**
|
||||
* User or code tried to delete or rename a protected directory, see Vfs::isProtectedDir
|
||||
*
|
||||
* This exception extends \Exception to not catch it accidently.
|
||||
*/
|
||||
class ProtectedDirectory extends \Exception { }
|
@ -571,9 +571,14 @@ class StreamWrapper implements StreamWrapperIface
|
||||
* @param string $path_from
|
||||
* @param string $path_to
|
||||
* @return boolean TRUE on success or FALSE on failure
|
||||
* @throws Exception\ProtectedDirectory if trying to delete a protected directory, see Vfs::isProtected()
|
||||
*/
|
||||
function rename ( $path_from, $path_to )
|
||||
{
|
||||
if (Vfs::isProtectedDir($path_from))
|
||||
{
|
||||
throw new Exception\ProtectedDirectory("Renaming protected directory '$path_from' rejected!");
|
||||
}
|
||||
if (!($url_from = $this->resolve_url_symlinks($path_from,true,false)) ||
|
||||
!($url_to = $this->resolve_url_symlinks($path_to,false)))
|
||||
{
|
||||
@ -665,9 +670,14 @@ class StreamWrapper implements StreamWrapperIface
|
||||
* @param string $path
|
||||
* @param int $options Possible values include STREAM_REPORT_ERRORS.
|
||||
* @return boolean TRUE on success or FALSE on failure.
|
||||
* @throws Exception\ProtectedDirectory if trying to delete a protected directory, see Vfs::isProtected()
|
||||
*/
|
||||
function rmdir ( $path, $options )
|
||||
{
|
||||
if (Vfs::isProtectedDir($path))
|
||||
{
|
||||
throw new Exception\ProtectedDirectory("Deleting protected directory '$path' rejected!");
|
||||
}
|
||||
unset($options); // not uses but required by function signature
|
||||
if (!($url = $this->resolve_url_symlinks($path)))
|
||||
{
|
||||
|
@ -95,7 +95,7 @@ class WebDAV extends HTTP_WebDAV_Server_Filesystem
|
||||
$ret = !empty($deleted[$options['path']]);
|
||||
//error_log(__METHOD__."() Vfs::remove($options[path]) returned ".array2string($deleted)." --> ".array2string($ret));
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
catch (Exception\ProtectedDirectory $e) {
|
||||
return '403 Forbidden: '.$e->getMessage();
|
||||
}
|
||||
}
|
||||
@ -221,9 +221,14 @@ class WebDAV extends HTTP_WebDAV_Server_Filesystem
|
||||
}
|
||||
|
||||
if ($del) {
|
||||
if (!rename($source, $dest)) {
|
||||
return "500 Internal server error";
|
||||
}
|
||||
try {
|
||||
if (!rename($source, $dest)) {
|
||||
return "500 Internal server error";
|
||||
}
|
||||
}
|
||||
catch (Exception\ProtectedDirectory $e) {
|
||||
return "403 Forbidden: ".$e->getMessage();
|
||||
}
|
||||
} else {
|
||||
if (is_dir($source) && $options['depth'] == 'infinity') {
|
||||
$files = Vfs::find($source,array('depth' => true,'url' => true)); // depth=true: return dirs first, url=true: allow urls!
|
||||
|
@ -732,7 +732,7 @@ class filemanager_ui
|
||||
// some precaution to never allow to (recursivly) remove /, /apps or /home
|
||||
foreach((array)$selected as $path)
|
||||
{
|
||||
if (preg_match('/^\/?(home|apps|)\/*$/',$path))
|
||||
if (Vfs::isProtectedDir($path))
|
||||
{
|
||||
$errs++;
|
||||
return lang("Cautiously rejecting to remove folder '%1'!",Vfs::decodePath($path));
|
||||
|
Loading…
Reference in New Issue
Block a user