From 55890b471a151c5c8e889723b9727061dccc050c Mon Sep 17 00:00:00 2001 From: Nathaniel Catchpole <catch@35733.no-reply.drupal.org> Date: Wed, 5 Feb 2014 10:28:48 +0000 Subject: [PATCH] Issue #2110863 by sun, cpj: Support open_basedir. --- core/includes/file.inc | 3 ++ core/install.php | 6 --- .../Component/PhpStorage/FileStorage.php | 51 ++++++++++++------- core/lib/Drupal/Core/DrupalKernel.php | 2 +- 4 files changed, 37 insertions(+), 25 deletions(-) diff --git a/core/includes/file.inc b/core/includes/file.inc index e1219b3fdf2c..83e6dc9df218 100644 --- a/core/includes/file.inc +++ b/core/includes/file.inc @@ -1497,6 +1497,9 @@ function drupal_basename($uri, $suffix = NULL) { * @see mkdir() * @see http://drupal.org/node/515192 * @ingroup php_wrappers + * + * @todo Update with open_basedir compatible recursion logic from + * \Drupal\Component\PhpStorage\FileStorage::ensureDirectory(). */ function drupal_mkdir($uri, $mode = NULL, $recursive = FALSE, $context = NULL) { if (!isset($mode)) { diff --git a/core/install.php b/core/install.php index b12947a618d4..7152fd812b02 100644 --- a/core/install.php +++ b/core/install.php @@ -36,12 +36,6 @@ exit; } -// Exit early if the PHP option open_basedir is enabled to avoid fatal errors. -if (ini_get('open_basedir')) { - print 'Your PHP installation has open_basedir enabled. Drupal currently requires the open_basedir option to be turned off. See the <a href="http://www.php.net/manual/en/ini.core.php#ini.open-basedir">PHP manual</a> for details of how to do this. This issue is currently <a href="https://drupal.org/node/2110863">under discussion at drupal.org</a>.'; - exit; -} - // Start the installer. require_once __DIR__ . '/includes/install.core.inc'; install_drupal(); diff --git a/core/lib/Drupal/Component/PhpStorage/FileStorage.php b/core/lib/Drupal/Component/PhpStorage/FileStorage.php index dbfa12d0344c..e6b4f0f84905 100644 --- a/core/lib/Drupal/Component/PhpStorage/FileStorage.php +++ b/core/lib/Drupal/Component/PhpStorage/FileStorage.php @@ -58,31 +58,46 @@ public function save($name, $code) { } /** - * Ensures the root directory exists and has the right permissions. + * Ensures the requested directory exists and has the right permissions. + * + * For compatibility with open_basedir, the requested directory is created + * using a recursion logic that is based on the relative directory path/tree: + * It works from the end of the path recursively back towards the root + * directory, until an existing parent directory is found. From there, the + * subdirectories are created. * * @param string $directory * The directory path. - * * @param int $mode * The mode, permissions, the directory should have. + * @param bool $is_backwards_recursive + * Internal use only. + * + * @return bool + * TRUE if the directory exists or has been created, FALSE otherwise. */ - protected function ensureDirectory($directory, $mode = 0777) { - if (!file_exists($directory)) { - // mkdir() obeys umask() so we need to mkdir() and chmod() manually. - $parts = explode('/', $directory); - $path = ''; - $delimiter = ''; - do { - $part = array_shift($parts); - $path .= $delimiter . $part; - $delimiter = '/'; - // For absolute paths the first part will be empty. - if ($part && !file_exists($path)) { - mkdir($path); - chmod($path, $mode); - } - } while ($parts); + protected function ensureDirectory($directory, $mode = 0777, $is_backwards_recursive = FALSE) { + // If the directory exists already, there's nothing to do. + if (is_dir($directory)) { + return TRUE; + } + // Otherwise, try to create the directory and ensure to set its permissions, + // because mkdir() obeys the umask of the current process. + if (is_dir($parent = dirname($directory))) { + // If the parent directory exists, then the backwards recursion must end, + // regardless of whether the subdirectory could be created. + if ($status = mkdir($directory)) { + // Only try to chmod() if the subdirectory could be created. + $status = chmod($directory, $mode); + } + return $is_backwards_recursive ? TRUE : $status; } + // If the parent directory and the requested directory does not exist and + // could not be created above, walk the requested directory path back up + // until an existing directory is hit, and from there, recursively create + // the sub-directories. Only if that recursion succeeds, create the final, + // originally requested subdirectory. + return $this->ensureDirectory($parent, $mode, TRUE) && mkdir($directory) && chmod($directory, $mode); } /** diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php index 46a7fee6b4d3..85fa7f817ee5 100644 --- a/core/lib/Drupal/Core/DrupalKernel.php +++ b/core/lib/Drupal/Core/DrupalKernel.php @@ -510,7 +510,7 @@ protected function buildContainer() { foreach (array('Core', 'Component') as $parent_directory) { $path = DRUPAL_ROOT . '/core/lib/Drupal/' . $parent_directory; foreach (new \DirectoryIterator($path) as $component) { - if (!$component->isDot() && is_dir($component->getPathname() . '/Plugin')) { + if (!$component->isDot() && $component->isDir() && is_dir($component->getPathname() . '/Plugin')) { $namespaces['Drupal\\' . $parent_directory . '\\' . $component->getFilename()] = DRUPAL_ROOT . '/core/lib'; } } -- GitLab