MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Timothy Smith Date:October 30 2009 8:37pm
Subject:bzr commit into mysql-5.0-bugteam branch (timothy.smith:2834) Bug#35106
View as plain text  
#At file:///home/tsmith/m/bzr/bugteam/b35106-50/ based on revid:alexey.kopytov@stripped

 2834 Timothy Smith	2009-10-30
      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.

    modified:
      scripts/mysql_secure_installation.pl.in
=== modified file 'scripts/mysql_secure_installation.pl.in'
--- a/scripts/mysql_secure_installation.pl.in	2007-12-28 21:58:54 +0000
+++ b/scripts/mysql_secure_installation.pl.in	2009-10-30 20:28:33 +0000
@@ -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();
-
-  if ( $password1 eq $password2 ) {
-    print "Sorry, passwords do not match.\n\n";
-    return 1;
-  }
+  my $password1;
+  for (;;) {
+    $password1 = read_without_echo("New password: ");
+
+    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;
 
 


Attachment: [text/bzr-bundle] bzr/timothy.smith@sun.com-20091030202833-csq1et337cpf6kaz.bundle
Thread
bzr commit into mysql-5.0-bugteam branch (timothy.smith:2834) Bug#35106Timothy Smith30 Oct