Commit 3b98d69d authored by Sergei Golubchik's avatar Sergei Golubchik

crash on --with-embedded-privilege-control builds:

1. fix broken change user handling (no restart should happen in the normal case)
2. add assert to guarantee that we never send a request to change to the same plugin
3. "fix" plugin string as sent by the client to be able to compare native plugins by pointers
4. more complete MYSQL initialization in the embedded case
5. change_user.test updated to handle -with-embedded-privilege-control builds
parent c9b10e25
...@@ -583,6 +583,7 @@ void init_embedded_mysql(MYSQL *mysql, int client_flag) ...@@ -583,6 +583,7 @@ void init_embedded_mysql(MYSQL *mysql, int client_flag)
thd->mysql= mysql; thd->mysql= mysql;
mysql->server_version= server_version; mysql->server_version= server_version;
mysql->client_flag= client_flag; mysql->client_flag= client_flag;
mysql->server_capabilities= client_flag;
init_alloc_root(&mysql->field_alloc, 8192, 0); init_alloc_root(&mysql->field_alloc, 8192, 0);
} }
...@@ -694,6 +695,7 @@ int check_embedded_connection(MYSQL *mysql, const char *db) ...@@ -694,6 +695,7 @@ int check_embedded_connection(MYSQL *mysql, const char *db)
memset(thd->scramble, 55, SCRAMBLE_LENGTH); // dummy scramble memset(thd->scramble, 55, SCRAMBLE_LENGTH); // dummy scramble
thd->scramble[SCRAMBLE_LENGTH]= 0; thd->scramble[SCRAMBLE_LENGTH]= 0;
strcpy(mysql->scramble, thd->scramble);
if (mysql->passwd && mysql->passwd[0]) if (mysql->passwd && mysql->passwd[0])
{ {
......
...@@ -6,19 +6,30 @@ grant select on test.* to test_nopw; ...@@ -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_oldpw identified by password "09301740536db389";
grant select on test.* to test_newpw identified by "newpw"; 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, # 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 <@> <test_nopw@%> @> @localhost>
select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
change_user test_nopw; change_user test_nopw;
--replace_result <@> <test_nopw@%> @> @localhost> --replace_result <@> <test_nopw@%> @> @localhost>
select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); 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; change_user test_oldpw, oldpw;
--replace_result <@> <test_oldpw@%> @> @localhost> --replace_result <@> <test_oldpw@%> @> @localhost> $repl oldpw
select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
change_user test_newpw, newpw; change_user test_newpw, newpw;
--replace_result <@> <test_newpw@%> @> @localhost> --replace_result <@> <test_newpw@%> @> @localhost>
...@@ -31,7 +42,7 @@ change_user test_nopw,,test; ...@@ -31,7 +42,7 @@ change_user test_nopw,,test;
--replace_result <@> <test_nopw@%> @> @localhost> --replace_result <@> <test_nopw@%> @> @localhost>
select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
change_user test_oldpw,oldpw,test; change_user test_oldpw,oldpw,test;
--replace_result <@> <test_oldpw@%> @> @localhost> --replace_result <@> <test_oldpw@%> @> @localhost> $repl oldpw
select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
change_user test_newpw,newpw,test; change_user test_newpw,newpw,test;
--replace_result <@> <test_newpw@%> @> @localhost> --replace_result <@> <test_newpw@%> @> @localhost>
......
...@@ -316,6 +316,19 @@ set_user_salt(ACL_USER *acl_user, const char *password, uint password_len) ...@@ -316,6 +316,19 @@ set_user_salt(ACL_USER *acl_user, const char *password, uint password_len)
acl_user->salt_len= 0; 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 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, ...@@ -5475,7 +5488,7 @@ static int handle_grant_struct(uint struct_no, bool drop,
host= grant_name->host.hostname; host= grant_name->host.hostname;
break; break;
default: default:
assert(0); DBUG_ASSERT(0);
} }
if (! user) if (! user)
user= ""; user= "";
...@@ -7140,6 +7153,8 @@ static bool send_plugin_request_packet(MPVIO_EXT *mpvio, ...@@ -7140,6 +7153,8 @@ static bool send_plugin_request_packet(MPVIO_EXT *mpvio,
((st_mysql_auth *)(plugin_decl(mpvio->plugin)->info))->client_auth_plugin; ((st_mysql_auth *)(plugin_decl(mpvio->plugin)->info))->client_auth_plugin;
DBUG_ASSERT(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 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) ...@@ -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)); my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
return 1; return 1;
} }
client_plugin= fix_plugin_ptr(client_plugin);
} }
else else
{ {
...@@ -7539,6 +7555,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, ...@@ -7539,6 +7555,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
if ((client_plugin + strlen(client_plugin)) > if ((client_plugin + strlen(client_plugin)) >
(char *)net->read_pos + pkt_len) (char *)net->read_pos + pkt_len)
return packet_error; return packet_error;
client_plugin= fix_plugin_ptr(client_plugin);
} }
else else
{ {
...@@ -8143,11 +8160,12 @@ static int native_password_authenticate(MYSQL_PLUGIN_VIO *vio, ...@@ -8143,11 +8160,12 @@ static int native_password_authenticate(MYSQL_PLUGIN_VIO *vio,
/* generate the scramble, or reuse the old one */ /* generate the scramble, or reuse the old one */
if (thd->scramble[SCRAMBLE_LENGTH]) if (thd->scramble[SCRAMBLE_LENGTH])
{
create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand); create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand);
/* and send it to the client */
/* send it to the client */
if (mpvio->write_packet(mpvio, (uchar*)thd->scramble, SCRAMBLE_LENGTH + 1)) if (mpvio->write_packet(mpvio, (uchar*)thd->scramble, SCRAMBLE_LENGTH + 1))
return CR_ERROR; return CR_ERROR;
}
/* reply and authenticate */ /* reply and authenticate */
...@@ -8218,11 +8236,12 @@ static int old_password_authenticate(MYSQL_PLUGIN_VIO *vio, ...@@ -8218,11 +8236,12 @@ static int old_password_authenticate(MYSQL_PLUGIN_VIO *vio,
/* generate the scramble, or reuse the old one */ /* generate the scramble, or reuse the old one */
if (thd->scramble[SCRAMBLE_LENGTH]) if (thd->scramble[SCRAMBLE_LENGTH])
{
create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand); create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand);
/* and send it to the client */
/* send it to the client */
if (mpvio->write_packet(mpvio, (uchar*)thd->scramble, SCRAMBLE_LENGTH + 1)) if (mpvio->write_packet(mpvio, (uchar*)thd->scramble, SCRAMBLE_LENGTH + 1))
return CR_ERROR; return CR_ERROR;
}
/* read the reply and authenticate */ /* read the reply and authenticate */
if ((pkt_len= mpvio->read_packet(mpvio, &pkt)) < 0) if ((pkt_len= mpvio->read_packet(mpvio, &pkt)) < 0)
......
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