mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
bugfix: propagate grant changes through the role graph after table/column/routine grants
This commit is contained in:
@ -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_%';
|
|||||||
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
|
|||||||
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
|
|||||||
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;
|
|||||||
|
|
||||||
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;
|
|||||||
|
|
||||||
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;
|
|||||||
|
|
||||||
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,
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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)
|
||||||
|
Reference in New Issue
Block a user