diff options
author | Timothy Smith <timothy.smith@sun.com> | 2009-10-30 14:28:33 -0600 |
---|---|---|
committer | Timothy Smith <timothy.smith@sun.com> | 2009-10-30 14:28:33 -0600 |
commit | 141e79616303320289b33323cedbcdbe2d78c445 (patch) | |
tree | a0c3d83edaed026f2035de315751b6a3bd45cadd /scripts | |
parent | 7f9656369f97803bb10a1111f60d60db295b82a4 (diff) | |
download | mariadb-git-141e79616303320289b33323cedbcdbe2d78c445.tar.gz |
Bug#35106: mysql_secure_installation fails on Windows, missing "use
Term::ReadKey"
Add the missing module import. Also, while here, fix a few glaring problems
with the script, and ensure that it behaves properly. It seems this script
may have never been working correctly (e.g., reading password didn't chomp()
the result, so password was set with \n at the end; comparing the re-typed
password to original was done with inverted test).
Add END { cleanup(); } block to ensure the script removes temporary working
files.
Add SIG{INT} / SIG{QUIT} handler.
Do a bit of reorganization to make the code easier to understand.
Limit failed connection attempts to 3.
Use ./bin/mysql if it exists, and then fall back on mysql in PATH (before it
assumed 'mysql' in the path). Print a nicer error if 'mysql' can't be called.
This has been tested on Windows (ActivePerl from cmd.exe, no cygwin needed)
and Linux.
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/mysql_secure_installation.pl.in | 169 |
1 files changed, 92 insertions, 77 deletions
diff --git a/scripts/mysql_secure_installation.pl.in b/scripts/mysql_secure_installation.pl.in index 4eeb50e6d2f..281f3558808 100755 --- a/scripts/mysql_secure_installation.pl.in +++ b/scripts/mysql_secure_installation.pl.in @@ -17,16 +17,41 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use Fcntl; +use File::Spec; +use if $^O eq 'MSWin32', 'Term::ReadKey' => qw/ReadMode/; use strict; my $config = ".my.cnf.$$"; my $command = ".mysql.$$"; my $hadpass = 0; +my $mysql; # How to call the mysql client +my $rootpass = ""; -# FIXME -# trap "interrupt" 2 -my $rootpass = ""; +$SIG{QUIT} = $SIG{INT} = sub { + print "\nAborting!\n\n"; + echo_on(); + cleanup(); + exit 1; +}; + + +END { + # Remove temporary files, even if exiting via die(), etc. + cleanup(); +} + + +sub read_without_echo { + my ($prompt) = @_; + print $prompt; + echo_off(); + my $answer = <STDIN>; + echo_on(); + print "\n"; + chomp($answer); + return $answer; +} sub echo_on { if ($^O eq 'MSWin32') { @@ -55,6 +80,25 @@ sub write_file { } sub prepare { + # Locate the mysql client; look in current directory first, then + # in path + our $SAVEERR; # Suppress Perl warning message + open SAVEERR, ">& STDERR"; + close STDERR; + for my $m (File::Spec->catfile('bin', 'mysql'), 'mysql') { + # mysql --version should always work + qx($m --no-defaults --version); + next unless $? == 0; + + $mysql = $m; + last; + } + open STDERR, ">& SAVEERR"; + + die "Can't find a 'mysql' client in PATH or ./bin\n" + unless $mysql; + + # Create safe files to avoid leaking info to other users foreach my $file ( $config, $command ) { next if -f $file; # Already exists local *FILE; @@ -67,8 +111,9 @@ sub prepare { sub do_query { my $query = shift; write_file($command, $query); - system("mysql --defaults-file=$config < $command"); - return $?; + my $rv = system("$mysql --defaults-file=$config < $command"); + die "Failed to execute mysql client '$mysql'\n" if $rv == -1; + return ($rv == 0 ? 1 : undef); } sub make_config { @@ -82,12 +127,9 @@ sub make_config { } sub get_root_password { - my $status = 1; - while ( $status == 1 ) { - echo_off(); - print "Enter current password for root (enter for none): "; - my $password = <STDIN>; - echo_on(); + my $attempts = 3; + for (;;) { + my $password = read_without_echo("Enter current password for root (enter for none): "); if ( $password ) { $hadpass = 1; } else { @@ -95,64 +137,56 @@ sub get_root_password { } $rootpass = $password; make_config($rootpass); - do_query(""); - $status = $?; + last if do_query(""); + + die "Unable to connect to the server as root user, giving up.\n" + if --$attempts == 0; } print "OK, successfully used password, moving on...\n\n"; } sub set_root_password { - echo_off(); - print "New password: "; - my $password1 = <STDIN>; - print "\nRe-enter new password: "; - my $password2 = <STDIN>; - print "\n"; - echo_on(); + my $password1; + for (;;) { + $password1 = read_without_echo("New password: "); - if ( $password1 eq $password2 ) { - print "Sorry, passwords do not match.\n\n"; - return 1; - } + if ( !$password1 ) { + print "Sorry, you can't use an empty password here.\n\n"; + next; + } - if ( !$password1 ) { - print "Sorry, you can't use an empty password here.\n\n"; - return 1; - } + my $password2 = read_without_echo("Re-enter new password: "); - do_query("UPDATE mysql.user SET Password=PASSWORD('$password1') WHERE User='root';"); - if ( $? == 0 ) { - print "Password updated successfully!\n"; - print "Reloading privilege tables..\n"; - if ( !reload_privilege_tables() ) { - exit 1; + if ( $password1 ne $password2 ) { + print "Sorry, passwords do not match.\n\n"; + next; } - print "\n"; - $rootpass = $password1; - make_config($rootpass); - } else { - print "Password update failed!\n"; - exit 1; + + last; } - return 0; + # FIXME: Quote password1 properly for SQL + do_query("UPDATE mysql.user SET Password=PASSWORD('$password1') WHERE User='root';") + or die "Password update failed!\n"; + + print "Password updated successfully!\n"; + print "Reloading privilege tables..\n"; + reload_privilege_tables() + or die "Can not continue.\n"; + + print "\n"; + $rootpass = $password1; + make_config($rootpass); } sub remove_anonymous_users { - do_query("DELETE FROM mysql.user WHERE User='';"); - if ( $? == 0 ) { - print " ... Success!\n"; - } else { - print " ... Failed!\n"; - exit 1; - } - - return 0; + do_query("DELETE FROM mysql.user WHERE User='';") + or die print " ... Failed!\n"; + print " ... Success!\n"; } sub remove_remote_root { - do_query("DELETE FROM mysql.user WHERE User='root' AND Host!='localhost';"); - if ( $? == 0 ) { + if (do_query("DELETE FROM mysql.user WHERE User='root' AND Host!='localhost';")) { print " ... Success!\n"; } else { print " ... Failed!\n"; @@ -161,44 +195,31 @@ sub remove_remote_root { sub remove_test_database { print " - Dropping test database...\n"; - do_query("DROP DATABASE test;"); - if ( $? == 0 ) { + if (do_query("DROP DATABASE test;")) { print " ... Success!\n"; } else { print " ... Failed! Not critical, keep moving...\n"; } print " - Removing privileges on test database...\n"; - do_query("DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%'"); - if ( $? == 0 ) { + if (do_query("DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%'")) { print " ... Success!\n"; } else { print " ... Failed! Not critical, keep moving...\n"; } - - return 0; } sub reload_privilege_tables { - do_query("FLUSH PRIVILEGES;"); - if ( $? == 0 ) { + if (do_query("FLUSH PRIVILEGES;")) { print " ... Success!\n"; - return 0; + return 1; } else { print " ... Failed!\n"; - return 1; + return undef; } } -sub interrupt { - print "\nAborting!\n\n"; - cleanup(); - echo_on(); - exit 1; -} - sub cleanup { - print "Cleaning up...\n"; unlink($config,$command); } @@ -242,11 +263,7 @@ my $reply = <STDIN>; if ( $reply =~ /n/i ) { print " ... skipping.\n"; } else { - my $status = 1; - while ( $status == 1 ) { - set_root_password(); - $status = $?; - } + set_root_password(); } print "\n"; @@ -334,8 +351,6 @@ if ( $reply =~ /n/i ) { } print "\n"; -cleanup(); - print <<HERE; |