From cc04a9fc0f60610d900f27ef60f8916a4ce1bb4c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 18 Apr 2016 18:30:42 +0200 Subject: [PATCH] MDEV-9835 Valid password is not working after server restart On SET PASSWORD if the plugin is mysql_native_password or mysql_old_password, do reset plugin and auth_str fields. --- mysql-test/r/set_password_plugin-9835.result | 158 +++++++++++++++++++ mysql-test/t/set_password_plugin-9835.test | 128 +++++++++++++++ sql/sql_acl.cc | 17 +- 3 files changed, 298 insertions(+), 5 deletions(-) create mode 100644 mysql-test/r/set_password_plugin-9835.result create mode 100644 mysql-test/t/set_password_plugin-9835.test diff --git a/mysql-test/r/set_password_plugin-9835.result b/mysql-test/r/set_password_plugin-9835.result new file mode 100644 index 00000000000..e9ee09fe952 --- /dev/null +++ b/mysql-test/r/set_password_plugin-9835.result @@ -0,0 +1,158 @@ +create user natauth@localhost identified via 'mysql_native_password' using '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29'; +create user newpass@localhost identified by password '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29'; +create user newpassnat@localhost identified via 'mysql_native_password'; +set password for newpassnat@localhost = '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29'; +create user oldauth@localhost identified with 'mysql_old_password' using '378b243e220ca493'; +create user oldpass@localhost identified by password '378b243e220ca493'; +create user oldpassold@localhost identified with 'mysql_old_password'; +set password for oldpassold@localhost = '378b243e220ca493'; +select user, host, password, plugin, authentication_string from mysql.user where user != 'root'; +user host password plugin authentication_string +natauth localhost mysql_native_password *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 +newpass localhost *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 +newpassnat localhost *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 +oldauth localhost mysql_old_password 378b243e220ca493 +oldpass localhost 378b243e220ca493 +oldpassold localhost 378b243e220ca493 +connect con,localhost,natauth,test,; +select current_user(); +current_user() +natauth@localhost +disconnect con; +connect con,localhost,newpass,test,; +select current_user(); +current_user() +newpass@localhost +disconnect con; +connect con,localhost,newpassnat,test,; +select current_user(); +current_user() +newpassnat@localhost +disconnect con; +connect con,localhost,oldauth,test,; +select current_user(); +current_user() +oldauth@localhost +disconnect con; +connect con,localhost,oldpass,test,; +select current_user(); +current_user() +oldpass@localhost +disconnect con; +connect con,localhost,oldpassold,test,; +select current_user(); +current_user() +oldpassold@localhost +disconnect con; +connection default; +flush privileges; +connect con,localhost,natauth,test,; +select current_user(); +current_user() +natauth@localhost +disconnect con; +connect con,localhost,newpass,test,; +select current_user(); +current_user() +newpass@localhost +disconnect con; +connect con,localhost,newpassnat,test,; +select current_user(); +current_user() +newpassnat@localhost +disconnect con; +connect con,localhost,oldauth,test,; +select current_user(); +current_user() +oldauth@localhost +disconnect con; +connect con,localhost,oldpass,test,; +select current_user(); +current_user() +oldpass@localhost +disconnect con; +connect con,localhost,oldpassold,test,; +select current_user(); +current_user() +oldpassold@localhost +disconnect con; +connection default; +set password for natauth@localhost = PASSWORD('test2'); +set password for newpass@localhost = PASSWORD('test2'); +set password for newpassnat@localhost = PASSWORD('test2'); +set password for oldauth@localhost = PASSWORD('test2'); +set password for oldpass@localhost = PASSWORD('test2'); +set password for oldpassold@localhost = PASSWORD('test2'); +select user, host, password, plugin, authentication_string from mysql.user where user != 'root'; +user host password plugin authentication_string +natauth localhost *7CEB3FDE5F7A9C4CE5FBE610D7D8EDA62EBE5F4E +newpass localhost *7CEB3FDE5F7A9C4CE5FBE610D7D8EDA62EBE5F4E +newpassnat localhost *7CEB3FDE5F7A9C4CE5FBE610D7D8EDA62EBE5F4E +oldauth localhost *7CEB3FDE5F7A9C4CE5FBE610D7D8EDA62EBE5F4E +oldpass localhost *7CEB3FDE5F7A9C4CE5FBE610D7D8EDA62EBE5F4E +oldpassold localhost *7CEB3FDE5F7A9C4CE5FBE610D7D8EDA62EBE5F4E +connect con,localhost,natauth,test2,; +select current_user(); +current_user() +natauth@localhost +disconnect con; +connect con,localhost,newpass,test2,; +select current_user(); +current_user() +newpass@localhost +disconnect con; +connect con,localhost,newpassnat,test2,; +select current_user(); +current_user() +newpassnat@localhost +disconnect con; +connect con,localhost,oldauth,test2,; +select current_user(); +current_user() +oldauth@localhost +disconnect con; +connect con,localhost,oldpass,test2,; +select current_user(); +current_user() +oldpass@localhost +disconnect con; +connect con,localhost,oldpassold,test2,; +select current_user(); +current_user() +oldpassold@localhost +disconnect con; +connection default; +flush privileges; +connect con,localhost,natauth,test2,; +select current_user(); +current_user() +natauth@localhost +disconnect con; +connect con,localhost,newpass,test2,; +select current_user(); +current_user() +newpass@localhost +disconnect con; +connect con,localhost,newpassnat,test2,; +select current_user(); +current_user() +newpassnat@localhost +disconnect con; +connect con,localhost,oldauth,test2,; +select current_user(); +current_user() +oldauth@localhost +disconnect con; +connect con,localhost,oldpass,test2,; +select current_user(); +current_user() +oldpass@localhost +disconnect con; +connect con,localhost,oldpassold,test2,; +select current_user(); +current_user() +oldpassold@localhost +disconnect con; +connection default; +drop user natauth@localhost, newpass@localhost, newpassnat@localhost; +drop user oldauth@localhost, oldpass@localhost, oldpassold@localhost; diff --git a/mysql-test/t/set_password_plugin-9835.test b/mysql-test/t/set_password_plugin-9835.test new file mode 100644 index 00000000000..a10a339540f --- /dev/null +++ b/mysql-test/t/set_password_plugin-9835.test @@ -0,0 +1,128 @@ +# +# MDEV-9835 Valid password is not working after server restart. +# +# Various combinations of SET PASSWORD and not-empty mysql.user.plugin field +# +--source include/not_embedded.inc + +--enable_connect_log + +# The hash (old and new) is for 'test' +create user natauth@localhost identified via 'mysql_native_password' using '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29'; + +create user newpass@localhost identified by password '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29'; + +create user newpassnat@localhost identified via 'mysql_native_password'; +set password for newpassnat@localhost = '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29'; + +create user oldauth@localhost identified with 'mysql_old_password' using '378b243e220ca493'; + +create user oldpass@localhost identified by password '378b243e220ca493'; + +create user oldpassold@localhost identified with 'mysql_old_password'; +set password for oldpassold@localhost = '378b243e220ca493'; + +--sorted_result +select user, host, password, plugin, authentication_string from mysql.user where user != 'root'; + +--connect(con,localhost,natauth,test,) +select current_user(); +--disconnect con +--connect(con,localhost,newpass,test,) +select current_user(); +--disconnect con +--connect(con,localhost,newpassnat,test,) +select current_user(); +--disconnect con +--connect(con,localhost,oldauth,test,) +select current_user(); +--disconnect con +--connect(con,localhost,oldpass,test,) +select current_user(); +--disconnect con +--connect(con,localhost,oldpassold,test,) +select current_user(); +--disconnect con + +--connection default + +flush privileges; + +--connect(con,localhost,natauth,test,) +select current_user(); +--disconnect con +--connect(con,localhost,newpass,test,) +select current_user(); +--disconnect con +--connect(con,localhost,newpassnat,test,) +select current_user(); +--disconnect con +--connect(con,localhost,oldauth,test,) +select current_user(); +--disconnect con +--connect(con,localhost,oldpass,test,) +select current_user(); +--disconnect con +--connect(con,localhost,oldpassold,test,) +select current_user(); +--disconnect con + +--connection default + +# changing to the NEW password hash +set password for natauth@localhost = PASSWORD('test2'); +set password for newpass@localhost = PASSWORD('test2'); +set password for newpassnat@localhost = PASSWORD('test2'); +set password for oldauth@localhost = PASSWORD('test2'); +set password for oldpass@localhost = PASSWORD('test2'); +set password for oldpassold@localhost = PASSWORD('test2'); + +--sorted_result +select user, host, password, plugin, authentication_string from mysql.user where user != 'root'; + +--connect(con,localhost,natauth,test2,) +select current_user(); +--disconnect con +--connect(con,localhost,newpass,test2,) +select current_user(); +--disconnect con +--connect(con,localhost,newpassnat,test2,) +select current_user(); +--disconnect con +--connect(con,localhost,oldauth,test2,) +select current_user(); +--disconnect con +--connect(con,localhost,oldpass,test2,) +select current_user(); +--disconnect con +--connect(con,localhost,oldpassold,test2,) +select current_user(); +--disconnect con + +--connection default + +flush privileges; + +--connect(con,localhost,natauth,test2,) +select current_user(); +--disconnect con +--connect(con,localhost,newpass,test2,) +select current_user(); +--disconnect con +--connect(con,localhost,newpassnat,test2,) +select current_user(); +--disconnect con +--connect(con,localhost,oldauth,test2,) +select current_user(); +--disconnect con +--connect(con,localhost,oldpass,test2,) +select current_user(); +--disconnect con +--connect(con,localhost,oldpassold,test2,) +select current_user(); +--disconnect con + +--connection default +drop user natauth@localhost, newpass@localhost, newpassnat@localhost; +drop user oldauth@localhost, oldpass@localhost, oldpassold@localhost; + diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index da7c3f17c63..de76f27dee6 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -557,9 +557,8 @@ static void init_check_host(void); static void rebuild_check_host(void); static ACL_USER *find_acl_user(const char *host, const char *user, my_bool exact); -static bool update_user_table(THD *thd, TABLE *table, const char *host, - const char *user, const char *new_password, - uint new_password_len); +static bool update_user_table(THD *, TABLE *, const char *, const char *, const + char *, uint, bool); 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); @@ -1912,6 +1911,7 @@ bool change_password(THD *thd, const char *host, const char *user, bool save_binlog_row_based; uint new_password_len= (uint) strlen(new_password); bool result= 1; + bool use_salt= 0; DBUG_ENTER("change_password"); DBUG_PRINT("enter",("host: '%s' user: '%s' new_password: '%s'", host,user,new_password)); @@ -1967,6 +1967,7 @@ bool change_password(THD *thd, const char *host, const char *user, acl_user->auth_string.length= new_password_len; set_user_salt(acl_user, new_password, new_password_len); set_user_plugin(acl_user, new_password_len); + use_salt= 1; } else push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, @@ -1975,7 +1976,7 @@ bool change_password(THD *thd, const char *host, const char *user, if (update_user_table(thd, table, acl_user->host.hostname ? acl_user->host.hostname : "", acl_user->user ? acl_user->user : "", - new_password, new_password_len)) + new_password, new_password_len, use_salt)) { mysql_mutex_unlock(&acl_cache->lock); /* purecov: deadcode */ goto end; @@ -2223,7 +2224,8 @@ bool hostname_requires_resolving(const char *hostname) static bool update_user_table(THD *thd, TABLE *table, const char *host, const char *user, - const char *new_password, uint new_password_len) + const char *new_password, uint new_password_len, + bool reset_plugin) { char user_key[MAX_KEY_LENGTH]; int error; @@ -2246,6 +2248,11 @@ static bool update_user_table(THD *thd, TABLE *table, } store_record(table,record[1]); table->field[2]->store(new_password, new_password_len, system_charset_info); + if (reset_plugin && table->s->fields >= 41) + { + table->field[40]->reset(); + table->field[41]->reset(); + } if ((error=table->file->ha_update_row(table->record[1],table->record[0])) && error != HA_ERR_RECORD_IS_THE_SAME) {