Files
alt-mysql/scripts/setup/phpmyadmin_install.sh
T
Marek Miklewicz 1560759c51 Scope phpMyAdmin SSO to one database, fix logout, reset create form
After live testing on the real server, three follow-up issues surfaced:

- PhpMyAdminSso granted the temporary SSO MySQL role access to every
  database the account owns, not just the one the "Zaloguj do bazy"
  button was clicked for, so phpMyAdmin showed all databases. Extract
  determineGrantTargets() and scope the GRANT to only the requested
  database; also set phpMyAdmin's only_db from the SSO session so the
  UI itself only shows that database.

- phpMyAdmin's LogoutURL pointed at da_login.php with no ticket, which
  always produced "Missing or invalid phpMyAdmin login ticket." on
  logout. Add a DIRECTADMIN_PANEL_PORT setting (default 2222) and
  point LogoutURL at the plugin's own database list
  (/CMD_PLUGINS/alt-mysql/index.html) instead.

- The create-database form kept echoing back the just-submitted
  values after a successful creation, forcing manual clearing before
  creating the next database. Clear the relevant $_POST keys once
  creation succeeds so the form resets while still preserving sticky
  values on validation failure.

Bump version to 1.2.14 and rebuild the release archive.
2026-07-04 20:38:04 +02:00

684 lines
22 KiB
Bash

