| Project: | ProjectPier |
| Version: | 0.8.5.0-Beta1 |
| Component: | Code |
| Category: | bug report |
| Priority: | critical |
| Assigned: | Jon |
| Status: | closed - by issue author |
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..
Tested and committed to SVN trunk with revision 177. Will be included in version 0.8.5 Beta 2.
http://projectpier.svn.sourceforge.net/viewvc/projectpier?view=rev&revision=177