Commit c28bf2a3 authored by Sergei Golubchik's avatar Sergei Golubchik

bugfix: propagate grant changes through the role graph after table/column/routine grants

parent d0db4f22
...@@ -26,7 +26,6 @@ end| ...@@ -26,7 +26,6 @@ end|
grant execute on function mysql.test_func to test_role2; grant execute on function mysql.test_func to test_role2;
grant execute on procedure mysql.test_proc to test_role2; grant execute on procedure mysql.test_proc to test_role2;
grant execute on mysql.* to test_role3; grant execute on mysql.* to test_role3;
flush privileges;
show grants; show grants;
Grants for test_user@localhost Grants for test_user@localhost
GRANT USAGE ON *.* TO 'test_user'@'localhost' GRANT USAGE ON *.* TO 'test_user'@'localhost'
...@@ -98,6 +97,4 @@ delete from mysql.user where user like'test_%'; ...@@ -98,6 +97,4 @@ delete from mysql.user where user like'test_%';
delete from mysql.roles_mapping where Role like 'test%'; delete from mysql.roles_mapping where Role like 'test%';
drop function mysql.test_func; drop function mysql.test_func;
drop procedure mysql.test_proc; drop procedure mysql.test_proc;
Warnings:
Warning 1403 There is no such grant defined for user 'test_role1' on host '' on routine 'test_proc'
flush privileges; flush privileges;
...@@ -13,7 +13,6 @@ Host User Role Admin_option ...@@ -13,7 +13,6 @@ Host User Role Admin_option
test_role1 test_role2 N test_role1 test_role2 N
localhost test_user test_role1 N localhost test_user test_role1 N
grant select (Role) on mysql.roles_mapping to test_role2; grant select (Role) on mysql.roles_mapping to test_role2;
flush privileges;
select * from mysql.roles_mapping; select * from mysql.roles_mapping;
ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table 'roles_mapping' ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table 'roles_mapping'
show grants; show grants;
......
...@@ -13,7 +13,6 @@ Host User Role Admin_option ...@@ -13,7 +13,6 @@ Host User Role Admin_option
test_role1 test_role2 N test_role1 test_role2 N
localhost test_user test_role1 N localhost test_user test_role1 N
grant select on mysql.roles_mapping to test_role2; grant select on mysql.roles_mapping to test_role2;
flush privileges;
select * from mysql.roles_mapping; select * from mysql.roles_mapping;
ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table 'roles_mapping' ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table 'roles_mapping'
show grants; show grants;
......
...@@ -29,8 +29,6 @@ grant execute on procedure mysql.test_proc to test_role2; ...@@ -29,8 +29,6 @@ grant execute on procedure mysql.test_proc to test_role2;
grant execute on mysql.* to test_role3; grant execute on mysql.* to test_role3;
flush privileges;
change_user 'test_user'; change_user 'test_user';
--sorted_result --sorted_result
show grants; show grants;
......
...@@ -11,8 +11,6 @@ select * from mysql.roles_mapping; ...@@ -11,8 +11,6 @@ select * from mysql.roles_mapping;
grant select (Role) on mysql.roles_mapping to test_role2; grant select (Role) on mysql.roles_mapping to test_role2;
flush privileges;
change_user 'test_user'; change_user 'test_user';
--error ER_TABLEACCESS_DENIED_ERROR --error ER_TABLEACCESS_DENIED_ERROR
......
...@@ -11,8 +11,6 @@ select * from mysql.roles_mapping; ...@@ -11,8 +11,6 @@ select * from mysql.roles_mapping;
grant select on mysql.roles_mapping to test_role2; grant select on mysql.roles_mapping to test_role2;
flush privileges;
change_user 'test_user'; change_user 'test_user';
--error ER_TABLEACCESS_DENIED_ERROR --error ER_TABLEACCESS_DENIED_ERROR
......
...@@ -709,41 +709,24 @@ static bool update_user_table(THD *thd, TABLE *table, const char *host, ...@@ -709,41 +709,24 @@ static bool update_user_table(THD *thd, TABLE *table, const char *host,
static my_bool acl_load(THD *thd, TABLE_LIST *tables); static my_bool acl_load(THD *thd, TABLE_LIST *tables);
static my_bool grant_load(THD *thd, TABLE_LIST *tables); static my_bool grant_load(THD *thd, TABLE_LIST *tables);
static inline void get_grantor(THD *thd, char* grantor); static inline void get_grantor(THD *thd, char* grantor);
static my_bool acl_user_reset_grant(ACL_USER *user, static my_bool acl_user_reset_grant(ACL_USER *, void *);
void * not_used __attribute__((unused))); static my_bool acl_role_reset_grant(ACL_ROLE *, void *);
static my_bool acl_role_reset_grant(ACL_ROLE *role, static my_bool acl_role_propagate_grants(ACL_ROLE *, void *);
void * not_used __attribute__((unused)));
static my_bool acl_role_propagate_grants(ACL_ROLE *role,
void * not_used __attribute__((unused)));
static int add_role_user_mapping(ROLE_GRANT_PAIR *mapping); static int add_role_user_mapping(ROLE_GRANT_PAIR *mapping);
static void reset_role_db_privileges(ACL_ROLE *role); static void reset_role_db_privileges(ACL_ROLE *role);
static void reset_role_table_and_column_privileges(ACL_ROLE *role); static void reset_role_table_and_column_privileges(ACL_ROLE *role);
static void reset_role_routine_grant_privileges(ACL_ROLE *role); static void reset_role_routine_grant_privileges(ACL_ROLE *role);
static void role_explore_create_list(ACL_ROLE *unused, static void role_explore_create_list(ACL_ROLE *, ACL_ROLE *, void *);
ACL_ROLE *role,
void *context_data);
static bool role_explore_start_access_check(ACL_ROLE *role, void *unused); static bool role_explore_start_access_check(ACL_ROLE *role, void *unused);
static bool role_explore_merge_if_final(ACL_ROLE *current, ACL_ROLE *neighbour, static bool role_explore_merge_if_final(ACL_ROLE *, ACL_ROLE *, void *);
void *unused); static void role_explore_set_final_access_bits(ACL_ROLE *, ACL_ROLE *, void *);
static void role_explore_set_final_access_bits(ACL_ROLE *parent, static bool role_explore_detect_cycle(ACL_ROLE *, ACL_ROLE *, void *);
ACL_ROLE *current, static int traverse_role_graph(ACL_ROLE *, void *,
void *unused); bool (*)(ACL_ROLE *, void *),
static bool role_explore_detect_cycle(ACL_ROLE *current, bool (*)(ACL_ROLE *, ACL_ROLE *, void *),
ACL_ROLE *neighbour, bool (*)(ACL_ROLE *, ACL_ROLE *, void *),
void *context_data); void (*)(ACL_ROLE *, ACL_ROLE *, void *));
static int traverse_role_graph(ACL_ROLE *role, void *context_data,
bool (*on_start) (ACL_ROLE *role,
void *context_data),
bool (*on_open) (ACL_ROLE *current,
ACL_ROLE *neighbour,
void *context_data),
bool (*on_cycle) (ACL_ROLE *current,
ACL_ROLE *neighbour,
void *context_data),
void (*on_finish)(ACL_ROLE *parent,
ACL_ROLE *current,
void *context_data));
static void merge_role_grant_privileges(ACL_ROLE *target, ACL_ROLE *source); static void merge_role_grant_privileges(ACL_ROLE *target, ACL_ROLE *source);
...@@ -1999,15 +1982,22 @@ static void acl_update_role_entry(ACL_ROLE *role, ulong privileges) ...@@ -1999,15 +1982,22 @@ static void acl_update_role_entry(ACL_ROLE *role, ulong privileges)
} }
static void acl_update_role(const char *rolename, static void acl_update_role(const char *rolename)
ulong privileges) {
mysql_mutex_assert_owner(&acl_cache->lock);
ACL_ROLE *role= find_acl_role(rolename);
if (!role)
return;
acl_update_role_entry(role, role->initial_role_access);
}
static void acl_update_role(const char *rolename, ulong privileges)
{ {
mysql_mutex_assert_owner(&acl_cache->lock); mysql_mutex_assert_owner(&acl_cache->lock);
ACL_ROLE *role= find_acl_role(rolename); ACL_ROLE *role= find_acl_role(rolename);
if (!role) if (!role)
{
return; return;
}
acl_update_role_entry(role, privileges); acl_update_role_entry(role, privileges);
} }
...@@ -5117,7 +5107,10 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, ...@@ -5117,7 +5107,10 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
result= TRUE; result= TRUE;
} }
} }
if (Str->is_role())
acl_update_role(Str->user.str);
} }
thd->mem_root= old_root; thd->mem_root= old_root;
mysql_mutex_unlock(&acl_cache->lock); mysql_mutex_unlock(&acl_cache->lock);
...@@ -5278,6 +5271,8 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, ...@@ -5278,6 +5271,8 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
result= TRUE; result= TRUE;
continue; continue;
} }
if (Str->is_role())
acl_update_role(Str->user.str);
} }
thd->mem_root= old_root; thd->mem_root= old_root;
mysql_mutex_unlock(&acl_cache->lock); mysql_mutex_unlock(&acl_cache->lock);
...@@ -7903,6 +7898,10 @@ static int modify_grant_table(TABLE *table, Field *host_field, ...@@ -7903,6 +7898,10 @@ static int modify_grant_table(TABLE *table, Field *host_field,
It creates data structures if they don't exist for the grantee. It creates data structures if they don't exist for the grantee.
This includes data structures related to database privileges, tables This includes data structures related to database privileges, tables
privileges, column privileges, function and procedures privileges privileges, column privileges, function and procedures privileges
TODO only merge those privileges that were changed
(e.g. only table/column privileges after mysql_table_grant, only routine
privileges after mysql_routine_grant)
*/ */
static void merge_role_grant_privileges(ACL_ROLE *target, ACL_ROLE *source) static void merge_role_grant_privileges(ACL_ROLE *target, ACL_ROLE *source)
......
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