summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorTimothy Smith <timothy.smith@sun.com>2009-11-03 13:50:28 -0700
committerTimothy Smith <timothy.smith@sun.com>2009-11-03 13:50:28 -0700
commite29b7ef5b8f663c04d7a40a575a6ff8c231c9433 (patch)
tree56ecb78704127c6fe6b3e4f6a8102d0c9f13efda /scripts
parentd31e4636b6e84a0b7ffb0d3d2c86ff0af912a38d (diff)
downloadmariadb-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-xscripts/mysql_secure_installation.pl.in24
-rw-r--r--scripts/mysql_secure_installation.sh30
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.."