auto-merge
This commit is contained in:
commit
f6406bcdd8
@ -17,17 +17,42 @@
|
|||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
use Fcntl;
|
use Fcntl;
|
||||||
|
use File::Spec;
|
||||||
|
use if $^O eq 'MSWin32', 'Term::ReadKey' => qw/ReadMode/;
|
||||||
use strict;
|
use strict;
|
||||||
|
|
||||||
my $config = ".my.cnf.$$";
|
my $config = ".my.cnf.$$";
|
||||||
my $command = ".mysql.$$";
|
my $command = ".mysql.$$";
|
||||||
my $hadpass = 0;
|
my $hadpass = 0;
|
||||||
|
my $mysql; # How to call the mysql client
|
||||||
# FIXME
|
|
||||||
# trap "interrupt" 2
|
|
||||||
|
|
||||||
my $rootpass = "";
|
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 {
|
sub echo_on {
|
||||||
if ($^O eq 'MSWin32') {
|
if ($^O eq 'MSWin32') {
|
||||||
ReadMode('normal');
|
ReadMode('normal');
|
||||||
@ -55,6 +80,25 @@ sub write_file {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub prepare {
|
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 ) {
|
foreach my $file ( $config, $command ) {
|
||||||
next if -f $file; # Already exists
|
next if -f $file; # Already exists
|
||||||
local *FILE;
|
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 {
|
sub do_query {
|
||||||
my $query = shift;
|
my $query = shift;
|
||||||
write_file($command, $query);
|
write_file($command, $query);
|
||||||
system("mysql --defaults-file=$config < $command");
|
my $rv = system("$mysql --defaults-file=$config < $command");
|
||||||
return $?;
|
# 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 {
|
sub make_config {
|
||||||
my $password = shift;
|
my $password = shift;
|
||||||
|
|
||||||
|
my $esc_pass = basic_single_escape($rootpass);
|
||||||
write_file($config,
|
write_file($config,
|
||||||
"# mysql_secure_installation config file",
|
"# mysql_secure_installation config file",
|
||||||
"[mysql]",
|
"[mysql]",
|
||||||
"user=root",
|
"user=root",
|
||||||
"password=$rootpass");
|
"password='$esc_pass'");
|
||||||
}
|
}
|
||||||
|
|
||||||
sub get_root_password {
|
sub get_root_password {
|
||||||
my $status = 1;
|
my $attempts = 3;
|
||||||
while ( $status == 1 ) {
|
for (;;) {
|
||||||
echo_off();
|
my $password = read_without_echo("Enter current password for root (enter for none): ");
|
||||||
print "Enter current password for root (enter for none): ";
|
|
||||||
my $password = <STDIN>;
|
|
||||||
echo_on();
|
|
||||||
if ( $password ) {
|
if ( $password ) {
|
||||||
$hadpass = 1;
|
$hadpass = 1;
|
||||||
} else {
|
} else {
|
||||||
@ -95,64 +159,56 @@ sub get_root_password {
|
|||||||
}
|
}
|
||||||
$rootpass = $password;
|
$rootpass = $password;
|
||||||
make_config($rootpass);
|
make_config($rootpass);
|
||||||
do_query("");
|
last if do_query("");
|
||||||
$status = $?;
|
|
||||||
|
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";
|
print "OK, successfully used password, moving on...\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
sub set_root_password {
|
sub set_root_password {
|
||||||
echo_off();
|
my $password1;
|
||||||
print "New password: ";
|
for (;;) {
|
||||||
my $password1 = <STDIN>;
|
$password1 = read_without_echo("New password: ");
|
||||||
print "\nRe-enter new password: ";
|
|
||||||
my $password2 = <STDIN>;
|
|
||||||
print "\n";
|
|
||||||
echo_on();
|
|
||||||
|
|
||||||
if ( $password1 eq $password2 ) {
|
if ( !$password1 ) {
|
||||||
print "Sorry, passwords do not match.\n\n";
|
print "Sorry, you can't use an empty password here.\n\n";
|
||||||
return 1;
|
next;
|
||||||
}
|
|
||||||
|
|
||||||
if ( !$password1 ) {
|
|
||||||
print "Sorry, you can't use an empty password here.\n\n";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
print "\n";
|
|
||||||
$rootpass = $password1;
|
my $password2 = read_without_echo("Re-enter new password: ");
|
||||||
make_config($rootpass);
|
|
||||||
} else {
|
if ( $password1 ne $password2 ) {
|
||||||
print "Password update failed!\n";
|
print "Sorry, passwords do not match.\n\n";
|
||||||
exit 1;
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
sub remove_anonymous_users {
|
||||||
do_query("DELETE FROM mysql.user WHERE User='';");
|
do_query("DELETE FROM mysql.user WHERE User='';")
|
||||||
if ( $? == 0 ) {
|
or die print " ... Failed!\n";
|
||||||
print " ... Success!\n";
|
print " ... Success!\n";
|
||||||
} else {
|
|
||||||
print " ... Failed!\n";
|
|
||||||
exit 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub remove_remote_root {
|
sub remove_remote_root {
|
||||||
do_query("DELETE FROM mysql.user WHERE User='root' AND Host!='localhost';");
|
if (do_query("DELETE FROM mysql.user WHERE User='root' AND Host!='localhost';")) {
|
||||||
if ( $? == 0 ) {
|
|
||||||
print " ... Success!\n";
|
print " ... Success!\n";
|
||||||
} else {
|
} else {
|
||||||
print " ... Failed!\n";
|
print " ... Failed!\n";
|
||||||
@ -161,44 +217,31 @@ sub remove_remote_root {
|
|||||||
|
|
||||||
sub remove_test_database {
|
sub remove_test_database {
|
||||||
print " - Dropping test database...\n";
|
print " - Dropping test database...\n";
|
||||||
do_query("DROP DATABASE test;");
|
if (do_query("DROP DATABASE test;")) {
|
||||||
if ( $? == 0 ) {
|
|
||||||
print " ... Success!\n";
|
print " ... Success!\n";
|
||||||
} else {
|
} else {
|
||||||
print " ... Failed! Not critical, keep moving...\n";
|
print " ... Failed! Not critical, keep moving...\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
print " - Removing privileges on test database...\n";
|
print " - Removing privileges on test database...\n";
|
||||||
do_query("DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%'");
|
if (do_query("DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%'")) {
|
||||||
if ( $? == 0 ) {
|
|
||||||
print " ... Success!\n";
|
print " ... Success!\n";
|
||||||
} else {
|
} else {
|
||||||
print " ... Failed! Not critical, keep moving...\n";
|
print " ... Failed! Not critical, keep moving...\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub reload_privilege_tables {
|
sub reload_privilege_tables {
|
||||||
do_query("FLUSH PRIVILEGES;");
|
if (do_query("FLUSH PRIVILEGES;")) {
|
||||||
if ( $? == 0 ) {
|
|
||||||
print " ... Success!\n";
|
print " ... Success!\n";
|
||||||
return 0;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
print " ... Failed!\n";
|
print " ... Failed!\n";
|
||||||
return 1;
|
return undef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub interrupt {
|
|
||||||
print "\nAborting!\n\n";
|
|
||||||
cleanup();
|
|
||||||
echo_on();
|
|
||||||
exit 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub cleanup {
|
sub cleanup {
|
||||||
print "Cleaning up...\n";
|
|
||||||
unlink($config,$command);
|
unlink($config,$command);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,11 +285,7 @@ my $reply = <STDIN>;
|
|||||||
if ( $reply =~ /n/i ) {
|
if ( $reply =~ /n/i ) {
|
||||||
print " ... skipping.\n";
|
print " ... skipping.\n";
|
||||||
} else {
|
} else {
|
||||||
my $status = 1;
|
set_root_password();
|
||||||
while ( $status == 1 ) {
|
|
||||||
set_root_password();
|
|
||||||
$status = $?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
print "\n";
|
print "\n";
|
||||||
|
|
||||||
@ -334,8 +373,6 @@ if ( $reply =~ /n/i ) {
|
|||||||
}
|
}
|
||||||
print "\n";
|
print "\n";
|
||||||
|
|
||||||
cleanup();
|
|
||||||
|
|
||||||
print <<HERE;
|
print <<HERE;
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,16 +38,39 @@ prepare() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
do_query() {
|
do_query() {
|
||||||
echo $1 >$command
|
echo "$1" >$command
|
||||||
|
#sed 's,^,> ,' < $command # Debugging
|
||||||
mysql --defaults-file=$config <$command
|
mysql --defaults-file=$config <$command
|
||||||
return $?
|
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() {
|
make_config() {
|
||||||
echo "# mysql_secure_installation config file" >$config
|
echo "# mysql_secure_installation config file" >$config
|
||||||
echo "[mysql]" >>$config
|
echo "[mysql]" >>$config
|
||||||
echo "user=root" >>$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() {
|
get_root_password() {
|
||||||
@ -94,13 +117,12 @@ set_root_password() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
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
|
if [ $? -eq 0 ]; then
|
||||||
echo "Password updated successfully!"
|
echo "Password updated successfully!"
|
||||||
echo "Reloading privilege tables.."
|
echo "Reloading privilege tables.."
|
||||||
if ! reload_privilege_tables; then
|
reload_privilege_tables || exit 1
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo
|
echo
|
||||||
rootpass=$password1
|
rootpass=$password1
|
||||||
make_config
|
make_config
|
||||||
|
Loading…
x
Reference in New Issue
Block a user