ba64342702
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.
147 lines
4.8 KiB
PHP
147 lines
4.8 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
return static function (AppContext $ctx): void {
|
|
$rawMode = defined('DA_MYSQL_RAW_MODE') && DA_MYSQL_RAW_MODE === true;
|
|
$ensurePhpMyAdminReady = static function (): void {
|
|
$healthScript = PLUGIN_ROOT . '/scripts/setup/phpmyadmin_health_check.sh';
|
|
$repairScript = PLUGIN_ROOT . '/scripts/setup/phpmyadmin_repair.sh';
|
|
$runScript = static function (string $script, string &$output): int {
|
|
if (!is_file($script)) {
|
|
$output = 'Brak skryptu: ' . $script;
|
|
return 127;
|
|
}
|
|
|
|
$lines = [];
|
|
$code = 0;
|
|
exec('/bin/bash ' . escapeshellarg($script) . ' 2>&1', $lines, $code);
|
|
$output = implode("\n", $lines);
|
|
return $code;
|
|
};
|
|
|
|
$healthOutput = '';
|
|
if ($runScript($healthScript, $healthOutput) === 0) {
|
|
return;
|
|
}
|
|
|
|
$repairOutput = '';
|
|
$repairCode = $runScript($repairScript, $repairOutput);
|
|
if ($repairCode !== 0) {
|
|
throw new RuntimeException(
|
|
"Nie udało się naprawić konfiguracji phpMyAdmin.\n" . trim($repairOutput)
|
|
);
|
|
}
|
|
|
|
$healthAfterRepair = '';
|
|
if ($runScript($healthScript, $healthAfterRepair) !== 0) {
|
|
throw new RuntimeException(
|
|
"Konfiguracja phpMyAdmin nadal nie przechodzi health-check po repair.\n" . trim($healthAfterRepair)
|
|
);
|
|
}
|
|
};
|
|
|
|
if (!Http::isPost()) {
|
|
$message = 'Nieprawidłowa metoda żądania.';
|
|
if ($rawMode) {
|
|
echo "HTTP/1.1 405 Method Not Allowed\r\n";
|
|
echo "Content-Type: text/plain; charset=UTF-8\r\n\r\n";
|
|
echo $message;
|
|
} else {
|
|
http_response_code(405);
|
|
header('Content-Type: text/plain; charset=UTF-8');
|
|
echo $message;
|
|
}
|
|
exit;
|
|
}
|
|
|
|
try {
|
|
$ensurePhpMyAdminReady();
|
|
} catch (Throwable $e) {
|
|
$message = 'Nie można przygotować phpMyAdmin: ' . $e->getMessage();
|
|
@error_log(
|
|
sprintf(
|
|
"[%s] PHPMYADMIN_PROVISION_FAIL user=%s remote=%s message=%s\n",
|
|
date('c'),
|
|
$ctx->daUser->username(),
|
|
Http::server('REMOTE_ADDR'),
|
|
$e->getMessage()
|
|
),
|
|
3,
|
|
PLUGIN_ROOT . '/error.log'
|
|
);
|
|
if ($rawMode) {
|
|
echo "HTTP/1.1 500 Internal Server Error\r\n";
|
|
echo "Content-Type: text/plain; charset=UTF-8\r\n\r\n";
|
|
echo $message;
|
|
} else {
|
|
http_response_code(500);
|
|
header('Content-Type: text/plain; charset=UTF-8');
|
|
echo $message;
|
|
}
|
|
exit;
|
|
}
|
|
|
|
if (!$ctx->settings->enableAdminer()) {
|
|
$message = 'Integracja phpMyAdmin jest wyłączona na tym serwerze.';
|
|
if ($rawMode) {
|
|
echo "HTTP/1.1 403 Forbidden\r\n";
|
|
echo "Content-Type: text/plain; charset=UTF-8\r\n\r\n";
|
|
echo $message;
|
|
} else {
|
|
http_response_code(403);
|
|
header('Content-Type: text/plain; charset=UTF-8');
|
|
echo $message;
|
|
}
|
|
exit;
|
|
}
|
|
|
|
try {
|
|
$ctx->requireCsrf('open_phpmyadmin_submit');
|
|
$requestedDb = trim($ctx->postString('adminer_db'));
|
|
if ($requestedDb === '') {
|
|
$requestedDb = null;
|
|
}
|
|
|
|
$sso = new PhpMyAdminSso($ctx->settings, $ctx->daUser, $ctx->mysql);
|
|
$payload = $sso->issueLoginPayload($requestedDb);
|
|
$target = (string)($payload['target'] ?? '');
|
|
if ($target === '') {
|
|
throw new RuntimeException('Nie udało się przygotować danych sesji do phpMyAdmin.');
|
|
}
|
|
|
|
if ($rawMode) {
|
|
echo "HTTP/1.1 302 Found\r\n";
|
|
echo "Location: " . $target . "\r\n";
|
|
echo "Cache-Control: no-store, no-cache, must-revalidate\r\n";
|
|
echo "Pragma: no-cache\r\n\r\n";
|
|
} else {
|
|
header('Location: ' . $target, true, 302);
|
|
}
|
|
exit;
|
|
} catch (Throwable $e) {
|
|
$message = 'Nie można otworzyć phpMyAdmin: ' . $e->getMessage();
|
|
@error_log(
|
|
sprintf(
|
|
"[%s] PHPMYADMIN_SSO_FAIL user=%s remote=%s message=%s\n",
|
|
date('c'),
|
|
$ctx->daUser->username(),
|
|
Http::server('REMOTE_ADDR'),
|
|
$e->getMessage()
|
|
),
|
|
3,
|
|
PLUGIN_ROOT . '/error.log'
|
|
);
|
|
|
|
if ($rawMode) {
|
|
echo "HTTP/1.1 400 Bad Request\r\n";
|
|
echo "Content-Type: text/plain; charset=UTF-8\r\n\r\n";
|
|
echo $message;
|
|
} else {
|
|
http_response_code(400);
|
|
header('Content-Type: text/plain; charset=UTF-8');
|
|
echo $message;
|
|
}
|
|
exit;
|
|
}
|
|
};
|