Commit dfd4dd67 authored by Georgi Kodinov's avatar Georgi Kodinov

BUG 12610784: SET PASSWORD INCORRECTLY KEEP AN OLD EMPTY PASSWORD

The check for empty password in the user account was checking the wrong field.
Fixed to check the proper password hash.
Test case added.
Fixed native_password and old_password plugins that suffered from the same
problems.
Unambuguated the auth_string ACL_USER member : previously it was used for 
both password and the authentication string (depending on the plugin). Now
fixed to contain either the authentication string specified or empty string.
parent b2df3228
...@@ -447,4 +447,11 @@ ORDER BY COLUMN_NAME; ...@@ -447,4 +447,11 @@ ORDER BY COLUMN_NAME;
IS_NULLABLE COLUMN_NAME IS_NULLABLE COLUMN_NAME
YES authentication_string YES authentication_string
YES plugin YES plugin
#
# Bug #12610784: SET PASSWORD INCORRECTLY KEEP AN OLD EMPTY PASSWORD
#
CREATE USER bug12610784@localhost;
SET PASSWORD FOR bug12610784@localhost = PASSWORD('secret');
ERROR 28000: Access denied for user 'bug12610784'@'localhost' (using password: NO)
DROP USER bug12610784@localhost;
End of 5.5 tests End of 5.5 tests
...@@ -512,4 +512,19 @@ SELECT IS_NULLABLE, COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS ...@@ -512,4 +512,19 @@ SELECT IS_NULLABLE, COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
ORDER BY COLUMN_NAME; ORDER BY COLUMN_NAME;
--echo #
--echo # Bug #12610784: SET PASSWORD INCORRECTLY KEEP AN OLD EMPTY PASSWORD
--echo #
CREATE USER bug12610784@localhost;
SET PASSWORD FOR bug12610784@localhost = PASSWORD('secret');
--disable_query_log
--error ER_ACCESS_DENIED_ERROR
connect(b12610784,localhost,bug12610784,,test);
--enable_query_log
connect(b12610784,localhost,bug12610784,secret,test);
connection default;
disconnect b12610784;
DROP USER bug12610784@localhost;
--echo End of 5.5 tests --echo End of 5.5 tests
...@@ -825,8 +825,6 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) ...@@ -825,8 +825,6 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
char *password= get_field(&mem, table->field[2]); char *password= get_field(&mem, table->field[2]);
uint password_len= password ? strlen(password) : 0; uint password_len= password ? strlen(password) : 0;
user.auth_string.str= password ? password : const_cast<char*>("");
user.auth_string.length= password_len;
set_user_salt(&user, password, password_len); set_user_salt(&user, password, password_len);
if (set_user_plugin(&user, password_len)) if (set_user_plugin(&user, password_len))
...@@ -915,7 +913,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) ...@@ -915,7 +913,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
char *tmpstr= get_field(&mem, table->field[next_field++]); char *tmpstr= get_field(&mem, table->field[next_field++]);
if (tmpstr) if (tmpstr)
{ {
if (user.auth_string.length) if (password_len)
{ {
sql_print_warning("'user' entry '%s@%s' has both a password " sql_print_warning("'user' entry '%s@%s' has both a password "
"and an authentication plugin specified. The " "and an authentication plugin specified. The "
...@@ -1483,8 +1481,8 @@ static void acl_insert_user(const char *user, const char *host, ...@@ -1483,8 +1481,8 @@ static void acl_insert_user(const char *user, const char *host,
{ {
acl_user.plugin= password_len == SCRAMBLED_PASSWORD_CHAR_LENGTH_323 ? acl_user.plugin= password_len == SCRAMBLED_PASSWORD_CHAR_LENGTH_323 ?
old_password_plugin_name : native_password_plugin_name; old_password_plugin_name : native_password_plugin_name;
acl_user.auth_string.str= strmake_root(&mem, password, password_len); acl_user.auth_string.str= const_cast<char*>("");
acl_user.auth_string.length= password_len; acl_user.auth_string.length= 0;
} }
acl_user.access=privileges; acl_user.access=privileges;
...@@ -8380,7 +8378,7 @@ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length) ...@@ -8380,7 +8378,7 @@ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length)
old_password_plugin, otherwise MySQL will think that server old_password_plugin, otherwise MySQL will think that server
and client plugins don't match. and client plugins don't match.
*/ */
if (mpvio->acl_user->auth_string.length == 0) if (mpvio->acl_user->salt_len == 0)
mpvio->acl_user_plugin= old_password_plugin_name; mpvio->acl_user_plugin= old_password_plugin_name;
} }
} }
...@@ -8685,7 +8683,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, ...@@ -8685,7 +8683,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
old_password_plugin, otherwise MySQL will think that server old_password_plugin, otherwise MySQL will think that server
and client plugins don't match. and client plugins don't match.
*/ */
if (mpvio->acl_user->auth_string.length == 0) if (mpvio->acl_user->salt_len == 0)
mpvio->acl_user_plugin= old_password_plugin_name; mpvio->acl_user_plugin= old_password_plugin_name;
} }
} }
...@@ -9473,7 +9471,7 @@ static int native_password_authenticate(MYSQL_PLUGIN_VIO *vio, ...@@ -9473,7 +9471,7 @@ static int native_password_authenticate(MYSQL_PLUGIN_VIO *vio,
#endif #endif
if (pkt_len == 0) /* no password */ if (pkt_len == 0) /* no password */
DBUG_RETURN(info->auth_string[0] ? CR_ERROR : CR_OK); DBUG_RETURN(mpvio->acl_user->salt_len != 0 ? CR_ERROR : CR_OK);
info->password_used= PASSWORD_USED_YES; info->password_used= PASSWORD_USED_YES;
if (pkt_len == SCRAMBLE_LENGTH) if (pkt_len == SCRAMBLE_LENGTH)
...@@ -9522,7 +9520,7 @@ static int old_password_authenticate(MYSQL_PLUGIN_VIO *vio, ...@@ -9522,7 +9520,7 @@ static int old_password_authenticate(MYSQL_PLUGIN_VIO *vio,
pkt_len= strnlen((char*)pkt, pkt_len); pkt_len= strnlen((char*)pkt, pkt_len);
if (pkt_len == 0) /* no password */ if (pkt_len == 0) /* no password */
return info->auth_string[0] ? CR_ERROR : CR_OK; return mpvio->acl_user->salt_len != 0 ? CR_ERROR : CR_OK;
if (secure_auth(mpvio)) if (secure_auth(mpvio))
return CR_ERROR; return CR_ERROR;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment