Problems with file upload under linux *solved*
| Project: | ProjectPier |
| Component: | Code |
| Category: | bug report |
| Priority: | critical |
| Assigned: | Unassigned |
| Status: | patch - code needs review |
Hello Team,
related to my previous posting in the forum:
http://www.projectpier.org/node/285
The force_mkdir function has the problem that it doesn't work if a webserver user hasn't
the permission to check the system directory, means is_dir returns false if you check the
root dir "/" or "/var" because of the permissions.
I've written a workaround for the exists force_mkdir function and my recommodation
for a new one, which need to be testet on different systems!
New Function:
------------------------------------------------------
function force_mkdir($path, $chmod = null) {
$real_path = str_replace('\\', '/', $path);
mkdir($real_path, $chmod, true);
return is_dir($real_path);
}------------------------------------------------------
Temp. Workaround:
------------------------------------------------------
function force_mkdir($path, $chmod = null) {
if(is_dir($path)) return true;
$forced_path = '';
$real_path = str_replace($_SERVER["DOCUMENT_ROOT"], '', $path);
$forced_path = $path != $real_path ? $_SERVER["DOCUMENT_ROOT"] : '';
$real_path = str_replace('\\', '/', $real_path);
$parts = explode('/', $real_path);
foreach($parts as $part) {
if($forced_path == '') {
$start = substr(__FILE__, 0, 1) == '/' ? '/' : '';
$forced_path = $start . $part;
} else {
$forced_path .= '/' . $part;
} // if
if(!is_dir($forced_path) && $forced_path!='/') {
if(!is_null($chmod)) {
if(!mkdir($forced_path)) return false;
} else {
if(!mkdir($forced_path, $chmod)) return false;
} // if
} // if
} // foreach
return true;
} // force_mkdir
</p>
------------------------------------------------------

I think you should work on this function:
function force_mkdir($path, $chmod = null) {
$real_path = str_replace('\\', '/', $path);
mkdir($real_path, $chmod, true);
return is_dir($real_path);
}
anyway, it seems there are problems with this workaround under windows!
so have a check specialy with a windows server, i can't check it for my
self, because i run only linux servers.
I'm not convinced this is a good path to take, because if the open_basedir setting is in effect, you shouldn't be trying to access files outside of it anyway.
This sort of patch solved my problem for uploading files. First i had to turn off "safe_mode" on my server, but then the upload script would throw an error "File(/) is not within the allowed path(s)" (an open_basedir restriction error).
Which is clear when you don't run PHP in his own shell that users cannot upload, chdir or whatever to root (/). Can this be fixed by the team? I think it's a pretty serious issue. Martings code solved the problem for me.
The current code is not usable on a web-site that has open_basedir restriction. This works on my Linux site.
Please review this patch.
Changed function:
<?php/**
* Force creation of all dirs. <a href="http://projectpier.org/node/315
*
*" title="http://projectpier.org/node/315
*
*" rel="nofollow">http://projectpier.org/node/315
*
*</a> @access public
* @param void
* @return null
*/
function force_mkdir($path, $chmod = null) {
$real_path = str_replace('\\', '/', $path);
if (!isOpenbasedirAllowedPath($real_path)) {
return false;
}
mkdir($real_path, $chmod, true);
return is_dir($real_path);
}
?>
Added function:
<?php
/**
* Checks wether a given path is accesible with respect to openbase_dir restriction
*
* @link <a href="http://projectpier.org/node/315" title="http://projectpier.org/node/315" rel="nofollow">http://projectpier.org/node/315</a> is a problematic solution to the bug, as it relies on
* command line access
* @access public
* @param void
* @return null
*/
function isOpenbasedirAllowedPath($path) {
$basedirs = explode (PATH_SEPARATOR, ini_get("open_basedir"));
// no basedir restrictions
if (empty($basedirs)) return true;
// check if path is in basedirs
foreach ($basedirs as $basedir) {
if (substr($basedir,-1,1) === DIRECTORY_SEPARATOR) {
// open_basedir restricts access to $basedir only, not in its subdirs
// remove trailing slash
$basedir = substr($basedir, 0, -1);
// if the path points to exactly this strict basedir, then open_basedir restriction permits access
if ($basedir === $path) {
return true;
}
} elseif (substr($path, 0, strlen($basedir)) === $basedir) {
// the path is in the allowed basedir
return true;
}
}
// path is not in any basedir, so path is forbidden
return false;
}
?>
Hi Exception,
it would be helpful and easier for people to try your fix by creating a patch.
Please have a look at this page: http://projectpier.org/patch and ask if you have any problems with that.
Thanks,
Tim
Here you go..