diff options
author | Timothy Smith <timothy.smith@sun.com> | 2009-11-03 13:50:28 -0700 |
---|---|---|
committer | Timothy Smith <timothy.smith@sun.com> | 2009-11-03 13:50:28 -0700 |
commit | e29b7ef5b8f663c04d7a40a575a6ff8c231c9433 (patch) | |
tree | 56ecb78704127c6fe6b3e4f6a8102d0c9f13efda /scripts | |
parent | d31e4636b6e84a0b7ffb0d3d2c86ff0af912a38d (diff) | |
download | mariadb-git-e29b7ef5b8f663c04d7a40a575a6ff8c231c9433.tar.gz |
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.
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/mysql_secure_installation.pl.in | 24 | ||||
-rw-r--r-- | scripts/mysql_secure_installation.sh | 30 |
2 files changed, 48 insertions, 6 deletions
diff --git a/scripts/mysql_secure_installation.pl.in b/scripts/mysql_secure_installation.pl.in index 281f3558808..255416763ef 100755 --- a/scripts/mysql_secure_installation.pl.in +++ b/scripts/mysql_secure_installation.pl.in @@ -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"; diff --git a/scripts/mysql_secure_installation.sh b/scripts/mysql_secure_installation.sh index 597f6cac83f..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,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.." |