Merge branch 'master' into next

This commit is contained in:
Daniel Black 2022-09-23 13:18:12 +10:00
commit dfaba17cd4
12 changed files with 673 additions and 482 deletions

View File

@ -1,4 +1,5 @@
#!/bin/sh #!/bin/sh
mysql -u "${MARIADB_USER:-$MYSQL_USER}" -p"${MARIADB_PASSWORD:-$MYSQL_PASSWORD}" \ PASS="${MARIADB_PASSWORD:-$MYSQL_PASSWORD}"
mysql -u "${MARIADB_USER:-$MYSQL_USER}" -p"${PASS}" \
-e 'create table t1 (i int unsigned primary key not null)' \ -e 'create table t1 (i int unsigned primary key not null)' \
"${MARIADB_DATABASE:-$MYSQL_DATABASE}" "${MARIADB_DATABASE:-$MYSQL_DATABASE}"

View File

@ -199,6 +199,16 @@ echo -e "Test: MYSQL_ROOT_HOST\n"
runandwait -e MYSQL_ALLOW_EMPTY_PASSWORD=1 -e MYSQL_ROOT_HOST=apple "${image}" runandwait -e MYSQL_ALLOW_EMPTY_PASSWORD=1 -e MYSQL_ROOT_HOST=apple "${image}"
ru=$(mariadbclient_unix --skip-column-names -B -u root -e 'select user,host from mysql.user where host="apple"') ru=$(mariadbclient_unix --skip-column-names -B -u root -e 'select user,host from mysql.user where host="apple"')
[ "${ru}" = '' ] && die 'root@apple not created' [ "${ru}" = '' ] && die 'root@apple not created'
killoff
;&
mysql_root_host_localhost)
echo -e "Test: MYSQL_ROOT_HOST=localhost\n"
runandwait -e MARIADB_ROOT_PASSWORD=bob -e MYSQL_ROOT_HOST=localhost "${image}"
ru=$(mariadbclient_unix --skip-column-names -B -u root -pbob -e 'select user,host from mysql.user where user="root" and host="localhost"')
[ "${ru}" = '' ] && die 'root@localhost not created'
killoff killoff
;& ;&
@ -591,10 +601,28 @@ binlog)
echo -e "Test: create user passwords using password hash\n" echo -e "Test: create user passwords using password hash\n"
runandwait -e MARIADB_ROOT_PASSWORD_HASH='*61584B76F6ECE8FB9A328E7CF198094B2FAC55C7' -e MARIADB_PASSWORD_HASH='*0FD9A3F0F816D076CF239580A68A1147C250EB7B' -e MARIADB_DATABASE=neptune -e MARIADB_USER=henry "${image}" initdb=$(mktemp -d)
chmod go+rx "${initdb}"
cp -a "$dir"/initdb.d/* "${initdb}"
sed -i -e 's/^PASS=.*/PASS=jane/' "${initdb}"/a_first.sh
gzip "${initdb}"/*gz*
xz "${initdb}"/*xz*
zstd "${initdb}"/*zst*
runandwait -e MARIADB_ROOT_PASSWORD_HASH='*61584B76F6ECE8FB9A328E7CF198094B2FAC55C7' \
-e MARIADB_PASSWORD_HASH='*0FD9A3F0F816D076CF239580A68A1147C250EB7B' \
-e MARIADB_DATABASE=neptune \
-e MARIADB_USER=henry \
-v "${initdb}":/docker-entrypoint-initdb.d:Z \
"${image}"
mariadbclient -u root -pbob -e 'select current_user()' mariadbclient -u root -pbob -e 'select current_user()'
mariadbclient_unix -u root -pbob -e 'select current_user()'
mariadbclient -u henry -pjane neptune -e 'select current_user()' mariadbclient -u henry -pjane neptune -e 'select current_user()'
init_sum=$(mariadbclient --skip-column-names -B -u henry -pjane -P 3306 -h 127.0.0.1 --protocol tcp neptune -e "select sum(i) from t1;")
[ "${init_sum}" = '1833' ] || (podman logs m_init; die 'initialization order error')
killoff killoff
rm -rf "${initdb}"
# Insert new tests above by copying the comments below # Insert new tests above by copying the comments below
# ;& # ;&
@ -605,3 +633,5 @@ binlog)
echo "Test $2 not found" >&2 echo "Test $2 not found" >&2
exit 1 exit 1
esac esac
echo "Tests finished"

View File

@ -147,9 +147,8 @@ docker_temp_server_start() {
# Stop the server. When using a local socket file mariadb-admin will block until # Stop the server. When using a local socket file mariadb-admin will block until
# the shutdown is complete. # the shutdown is complete.
docker_temp_server_stop() { docker_temp_server_stop() {
if ! MYSQL_PWD=$MARIADB_ROOT_PASSWORD mariadb-admin shutdown -uroot --socket="${SOCKET}"; then kill "$MARIADB_PID"
mysql_error "Unable to shut down server." wait "$MARIADB_PID"
fi
} }
# Verify that the minimally required password settings are set for new databases. # Verify that the minimally required password settings are set for new databases.
@ -291,22 +290,24 @@ docker_setup_db() {
# Creates root users for non-localhost hosts # Creates root users for non-localhost hosts
local rootCreate= local rootCreate=
local rootPasswordEscaped=
if [ -n "$MARIADB_ROOT_PASSWORD" ]; then
# Sets root password and creates root users for non-localhost hosts
rootPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_ROOT_PASSWORD}" )
fi
# default root to listen for connections from anywhere # default root to listen for connections from anywhere
if [ -n "$MARIADB_ROOT_HOST" ] && [ "$MARIADB_ROOT_HOST" != 'localhost' ]; then if [ -n "$MARIADB_ROOT_HOST" ] && [ "$MARIADB_ROOT_HOST" != 'localhost' ]; then
if [ -n "$MARIADB_ROOT_PASSWORD" ]; then # ref "read -d ''", no, we don't care if read finds a terminating character in this heredoc
# Sets root password and creates root users for non-localhost hosts # https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
local rootPasswordEscaped if [ -n "$MARIADB_ROOT_PASSWORD_HASH" ]; then
rootPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_ROOT_PASSWORD}" )
# no, we don't care if read finds a terminating character in this heredoc
# https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
read -r -d '' rootCreate <<-EOSQL || true read -r -d '' rootCreate <<-EOSQL || true
CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY '${rootPasswordEscaped}' ; CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY PASSWORD '${MARIADB_ROOT_PASSWORD_HASH}' ;
GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ; GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ;
EOSQL EOSQL
else else
read -r -d '' rootCreate <<-EOSQL || true read -r -d '' rootCreate <<-EOSQL || true
CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY PASSWORD '${MARIADB_ROOT_PASSWORD_HASH}' ; CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY '${rootPasswordEscaped}' ;
GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ; GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ;
EOSQL EOSQL
fi fi
@ -335,12 +336,44 @@ docker_setup_db() {
fi fi
fi fi
local rootLocalhostPass=
if [ -z "$MARIADB_ROOT_PASSWORD_HASH" ]; then
# handle MARIADB_ROOT_PASSWORD_HASH for root@localhost after /docker-entrypoint-initdb.d
rootLocalhostPass="SET PASSWORD FOR 'root'@'localhost'= PASSWORD('${rootPasswordEscaped}');"
fi
local createDatabase=
# Creates a custom database and user if specified
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Creating database ${MARIADB_DATABASE}"
createDatabase="CREATE DATABASE IF NOT EXISTS \`$MARIADB_DATABASE\`;"
fi
local createUser=
local userGrants=
if [ -n "$MARIADB_PASSWORD" ] || [ -n "$MARIADB_PASSWORD_HASH" ] && [ -n "$MARIADB_USER" ]; then
mysql_note "Creating user ${MARIADB_USER}"
if [ -n "$MARIADB_PASSWORD_HASH" ]; then
createUser="CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY PASSWORD '$MARIADB_PASSWORD_HASH';"
else
# SQL escape the user password, \ followed by '
local userPasswordEscaped
userPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_PASSWORD}" )
createUser="CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$userPasswordEscaped';"
fi
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Giving user ${MARIADB_USER} access to schema ${MARIADB_DATABASE}"
userGrants="GRANT ALL ON \`${MARIADB_DATABASE//_/\\_}\`.* TO '$MARIADB_USER'@'%';"
fi
fi
mysql_note "Securing system users (equivalent to running mysql_secure_installation)" mysql_note "Securing system users (equivalent to running mysql_secure_installation)"
# tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set # tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set
# --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding. # --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding.
docker_process_sql --dont-use-mysql-root-password --database=mysql --binary-mode <<-EOSQL docker_process_sql --dont-use-mysql-root-password --database=mysql --binary-mode <<-EOSQL
-- What's done in this file shouldn't be replicated -- Securing system users shouldn't be replicated
-- or products like mysql-fabric won't work SET @orig_sql_log_bin= @@SESSION.SQL_LOG_BIN;
SET @@SESSION.SQL_LOG_BIN=0; SET @@SESSION.SQL_LOG_BIN=0;
-- we need the SQL_MODE NO_BACKSLASH_ESCAPES mode to be clear for the password to be set -- we need the SQL_MODE NO_BACKSLASH_ESCAPES mode to be clear for the password to be set
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', ''); SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
@ -348,42 +381,19 @@ docker_setup_db() {
DROP USER IF EXISTS root@'127.0.0.1', root@'::1'; DROP USER IF EXISTS root@'127.0.0.1', root@'::1';
EXECUTE IMMEDIATE CONCAT('DROP USER IF EXISTS root@\'', @@hostname,'\''); EXECUTE IMMEDIATE CONCAT('DROP USER IF EXISTS root@\'', @@hostname,'\'');
SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${rootPasswordEscaped}') ; ${rootLocalhostPass}
${rootCreate} ${rootCreate}
${mysqlAtLocalhost} ${mysqlAtLocalhost}
${mysqlAtLocalhostGrants} ${mysqlAtLocalhostGrants}
-- pre-10.3 -- pre-10.3 only
DROP DATABASE IF EXISTS test ; DROP DATABASE IF EXISTS test ;
-- end of securing system users, rest of init now...
SET @@SESSION.SQL_LOG_BIN=@orig_sql_log_bin;
-- create users/databases
${createDatabase}
${createUser}
${userGrants}
EOSQL EOSQL
# Creates a custom database and user if specified
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Creating database ${MARIADB_DATABASE}"
docker_process_sql --database=mysql <<<"CREATE DATABASE IF NOT EXISTS \`$MARIADB_DATABASE\` ;"
fi
if [ -n "$MARIADB_PASSWORD" ] || [ -n "$MARIADB_PASSWORD_HASH" ] && [ -n "$MARIADB_USER" ]; then
mysql_note "Creating user ${MARIADB_USER}"
if [ -n "$MARIADB_PASSWORD" ]; then
# SQL escape the user password, \ followed by '
local userPasswordEscaped
userPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_PASSWORD}" )
docker_process_sql --database=mysql --binary-mode <<-EOSQL_USER
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$userPasswordEscaped';
EOSQL_USER
else
docker_process_sql --database=mysql --binary-mode <<-EOSQL_USER
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY PASSWORD '$MARIADB_PASSWORD_HASH';
EOSQL_USER
fi
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Giving user ${MARIADB_USER} access to schema ${MARIADB_DATABASE}"
docker_process_sql --database=mysql <<<"GRANT ALL ON \`${MARIADB_DATABASE//_/\\_}\`.* TO '$MARIADB_USER'@'%' ;"
fi
fi
} }
# backup the mysql database # backup the mysql database
@ -430,11 +440,8 @@ docker_mariadb_upgrade() {
mariadb-upgrade --upgrade-system-tables mariadb-upgrade --upgrade-system-tables
mysql_note "Finished mariadb-upgrade" mysql_note "Finished mariadb-upgrade"
# docker_temp_server_stop needs authentication since
# upgrade ended in FLUSH PRIVILEGES
mysql_note "Stopping temporary server" mysql_note "Stopping temporary server"
kill "$MARIADB_PID" docker_temp_server_stop
wait "$MARIADB_PID"
mysql_note "Temporary server stopped" mysql_note "Temporary server stopped"
} }
@ -509,6 +516,15 @@ _main() {
docker_setup_db docker_setup_db
docker_process_init_files /docker-entrypoint-initdb.d/* docker_process_init_files /docker-entrypoint-initdb.d/*
# Wait until after /docker-entrypoint-initdb.d is performed before setting
# root@localhost password to a hash we don't know the password for.
if [ -n "${MARIADB_ROOT_PASSWORD_HASH}" ]; then
mysql_note "Setting root@localhost password hash"
docker_process_sql --dont-use-mysql-root-password --binary-mode <<-EOSQL
SET @@SESSION.SQL_LOG_BIN=0;
SET PASSWORD FOR 'root'@'localhost'= '${MARIADB_ROOT_PASSWORD_HASH}';
EOSQL
fi
mysql_note "Stopping temporary server" mysql_note "Stopping temporary server"
docker_temp_server_stop docker_temp_server_stop

View File

@ -147,9 +147,8 @@ docker_temp_server_start() {
# Stop the server. When using a local socket file mariadb-admin will block until # Stop the server. When using a local socket file mariadb-admin will block until
# the shutdown is complete. # the shutdown is complete.
docker_temp_server_stop() { docker_temp_server_stop() {
if ! MYSQL_PWD=$MARIADB_ROOT_PASSWORD mariadb-admin shutdown -uroot --socket="${SOCKET}"; then kill "$MARIADB_PID"
mysql_error "Unable to shut down server." wait "$MARIADB_PID"
fi
} }
# Verify that the minimally required password settings are set for new databases. # Verify that the minimally required password settings are set for new databases.
@ -291,22 +290,24 @@ docker_setup_db() {
# Creates root users for non-localhost hosts # Creates root users for non-localhost hosts
local rootCreate= local rootCreate=
local rootPasswordEscaped=
if [ -n "$MARIADB_ROOT_PASSWORD" ]; then
# Sets root password and creates root users for non-localhost hosts
rootPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_ROOT_PASSWORD}" )
fi
# default root to listen for connections from anywhere # default root to listen for connections from anywhere
if [ -n "$MARIADB_ROOT_HOST" ] && [ "$MARIADB_ROOT_HOST" != 'localhost' ]; then if [ -n "$MARIADB_ROOT_HOST" ] && [ "$MARIADB_ROOT_HOST" != 'localhost' ]; then
if [ -n "$MARIADB_ROOT_PASSWORD" ]; then # ref "read -d ''", no, we don't care if read finds a terminating character in this heredoc
# Sets root password and creates root users for non-localhost hosts # https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
local rootPasswordEscaped if [ -n "$MARIADB_ROOT_PASSWORD_HASH" ]; then
rootPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_ROOT_PASSWORD}" )
# no, we don't care if read finds a terminating character in this heredoc
# https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
read -r -d '' rootCreate <<-EOSQL || true read -r -d '' rootCreate <<-EOSQL || true
CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY '${rootPasswordEscaped}' ; CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY PASSWORD '${MARIADB_ROOT_PASSWORD_HASH}' ;
GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ; GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ;
EOSQL EOSQL
else else
read -r -d '' rootCreate <<-EOSQL || true read -r -d '' rootCreate <<-EOSQL || true
CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY PASSWORD '${MARIADB_ROOT_PASSWORD_HASH}' ; CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY '${rootPasswordEscaped}' ;
GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ; GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ;
EOSQL EOSQL
fi fi
@ -335,12 +336,44 @@ docker_setup_db() {
fi fi
fi fi
local rootLocalhostPass=
if [ -z "$MARIADB_ROOT_PASSWORD_HASH" ]; then
# handle MARIADB_ROOT_PASSWORD_HASH for root@localhost after /docker-entrypoint-initdb.d
rootLocalhostPass="SET PASSWORD FOR 'root'@'localhost'= PASSWORD('${rootPasswordEscaped}');"
fi
local createDatabase=
# Creates a custom database and user if specified
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Creating database ${MARIADB_DATABASE}"
createDatabase="CREATE DATABASE IF NOT EXISTS \`$MARIADB_DATABASE\`;"
fi
local createUser=
local userGrants=
if [ -n "$MARIADB_PASSWORD" ] || [ -n "$MARIADB_PASSWORD_HASH" ] && [ -n "$MARIADB_USER" ]; then
mysql_note "Creating user ${MARIADB_USER}"
if [ -n "$MARIADB_PASSWORD_HASH" ]; then
createUser="CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY PASSWORD '$MARIADB_PASSWORD_HASH';"
else
# SQL escape the user password, \ followed by '
local userPasswordEscaped
userPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_PASSWORD}" )
createUser="CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$userPasswordEscaped';"
fi
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Giving user ${MARIADB_USER} access to schema ${MARIADB_DATABASE}"
userGrants="GRANT ALL ON \`${MARIADB_DATABASE//_/\\_}\`.* TO '$MARIADB_USER'@'%';"
fi
fi
mysql_note "Securing system users (equivalent to running mysql_secure_installation)" mysql_note "Securing system users (equivalent to running mysql_secure_installation)"
# tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set # tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set
# --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding. # --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding.
docker_process_sql --dont-use-mysql-root-password --database=mysql --binary-mode <<-EOSQL docker_process_sql --dont-use-mysql-root-password --database=mysql --binary-mode <<-EOSQL
-- What's done in this file shouldn't be replicated -- Securing system users shouldn't be replicated
-- or products like mysql-fabric won't work SET @orig_sql_log_bin= @@SESSION.SQL_LOG_BIN;
SET @@SESSION.SQL_LOG_BIN=0; SET @@SESSION.SQL_LOG_BIN=0;
-- we need the SQL_MODE NO_BACKSLASH_ESCAPES mode to be clear for the password to be set -- we need the SQL_MODE NO_BACKSLASH_ESCAPES mode to be clear for the password to be set
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', ''); SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
@ -348,42 +381,19 @@ docker_setup_db() {
DROP USER IF EXISTS root@'127.0.0.1', root@'::1'; DROP USER IF EXISTS root@'127.0.0.1', root@'::1';
EXECUTE IMMEDIATE CONCAT('DROP USER IF EXISTS root@\'', @@hostname,'\''); EXECUTE IMMEDIATE CONCAT('DROP USER IF EXISTS root@\'', @@hostname,'\'');
SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${rootPasswordEscaped}') ; ${rootLocalhostPass}
${rootCreate} ${rootCreate}
${mysqlAtLocalhost} ${mysqlAtLocalhost}
${mysqlAtLocalhostGrants} ${mysqlAtLocalhostGrants}
-- pre-10.3 -- pre-10.3 only
DROP DATABASE IF EXISTS test ; DROP DATABASE IF EXISTS test ;
-- end of securing system users, rest of init now...
SET @@SESSION.SQL_LOG_BIN=@orig_sql_log_bin;
-- create users/databases
${createDatabase}
${createUser}
${userGrants}
EOSQL EOSQL
# Creates a custom database and user if specified
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Creating database ${MARIADB_DATABASE}"
docker_process_sql --database=mysql <<<"CREATE DATABASE IF NOT EXISTS \`$MARIADB_DATABASE\` ;"
fi
if [ -n "$MARIADB_PASSWORD" ] || [ -n "$MARIADB_PASSWORD_HASH" ] && [ -n "$MARIADB_USER" ]; then
mysql_note "Creating user ${MARIADB_USER}"
if [ -n "$MARIADB_PASSWORD" ]; then
# SQL escape the user password, \ followed by '
local userPasswordEscaped
userPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_PASSWORD}" )
docker_process_sql --database=mysql --binary-mode <<-EOSQL_USER
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$userPasswordEscaped';
EOSQL_USER
else
docker_process_sql --database=mysql --binary-mode <<-EOSQL_USER
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY PASSWORD '$MARIADB_PASSWORD_HASH';
EOSQL_USER
fi
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Giving user ${MARIADB_USER} access to schema ${MARIADB_DATABASE}"
docker_process_sql --database=mysql <<<"GRANT ALL ON \`${MARIADB_DATABASE//_/\\_}\`.* TO '$MARIADB_USER'@'%' ;"
fi
fi
} }
# backup the mysql database # backup the mysql database
@ -430,11 +440,8 @@ docker_mariadb_upgrade() {
mariadb-upgrade --upgrade-system-tables mariadb-upgrade --upgrade-system-tables
mysql_note "Finished mariadb-upgrade" mysql_note "Finished mariadb-upgrade"
# docker_temp_server_stop needs authentication since
# upgrade ended in FLUSH PRIVILEGES
mysql_note "Stopping temporary server" mysql_note "Stopping temporary server"
kill "$MARIADB_PID" docker_temp_server_stop
wait "$MARIADB_PID"
mysql_note "Temporary server stopped" mysql_note "Temporary server stopped"
} }
@ -509,6 +516,15 @@ _main() {
docker_setup_db docker_setup_db
docker_process_init_files /docker-entrypoint-initdb.d/* docker_process_init_files /docker-entrypoint-initdb.d/*
# Wait until after /docker-entrypoint-initdb.d is performed before setting
# root@localhost password to a hash we don't know the password for.
if [ -n "${MARIADB_ROOT_PASSWORD_HASH}" ]; then
mysql_note "Setting root@localhost password hash"
docker_process_sql --dont-use-mysql-root-password --binary-mode <<-EOSQL
SET @@SESSION.SQL_LOG_BIN=0;
SET PASSWORD FOR 'root'@'localhost'= '${MARIADB_ROOT_PASSWORD_HASH}';
EOSQL
fi
mysql_note "Stopping temporary server" mysql_note "Stopping temporary server"
docker_temp_server_stop docker_temp_server_stop

View File

@ -147,9 +147,8 @@ docker_temp_server_start() {
# Stop the server. When using a local socket file mysqladmin will block until # Stop the server. When using a local socket file mysqladmin will block until
# the shutdown is complete. # the shutdown is complete.
docker_temp_server_stop() { docker_temp_server_stop() {
if ! MYSQL_PWD=$MARIADB_ROOT_PASSWORD mysqladmin shutdown -uroot --socket="${SOCKET}"; then kill "$MARIADB_PID"
mysql_error "Unable to shut down server." wait "$MARIADB_PID"
fi
} }
# Verify that the minimally required password settings are set for new databases. # Verify that the minimally required password settings are set for new databases.
@ -291,22 +290,24 @@ docker_setup_db() {
# Creates root users for non-localhost hosts # Creates root users for non-localhost hosts
local rootCreate= local rootCreate=
local rootPasswordEscaped=
if [ -n "$MARIADB_ROOT_PASSWORD" ]; then
# Sets root password and creates root users for non-localhost hosts
rootPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_ROOT_PASSWORD}" )
fi
# default root to listen for connections from anywhere # default root to listen for connections from anywhere
if [ -n "$MARIADB_ROOT_HOST" ] && [ "$MARIADB_ROOT_HOST" != 'localhost' ]; then if [ -n "$MARIADB_ROOT_HOST" ] && [ "$MARIADB_ROOT_HOST" != 'localhost' ]; then
if [ -n "$MARIADB_ROOT_PASSWORD" ]; then # ref "read -d ''", no, we don't care if read finds a terminating character in this heredoc
# Sets root password and creates root users for non-localhost hosts # https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
local rootPasswordEscaped if [ -n "$MARIADB_ROOT_PASSWORD_HASH" ]; then
rootPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_ROOT_PASSWORD}" )
# no, we don't care if read finds a terminating character in this heredoc
# https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
read -r -d '' rootCreate <<-EOSQL || true read -r -d '' rootCreate <<-EOSQL || true
CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY '${rootPasswordEscaped}' ; CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY PASSWORD '${MARIADB_ROOT_PASSWORD_HASH}' ;
GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ; GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ;
EOSQL EOSQL
else else
read -r -d '' rootCreate <<-EOSQL || true read -r -d '' rootCreate <<-EOSQL || true
CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY PASSWORD '${MARIADB_ROOT_PASSWORD_HASH}' ; CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY '${rootPasswordEscaped}' ;
GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ; GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ;
EOSQL EOSQL
fi fi
@ -335,12 +336,44 @@ docker_setup_db() {
fi fi
fi fi
local rootLocalhostPass=
if [ -z "$MARIADB_ROOT_PASSWORD_HASH" ]; then
# handle MARIADB_ROOT_PASSWORD_HASH for root@localhost after /docker-entrypoint-initdb.d
rootLocalhostPass="SET PASSWORD FOR 'root'@'localhost'= PASSWORD('${rootPasswordEscaped}');"
fi
local createDatabase=
# Creates a custom database and user if specified
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Creating database ${MARIADB_DATABASE}"
createDatabase="CREATE DATABASE IF NOT EXISTS \`$MARIADB_DATABASE\`;"
fi
local createUser=
local userGrants=
if [ -n "$MARIADB_PASSWORD" ] || [ -n "$MARIADB_PASSWORD_HASH" ] && [ -n "$MARIADB_USER" ]; then
mysql_note "Creating user ${MARIADB_USER}"
if [ -n "$MARIADB_PASSWORD_HASH" ]; then
createUser="CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY PASSWORD '$MARIADB_PASSWORD_HASH';"
else
# SQL escape the user password, \ followed by '
local userPasswordEscaped
userPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_PASSWORD}" )
createUser="CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$userPasswordEscaped';"
fi
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Giving user ${MARIADB_USER} access to schema ${MARIADB_DATABASE}"
userGrants="GRANT ALL ON \`${MARIADB_DATABASE//_/\\_}\`.* TO '$MARIADB_USER'@'%';"
fi
fi
mysql_note "Securing system users (equivalent to running mysql_secure_installation)" mysql_note "Securing system users (equivalent to running mysql_secure_installation)"
# tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set # tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set
# --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding. # --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding.
docker_process_sql --dont-use-mysql-root-password --database=mysql --binary-mode <<-EOSQL docker_process_sql --dont-use-mysql-root-password --database=mysql --binary-mode <<-EOSQL
-- What's done in this file shouldn't be replicated -- Securing system users shouldn't be replicated
-- or products like mysql-fabric won't work SET @orig_sql_log_bin= @@SESSION.SQL_LOG_BIN;
SET @@SESSION.SQL_LOG_BIN=0; SET @@SESSION.SQL_LOG_BIN=0;
-- we need the SQL_MODE NO_BACKSLASH_ESCAPES mode to be clear for the password to be set -- we need the SQL_MODE NO_BACKSLASH_ESCAPES mode to be clear for the password to be set
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', ''); SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
@ -348,42 +381,19 @@ docker_setup_db() {
DROP USER IF EXISTS root@'127.0.0.1', root@'::1'; DROP USER IF EXISTS root@'127.0.0.1', root@'::1';
EXECUTE IMMEDIATE CONCAT('DROP USER IF EXISTS root@\'', @@hostname,'\''); EXECUTE IMMEDIATE CONCAT('DROP USER IF EXISTS root@\'', @@hostname,'\'');
SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${rootPasswordEscaped}') ; ${rootLocalhostPass}
${rootCreate} ${rootCreate}
${mysqlAtLocalhost} ${mysqlAtLocalhost}
${mysqlAtLocalhostGrants} ${mysqlAtLocalhostGrants}
-- pre-10.3 -- pre-10.3 only
DROP DATABASE IF EXISTS test ; DROP DATABASE IF EXISTS test ;
-- end of securing system users, rest of init now...
SET @@SESSION.SQL_LOG_BIN=@orig_sql_log_bin;
-- create users/databases
${createDatabase}
${createUser}
${userGrants}
EOSQL EOSQL
# Creates a custom database and user if specified
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Creating database ${MARIADB_DATABASE}"
docker_process_sql --database=mysql <<<"CREATE DATABASE IF NOT EXISTS \`$MARIADB_DATABASE\` ;"
fi
if [ -n "$MARIADB_PASSWORD" ] || [ -n "$MARIADB_PASSWORD_HASH" ] && [ -n "$MARIADB_USER" ]; then
mysql_note "Creating user ${MARIADB_USER}"
if [ -n "$MARIADB_PASSWORD" ]; then
# SQL escape the user password, \ followed by '
local userPasswordEscaped
userPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_PASSWORD}" )
docker_process_sql --database=mysql --binary-mode <<-EOSQL_USER
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$userPasswordEscaped';
EOSQL_USER
else
docker_process_sql --database=mysql --binary-mode <<-EOSQL_USER
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY PASSWORD '$MARIADB_PASSWORD_HASH';
EOSQL_USER
fi
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Giving user ${MARIADB_USER} access to schema ${MARIADB_DATABASE}"
docker_process_sql --database=mysql <<<"GRANT ALL ON \`${MARIADB_DATABASE//_/\\_}\`.* TO '$MARIADB_USER'@'%' ;"
fi
fi
} }
# backup the mysql database # backup the mysql database
@ -430,11 +440,8 @@ docker_mariadb_upgrade() {
mysql_upgrade --upgrade-system-tables mysql_upgrade --upgrade-system-tables
mysql_note "Finished mariadb-upgrade" mysql_note "Finished mariadb-upgrade"
# docker_temp_server_stop needs authentication since
# upgrade ended in FLUSH PRIVILEGES
mysql_note "Stopping temporary server" mysql_note "Stopping temporary server"
kill "$MARIADB_PID" docker_temp_server_stop
wait "$MARIADB_PID"
mysql_note "Temporary server stopped" mysql_note "Temporary server stopped"
} }
@ -509,6 +516,15 @@ _main() {
docker_setup_db docker_setup_db
docker_process_init_files /docker-entrypoint-initdb.d/* docker_process_init_files /docker-entrypoint-initdb.d/*
# Wait until after /docker-entrypoint-initdb.d is performed before setting
# root@localhost password to a hash we don't know the password for.
if [ -n "${MARIADB_ROOT_PASSWORD_HASH}" ]; then
mysql_note "Setting root@localhost password hash"
docker_process_sql --dont-use-mysql-root-password --binary-mode <<-EOSQL
SET @@SESSION.SQL_LOG_BIN=0;
SET PASSWORD FOR 'root'@'localhost'= '${MARIADB_ROOT_PASSWORD_HASH}';
EOSQL
fi
mysql_note "Stopping temporary server" mysql_note "Stopping temporary server"
docker_temp_server_stop docker_temp_server_stop

View File

@ -147,9 +147,8 @@ docker_temp_server_start() {
# Stop the server. When using a local socket file mysqladmin will block until # Stop the server. When using a local socket file mysqladmin will block until
# the shutdown is complete. # the shutdown is complete.
docker_temp_server_stop() { docker_temp_server_stop() {
if ! MYSQL_PWD=$MARIADB_ROOT_PASSWORD mysqladmin shutdown -uroot --socket="${SOCKET}"; then kill "$MARIADB_PID"
mysql_error "Unable to shut down server." wait "$MARIADB_PID"
fi
} }
# Verify that the minimally required password settings are set for new databases. # Verify that the minimally required password settings are set for new databases.
@ -291,22 +290,24 @@ docker_setup_db() {
# Creates root users for non-localhost hosts # Creates root users for non-localhost hosts
local rootCreate= local rootCreate=
local rootPasswordEscaped=
if [ -n "$MARIADB_ROOT_PASSWORD" ]; then
# Sets root password and creates root users for non-localhost hosts
rootPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_ROOT_PASSWORD}" )
fi
# default root to listen for connections from anywhere # default root to listen for connections from anywhere
if [ -n "$MARIADB_ROOT_HOST" ] && [ "$MARIADB_ROOT_HOST" != 'localhost' ]; then if [ -n "$MARIADB_ROOT_HOST" ] && [ "$MARIADB_ROOT_HOST" != 'localhost' ]; then
if [ -n "$MARIADB_ROOT_PASSWORD" ]; then # ref "read -d ''", no, we don't care if read finds a terminating character in this heredoc
# Sets root password and creates root users for non-localhost hosts # https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
local rootPasswordEscaped if [ -n "$MARIADB_ROOT_PASSWORD_HASH" ]; then
rootPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_ROOT_PASSWORD}" )
# no, we don't care if read finds a terminating character in this heredoc
# https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
read -r -d '' rootCreate <<-EOSQL || true read -r -d '' rootCreate <<-EOSQL || true
CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY '${rootPasswordEscaped}' ; CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY PASSWORD '${MARIADB_ROOT_PASSWORD_HASH}' ;
GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ; GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ;
EOSQL EOSQL
else else
read -r -d '' rootCreate <<-EOSQL || true read -r -d '' rootCreate <<-EOSQL || true
CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY PASSWORD '${MARIADB_ROOT_PASSWORD_HASH}' ; CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY '${rootPasswordEscaped}' ;
GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ; GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ;
EOSQL EOSQL
fi fi
@ -335,12 +336,44 @@ docker_setup_db() {
fi fi
fi fi
local rootLocalhostPass=
if [ -z "$MARIADB_ROOT_PASSWORD_HASH" ]; then
# handle MARIADB_ROOT_PASSWORD_HASH for root@localhost after /docker-entrypoint-initdb.d
rootLocalhostPass="SET PASSWORD FOR 'root'@'localhost'= PASSWORD('${rootPasswordEscaped}');"
fi
local createDatabase=
# Creates a custom database and user if specified
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Creating database ${MARIADB_DATABASE}"
createDatabase="CREATE DATABASE IF NOT EXISTS \`$MARIADB_DATABASE\`;"
fi
local createUser=
local userGrants=
if [ -n "$MARIADB_PASSWORD" ] || [ -n "$MARIADB_PASSWORD_HASH" ] && [ -n "$MARIADB_USER" ]; then
mysql_note "Creating user ${MARIADB_USER}"
if [ -n "$MARIADB_PASSWORD_HASH" ]; then
createUser="CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY PASSWORD '$MARIADB_PASSWORD_HASH';"
else
# SQL escape the user password, \ followed by '
local userPasswordEscaped
userPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_PASSWORD}" )
createUser="CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$userPasswordEscaped';"
fi
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Giving user ${MARIADB_USER} access to schema ${MARIADB_DATABASE}"
userGrants="GRANT ALL ON \`${MARIADB_DATABASE//_/\\_}\`.* TO '$MARIADB_USER'@'%';"
fi
fi
mysql_note "Securing system users (equivalent to running mysql_secure_installation)" mysql_note "Securing system users (equivalent to running mysql_secure_installation)"
# tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set # tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set
# --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding. # --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding.
docker_process_sql --dont-use-mysql-root-password --database=mysql --binary-mode <<-EOSQL docker_process_sql --dont-use-mysql-root-password --database=mysql --binary-mode <<-EOSQL
-- What's done in this file shouldn't be replicated -- Securing system users shouldn't be replicated
-- or products like mysql-fabric won't work SET @orig_sql_log_bin= @@SESSION.SQL_LOG_BIN;
SET @@SESSION.SQL_LOG_BIN=0; SET @@SESSION.SQL_LOG_BIN=0;
-- we need the SQL_MODE NO_BACKSLASH_ESCAPES mode to be clear for the password to be set -- we need the SQL_MODE NO_BACKSLASH_ESCAPES mode to be clear for the password to be set
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', ''); SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
@ -348,42 +381,19 @@ docker_setup_db() {
DROP USER IF EXISTS root@'127.0.0.1', root@'::1'; DROP USER IF EXISTS root@'127.0.0.1', root@'::1';
EXECUTE IMMEDIATE CONCAT('DROP USER IF EXISTS root@\'', @@hostname,'\''); EXECUTE IMMEDIATE CONCAT('DROP USER IF EXISTS root@\'', @@hostname,'\'');
SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${rootPasswordEscaped}') ; ${rootLocalhostPass}
${rootCreate} ${rootCreate}
${mysqlAtLocalhost} ${mysqlAtLocalhost}
${mysqlAtLocalhostGrants} ${mysqlAtLocalhostGrants}
-- pre-10.3 -- pre-10.3 only
DROP DATABASE IF EXISTS test ; DROP DATABASE IF EXISTS test ;
-- end of securing system users, rest of init now...
SET @@SESSION.SQL_LOG_BIN=@orig_sql_log_bin;
-- create users/databases
${createDatabase}
${createUser}
${userGrants}
EOSQL EOSQL
# Creates a custom database and user if specified
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Creating database ${MARIADB_DATABASE}"
docker_process_sql --database=mysql <<<"CREATE DATABASE IF NOT EXISTS \`$MARIADB_DATABASE\` ;"
fi
if [ -n "$MARIADB_PASSWORD" ] || [ -n "$MARIADB_PASSWORD_HASH" ] && [ -n "$MARIADB_USER" ]; then
mysql_note "Creating user ${MARIADB_USER}"
if [ -n "$MARIADB_PASSWORD" ]; then
# SQL escape the user password, \ followed by '
local userPasswordEscaped
userPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_PASSWORD}" )
docker_process_sql --database=mysql --binary-mode <<-EOSQL_USER
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$userPasswordEscaped';
EOSQL_USER
else
docker_process_sql --database=mysql --binary-mode <<-EOSQL_USER
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY PASSWORD '$MARIADB_PASSWORD_HASH';
EOSQL_USER
fi
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Giving user ${MARIADB_USER} access to schema ${MARIADB_DATABASE}"
docker_process_sql --database=mysql <<<"GRANT ALL ON \`${MARIADB_DATABASE//_/\\_}\`.* TO '$MARIADB_USER'@'%' ;"
fi
fi
} }
# backup the mysql database # backup the mysql database
@ -430,11 +440,8 @@ docker_mariadb_upgrade() {
mysql_upgrade --upgrade-system-tables mysql_upgrade --upgrade-system-tables
mysql_note "Finished mariadb-upgrade" mysql_note "Finished mariadb-upgrade"
# docker_temp_server_stop needs authentication since
# upgrade ended in FLUSH PRIVILEGES
mysql_note "Stopping temporary server" mysql_note "Stopping temporary server"
kill "$MARIADB_PID" docker_temp_server_stop
wait "$MARIADB_PID"
mysql_note "Temporary server stopped" mysql_note "Temporary server stopped"
} }
@ -509,6 +516,15 @@ _main() {
docker_setup_db docker_setup_db
docker_process_init_files /docker-entrypoint-initdb.d/* docker_process_init_files /docker-entrypoint-initdb.d/*
# Wait until after /docker-entrypoint-initdb.d is performed before setting
# root@localhost password to a hash we don't know the password for.
if [ -n "${MARIADB_ROOT_PASSWORD_HASH}" ]; then
mysql_note "Setting root@localhost password hash"
docker_process_sql --dont-use-mysql-root-password --binary-mode <<-EOSQL
SET @@SESSION.SQL_LOG_BIN=0;
SET PASSWORD FOR 'root'@'localhost'= '${MARIADB_ROOT_PASSWORD_HASH}';
EOSQL
fi
mysql_note "Stopping temporary server" mysql_note "Stopping temporary server"
docker_temp_server_stop docker_temp_server_stop

View File

@ -147,9 +147,8 @@ docker_temp_server_start() {
# Stop the server. When using a local socket file mysqladmin will block until # Stop the server. When using a local socket file mysqladmin will block until
# the shutdown is complete. # the shutdown is complete.
docker_temp_server_stop() { docker_temp_server_stop() {
if ! MYSQL_PWD=$MARIADB_ROOT_PASSWORD mysqladmin shutdown -uroot --socket="${SOCKET}"; then kill "$MARIADB_PID"
mysql_error "Unable to shut down server." wait "$MARIADB_PID"
fi
} }
# Verify that the minimally required password settings are set for new databases. # Verify that the minimally required password settings are set for new databases.
@ -291,22 +290,24 @@ docker_setup_db() {
# Creates root users for non-localhost hosts # Creates root users for non-localhost hosts
local rootCreate= local rootCreate=
local rootPasswordEscaped=
if [ -n "$MARIADB_ROOT_PASSWORD" ]; then
# Sets root password and creates root users for non-localhost hosts
rootPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_ROOT_PASSWORD}" )
fi
# default root to listen for connections from anywhere # default root to listen for connections from anywhere
if [ -n "$MARIADB_ROOT_HOST" ] && [ "$MARIADB_ROOT_HOST" != 'localhost' ]; then if [ -n "$MARIADB_ROOT_HOST" ] && [ "$MARIADB_ROOT_HOST" != 'localhost' ]; then
if [ -n "$MARIADB_ROOT_PASSWORD" ]; then # ref "read -d ''", no, we don't care if read finds a terminating character in this heredoc
# Sets root password and creates root users for non-localhost hosts # https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
local rootPasswordEscaped if [ -n "$MARIADB_ROOT_PASSWORD_HASH" ]; then
rootPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_ROOT_PASSWORD}" )
# no, we don't care if read finds a terminating character in this heredoc
# https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
read -r -d '' rootCreate <<-EOSQL || true read -r -d '' rootCreate <<-EOSQL || true
CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY '${rootPasswordEscaped}' ; CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY PASSWORD '${MARIADB_ROOT_PASSWORD_HASH}' ;
GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ; GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ;
EOSQL EOSQL
else else
read -r -d '' rootCreate <<-EOSQL || true read -r -d '' rootCreate <<-EOSQL || true
CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY PASSWORD '${MARIADB_ROOT_PASSWORD_HASH}' ; CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY '${rootPasswordEscaped}' ;
GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ; GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ;
EOSQL EOSQL
fi fi
@ -335,12 +336,44 @@ docker_setup_db() {
fi fi
fi fi
local rootLocalhostPass=
if [ -z "$MARIADB_ROOT_PASSWORD_HASH" ]; then
# handle MARIADB_ROOT_PASSWORD_HASH for root@localhost after /docker-entrypoint-initdb.d
rootLocalhostPass="SET PASSWORD FOR 'root'@'localhost'= PASSWORD('${rootPasswordEscaped}');"
fi
local createDatabase=
# Creates a custom database and user if specified
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Creating database ${MARIADB_DATABASE}"
createDatabase="CREATE DATABASE IF NOT EXISTS \`$MARIADB_DATABASE\`;"
fi
local createUser=
local userGrants=
if [ -n "$MARIADB_PASSWORD" ] || [ -n "$MARIADB_PASSWORD_HASH" ] && [ -n "$MARIADB_USER" ]; then
mysql_note "Creating user ${MARIADB_USER}"
if [ -n "$MARIADB_PASSWORD_HASH" ]; then
createUser="CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY PASSWORD '$MARIADB_PASSWORD_HASH';"
else
# SQL escape the user password, \ followed by '
local userPasswordEscaped
userPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_PASSWORD}" )
createUser="CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$userPasswordEscaped';"
fi
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Giving user ${MARIADB_USER} access to schema ${MARIADB_DATABASE}"
userGrants="GRANT ALL ON \`${MARIADB_DATABASE//_/\\_}\`.* TO '$MARIADB_USER'@'%';"
fi
fi
mysql_note "Securing system users (equivalent to running mysql_secure_installation)" mysql_note "Securing system users (equivalent to running mysql_secure_installation)"
# tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set # tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set
# --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding. # --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding.
docker_process_sql --dont-use-mysql-root-password --database=mysql --binary-mode <<-EOSQL docker_process_sql --dont-use-mysql-root-password --database=mysql --binary-mode <<-EOSQL
-- What's done in this file shouldn't be replicated -- Securing system users shouldn't be replicated
-- or products like mysql-fabric won't work SET @orig_sql_log_bin= @@SESSION.SQL_LOG_BIN;
SET @@SESSION.SQL_LOG_BIN=0; SET @@SESSION.SQL_LOG_BIN=0;
-- we need the SQL_MODE NO_BACKSLASH_ESCAPES mode to be clear for the password to be set -- we need the SQL_MODE NO_BACKSLASH_ESCAPES mode to be clear for the password to be set
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', ''); SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
@ -348,42 +381,19 @@ docker_setup_db() {
DROP USER IF EXISTS root@'127.0.0.1', root@'::1'; DROP USER IF EXISTS root@'127.0.0.1', root@'::1';
EXECUTE IMMEDIATE CONCAT('DROP USER IF EXISTS root@\'', @@hostname,'\''); EXECUTE IMMEDIATE CONCAT('DROP USER IF EXISTS root@\'', @@hostname,'\'');
SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${rootPasswordEscaped}') ; ${rootLocalhostPass}
${rootCreate} ${rootCreate}
${mysqlAtLocalhost} ${mysqlAtLocalhost}
${mysqlAtLocalhostGrants} ${mysqlAtLocalhostGrants}
-- pre-10.3 -- pre-10.3 only
DROP DATABASE IF EXISTS test ; DROP DATABASE IF EXISTS test ;
-- end of securing system users, rest of init now...
SET @@SESSION.SQL_LOG_BIN=@orig_sql_log_bin;
-- create users/databases
${createDatabase}
${createUser}
${userGrants}
EOSQL EOSQL
# Creates a custom database and user if specified
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Creating database ${MARIADB_DATABASE}"
docker_process_sql --database=mysql <<<"CREATE DATABASE IF NOT EXISTS \`$MARIADB_DATABASE\` ;"
fi
if [ -n "$MARIADB_PASSWORD" ] || [ -n "$MARIADB_PASSWORD_HASH" ] && [ -n "$MARIADB_USER" ]; then
mysql_note "Creating user ${MARIADB_USER}"
if [ -n "$MARIADB_PASSWORD" ]; then
# SQL escape the user password, \ followed by '
local userPasswordEscaped
userPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_PASSWORD}" )
docker_process_sql --database=mysql --binary-mode <<-EOSQL_USER
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$userPasswordEscaped';
EOSQL_USER
else
docker_process_sql --database=mysql --binary-mode <<-EOSQL_USER
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY PASSWORD '$MARIADB_PASSWORD_HASH';
EOSQL_USER
fi
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Giving user ${MARIADB_USER} access to schema ${MARIADB_DATABASE}"
docker_process_sql --database=mysql <<<"GRANT ALL ON \`${MARIADB_DATABASE//_/\\_}\`.* TO '$MARIADB_USER'@'%' ;"
fi
fi
} }
# backup the mysql database # backup the mysql database
@ -430,11 +440,8 @@ docker_mariadb_upgrade() {
mysql_upgrade --upgrade-system-tables mysql_upgrade --upgrade-system-tables
mysql_note "Finished mariadb-upgrade" mysql_note "Finished mariadb-upgrade"
# docker_temp_server_stop needs authentication since
# upgrade ended in FLUSH PRIVILEGES
mysql_note "Stopping temporary server" mysql_note "Stopping temporary server"
kill "$MARIADB_PID" docker_temp_server_stop
wait "$MARIADB_PID"
mysql_note "Temporary server stopped" mysql_note "Temporary server stopped"
} }
@ -509,6 +516,15 @@ _main() {
docker_setup_db docker_setup_db
docker_process_init_files /docker-entrypoint-initdb.d/* docker_process_init_files /docker-entrypoint-initdb.d/*
# Wait until after /docker-entrypoint-initdb.d is performed before setting
# root@localhost password to a hash we don't know the password for.
if [ -n "${MARIADB_ROOT_PASSWORD_HASH}" ]; then
mysql_note "Setting root@localhost password hash"
docker_process_sql --dont-use-mysql-root-password --binary-mode <<-EOSQL
SET @@SESSION.SQL_LOG_BIN=0;
SET PASSWORD FOR 'root'@'localhost'= '${MARIADB_ROOT_PASSWORD_HASH}';
EOSQL
fi
mysql_note "Stopping temporary server" mysql_note "Stopping temporary server"
docker_temp_server_stop docker_temp_server_stop

View File

@ -147,9 +147,8 @@ docker_temp_server_start() {
# Stop the server. When using a local socket file mariadb-admin will block until # Stop the server. When using a local socket file mariadb-admin will block until
# the shutdown is complete. # the shutdown is complete.
docker_temp_server_stop() { docker_temp_server_stop() {
if ! MYSQL_PWD=$MARIADB_ROOT_PASSWORD mariadb-admin shutdown -uroot --socket="${SOCKET}"; then kill "$MARIADB_PID"
mysql_error "Unable to shut down server." wait "$MARIADB_PID"
fi
} }
# Verify that the minimally required password settings are set for new databases. # Verify that the minimally required password settings are set for new databases.
@ -291,22 +290,24 @@ docker_setup_db() {
# Creates root users for non-localhost hosts # Creates root users for non-localhost hosts
local rootCreate= local rootCreate=
local rootPasswordEscaped=
if [ -n "$MARIADB_ROOT_PASSWORD" ]; then
# Sets root password and creates root users for non-localhost hosts
rootPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_ROOT_PASSWORD}" )
fi
# default root to listen for connections from anywhere # default root to listen for connections from anywhere
if [ -n "$MARIADB_ROOT_HOST" ] && [ "$MARIADB_ROOT_HOST" != 'localhost' ]; then if [ -n "$MARIADB_ROOT_HOST" ] && [ "$MARIADB_ROOT_HOST" != 'localhost' ]; then
if [ -n "$MARIADB_ROOT_PASSWORD" ]; then # ref "read -d ''", no, we don't care if read finds a terminating character in this heredoc
# Sets root password and creates root users for non-localhost hosts # https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
local rootPasswordEscaped if [ -n "$MARIADB_ROOT_PASSWORD_HASH" ]; then
rootPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_ROOT_PASSWORD}" )
# no, we don't care if read finds a terminating character in this heredoc
# https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
read -r -d '' rootCreate <<-EOSQL || true read -r -d '' rootCreate <<-EOSQL || true
CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY '${rootPasswordEscaped}' ; CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY PASSWORD '${MARIADB_ROOT_PASSWORD_HASH}' ;
GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ; GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ;
EOSQL EOSQL
else else
read -r -d '' rootCreate <<-EOSQL || true read -r -d '' rootCreate <<-EOSQL || true
CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY PASSWORD '${MARIADB_ROOT_PASSWORD_HASH}' ; CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY '${rootPasswordEscaped}' ;
GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ; GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ;
EOSQL EOSQL
fi fi
@ -335,12 +336,44 @@ docker_setup_db() {
fi fi
fi fi
local rootLocalhostPass=
if [ -z "$MARIADB_ROOT_PASSWORD_HASH" ]; then
# handle MARIADB_ROOT_PASSWORD_HASH for root@localhost after /docker-entrypoint-initdb.d
rootLocalhostPass="SET PASSWORD FOR 'root'@'localhost'= PASSWORD('${rootPasswordEscaped}');"
fi
local createDatabase=
# Creates a custom database and user if specified
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Creating database ${MARIADB_DATABASE}"
createDatabase="CREATE DATABASE IF NOT EXISTS \`$MARIADB_DATABASE\`;"
fi
local createUser=
local userGrants=
if [ -n "$MARIADB_PASSWORD" ] || [ -n "$MARIADB_PASSWORD_HASH" ] && [ -n "$MARIADB_USER" ]; then
mysql_note "Creating user ${MARIADB_USER}"
if [ -n "$MARIADB_PASSWORD_HASH" ]; then
createUser="CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY PASSWORD '$MARIADB_PASSWORD_HASH';"
else
# SQL escape the user password, \ followed by '
local userPasswordEscaped
userPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_PASSWORD}" )
createUser="CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$userPasswordEscaped';"
fi
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Giving user ${MARIADB_USER} access to schema ${MARIADB_DATABASE}"
userGrants="GRANT ALL ON \`${MARIADB_DATABASE//_/\\_}\`.* TO '$MARIADB_USER'@'%';"
fi
fi
mysql_note "Securing system users (equivalent to running mysql_secure_installation)" mysql_note "Securing system users (equivalent to running mysql_secure_installation)"
# tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set # tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set
# --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding. # --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding.
docker_process_sql --dont-use-mysql-root-password --database=mysql --binary-mode <<-EOSQL docker_process_sql --dont-use-mysql-root-password --database=mysql --binary-mode <<-EOSQL
-- What's done in this file shouldn't be replicated -- Securing system users shouldn't be replicated
-- or products like mysql-fabric won't work SET @orig_sql_log_bin= @@SESSION.SQL_LOG_BIN;
SET @@SESSION.SQL_LOG_BIN=0; SET @@SESSION.SQL_LOG_BIN=0;
-- we need the SQL_MODE NO_BACKSLASH_ESCAPES mode to be clear for the password to be set -- we need the SQL_MODE NO_BACKSLASH_ESCAPES mode to be clear for the password to be set
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', ''); SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
@ -348,42 +381,19 @@ docker_setup_db() {
DROP USER IF EXISTS root@'127.0.0.1', root@'::1'; DROP USER IF EXISTS root@'127.0.0.1', root@'::1';
EXECUTE IMMEDIATE CONCAT('DROP USER IF EXISTS root@\'', @@hostname,'\''); EXECUTE IMMEDIATE CONCAT('DROP USER IF EXISTS root@\'', @@hostname,'\'');
SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${rootPasswordEscaped}') ; ${rootLocalhostPass}
${rootCreate} ${rootCreate}
${mysqlAtLocalhost} ${mysqlAtLocalhost}
${mysqlAtLocalhostGrants} ${mysqlAtLocalhostGrants}
-- pre-10.3 -- pre-10.3 only
DROP DATABASE IF EXISTS test ; DROP DATABASE IF EXISTS test ;
-- end of securing system users, rest of init now...
SET @@SESSION.SQL_LOG_BIN=@orig_sql_log_bin;
-- create users/databases
${createDatabase}
${createUser}
${userGrants}
EOSQL EOSQL
# Creates a custom database and user if specified
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Creating database ${MARIADB_DATABASE}"
docker_process_sql --database=mysql <<<"CREATE DATABASE IF NOT EXISTS \`$MARIADB_DATABASE\` ;"
fi
if [ -n "$MARIADB_PASSWORD" ] || [ -n "$MARIADB_PASSWORD_HASH" ] && [ -n "$MARIADB_USER" ]; then
mysql_note "Creating user ${MARIADB_USER}"
if [ -n "$MARIADB_PASSWORD" ]; then
# SQL escape the user password, \ followed by '
local userPasswordEscaped
userPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_PASSWORD}" )
docker_process_sql --database=mysql --binary-mode <<-EOSQL_USER
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$userPasswordEscaped';
EOSQL_USER
else
docker_process_sql --database=mysql --binary-mode <<-EOSQL_USER
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY PASSWORD '$MARIADB_PASSWORD_HASH';
EOSQL_USER
fi
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Giving user ${MARIADB_USER} access to schema ${MARIADB_DATABASE}"
docker_process_sql --database=mysql <<<"GRANT ALL ON \`${MARIADB_DATABASE//_/\\_}\`.* TO '$MARIADB_USER'@'%' ;"
fi
fi
} }
# backup the mysql database # backup the mysql database
@ -430,11 +440,8 @@ docker_mariadb_upgrade() {
mariadb-upgrade --upgrade-system-tables mariadb-upgrade --upgrade-system-tables
mysql_note "Finished mariadb-upgrade" mysql_note "Finished mariadb-upgrade"
# docker_temp_server_stop needs authentication since
# upgrade ended in FLUSH PRIVILEGES
mysql_note "Stopping temporary server" mysql_note "Stopping temporary server"
kill "$MARIADB_PID" docker_temp_server_stop
wait "$MARIADB_PID"
mysql_note "Temporary server stopped" mysql_note "Temporary server stopped"
} }
@ -509,6 +516,15 @@ _main() {
docker_setup_db docker_setup_db
docker_process_init_files /docker-entrypoint-initdb.d/* docker_process_init_files /docker-entrypoint-initdb.d/*
# Wait until after /docker-entrypoint-initdb.d is performed before setting
# root@localhost password to a hash we don't know the password for.
if [ -n "${MARIADB_ROOT_PASSWORD_HASH}" ]; then
mysql_note "Setting root@localhost password hash"
docker_process_sql --dont-use-mysql-root-password --binary-mode <<-EOSQL
SET @@SESSION.SQL_LOG_BIN=0;
SET PASSWORD FOR 'root'@'localhost'= '${MARIADB_ROOT_PASSWORD_HASH}';
EOSQL
fi
mysql_note "Stopping temporary server" mysql_note "Stopping temporary server"
docker_temp_server_stop docker_temp_server_stop

View File

@ -147,9 +147,8 @@ docker_temp_server_start() {
# Stop the server. When using a local socket file mariadb-admin will block until # Stop the server. When using a local socket file mariadb-admin will block until
# the shutdown is complete. # the shutdown is complete.
docker_temp_server_stop() { docker_temp_server_stop() {
if ! MYSQL_PWD=$MARIADB_ROOT_PASSWORD mariadb-admin shutdown -uroot --socket="${SOCKET}"; then kill "$MARIADB_PID"
mysql_error "Unable to shut down server." wait "$MARIADB_PID"
fi
} }
# Verify that the minimally required password settings are set for new databases. # Verify that the minimally required password settings are set for new databases.
@ -291,22 +290,24 @@ docker_setup_db() {
# Creates root users for non-localhost hosts # Creates root users for non-localhost hosts
local rootCreate= local rootCreate=
local rootPasswordEscaped=
if [ -n "$MARIADB_ROOT_PASSWORD" ]; then
# Sets root password and creates root users for non-localhost hosts
rootPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_ROOT_PASSWORD}" )
fi
# default root to listen for connections from anywhere # default root to listen for connections from anywhere
if [ -n "$MARIADB_ROOT_HOST" ] && [ "$MARIADB_ROOT_HOST" != 'localhost' ]; then if [ -n "$MARIADB_ROOT_HOST" ] && [ "$MARIADB_ROOT_HOST" != 'localhost' ]; then
if [ -n "$MARIADB_ROOT_PASSWORD" ]; then # ref "read -d ''", no, we don't care if read finds a terminating character in this heredoc
# Sets root password and creates root users for non-localhost hosts # https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
local rootPasswordEscaped if [ -n "$MARIADB_ROOT_PASSWORD_HASH" ]; then
rootPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_ROOT_PASSWORD}" )
# no, we don't care if read finds a terminating character in this heredoc
# https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
read -r -d '' rootCreate <<-EOSQL || true read -r -d '' rootCreate <<-EOSQL || true
CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY '${rootPasswordEscaped}' ; CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY PASSWORD '${MARIADB_ROOT_PASSWORD_HASH}' ;
GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ; GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ;
EOSQL EOSQL
else else
read -r -d '' rootCreate <<-EOSQL || true read -r -d '' rootCreate <<-EOSQL || true
CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY PASSWORD '${MARIADB_ROOT_PASSWORD_HASH}' ; CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY '${rootPasswordEscaped}' ;
GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ; GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ;
EOSQL EOSQL
fi fi
@ -335,12 +336,44 @@ docker_setup_db() {
fi fi
fi fi
local rootLocalhostPass=
if [ -z "$MARIADB_ROOT_PASSWORD_HASH" ]; then
# handle MARIADB_ROOT_PASSWORD_HASH for root@localhost after /docker-entrypoint-initdb.d
rootLocalhostPass="SET PASSWORD FOR 'root'@'localhost'= PASSWORD('${rootPasswordEscaped}');"
fi
local createDatabase=
# Creates a custom database and user if specified
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Creating database ${MARIADB_DATABASE}"
createDatabase="CREATE DATABASE IF NOT EXISTS \`$MARIADB_DATABASE\`;"
fi
local createUser=
local userGrants=
if [ -n "$MARIADB_PASSWORD" ] || [ -n "$MARIADB_PASSWORD_HASH" ] && [ -n "$MARIADB_USER" ]; then
mysql_note "Creating user ${MARIADB_USER}"
if [ -n "$MARIADB_PASSWORD_HASH" ]; then
createUser="CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY PASSWORD '$MARIADB_PASSWORD_HASH';"
else
# SQL escape the user password, \ followed by '
local userPasswordEscaped
userPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_PASSWORD}" )
createUser="CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$userPasswordEscaped';"
fi
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Giving user ${MARIADB_USER} access to schema ${MARIADB_DATABASE}"
userGrants="GRANT ALL ON \`${MARIADB_DATABASE//_/\\_}\`.* TO '$MARIADB_USER'@'%';"
fi
fi
mysql_note "Securing system users (equivalent to running mysql_secure_installation)" mysql_note "Securing system users (equivalent to running mysql_secure_installation)"
# tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set # tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set
# --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding. # --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding.
docker_process_sql --dont-use-mysql-root-password --database=mysql --binary-mode <<-EOSQL docker_process_sql --dont-use-mysql-root-password --database=mysql --binary-mode <<-EOSQL
-- What's done in this file shouldn't be replicated -- Securing system users shouldn't be replicated
-- or products like mysql-fabric won't work SET @orig_sql_log_bin= @@SESSION.SQL_LOG_BIN;
SET @@SESSION.SQL_LOG_BIN=0; SET @@SESSION.SQL_LOG_BIN=0;
-- we need the SQL_MODE NO_BACKSLASH_ESCAPES mode to be clear for the password to be set -- we need the SQL_MODE NO_BACKSLASH_ESCAPES mode to be clear for the password to be set
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', ''); SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
@ -348,42 +381,19 @@ docker_setup_db() {
DROP USER IF EXISTS root@'127.0.0.1', root@'::1'; DROP USER IF EXISTS root@'127.0.0.1', root@'::1';
EXECUTE IMMEDIATE CONCAT('DROP USER IF EXISTS root@\'', @@hostname,'\''); EXECUTE IMMEDIATE CONCAT('DROP USER IF EXISTS root@\'', @@hostname,'\'');
SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${rootPasswordEscaped}') ; ${rootLocalhostPass}
${rootCreate} ${rootCreate}
${mysqlAtLocalhost} ${mysqlAtLocalhost}
${mysqlAtLocalhostGrants} ${mysqlAtLocalhostGrants}
-- pre-10.3 -- pre-10.3 only
DROP DATABASE IF EXISTS test ; DROP DATABASE IF EXISTS test ;
-- end of securing system users, rest of init now...
SET @@SESSION.SQL_LOG_BIN=@orig_sql_log_bin;
-- create users/databases
${createDatabase}
${createUser}
${userGrants}
EOSQL EOSQL
# Creates a custom database and user if specified
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Creating database ${MARIADB_DATABASE}"
docker_process_sql --database=mysql <<<"CREATE DATABASE IF NOT EXISTS \`$MARIADB_DATABASE\` ;"
fi
if [ -n "$MARIADB_PASSWORD" ] || [ -n "$MARIADB_PASSWORD_HASH" ] && [ -n "$MARIADB_USER" ]; then
mysql_note "Creating user ${MARIADB_USER}"
if [ -n "$MARIADB_PASSWORD" ]; then
# SQL escape the user password, \ followed by '
local userPasswordEscaped
userPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_PASSWORD}" )
docker_process_sql --database=mysql --binary-mode <<-EOSQL_USER
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$userPasswordEscaped';
EOSQL_USER
else
docker_process_sql --database=mysql --binary-mode <<-EOSQL_USER
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY PASSWORD '$MARIADB_PASSWORD_HASH';
EOSQL_USER
fi
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Giving user ${MARIADB_USER} access to schema ${MARIADB_DATABASE}"
docker_process_sql --database=mysql <<<"GRANT ALL ON \`${MARIADB_DATABASE//_/\\_}\`.* TO '$MARIADB_USER'@'%' ;"
fi
fi
} }
# backup the mysql database # backup the mysql database
@ -430,11 +440,8 @@ docker_mariadb_upgrade() {
mariadb-upgrade --upgrade-system-tables mariadb-upgrade --upgrade-system-tables
mysql_note "Finished mariadb-upgrade" mysql_note "Finished mariadb-upgrade"
# docker_temp_server_stop needs authentication since
# upgrade ended in FLUSH PRIVILEGES
mysql_note "Stopping temporary server" mysql_note "Stopping temporary server"
kill "$MARIADB_PID" docker_temp_server_stop
wait "$MARIADB_PID"
mysql_note "Temporary server stopped" mysql_note "Temporary server stopped"
} }
@ -509,6 +516,15 @@ _main() {
docker_setup_db docker_setup_db
docker_process_init_files /docker-entrypoint-initdb.d/* docker_process_init_files /docker-entrypoint-initdb.d/*
# Wait until after /docker-entrypoint-initdb.d is performed before setting
# root@localhost password to a hash we don't know the password for.
if [ -n "${MARIADB_ROOT_PASSWORD_HASH}" ]; then
mysql_note "Setting root@localhost password hash"
docker_process_sql --dont-use-mysql-root-password --binary-mode <<-EOSQL
SET @@SESSION.SQL_LOG_BIN=0;
SET PASSWORD FOR 'root'@'localhost'= '${MARIADB_ROOT_PASSWORD_HASH}';
EOSQL
fi
mysql_note "Stopping temporary server" mysql_note "Stopping temporary server"
docker_temp_server_stop docker_temp_server_stop

View File

@ -147,9 +147,8 @@ docker_temp_server_start() {
# Stop the server. When using a local socket file mariadb-admin will block until # Stop the server. When using a local socket file mariadb-admin will block until
# the shutdown is complete. # the shutdown is complete.
docker_temp_server_stop() { docker_temp_server_stop() {
if ! MYSQL_PWD=$MARIADB_ROOT_PASSWORD mariadb-admin shutdown -uroot --socket="${SOCKET}"; then kill "$MARIADB_PID"
mysql_error "Unable to shut down server." wait "$MARIADB_PID"
fi
} }
# Verify that the minimally required password settings are set for new databases. # Verify that the minimally required password settings are set for new databases.
@ -291,22 +290,24 @@ docker_setup_db() {
# Creates root users for non-localhost hosts # Creates root users for non-localhost hosts
local rootCreate= local rootCreate=
local rootPasswordEscaped=
if [ -n "$MARIADB_ROOT_PASSWORD" ]; then
# Sets root password and creates root users for non-localhost hosts
rootPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_ROOT_PASSWORD}" )
fi
# default root to listen for connections from anywhere # default root to listen for connections from anywhere
if [ -n "$MARIADB_ROOT_HOST" ] && [ "$MARIADB_ROOT_HOST" != 'localhost' ]; then if [ -n "$MARIADB_ROOT_HOST" ] && [ "$MARIADB_ROOT_HOST" != 'localhost' ]; then
if [ -n "$MARIADB_ROOT_PASSWORD" ]; then # ref "read -d ''", no, we don't care if read finds a terminating character in this heredoc
# Sets root password and creates root users for non-localhost hosts # https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
local rootPasswordEscaped if [ -n "$MARIADB_ROOT_PASSWORD_HASH" ]; then
rootPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_ROOT_PASSWORD}" )
# no, we don't care if read finds a terminating character in this heredoc
# https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
read -r -d '' rootCreate <<-EOSQL || true read -r -d '' rootCreate <<-EOSQL || true
CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY '${rootPasswordEscaped}' ; CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY PASSWORD '${MARIADB_ROOT_PASSWORD_HASH}' ;
GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ; GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ;
EOSQL EOSQL
else else
read -r -d '' rootCreate <<-EOSQL || true read -r -d '' rootCreate <<-EOSQL || true
CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY PASSWORD '${MARIADB_ROOT_PASSWORD_HASH}' ; CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY '${rootPasswordEscaped}' ;
GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ; GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ;
EOSQL EOSQL
fi fi
@ -335,12 +336,44 @@ docker_setup_db() {
fi fi
fi fi
local rootLocalhostPass=
if [ -z "$MARIADB_ROOT_PASSWORD_HASH" ]; then
# handle MARIADB_ROOT_PASSWORD_HASH for root@localhost after /docker-entrypoint-initdb.d
rootLocalhostPass="SET PASSWORD FOR 'root'@'localhost'= PASSWORD('${rootPasswordEscaped}');"
fi
local createDatabase=
# Creates a custom database and user if specified
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Creating database ${MARIADB_DATABASE}"
createDatabase="CREATE DATABASE IF NOT EXISTS \`$MARIADB_DATABASE\`;"
fi
local createUser=
local userGrants=
if [ -n "$MARIADB_PASSWORD" ] || [ -n "$MARIADB_PASSWORD_HASH" ] && [ -n "$MARIADB_USER" ]; then
mysql_note "Creating user ${MARIADB_USER}"
if [ -n "$MARIADB_PASSWORD_HASH" ]; then
createUser="CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY PASSWORD '$MARIADB_PASSWORD_HASH';"
else
# SQL escape the user password, \ followed by '
local userPasswordEscaped
userPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_PASSWORD}" )
createUser="CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$userPasswordEscaped';"
fi
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Giving user ${MARIADB_USER} access to schema ${MARIADB_DATABASE}"
userGrants="GRANT ALL ON \`${MARIADB_DATABASE//_/\\_}\`.* TO '$MARIADB_USER'@'%';"
fi
fi
mysql_note "Securing system users (equivalent to running mysql_secure_installation)" mysql_note "Securing system users (equivalent to running mysql_secure_installation)"
# tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set # tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set
# --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding. # --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding.
docker_process_sql --dont-use-mysql-root-password --database=mysql --binary-mode <<-EOSQL docker_process_sql --dont-use-mysql-root-password --database=mysql --binary-mode <<-EOSQL
-- What's done in this file shouldn't be replicated -- Securing system users shouldn't be replicated
-- or products like mysql-fabric won't work SET @orig_sql_log_bin= @@SESSION.SQL_LOG_BIN;
SET @@SESSION.SQL_LOG_BIN=0; SET @@SESSION.SQL_LOG_BIN=0;
-- we need the SQL_MODE NO_BACKSLASH_ESCAPES mode to be clear for the password to be set -- we need the SQL_MODE NO_BACKSLASH_ESCAPES mode to be clear for the password to be set
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', ''); SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
@ -348,42 +381,19 @@ docker_setup_db() {
DROP USER IF EXISTS root@'127.0.0.1', root@'::1'; DROP USER IF EXISTS root@'127.0.0.1', root@'::1';
EXECUTE IMMEDIATE CONCAT('DROP USER IF EXISTS root@\'', @@hostname,'\''); EXECUTE IMMEDIATE CONCAT('DROP USER IF EXISTS root@\'', @@hostname,'\'');
SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${rootPasswordEscaped}') ; ${rootLocalhostPass}
${rootCreate} ${rootCreate}
${mysqlAtLocalhost} ${mysqlAtLocalhost}
${mysqlAtLocalhostGrants} ${mysqlAtLocalhostGrants}
-- pre-10.3 -- pre-10.3 only
DROP DATABASE IF EXISTS test ; DROP DATABASE IF EXISTS test ;
-- end of securing system users, rest of init now...
SET @@SESSION.SQL_LOG_BIN=@orig_sql_log_bin;
-- create users/databases
${createDatabase}
${createUser}
${userGrants}
EOSQL EOSQL
# Creates a custom database and user if specified
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Creating database ${MARIADB_DATABASE}"
docker_process_sql --database=mysql <<<"CREATE DATABASE IF NOT EXISTS \`$MARIADB_DATABASE\` ;"
fi
if [ -n "$MARIADB_PASSWORD" ] || [ -n "$MARIADB_PASSWORD_HASH" ] && [ -n "$MARIADB_USER" ]; then
mysql_note "Creating user ${MARIADB_USER}"
if [ -n "$MARIADB_PASSWORD" ]; then
# SQL escape the user password, \ followed by '
local userPasswordEscaped
userPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_PASSWORD}" )
docker_process_sql --database=mysql --binary-mode <<-EOSQL_USER
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$userPasswordEscaped';
EOSQL_USER
else
docker_process_sql --database=mysql --binary-mode <<-EOSQL_USER
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY PASSWORD '$MARIADB_PASSWORD_HASH';
EOSQL_USER
fi
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Giving user ${MARIADB_USER} access to schema ${MARIADB_DATABASE}"
docker_process_sql --database=mysql <<<"GRANT ALL ON \`${MARIADB_DATABASE//_/\\_}\`.* TO '$MARIADB_USER'@'%' ;"
fi
fi
} }
# backup the mysql database # backup the mysql database
@ -430,11 +440,8 @@ docker_mariadb_upgrade() {
mariadb-upgrade --upgrade-system-tables mariadb-upgrade --upgrade-system-tables
mysql_note "Finished mariadb-upgrade" mysql_note "Finished mariadb-upgrade"
# docker_temp_server_stop needs authentication since
# upgrade ended in FLUSH PRIVILEGES
mysql_note "Stopping temporary server" mysql_note "Stopping temporary server"
kill "$MARIADB_PID" docker_temp_server_stop
wait "$MARIADB_PID"
mysql_note "Temporary server stopped" mysql_note "Temporary server stopped"
} }
@ -509,6 +516,15 @@ _main() {
docker_setup_db docker_setup_db
docker_process_init_files /docker-entrypoint-initdb.d/* docker_process_init_files /docker-entrypoint-initdb.d/*
# Wait until after /docker-entrypoint-initdb.d is performed before setting
# root@localhost password to a hash we don't know the password for.
if [ -n "${MARIADB_ROOT_PASSWORD_HASH}" ]; then
mysql_note "Setting root@localhost password hash"
docker_process_sql --dont-use-mysql-root-password --binary-mode <<-EOSQL
SET @@SESSION.SQL_LOG_BIN=0;
SET PASSWORD FOR 'root'@'localhost'= '${MARIADB_ROOT_PASSWORD_HASH}';
EOSQL
fi
mysql_note "Stopping temporary server" mysql_note "Stopping temporary server"
docker_temp_server_stop docker_temp_server_stop

View File

@ -147,9 +147,8 @@ docker_temp_server_start() {
# Stop the server. When using a local socket file mariadb-admin will block until # Stop the server. When using a local socket file mariadb-admin will block until
# the shutdown is complete. # the shutdown is complete.
docker_temp_server_stop() { docker_temp_server_stop() {
if ! MYSQL_PWD=$MARIADB_ROOT_PASSWORD mariadb-admin shutdown -uroot --socket="${SOCKET}"; then kill "$MARIADB_PID"
mysql_error "Unable to shut down server." wait "$MARIADB_PID"
fi
} }
# Verify that the minimally required password settings are set for new databases. # Verify that the minimally required password settings are set for new databases.
@ -291,22 +290,24 @@ docker_setup_db() {
# Creates root users for non-localhost hosts # Creates root users for non-localhost hosts
local rootCreate= local rootCreate=
local rootPasswordEscaped=
if [ -n "$MARIADB_ROOT_PASSWORD" ]; then
# Sets root password and creates root users for non-localhost hosts
rootPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_ROOT_PASSWORD}" )
fi
# default root to listen for connections from anywhere # default root to listen for connections from anywhere
if [ -n "$MARIADB_ROOT_HOST" ] && [ "$MARIADB_ROOT_HOST" != 'localhost' ]; then if [ -n "$MARIADB_ROOT_HOST" ] && [ "$MARIADB_ROOT_HOST" != 'localhost' ]; then
if [ -n "$MARIADB_ROOT_PASSWORD" ]; then # ref "read -d ''", no, we don't care if read finds a terminating character in this heredoc
# Sets root password and creates root users for non-localhost hosts # https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
local rootPasswordEscaped if [ -n "$MARIADB_ROOT_PASSWORD_HASH" ]; then
rootPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_ROOT_PASSWORD}" )
# no, we don't care if read finds a terminating character in this heredoc
# https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
read -r -d '' rootCreate <<-EOSQL || true read -r -d '' rootCreate <<-EOSQL || true
CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY '${rootPasswordEscaped}' ; CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY PASSWORD '${MARIADB_ROOT_PASSWORD_HASH}' ;
GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ; GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ;
EOSQL EOSQL
else else
read -r -d '' rootCreate <<-EOSQL || true read -r -d '' rootCreate <<-EOSQL || true
CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY PASSWORD '${MARIADB_ROOT_PASSWORD_HASH}' ; CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY '${rootPasswordEscaped}' ;
GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ; GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ;
EOSQL EOSQL
fi fi
@ -335,12 +336,44 @@ docker_setup_db() {
fi fi
fi fi
local rootLocalhostPass=
if [ -z "$MARIADB_ROOT_PASSWORD_HASH" ]; then
# handle MARIADB_ROOT_PASSWORD_HASH for root@localhost after /docker-entrypoint-initdb.d
rootLocalhostPass="SET PASSWORD FOR 'root'@'localhost'= PASSWORD('${rootPasswordEscaped}');"
fi
local createDatabase=
# Creates a custom database and user if specified
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Creating database ${MARIADB_DATABASE}"
createDatabase="CREATE DATABASE IF NOT EXISTS \`$MARIADB_DATABASE\`;"
fi
local createUser=
local userGrants=
if [ -n "$MARIADB_PASSWORD" ] || [ -n "$MARIADB_PASSWORD_HASH" ] && [ -n "$MARIADB_USER" ]; then
mysql_note "Creating user ${MARIADB_USER}"
if [ -n "$MARIADB_PASSWORD_HASH" ]; then
createUser="CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY PASSWORD '$MARIADB_PASSWORD_HASH';"
else
# SQL escape the user password, \ followed by '
local userPasswordEscaped
userPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_PASSWORD}" )
createUser="CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$userPasswordEscaped';"
fi
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Giving user ${MARIADB_USER} access to schema ${MARIADB_DATABASE}"
userGrants="GRANT ALL ON \`${MARIADB_DATABASE//_/\\_}\`.* TO '$MARIADB_USER'@'%';"
fi
fi
mysql_note "Securing system users (equivalent to running mysql_secure_installation)" mysql_note "Securing system users (equivalent to running mysql_secure_installation)"
# tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set # tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set
# --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding. # --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding.
docker_process_sql --dont-use-mysql-root-password --database=mysql --binary-mode <<-EOSQL docker_process_sql --dont-use-mysql-root-password --database=mysql --binary-mode <<-EOSQL
-- What's done in this file shouldn't be replicated -- Securing system users shouldn't be replicated
-- or products like mysql-fabric won't work SET @orig_sql_log_bin= @@SESSION.SQL_LOG_BIN;
SET @@SESSION.SQL_LOG_BIN=0; SET @@SESSION.SQL_LOG_BIN=0;
-- we need the SQL_MODE NO_BACKSLASH_ESCAPES mode to be clear for the password to be set -- we need the SQL_MODE NO_BACKSLASH_ESCAPES mode to be clear for the password to be set
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', ''); SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
@ -348,42 +381,19 @@ docker_setup_db() {
DROP USER IF EXISTS root@'127.0.0.1', root@'::1'; DROP USER IF EXISTS root@'127.0.0.1', root@'::1';
EXECUTE IMMEDIATE CONCAT('DROP USER IF EXISTS root@\'', @@hostname,'\''); EXECUTE IMMEDIATE CONCAT('DROP USER IF EXISTS root@\'', @@hostname,'\'');
SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${rootPasswordEscaped}') ; ${rootLocalhostPass}
${rootCreate} ${rootCreate}
${mysqlAtLocalhost} ${mysqlAtLocalhost}
${mysqlAtLocalhostGrants} ${mysqlAtLocalhostGrants}
-- pre-10.3 -- pre-10.3 only
DROP DATABASE IF EXISTS test ; DROP DATABASE IF EXISTS test ;
-- end of securing system users, rest of init now...
SET @@SESSION.SQL_LOG_BIN=@orig_sql_log_bin;
-- create users/databases
${createDatabase}
${createUser}
${userGrants}
EOSQL EOSQL
# Creates a custom database and user if specified
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Creating database ${MARIADB_DATABASE}"
docker_process_sql --database=mysql <<<"CREATE DATABASE IF NOT EXISTS \`$MARIADB_DATABASE\` ;"
fi
if [ -n "$MARIADB_PASSWORD" ] || [ -n "$MARIADB_PASSWORD_HASH" ] && [ -n "$MARIADB_USER" ]; then
mysql_note "Creating user ${MARIADB_USER}"
if [ -n "$MARIADB_PASSWORD" ]; then
# SQL escape the user password, \ followed by '
local userPasswordEscaped
userPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_PASSWORD}" )
docker_process_sql --database=mysql --binary-mode <<-EOSQL_USER
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$userPasswordEscaped';
EOSQL_USER
else
docker_process_sql --database=mysql --binary-mode <<-EOSQL_USER
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY PASSWORD '$MARIADB_PASSWORD_HASH';
EOSQL_USER
fi
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Giving user ${MARIADB_USER} access to schema ${MARIADB_DATABASE}"
docker_process_sql --database=mysql <<<"GRANT ALL ON \`${MARIADB_DATABASE//_/\\_}\`.* TO '$MARIADB_USER'@'%' ;"
fi
fi
} }
# backup the mysql database # backup the mysql database
@ -430,11 +440,8 @@ docker_mariadb_upgrade() {
mariadb-upgrade --upgrade-system-tables mariadb-upgrade --upgrade-system-tables
mysql_note "Finished mariadb-upgrade" mysql_note "Finished mariadb-upgrade"
# docker_temp_server_stop needs authentication since
# upgrade ended in FLUSH PRIVILEGES
mysql_note "Stopping temporary server" mysql_note "Stopping temporary server"
kill "$MARIADB_PID" docker_temp_server_stop
wait "$MARIADB_PID"
mysql_note "Temporary server stopped" mysql_note "Temporary server stopped"
} }
@ -509,6 +516,15 @@ _main() {
docker_setup_db docker_setup_db
docker_process_init_files /docker-entrypoint-initdb.d/* docker_process_init_files /docker-entrypoint-initdb.d/*
# Wait until after /docker-entrypoint-initdb.d is performed before setting
# root@localhost password to a hash we don't know the password for.
if [ -n "${MARIADB_ROOT_PASSWORD_HASH}" ]; then
mysql_note "Setting root@localhost password hash"
docker_process_sql --dont-use-mysql-root-password --binary-mode <<-EOSQL
SET @@SESSION.SQL_LOG_BIN=0;
SET PASSWORD FOR 'root'@'localhost'= '${MARIADB_ROOT_PASSWORD_HASH}';
EOSQL
fi
mysql_note "Stopping temporary server" mysql_note "Stopping temporary server"
docker_temp_server_stop docker_temp_server_stop

View File

@ -147,9 +147,8 @@ docker_temp_server_start() {
# Stop the server. When using a local socket file mysqladmin will block until # Stop the server. When using a local socket file mysqladmin will block until
# the shutdown is complete. # the shutdown is complete.
docker_temp_server_stop() { docker_temp_server_stop() {
if ! MYSQL_PWD=$MARIADB_ROOT_PASSWORD mysqladmin shutdown -uroot --socket="${SOCKET}"; then kill "$MARIADB_PID"
mysql_error "Unable to shut down server." wait "$MARIADB_PID"
fi
} }
# Verify that the minimally required password settings are set for new databases. # Verify that the minimally required password settings are set for new databases.
@ -291,22 +290,24 @@ docker_setup_db() {
# Creates root users for non-localhost hosts # Creates root users for non-localhost hosts
local rootCreate= local rootCreate=
local rootPasswordEscaped=
if [ -n "$MARIADB_ROOT_PASSWORD" ]; then
# Sets root password and creates root users for non-localhost hosts
rootPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_ROOT_PASSWORD}" )
fi
# default root to listen for connections from anywhere # default root to listen for connections from anywhere
if [ -n "$MARIADB_ROOT_HOST" ] && [ "$MARIADB_ROOT_HOST" != 'localhost' ]; then if [ -n "$MARIADB_ROOT_HOST" ] && [ "$MARIADB_ROOT_HOST" != 'localhost' ]; then
if [ -n "$MARIADB_ROOT_PASSWORD" ]; then # ref "read -d ''", no, we don't care if read finds a terminating character in this heredoc
# Sets root password and creates root users for non-localhost hosts # https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
local rootPasswordEscaped if [ -n "$MARIADB_ROOT_PASSWORD_HASH" ]; then
rootPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_ROOT_PASSWORD}" )
# no, we don't care if read finds a terminating character in this heredoc
# https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
read -r -d '' rootCreate <<-EOSQL || true read -r -d '' rootCreate <<-EOSQL || true
CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY '${rootPasswordEscaped}' ; CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY PASSWORD '${MARIADB_ROOT_PASSWORD_HASH}' ;
GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ; GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ;
EOSQL EOSQL
else else
read -r -d '' rootCreate <<-EOSQL || true read -r -d '' rootCreate <<-EOSQL || true
CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY PASSWORD '${MARIADB_ROOT_PASSWORD_HASH}' ; CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY '${rootPasswordEscaped}' ;
GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ; GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ;
EOSQL EOSQL
fi fi
@ -335,12 +336,44 @@ docker_setup_db() {
fi fi
fi fi
local rootLocalhostPass=
if [ -z "$MARIADB_ROOT_PASSWORD_HASH" ]; then
# handle MARIADB_ROOT_PASSWORD_HASH for root@localhost after /docker-entrypoint-initdb.d
rootLocalhostPass="SET PASSWORD FOR 'root'@'localhost'= PASSWORD('${rootPasswordEscaped}');"
fi
local createDatabase=
# Creates a custom database and user if specified
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Creating database ${MARIADB_DATABASE}"
createDatabase="CREATE DATABASE IF NOT EXISTS \`$MARIADB_DATABASE\`;"
fi
local createUser=
local userGrants=
if [ -n "$MARIADB_PASSWORD" ] || [ -n "$MARIADB_PASSWORD_HASH" ] && [ -n "$MARIADB_USER" ]; then
mysql_note "Creating user ${MARIADB_USER}"
if [ -n "$MARIADB_PASSWORD_HASH" ]; then
createUser="CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY PASSWORD '$MARIADB_PASSWORD_HASH';"
else
# SQL escape the user password, \ followed by '
local userPasswordEscaped
userPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_PASSWORD}" )
createUser="CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$userPasswordEscaped';"
fi
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Giving user ${MARIADB_USER} access to schema ${MARIADB_DATABASE}"
userGrants="GRANT ALL ON \`${MARIADB_DATABASE//_/\\_}\`.* TO '$MARIADB_USER'@'%';"
fi
fi
mysql_note "Securing system users (equivalent to running mysql_secure_installation)" mysql_note "Securing system users (equivalent to running mysql_secure_installation)"
# tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set # tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set
# --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding. # --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding.
docker_process_sql --dont-use-mysql-root-password --database=mysql --binary-mode <<-EOSQL docker_process_sql --dont-use-mysql-root-password --database=mysql --binary-mode <<-EOSQL
-- What's done in this file shouldn't be replicated -- Securing system users shouldn't be replicated
-- or products like mysql-fabric won't work SET @orig_sql_log_bin= @@SESSION.SQL_LOG_BIN;
SET @@SESSION.SQL_LOG_BIN=0; SET @@SESSION.SQL_LOG_BIN=0;
-- we need the SQL_MODE NO_BACKSLASH_ESCAPES mode to be clear for the password to be set -- we need the SQL_MODE NO_BACKSLASH_ESCAPES mode to be clear for the password to be set
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', ''); SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
@ -348,42 +381,19 @@ docker_setup_db() {
DROP USER IF EXISTS root@'127.0.0.1', root@'::1'; DROP USER IF EXISTS root@'127.0.0.1', root@'::1';
EXECUTE IMMEDIATE CONCAT('DROP USER IF EXISTS root@\'', @@hostname,'\''); EXECUTE IMMEDIATE CONCAT('DROP USER IF EXISTS root@\'', @@hostname,'\'');
SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${rootPasswordEscaped}') ; ${rootLocalhostPass}
${rootCreate} ${rootCreate}
${mysqlAtLocalhost} ${mysqlAtLocalhost}
${mysqlAtLocalhostGrants} ${mysqlAtLocalhostGrants}
-- pre-10.3 -- pre-10.3 only
DROP DATABASE IF EXISTS test ; DROP DATABASE IF EXISTS test ;
-- end of securing system users, rest of init now...
SET @@SESSION.SQL_LOG_BIN=@orig_sql_log_bin;
-- create users/databases
${createDatabase}
${createUser}
${userGrants}
EOSQL EOSQL
# Creates a custom database and user if specified
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Creating database ${MARIADB_DATABASE}"
docker_process_sql --database=mysql <<<"CREATE DATABASE IF NOT EXISTS \`$MARIADB_DATABASE\` ;"
fi
if [ -n "$MARIADB_PASSWORD" ] || [ -n "$MARIADB_PASSWORD_HASH" ] && [ -n "$MARIADB_USER" ]; then
mysql_note "Creating user ${MARIADB_USER}"
if [ -n "$MARIADB_PASSWORD" ]; then
# SQL escape the user password, \ followed by '
local userPasswordEscaped
userPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_PASSWORD}" )
docker_process_sql --database=mysql --binary-mode <<-EOSQL_USER
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$userPasswordEscaped';
EOSQL_USER
else
docker_process_sql --database=mysql --binary-mode <<-EOSQL_USER
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY PASSWORD '$MARIADB_PASSWORD_HASH';
EOSQL_USER
fi
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Giving user ${MARIADB_USER} access to schema ${MARIADB_DATABASE}"
docker_process_sql --database=mysql <<<"GRANT ALL ON \`${MARIADB_DATABASE//_/\\_}\`.* TO '$MARIADB_USER'@'%' ;"
fi
fi
} }
# backup the mysql database # backup the mysql database
@ -430,11 +440,8 @@ docker_mariadb_upgrade() {
mysql_upgrade --upgrade-system-tables mysql_upgrade --upgrade-system-tables
mysql_note "Finished mariadb-upgrade" mysql_note "Finished mariadb-upgrade"
# docker_temp_server_stop needs authentication since
# upgrade ended in FLUSH PRIVILEGES
mysql_note "Stopping temporary server" mysql_note "Stopping temporary server"
kill "$MARIADB_PID" docker_temp_server_stop
wait "$MARIADB_PID"
mysql_note "Temporary server stopped" mysql_note "Temporary server stopped"
} }
@ -509,6 +516,15 @@ _main() {
docker_setup_db docker_setup_db
docker_process_init_files /docker-entrypoint-initdb.d/* docker_process_init_files /docker-entrypoint-initdb.d/*
# Wait until after /docker-entrypoint-initdb.d is performed before setting
# root@localhost password to a hash we don't know the password for.
if [ -n "${MARIADB_ROOT_PASSWORD_HASH}" ]; then
mysql_note "Setting root@localhost password hash"
docker_process_sql --dont-use-mysql-root-password --binary-mode <<-EOSQL
SET @@SESSION.SQL_LOG_BIN=0;
SET PASSWORD FOR 'root'@'localhost'= '${MARIADB_ROOT_PASSWORD_HASH}';
EOSQL
fi
mysql_note "Stopping temporary server" mysql_note "Stopping temporary server"
docker_temp_server_stop docker_temp_server_stop