Bug #66250 | ALTER USER ... PASSWORD EXPIRE allows open access to account | ||
---|---|---|---|
Submitted: | 7 Aug 2012 20:42 | Modified: | 20 Aug 2012 17:58 |
Reporter: | Kolbe Kegel | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Security: Privileges | Severity: | S2 (Serious) |
Version: | 5.6.6 | OS: | Any |
Assigned to: | CPU Architecture: | Any |
[7 Aug 2012 20:42]
Kolbe Kegel
[8 Aug 2012 11:50]
Mark Leith
This has been fixed, patch that fixed this: 3968 Georgi Kodinov 2012-07-04 Bug #14226518: ALTER USER ... PASSWORD EXPIRE HAS CONFUSING AFTEREFFECTS Made sure ALTER USER ... PASSWORD EXPIRE doesn't clear the password neither in the table nor into the in-memory cache of it. Test added. added: internal/mysql-test/suite/i_main/r/connect.result internal/mysql-test/suite/i_main/t/connect.test modified: sql/sql_acl.cc === added file 'internal/mysql-test/suite/i_main/r/connect.result' --- a/internal/mysql-test/suite/i_main/r/connect.result 1970-01-01 00:00:00 +0000 +++ b/internal/mysql-test/suite/i_main/r/connect.result 2012-07-04 15:30:17 +0000 @@ -0,0 +1,37 @@ +# +# Bug #14226518: ALTER USER ... PASSWORD EXPIRE HAS CONFUSING +# AFTEREFFECTS +# +CREATE USER g1@localhost identified by 'g1pass'; +SELECT LENGTH(password) FROM mysql.user WHERE Host = 'localhost' AND User = 'g1'; +LENGTH(password) +41 +ALTER USER g1@localhost PASSWORD EXPIRE; +SELECT LENGTH(password) FROM mysql.user WHERE Host = 'localhost' AND User = 'g1'; +LENGTH(password) +41 +SELECT USER(); +USER() +g1@localhost +SELECT USER(); +ERROR HY000: You must SET PASSWORD before executing this statement +FLUSH PRIVILEGES; +SELECT USER(); +USER() +g1@localhost +SELECT USER(); +ERROR HY000: You must SET PASSWORD before executing this statement +SET PASSWORD = PASSWORD('g1newpass'); +SELECT USER(); +USER() +g1@localhost +SELECT USER(); +USER() +g1@localhost +SELECT LENGTH(password) FROM mysql.user WHERE Host = 'localhost' AND User = 'g1'; +LENGTH(password) +41 +DROP USER g1@localhost; +# ------------------------------------------------------------------ +# -- End of 5.6 tests +# ------------------------------------------------------------------ === added file 'internal/mysql-test/suite/i_main/t/connect.test' --- a/internal/mysql-test/suite/i_main/t/connect.test 1970-01-01 00:00:00 +0000 +++ b/internal/mysql-test/suite/i_main/t/connect.test 2012-07-04 15:30:17 +0000 @@ -0,0 +1,61 @@ +# This test makes no sense with the embedded server +--source include/not_embedded.inc + +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + + +--echo # +--echo # Bug #14226518: ALTER USER ... PASSWORD EXPIRE HAS CONFUSING +--echo # AFTEREFFECTS +--echo # + +CREATE USER g1@localhost identified by 'g1pass'; +SELECT LENGTH(password) FROM mysql.user WHERE Host = 'localhost' AND User = 'g1'; + +connect(g1_conn_before,localhost,g1,g1pass,test); + +connection default; +ALTER USER g1@localhost PASSWORD EXPIRE; +SELECT LENGTH(password) FROM mysql.user WHERE Host = 'localhost' AND User = 'g1'; +connect(g1_conn_after,localhost,g1,g1pass,test); + +connection g1_conn_before; +SELECT USER(); + +connection g1_conn_after; +--error ER_MUST_CHANGE_PASSWORD +SELECT USER(); + +connection default; +FLUSH PRIVILEGES; + +connection g1_conn_before; +SELECT USER(); + +connection g1_conn_after; +--error ER_MUST_CHANGE_PASSWORD +SELECT USER(); +SET PASSWORD = PASSWORD('g1newpass'); + +connection g1_conn_before; +SELECT USER(); + +connection g1_conn_after; +SELECT USER(); + +connection default; +SELECT LENGTH(password) FROM mysql.user WHERE Host = 'localhost' AND User = 'g1'; + +disconnect g1_conn_before; +disconnect g1_conn_after; +DROP USER g1@localhost; + + +--echo # ------------------------------------------------------------------ +--echo # -- End of 5.6 tests +--echo # ------------------------------------------------------------------ + +# Wait till all disconnects are completed +--source include/wait_until_count_sessions.inc + === modified file 'sql/sql_acl.cc' --- a/sql/sql_acl.cc 2012-06-20 09:19:32 +0000 +++ b/sql/sql_acl.cc 2012-07-04 15:30:17 +0000 @@ -867,7 +867,7 @@ static bool update_user_table(THD *, TAB const char *new_password, uint new_password_len, enum mysql_user_table_field password_field, - const char must_expire); + bool password_expired); static my_bool acl_load(THD *thd, TABLE_LIST *tables); static my_bool grant_load(THD *thd, TABLE_LIST *tables); static inline void get_grantor(THD *thd, char* grantor); @@ -2443,7 +2443,7 @@ bool change_password(THD *thd, const cha if (update_user_table(thd, table, acl_user->host.get_host() ? acl_user->host.get_host() : "", acl_user->user ? acl_user->user : "", - new_password, new_password_len, password_field, 'N')) + new_password, new_password_len, password_field, false)) { mysql_mutex_unlock(&acl_cache->lock); /* purecov: deadcode */ goto end; @@ -2633,7 +2633,7 @@ update_user_table(THD *thd, TABLE *table const char *host, const char *user, const char *new_password, uint new_password_len, enum mysql_user_table_field password_field, - const char password_expired) + bool password_expired) { char user_key[MAX_KEY_LENGTH]; int error; @@ -2658,17 +2658,25 @@ update_user_table(THD *thd, TABLE *table DBUG_RETURN(1); /* purecov: deadcode */ } store_record(table,record[1]); - - table->field[(int) password_field]->store(new_password, new_password_len, - system_charset_info); - if (new_password_len == SCRAMBLED_PASSWORD_CHAR_LENGTH_323 && - password_field == MYSQL_USER_FIELD_PASSWORD) + + /* + When the flag is on we're inside ALTER TABLE ... PASSWORD EXPIRE and we + have no password to update. + */ + if (!password_expired) { - WARN_DEPRECATED_41_PWD_HASH(thd); + table->field[(int) password_field]->store(new_password, new_password_len, + system_charset_info); + if (new_password_len == SCRAMBLED_PASSWORD_CHAR_LENGTH_323 && + password_field == MYSQL_USER_FIELD_PASSWORD) + { + WARN_DEPRECATED_41_PWD_HASH(thd); + } } /* password_expired */ - table->field[MYSQL_USER_FIELD_PASSWORD_EXPIRED]->store(&password_expired, 1, + table->field[MYSQL_USER_FIELD_PASSWORD_EXPIRED]->store(password_expired ? + "Y" : "N", 1, system_charset_info); if ((error=table->file->ha_update_row(table->record[1],table->record[0])) && @@ -7730,7 +7738,7 @@ bool mysql_user_password_expire(THD *thd acl_user->host.get_host() ? acl_user->host.get_host() : "", acl_user->user ? acl_user->user : "", - NULL, 0, password_field,'Y')) + NULL, 0, password_field, true)) { result= true; append_user(thd, &wrong_users, user_from, wrong_users.length() > 0,
[20 Aug 2012 17:58]
Paul DuBois
Documentation is updated. http://dev.mysql.com/doc/refman/5.6/en/alter-user.html