diff options
author | Vicențiu Ciorbaru <vicentiu@mariadb.org> | 2017-12-22 12:23:39 +0200 |
---|---|---|
committer | Vicențiu Ciorbaru <vicentiu@mariadb.org> | 2017-12-22 12:23:39 +0200 |
commit | 985d2d393c285ecd4539cb579b680f7b91fdaa1a (patch) | |
tree | 8cabf6c09758c30df04de96ca98c7827d5665493 /sql/sql_acl.cc | |
parent | a76a2522ec4f8c069827e038997387a8b8eb3a3a (diff) | |
parent | 461cf3e5a3c2d346d75b1407b285f8daf9d01f67 (diff) | |
download | mariadb-git-985d2d393c285ecd4539cb579b680f7b91fdaa1a.tar.gz |
Merge remote-tracking branch 'origin/10.1' into 10.2
Diffstat (limited to 'sql/sql_acl.cc')
-rw-r--r-- | sql/sql_acl.cc | 77 |
1 files changed, 50 insertions, 27 deletions
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 7f155ec7808..9c7eb8af736 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2851,37 +2851,42 @@ static void acl_insert_user(const char *user, const char *host, } -static void acl_update_db(const char *user, const char *host, const char *db, +static bool acl_update_db(const char *user, const char *host, const char *db, ulong privileges) { mysql_mutex_assert_owner(&acl_cache->lock); + bool updated= false; + for (uint i=0 ; i < acl_dbs.elements ; i++) { ACL_DB *acl_db=dynamic_element(&acl_dbs,i,ACL_DB*); if ((!acl_db->user && !user[0]) || - (acl_db->user && - !strcmp(user,acl_db->user))) + (acl_db->user && + !strcmp(user,acl_db->user))) { if ((!acl_db->host.hostname && !host[0]) || - (acl_db->host.hostname && - !strcmp(host, acl_db->host.hostname))) + (acl_db->host.hostname && + !strcmp(host, acl_db->host.hostname))) { - if ((!acl_db->db && !db[0]) || - (acl_db->db && !strcmp(db,acl_db->db))) + if ((!acl_db->db && !db[0]) || + (acl_db->db && !strcmp(db,acl_db->db))) - { - if (privileges) + { + if (privileges) { acl_db->access= privileges; acl_db->initial_access= acl_db->access; } - else - delete_dynamic_element(&acl_dbs,i); - } + else + delete_dynamic_element(&acl_dbs,i); + updated= true; + } } } } + + return updated; } @@ -4373,9 +4378,21 @@ static int replace_db_table(TABLE *table, const char *db, acl_cache->clear(1); // Clear privilege cache if (old_row_exists) acl_update_db(combo.user.str,combo.host.str,db,rights); - else - if (rights) - acl_insert_db(combo.user.str,combo.host.str,db,rights); + else if (rights) + { + /* + If we did not have an already existing row, for users, we must always + insert an ACL_DB entry. For roles however, it is possible that one was + already created when DB privileges were propagated from other granted + roles onto the current role. For this case, first try to update the + existing entry, otherwise insert a new one. + */ + if (!combo.is_role() || + !acl_update_db(combo.user.str, combo.host.str, db, rights)) + { + acl_insert_db(combo.user.str,combo.host.str,db,rights); + } + } DBUG_RETURN(0); /* This could only happen if the grant tables got corrupted */ @@ -6280,6 +6297,7 @@ static int merge_role_privileges(ACL_ROLE *role __attribute__((unused)), { PRIVS_TO_MERGE *data= (PRIVS_TO_MERGE *)context; + DBUG_ASSERT(grantee->counter > 0); if (--grantee->counter) return 1; // don't recurse into grantee just yet @@ -7381,17 +7399,14 @@ end_index_init: DBUG_RETURN(return_val); } - -static my_bool role_propagate_grants_action(void *ptr, - void *unused __attribute__((unused))) +static my_bool collect_leaf_roles(void *role_ptr, + void *roles_array) { - ACL_ROLE *role= (ACL_ROLE *)ptr; - if (role->counter) - return 0; - - mysql_mutex_assert_owner(&acl_cache->lock); - PRIVS_TO_MERGE data= { PRIVS_TO_MERGE::ALL, 0, 0 }; - traverse_role_graph_up(role, &data, NULL, merge_role_privileges); + ACL_ROLE *role= static_cast<ACL_ROLE *>(role_ptr); + Dynamic_array<ACL_ROLE *> *array= + static_cast<Dynamic_array<ACL_ROLE *> *>(roles_array); + if (!role->counter) + array->push(role); return 0; } @@ -7461,7 +7476,15 @@ bool grant_reload(THD *thd) } mysql_mutex_lock(&acl_cache->lock); - my_hash_iterate(&acl_roles, role_propagate_grants_action, NULL); + Dynamic_array<ACL_ROLE *> leaf_roles; + my_hash_iterate(&acl_roles, collect_leaf_roles, &leaf_roles); + PRIVS_TO_MERGE data= { PRIVS_TO_MERGE::ALL, 0, 0 }; + for (size_t i= 0; i < leaf_roles.elements(); i++) + { + traverse_role_graph_up(leaf_roles.at(i), &data, NULL, + merge_role_privileges); + } + mysql_mutex_unlock(&acl_cache->lock); mysql_rwlock_unlock(&LOCK_grant); @@ -10181,13 +10204,13 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list, bool handle_as_role) } } - binlog= true; if (replace_user_table(thd, tables.user_table(), *user_name, 0, 0, 1, 0)) { append_user(thd, &wrong_users, user_name); result= TRUE; continue; } + binlog= true; // every created role is automatically granted to its creator-admin if (handle_as_role) |