diff options
author | Lukas Reschke <lukas@owncloud.com> | 2014-10-01 10:43:18 +0200 |
---|---|---|
committer | Lukas Reschke <lukas@owncloud.com> | 2014-10-01 10:43:18 +0200 |
commit | cbecd622875bd7e251d955e0574437d3862e01b0 (patch) | |
tree | 330a63df9fef0cfb9f64d6a9bbab70353ec127b6 /lib | |
parent | 5beeb923e66fb3b45004e079fcf13534705c494b (diff) | |
parent | 68cf6681e5efc79610eec2199e8850ba88cc1808 (diff) | |
download | nextcloud-server-cbecd622875bd7e251d955e0574437d3862e01b0.tar.gz nextcloud-server-cbecd622875bd7e251d955e0574437d3862e01b0.zip |
Merge pull request #11303 from owncloud/addFilelockToConfig
Add flock to config
Diffstat (limited to 'lib')
-rw-r--r-- | lib/private/config.php | 134 | ||||
-rw-r--r-- | lib/private/legacy/config.php | 38 |
2 files changed, 89 insertions, 83 deletions
diff --git a/lib/private/config.php b/lib/private/config.php index 82a1c46c9d5..7bf3863e2a6 100644 --- a/lib/private/config.php +++ b/lib/private/config.php @@ -1,37 +1,12 @@ <?php /** - * ownCloud - * * @author Frank Karlitschek * @author Jakob Sack * @copyright 2012 Frank Karlitschek frank@owncloud.org * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AFFERO GENERAL PUBLIC LICENSE for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with this library. If not, see <http://www.gnu.org/licenses/>. - * - */ -/* - * - * An example of config.php - * - * <?php - * $CONFIG = array( - * "database" => "mysql", - * "firstrun" => false, - * "pi" => 3.14 - * ); - * ?> - * + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. */ namespace OC; @@ -41,26 +16,45 @@ namespace OC; * configuration file of ownCloud. */ class Config { - // associative array key => value + /** @var array Associative array ($key => $value) */ protected $cache = array(); - + /** @var string */ protected $configDir; - protected $configFilename; - + /** @var string */ + protected $configFilePath; + /** @var string */ + protected $configFileName; + /** @var bool */ protected $debugMode; /** - * @param string $configDir path to the config dir, needs to end with '/' + * @param string $configDir Path to the config dir, needs to end with '/' + * @param string $fileName (Optional) Name of the config file. Defaults to config.php */ - public function __construct($configDir) { + public function __construct($configDir, $fileName = 'config.php') { $this->configDir = $configDir; - $this->configFilename = $this->configDir.'config.php'; + $this->configFilePath = $this->configDir.$fileName; + $this->configFileName = $fileName; $this->readData(); - $this->setDebugMode(defined('DEBUG') && DEBUG); + $this->debugMode = (defined('DEBUG') && DEBUG); + } + + /** + * Enables or disables the debug mode + * @param bool $state True to enable, false to disable + */ + public function setDebugMode($state) { + $this->debugMode = $state; + $this->writeData(); + $this->cache; } - public function setDebugMode($enable) { - $this->debugMode = $enable; + /** + * Returns whether the debug mode is enabled or disabled + * @return bool True when enabled, false otherwise + */ + public function isDebugMode() { + return $this->debugMode; } /** @@ -128,27 +122,43 @@ class Config { * Loads the config file * * Reads the config file and saves it to the cache + * + * @throws \Exception If no lock could be acquired or the config file has not been found */ private function readData() { - // Default config - $configFiles = array($this->configFilename); - // Add all files in the config dir ending with config.php - $extra = glob($this->configDir.'*.config.php'); + // Default config should always get loaded + $configFiles = array($this->configFilePath); + + // Add all files in the config dir ending with the same file name + $extra = glob($this->configDir.'*.'.$this->configFileName); if (is_array($extra)) { natsort($extra); $configFiles = array_merge($configFiles, $extra); } + // Include file and merge config foreach ($configFiles as $file) { - if (!file_exists($file)) { + if(!@touch($file) && $file === $this->configFilePath) { + // Writing to the main config might not be possible, e.g. if the wrong + // permissions are set (likely on a new installation) continue; } + $filePointer = fopen($file, 'r'); + + // Try to acquire a file lock + if(!flock($filePointer, LOCK_SH)) { + throw new \Exception(sprintf('Could not acquire a shared lock on the config file %s', $file)); + } + unset($CONFIG); - // ignore errors on include, this can happen when doing a fresh install - @include $file; - if (isset($CONFIG) && is_array($CONFIG)) { + include $file; + if(isset($CONFIG) && is_array($CONFIG)) { $this->cache = array_merge($this->cache, $CONFIG); } + + // Close the file pointer and release the lock + flock($filePointer, LOCK_UN); + fclose($filePointer); } } @@ -157,6 +167,8 @@ class Config { * * Saves the config to the config file. * + * @throws HintException If the config file cannot be written to + * @throws \Exception If no file lock can be acquired */ private function writeData() { // Create a php file ... @@ -168,18 +180,34 @@ class Config { $content .= var_export($this->cache, true); $content .= ";\n"; - // Write the file - $result = @file_put_contents($this->configFilename, $content); - if (!$result) { - $defaults = new \OC_Defaults; + touch ($this->configFilePath); + $filePointer = fopen($this->configFilePath, 'r+'); + + // Prevent others not to read the config + chmod($this->configFilePath, 0640); + + // File does not exist, this can happen when doing a fresh install + if(!is_resource ($filePointer)) { $url = \OC_Helper::linkToDocs('admin-dir_permissions'); throw new HintException( "Can't write into config directory!", 'This can usually be fixed by ' - .'<a href="' . $url . '" target="_blank">giving the webserver write access to the config directory</a>.'); + .'<a href="' . $url . '" target="_blank">giving the webserver write access to the config directory</a>.'); } - // Prevent others not to read the config - @chmod($this->configFilename, 0640); + + // Try to acquire a file lock + if(!flock($filePointer, LOCK_EX)) { + throw new \Exception(sprintf('Could not acquire an exclusive lock on the config file %s', $this->configFilePath)); + } + + // Write the config and release the lock + ftruncate ($filePointer, 0); + fwrite($filePointer, $content); + fflush($filePointer); + flock($filePointer, LOCK_UN); + fclose($filePointer); + + // Clear the opcode cache \OC_Util::clearOpcodeCache(); } } diff --git a/lib/private/legacy/config.php b/lib/private/legacy/config.php index 4d6fefc4e17..13ff0dbe040 100644 --- a/lib/private/legacy/config.php +++ b/lib/private/legacy/config.php @@ -6,32 +6,9 @@ * @author Jakob Sack * @copyright 2012 Frank Karlitschek frank@owncloud.org * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AFFERO GENERAL PUBLIC LICENSE for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with this library. If not, see <http://www.gnu.org/licenses/>. - * - */ -/* - * - * An example of config.php - * - * <?php - * $CONFIG = array( - * "database" => "mysql", - * "firstrun" => false, - * "pi" => 3.14 - * ); - * ?> - * + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. */ /** @@ -42,11 +19,13 @@ */ class OC_Config { - /** - * @var \OC\Config - */ + /** @var \OC\Config */ public static $object; + /** + * Returns the config instance + * @return \OC\Config + */ public static function getObject() { return self::$object; } @@ -92,7 +71,6 @@ class OC_Config { * @param string $key key * * This function removes a key from the config.php. - * */ public static function deleteKey($key) { self::$object->deleteKey($key); |