From f1a71b68155c9ef7c4c8b4a8111aa545a5f8100f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 18 Oct 2013 12:27:07 -0700 Subject: [PATCH] bugfix: missing restore_record when modifying roles_mapping() table. (and an assert in myisam to catch these bugs easier in the future) update tests/results --- .../r/acl_roles_create_and_grant_role.result | 6 +++--- mysql-test/r/acl_roles_rebuild_role_grants.result | 12 ++++++++---- mysql-test/r/acl_roles_rename_user.result | 4 ++++ .../acl_roles_set_role-database-recursive.result | 6 ++++++ .../r/acl_roles_set_role-database-simple.result | 2 ++ .../r/acl_roles_set_role-multiple-role.result | 7 +++++++ .../r/acl_roles_set_role-routine-simple.result | 7 +++++-- mysql-test/r/acl_roles_set_role-simple.result | 2 ++ .../r/acl_roles_set_role-table-column-priv.result | 4 ++++ .../r/acl_roles_set_role-table-simple.result | 4 ++++ mysql-test/r/acl_roles_show_grants.result | 11 ++++++++--- mysql-test/t/acl_roles_create_and_grant_role.test | 5 +++++ mysql-test/t/acl_roles_rebuild_role_grants.test | 15 +++++++++++++-- .../t/acl_roles_set_role-database-simple.test | 1 + sql/sql_acl.cc | 9 +++++++-- storage/myisam/mi_write.c | 4 ++++ 16 files changed, 83 insertions(+), 16 deletions(-) diff --git a/mysql-test/r/acl_roles_create_and_grant_role.result b/mysql-test/r/acl_roles_create_and_grant_role.result index 5cf670fdbee..883ae44397d 100644 --- a/mysql-test/r/acl_roles_create_and_grant_role.result +++ b/mysql-test/r/acl_roles_create_and_grant_role.result @@ -5,18 +5,18 @@ set role r1; grant r1 to u1; select * from mysql.roles_mapping; Host User Role Admin_option -localhost root r1 N % u1 r1 N +localhost root r1 Y drop user u1; select * from mysql.roles_mapping; Host User Role Admin_option -localhost root r1 N +localhost root r1 Y show grants; Grants for root@localhost -GRANT r1 TO 'root'@'localhost' GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION GRANT USAGE ON *.* TO 'r1' +GRANT r1 TO 'root'@'localhost' WITH ADMIN OPTION drop role r1; select * from mysql.roles_mapping; Host User Role Admin_option diff --git a/mysql-test/r/acl_roles_rebuild_role_grants.result b/mysql-test/r/acl_roles_rebuild_role_grants.result index 023abda8cde..2817c046ae9 100644 --- a/mysql-test/r/acl_roles_rebuild_role_grants.result +++ b/mysql-test/r/acl_roles_rebuild_role_grants.result @@ -3,19 +3,20 @@ create user u1; grant r1 to u1; show grants for u1; Grants for u1@% -GRANT r1 TO 'u1'@'%' GRANT USAGE ON *.* TO 'u1'@'%' +GRANT r1 TO 'u1'@'%' create user u2; show grants for u1; Grants for u1@% -GRANT r1 TO 'u1'@'%' GRANT USAGE ON *.* TO 'u1'@'%' +GRANT r1 TO 'u1'@'%' show grants for u2; Grants for u2@% GRANT USAGE ON *.* TO 'u2'@'%' select * from mysql.roles_mapping; Host User Role Admin_option % u1 r1 N +localhost root r1 Y revoke r1 from u1; revoke r1 from u1; ERROR HY000: Cannot revoke role 'r1' from: 'u1'@'%'. @@ -24,16 +25,17 @@ Grants for u1@% GRANT USAGE ON *.* TO 'u1'@'%' select * from mysql.roles_mapping; Host User Role Admin_option +localhost root r1 Y grant r1 to u1; grant r1 to u1; -ERROR HY000: Cannot grant role 'r1' to: 'u1'. show grants for u1; Grants for u1@% -GRANT r1 TO 'u1'@'%' GRANT USAGE ON *.* TO 'u1'@'%' +GRANT r1 TO 'u1'@'%' select * from mysql.roles_mapping; Host User Role Admin_option % u1 r1 N +localhost root r1 Y drop role r1; show grants for u1; Grants for u1@% @@ -45,10 +47,12 @@ grant r1 to u1; select * from mysql.roles_mapping; Host User Role Admin_option % u1 r1 N +localhost root r1 Y drop user u1; show grants for u1; ERROR 42000: There is no such grant defined for user 'u1' on host '%' select * from mysql.roles_mapping; Host User Role Admin_option +localhost root r1 Y drop role r1; drop user u2; diff --git a/mysql-test/r/acl_roles_rename_user.result b/mysql-test/r/acl_roles_rename_user.result index 5817a7f94a8..987d90a5820 100644 --- a/mysql-test/r/acl_roles_rename_user.result +++ b/mysql-test/r/acl_roles_rename_user.result @@ -7,6 +7,8 @@ use mysql; select * from roles_mapping; Host User Role Admin_option test_role1 test_role2 N +localhost root test_role1 Y +localhost root test_role2 Y localhost test_user test_role1 N rename user 'test_user'@'localhost' to 'test_user_rm'@'newhost'; select user, host from user where user like 'test%'; @@ -17,6 +19,8 @@ test_user_rm newhost select * from roles_mapping; Host User Role Admin_option test_role1 test_role2 N +localhost root test_role1 Y +localhost root test_role2 Y newhost test_user_rm test_role1 N delete from mysql.roles_mapping; delete from mysql.user where user like 'test%'; diff --git a/mysql-test/r/acl_roles_set_role-database-recursive.result b/mysql-test/r/acl_roles_set_role-database-recursive.result index e61d9ed4bff..ef3c23077ec 100644 --- a/mysql-test/r/acl_roles_set_role-database-recursive.result +++ b/mysql-test/r/acl_roles_set_role-database-recursive.result @@ -12,6 +12,8 @@ test_user localhost select * from mysql.roles_mapping; Host User Role Admin_option test_role1 test_role2 N +localhost root test_role1 Y +localhost root test_role2 Y localhost test_user test_role1 N localhost test_user test_role2 N select user, host from mysql.db; @@ -32,6 +34,8 @@ test_user@localhost test_role1 select * from mysql.roles_mapping; Host User Role Admin_option test_role1 test_role2 N +localhost root test_role1 Y +localhost root test_role2 Y localhost test_user test_role1 N localhost test_user test_role2 N set role none; @@ -47,6 +51,8 @@ test_user@localhost test_role2 select * from mysql.roles_mapping; Host User Role Admin_option test_role1 test_role2 N +localhost root test_role1 Y +localhost root test_role2 Y localhost test_user test_role1 N localhost test_user test_role2 N drop user 'test_user'@'localhost'; diff --git a/mysql-test/r/acl_roles_set_role-database-simple.result b/mysql-test/r/acl_roles_set_role-database-simple.result index 7e81e3eec9b..e21a55edf2e 100644 --- a/mysql-test/r/acl_roles_set_role-database-simple.result +++ b/mysql-test/r/acl_roles_set_role-database-simple.result @@ -7,6 +7,7 @@ test_role1 test_user localhost select * from mysql.roles_mapping; Host User Role Admin_option +localhost root test_role1 Y localhost test_user test_role1 N grant select on mysql.* to test_role1; grant insert, delete on mysql.roles_mapping to test_role1; @@ -22,6 +23,7 @@ current_user() current_role() test_user@localhost test_role1 select * from mysql.roles_mapping; Host User Role Admin_option +localhost root test_role1 Y localhost test_user test_role1 N insert into mysql.user (user, host) values ('Dummy', 'Dummy'); ERROR 42000: INSERT command denied to user 'test_user'@'localhost' for table 'user' diff --git a/mysql-test/r/acl_roles_set_role-multiple-role.result b/mysql-test/r/acl_roles_set_role-multiple-role.result index f29ad5b97e0..fca53b4d645 100644 --- a/mysql-test/r/acl_roles_set_role-multiple-role.result +++ b/mysql-test/r/acl_roles_set_role-multiple-role.result @@ -53,6 +53,13 @@ GRANT r_sel TO 'test_user'@'localhost' GRANT r_upd TO 'test_user'@'localhost' select * from mysql.roles_mapping; Host User Role Admin_option +localhost root r_crt Y +localhost root r_del Y +localhost root r_drp Y +localhost root r_ins Y +localhost root r_rld Y +localhost root r_sel Y +localhost root r_upd Y localhost test_user r_crt N localhost test_user r_del N localhost test_user r_drp N diff --git a/mysql-test/r/acl_roles_set_role-routine-simple.result b/mysql-test/r/acl_roles_set_role-routine-simple.result index b791e87d724..3e17a78ad77 100644 --- a/mysql-test/r/acl_roles_set_role-routine-simple.result +++ b/mysql-test/r/acl_roles_set_role-routine-simple.result @@ -14,6 +14,9 @@ test_user localhost select * from mysql.roles_mapping; Host User Role Admin_option test_role1 test_role2 N +localhost root test_role1 Y +localhost root test_role2 Y +localhost root test_role3 Y localhost test_user test_role1 N localhost test_user test_role3 N create function mysql.test_func (s CHAR(20)) @@ -44,7 +47,7 @@ use mysql; call test_proc(@a); SELECT @a; @a -3 +6 SELECT test_func('AABBCCDD'); test_func('AABBCCDD') Test string: AABBCCDD @@ -85,7 +88,7 @@ GRANT test_role3 TO 'test_user'@'localhost' call test_proc(@a); SELECT @a; @a -3 +6 SELECT test_func('AABBCCDD'); test_func('AABBCCDD') Test string: AABBCCDD diff --git a/mysql-test/r/acl_roles_set_role-simple.result b/mysql-test/r/acl_roles_set_role-simple.result index 3405a6dc0cf..9a4ab4d6bb5 100644 --- a/mysql-test/r/acl_roles_set_role-simple.result +++ b/mysql-test/r/acl_roles_set_role-simple.result @@ -7,6 +7,7 @@ test_role1 test_user localhost select * from mysql.roles_mapping; Host User Role Admin_option +localhost root test_role1 Y localhost test_user test_role1 N grant select on *.* to test_role1; select * from mysql.user where user='test_role1'; @@ -32,6 +33,7 @@ GRANT USAGE ON *.* TO 'test_user'@'localhost' GRANT test_role1 TO 'test_user'@'localhost' select * from mysql.roles_mapping; Host User Role Admin_option +localhost root test_role1 Y localhost test_user test_role1 N set role none; select current_user(), current_role(); diff --git a/mysql-test/r/acl_roles_set_role-table-column-priv.result b/mysql-test/r/acl_roles_set_role-table-column-priv.result index 058b8b43f76..7c621da003c 100644 --- a/mysql-test/r/acl_roles_set_role-table-column-priv.result +++ b/mysql-test/r/acl_roles_set_role-table-column-priv.result @@ -11,6 +11,8 @@ test_user localhost select * from mysql.roles_mapping; Host User Role Admin_option test_role1 test_role2 N +localhost root test_role1 Y +localhost root test_role2 Y localhost test_user test_role1 N grant select (Role) on mysql.roles_mapping to test_role2; select * from mysql.roles_mapping; @@ -39,6 +41,8 @@ ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for column 'H select Role from mysql.roles_mapping; Role test_role1 +test_role1 +test_role2 test_role2 show grants; Grants for test_user@localhost diff --git a/mysql-test/r/acl_roles_set_role-table-simple.result b/mysql-test/r/acl_roles_set_role-table-simple.result index f2f88185047..a564f078962 100644 --- a/mysql-test/r/acl_roles_set_role-table-simple.result +++ b/mysql-test/r/acl_roles_set_role-table-simple.result @@ -11,6 +11,8 @@ test_user localhost select * from mysql.roles_mapping; Host User Role Admin_option test_role1 test_role2 N +localhost root test_role1 Y +localhost root test_role2 Y localhost test_user test_role1 N grant select on mysql.roles_mapping to test_role2; select * from mysql.roles_mapping; @@ -37,6 +39,8 @@ GRANT test_role2 TO 'test_role1' select * from mysql.roles_mapping; Host User Role Admin_option test_role1 test_role2 N +localhost root test_role1 Y +localhost root test_role2 Y localhost test_user test_role1 N show grants; Grants for test_user@localhost diff --git a/mysql-test/r/acl_roles_show_grants.result b/mysql-test/r/acl_roles_show_grants.result index 02a43eca7db..e6b6bde887f 100644 --- a/mysql-test/r/acl_roles_show_grants.result +++ b/mysql-test/r/acl_roles_show_grants.result @@ -12,6 +12,8 @@ test_user localhost select * from mysql.roles_mapping; Host User Role Admin_option test_role1 test_role2 N +localhost root test_role1 Y +localhost root test_role2 Y localhost test_user test_role1 N localhost test_user test_role2 N select user, host from mysql.db; @@ -22,11 +24,14 @@ grant select on mysql.* to test_role2; flush privileges; select * from information_schema.applicable_roles; GRANTEE ROLE_NAME IS_GRANTABLE +root@localhost test_role1 YES +root@localhost test_role2 YES +test_role1 test_role2 NO select * from information_schema.applicable_roles; GRANTEE ROLE_NAME IS_GRANTABLE -test_role1 test_role2 YES -test_user@localhost test_role1 YES -test_user@localhost test_role2 YES +test_role1 test_role2 NO +test_user@localhost test_role1 NO +test_user@localhost test_role2 NO show grants; Grants for test_user@localhost GRANT USAGE ON *.* TO 'test_user'@'localhost' diff --git a/mysql-test/t/acl_roles_create_and_grant_role.test b/mysql-test/t/acl_roles_create_and_grant_role.test index f2ade04820a..99698c67497 100644 --- a/mysql-test/t/acl_roles_create_and_grant_role.test +++ b/mysql-test/t/acl_roles_create_and_grant_role.test @@ -4,11 +4,16 @@ create user u1; set role r1; grant r1 to u1; +--sorted_result select * from mysql.roles_mapping; drop user u1; +--sorted_result select * from mysql.roles_mapping; +--sorted_result show grants; drop role r1; +--sorted_result select * from mysql.roles_mapping; +--sorted_result show grants; diff --git a/mysql-test/t/acl_roles_rebuild_role_grants.test b/mysql-test/t/acl_roles_rebuild_role_grants.test index 5a9b2a0944a..1898699964c 100644 --- a/mysql-test/t/acl_roles_rebuild_role_grants.test +++ b/mysql-test/t/acl_roles_rebuild_role_grants.test @@ -4,40 +4,51 @@ create user u1; grant r1 to u1; #CHECK IF GRANTS ARE UPDATED ON GRANT +--sorted_result show grants for u1; create user u2; #CHECK THAT GRANTS ARE UPDATED ON ACL_USERS CHANGE +--sorted_result show grants for u1; +--sorted_result show grants for u2; +--sorted_result select * from mysql.roles_mapping; revoke r1 from u1; #TEST ERROR MESSAGE --error ER_CANNOT_REVOKE_ROLE revoke r1 from u1; +--sorted_result show grants for u1; +--sorted_result select * from mysql.roles_mapping; +# granting twice is ok grant r1 to u1; -#TEST ERROR MESSAGE ---error ER_CANNOT_GRANT_ROLE grant r1 to u1; +--sorted_result show grants for u1; +--sorted_result select * from mysql.roles_mapping; drop role r1; +--sorted_result show grants for u1; +--sorted_result select * from mysql.roles_mapping; create role r1; grant r1 to u1; +--sorted_result select * from mysql.roles_mapping; drop user u1; --error ER_NONEXISTING_GRANT show grants for u1; +--sorted_result select * from mysql.roles_mapping; drop role r1; diff --git a/mysql-test/t/acl_roles_set_role-database-simple.test b/mysql-test/t/acl_roles_set_role-database-simple.test index 4db9ee26829..1548e3d98e2 100644 --- a/mysql-test/t/acl_roles_set_role-database-simple.test +++ b/mysql-test/t/acl_roles_set_role-database-simple.test @@ -21,6 +21,7 @@ select * from mysql.roles_mapping; select current_user(), current_role(); set role test_role1; select current_user(), current_role(); +--sorted_result select * from mysql.roles_mapping; --error ER_TABLEACCESS_DENIED_ERROR insert into mysql.user (user, host) values ('Dummy', 'Dummy'); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index cedf4113f7e..ed283613371 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3798,6 +3798,7 @@ replace_roles_mapping_table(TABLE *table, ROLE_GRANT_PAIR *pair, uchar row_key[MAX_KEY_LENGTH]; int error; table->use_all_columns(); + restore_record(table, s->default_values); table->field[0]->store(pair->u_hname, strlen(pair->u_hname), system_charset_info); table->field[1]->store(pair->u_uname, strlen(pair->u_uname), @@ -3805,6 +3806,8 @@ replace_roles_mapping_table(TABLE *table, ROLE_GRANT_PAIR *pair, table->field[2]->store(pair->r_uname, strlen(pair->r_uname), system_charset_info); + DBUG_ASSERT(!revoke_grant || existing); + if (existing) // delete or update { key_copy(row_key, table->record[0], table->key_info, @@ -7874,11 +7877,13 @@ int open_grant_tables(THD *thd, TABLE_LIST *tables) account in tests. */ tables[0].updating= tables[1].updating= tables[2].updating= - tables[3].updating= tables[4].updating= tables[5].updating= 1; + tables[3].updating= tables[4].updating= tables[5].updating= + tables[6].updating= 1; if (!(thd->spcont || rpl_filter->tables_ok(0, tables))) DBUG_RETURN(1); tables[0].updating= tables[1].updating= tables[2].updating= - tables[3].updating= tables[4].updating= tables[5].updating= 0; + tables[3].updating= tables[4].updating= tables[5].updating= + tables[6].updating= 0; } #endif diff --git a/storage/myisam/mi_write.c b/storage/myisam/mi_write.c index cdf4f5d2bf8..5ac5a128918 100644 --- a/storage/myisam/mi_write.c +++ b/storage/myisam/mi_write.c @@ -55,6 +55,10 @@ int mi_write(MI_INFO *info, uchar *record) DBUG_EXECUTE_IF("myisam_pretend_crashed_table_on_usage", mi_print_error(info->s, HA_ERR_CRASHED); DBUG_RETURN(my_errno= HA_ERR_CRASHED);); + + /* it's always a bug to try to write a record with the deleted flag set */ + DBUG_ASSERT(info->s->data_file_type != STATIC_RECORD || *record); + if (share->options & HA_OPTION_READ_ONLY_DATA) { DBUG_RETURN(my_errno=EACCES);