diff --git a/phpgwapi/inc/class.egw_sharing.inc.php b/phpgwapi/inc/class.egw_sharing.inc.php index e07a236637..81a243efcb 100644 --- a/phpgwapi/inc/class.egw_sharing.inc.php +++ b/phpgwapi/inc/class.egw_sharing.inc.php @@ -126,10 +126,22 @@ class egw_sharing /** * Create sharing session * - * @param boolean $keep_session =false false: create a new session, true: try mounting it into existing (already verified) session + * Certain cases: + * a) there is not session $keep_session === null + * --> create new anon session with just filemanager rights and share as fstab + * b) there is a session $keep_session === true + * b1) current user is share owner (eg. checking the link) + * --> mount share under token additionally + * b2) current user not share owner + * b2a) need/use filemanager UI (eg. directory) + * --> destroy current session and continue with a) + * b2b) single file or WebDAV + * --> modify EGroupware enviroment for that request only, no change in session + * + * @param boolean $keep_session =null null: create a new session, true: try mounting it into existing (already verified) session * @return string with sessionid, does NOT return if no session created */ - public static function create_session($keep_session=false) + public static function create_session($keep_session=null) { self::$db = $GLOBALS['egw']->db; @@ -191,39 +203,14 @@ class egw_sharing { $share['share_root'] = '/'.$share['share_token']; - // if current user is not the share owner, we need to give him access to mounted share + // if current user is not the share owner, we cant just mount share if (egw_vfs::$user != $share['share_owner']) { - // check if sharing user has owner rights for shared path - egw_vfs::$user = $share['share_owner']; - egw_vfs::clearstatcache(); - if (egw_vfs::has_owner_rights($share['share_path'])) - { - $rights = $share['share_writable'] && egw_vfs::is_writable($share['share_path']) ? 7 : 5; - egw_vfs::$user = $GLOBALS['egw']->session->account_id; - egw_vfs::eacl($share['share_root'], $rights, egw_vfs::$user, true); // true = session-only, not permanent - } - // if not, we must not use an eacl, as it grants recursive rights! - // (one could eg. create a writable share for / and use it to escalate his own rights) - // --> create a new session with propper rights (loosing current session) - else - { - $keep_session = false; - } + $keep_session = false; } } if (!$keep_session) // do NOT change to else, as we might have set $keep_session=false! { - // create session without checking auth: create(..., false, false) - if (!($sessionid = $GLOBALS['egw']->session->create('anonymous', '', 'text', false, false))) - { - sleep(1); - $status = '500 Internal Server Error'; - header("HTTP/1.1 $status"); - header("X-WebDAV-Status: $status", true); - echo "Failed to create session: ".$GLOBALS['egw']->session->reason."\n"; - common::egw_exit(); - } // only allow filemanager app $GLOBALS['egw_info']['user']['apps'] = array( 'filemanager' => $GLOBALS['egw_info']['apps']['filemanager'] @@ -260,8 +247,34 @@ class egw_sharing // store sharing object in egw object and therefore in session $GLOBALS['egw']->sharing = new egw_sharing($share); - // for an existing session we need to store modified egw and egw_info again in session - if ($keep_session) + // we have a session we want to keep, but share owner is different from current user and we need filemanager UI, or no session + // --> create a new anon session + if ($keep_session === false && $GLOBALS['egw']->sharing->use_filemanager() || is_null($keep_session)) + { + // create session without checking auth: create(..., false, false) + if (!($sessionid = $GLOBALS['egw']->session->create('anonymous', '', 'text', false, false))) + { + sleep(1); + $status = '500 Internal Server Error'; + header("HTTP/1.1 $status"); + header("X-WebDAV-Status: $status", true); + echo "Failed to create session: ".$GLOBALS['egw']->session->reason."\n"; + common::egw_exit(); + } + // only allow filemanager app (gets overwritten by session::create) + $GLOBALS['egw_info']['user']['apps'] = array( + 'filemanager' => $GLOBALS['egw_info']['apps']['filemanager'] + ); + } + // we have a session we want to keep, but share owner is different from current user and we dont need filemanager UI + // --> we dont need session and close it, to not modifiy it + elseif ($keep_session === false) + { + $GLOBALS['egw']->session->commit_session(); + } + + // update modified egw and egw_info again in session, if neccessary + if ($keep_session || $sessionid) { $_SESSION[egw_session::EGW_INFO_CACHE] = $GLOBALS['egw_info']; unset($_SESSION[egw_session::EGW_INFO_CACHE]['flags']); // dont save the flags, they change on each request @@ -272,6 +285,22 @@ class egw_sharing return $sessionid; } + /** + * Check if we use filemanager UI + * + * Only for directories, if browser supports it and filemanager is installed + * + * @return boolean + */ + public function use_filemanager() + { + return !(!egw_vfs::is_dir($this->share['share_root']) || $_SERVER['REQUEST_METHOD'] != 'GET' || + // or unsupported browsers like ie < 10 + html::$user_agent == 'msie' && html::$ua_version < 10.0 || + // or if no filemanager installed (WebDAV has own autoindex) + !file_exists(__DIR__.'/../../filemanager/inc/class.filemanager_ui.inc.php')); + } + /** * Server a request on a share specified in REQUEST_URI */ @@ -285,11 +314,7 @@ class egw_sharing return $GLOBALS['egw']->sharing->ServeRequest(); } // use pure WebDAV for everything but GET requests to directories - if (!egw_vfs::is_dir($this->share['share_root']) || $_SERVER['REQUEST_METHOD'] != 'GET' || - // or unsupported browsers like ie < 10 - html::$user_agent == 'msie' && html::$ua_version < 10.0 || - // or if no filemanager installed (WebDAV has own autoindex) - !file_exists(__DIR__.'/../../filemanager/inc/class.filemanager_ui.inc.php')) + if (!$this->use_filemanager()) { // send a content-disposition header, so browser knows how to name downloaded file if (!egw_vfs::is_dir($this->share['share_root'])) diff --git a/phpgwapi/inc/class.sqlfs_stream_wrapper.inc.php b/phpgwapi/inc/class.sqlfs_stream_wrapper.inc.php index a0d0f8ad2b..6b83baa41a 100644 --- a/phpgwapi/inc/class.sqlfs_stream_wrapper.inc.php +++ b/phpgwapi/inc/class.sqlfs_stream_wrapper.inc.php @@ -548,7 +548,11 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper $path = egw_vfs::parse_url($url,PHP_URL_PATH); - if (!($stat = self::url_stat($path,STREAM_URL_STAT_LINK)) || !egw_vfs::check_access(egw_vfs::dirname($path),egw_vfs::WRITABLE, $parent_stat)) + // need to get parent stat from Sqlfs, not Vfs + if (!isset($parent_stat)) $parent_stat = static::url_stat(egw_vfs::dirname($path), STREAM_URL_STAT_LINK); + + if (!$parent_stat || !($stat = self::url_stat($path,STREAM_URL_STAT_LINK)) || + !egw_vfs::check_access(egw_vfs::dirname($path), egw_vfs::WRITABLE, $parent_stat)) { self::_remove_password($url); if (self::LOG_LEVEL) error_log(__METHOD__."($url) permission denied!"); @@ -779,7 +783,7 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper $parent = egw_vfs::dirname($path); if (!($stat = self::url_stat($path,0)) || $stat['mime'] != self::DIR_MIME_TYPE || - !egw_vfs::check_access($parent,egw_vfs::WRITABLE)) + !egw_vfs::check_access($parent, egw_vfs::WRITABLE, static::url_stat($parent,0))) { self::_remove_password($url); $err_msg = __METHOD__."($url,$options) ".(!$stat ? 'not found!' : diff --git a/phpgwapi/inc/class.vfs_webdav_server.inc.php b/phpgwapi/inc/class.vfs_webdav_server.inc.php index 36c31e9fea..48762610a9 100644 --- a/phpgwapi/inc/class.vfs_webdav_server.inc.php +++ b/phpgwapi/inc/class.vfs_webdav_server.inc.php @@ -90,7 +90,9 @@ class vfs_webdav_server extends HTTP_WebDAV_Server_Filesystem { // recursive delete the directory try { - $ret = egw_vfs::remove($options['path']) && !file_exists($path); + $deleted = egw_vfs::remove($options['path']); + $ret = !empty($deleted[$options['path']]); + //error_log(__METHOD__."() egw_vfs::remove($options[path]) returned ".array2string($deleted)." --> ".array2string($ret)); } catch (Exception $e) { return '403 Forbidden: '.$e->getMessage(); @@ -129,7 +131,7 @@ class vfs_webdav_server extends HTTP_WebDAV_Server_Filesystem return "403 Forbidden"; } - if ( file_exists($parent."/".$name) ) { + if ( file_exists($path) ) { return "405 Method not allowed"; } @@ -137,7 +139,7 @@ class vfs_webdav_server extends HTTP_WebDAV_Server_Filesystem return "415 Unsupported media type"; } - $stat = mkdir($parent."/".$name, 0777); + $stat = mkdir($path, 0777); if (!$stat) { return "403 Forbidden"; }