Skip to content

Commit

Permalink
mysql_install_db enhancements to facilitate Debian bug#848616 fix
Browse files Browse the repository at this point in the history
In Debian, the default install is made more secure by omitting the anonymous
user and by making the root account authenticate by unix socket
authentication instead of the default password-less root. However, Debian
hard-codes this change in mysql_install_db, which breaks that program for
other users.

This commit instead implements new general options for mysql_install_db that
can be used by anyone to similarly perform a more secure install:

  --skip-auth-anonymous-user: omits the anonymous user.

  --auth-root-authentication-method=normal: Keeps the existing behaviour
    with a password-less root account. Currently on by default.

  --auth-root-socket-user=USER
  --auth-root-authentication-method=socket: creates the MariaDB root user
    with the name USER (defaults to 'root') and using unix socket
    authentication. This way, only that user has MariaDB root access
    after install.

The idea with --auth-root-authentication-method=normal is that
applications that need this behaviour can give that option explicitly.
Then eventually we could make --auth-root-authentication-method=socket
the default, giving a more secure default installation.

Note that it is perfectly possible to do a secure install with
--auth-root-authentication-method=normal. For example, installing a
private server just for local access by a single OS-level user, by
using --skip-networking and putting the connection socket in a
location without public access. So it is important to preserve this
API for backwards compatibility.
  • Loading branch information
knielsen committed Jan 17, 2017
1 parent 719e811 commit 736afe8
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 22 deletions.
Expand Up @@ -8,8 +8,8 @@
## DP: http://bugs.mysql.com/bug.php?id=6901

@DPATCH@
--- old/scripts/mysql_system_tables_data.sql 2008-12-04 22:59:44.000000000 +0100
+++ new/scripts/mysql_system_tables_data.sql 2008-12-04 23:00:07.000000000 +0100
--- a/scripts/mysql_system_tables_data.sql
+++ b/scripts/mysql_system_tables_data.sql
@@ -26,16 +26,6 @@
-- a plain character
SELECT LOWER( REPLACE((SELECT REPLACE(@@hostname,'_','\_')),'%','\%') )INTO @current_hostname;
Expand All @@ -26,14 +26,14 @@
-
-- Fill "user" table with default users allowing root access
-- from local machine if "user" table didn't exist before
CREATE TEMPORARY TABLE tmp_user LIKE user;
@@ -43,8 +33,6 @@ INSERT INTO tmp_user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','
REPLACE INTO tmp_user SELECT @current_hostname,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N','',0 FROM dual WHERE @current_hostname != 'localhost';
REPLACE INTO tmp_user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N','',0);
REPLACE INTO tmp_user VALUES ('::1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N', '', 0);
-INSERT INTO tmp_user (host,user) VALUES ('localhost','');
-INSERT INTO tmp_user (host,user) SELECT @current_hostname,'' FROM dual WHERE @current_hostname != 'localhost';
INSERT INTO user SELECT * FROM tmp_user WHERE @had_user_table=0;
DROP TABLE tmp_user;
CREATE TEMPORARY TABLE tmp_user_nopasswd LIKE user;
@@ -48,9 +38,6 @@ REPLACE INTO tmp_user_nopasswd VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y'
REPLACE INTO tmp_user_nopasswd VALUES ('::1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N', '', 0);
-- More secure root account using unix sucket auth.
INSERT INTO tmp_user_socket VALUES ('localhost',IFNULL(@auth_root_socket, 'root'),'','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'unix_socket','','N', 'N','', 0);
--- Anonymous user with no privileges.
-INSERT INTO tmp_user_anonymous (host,user) VALUES ('localhost','');
-INSERT INTO tmp_user_anonymous (host,user) SELECT @current_hostname,'' FROM dual WHERE @current_hostname != 'localhost';

INSERT INTO user SELECT * FROM tmp_user_nopasswd WHERE @had_user_table=0 AND @skip_auth_root_nopasswd IS NULL;
INSERT INTO user SELECT * FROM tmp_user_socket WHERE @had_user_table=0 AND @auth_root_socket IS NOT NULL;
40 changes: 39 additions & 1 deletion scripts/mysql_install_db.sh
Expand Up @@ -34,11 +34,26 @@ force=0
in_rpm=0
ip_only=0
cross_bootstrap=0
install_params=""
auth_root_authentication_method=normal
auth_root_socket_user='root'

usage()
{
cat <<EOF
Usage: $0 [OPTIONS]
--auth-root-authentication-method=normal|socket
Chooses the authentication method for the created initial
root user. The default is 'normal' to creates a root user
that can login without password, which can be insecure.
The alternative 'socket' allows only the system root user
to login as MariaDB root; this requires the unix socket
authentication plugin.
--auth-root-socket-user=user
Used with --auth-root-authentication-method=socket. It
specifies the name of the MariaDB root account, as well
as of the system account allowed to access it. Defaults
to 'root'.
--basedir=path The path to the MariaDB installation directory.
--builddir=path If using --srcdir with out-of-directory builds, you
will need to set this to the location of the build
Expand All @@ -59,6 +74,8 @@ Usage: $0 [OPTIONS]
--defaults-file=path Read only this configuration file.
--rpm For internal use. This option is used by RPM files
during the MariaDB installation process.
--skip-auth-anonymous-user
Do not install an unprivileged anonymous user.
--skip-name-resolve Use IP addresses rather than hostnames when creating
grant table entries. This option can be useful if
your DNS does not work.
Expand Down Expand Up @@ -141,6 +158,17 @@ parse_arguments()
#
# --windows is a deprecated alias
cross_bootstrap=1 ;;
--skip-auth-anonymous-user)
install_params="$install_params
SET @skip_auth_anonymous=1;" ;;
--auth-root-authentication-method=normal)
auth_root_authentication_method=normal ;;
--auth-root-authentication-method=socket)
auth_root_authentication_method=socket ;;
--auth-root-authentication-method=*)
usage ;;
--auth-root-socket-user=*)
auth_root_socket_user="$(parse_arg "$arg")" ;;

