Bug #4779 SET PASSWORD command doesn't check for valid password hash
Submitted: 28 Jul 2004 0:46 Modified: 30 Jul 2004 21:53
Reporter: Harrison Fisk Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S4 (Feature request)
Version:4.1.3b OS:Windows (Windows XP Pro)
Assigned to: Sergei Golubchik CPU Architecture:Any

[28 Jul 2004 0:46] Harrison Fisk
Description:
The SET PASSWORD command doesn't check to make sure that the password you are giving it is a correct hashed value.  This makes it very easy to set to a password that can not be possibly matched, and totally locks out the user account.  

The GRANT statement does verify the hash if you use the option IDENTIFIED BY PASSWORD option, which implies that SET PASSWORD should do so as well.

How to repeat:
1.  Login to mysql.
2.  mysql> set password = 'test';
3.  Notice that it allows that, but test isn't a proper hash so it can never be a correct password.
4.  mysql> GRANT USAGE ON *.* TO root@localhost IDENTIFIED BY PASSWORD 'test';
5.  Notice that gives an error.

Suggested fix:
Either check to verify that it is proper hash for the password, similar to IDENTIFIED BY PASSWORD as above, or automatically hash the string give to SET PASSWORD.
[28 Jul 2004 1:34] Matthew Lord
I completely agree with this request but it is a feature request as the current functionality 
complies with the manual.

This is not particular to any OS.
[30 Jul 2004 4:49] Harrison Fisk
Here is a patch that seems to work in making the SET PASSWORD give the same error as the GRANT statement.  It is against a recent 4.1 tree.

===== sql_acl.cc 1.131 vs edited =====
--- 1.131/sql/sql_acl.cc        Mon Jul 19 10:01:48 2004
+++ edited/sql_acl.cc   Thu Jul 29 22:43:19 2004
@@ -1187,6 +1187,16 @@
   }
   /* update loaded acl entry: */
   uint new_password_len= new_password ? strlen(new_password) : 0;
+  if (new_password_len != SCRAMBLED_PASSWORD_CHAR_LENGTH &&
+        new_password_len != SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
+  {
+    VOID(pthread_mutex_unlock(&acl_cache->lock));
+    my_printf_error(ER_PASSWORD_NO_MATCH,
+                      "Password hash should be a %d-digit hexadecimal number",
+                      MYF(0), SCRAMBLED_PASSWORD_CHAR_LENGTH);
+    DBUG_RETURN(1);
+  }
+  
   set_user_salt(acl_user, new_password, new_password_len);
 
   if (update_user_table(thd,
[30 Jul 2004 20:18] Harrison Fisk
I noticed that the previous patch I gave doesn't allow zero length strings for the password (to have no password at all).  Here is a new patch that fixes that:

===== sql_acl.cc 1.131 vs edited =====
--- 1.131/sql/sql_acl.cc        Mon Jul 19 10:01:48 2004
+++ edited/sql_acl.cc   Fri Jul 30 14:15:43 2004
@@ -1187,6 +1187,17 @@
   }
   /* update loaded acl entry: */
   uint new_password_len= new_password ? strlen(new_password) : 0;
+  if (new_password_len != SCRAMBLED_PASSWORD_CHAR_LENGTH &&
+        new_password_len != SCRAMBLED_PASSWORD_CHAR_LENGTH_323 &&
+        new_password_len != 0)
+  {
+    VOID(pthread_mutex_unlock(&acl_cache->lock));
+    my_printf_error(ER_PASSWORD_NO_MATCH,
+                      "Password hash should be a %d-digit hexadecimal number",
+                      MYF(0), SCRAMBLED_PASSWORD_CHAR_LENGTH);
+    DBUG_RETURN(1);
+  }
+  
   set_user_salt(acl_user, new_password, new_password_len);
 
   if (update_user_table(thd,
[30 Jul 2004 21:53] Sergei Golubchik
Thank you for your bug report. This issue has been committed to our
source repository of that product and will be incorporated into the
next release.

If necessary, you can access the source repository and build the latest
available version, including the bugfix, yourself. More information 
about accessing the source trees is available at
    http://www.mysql.com/doc/en/Installing_source_tree.html

Additional info:

fixed in 4.1.4