Problems with file upload under linux *solved*

Project:ProjectPier
Component:Code
Category:bug report
Priority:critical
Assigned:Unassigned
Status:patch - code needs review
Description

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.

Status:new» patch - code needs review
Priority:critical» normal
Status:patch - code needs review» closed - by design

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.

Priority:normal» critical
Status:closed - by design» patch - code needs review

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..

AttachmentSize
files.php.patch2.64 KB