summaryrefslogtreecommitdiff
path: root/sql/sql_acl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_acl.cc')
-rw-r--r--sql/sql_acl.cc85
1 files changed, 50 insertions, 35 deletions
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index d4d69345689..becf519901a 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -5394,7 +5394,7 @@ GRANT_NAME::GRANT_NAME(const char *h, const char *d,const char *u,
GRANT_TABLE::GRANT_TABLE(const char *h, const char *d,const char *u,
const char *t, privilege_t p, privilege_t c)
- :GRANT_NAME(h,d,u,t,p, FALSE), cols(c), init_cols(NO_ACL)
+ :GRANT_NAME(h,d,u,t,p, FALSE), cols(c), init_cols(c)
{
init_hash();
}
@@ -6185,6 +6185,7 @@ static int count_subgraph_nodes(ACL_ROLE *role, ACL_ROLE *grantee, void *context
}
static int merge_role_privileges(ACL_ROLE *, ACL_ROLE *, void *);
+static bool merge_one_role_privileges(ACL_ROLE *grantee, PRIVS_TO_MERGE what);
/**
rebuild privileges of all affected roles
@@ -6204,6 +6205,11 @@ static void propagate_role_grants(ACL_ROLE *role,
PRIVS_TO_MERGE data= { what, db, name };
/*
+ Before updating grants to roles that inherit from this role, ensure that
+ the effective grants on this role are up-to-date from *its* granted roles.
+ */
+ merge_one_role_privileges(role, data);
+ /*
Changing privileges of a role causes all other roles that had
this role granted to them to have their rights invalidated.
@@ -6651,7 +6657,6 @@ static int table_name_sort(GRANT_TABLE * const *tbl1, GRANT_TABLE * const *tbl2)
*/
static int update_role_columns(GRANT_TABLE *merged,
GRANT_TABLE **cur, GRANT_TABLE **last)
-
{
privilege_t rights __attribute__((unused)) (NO_ACL);
int changed= 0;
@@ -7002,11 +7007,12 @@ static int merge_role_privileges(ACL_ROLE *role __attribute__((unused)),
return !changed; // don't recurse into the subgraph if privs didn't change
}
-static bool merge_one_role_privileges(ACL_ROLE *grantee)
+static
+bool merge_one_role_privileges(ACL_ROLE *grantee,
+ PRIVS_TO_MERGE what)
{
- PRIVS_TO_MERGE data= { PRIVS_TO_MERGE::ALL, 0, 0 };
grantee->counter= 1;
- return merge_role_privileges(0, grantee, &data);
+ return merge_role_privileges(0, grantee, &what);
}
/*****************************************************************
@@ -7197,15 +7203,15 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
/* Find/create cached table grant */
grant_table= table_hash_search(Str->host.str, NullS, db_name,
- Str->user.str, table_name, 1);
+ Str->user.str, table_name, 1);
if (!grant_table)
{
if (revoke_grant)
{
- my_error(ER_NONEXISTING_TABLE_GRANT, MYF(0),
+ my_error(ER_NONEXISTING_TABLE_GRANT, MYF(0),
Str->user.str, Str->host.str, table_list->table_name.str);
- result= TRUE;
- continue;
+ result= TRUE;
+ continue;
}
grant_table= new (&grant_memroot) GRANT_TABLE(Str->host.str, db_name,
Str->user.str, table_name,
@@ -7214,8 +7220,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
if (!grant_table ||
column_priv_insert(grant_table))
{
- result= TRUE; /* purecov: deadcode */
- continue; /* purecov: deadcode */
+ result= TRUE; /* purecov: deadcode */
+ continue; /* purecov: deadcode */
}
}
@@ -7229,11 +7235,15 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
/* Fix old grants */
while ((column = column_iter++))
{
- grant_column = column_hash_search(grant_table,
- column->column.ptr(),
- column->column.length());
- if (grant_column)
- grant_column->rights&= ~(column->rights | rights);
+ grant_column = column_hash_search(grant_table,
+ column->column.ptr(),
+ column->column.length());
+ if (grant_column)
+ {
+ grant_column->init_rights&= ~(column->rights | rights);
+ // If this is a role, rights will need to be reconstructed.
+ grant_column->rights= grant_column->init_rights;
+ }
}
/* scan trough all columns to get new column grant */
column_priv= NO_ACL;
@@ -7241,13 +7251,14 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
{
grant_column= (GRANT_COLUMN*)
my_hash_element(&grant_table->hash_columns, idx);
- grant_column->rights&= ~rights; // Fix other columns
- column_priv|= grant_column->rights;
+ grant_column->init_rights&= ~rights; // Fix other columns
+ grant_column->rights= grant_column->init_rights;
+ column_priv|= grant_column->init_rights;
}
}
else
{
- column_priv|= grant_table->cols;
+ column_priv|= grant_table->init_cols;
}
@@ -7375,23 +7386,24 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list,
table_name= table_list->table_name.str;
grant_name= routine_hash_search(Str->host.str, NullS, db_name,
Str->user.str, table_name, sph, 1);
- if (!grant_name || !grant_name->init_privs)
+ if (revoke_grant && (!grant_name || !grant_name->init_privs))
{
- if (revoke_grant)
- {
- my_error(ER_NONEXISTING_PROC_GRANT, MYF(0),
- Str->user.str, Str->host.str, table_name);
- result= TRUE;
- continue;
- }
+ my_error(ER_NONEXISTING_PROC_GRANT, MYF(0),
+ Str->user.str, Str->host.str, table_name);
+ result= TRUE;
+ continue;
+ }
+ if (!grant_name)
+ {
+ DBUG_ASSERT(!revoke_grant);
grant_name= new GRANT_NAME(Str->host.str, db_name,
- Str->user.str, table_name,
- rights, TRUE);
+ Str->user.str, table_name,
+ rights, TRUE);
if (!grant_name ||
- my_hash_insert(sph->get_priv_hash(), (uchar*) grant_name))
+ my_hash_insert(sph->get_priv_hash(), (uchar*) grant_name))
{
result= TRUE;
- continue;
+ continue;
}
}
@@ -7728,7 +7740,7 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list, bool revoke)
Only need to propagate grants when granting/revoking a role to/from
a role
*/
- if (role_as_user && merge_one_role_privileges(role_as_user) == 0)
+ if (role_as_user)
propagate_role_grants(role_as_user, PRIVS_TO_MERGE::ALL);
}
@@ -10348,9 +10360,6 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
size_t old_key_length= acl_role->user.length;
if (drop)
{
- /* all grants must be revoked from this role by now. propagate this */
- propagate_role_grants(acl_role, PRIVS_TO_MERGE::ALL);
-
// delete the role from cross-reference arrays
for (size_t i=0; i < acl_role->role_grants.elements; i++)
{
@@ -10366,6 +10375,12 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
remove_ptr_from_dynarray(&grantee->role_grants, acl_role);
}
+ /* Remove all of the role_grants from this role. */
+ delete_dynamic(&acl_role->role_grants);
+
+ /* all grants must be revoked from this role by now. propagate this */
+ propagate_role_grants(acl_role, PRIVS_TO_MERGE::ALL);
+
my_hash_delete(&acl_roles, (uchar*) acl_role);
DBUG_RETURN(1);
}