Skip to content

Commit 4b36f9d

Browse files
Merge pull request #30130 from nextcloud/fix/config_is_read_only
Don't write to config file if `config_is_read_only` is set
2 parents e231338 + 241dfef commit 4b36f9d

File tree

3 files changed

+33
-5
lines changed

3 files changed

+33
-5
lines changed

config/config.sample.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -809,11 +809,11 @@
809809

810810
/**
811811
* In certain environments it is desired to have a read-only configuration file.
812-
* When this switch is set to ``true`` Nextcloud will not verify whether the
813-
* configuration is writable. However, it will not be possible to configure
814-
* all options via the Web interface. Furthermore, when updating Nextcloud
815-
* it is required to make the configuration file writable again for the update
816-
* process.
812+
* When this switch is set to ``true``, writing to the config file will be
813+
* forbidden. Therefore, it will not be possible to configure all options via
814+
* the Web interface. Furthermore, when updating Nextcloud it is required to
815+
* make the configuration file writable again and to set this switch to ``false``
816+
* for the update process.
817817
*
818818
* Defaults to ``false``
819819
*/

lib/private/Config.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ class Config {
5757
protected $configFilePath;
5858
/** @var string */
5959
protected $configFileName;
60+
/** @var bool */
61+
protected $isReadOnly;
6062

6163
/**
6264
* @param string $configDir Path to the config dir, needs to end with '/'
@@ -67,6 +69,7 @@ public function __construct($configDir, $fileName = 'config.php') {
6769
$this->configFilePath = $this->configDir.$fileName;
6870
$this->configFileName = $fileName;
6971
$this->readData();
72+
$this->isReadOnly = $this->getValue('config_is_read_only', false);
7073
}
7174

7275
/**
@@ -109,6 +112,7 @@ public function getValue($key, $default = null) {
109112
*
110113
* @param array $configs Associative array with `key => value` pairs
111114
* If value is null, the config key will be deleted
115+
* @throws HintException
112116
*/
113117
public function setValues(array $configs) {
114118
$needsUpdate = false;
@@ -131,6 +135,7 @@ public function setValues(array $configs) {
131135
*
132136
* @param string $key key
133137
* @param mixed $value value
138+
* @throws HintException
134139
*/
135140
public function setValue($key, $value) {
136141
if ($this->set($key, $value)) {
@@ -145,8 +150,11 @@ public function setValue($key, $value) {
145150
* @param string $key key
146151
* @param mixed $value value
147152
* @return bool True if the file needs to be updated, false otherwise
153+
* @throws HintException
148154
*/
149155
protected function set($key, $value) {
156+
$this->checkReadOnly();
157+
150158
if (!isset($this->cache[$key]) || $this->cache[$key] !== $value) {
151159
// Add change
152160
$this->cache[$key] = $value;
@@ -158,7 +166,9 @@ protected function set($key, $value) {
158166

159167
/**
160168
* Removes a key from the config and removes it from config.php if required
169+
*
161170
* @param string $key
171+
* @throws HintException
162172
*/
163173
public function deleteKey($key) {
164174
if ($this->delete($key)) {
@@ -172,8 +182,11 @@ public function deleteKey($key) {
172182
*
173183
* @param string $key
174184
* @return bool True if the file needs to be updated, false otherwise
185+
* @throws HintException
175186
*/
176187
protected function delete($key) {
188+
$this->checkReadOnly();
189+
177190
if (isset($this->cache[$key])) {
178191
// Delete key from cache
179192
unset($this->cache[$key]);
@@ -239,6 +252,8 @@ private function readData() {
239252
* @throws \Exception If no file lock can be acquired
240253
*/
241254
private function writeData() {
255+
$this->checkReadOnly();
256+
242257
// Create a php file ...
243258
$content = "<?php\n";
244259
$content .= '$CONFIG = ';
@@ -274,4 +289,15 @@ private function writeData() {
274289
@opcache_invalidate($this->configFilePath, true);
275290
}
276291
}
292+
293+
/**
294+
* @throws HintException
295+
*/
296+
private function checkReadOnly(): void {
297+
if ($this->isReadOnly) {
298+
throw new HintException(
299+
'Config is set to be read-only via option "config_is_read_only".',
300+
'Unset "config_is_read_only" to allow changes to the config file.');
301+
}
302+
}
277303
}

lib/public/IConfig.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ interface IConfig {
4747
*
4848
* @param array $configs Associative array with `key => value` pairs
4949
* If value is null, the config key will be deleted
50+
* @throws HintException if config file is read-only
5051
* @since 8.0.0
5152
*/
5253
public function setSystemValues(array $configs);
@@ -56,6 +57,7 @@ public function setSystemValues(array $configs);
5657
*
5758
* @param string $key the key of the value, under which will be saved
5859
* @param mixed $value the value that should be stored
60+
* @throws HintException if config file is read-only
5961
* @since 8.0.0
6062
*/
6163
public function setSystemValue($key, $value);

0 commit comments

Comments
 (0)