Skip to content

Commit 3805a68

Browse files
committed
MDEV-27732: Add env MARIADB_MYSQL_LOCALHOST_{USER,GRANTS}
We create a mysql@localhost user under MARIADB_MYSQL_LOCALHOST_USER=1 with its default USAGE privileges. This gives access to SHOW GLOBAL STATUS/VARIABLES but no other real access including database visibility or process visibility. Being a @localhost this restricts access to via the unix socket. The level of access can be increased controlled by the environment variable MARIADB_MYSQL_LOCALHOST_GRANTS. If you are using monitoring replication or processes addition privileges are required, and the setting of the environment variable is the comma separated list of grants possible. For the moment, these are a set of global grants only. If you share the unix socket location, /var/run/mysqld by default, as a volume with another container, you have effectively given that container the mysql@localhost provided they have the same uid map or can create arbitrary users. This can be good for things like backup. This would require the datadir volume as well and the set of privileges (https://mariadb.com/kb/en/mariabackup-overview/#authentication-and-privileges). Any grants of UPDATE on mysql database will mean that the mysql@localhost user can manipulate any other user, potentially transparently adding unix_socket auth (in 10.4+), and the being able to gain their privileges. Grants of CREATE USER, or INSERT on the mysql database allow the creation of user and privilege escalation. For these reasons, ALL for MARIADB_MYSQL_LOCALHOST_GRANTS gains a warning. Many thanks to Daniel Rudolf for all the reviews and the support to develop this feature.
1 parent 01821a5 commit 3805a68

9 files changed

+264
-11
lines changed

.test/run.sh

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -116,31 +116,68 @@ killoff
116116
;&
117117
mysql_root_password_is_set)
118118

119-
echo -e "Test: MYSQL_ROOT_PASSWORD\n"
119+
echo -e "Test: MYSQL_ROOT_PASSWORD and mysql@localhost user\n"
120120

121-
runandwait -e MYSQL_ROOT_PASSWORD=examplepass "${image}"
122-
mariadbclient -u root -pexamplepass -e 'select current_user()'
123-
mariadbclient -u root -pwrongpass -e 'select current_user()' || echo 'expected failure'
124-
killoff
121+
runandwait -e MYSQL_ROOT_PASSWORD=examplepass -e MARIADB_MYSQL_LOCALHOST_USER=1 "${image}"
122+
mariadbclient -u root -pexamplepass -e 'select current_user()'
123+
mariadbclient -u root -pwrongpass -e 'select current_user()' || echo 'expected failure'
124+
125+
otherusers=$(mariadbclient -u root -pexamplepass --skip-column-names -Be "select user,host from mysql.user where (user,host) not in (('root', 'localhost'), ('root', '%'), ('mariadb.sys', 'localhost'), ('mysql','localhost'))")
126+
[ "$otherusers" != '' ] && die "unexpected users $otherusers"
127+
128+
createuser=$(docker exec --user mysql -i \
129+
"$cname" \
130+
mysql \
131+
--silent \
132+
-e "show create user")
133+
# shellcheck disable=SC2016
134+
[ "${createuser//\'/\`}" == 'CREATE USER `mysql`@`localhost` IDENTIFIED VIA unix_socket' ] || die "I wasn't created how I was expected"
135+
136+
grants="$(docker exec --user mysql -i \
137+
$cname \
138+
mysql \
139+
--silent \
140+
-e show\ grants)"
141+
142+
# shellcheck disable=SC2016
143+
[ "${grants//\'/\`}" == 'GRANT USAGE ON *.* TO `mysql`@`localhost` IDENTIFIED VIA unix_socket' ] || die "I wasn't granted what I was expected"
144+
145+
killoff
125146

126147
;&
127148
mysql_random_password_is_complex)
128149

129150
echo -e "Test: MYSQL_RANDOM_ROOT_PASSWORD, needs to satisify minimium complexity of simple-password-check plugin\n"
130151

