diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2022-09-20 12:38:25 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2022-09-20 12:38:25 +0300 |
commit | 0c0a56902898038726342ae11decf4bf5421d339 (patch) | |
tree | ed1f66692ac80cce3d168831a72f22100f5ee928 /sql/sql_acl.cc | |
parent | ef784c4ea2ce93bc8cdd953e84456e69f5875dda (diff) | |
parent | 5dcc56be4d9979e9be927b68f4e62df7a6c3d5a1 (diff) | |
download | mariadb-git-0c0a56902898038726342ae11decf4bf5421d339.tar.gz |
Merge 10.3 into 10.4
Diffstat (limited to 'sql/sql_acl.cc')
-rw-r--r-- | sql/sql_acl.cc | 85 |
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); } |