Fix phpMyAdmin SSO ticket group ownership under SuExec (webapps)

Live testing on a real DirectAdmin/CustomBuild server showed the Apache
alias fix alone wasn't enough: the default vhost serving /var/www/html
uses `SuexecUserGroup webapps webapps`, so PHP for the private phpMyAdmin
copy actually executes as user/group "webapps" - not as Apache's own
httpd.conf "Group" (typically "apache"), which is what
detect_apache_group() was reading. SSO ticket files ended up owned
root:apache with mode 0640, unreadable by the webapps-executing
da_login.php, producing "The phpMyAdmin login ticket is not available
or has already been used." even though the ticket really was written.

detect_apache_group() now checks the default vhost's SuexecUserGroup
directive first (the actual PHP-execution identity under SuExec), and
only falls back to the plain Apache Group directive when no
SuexecUserGroup is configured.

Bump version to 1.2.13 and rebuild the release archive.
This commit is contained in:
Marek Miklewicz
2026-07-04 20:05:14 +02:00
parent ba64342702
commit abbeaf67ec
5 changed files with 50 additions and 6 deletions
+1 -1
View File
@@ -2,7 +2,7 @@ name=alt-mysql
id=alt-mysql
type=user
author=HITME.PL
version=1.2.12
version=1.2.13
active=no
installed=no
user_run_as=root
+14 -2
View File
@@ -14,6 +14,8 @@ 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"
@@ -57,8 +59,18 @@ chmod_or_warn() {
detect_apache_group() {
local group_name=""
if [ -f /etc/httpd/conf/httpd.conf ]; then
group_name="$(awk 'tolower($1)=="group" {print $2; exit}' /etc/httpd/conf/httpd.conf | tr -d '[:space:]')"
# 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
+2 -2
View File
@@ -2,7 +2,7 @@
set -euo pipefail
PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)"
ARCHIVE="${1:-$(cd "$PLUGIN_DIR/.." && pwd)/archives/1.2.12/alt-mysql.tar.gz}"
ARCHIVE="${1:-$(cd "$PLUGIN_DIR/.." && pwd)/archives/1.2.13/alt-mysql.tar.gz}"
fail() {
echo "FAIL: $*" >&2
@@ -37,7 +37,7 @@ fi
CONF="$(tar -xOzf "$ARCHIVE" ./plugin.conf 2>/dev/null || tar -xOzf "$ARCHIVE" plugin.conf)"
printf '%s\n' "$CONF" | grep -Fxq "name=alt-mysql" || fail "archive plugin name is not alt-mysql"
printf '%s\n' "$CONF" | grep -Fxq "id=alt-mysql" || fail "archive plugin id is not alt-mysql"
printf '%s\n' "$CONF" | grep -Fxq "version=1.2.12" || fail "archive plugin version is not 1.2.12"
printf '%s\n' "$CONF" | grep -Fxq "version=1.2.13" || fail "archive plugin version is not 1.2.13"
SETTINGS="$(tar -xOzf "$ARCHIVE" ./plugin-settings.conf 2>/dev/null || tar -xOzf "$ARCHIVE" plugin-settings.conf)"
printf '%s\n' "$SETTINGS" | grep -Fxq "PHPMYADMIN_INSTALL_DIR=/var/www/html/alt-mysql-phpmyadmin" \
+32
View File
@@ -59,6 +59,38 @@ bash "$SCRIPT" >/dev/null
BEGIN_COUNT="$(grep -Fc "# BEGIN ALT_MYSQL_PHPMYADMIN" "$ALIAS_CONF" || true)"
[ "$BEGIN_COUNT" -eq 1 ] || fail "Apache alias block was duplicated on re-run (found $BEGIN_COUNT times)"
# Under SuExec (DirectAdmin's default vhost convention), PHP for the shared
# /var/www/html vhost executes as the SuexecUserGroup account (e.g. "webapps"),
# not as Apache's own httpd.conf "Group" (e.g. "apache"). Ticket files must be
# group-owned by whichever account actually executes PHP there, or phpMyAdmin's
# da_login.php cannot read them.
FAKE_HTTPD_CONF="$TMP_DIR/httpd.conf"
cat > "$FAKE_HTTPD_CONF" <<'EOF'
User apache
Group apache
EOF
FAKE_VHOSTS_CONF="$TMP_DIR/httpd-vhosts.conf"
cat > "$FAKE_VHOSTS_CONF" <<'EOF'
<VirtualHost 127.0.0.1:80>
DocumentRoot /var/www/html
SuexecUserGroup webapps webapps
</VirtualHost>
EOF
SUEXEC_CUSTOMBUILD_DIR="$TMP_DIR/custombuild-suexec"
mkdir -p "$SUEXEC_CUSTOMBUILD_DIR"
SUEXEC_STDERR="$TMP_DIR/suexec-install.stderr"
PHPMYADMIN_PRIVATE_DIR="$TMP_DIR/alt-mysql-phpmyadmin-suexec" \
PHPMYADMIN_SOURCE_DIR="$TMP_DIR/phpMyAdmin-source" \
PHPMYADMIN_INSTALL_ASSUME_ROOT=1 \
CUSTOMBUILD_DIR="$SUEXEC_CUSTOMBUILD_DIR" \
APACHE_HTTPD_CONF="$FAKE_HTTPD_CONF" \
APACHE_VHOSTS_CONF="$FAKE_VHOSTS_CONF" \
bash "$SCRIPT" >/dev/null 2>"$SUEXEC_STDERR"
grep -Fq "diradmin:webapps" "$SUEXEC_STDERR" \
|| fail "phpMyAdmin installer must chown the runtime/tickets dirs to the SuexecUserGroup account (webapps), not Apache's own Group (apache). stderr was: $(cat "$SUEXEC_STDERR")"
SERVER_JSON="$(php -r '
$_SERVER["HTTPS"] = "on";
$_SERVER["HTTP_HOST"] = "panel.example.test";
+1 -1
View File
@@ -14,7 +14,7 @@ case "$(basename "$PLUGIN_DIR")" in
esac
grep -Fxq "name=alt-mysql" "$PLUGIN_DIR/plugin.conf" || fail "plugin.conf name is not alt-mysql"
grep -Fxq "id=alt-mysql" "$PLUGIN_DIR/plugin.conf" || fail "plugin.conf id is not alt-mysql"
grep -Fxq "version=1.2.12" "$PLUGIN_DIR/plugin.conf" || fail "plugin.conf version is not 1.2.12"
grep -Fxq "version=1.2.13" "$PLUGIN_DIR/plugin.conf" || fail "plugin.conf version is not 1.2.13"
grep -Fq "return '/CMD_PLUGINS/alt-mysql';" "$PLUGIN_DIR/exec/lib/AppContext.php" \
|| fail "AppContext base URL is not alt-mysql"
grep -Fq "\$pluginId = 'alt-mysql';" "$PLUGIN_DIR/exec/lib/DirectAdminUser.php" \