131-
runandwait -e MYSQL_RANDOM_ROOT_PASSWORD=1 "${image}" --plugin-load-add=simple_password_check
152+
runandwait -e MYSQL_RANDOM_ROOT_PASSWORD=1 -e MARIADB_MYSQL_LOCALHOST_GRANTS="RELOAD, PROCESS, LOCK TABLES" "${image}" --plugin-load-add=simple_password_check
132153
pass=$(docker logs "$cid" | grep 'GENERATED ROOT PASSWORD' 2>&1)
133154
# trim up until passwod
134155
pass=${pass#*GENERATED ROOT PASSWORD: }
135156
mariadbclient -u root -p"${pass}" -e 'select current_user()'
136-
killoff
157+
158+
docker exec --user mysql -i \
159+
"$cname" \
160+
mysql \
161+
--silent \
162+
-e "select 'I connect therefore I am'" || die "I'd hoped to work around MDEV-24111"
163+
164+
grants="$(docker exec --user mysql -i \
165+
$cname \
166+
mysql \
167+
--silent \
168+
-e show\ grants)"
169+
170+
# shellcheck disable=SC2016
171+
[ "${grants//\'/\`}" == 'GRANT RELOAD, PROCESS, LOCK TABLES ON *.* TO `mysql`@`localhost` IDENTIFIED VIA unix_socket' ] || die "I wasn't granted what I was expected"
172+
173+
killoff
137174

138175
;&
139176
mysql_random_password_is_different)
140177

141-
echo -e "Test: second instance of MYSQL_RANDOM_ROOT_PASSWORD has a different password\n"
178+
echo -e "Test: second instance of MYSQL_RANDOM_ROOT_PASSWORD has a different password (and mysql@localhost can be created(\n"
142179

143-
runandwait -e MYSQL_RANDOM_ROOT_PASSWORD=1 "${image}" --plugin-load-add=simple_password_check
180+
runandwait -e MYSQL_RANDOM_ROOT_PASSWORD=1 -e MARIADB_MYSQL_LOCALHOST_USER=1 "${image}" --plugin-load-add=simple_password_check
144181
newpass=$(docker logs "$cid" | grep 'GENERATED ROOT PASSWORD' 2>&1)
145182
# trim up until passwod
146183
newpass=${newpass#*GENERATED ROOT PASSWORD: }
@@ -274,7 +311,7 @@ mariadbclient -u root -e 'show databases'
274311
othertables=$(mariadbclient -u root --skip-column-names -Be "select group_concat(SCHEMA_NAME) from information_schema.SCHEMATA where SCHEMA_NAME not in ('mysql', 'information_schema', 'performance_schema', 'sys')")
275312
[ "${othertables}" != 'NULL' ] && die "unexpected table(s) $othertables"
276313

277-
otherusers=$(mariadbclient -u root --skip-column-names -Be "select user,host from mysql.user where (user,host) not in (('root', 'localhost'), ('root', '%'), ('mariadb.sys', 'localhost'))")
314+
otherusers=$(mariadbclient -u root --skip-column-names -Be "select user,host from mysql.user where (user,host) not in (('root', 'localhost'), ('root', '%'), ('mariadb.sys', 'localhost'), ('mysql','localhost'))")
278315
[ "$otherusers" != '' ] && die "unexpected users $otherusers"
279316
killoff
280317

@@ -286,7 +323,7 @@ echo -e "Test: MARIADB_ROOT_PASSWORD\n"
286323
runandwait -e MARIADB_ROOT_PASSWORD=examplepass "${image}"
287324
mariadbclient -u root -pexamplepass -e 'select current_user()'
288325
mariadbclient -u root -pwrongpass -e 'select current_user()' || echo 'expected failure'
289-
killoff
326+
killoff
290327

291328
;&
292329
mariadb_root_password_is_complex)

