Skip to content

Commit

Permalink
MDL-23984 improved check_dir_exists() and make_upload_directory() inc…
Browse files Browse the repository at this point in the history
…orrect permissions throw fatal exceptions by default; it is possible to create dirs outside of dataroot (necessary for custom dir locations); fixed Win32 compatibility in session_exists method
  • Loading branch information
skodak committed Aug 29, 2010
1 parent 8d3bf3e commit 4031f6a
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 67 deletions.
2 changes: 1 addition & 1 deletion lang/en/error.php
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@
$string['invalidcoursemodule'] = 'Invalid course module ID';
$string['invalidcoursenameshort'] = 'Invalid short course name';
$string['invaliddata'] = 'Data submitted is invalid';
$string['invaliddatarootpermissions'] = 'Invalid permissions detected in $CFG->dataroot directory, administrator has to fix permissions.';
$string['invalidelementid'] = 'Incorrect element id!';
$string['invalidentry'] = 'This is not valid entry!';
$string['invalidevent'] = 'Invalid event';
Expand Down Expand Up @@ -419,7 +420,6 @@
$string['sessionerroruser2'] = 'A server error that affects your login session was detected. Please login again or restart your browser.';
$string['sessionipnomatch'] = 'Sorry, but your IP number seems to have changed from when you first logged in. This security feature prevents crackers stealing your identity while logged in to this site. Normal users should not be seeing this message - please ask the site administrator for help.';
$string['sessionipnomatch2'] = 'Sorry, but your IP number seems to have changed from when you first logged in. This security feature prevents crackers stealing your identity while logged in to this site. You may see this error if you use wireless networks or if you are roaming between different networks. Please ask the site administrator for more help.<br /><br />If you want to continue please press F5 key to refresh this page.';
$string['sessionnotwritable'] = 'Write permission problem detected in session directory.<br /><br />Please notify server administrator.';
$string['shortnametaken'] = 'Short name is already used for another course';
$string['scheduledbackupsdisabled'] = 'Scheduled backups have been disabled by the server admin';
$string['socksnotsupported'] = 'SOCKS5 proxy is not supported in PHP4';
Expand Down
26 changes: 0 additions & 26 deletions lib/moodlelib.php
Original file line number Diff line number Diff line change
Expand Up @@ -9024,32 +9024,6 @@ function remove_dir($dir, $content_only=false) {
return rmdir($dir); // if anything left the result will be false, no need for && $result
}

/**
* Function to check if a directory exists and by default create it if not exists.
*
* Previously this was accepting paths only from dataroot, but we now allow
* some data outside of dataroot if you supply custom paths
* for some settings in config.php.
*
* @param string absolute directory path
* @param boolean create directory if does not exist
* @param boolean create directory recursively
* @return boolean true if directory exists or created
*/
function check_dir_exists($dir, $create = true, $recursive = true) {
global $CFG;

if (is_dir($dir)) {
return true;
}

if (!$create) {
return false;
}

return mkdir($dir, $CFG->directorypermissions, $recursive);
}

/**
* Detect if an object or a class contains a given property
* will take an actual object or the name of a class
Expand Down
13 changes: 4 additions & 9 deletions lib/sessionlib.php
Original file line number Diff line number Diff line change
Expand Up @@ -339,12 +339,9 @@ protected function init_session_storage() {

ini_set('session.gc_maxlifetime', $CFG->sessiontimeout);

if (!file_exists($CFG->dataroot .'/sessions')) {
make_upload_directory('sessions');
}
if (!is_writable($CFG->dataroot .'/sessions/')) {
print_error('sessionnotwritable', 'error');
}
// make sure sessions dir exists and is writable, throws exception if not
make_upload_directory('sessions');

// Need to disable debugging since disk_free_space()
// will fail on very large partitions (see MDL-19222)
$freespace = @disk_free_space($CFG->dataroot.'/sessions');
Expand All @@ -360,11 +357,9 @@ protected function init_session_storage() {
*/
public function session_exists($sid){
$sid = clean_param($sid, PARAM_FILE);
$sessionfile = clean_param("$CFG->dataroot/sessions/sess_$sid", PARAM_FILE);
$sessionfile = "$CFG->dataroot/sessions/sess_$sid";
return file_exists($sessionfile);
}


}

