Commit 376090ca authored by Georgi Kodinov's avatar Georgi Kodinov

Bug #57551: Live upgrade fails between 5.1.52 -> 5.5.7-rc

Updated the server to treat a missing mysql.proxies_priv table 
as empty. 
Added some grants to make sure tables are correctly opened
when they must be opened.
Fixed a mysql_upgrade omission not adding rights to root to 
execute GRANT PROXY on other users.
Removed a redundant CREATE TABLE from 
mysql_system_tables_fix.sql since it's always executed after
mysql_system_tables.sql and the first file has CREATE TABLE 
in it. 
Added a test case for the above.
Fixed error handling code to close the cursor
parent f4586f48
......@@ -255,3 +255,67 @@ GRANT PROXY ON standard_user TO ''@'';
DROP USER ''@'';
DROP USER standard_user;
DROP DATABASE shared;
#
# Bug #57551 : Live upgrade fails between 5.1.52 -> 5.5.7-rc
#
CALL mtr.add_suppression("Missing system table mysql.proxies_priv.");
DROP TABLE mysql.proxies_priv;
# Must come back with mysql.proxies_priv absent.
SELECT * FROM mysql.proxies_priv;
ERROR 42S02: Table 'mysql.proxies_priv' doesn't exist
CREATE USER u1@localhost;
GRANT ALL PRIVILEGES ON *.* TO u1@localhost;
REVOKE ALL PRIVILEGES ON *.* FROM u1@localhost;
GRANT ALL PRIVILEGES ON *.* TO u1@localhost;
CREATE USER u2@localhost;
GRANT ALL PRIVILEGES ON *.* TO u2@localhost;
# access denied because of no privileges to root
GRANT PROXY ON u2@localhost TO u1@localhost;
ERROR 28000: Access denied for user 'root'@'localhost'
# access denied because of no privileges to root
REVOKE PROXY ON u2@localhost FROM u1@localhost;
ERROR 28000: Access denied for user 'root'@'localhost'
# go try graning proxy on itself, so that it will need the table
GRANT PROXY ON u2@localhost TO u1@localhost;
ERROR 42S02: Table 'mysql.proxies_priv' doesn't exist
REVOKE PROXY ON u2@localhost FROM u1@localhost;
ERROR 42S02: Table 'mysql.proxies_priv' doesn't exist
# test if REVOKE works without the proxies_priv table
REVOKE ALL PRIVILEGES ON *.* FROM u1@localhost, u2@localhost;
# test if DROP USER work without the proxies_priv table
DROP USER u1@localhost,u2@localhost;
# test if FLUSH PRIVILEGES works without the proxies_priv table
FLUSH PRIVILEGES;
mtr.global_suppressions OK
mtr.test_suppressions OK
mysql.columns_priv OK
mysql.db OK
mysql.event OK
mysql.func OK
mysql.general_log OK
mysql.help_category OK
mysql.help_keyword OK
mysql.help_relation OK
mysql.help_topic OK
mysql.host OK
mysql.ndb_binlog_index OK
mysql.plugin OK
mysql.proc OK
mysql.procs_priv OK
mysql.servers OK
mysql.slow_log OK
mysql.tables_priv OK
mysql.time_zone OK
mysql.time_zone_leap_second OK
mysql.time_zone_name OK
mysql.time_zone_transition OK
mysql.time_zone_transition_type OK
mysql.user OK
SELECT Host,User,Proxied_host,Proxied_user,With_grant FROM mysql.proxies_priv;
Host localhost
User root
Proxied_host
Proxied_user
With_grant 1
FLUSH PRIVILEGES;
End of 5.5 tests
--source include/have_plugin_auth.inc
--source include/not_embedded.inc
--source include/mysql_upgrade_preparation.inc
query_vertical SELECT PLUGIN_STATUS, PLUGIN_TYPE, PLUGIN_DESCRIPTION
FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME='test_plugin_server';
......@@ -335,3 +336,62 @@ GRANT PROXY ON standard_user TO ''@'';
DROP USER ''@'';
DROP USER standard_user;
DROP DATABASE shared;
--echo #
--echo # Bug #57551 : Live upgrade fails between 5.1.52 -> 5.5.7-rc
--echo #
CALL mtr.add_suppression("Missing system table mysql.proxies_priv.");
DROP TABLE mysql.proxies_priv;
--echo # Must come back with mysql.proxies_priv absent.
--source include/restart_mysqld.inc
--error ER_NO_SUCH_TABLE
SELECT * FROM mysql.proxies_priv;
CREATE USER u1@localhost;
GRANT ALL PRIVILEGES ON *.* TO u1@localhost;
REVOKE ALL PRIVILEGES ON *.* FROM u1@localhost;
GRANT ALL PRIVILEGES ON *.* TO u1@localhost;
CREATE USER u2@localhost;
GRANT ALL PRIVILEGES ON *.* TO u2@localhost;
--echo # access denied because of no privileges to root
--error ER_ACCESS_DENIED_NO_PASSWORD_ERROR
GRANT PROXY ON u2@localhost TO u1@localhost;
--echo # access denied because of no privileges to root
--error ER_ACCESS_DENIED_NO_PASSWORD_ERROR
REVOKE PROXY ON u2@localhost FROM u1@localhost;
--echo # go try graning proxy on itself, so that it will need the table
connect(proxy_granter_con,localhost,u2,);
connection proxy_granter_con;
--error ER_NO_SUCH_TABLE
GRANT PROXY ON u2@localhost TO u1@localhost;
--error ER_NO_SUCH_TABLE
REVOKE PROXY ON u2@localhost FROM u1@localhost;
connection default;
disconnect proxy_granter_con;
--echo # test if REVOKE works without the proxies_priv table
REVOKE ALL PRIVILEGES ON *.* FROM u1@localhost, u2@localhost;
--echo # test if DROP USER work without the proxies_priv table
DROP USER u1@localhost,u2@localhost;
--echo # test if FLUSH PRIVILEGES works without the proxies_priv table
FLUSH PRIVILEGES;
--exec $MYSQL_UPGRADE --skip-verbose --force 2>&1
--query_vertical SELECT Host,User,Proxied_host,Proxied_user,With_grant FROM mysql.proxies_priv
FLUSH PRIVILEGES;
--echo End of 5.5 tests
......@@ -643,7 +643,14 @@ drop procedure mysql.die;
ALTER TABLE user ADD plugin char(60) DEFAULT '' NOT NULL, ADD authentication_string TEXT NOT NULL;
ALTER TABLE user MODIFY plugin char(60) DEFAULT '' NOT NULL;
CREATE TABLE IF NOT EXISTS proxies_priv (Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Proxied_host char(60) binary DEFAULT '' NOT NULL, Proxied_user char(16) binary DEFAULT '' NOT NULL, With_grant BOOL DEFAULT 0 NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp, PRIMARY KEY Host (Host,User,Proxied_host,Proxied_user), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='User proxy privileges';
-- Need to pre-fill mysql.proxies_priv with access for root even when upgrading from
-- older versions
CREATE TEMPORARY TABLE tmp_proxies_priv LIKE proxies_priv;
INSERT INTO tmp_proxies_priv VALUES ('localhost', 'root', '', '', TRUE, '', now());
INSERT INTO proxies_priv SELECT * FROM tmp_proxies_priv WHERE @had_proxies_priv_table=0;
DROP TABLE tmp_proxies_priv;
# Activate the new, possible modified privilege tables
# This should not be needed, but gives us some extra testing that the above
......
......@@ -1029,11 +1029,13 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
end_read_record(&read_record_info);
freeze_size(&acl_dbs);
(void) my_init_dynamic_array(&acl_proxy_users, sizeof(ACL_PROXY_USER),
50, 100);
if (tables[3].table)
{
init_read_record(&read_record_info, thd, table= tables[3].table, NULL, 1,
0, FALSE);
table->use_all_columns();
(void) my_init_dynamic_array(&acl_proxy_users, sizeof(ACL_PROXY_USER),
50, 100);
while (!(read_record_info.read_record(&read_record_info)))
{
ACL_PROXY_USER proxy;
......@@ -1041,12 +1043,21 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
if (proxy.check_validity(check_no_resolve))
continue;
if (push_dynamic(&acl_proxy_users, (uchar*) &proxy))
return TRUE;
{
end_read_record(&read_record_info);
goto end;
}
}
my_qsort((uchar*) dynamic_element(&acl_proxy_users, 0, ACL_PROXY_USER*),
acl_proxy_users.elements,
sizeof(ACL_PROXY_USER), (qsort_cmp) acl_compare);
end_read_record(&read_record_info);
}
else
{
sql_print_error("Missing system table mysql.proxies_priv; "
"please run mysql_upgrade to create it");
}
freeze_size(&acl_proxy_users);
init_check_host();
......@@ -1127,6 +1138,7 @@ my_bool acl_reload(THD *thd)
tables[2].next_local= tables[2].next_global= tables + 3;
tables[0].open_type= tables[1].open_type= tables[2].open_type=
tables[3].open_type= OT_BASE_ONLY;
tables[3].open_strategy= TABLE_LIST::OPEN_IF_EXISTS;
if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
{
......@@ -5703,6 +5715,8 @@ int open_grant_tables(THD *thd, TABLE_LIST *tables)
(tables+5)->init_one_table(C_STRING_WITH_LEN("mysql"),
C_STRING_WITH_LEN("proxies_priv"),
"proxies_priv", TL_WRITE);
tables[5].open_strategy= TABLE_LIST::OPEN_IF_EXISTS;
tables->next_local= tables->next_global= tables + 1;
(tables+1)->next_local= (tables+1)->next_global= tables + 2;
(tables+2)->next_local= (tables+2)->next_global= tables + 3;
......@@ -6295,6 +6309,8 @@ static int handle_grant_data(TABLE_LIST *tables, bool drop,
}
/* Handle proxies_priv table. */
if (tables[5].table)
{
if ((found= handle_grant_table(tables, 5, drop, user_from, user_to)) < 0)
{
/* Handle of table failed, don't touch the in-memory array. */
......@@ -6307,6 +6323,7 @@ static int handle_grant_data(TABLE_LIST *tables, bool drop,
found)
result= 1; /* At least one record/element found. */
}
}
end:
DBUG_RETURN(result);
}
......
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