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
73dbaa0dfb
commit
f1f8c4e98d
@ -723,23 +723,42 @@ class Vfs
|
|||||||
return $value > (int) substr($argument,1);
|
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
|
* 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 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)
|
* @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
|
* @return array
|
||||||
*/
|
*/
|
||||||
static function remove($urls,$allow_urls=false)
|
static function remove($urls,$allow_urls=false)
|
||||||
{
|
{
|
||||||
//error_log(__METHOD__.'('.array2string($urls).')');
|
//error_log(__METHOD__.'('.array2string($urls).')');
|
||||||
// some precaution to never allow to (recursivly) remove /, /apps or /home
|
|
||||||
foreach((array)$urls as $url)
|
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');
|
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_from
|
||||||
* @param string $path_to
|
* @param string $path_to
|
||||||
* @return boolean TRUE on success or FALSE on failure
|
* @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 )
|
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)) ||
|
if (!($url_from = $this->resolve_url_symlinks($path_from,true,false)) ||
|
||||||
!($url_to = $this->resolve_url_symlinks($path_to,false)))
|
!($url_to = $this->resolve_url_symlinks($path_to,false)))
|
||||||
{
|
{
|
||||||
@ -665,9 +670,14 @@ class StreamWrapper implements StreamWrapperIface
|
|||||||
* @param string $path
|
* @param string $path
|
||||||
* @param int $options Possible values include STREAM_REPORT_ERRORS.
|
* @param int $options Possible values include STREAM_REPORT_ERRORS.
|
||||||
* @return boolean TRUE on success or FALSE on failure.
|
* @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 )
|
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
|
unset($options); // not uses but required by function signature
|
||||||
if (!($url = $this->resolve_url_symlinks($path)))
|
if (!($url = $this->resolve_url_symlinks($path)))
|
||||||
{
|
{
|
||||||
|
@ -95,7 +95,7 @@ class WebDAV extends HTTP_WebDAV_Server_Filesystem
|
|||||||
$ret = !empty($deleted[$options['path']]);
|
$ret = !empty($deleted[$options['path']]);
|
||||||
//error_log(__METHOD__."() Vfs::remove($options[path]) returned ".array2string($deleted)." --> ".array2string($ret));
|
//error_log(__METHOD__."() Vfs::remove($options[path]) returned ".array2string($deleted)." --> ".array2string($ret));
|
||||||
}
|
}
|
||||||
catch (\Exception $e) {
|
catch (Exception\ProtectedDirectory $e) {
|
||||||
return '403 Forbidden: '.$e->getMessage();
|
return '403 Forbidden: '.$e->getMessage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -221,9 +221,14 @@ class WebDAV extends HTTP_WebDAV_Server_Filesystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($del) {
|
if ($del) {
|
||||||
if (!rename($source, $dest)) {
|
try {
|
||||||
return "500 Internal server error";
|
if (!rename($source, $dest)) {
|
||||||
}
|
return "500 Internal server error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception\ProtectedDirectory $e) {
|
||||||
|
return "403 Forbidden: ".$e->getMessage();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (is_dir($source) && $options['depth'] == 'infinity') {
|
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!
|
$files = Vfs::find($source,array('depth' => true,'url' => true)); // depth=true: return dirs first, url=true: allow urls!
|
||||||
|
@ -751,7 +751,7 @@ class filemanager_ui
|
|||||||
// some precaution to never allow to (recursivly) remove /, /apps or /home
|
// some precaution to never allow to (recursivly) remove /, /apps or /home
|
||||||
foreach((array)$selected as $path)
|
foreach((array)$selected as $path)
|
||||||
{
|
{
|
||||||
if (preg_match('/^\/?(home|apps|)\/*$/',$path))
|
if (Vfs::isProtectedDir($path))
|
||||||
{
|
{
|
||||||
$errs++;
|
$errs++;
|
||||||
return lang("Cautiously rejecting to remove folder '%1'!",Vfs::decodePath($path));
|
return lang("Cautiously rejecting to remove folder '%1'!",Vfs::decodePath($path));
|
||||||
|
Loading…
Reference in New Issue
Block a user