Fix phpMyAdmin SSO login and harden SSO/security posture
phpMyAdmin login was broken because phpmyadmin_install.sh never wired the private phpMyAdmin copy into the web server: no Apache Alias was registered via DirectAdmin CustomBuild, so the SSO redirect target was unreachable. Add configure_apache_alias()/apply_apache_alias() (Alias + Directory blocks, ./build rewrite_confs, httpd reload), detect the real Apache group instead of hardcoding diradmin:diradmin, stop silently swallowing chown/chmod failures, and verify an optional SHA256 for the downloaded phpMyAdmin tarball. Extend phpmyadmin_health_check.sh to detect a missing/incorrect Apache alias and to probe HTTP reachability. Security hardening: scope temporary phpMyAdmin SSO MySQL roles to 127.0.0.1 instead of '%', tighten SSO ticket file permissions to 0640 (they contain a plaintext MySQL password), and log MySQL connection failures for diagnosis instead of swallowing them silently. Bump version to 1.2.12 and rebuild the release archive.
This commit is contained in:
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
final class MySQLService
|
||||
{
|
||||
private const TMP_ROLE_PREFIX = 'da_tmp_phpmyadmin_';
|
||||
public const TMP_ROLE_HOST = '127.0.0.1';
|
||||
|
||||
/** @var array{host:string,port:int,database:string,user:string,password:string,socket:string} */
|
||||
private array $credentials;
|
||||
@@ -703,13 +704,14 @@ final class MySQLService
|
||||
public function createTemporaryRole(string $role, string $password, int $expiresAt): void
|
||||
{
|
||||
$this->query(
|
||||
'CREATE USER ' . $this->quoteLiteral($role) . '@\'%\' IDENTIFIED BY ' . $this->quoteLiteral($password)
|
||||
'CREATE USER ' . $this->quoteLiteral($role) . '@' . $this->quoteLiteral(self::TMP_ROLE_HOST) .
|
||||
' IDENTIFIED BY ' . $this->quoteLiteral($password)
|
||||
);
|
||||
$this->query(
|
||||
'INSERT INTO da_plugin_sso_accounts (role_name, host_pattern, expires_at)
|
||||
VALUES (?, \'%\', ?)
|
||||
VALUES (?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE expires_at = VALUES(expires_at)',
|
||||
[$role, (string)$expiresAt]
|
||||
[$role, self::TMP_ROLE_HOST, (string)$expiresAt]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -717,13 +719,13 @@ final class MySQLService
|
||||
{
|
||||
$this->query(
|
||||
'GRANT ALL PRIVILEGES ON ' . $this->quoteIdentifier($dbName) . '.* TO ' .
|
||||
$this->quoteLiteral($role) . '@\'%\''
|
||||
$this->quoteLiteral($role) . '@' . $this->quoteLiteral(self::TMP_ROLE_HOST)
|
||||
);
|
||||
}
|
||||
|
||||
public function dropTemporaryRole(string $role): void
|
||||
{
|
||||
$this->tryQuery('DROP USER IF EXISTS ' . $this->quoteLiteral($role) . '@\'%\'');
|
||||
$this->tryQuery('DROP USER IF EXISTS ' . $this->quoteLiteral($role) . '@' . $this->quoteLiteral(self::TMP_ROLE_HOST));
|
||||
$this->query('DELETE FROM da_plugin_sso_accounts WHERE role_name = ?', [$role]);
|
||||
}
|
||||
|
||||
@@ -1155,6 +1157,14 @@ final class MySQLService
|
||||
);
|
||||
|
||||
if ($ok !== true) {
|
||||
error_log(sprintf(
|
||||
'[%s] MYSQL_CONNECT_FAIL host=%s port=%d database=%s error=%s',
|
||||
date('c'),
|
||||
$this->credentials['host'],
|
||||
$this->credentials['port'],
|
||||
$targetDb,
|
||||
$conn->connect_error ?? 'unknown'
|
||||
));
|
||||
throw new RuntimeException('Nie udało się połączyć z MySQL.');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user