mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
Bug#48031: mysql_secure_installation -- bash bug regarding passwords with
special chars This script failed when the user tried passwords with multiple spaces, \, # or ' characters. Now proper escaping and quoting is used in all contexts. This problem occurs in the Perl version of this script, too, so fix it in both places.
This commit is contained in:
parent
d31e4636b6
commit
e29b7ef5b8
2 changed files with 48 additions and 6 deletions
|
@ -108,6 +108,23 @@ 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);
|
||||
|
@ -119,11 +136,12 @@ sub do_query {
|
|||
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 {
|
||||
|
@ -165,8 +183,8 @@ sub set_root_password {
|
|||
last;
|
||||
}
|
||||
|
||||
# FIXME: Quote password1 properly for SQL
|
||||
do_query("UPDATE mysql.user SET Password=PASSWORD('$password1') WHERE User='root';")
|
||||
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";
|
||||
|
|
|
@ -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,7 +117,8 @@ 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.."
|
||||
|
|
Loading…
Reference in a new issue