fix(db): use `caching_sha2_password` for MySQL

`caching_sha2_password` was added in 8.0.4 as the default
authentication plugin. `mysql_native_password` is deprecated since then.
In MySQL 8.4 it was disabled by default so a user need to manually
reenable it to make it work.
In MySQL 9.0 it is removed and causes the following error:

> SQLSTATE[HY000] [1524] Plugin 'mysql_native_password' is not loaded

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
pull/54043/head
Ferdinand Thiessen 3 months ago
parent db8dd9f7f6
commit b814f3bba6
No known key found for this signature in database
GPG Key ID: 45FAE7268762B400
  1. 27
      lib/private/Setup/MySQL.php

@ -8,6 +8,7 @@
namespace OC\Setup;
use Doctrine\DBAL\Platforms\MySQL80Platform;
use Doctrine\DBAL\Platforms\MySQL84Platform;
use OC\DB\ConnectionAdapter;
use OC\DB\MySqlTools;
use OCP\IDBConnection;
@ -92,22 +93,29 @@ class MySQL extends AbstractDatabase {
* @throws \OC\DatabaseSetupException
*/
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) {
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->executeUpdate($query, [$name,$password]);
$connection->executeStatement($query, [$name,$password]);
$query = "CREATE USER ?@'%' IDENTIFIED WITH mysql_native_password BY ?";
$connection->executeUpdate($query, [$name,$password]);
$connection->executeStatement($query, [$name,$password]);
} else {
$query = "CREATE USER ?@'localhost' IDENTIFIED BY ?";
$connection->executeUpdate($query, [$name,$password]);
$connection->executeStatement($query, [$name,$password]);
$query = "CREATE USER ?@'%' IDENTIFIED BY ?";
$connection->executeUpdate($query, [$name,$password]);
$connection->executeStatement($query, [$name,$password]);
}
} catch (\Exception $ex) {
$this->logger->error('Database user creation failed.', [
@ -158,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 {

Loading…
Cancel
Save