Bug #68883 Existed user identified by old_password connect failed unless flush privileges
Submitted: 8 Apr 2013 3:58 Modified: 25 Apr 2013 14:17
Reporter: vin chen Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Security: Privileges Severity:S3 (Non-critical)
Version:5.5 OS:Any
Assigned to: Georgi Kodinov CPU Architecture:Any
Tags: flush privileges old_password

[8 Apr 2013 3:58] vin chen
Description:
Grant privileges to existed user identified by old_password.
This user connect failed unless flush privileges.

How to repeat:
session 1
mysql> grant all privileges on *.* to 'vin'@localhost identified by 'vinchen1';
Query OK, 0 rows affected (4.83 sec)

mysql> select old_password('vinchen');
+-------------------------+
| old_password('vinchen') |
+-------------------------+
| 7f8da8b51a961f6e        |
+-------------------------+
1 row in set (0.01 sec)

mysql> grant all privileges on *.* to 'vin'@localhost identified by password '7f8da8b51a961f6e';
Query OK, 0 rows affected (2.00 sec)

session 2
shell> mysql -uvin -pvinchen
ERROR 1045 (28000): Access denied for user 'vin'@'localhost' (using password: YES)

session 1
mysql> flush privileges;
Query OK, 0 rows affected (1.37 sec)

session 2
shell> mysql -uvin -pvinchen
--connect success

Suggested fix:
sql/sql_acl.cc  
function acl_update_user need set_user_plugin

--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1409,6 +1409,10 @@ static void acl_update_user(const char *user, const char
             strmake_root(&mem, auth->str, auth->length) : const_cast<char*>("")
           acl_user->auth_string.length= auth->length;
         }
+        else
+        {
+          set_user_plugin(acl_user, password_len);
+        }
        acl_user->access=privileges;
        if (mqh->specified_limits & USER_RESOURCES::QUERIES_PER_HOUR)
          acl_user->user_resource.questions=mqh->questions;
[15 Apr 2013 11:45] vin chen
No comment??
[15 Apr 2013 15:23] MySQL Verification Team
Thank you for the bug report. Verified as described (not repeatable with 5.1 works without flush privileges).

miguel@tikal:~/dbs/5.5/data> cd ..
miguel@tikal:~/dbs/5.5> bin/mysql -uroot
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.5.32-debug Source distribution

Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> grant all privileges on *.* to 'vin'@localhost identified by 'vinchen1';
Query OK, 0 rows affected (0.00 sec)

mysql> select old_password('vinchen');
+-------------------------+
| old_password('vinchen') |
+-------------------------+
| 7f8da8b51a961f6e        |
+-------------------------+
1 row in set (0.00 sec)

mysql>  grant all privileges on *.* to 'vin'@localhost identified by password '7f8da8b51a961f6e';
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)
***************************************************************************************************
miguel@tikal:~/dbs/5.5> bin/mysql -uvin -pvinchen
ERROR 1045 (28000): Access denied for user 'vin'@'localhost' (using password: YES)
miguel@tikal:~/dbs/5.5> bin/mysql -uvin -pvinchen
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.5.32-debug Source distribution

Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
[25 Apr 2013 14:17] Georgi Kodinov
Thank you for your bug report. This issue has already been fixed in the latest released version of that product, which you can download at

  http://www.mysql.com/downloads/

Thanks for your contribution ! Your analysis is correct. So is your proposed fix. 
Unfortunately the support for "old" passwords is causing all kinds of trouble like the one you've proposed fixing. Also the way to freely alternate between "old" and "native" passwords for a single account based on the hash length is producing a number of edge cases that are non-trivial to find and fix.
Add this to the fact that the calculation itself is not very strong and you will understand why old passwords are deprecated in 5.6. And the duality of account definitions is going with it too.
I suggest you consider migrating to our latest GA release where a number of more robust authentication mechanisms is available: http://dev.mysql.com/doc/refman/5.6/en/pluggable-authentication.html