diff --git a/core/src/plugins/access.ftp/class.ftpAccessDriver.php b/core/src/plugins/access.ftp/class.ftpAccessDriver.php index c1a4430728..6e56abd638 100644 --- a/core/src/plugins/access.ftp/class.ftpAccessDriver.php +++ b/core/src/plugins/access.ftp/class.ftpAccessDriver.php @@ -214,6 +214,20 @@ public function uploadActions($action, $httpVars, $filesVars) } + // Checks if a file belongs to currently logged in FTP user + private function isFileOwner($path) + { + $ftp = new ftpAccessWrapper(); + $stat = $ftp->url_stat($path, 2); + $urlParts = AJXP_Utils::safeParseUrl($path); + $repository = ConfService::getRepositoryById($urlParts["host"]); + $credentials = AJXP_Safe::tryLoadingCredentialsFromSources($urlParts, $repository); + if (empty($credentials["user"])) + return is_writable($path); + if ((string)$stat["uid"] == $credentials["user"]) + return true; + } + public function isWriteable($path, $type="dir") { $parts = parse_url($path); @@ -221,9 +235,15 @@ public function isWriteable($path, $type="dir") if ($type == "dir" && ($dir == "" || $dir == "/" || $dir == "\\")) { // ROOT, WE ARE NOT SURE TO BE ABLE TO READ THE PARENT return true; } else { - return is_writable($path); + $perms = substr(decoct(fileperms($path)), -3); + // World writable files + if (preg_match("/..[2367]$/", $perms)) + return true; + // Files belonging to currently logged in FTP user that are writable by owner + if ((preg_match("/^[2367]/", $perms)) && ($this->isFileOwner($path))) + return true; } - + return false; } public function deldir($location)