10.2/docker-entrypoint.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,31 @@ docker_setup_db() {
295295
EOSQL
296296
fi
297297

298+
local mysqlAtLocalhost=
299+
local mysqlAtLocalhostGrants=
300+
# Install mysql@localhost user
301+
if [ -n "$MARIADB_MYSQL_LOCALHOST_USER" ] || [ -n "$MARIADB_MYSQL_LOCALHOST_GRANTS" ]; then
302+
local pw=
303+
pw="$(pwgen --numerals --capitalize --symbols --remove-chars="'\\" -1 32)"
304+
# MDEV-24111 before MariaDB-10.4 cannot create unix_socket user directly auth with simple_password_check
305+
# It wasn't until 10.4 that the unix_socket auth was built in to the server.
306+
read -r -d '' mysqlAtLocalhost <<-EOSQL || true
307+
EXECUTE IMMEDIATE IF(VERSION() RLIKE '^10\.[23]\.',
308+
"INSTALL PLUGIN /*M10401 IF NOT EXISTS */ unix_socket SONAME 'auth_socket'",
309+
"SELECT 'already there'");
310+
CREATE USER mysql@localhost IDENTIFIED BY '$pw';
311+
ALTER USER mysql@localhost IDENTIFIED VIA unix_socket;
312+
EOSQL
313+
if [ -n "$MARIADB_MYSQL_LOCALHOST_GRANTS" ]; then
314+
if [[ "$MARIADB_MYSQL_LOCALHOST_GRANTS" = ALL* ]] || \
315+
[[ "$MARIADB_MYSQL_LOCALHOST_GRANTS" = *UPDATE* ]] || \
316+
[[ "$MARIADB_MYSQL_LOCALHOST_GRANTS" = *INSERT* ]]; then
317+
mysql_warn "ALL/INSERT/UPDATE privileges ON *.* TO mysql@localhost facilitates privilege escalation, recommending limiting to required privileges"
318+
fi
319+
mysqlAtLocalhostGrants="GRANT ${MARIADB_MYSQL_LOCALHOST_GRANTS} ON *.* TO mysql@localhost;";
320+
fi
321+
fi
322+
298323
mysql_note "Securing system users (equivalent to running mysql_secure_installation)"
299324
# tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set
300325
# --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding.
@@ -310,6 +335,8 @@ docker_setup_db() {
310335
311336
SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${rootPasswordEscaped}') ;
312337
${rootCreate}
338+
${mysqlAtLocalhost}
339+
${mysqlAtLocalhostGrants}
313340
-- pre-10.3
314341
DROP DATABASE IF EXISTS test ;
315342
EOSQL

10.3/docker-entrypoint.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,31 @@ docker_setup_db() {
295295
EOSQL
296296
fi
297297

298+
local mysqlAtLocalhost=
299+
local mysqlAtLocalhostGrants=
300+
# Install mysql@localhost user
301+
if [ -n "$MARIADB_MYSQL_LOCALHOST_USER" ] || [ -n "$MARIADB_MYSQL_LOCALHOST_GRANTS" ]; then
302+
local pw=
303+
pw="$(pwgen --numerals --capitalize --symbols --remove-chars="'\\" -1 32)"
304+
# MDEV-24111 before MariaDB-10.4 cannot create unix_socket user directly auth with simple_password_check
305+
# It wasn't until 10.4 that the unix_socket auth was built in to the server.
306+
read -r -d '' mysqlAtLocalhost <<-EOSQL || true
307+
EXECUTE IMMEDIATE IF(VERSION() RLIKE '^10\.[23]\.',
308+
"INSTALL PLUGIN /*M10401 IF NOT EXISTS */ unix_socket SONAME 'auth_socket'",
309+
"SELECT 'already there'");
310+
CREATE USER mysql@localhost IDENTIFIED BY '$pw';
311+
ALTER USER mysql@localhost IDENTIFIED VIA unix_socket;
312+
EOSQL
313+
if [ -n "$MARIADB_MYSQL_LOCALHOST_GRANTS" ]; then
314+
if [[ "$MARIADB_MYSQL_LOCALHOST_GRANTS" = ALL* ]] || \
315+
[[ "$MARIADB_MYSQL_LOCALHOST_GRANTS" = *UPDATE* ]] || \
316+
[[ "$MARIADB_MYSQL_LOCALHOST_GRANTS" = *INSERT* ]]; then
317+
mysql_warn "ALL/INSERT/UPDATE privileges ON *.* TO mysql@localhost facilitates privilege escalation, recommending limiting to required privileges"
318+
fi
319+
mysqlAtLocalhostGrants="GRANT ${MARIADB_MYSQL_LOCALHOST_GRANTS} ON *.* TO mysql@localhost;";
320+
fi
321+
fi
322+
298323
mysql_note "Securing system users (equivalent to running mysql_secure_installation)"
299324
# tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set
300325
# --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding.
@@ -310,6 +335,8 @@ docker_setup_db() {
310335
311336
SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${rootPasswordEscaped}') ;
312337
${rootCreate}
338+
${mysqlAtLocalhost}
339+
${mysqlAtLocalhostGrants}
313340
-- pre-10.3
314341
DROP DATABASE IF EXISTS test ;
315342
EOSQL

10.4/docker-entrypoint.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,31 @@ docker_setup_db() {
295295
EOSQL
296296
fi
297297

298+
local mysqlAtLocalhost=
299+
local mysqlAtLocalhostGrants=
300+
# Install mysql@localhost user
301+
if [ -n "$MARIADB_MYSQL_LOCALHOST_USER" ] || [ -n "$MARIADB_MYSQL_LOCALHOST_GRANTS" ]; then
302+
local pw=
303+
pw="$(pwgen --numerals --capitalize --symbols --remove-chars="'\\" -1 32)"
304+
# MDEV-24111 before MariaDB-10.4 cannot create unix_socket user directly auth with simple_password_check
305+
# It wasn't until 10.4 that the unix_socket auth was built in to the server.
306+
read -r -d '' mysqlAtLocalhost <<-EOSQL || true
307+
EXECUTE IMMEDIATE IF(VERSION() RLIKE '^10\.[23]\.',
308+
"INSTALL PLUGIN /*M10401 IF NOT EXISTS */ unix_socket SONAME 'auth_socket'",
309+
"SELECT 'already there'");
310+
CREATE USER mysql@localhost IDENTIFIED BY '$pw';
311+
ALTER USER mysql@localhost IDENTIFIED VIA unix_socket;
312+
EOSQL
313+
if [ -n "$MARIADB_MYSQL_LOCALHOST_GRANTS" ]; then
314+
if [[ "$MARIADB_MYSQL_LOCALHOST_GRANTS" = ALL* ]] || \
315+
[[ "$MARIADB_MYSQL_LOCALHOST_GRANTS" = *UPDATE* ]] || \
316+
[[ "$MARIADB_MYSQL_LOCALHOST_GRANTS" = *INSERT* ]]; then
317+
mysql_warn "ALL/INSERT/UPDATE privileges ON *.* TO mysql@localhost facilitates privilege escalation, recommending limiting to required privileges"
318+
fi
319+
mysqlAtLocalhostGrants="GRANT ${MARIADB_MYSQL_LOCALHOST_GRANTS} ON *.* TO mysql@localhost;";
320+
fi
321+
fi
322+
298323
mysql_note "Securing system users (equivalent to running mysql_secure_installation)"
299324
# tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set
300325
# --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding.
@@ -310,6 +335,8 @@ docker_setup_db() {
310335
311336
SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${rootPasswordEscaped}') ;
312337
${rootCreate}
338+
${mysqlAtLocalhost}
339+
${mysqlAtLocalhostGrants}
313340
-- pre-10.3
314341
DROP DATABASE IF EXISTS test ;
315342
EOSQL

10.5/docker-entrypoint.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,31 @@ docker_setup_db() {
295295
EOSQL
296296
fi
297297

298+
local mysqlAtLocalhost=
299+
local mysqlAtLocalhostGrants=
300+
# Install mysql@localhost user
301+
if [ -n "$MARIADB_MYSQL_LOCALHOST_USER" ] || [ -n "$MARIADB_MYSQL_LOCALHOST_GRANTS" ]; then
302+
local pw=
303+
pw="$(pwgen --numerals --capitalize --symbols --remove-chars="'\\" -1 32)"
304+
# MDEV-24111 before MariaDB-10.4 cannot create unix_socket user directly auth with simple_password_check
305+
# It wasn't until 10.4 that the unix_socket auth was built in to the server.
306+
read -r -d '' mysqlAtLocalhost <<-EOSQL || true
307+
EXECUTE IMMEDIATE IF(VERSION() RLIKE '^10\.[23]\.',
308+
"INSTALL PLUGIN /*M10401 IF NOT EXISTS */ unix_socket SONAME 'auth_socket'",
309+
"SELECT 'already there'");
310+
CREATE USER mysql@localhost IDENTIFIED BY '$pw';
311+
ALTER USER mysql@localhost IDENTIFIED VIA unix_socket;
312+
EOSQL
313+
if [ -n "$MARIADB_MYSQL_LOCALHOST_GRANTS" ]; then
314+
if [[ "$MARIADB_MYSQL_LOCALHOST_GRANTS" = ALL* ]] || \
315+
[[ "$MARIADB_MYSQL_LOCALHOST_GRANTS" = *UPDATE* ]] || \
316+
[[ "$MARIADB_MYSQL_LOCALHOST_GRANTS" = *INSERT* ]]; then
317+
mysql_warn "ALL/INSERT/UPDATE privileges ON *.* TO mysql@localhost facilitates privilege escalation, recommending limiting to required privileges"
318+
fi
319+
mysqlAtLocalhostGrants="GRANT ${MARIADB_MYSQL_LOCALHOST_GRANTS} ON *.* TO mysql@localhost;";
320+
fi
321+
fi
322+
298323
mysql_note "Securing system users (equivalent to running mysql_secure_installation)"
299324
# tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set
300325
# --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding.
@@ -310,6 +335,8 @@ docker_setup_db() {
310335
311336
SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${rootPasswordEscaped}') ;
312337
${rootCreate}
338+
${mysqlAtLocalhost}
339+
${mysqlAtLocalhostGrants}
313340
-- pre-10.3
314341
DROP DATABASE IF EXISTS test ;
315342
EOSQL

10.6/docker-entrypoint.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,31 @@ docker_setup_db() {
295295
EOSQL
296296
fi
297297

298+
local mysqlAtLocalhost=
299+
local mysqlAtLocalhostGrants=
300+
# Install mysql@localhost user
301+
if [ -n "$MARIADB_MYSQL_LOCALHOST_USER" ] || [ -n "$MARIADB_MYSQL_LOCALHOST_GRANTS" ]; then
302+
local pw=
303+
pw="$(pwgen --numerals --capitalize --symbols --remove-chars="'\\" -1 32)"
304+
# MDEV-24111 before MariaDB-10.4 cannot create unix_socket user directly auth with simple_password_check
305+
# It wasn't until 10.4 that the unix_socket auth was built in to the server.
306+
read -r -d '' mysqlAtLocalhost <<-EOSQL || true
307+
EXECUTE IMMEDIATE IF(VERSION() RLIKE '^10\.[23]\.',
308+
"INSTALL PLUGIN /*M10401 IF NOT EXISTS */ unix_socket SONAME 'auth_socket'",
309+
"SELECT 'already there'");
310+
CREATE USER mysql@localhost IDENTIFIED BY '$pw';
311+
ALTER USER mysql@localhost IDENTIFIED VIA unix_socket;
312+
EOSQL
313+
if [ -n "$MARIADB_MYSQL_LOCALHOST_GRANTS" ]; then
314+
if [[ "$MARIADB_MYSQL_LOCALHOST_GRANTS" = ALL* ]] || \
315+
[[ "$MARIADB_MYSQL_LOCALHOST_GRANTS" = *UPDATE* ]] || \
316+
[[ "$MARIADB_MYSQL_LOCALHOST_GRANTS" = *INSERT* ]]; then
317+
mysql_warn "ALL/INSERT/UPDATE privileges ON *.* TO mysql@localhost facilitates privilege escalation, recommending limiting to required privileges"
318+
fi
319+
mysqlAtLocalhostGrants="GRANT ${MARIADB_MYSQL_LOCALHOST_GRANTS} ON *.* TO mysql@localhost;";
320+
fi
321+
fi
322+
298323
mysql_note "Securing system users (equivalent to running mysql_secure_installation)"
299324
# tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set
300325
# --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding.
@@ -310,6 +335,8 @@ docker_setup_db() {
310335
311336
SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${rootPasswordEscaped}') ;
312337
${rootCreate}
338+
${mysqlAtLocalhost}
339+
${mysqlAtLocalhostGrants}
313340
-- pre-10.3
314341
DROP DATABASE IF EXISTS test ;
315342
EOSQL

10.7/docker-entrypoint.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,31 @@ docker_setup_db() {
295295
EOSQL
296296
fi
297297

298+
local mysqlAtLocalhost=
299+
local mysqlAtLocalhostGrants=
300+
# Install mysql@localhost user
301+
if [ -n "$MARIADB_MYSQL_LOCALHOST_USER" ] || [ -n "$MARIADB_MYSQL_LOCALHOST_GRANTS" ]; then
302+
local pw=
303+
pw="$(pwgen --numerals --capitalize --symbols --remove-chars="'\\" -1 32)"
304+
# MDEV-24111 before MariaDB-10.4 cannot create unix_socket user directly auth with simple_password_check
305+
# It wasn't until 10.4 that the unix_socket auth was built in to the server.
306+
read -r -d '' mysqlAtLocalhost <<-EOSQL || true
307+
EXECUTE IMMEDIATE IF(VERSION() RLIKE '^10\.[23]\.',
308+
"INSTALL PLUGIN /*M10401 IF NOT EXISTS */ unix_socket SONAME 'auth_socket'",
309+
"SELECT 'already there'");
310+
CREATE USER mysql@localhost IDENTIFIED BY '$pw';
311+
ALTER USER mysql@localhost IDENTIFIED VIA unix_socket;
312+
EOSQL
313+
if [ -n "$MARIADB_MYSQL_LOCALHOST_GRANTS" ]; then
314+
if [[ "$MARIADB_MYSQL_LOCALHOST_GRANTS" = ALL* ]] || \
315+
[[ "$MARIADB_MYSQL_LOCALHOST_GRANTS" = *UPDATE* ]] || \
316+
[[ "$MARIADB_MYSQL_LOCALHOST_GRANTS" = *INSERT* ]]; then
317+
mysql_warn "ALL/INSERT/UPDATE privileges ON *.* TO mysql@localhost facilitates privilege escalation, recommending limiting to required privileges"
318+
fi
319+
mysqlAtLocalhostGrants="GRANT ${MARIADB_MYSQL_LOCALHOST_GRANTS} ON *.* TO mysql@localhost;";
320+
fi
321+
fi
322+
298323
mysql_note "Securing system users (equivalent to running mysql_secure_installation)"
299324
# tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set
300325
# --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding.
@@ -310,6 +335,8 @@ docker_setup_db() {
310335
311336
SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${rootPasswordEscaped}') ;
312337
${rootCreate}
338+
${mysqlAtLocalhost}
339+
${mysqlAtLocalhostGrants}
313340
-- pre-10.3
314341
DROP DATABASE IF EXISTS test ;
315342
EOSQL

10.8/docker-entrypoint.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,31 @@ docker_setup_db() {
295295
EOSQL
296296
fi
297297

298+
local mysqlAtLocalhost=
299+
local mysqlAtLocalhostGrants=
300+
# Install mysql@localhost user
301+
if [ -n "$MARIADB_MYSQL_LOCALHOST_USER" ] || [ -n "$MARIADB_MYSQL_LOCALHOST_GRANTS" ]; then
302+
local pw=
303+
pw="$(pwgen --numerals --capitalize --symbols --remove-chars="'\\" -1 32)"
304+
# MDEV-24111 before MariaDB-10.4 cannot create unix_socket user directly auth with simple_password_check
305+
# It wasn't until 10.4 that the unix_socket auth was built in to the server.
306+
read -r -d '' mysqlAtLocalhost <<-EOSQL || true
307+
EXECUTE IMMEDIATE IF(VERSION() RLIKE '^10\.[23]\.',
308+
"INSTALL PLUGIN /*M10401 IF NOT EXISTS */ unix_socket SONAME 'auth_socket'",
309+
"SELECT 'already there'");
310+
CREATE USER mysql@localhost IDENTIFIED BY '$pw';
311+
ALTER USER mysql@localhost IDENTIFIED VIA unix_socket;
312+
EOSQL
313+
if [ -n "$MARIADB_MYSQL_LOCALHOST_GRANTS" ]; then
314+
if [[ "$MARIADB_MYSQL_LOCALHOST_GRANTS" = ALL* ]] || \
315+
[[ "$MARIADB_MYSQL_LOCALHOST_GRANTS" = *UPDATE* ]] || \
316+
[[ "$MARIADB_MYSQL_LOCALHOST_GRANTS" = *INSERT* ]]; then
317+
mysql_warn "ALL/INSERT/UPDATE privileges ON *.* TO mysql@localhost facilitates privilege escalation, recommending limiting to required privileges"
318+
fi
319+
mysqlAtLocalhostGrants="GRANT ${MARIADB_MYSQL_LOCALHOST_GRANTS} ON *.* TO mysql@localhost;";
320+
fi
321+
fi
322+
298323
mysql_note "Securing system users (equivalent to running mysql_secure_installation)"
299324
# tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set
300325
# --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding.
@@ -310,6 +335,8 @@ docker_setup_db() {
310335
311336
SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${rootPasswordEscaped}') ;
312337
${rootCreate}
338+
${mysqlAtLocalhost}
339+
${mysqlAtLocalhostGrants}
313340
-- pre-10.3
314341
DROP DATABASE IF EXISTS test ;
315342
EOSQL

0 commit comments

Comments
 (0)