At http://bazaar.launchpad.net/~maria-captains/maria/5.2/ ------------------------------------------------------------ revno: 2772 revision-id: sergii@pisem.net-20100405095031-bgjy005pcftkp6g1 parent: sergii@pisem.net-20100402200840-0nctbdvalpetkkzp committer: Sergei Golubchik <sergii@pisem.net> branch nick: 5.2 timestamp: Mon 2010-04-05 11:50:31 +0200 message: fixed a bug in handling mysql_native_password specified explicitly: CREATE USER mysqltest_up1 IDENTIFIED VIA mysql_native_password pointers were not always fixed, salt wasn't updated === modified file 'mysql-test/r/connect.result' --- a/mysql-test/r/connect.result 2009-04-25 09:04:38 +0000 +++ b/mysql-test/r/connect.result 2010-04-05 09:50:31 +0000 @@ -225,3 +225,17 @@ Connection on extra port 2 ok # ------------------------------------------------------------------ # -- End of 5.1 tests # ------------------------------------------------------------------ +CREATE USER mysqltest_up1 IDENTIFIED VIA mysql_native_password using '*E8D46CE25265E545D225A8A6F1BAF642FEBEE5CB'; +CREATE USER mysqltest_up2 IDENTIFIED VIA mysql_old_password using '09301740536db389'; +connect(localhost,mysqltest_up1,foo,test,13001,MASTER_SOCKET); +ERROR 28000: Access denied for user 'mysqltest_up1'@'localhost' (using password: YES) +select user(), current_user(); +user() current_user() +mysqltest_up1@localhost mysqltest_up1@% +connect(localhost,mysqltest_up2,newpw,test,13001,MASTER_SOCKET); +ERROR 28000: Access denied for user 'mysqltest_up2'@'localhost' (using password: YES) +select user(), current_user(); +user() current_user() +mysqltest_up2@localhost mysqltest_up2@% +DROP USER mysqltest_up1@'%'; +DROP USER mysqltest_up2@'%'; === modified file 'mysql-test/t/connect.test' --- a/mysql-test/t/connect.test 2009-09-07 20:50:10 +0000 +++ b/mysql-test/t/connect.test 2010-04-05 09:50:31 +0000 @@ -328,6 +328,34 @@ if ($error) --disconnect extracon2 --connection default +# +# A couple of plugin tests - for builtin plugins only +# +CREATE USER mysqltest_up1 IDENTIFIED VIA mysql_native_password using '*E8D46CE25265E545D225A8A6F1BAF642FEBEE5CB'; +CREATE USER mysqltest_up2 IDENTIFIED VIA mysql_old_password using '09301740536db389'; + +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error ER_ACCESS_DENIED_ERROR +connect(pcon1,localhost,mysqltest_up1,foo,,$MASTER_EXTRA_PORT,); + +connect(pcon2,localhost,mysqltest_up1,bar,,$MASTER_EXTRA_PORT,); +connection pcon2; +select user(), current_user(); +disconnect pcon2; + +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error ER_ACCESS_DENIED_ERROR +connect(pcon3,localhost,mysqltest_up2,newpw,,$MASTER_EXTRA_PORT,); + +connect(pcon4,localhost,mysqltest_up2,oldpw,,$MASTER_EXTRA_PORT,); +connection pcon4; +select user(), current_user(); +disconnect pcon4; + +connection default; +DROP USER mysqltest_up1@'%'; +DROP USER mysqltest_up2@'%'; + # Wait till all disconnects are completed --source include/wait_until_count_sessions.inc === modified file 'sql/sql_acl.cc' --- a/sql/sql_acl.cc 2010-04-02 20:08:40 +0000 +++ b/sql/sql_acl.cc 2010-04-05 09:50:31 +0000 @@ -319,6 +319,35 @@ set_user_salt(ACL_USER *acl_user, const acl_user->salt_len= 0; } +/** + Fix ACL::plugin pointer to point to a hard-coded string, if appropriate + + Make sure that if ACL_USER's plugin is a built-in, then it points + to a hard coded string, not to an allocated copy. Run-time, for + authentication, we want to be able to detect built-ins by comparing + pointers, not strings. + + Additionally - update the salt if the plugin is built-in. + + @retval 0 the pointers were fixed + @retval 1 this ACL_USER uses a not built-in plugin +*/ +static bool fix_user_plugin_ptr(ACL_USER *user) +{ + if (my_strcasecmp(system_charset_info, user->plugin.str, + native_password_plugin_name.str) == 0) + user->plugin= native_password_plugin_name; + else + if (my_strcasecmp(system_charset_info, user->plugin.str, + old_password_plugin_name.str) == 0) + user->plugin= old_password_plugin_name; + else + return true; + + set_user_salt(user, user->auth_string.str, user->auth_string.length); + return false; +} + /* This after_update function is used when user.password is less than SCRAMBLE_LENGTH bytes. @@ -662,6 +691,8 @@ static my_bool acl_load(THD *thd, TABLE_ char *tmpstr= get_field(&mem, table->field[next_field++]); if (tmpstr) { + user.plugin.str= tmpstr; + user.plugin.length= strlen(user.plugin.str); if (user.auth_string.length) { sql_print_warning("'user' entry '%s@%s' has both a password " @@ -670,22 +701,12 @@ static my_bool acl_load(THD *thd, TABLE_ user.user ? user.user : "", user.host.hostname ? user.host.hostname : ""); } - if (my_strcasecmp(system_charset_info, tmpstr, - native_password_plugin_name.str) == 0) - user.plugin= native_password_plugin_name; - else - if (my_strcasecmp(system_charset_info, tmpstr, - old_password_plugin_name.str) == 0) - user.plugin= old_password_plugin_name; - else - { - user.plugin.str= tmpstr; - user.plugin.length= strlen(tmpstr); - } user.auth_string.str= get_field(&mem, table->field[next_field++]); if (!user.auth_string.str) user.auth_string.str= const_cast<char*>(""); user.auth_string.length= strlen(user.auth_string.str); + + fix_user_plugin_ptr(&user); } } } @@ -1132,12 +1153,15 @@ static void acl_update_user(const char * { if (plugin->str[0]) { - acl_user->plugin.str= strmake_root(&mem, plugin->str, plugin->length); - acl_user->plugin.length= plugin->length; + acl_user->plugin= *plugin; acl_user->auth_string.str= auth->str ? strmake_root(&mem, auth->str, auth->length) : const_cast<char*>(""); acl_user->auth_string.length= auth->length; + if (fix_user_plugin_ptr(acl_user)) + acl_user->plugin.str= strmake_root(&mem, plugin->str, plugin->length); } + else + set_user_salt(acl_user, password, password_len); acl_user->access=privileges; if (mqh->specified_limits & USER_RESOURCES::QUERIES_PER_HOUR) acl_user->user_resource.questions=mqh->questions; @@ -1157,8 +1181,6 @@ static void acl_update_user(const char * acl_user->x509_subject= (x509_subject ? strdup_root(&mem,x509_subject) : 0); } - if (password) - set_user_salt(acl_user, password, password_len); /* search complete: */ break; } @@ -1186,11 +1208,12 @@ static void acl_insert_user(const char * update_hostname(&acl_user.host, *host ? strdup_root(&mem, host): 0); if (plugin->str[0]) { - acl_user.plugin.str= strmake_root(&mem, plugin->str, plugin->length); - acl_user.plugin.length= plugin->length; + acl_user.plugin= *plugin; acl_user.auth_string.str= auth->str ? strmake_root(&mem, auth->str, auth->length) : const_cast<char*>(""); acl_user.auth_string.length= auth->length; + if (fix_user_plugin_ptr(&acl_user)) + acl_user.plugin.str= strmake_root(&mem, plugin->str, plugin->length); } else { @@ -1198,6 +1221,7 @@ static void acl_insert_user(const char * old_password_plugin_name : native_password_plugin_name; acl_user.auth_string.str= strmake_root(&mem, password, password_len); acl_user.auth_string.length= password_len; + set_user_salt(&acl_user, password, password_len); } acl_user.access=privileges; @@ -1210,8 +1234,6 @@ static void acl_insert_user(const char * acl_user.x509_issuer= x509_issuer ? strdup_root(&mem,x509_issuer) : 0; acl_user.x509_subject=x509_subject ? strdup_root(&mem,x509_subject) : 0; - set_user_salt(&acl_user, password, password_len); - VOID(push_dynamic(&acl_users,(uchar*) &acl_user)); if (!acl_user.host.hostname || (acl_user.host.hostname[0] == wild_many && !acl_user.host.hostname[1]))