summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2010-05-14 23:45:32 +0200
committerSergei Golubchik <sergii@pisem.net>2010-05-14 23:45:32 +0200
commit3b98d69d689efcaba97476f34537fde24cfd5451 (patch)
tree0841558c8f5a6b6386f4a040203b9c38bc7f436c
parentc9b10e250d96d3f8eab22ebb698654da78fed5d8 (diff)
downloadmariadb-git-3b98d69d689efcaba97476f34537fde24cfd5451.tar.gz
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
-rw-r--r--libmysqld/lib_sql.cc2
-rw-r--r--mysql-test/t/change_user.test23
-rw-r--r--sql/sql_acl.cc37
3 files changed, 47 insertions, 15 deletions
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 <@> <test_nopw@%> @> @localhost>
-select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
-
change_user test_nopw;
--replace_result <@> <test_nopw@%> @> @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 <@> <test_oldpw@%> @> @localhost>
+--replace_result <@> <test_oldpw@%> @> @localhost> $repl oldpw
select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
change_user test_newpw, newpw;
--replace_result <@> <test_newpw@%> @> @localhost>
@@ -31,7 +42,7 @@ change_user test_nopw,,test;
--replace_result <@> <test_nopw@%> @> @localhost>
select concat('<', user(), '>'), concat('<', current_user(), '>'), database();
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();
change_user test_newpw,newpw,test;
--replace_result <@> <test_newpw@%> @> @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)