/**
Expand Down
106 changes: 75 additions & 31 deletions lib/setuplib.php
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,24 @@ function __construct($hint, $debuginfo=null) {
}
}

/**
* An exception that indicates incorrect permissions in $CFG->dataroot
*
* @package core
* @subpackage lib
* @copyright 2010 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class invalid_dataroot_permissions extends moodle_exception {
/**
* Constructor
* @param string $debuginfo optional more detailed information
*/
function __construct($debuginfo = NULL) {
parent::__construct('invaliddatarootpermissions', 'error', '', NULL, $debuginfo);
}
}

/**
* Default exception handler, uncaught exceptions are equivalent to error() in 1.9 and earlier
*
Expand Down Expand Up @@ -839,56 +857,82 @@ function redirect_if_major_upgrade_required() {
}

/**
* Create a directory.
* Function to check if a directory exists and by default create it if not exists.
*
* Previously this was accepting paths only from dataroot, but we now allow
* files outside of dataroot if you supply custom paths for some settings in config.php.
* This function does not verify that the directory is writable.
*
* @uses $CFG
* @param string $directory a string of directory names under $CFG->dataroot eg stuff/assignment/1
* param bool $shownotices If true then notification messages will be printed out on error.
* @return string|false Returns full path to directory if successful, false if not
* @param string $dir absolute directory path
* @param boolean $create directory if does not exist
* @param boolean $recursive create directory recursively
* @return boolean true if directory exists or created, false otherwise
*/
function make_upload_directory($directory, $shownotices=true) {

function check_dir_exists($dir, $create = true, $recursive = true) {
global $CFG;

$currdir = $CFG->dataroot;
umask(0000); // just in case some evil code changed it

umask(0000);
if (is_dir($dir)) {
return true;
}

if (!file_exists($currdir)) {
if (!mkdir($currdir, $CFG->directorypermissions, true) or !is_writable($currdir)) {
if ($shownotices) {
echo '<div class="notifyproblem" align="center">ERROR: You need to create the directory '.
$currdir .' with web server write access</div>'."<br />\n";
}
return false;
}
if (!$create) {
return false;
}

// Make sure a .htaccess file is here, JUST IN CASE the files area is in the open
if (!file_exists($currdir.'/.htaccess')) {
if ($handle = fopen($currdir.'/.htaccess', 'w')) { // For safety
return mkdir($dir, $CFG->directorypermissions, $recursive);
}

/**
* Create a directory in dataroot and make sure it is writable.
*
* @param string $directory a string of directory names under $CFG->dataroot eg temp/something
* @param bool $exceptiononerror throw exception if error encountered
* @return string|false Returns full path to directory if successful, false if not; may throw exception
*/
function make_upload_directory($directory, $exceptiononerror = true) {
global $CFG;

// Make sure a .htaccess file is here, JUST IN CASE the files area is in the open and .htaccess is supported
if (!file_exists("$CFG->dataroot/.htaccess")) {
if ($handle = fopen("$CFG->dataroot/.htaccess", 'w')) { // For safety
@fwrite($handle, "deny from all\r\nAllowOverride None\r\nNote: this file is broken intentionally, we do not want anybody to undo it in subdirectory!\r\n");
@fclose($handle);
}
}

$dirarray = explode('/', $directory);
$dir = "$CFG->dataroot/$directory";

foreach ($dirarray as $dir) {
$currdir = $currdir .'/'. $dir;
if (! file_exists($currdir)) {
if (! mkdir($currdir, $CFG->directorypermissions)) {
if ($shownotices) {
echo '<div class="notifyproblem" align="center">ERROR: Could not find or create a directory ('.
$currdir .')</div>'."<br />\n";
}
if (file_exists($dir) and !is_dir($dir)) {
if ($exceptiononerror) {
throw new coding_exception($dir.' directory can not be created, file with the same name already exists.');
} else {
return false;
}
}

umask(0000); // just in case some evil code changed it

if (!file_exists($dir)) {
if (!mkdir($dir, $CFG->directorypermissions, true)) {
if ($exceptiononerror) {
throw new invalid_dataroot_permissions($dir.' can not be created, check permissions.');
} else {
return false;
}
//@chmod($currdir, $CFG->directorypermissions); // Just in case mkdir didn't do it
}
}

return $currdir;
if (!is_writable($dir)) {
if ($exceptiononerror) {
throw new invalid_dataroot_permissions($dir.' is not writable, check permissions.');
} else {
return false;
}
}

return $dir;
}

function init_memcached() {
Expand Down

0 comments on commit 4031f6a

Please sign in to comment.