summaryrefslogtreecommitdiff
path: root/sql/sql_acl.cc
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2022-09-20 12:38:25 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2022-09-20 12:38:25 +0300
commit0c0a56902898038726342ae11decf4bf5421d339 (patch)
treeed1f66692ac80cce3d168831a72f22100f5ee928 /sql/sql_acl.cc
parentef784c4ea2ce93bc8cdd953e84456e69f5875dda (diff)
parent5dcc56be4d9979e9be927b68f4e62df7a6c3d5a1 (diff)
downloadmariadb-git-0c0a56902898038726342ae11decf4bf5421d339.tar.gz
Merge 10.3 into 10.4
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 826b2d9ea22..3eb89b58289 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -5243,7 +5243,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, ulong p, ulong c)
- :GRANT_NAME(h,d,u,t,p, FALSE), cols(c)
+ :GRANT_NAME(h,d,u,t,p, FALSE), cols(c), init_cols(c)
{
init_hash();
}
@@ -6037,6 +6037,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
@@ -6056,6 +6057,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.
@@ -6502,7 +6508,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)
-
{
ulong rights __attribute__((unused))= 0;
int changed= 0;
@@ -6851,11 +6856,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);
}
/*****************************************************************
@@ -7045,15 +7051,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,
@@ -7062,8 +7068,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 */
}
}
@@ -7077,11 +7083,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= 0;
@@ -7089,13 +7099,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;
}
@@ -7223,23 +7234,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;
}
}
@@ -7576,7 +7588,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);
}
@@ -10179,9 +10191,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 (uint i=0; i < acl_role->role_grants.elements; i++)
{
@@ -10197,6 +10206,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);
}