*)
if test -n "$pick_args"
Expand Down Expand Up @@ -430,7 +458,17 @@ mysqld_install_cmd_line()

# Create the system and help tables by passing them to "mysqld --bootstrap"
s_echo "Installing MariaDB/MySQL system tables in '$ldata' ..."
if { echo "use mysql;"; cat "$create_system_tables" "$create_system_tables2" "$fill_system_tables"; } | eval "$filter_cmd_line" | mysqld_install_cmd_line > /dev/null
case "$auth_root_authentication_method" in
normal)
install_params="$install_params
SET @skip_auth_root_nopasswd=NULL;
SET @auth_root_socket=NULL;" ;;
socket)
install_params="$install_params
SET @skip_auth_root_nopasswd=1;
SET @auth_root_socket='$auth_root_socket_user';" ;;
esac
if { echo "use mysql;$install_params"; cat "$create_system_tables" "$create_system_tables2" "$fill_system_tables"; } | eval "$filter_cmd_line" | mysqld_install_cmd_line > /dev/null
then
s_echo "OK"
else
Expand Down
27 changes: 18 additions & 9 deletions scripts/mysql_system_tables_data.sql
Expand Up @@ -38,15 +38,24 @@ DROP TABLE tmp_db;

-- Fill "user" table with default users allowing root access
-- from local machine if "user" table didn't exist before
CREATE TEMPORARY TABLE tmp_user LIKE user;
INSERT INTO tmp_user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N', 'N','', 0);
REPLACE INTO tmp_user SELECT @current_hostname,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N','',0 FROM dual WHERE @current_hostname != 'localhost';
REPLACE INTO tmp_user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N','',0);
REPLACE INTO tmp_user VALUES ('::1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N', '', 0);
INSERT INTO tmp_user (host,user) VALUES ('localhost','');
INSERT INTO tmp_user (host,user) SELECT @current_hostname,'' FROM dual WHERE @current_hostname != 'localhost';
INSERT INTO user SELECT * FROM tmp_user WHERE @had_user_table=0;
DROP TABLE tmp_user;
CREATE TEMPORARY TABLE tmp_user_nopasswd LIKE user;
CREATE TEMPORARY TABLE tmp_user_socket LIKE user;
CREATE TEMPORARY TABLE tmp_user_anonymous LIKE user;
-- Classic passwordless root account.
INSERT INTO tmp_user_nopasswd VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N', 'N','', 0);
REPLACE INTO tmp_user_nopasswd SELECT @current_hostname,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N','',0 FROM dual WHERE @current_hostname != 'localhost';
REPLACE INTO tmp_user_nopasswd VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N','',0);
REPLACE INTO tmp_user_nopasswd VALUES ('::1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N', '', 0);
-- More secure root account using unix sucket auth.
INSERT INTO tmp_user_socket VALUES ('localhost',IFNULL(@auth_root_socket, 'root'),'','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'unix_socket','','N', 'N','', 0);
-- Anonymous user with no privileges.
INSERT INTO tmp_user_anonymous (host,user) VALUES ('localhost','');
INSERT INTO tmp_user_anonymous (host,user) SELECT @current_hostname,'' FROM dual WHERE @current_hostname != 'localhost';

INSERT INTO user SELECT * FROM tmp_user_nopasswd WHERE @had_user_table=0 AND @skip_auth_root_nopasswd IS NULL;
INSERT INTO user SELECT * FROM tmp_user_socket WHERE @had_user_table=0 AND @auth_root_socket IS NOT NULL;
INSERT INTO user SELECT * FROM tmp_user_anonymous WHERE @had_user_table=0 AND @skip_auth_anonymous IS NULL;
DROP TABLE tmp_user_nopasswd, tmp_user_socket, tmp_user_anonymous;

CREATE TEMPORARY TABLE tmp_proxies_priv LIKE proxies_priv;
INSERT INTO tmp_proxies_priv VALUES ('localhost', 'root', '', '', TRUE, '', now());
Expand Down

0 comments on commit 736afe8

Please sign in to comment.