aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/Setup
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private/Setup')
-rw-r--r--lib/private/Setup/AbstractDatabase.php49
-rw-r--r--lib/private/Setup/MySQL.php79
-rw-r--r--lib/private/Setup/OCI.php40
-rw-r--r--lib/private/Setup/PostgreSQL.php72
-rw-r--r--lib/private/Setup/Sqlite.php26
5 files changed, 88 insertions, 178 deletions
diff --git a/lib/private/Setup/AbstractDatabase.php b/lib/private/Setup/AbstractDatabase.php
index 82c00cb271a..8f6294faa66 100644
--- a/lib/private/Setup/AbstractDatabase.php
+++ b/lib/private/Setup/AbstractDatabase.php
@@ -1,30 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Thomas Pulzer <t.pulzer@kniel.de>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OC\Setup;
@@ -71,14 +50,14 @@ abstract class AbstractDatabase {
public function validate($config) {
$errors = [];
if (empty($config['dbuser']) && empty($config['dbname'])) {
- $errors[] = $this->trans->t("Enter the database username and name for %s", [$this->dbprettyname]);
+ $errors[] = $this->trans->t('Enter the database Login and name for %s', [$this->dbprettyname]);
} elseif (empty($config['dbuser'])) {
- $errors[] = $this->trans->t("Enter the database username for %s", [$this->dbprettyname]);
+ $errors[] = $this->trans->t('Enter the database Login for %s', [$this->dbprettyname]);
} elseif (empty($config['dbname'])) {
- $errors[] = $this->trans->t("Enter the database name for %s", [$this->dbprettyname]);
+ $errors[] = $this->trans->t('Enter the database name for %s', [$this->dbprettyname]);
}
if (substr_count($config['dbname'], '.') >= 1) {
- $errors[] = $this->trans->t("You cannot use dots in the database name %s", [$this->dbprettyname]);
+ $errors[] = $this->trans->t('You cannot use dots in the database name %s', [$this->dbprettyname]);
}
return $errors;
}
@@ -91,14 +70,13 @@ abstract class AbstractDatabase {
$dbPort = !empty($config['dbport']) ? $config['dbport'] : '';
$dbTablePrefix = $config['dbtableprefix'] ?? 'oc_';
- $createUserConfig = $this->config->getValue("setup_create_db_user", true);
+ $createUserConfig = $this->config->getValue('setup_create_db_user', true);
// accept `false` both as bool and string, since setting config values from env will result in a string
- $this->tryCreateDbUser = $createUserConfig !== false && $createUserConfig !== "false";
+ $this->tryCreateDbUser = $createUserConfig !== false && $createUserConfig !== 'false';
$this->config->setValues([
'dbname' => $dbName,
'dbhost' => $dbHost,
- 'dbport' => $dbPort,
'dbtableprefix' => $dbTablePrefix,
]);
@@ -148,13 +126,10 @@ abstract class AbstractDatabase {
return $connection;
}
- /**
- * @param string $username
- */
- abstract public function setupDatabase($username);
+ abstract public function setupDatabase();
public function runMigrations(?IOutput $output = null) {
- if (!is_dir(\OC::$SERVERROOT."/core/Migrations")) {
+ if (!is_dir(\OC::$SERVERROOT . '/core/Migrations')) {
return;
}
$ms = new MigrationService('core', \OC::$server->get(Connection::class), $output);
diff --git a/lib/private/Setup/MySQL.php b/lib/private/Setup/MySQL.php
index 0d672f324eb..c4794a86743 100644
--- a/lib/private/Setup/MySQL.php
+++ b/lib/private/Setup/MySQL.php
@@ -1,35 +1,14 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Hemanth Kumar Veeranki <hems.india1997@gmail.com>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Michael Göhler <somebody.here@gmx.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <vincent@nextcloud.com>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OC\Setup;
use Doctrine\DBAL\Platforms\MySQL80Platform;
+use Doctrine\DBAL\Platforms\MySQL84Platform;
use OC\DB\ConnectionAdapter;
use OC\DB\MySqlTools;
use OCP\IDBConnection;
@@ -38,7 +17,7 @@ use OCP\Security\ISecureRandom;
class MySQL extends AbstractDatabase {
public $dbprettyname = 'MySQL/MariaDB';
- public function setupDatabase($username) {
+ public function setupDatabase() {
//check if the database user has admin right
$connection = $this->connect(['dbname' => null]);
@@ -50,7 +29,7 @@ class MySQL extends AbstractDatabase {
}
if ($this->tryCreateDbUser) {
- $this->createSpecificUser($username, new ConnectionAdapter($connection));
+ $this->createSpecificUser('oc_admin', new ConnectionAdapter($connection));
}
$this->config->setValues([
@@ -63,7 +42,7 @@ class MySQL extends AbstractDatabase {
//fill the database if needed
$query = 'select count(*) from information_schema.tables where table_schema=? AND table_name = ?';
- $connection->executeQuery($query, [$this->dbName, $this->tablePrefix.'users']);
+ $connection->executeQuery($query, [$this->dbName, $this->tablePrefix . 'users']);
$connection->close();
$connection = $this->connect();
@@ -73,7 +52,7 @@ class MySQL extends AbstractDatabase {
$this->logger->error($e->getMessage(), [
'exception' => $e,
]);
- throw new \OC\DatabaseSetupException($this->trans->t('MySQL username and/or password not valid'),
+ throw new \OC\DatabaseSetupException($this->trans->t('MySQL Login and/or password not valid'),
$this->trans->t('You need to enter details of an existing account.'), 0, $e);
}
}
@@ -81,7 +60,7 @@ class MySQL extends AbstractDatabase {
/**
* @param \OC\DB\Connection $connection
*/
- private function createDatabase($connection) {
+ private function createDatabase($connection): void {
try {
$name = $this->dbName;
$user = $this->dbUser;
@@ -113,23 +92,30 @@ class MySQL extends AbstractDatabase {
* @param IDBConnection $connection
* @throws \OC\DatabaseSetupException
*/
- private function createDBUser($connection) {
+ private function createDBUser($connection): void {
+ $name = $this->dbUser;
+ $password = $this->dbPassword;
+
try {
- $name = $this->dbUser;
- $password = $this->dbPassword;
// we need to create 2 accounts, one for global use and one for local user. if we don't specify the local one,
// the anonymous user would take precedence when there is one.
- if ($connection->getDatabasePlatform() instanceof Mysql80Platform) {
- $query = "CREATE USER '$name'@'localhost' IDENTIFIED WITH mysql_native_password BY '$password'";
- $connection->executeUpdate($query);
- $query = "CREATE USER '$name'@'%' IDENTIFIED WITH mysql_native_password BY '$password'";
- $connection->executeUpdate($query);
+ if ($connection->getDatabasePlatform() instanceof MySQL84Platform) {
+ $query = "CREATE USER ?@'localhost' IDENTIFIED WITH caching_sha2_password BY ?";
+ $connection->executeStatement($query, [$name,$password]);
+ $query = "CREATE USER ?@'%' IDENTIFIED WITH caching_sha2_password BY ?";
+ $connection->executeStatement($query, [$name,$password]);
+ } elseif ($connection->getDatabasePlatform() instanceof Mysql80Platform) {
+ // TODO: Remove this elseif section as soon as MySQL 8.0 is out-of-support (after April 2026)
+ $query = "CREATE USER ?@'localhost' IDENTIFIED WITH mysql_native_password BY ?";
+ $connection->executeStatement($query, [$name,$password]);
+ $query = "CREATE USER ?@'%' IDENTIFIED WITH mysql_native_password BY ?";
+ $connection->executeStatement($query, [$name,$password]);
} else {
- $query = "CREATE USER '$name'@'localhost' IDENTIFIED BY '$password'";
- $connection->executeUpdate($query);
- $query = "CREATE USER '$name'@'%' IDENTIFIED BY '$password'";
- $connection->executeUpdate($query);
+ $query = "CREATE USER ?@'localhost' IDENTIFIED BY ?";
+ $connection->executeStatement($query, [$name,$password]);
+ $query = "CREATE USER ?@'%' IDENTIFIED BY ?";
+ $connection->executeStatement($query, [$name,$password]);
}
} catch (\Exception $ex) {
$this->logger->error('Database user creation failed.', [
@@ -141,7 +127,7 @@ class MySQL extends AbstractDatabase {
}
/**
- * @param $username
+ * @param string $username
* @param IDBConnection $connection
*/
private function createSpecificUser($username, $connection): void {
@@ -180,6 +166,11 @@ class MySQL extends AbstractDatabase {
//use the admin login data for the new database user
$this->dbUser = $adminUser;
$this->createDBUser($connection);
+ // if sharding is used we need to manually call this for every shard as those also need the user setup!
+ /** @var ConnectionAdapter $connection */
+ foreach ($connection->getInner()->getShardConnections() as $shard) {
+ $this->createDBUser($shard);
+ }
break;
} else {
diff --git a/lib/private/Setup/OCI.php b/lib/private/Setup/OCI.php
index 477561bbe2a..61c7f968787 100644
--- a/lib/private/Setup/OCI.php
+++ b/lib/private/Setup/OCI.php
@@ -1,31 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Andreas Fischer <bantu@owncloud.com>
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Victor Dubiniuk <dubiniuk@owncloud.com>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OC\Setup;
@@ -53,16 +31,16 @@ class OCI extends AbstractDatabase {
public function validate($config) {
$errors = [];
if (empty($config['dbuser']) && empty($config['dbname'])) {
- $errors[] = $this->trans->t("Enter the database username and name for %s", [$this->dbprettyname]);
+ $errors[] = $this->trans->t('Enter the database Login and name for %s', [$this->dbprettyname]);
} elseif (empty($config['dbuser'])) {
- $errors[] = $this->trans->t("Enter the database username for %s", [$this->dbprettyname]);
+ $errors[] = $this->trans->t('Enter the database Login for %s', [$this->dbprettyname]);
} elseif (empty($config['dbname'])) {
- $errors[] = $this->trans->t("Enter the database name for %s", [$this->dbprettyname]);
+ $errors[] = $this->trans->t('Enter the database name for %s', [$this->dbprettyname]);
}
return $errors;
}
- public function setupDatabase($username) {
+ public function setupDatabase() {
try {
$this->connect();
} catch (\Exception $e) {
@@ -75,7 +53,7 @@ class OCI extends AbstractDatabase {
. ' NLS_LANG=' . getenv('NLS_LANG')
. ' tnsnames.ora is ' . (is_readable(getenv('ORACLE_HOME') . '/network/admin/tnsnames.ora') ? '' : 'not ') . 'readable', 0, $e);
}
- throw new \OC\DatabaseSetupException($this->trans->t('Oracle username and/or password not valid'),
+ throw new \OC\DatabaseSetupException($this->trans->t('Oracle Login and/or password not valid'),
'Check environment: ORACLE_HOME=' . getenv('ORACLE_HOME')
. ' ORACLE_SID=' . getenv('ORACLE_SID')
. ' LD_LIBRARY_PATH=' . getenv('LD_LIBRARY_PATH')
diff --git a/lib/private/Setup/PostgreSQL.php b/lib/private/Setup/PostgreSQL.php
index 490cbba69a9..9a686db2e54 100644
--- a/lib/private/Setup/PostgreSQL.php
+++ b/lib/private/Setup/PostgreSQL.php
@@ -1,30 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author eduardo <eduardo@vnexu.net>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Vitor Mattos <vitor@php.rio>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OC\Setup;
@@ -37,10 +16,9 @@ class PostgreSQL extends AbstractDatabase {
public $dbprettyname = 'PostgreSQL';
/**
- * @param string $username
* @throws \OC\DatabaseSetupException
*/
- public function setupDatabase($username) {
+ public function setupDatabase() {
try {
$connection = $this->connect([
'dbname' => 'postgres'
@@ -67,21 +45,11 @@ class PostgreSQL extends AbstractDatabase {
//use the admin login data for the new database user
//add prefix to the postgresql user name to prevent collisions
- $this->dbUser = 'oc_' . strtolower($username);
+ $this->dbUser = 'oc_admin';
//create a new password so we don't need to store the admin config in the config file
- $this->dbPassword = \OC::$server->getSecureRandom()->generate(30, ISecureRandom::CHAR_ALPHANUMERIC);
+ $this->dbPassword = \OC::$server->get(ISecureRandom::class)->generate(30, ISecureRandom::CHAR_ALPHANUMERIC);
$this->createDBUser($connection);
-
- // Go to the main database and grant create on the public schema
- // The code below is implemented to make installing possible with PostgreSQL version 15:
- // https://www.postgresql.org/docs/release/15.0/
- // From the release notes: For new databases having no need to defend against insider threats, granting CREATE permission will yield the behavior of prior releases
- // Therefore we assume that the database is only used by one user/service which is Nextcloud
- // Additional services should get installed in a separate database in order to stay secure
- // Also see https://www.postgresql.org/docs/15/ddl-schemas.html#DDL-SCHEMAS-PATTERNS
- $connectionMainDatabase->executeQuery('GRANT CREATE ON SCHEMA public TO "' . addslashes($this->dbUser) . '"');
- $connectionMainDatabase->close();
}
}
@@ -94,6 +62,20 @@ class PostgreSQL extends AbstractDatabase {
$this->createDatabase($connection);
// the connection to dbname=postgres is not needed anymore
$connection->close();
+
+ if ($this->tryCreateDbUser) {
+ if ($canCreateRoles) {
+ // Go to the main database and grant create on the public schema
+ // The code below is implemented to make installing possible with PostgreSQL version 15:
+ // https://www.postgresql.org/docs/release/15.0/
+ // From the release notes: For new databases having no need to defend against insider threats, granting CREATE permission will yield the behavior of prior releases
+ // Therefore we assume that the database is only used by one user/service which is Nextcloud
+ // Additional services should get installed in a separate database in order to stay secure
+ // Also see https://www.postgresql.org/docs/15/ddl-schemas.html#DDL-SCHEMAS-PATTERNS
+ $connectionMainDatabase->executeQuery('GRANT CREATE ON SCHEMA public TO "' . addslashes($this->dbUser) . '"');
+ $connectionMainDatabase->close();
+ }
+ }
} catch (\Exception $e) {
$this->logger->warning('Error trying to connect as "postgres", assuming database is setup and tables need to be created', [
'exception' => $e,
@@ -114,7 +96,7 @@ class PostgreSQL extends AbstractDatabase {
$this->logger->error($e->getMessage(), [
'exception' => $e,
]);
- throw new \OC\DatabaseSetupException($this->trans->t('PostgreSQL username and/or password not valid'),
+ throw new \OC\DatabaseSetupException($this->trans->t('PostgreSQL Login and/or password not valid'),
$this->trans->t('You need to enter details of an existing account.'), 0, $e);
}
}
@@ -122,7 +104,7 @@ class PostgreSQL extends AbstractDatabase {
private function createDatabase(Connection $connection) {
if (!$this->databaseExists($connection)) {
//The database does not exists... let's create it
- $query = $connection->prepare("CREATE DATABASE " . addslashes($this->dbName) . " OWNER \"" . addslashes($this->dbUser) . '"');
+ $query = $connection->prepare('CREATE DATABASE ' . addslashes($this->dbName) . ' OWNER "' . addslashes($this->dbUser) . '"');
try {
$query->execute();
} catch (DatabaseException $e) {
@@ -131,7 +113,7 @@ class PostgreSQL extends AbstractDatabase {
]);
}
} else {
- $query = $connection->prepare("REVOKE ALL PRIVILEGES ON DATABASE " . addslashes($this->dbName) . " FROM PUBLIC");
+ $query = $connection->prepare('REVOKE ALL PRIVILEGES ON DATABASE ' . addslashes($this->dbName) . ' FROM PUBLIC');
try {
$query->execute();
} catch (DatabaseException $e) {
@@ -148,7 +130,7 @@ class PostgreSQL extends AbstractDatabase {
$query = $builder->select('*')
->from('pg_roles')
->where($builder->expr()->eq('rolname', $builder->createNamedParameter($this->dbUser)));
- $result = $query->execute();
+ $result = $query->executeQuery();
return $result->rowCount() > 0;
}
@@ -158,7 +140,7 @@ class PostgreSQL extends AbstractDatabase {
$query = $builder->select('datname')
->from('pg_database')
->where($builder->expr()->eq('datname', $builder->createNamedParameter($this->dbName)));
- $result = $query->execute();
+ $result = $query->executeQuery();
return $result->rowCount() > 0;
}
@@ -172,7 +154,7 @@ class PostgreSQL extends AbstractDatabase {
}
// create the user
- $query = $connection->prepare("CREATE USER \"" . addslashes($this->dbUser) . "\" CREATEDB PASSWORD '" . addslashes($this->dbPassword) . "'");
+ $query = $connection->prepare('CREATE USER "' . addslashes($this->dbUser) . "\" CREATEDB PASSWORD '" . addslashes($this->dbPassword) . "'");
$query->execute();
if ($this->databaseExists($connection)) {
$query = $connection->prepare('GRANT CONNECT ON DATABASE ' . addslashes($this->dbName) . ' TO "' . addslashes($this->dbUser) . '"');
diff --git a/lib/private/Setup/Sqlite.php b/lib/private/Setup/Sqlite.php
index 8ed432b039a..b34b1e32ede 100644
--- a/lib/private/Setup/Sqlite.php
+++ b/lib/private/Setup/Sqlite.php
@@ -1,25 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Daniel Kesselberg <mail@danielkesselberg.de>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OC\Setup;
@@ -61,7 +45,7 @@ class Sqlite extends AbstractDatabase {
}
}
- public function setupDatabase($username) {
+ public function setupDatabase() {
$datadir = $this->config->getValue(
'datadirectory',
\OC::$SERVERROOT . '/data'