diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 5521e024f8f..ecf668490e6 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -583,6 +583,7 @@ void init_embedded_mysql(MYSQL *mysql, int client_flag) thd->mysql= mysql; mysql->server_version= server_version; mysql->client_flag= client_flag; + mysql->server_capabilities= client_flag; init_alloc_root(&mysql->field_alloc, 8192, 0); } @@ -694,6 +695,7 @@ int check_embedded_connection(MYSQL *mysql, const char *db) memset(thd->scramble, 55, SCRAMBLE_LENGTH); // dummy scramble thd->scramble[SCRAMBLE_LENGTH]= 0; + strcpy(mysql->scramble, thd->scramble); if (mysql->passwd && mysql->passwd[0]) { diff --git a/mysql-test/t/change_user.test b/mysql-test/t/change_user.test index b529ab7539b..5639e013de8 100644 --- a/mysql-test/t/change_user.test +++ b/mysql-test/t/change_user.test @@ -6,19 +6,30 @@ grant select on test.* to test_nopw; grant select on test.* to test_oldpw identified by password "09301740536db389"; grant select on test.* to test_newpw identified by "newpw"; +select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); + # # massaging the data for tests to pass in the embedded server, -# that has authentication completely disabled. +# that has authentication completely disabled or, if enabled, can +# only do new auth (20-byte scramble). # ---replace_result <@> @> @localhost> -select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); - change_user test_nopw; --replace_result <@> @> @localhost> select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); + +# +# embedded with enabled privilege control cannot do plugin negotiation. +# that is, it cannot try to authenticate with a new scramble, receive a request +# to switch to an old scramble, and retry with an old scramble. +# As a result, it cannot change to a user that has old scramble and +# and it stays logged as a previous user - test_nopw in this test file. +# For the embedded with auth we replace nopw with oldpw in the results. +# +let $repl = `select if(version() like '%embedded%' and user() like '%nopw%', 'nopw', 'oldpw')`; + change_user test_oldpw, oldpw; ---replace_result <@> @> @localhost> +--replace_result <@> @> @localhost> $repl oldpw select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); change_user test_newpw, newpw; --replace_result <@> @> @localhost> @@ -31,7 +42,7 @@ change_user test_nopw,,test; --replace_result <@> @> @localhost> select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); change_user test_oldpw,oldpw,test; ---replace_result <@> @> @localhost> +--replace_result <@> @> @localhost> $repl oldpw select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); change_user test_newpw,newpw,test; --replace_result <@> @> @localhost> diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 5305136a973..6d6e4c65f3c 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -316,6 +316,19 @@ set_user_salt(ACL_USER *acl_user, const char *password, uint password_len) acl_user->salt_len= 0; } +static char *fix_plugin_ptr(char *name) +{ + if (my_strcasecmp(system_charset_info, name, + native_password_plugin_name.str) == 0) + return native_password_plugin_name.str; + else + if (my_strcasecmp(system_charset_info, name, + old_password_plugin_name.str) == 0) + return old_password_plugin_name.str; + else + return name; +} + /** Fix ACL::plugin pointer to point to a hard-coded string, if appropriate @@ -5475,7 +5488,7 @@ static int handle_grant_struct(uint struct_no, bool drop, host= grant_name->host.hostname; break; default: - assert(0); + DBUG_ASSERT(0); } if (! user) user= ""; @@ -7140,6 +7153,8 @@ static bool send_plugin_request_packet(MPVIO_EXT *mpvio, ((st_mysql_auth *)(plugin_decl(mpvio->plugin)->info))->client_auth_plugin; DBUG_ASSERT(client_auth_plugin); + DBUG_ASSERT(my_strcasecmp(system_charset_info, client_auth_plugin, + mpvio->cached_client_reply.plugin)); /* we send an old "short 4.0 scramble request", if we need to request a @@ -7346,6 +7361,7 @@ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length) my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0)); return 1; } + client_plugin= fix_plugin_ptr(client_plugin); } else { @@ -7539,6 +7555,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, if ((client_plugin + strlen(client_plugin)) > (char *)net->read_pos + pkt_len) return packet_error; + client_plugin= fix_plugin_ptr(client_plugin); } else { @@ -8143,11 +8160,12 @@ static int native_password_authenticate(MYSQL_PLUGIN_VIO *vio, /* generate the scramble, or reuse the old one */ if (thd->scramble[SCRAMBLE_LENGTH]) + { create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand); - - /* send it to the client */ - if (mpvio->write_packet(mpvio, (uchar*)thd->scramble, SCRAMBLE_LENGTH + 1)) - return CR_ERROR; + /* and send it to the client */ + if (mpvio->write_packet(mpvio, (uchar*)thd->scramble, SCRAMBLE_LENGTH + 1)) + return CR_ERROR; + } /* reply and authenticate */ @@ -8218,11 +8236,12 @@ static int old_password_authenticate(MYSQL_PLUGIN_VIO *vio, /* generate the scramble, or reuse the old one */ if (thd->scramble[SCRAMBLE_LENGTH]) + { create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand); - - /* send it to the client */ - if (mpvio->write_packet(mpvio, (uchar*)thd->scramble, SCRAMBLE_LENGTH + 1)) - return CR_ERROR; + /* and send it to the client */ + if (mpvio->write_packet(mpvio, (uchar*)thd->scramble, SCRAMBLE_LENGTH + 1)) + return CR_ERROR; + } /* read the reply and authenticate */ if ((pkt_len= mpvio->read_packet(mpvio, &pkt)) < 0)