#!/bin/bash
set -euo pipefail
PHPMYADMIN_PRIVATE_DIR="${PHPMYADMIN_PRIVATE_DIR:-${PHPMYADMIN_DIR:-/var/www/html/alt-mysql-phpmyadmin}}"
PHPMYADMIN_URL_PATH="${PHPMYADMIN_URL_PATH:-/alt-mysql-phpmyadmin}"
PHPMYADMIN_VERSION="${PHPMYADMIN_VERSION:-5.2.3}"
PHPMYADMIN_TARBALL_URL="${PHPMYADMIN_TARBALL_URL:-https://files.phpmyadmin.net/phpMyAdmin/5.2.3/phpMyAdmin-5.2.3-all-languages.tar.gz}"
PHPMYADMIN_TARBALL_SHA256="${PHPMYADMIN_TARBALL_SHA256:-}"
PHPMYADMIN_DOWNLOAD_DIR="${PHPMYADMIN_DOWNLOAD_DIR:-/usr/local/src}"
PHPMYADMIN_SOURCE_DIR="${PHPMYADMIN_SOURCE_DIR:-}"
RUNTIME_DIR="${PHPMYADMIN_PRIVATE_DIR}/runtime"
TICKETS_DIR="${RUNTIME_DIR}/tickets"
CONFIG_INC="${PHPMYADMIN_PRIVATE_DIR}/config.inc.php"
SIGNON_SCRIPT="${PHPMYADMIN_PRIVATE_DIR}/da_signon.php"
SIGNON_URL_PAGE="${PHPMYADMIN_PRIVATE_DIR}/da_login.php"
BLOWFISH_SECRET_FILE="${RUNTIME_DIR}/blowfish_secret"
APACHE_HTTPD_CONF="${APACHE_HTTPD_CONF:-/etc/httpd/conf/httpd.conf}"
APACHE_VHOSTS_CONF="${APACHE_VHOSTS_CONF:-/etc/httpd/conf/extra/httpd-vhosts.conf}"
CUSTOMBUILD_DIR="${CUSTOMBUILD_DIR:-/usr/local/directadmin/custombuild}"
CB_BUILD="${CUSTOMBUILD_DIR}/build"
APACHE_ALIAS_CUSTOM="${CUSTOMBUILD_DIR}/custom/ap2/conf/extra/httpd-alias.conf"
APACHE_ALIAS_SOURCE="/etc/httpd/conf/extra/httpd-alias.conf"
APACHE_ALIAS_CONFIGURE="${CUSTOMBUILD_DIR}/configure/ap2/conf/extra/httpd-alias.conf"
if [ "${PHPMYADMIN_INSTALL_ASSUME_ROOT:-0}" != "1" ] && [ "${EUID:-$(id -u)}" -ne 0 ]; then
echo "Skrypt musi być uruchomiony jako root." >&2
exit 1
fi
log() {
printf 'phpMyAdmin alt-mysql: %s\n' "$*"
}
warn() {
printf 'phpMyAdmin alt-mysql: WARNING: %s\n' "$*" >&2
}
die() {
printf 'phpMyAdmin alt-mysql: %s\n' "$*" >&2
exit 1
}
chown_or_warn() {
local owner="$1" errfile
shift
errfile="$(mktemp)"
chown "$owner" "$@" 2>"$errfile" || warn "chown $owner $* failed: $(cat "$errfile")"
rm -f "$errfile"
}
chmod_or_warn() {
local mode="$1" errfile
shift
errfile="$(mktemp)"
chmod "$mode" "$@" 2>"$errfile" || warn "chmod $mode $* failed: $(cat "$errfile")"
rm -f "$errfile"
}
detect_apache_group() {
local group_name=""
# Under SuExec (DirectAdmin's own convention for the default/shared
# vhost that serves /var/www/html), PHP actually executes as the
# SuexecUserGroup account (commonly "webapps"), not as Apache's own
# httpd.conf "Group" (commonly "apache"). That distinction is exactly
# what determines whether phpMyAdmin's SSO ticket files are readable,
# so it takes priority over the plain Group directive below.
if [ -f "$APACHE_VHOSTS_CONF" ]; then
group_name="$(awk 'tolower($1)=="suexecusergroup" {print $3; exit}' "$APACHE_VHOSTS_CONF" | tr -d '[:space:]')"
fi
if [ -z "$group_name" ] && [ -f "$APACHE_HTTPD_CONF" ]; then
group_name="$(awk 'tolower($1)=="group" {print $2; exit}' "$APACHE_HTTPD_CONF" | tr -d '[:space:]')"
fi
if [ -z "$group_name" ] && [ -f /etc/apache2/apache2.conf ]; then
group_name="$(awk 'tolower($1)=="group" {print $2; exit}' /etc/apache2/apache2.conf | tr -d '[:space:]')"
fi
if [ -z "$group_name" ]; then
for candidate in apache www-data nobody; do
if getent group "$candidate" >/dev/null 2>&1; then
group_name="$candidate"
break
fi
done
fi
printf '%s\n' "${group_name:-diradmin}"
}
install_private_copy_from_source() {
local source_dir="$1"
[ -d "$source_dir" ] || die "Katalog źródłowy phpMyAdmin nie istnieje: $source_dir"
[ -f "$source_dir/index.php" ] || die "Katalog źródłowy nie wygląda jak phpMyAdmin: $source_dir"
mkdir -p "$PHPMYADMIN_PRIVATE_DIR"
cp -a "$source_dir"/. "$PHPMYADMIN_PRIVATE_DIR"/
}
download_private_copy() {
local tarball extracted tmp_dir
command -v curl >/dev/null 2>&1 || die "Brak curl; ustaw PHPMYADMIN_SOURCE_DIR albo doinstaluj curl."
command -v tar >/dev/null 2>&1 || die "Brak tar."
mkdir -p "$PHPMYADMIN_DOWNLOAD_DIR"
tarball="$PHPMYADMIN_DOWNLOAD_DIR/phpMyAdmin-${PHPMYADMIN_VERSION}-all-languages.tar.gz"
if [ ! -s "$tarball" ]; then
log "Pobieram prywatny phpMyAdmin ${PHPMYADMIN_VERSION}."
curl -fL --retry 3 --connect-timeout 20 -o "$tarball" "$PHPMYADMIN_TARBALL_URL"
fi
if [ -n "$PHPMYADMIN_TARBALL_SHA256" ]; then
command -v sha256sum >/dev/null 2>&1 || die "Brak sha256sum do weryfikacji archiwum phpMyAdmin."
local actual_sum
actual_sum="$(sha256sum "$tarball" | awk '{print $1}')"
[ "$actual_sum" = "$PHPMYADMIN_TARBALL_SHA256" ] || {
rm -f "$tarball"
die "Niezgodna suma SHA256 archiwum phpMyAdmin. Oczekiwano: ${PHPMYADMIN_TARBALL_SHA256}, otrzymano: ${actual_sum}"
}
fi
tmp_dir="$(mktemp -d)"
tar -xzf "$tarball" -C "$tmp_dir"
extracted="$(find "$tmp_dir" -mindepth 1 -maxdepth 1 -type d -name 'phpMyAdmin-*' -print -quit)"
[ -n "$extracted" ] || {
rm -rf "$tmp_dir"
die "Tarball phpMyAdmin nie zawiera oczekiwanego katalogu."
}
install_private_copy_from_source "$extracted"
rm -rf "$tmp_dir"
}
ensure_private_copy() {
if [ -f "$PHPMYADMIN_PRIVATE_DIR/index.php" ]; then
return 0
fi
rm -rf "$PHPMYADMIN_PRIVATE_DIR"
if [ -n "$PHPMYADMIN_SOURCE_DIR" ]; then
install_private_copy_from_source "$PHPMYADMIN_SOURCE_DIR"
else
download_private_copy
fi
}
generate_secret() {
if [ -r "$BLOWFISH_SECRET_FILE" ]; then
local existing
existing="$(tr -d '\r\n' < "$BLOWFISH_SECRET_FILE")"
if [ -n "$existing" ]; then
printf '%s\n' "$existing"
return 0
fi
fi
if command -v openssl >/dev/null 2>&1; then
openssl rand -hex 32
return 0
fi
tr -dc 'a-f0-9' </dev/urandom | head -c 64
printf '\n'
}
write_private_config() {
local secret
mkdir -p "$RUNTIME_DIR" "$TICKETS_DIR"
secret="$(generate_secret)"
printf '%s\n' "$secret" > "$BLOWFISH_SECRET_FILE"
chmod 600 "$BLOWFISH_SECRET_FILE" 2>/dev/null || true
cat > "$RUNTIME_DIR/.htaccess" <<'EOF'
Require all denied
Deny from all
EOF
cat > "$TICKETS_DIR/.htaccess" <<'EOF'
Require all denied
Deny from all
EOF
printf '%s\n' '<!doctype html><title>Forbidden</title>' > "$RUNTIME_DIR/index.html"
printf '%s\n' '<!doctype html><title>Forbidden</title>' > "$TICKETS_DIR/index.html"
cat > "$CONFIG_INC" <<'PHP'
<?php
declare(strict_types=1);
const DA_MYSQL_PMA_DEFAULT_CONF = '/usr/local/directadmin/conf/alt-mysql.conf';
const DA_MYSQL_PMA_RUNTIME_CONFIG = __DIR__ . '/runtime/config.json';
const DA_MYSQL_PMA_BLOWFISH_SECRET_FILE = __DIR__ . '/runtime/blowfish_secret';
function da_mysql_phpmyadmin_runtime_config(): array
{
if (!is_readable(DA_MYSQL_PMA_RUNTIME_CONFIG)) {
return [];
}
$raw = file_get_contents(DA_MYSQL_PMA_RUNTIME_CONFIG);
if (!is_string($raw) || $raw === '') {
return [];
}
$decoded = json_decode($raw, true);
return is_array($decoded) ? $decoded : [];
}
function da_mysql_phpmyadmin_parse_conf(string $path): array
{
$data = [
'host' => '127.0.0.1',
'port' => '33033',
'socket' => '',
];
if (!is_readable($path)) {
return $data;
}
$lines = file($path, FILE_IGNORE_NEW_LINES);
if ($lines === false) {
return $data;
}
foreach ($lines as $line) {
$line = trim($line);
if ($line === '' || $line[0] === '#' || strpos($line, '=') === false) {
continue;
}
[$key, $value] = explode('=', $line, 2);
$key = strtolower(trim($key));
$value = trim(trim($value), "\"'");
if ($key === 'host' && $value !== '') {
$data['host'] = $value;
} elseif (($key === 'port' || $key === 'mysql_port') && ctype_digit($value)) {
$data['port'] = $value;
} elseif (($key === 'socket' || $key === 'mysql_socket') && $value !== '') {
$data['socket'] = $value;
}
}
if ($data['host'] === '' || $data['host'] === 'localhost') {
$data['host'] = '127.0.0.1';
}
return $data;
}
function da_mysql_phpmyadmin_blowfish_secret(): string
{
if (is_readable(DA_MYSQL_PMA_BLOWFISH_SECRET_FILE)) {
$secret = trim((string)file_get_contents(DA_MYSQL_PMA_BLOWFISH_SECRET_FILE));
if ($secret !== '') {
return $secret;
}
}
return 'alt-mysql-phpmyadmin-secret-change-me';
}
function da_mysql_phpmyadmin_url_path(array $runtimeConfig): string
{
$path = trim((string)($runtimeConfig['phpmyadmin_url_path'] ?? '/alt-mysql-phpmyadmin'));
if ($path === '') {
return '/alt-mysql-phpmyadmin';
}
if ($path[0] !== '/') {
$path = '/' . $path;
}
$path = rtrim($path, '/');
return $path !== '' ? $path : '/alt-mysql-phpmyadmin';
}
function da_mysql_phpmyadmin_public_base_url(array $runtimeConfig): string
{
$configured = trim((string)($runtimeConfig['phpmyadmin_public_base_url'] ?? ''));
if (preg_match('#^https?://#i', $configured) === 1) {
return rtrim($configured, '/');
}
$scheme = 'http';
$https = strtolower((string)($_SERVER['HTTPS'] ?? ''));
if ($https !== '' && $https !== 'off' && $https !== '0') {
$scheme = 'https';
} elseif (strtolower((string)($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '')) === 'https') {
$scheme = 'https';
} elseif (strtolower((string)($_SERVER['REQUEST_SCHEME'] ?? '')) === 'https') {
$scheme = 'https';
}
$host = trim((string)($_SERVER['HTTP_HOST'] ?? ''));
if ($host === '') {
$host = trim((string)($_SERVER['SERVER_NAME'] ?? 'localhost'));
}
if ($host === '') {
$host = 'localhost';
}
return $scheme . '://' . $host;
}
function da_mysql_phpmyadmin_signon_url(array $runtimeConfig): string
{
return da_mysql_phpmyadmin_public_base_url($runtimeConfig)
. da_mysql_phpmyadmin_url_path($runtimeConfig)
. '/da_login.php';
}
function da_mysql_phpmyadmin_panel_logout_url(array $runtimeConfig): string
{
$scheme = 'http';
$https = strtolower((string)($_SERVER['HTTPS'] ?? ''));
if ($https !== '' && $https !== 'off' && $https !== '0') {
$scheme = 'https';
} elseif (strtolower((string)($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '')) === 'https') {
$scheme = 'https';
} elseif (strtolower((string)($_SERVER['REQUEST_SCHEME'] ?? '')) === 'https') {
$scheme = 'https';
}
$host = trim((string)($_SERVER['HTTP_HOST'] ?? ''));
if ($host === '') {
$host = trim((string)($_SERVER['SERVER_NAME'] ?? 'localhost'));
}
if ($host === '') {
$host = 'localhost';
}
$host = preg_replace('/:\d+$/', '', $host) ?? $host;
$port = trim((string)($runtimeConfig['directadmin_panel_port'] ?? '2222'));
if ($port === '' || !ctype_digit($port)) {
$port = '2222';
}
return $scheme . '://' . $host . ':' . $port . '/CMD_PLUGINS/alt-mysql/index.html';
}
function da_mysql_phpmyadmin_only_db(): string
{
$sessionName = 'DA_MYSQL_PHPMYADMIN';
if (session_status() === PHP_SESSION_ACTIVE) {
return '';
}
$sessionId = (string)($_COOKIE[$sessionName] ?? '');
if ($sessionId === '' || preg_match('/\A[A-Za-z0-9,-]+\z/', $sessionId) !== 1) {
return '';
}
session_name($sessionName);
session_id($sessionId);
session_start();
$auth = $_SESSION['DA_MYSQL_PHPMYADMIN_AUTH'] ?? [];
$db = is_array($auth) ? (string)($auth['db'] ?? '') : '';
session_write_close();
return $db;
}
$runtimeConfig = da_mysql_phpmyadmin_runtime_config();
$credentialsFile = (string)($runtimeConfig['credentials_file'] ?? DA_MYSQL_PMA_DEFAULT_CONF);
if ($credentialsFile === '') {
$credentialsFile = DA_MYSQL_PMA_DEFAULT_CONF;
}
$daMysqlServer = da_mysql_phpmyadmin_parse_conf($credentialsFile);
$cfg = [];
$cfg['blowfish_secret'] = da_mysql_phpmyadmin_blowfish_secret();
$cfg['TempDir'] = __DIR__ . '/runtime/tmp';
$cfg['LoginCookieValidity'] = 900;
$i = 0;
$i++;
$cfg['Servers'][$i]['host'] = $daMysqlServer['host'];
$cfg['Servers'][$i]['port'] = $daMysqlServer['port'];
$cfg['Servers'][$i]['socket'] = $daMysqlServer['host'] === 'localhost' ? $daMysqlServer['socket'] : '';
$cfg['Servers'][$i]['auth_type'] = 'signon';
$cfg['Servers'][$i]['SignonScript'] = __DIR__ . '/da_signon.php';
$cfg['Servers'][$i]['SignonSession'] = 'DA_MYSQL_PHPMYADMIN';
$cfg['Servers'][$i]['SignonURL'] = da_mysql_phpmyadmin_signon_url($runtimeConfig);
$cfg['Servers'][$i]['LogoutURL'] = da_mysql_phpmyadmin_panel_logout_url($runtimeConfig);
$cfg['Servers'][$i]['AllowNoPassword'] = false;
$cfg['Servers'][$i]['verbose'] = 'DirectAdmin alt-mysql';
$cfg['Servers'][$i]['only_db'] = da_mysql_phpmyadmin_only_db();
$cfg['ServerDefault'] = 1;
$cfg['AllowArbitraryServer'] = false;
PHP
cat > "$SIGNON_URL_PAGE" <<'PHP'
<?php
declare(strict_types=1);
const DA_MYSQL_SESSION = 'DA_MYSQL_PHPMYADMIN';
const DA_MYSQL_RUNTIME_CONFIG = __DIR__ . '/runtime/config.json';
function da_mysql_login_runtime_config(): array
{
if (!is_readable(DA_MYSQL_RUNTIME_CONFIG)) {
return [];
}
$raw = file_get_contents(DA_MYSQL_RUNTIME_CONFIG);
if (!is_string($raw) || $raw === '') {
return [];
}
$decoded = json_decode($raw, true);
return is_array($decoded) ? $decoded : [];
}
function da_mysql_login_url_path(array $runtimeConfig): string
{
$path = trim((string)($runtimeConfig['phpmyadmin_url_path'] ?? '/alt-mysql-phpmyadmin'));
if ($path === '') {
return '/alt-mysql-phpmyadmin';
}
if ($path[0] !== '/') {
$path = '/' . $path;
}
$path = rtrim($path, '/');
return $path !== '' ? $path : '/alt-mysql-phpmyadmin';
}
function da_mysql_login_ticket_dir(array $runtimeConfig): string
{
$dir = trim((string)($runtimeConfig['ticket_dir'] ?? ''));
if ($dir !== '') {
return rtrim($dir, '/');
}
return __DIR__ . '/runtime/tickets';
}
function da_mysql_login_error(string $message): void
{
http_response_code(400);
header('Content-Type: text/html; charset=UTF-8');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Pragma: no-cache');
$safe = htmlspecialchars($message, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
echo '<!doctype html><html lang="en"><head><meta charset="utf-8"><title>alt-mysql phpMyAdmin</title></head><body>';
echo '<h1>alt-mysql phpMyAdmin</h1><p>' . $safe . '</p>';
echo '</body></html>';
exit;
}
function da_mysql_login_consume_ticket(array $runtimeConfig): array
{
$token = strtolower((string)($_GET['ticket'] ?? ''));
if (preg_match('/\A[a-f0-9]{64}\z/', $token) !== 1) {
da_mysql_login_error('Missing or invalid phpMyAdmin login ticket.');
}
$path = da_mysql_login_ticket_dir($runtimeConfig) . '/' . $token . '.json';
if (!is_readable($path)) {
da_mysql_login_error('The phpMyAdmin login ticket is not available or has already been used.');
}
$raw = file_get_contents($path);
@unlink($path);
$ticket = is_string($raw) ? json_decode($raw, true) : null;
if (!is_array($ticket)) {
da_mysql_login_error('The phpMyAdmin login ticket is invalid.');
}
if ((int)($ticket['expires_at'] ?? 0) < time()) {
da_mysql_login_error('The phpMyAdmin login ticket has expired.');
}
$auth = $ticket['auth'] ?? [];
if (!is_array($auth) || (string)($auth['user'] ?? '') === '' || (string)($auth['password'] ?? '') === '') {
da_mysql_login_error('The phpMyAdmin login ticket does not contain credentials.');
}
return $ticket;
}
function da_mysql_login_redirect_target(array $ticket): string
{
$route = (string)($ticket['route'] ?? '/database/structure');
if (preg_match('#^/[A-Za-z0-9_./-]+$#', $route) !== 1 || strpos($route, '//') !== false) {
$route = '/';
}
$query = ['route' => $route];
$db = (string)($ticket['db'] ?? ($ticket['auth']['db'] ?? ''));
if ($db !== '') {
$query['db'] = $db;
}
return 'index.php?' . http_build_query($query);
}
$runtimeConfig = da_mysql_login_runtime_config();
$ticket = da_mysql_login_consume_ticket($runtimeConfig);
$secure = false;
$https = strtolower((string)($_SERVER['HTTPS'] ?? ''));
if ($https !== '' && $https !== 'off' && $https !== '0') {
$secure = true;
} elseif (strtolower((string)($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '')) === 'https') {
$secure = true;
}
session_name(DA_MYSQL_SESSION);
session_set_cookie_params([
'lifetime' => 0,
'path' => da_mysql_login_url_path($runtimeConfig),
'secure' => $secure,
'httponly' => true,
'samesite' => 'Lax',
]);
session_start();
$_SESSION['DA_MYSQL_PHPMYADMIN_AUTH'] = $ticket['auth'];
session_write_close();
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Pragma: no-cache');
header('Location: ' . da_mysql_login_redirect_target($ticket), true, 302);
exit;
PHP
cat > "$SIGNON_SCRIPT" <<'PHP'
<?php
declare(strict_types=1);
const DA_MYSQL_SESSION = 'DA_MYSQL_PHPMYADMIN';
const DA_MYSQL_DEFAULT_CONF = '/usr/local/directadmin/conf/alt-mysql.conf';
const DA_MYSQL_RUNTIME_CONFIG = __DIR__ . '/runtime/config.json';
function da_mysql_runtime_config(): array
{
if (!is_readable(DA_MYSQL_RUNTIME_CONFIG)) {
return [];
}
$raw = file_get_contents(DA_MYSQL_RUNTIME_CONFIG);
if (!is_string($raw) || $raw === '') {
return [];
}
$decoded = json_decode($raw, true);
return is_array($decoded) ? $decoded : [];
}
function da_mysql_signon_session_auth(): array
{
$payload = $_SESSION['DA_MYSQL_PHPMYADMIN_AUTH'] ?? [];
return is_array($payload) ? $payload : [];
}
function da_mysql_signon_read_auth(): array
{
$previousActive = session_status() === PHP_SESSION_ACTIVE;
$previousName = session_name();
$previousId = $previousActive ? session_id() : '';
if ($previousActive && $previousName === DA_MYSQL_SESSION) {
return da_mysql_signon_session_auth();
}
if ($previousActive) {
session_write_close();
}
session_name(DA_MYSQL_SESSION);
session_id('');
$ssoSessionId = (string)($_COOKIE[DA_MYSQL_SESSION] ?? '');
if ($ssoSessionId !== '' && preg_match('/\A[A-Za-z0-9,-]+\z/', $ssoSessionId) === 1) {
session_id($ssoSessionId);
}
session_start();
$payload = da_mysql_signon_session_auth();
session_write_close();
if ($previousActive) {
session_name($previousName);
if ($previousId !== '') {
session_id($previousId);
}
session_start();
} elseif ($previousName !== '') {
session_name($previousName);
}
return $payload;
}
function get_login_credentials($user = ''): array
{
$payload = da_mysql_signon_read_auth();
$username = (string)($payload['user'] ?? '');
$password = (string)($payload['password'] ?? '');
return [$username, $password];
}
PHP
local apache_group
apache_group="$(detect_apache_group)"
mkdir -p "$RUNTIME_DIR/tmp"
chown_or_warn root:root "$PHPMYADMIN_PRIVATE_DIR"
chmod_or_warn 755 "$PHPMYADMIN_PRIVATE_DIR"
chown_or_warn "diradmin:${apache_group}" "$RUNTIME_DIR" "$TICKETS_DIR" "$RUNTIME_DIR/tmp" "$CONFIG_INC" "$SIGNON_SCRIPT" "$SIGNON_URL_PAGE"
chmod_or_warn 711 "$RUNTIME_DIR" "$RUNTIME_DIR/tmp"
chmod_or_warn 2733 "$TICKETS_DIR"
chmod_or_warn 644 "$CONFIG_INC" "$SIGNON_SCRIPT" "$SIGNON_URL_PAGE" "$RUNTIME_DIR/.htaccess" "$TICKETS_DIR/.htaccess" "$RUNTIME_DIR/index.html" "$TICKETS_DIR/index.html"
}
configure_apache_alias() {
if [ ! -d "$CUSTOMBUILD_DIR" ]; then
warn "Brak katalogu CustomBuild: ${CUSTOMBUILD_DIR} - pomijam konfigurację aliasu Apache. Skonfiguruj go ręcznie: Alias ${PHPMYADMIN_URL_PATH} ${PHPMYADMIN_PRIVATE_DIR}"
return 0
fi
mkdir -p "$(dirname "$APACHE_ALIAS_CUSTOM")"
if [ ! -f "$APACHE_ALIAS_CUSTOM" ]; then
if [ -f "$APACHE_ALIAS_SOURCE" ]; then
cp -p "$APACHE_ALIAS_SOURCE" "$APACHE_ALIAS_CUSTOM"
elif [ -f "$APACHE_ALIAS_CONFIGURE" ]; then
cp -p "$APACHE_ALIAS_CONFIGURE" "$APACHE_ALIAS_CUSTOM"
else
warn "Nie znaleziono źródłowego httpd-alias.conf - tworzę pusty szablon custom."
: > "$APACHE_ALIAS_CUSTOM"
fi
fi
local tmp_file
tmp_file="$(mktemp)"
awk '
BEGIN { skip = 0 }
/^# BEGIN ALT_MYSQL_PHPMYADMIN$/ { skip = 1; next }
/^# END ALT_MYSQL_PHPMYADMIN$/ { skip = 0; next }
skip == 0 { print }
' "$APACHE_ALIAS_CUSTOM" > "$tmp_file"
cat >> "$tmp_file" <<EOF
# BEGIN ALT_MYSQL_PHPMYADMIN
Alias ${PHPMYADMIN_URL_PATH} ${PHPMYADMIN_PRIVATE_DIR}
<Directory "${PHPMYADMIN_PRIVATE_DIR}">
AllowOverride None
Options -Indexes
Require all granted
</Directory>
<Directory "${RUNTIME_DIR}">
AllowOverride None
Options -Indexes
Require all denied
</Directory>
# END ALT_MYSQL_PHPMYADMIN
EOF
mv "$tmp_file" "$APACHE_ALIAS_CUSTOM"
chmod_or_warn 644 "$APACHE_ALIAS_CUSTOM"
}
apply_apache_alias() {
if [ -x "$CB_BUILD" ]; then
(cd "$CUSTOMBUILD_DIR" && ./build rewrite_confs) || warn "rewrite_confs zakończyło się błędem - uruchom ręcznie: cd ${CUSTOMBUILD_DIR} && ./build rewrite_confs"
else
warn "Brak ${CB_BUILD} - uruchom ręcznie: cd ${CUSTOMBUILD_DIR} && ./build rewrite_confs"
fi
if command -v systemctl >/dev/null 2>&1 && systemctl is-active --quiet httpd 2>/dev/null; then
systemctl reload httpd || warn "Nie udało się przeładować httpd."
fi
}
ensure_private_copy
write_private_config
configure_apache_alias
if [ "${PHPMYADMIN_SKIP_APACHE_RELOAD:-0}" != "1" ]; then
apply_apache_alias
fi
log "Prywatna kopia phpMyAdmin dla alt-mysql jest gotowa w ${PHPMYADMIN_PRIVATE_DIR}."