summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorAlexander Nozdrin <alik@sun.com>2009-12-12 23:38:59 +0300
committerAlexander Nozdrin <alik@sun.com>2009-12-12 23:38:59 +0300
commitaceea2342faa7e9a4b8b5cea6d18c0801e6975b6 (patch)
tree2a2432e481d124691d9fa4b39d8a192264178bd1 /scripts
parent376cf4275f28f6b8167eaf19b2c66dee41fbc5c5 (diff)
parent567671368723c704d60902b4d0ccff951b414552 (diff)
downloadmariadb-git-aceea2342faa7e9a4b8b5cea6d18c0801e6975b6.tar.gz
Manual merge from mysql-trunk-merge.
Conflicts: - extra/comp_err.c - mysql-test/collections/default.experimental - mysql-test/r/archive.result - mysql-test/r/select.result - mysql-test/suite/binlog/r/binlog_unsafe.result - mysql-test/suite/binlog/t/binlog_unsafe.test - mysql-test/suite/rpl/t/disabled.def - mysql-test/t/archive.test - mysql-test/t/select.test - sql/item.cc - sql/item.h - sql/item_timefunc.cc - sql/sql_base.cc - sql/sql_delete.cc - sql/sql_load.cc - sql/sql_partition.cc - sql/sql_table.cc - storage/innobase/handler/ha_innodb.cc - vio/vio.c
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/make_win_bin_dist2
-rwxr-xr-xscripts/mysql_secure_installation.pl.in193
-rw-r--r--scripts/mysql_secure_installation.sh34
3 files changed, 144 insertions, 85 deletions
diff --git a/scripts/make_win_bin_dist b/scripts/make_win_bin_dist
index bf148c45150..c5d429c2752 100755
--- a/scripts/make_win_bin_dist
+++ b/scripts/make_win_bin_dist
@@ -338,7 +338,7 @@ mkdir $DESTDIR/mysql-test
cp mysql-test/mysql-test-run.pl $DESTDIR/mysql-test/
cp mysql-test/mysql-stress-test.pl $DESTDIR/mysql-test/
cp mysql-test/README $DESTDIR/mysql-test/
-cp -R mysql-test/{t,r,include,suite,std_data,lib} $DESTDIR/mysql-test/
+cp -R mysql-test/{t,r,include,suite,std_data,lib,collections} $DESTDIR/mysql-test/
# Note that this will not copy "extra" if a soft link
if [ -d mysql-test/extra ] ; then
diff --git a/scripts/mysql_secure_installation.pl.in b/scripts/mysql_secure_installation.pl.in
index 4eeb50e6d2f..25339f9b916 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;
@@ -64,30 +108,50 @@ sub prepare {
}
}
+# Simple escape mechanism (\-escape any ' and \), suitable for two contexts:
+# - single-quoted SQL strings
+# - single-quoted option values on the right hand side of = in my.cnf
+#
+# These two contexts don't handle escapes identically. SQL strings allow
+# quoting any character (\C => C, for any C), but my.cnf parsing allows
+# quoting only \, ' or ". For example, password='a\b' quotes a 3-character
+# string in my.cnf, but a 2-character string in SQL.
+#
+# This simple escape works correctly in both places.
+sub basic_single_escape {
+ my ($str) = @_;
+ # Inside a character class, \ is not special; this escapes both \ and '
+ $str =~ s/([\'])/\\$1/g;
+ return $str;
+}
+
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");
+ # system() returns -1 if exec fails (e.g., command not found, etc.); die
+ # in this case because nothing is going to work
+ die "Failed to execute mysql client '$mysql'\n" if $rv == -1;
+ # Return true if query executed OK, or false if there was some problem
+ # (for example, SQL error or wrong password)
+ return ($rv == 0 ? 1 : undef);
}
sub make_config {
my $password = shift;
+ my $esc_pass = basic_single_escape($rootpass);
write_file($config,
"# mysql_secure_installation config file",
"[mysql]",
"user=root",
- "password=$rootpass");
+ "password='$esc_pass'");
}
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 +159,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;
+ my $esc_pass = basic_single_escape($password1);
+ do_query("UPDATE mysql.user SET Password=PASSWORD('$esc_pass') 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 +217,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 +285,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 +373,6 @@ if ( $reply =~ /n/i ) {
}
print "\n";
-cleanup();
-
print <<HERE;
diff --git a/scripts/mysql_secure_installation.sh b/scripts/mysql_secure_installation.sh
index 6c2d88d6d29..25d6343ee2c 100644
--- a/scripts/mysql_secure_installation.sh
+++ b/scripts/mysql_secure_installation.sh
@@ -38,16 +38,39 @@ prepare() {
}
do_query() {
- echo $1 >$command
+ echo "$1" >$command
+ #sed 's,^,> ,' < $command # Debugging
mysql --defaults-file=$config <$command
return $?
}
+# Simple escape mechanism (\-escape any ' and \), suitable for two contexts:
+# - single-quoted SQL strings
+# - single-quoted option values on the right hand side of = in my.cnf
+#
+# These two contexts don't handle escapes identically. SQL strings allow
+# quoting any character (\C => C, for any C), but my.cnf parsing allows
+# quoting only \, ' or ". For example, password='a\b' quotes a 3-character
+# string in my.cnf, but a 2-character string in SQL.
+#
+# This simple escape works correctly in both places.
+basic_single_escape () {
+ # The quoting on this sed command is a bit complex. Single-quoted strings
+ # don't allow *any* escape mechanism, so they cannot contain a single
+ # quote. The string sed gets (as argv[1]) is: s/\(['\]\)/\\\1/g
+ #
+ # Inside a character class, \ and ' are not special, so the ['\] character
+ # class is balanced and contains two characters.
+ echo "$1" | sed 's/\(['"'"'\]\)/\\\1/g'
+}
+
make_config() {
echo "# mysql_secure_installation config file" >$config
echo "[mysql]" >>$config
echo "user=root" >>$config
- echo "password=$rootpass" >>$config
+ esc_pass=`basic_single_escape "$rootpass"`
+ echo "password='$esc_pass'" >>$config
+ #sed 's,^,> ,' < $config # Debugging
}
get_root_password() {
@@ -94,13 +117,12 @@ set_root_password() {
return 1
fi
- do_query "UPDATE mysql.user SET Password=PASSWORD('$password1') WHERE User='root';"
+ esc_pass=`basic_single_escape "$password1"`
+ do_query "UPDATE mysql.user SET Password=PASSWORD('$esc_pass') WHERE User='root';"
if [ $? -eq 0 ]; then
echo "Password updated successfully!"
echo "Reloading privilege tables.."
- if ! reload_privilege_tables; then
- exit 1
- fi
+ reload_privilege_tables || exit 1
echo
rootpass=$password1
make_config