From a2f82b649d39ec8e5e321430adf1d1ed13f86174 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Wed, 20 Feb 2019 16:23:10 +0100 Subject: [PATCH] MDEV-17942 Assertion `found' failed in remove_ptr_from_dynarray after failed CREATE OR REPLACE Failed CREATE OR REPLACE for existing user removes that user from acl_users array. Thus dependend structures (roles, check_host) must be rebuilt. --- mysql-test/r/create_drop_role.result | 9 +++++++++ mysql-test/t/create_drop_role.test | 11 +++++++++++ sql/sql_acl.cc | 11 +++++++++++ 3 files changed, 31 insertions(+) diff --git a/mysql-test/r/create_drop_role.result b/mysql-test/r/create_drop_role.result index 6e05900264d..d77fc0afc3a 100644 --- a/mysql-test/r/create_drop_role.result +++ b/mysql-test/r/create_drop_role.result @@ -73,3 +73,12 @@ Note 1976 Can't drop role 'role_1'; it doesn't exist DROP ROLE role_1; ERROR HY000: Operation DROP ROLE failed for 'role_1' DROP USER u1@localhost; +CREATE ROLE r; +GRANT SHOW DATABASES ON *.* TO r; +CREATE USER foo; +CREATE USER bar; +GRANT r TO foo; +CREATE OR REPLACE USER foo IDENTIFIED WITH non_existing_plugin; +ERROR HY000: Plugin 'non_existing_plugin' is not loaded +DROP ROLE r; +DROP USER bar; diff --git a/mysql-test/t/create_drop_role.test b/mysql-test/t/create_drop_role.test index be33083e6c4..11bc832c6e9 100644 --- a/mysql-test/t/create_drop_role.test +++ b/mysql-test/t/create_drop_role.test @@ -54,3 +54,14 @@ DROP ROLE IF EXISTS role_1; DROP ROLE role_1; DROP USER u1@localhost; + +# MDEV-17942 +CREATE ROLE r; +GRANT SHOW DATABASES ON *.* TO r; +CREATE USER foo; +CREATE USER bar; +GRANT r TO foo; +--error ER_PLUGIN_IS_NOT_LOADED +CREATE OR REPLACE USER foo IDENTIFIED WITH non_existing_plugin; +DROP ROLE r; +DROP USER bar; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 9d6e6c51fb6..a7d1f6a1b38 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -9439,6 +9439,7 @@ bool mysql_create_user(THD *thd, List &list, bool handle_as_role) List_iterator user_list(list); TABLE_LIST tables[TABLES_MAX]; bool binlog= false; + bool some_users_dropped= false; DBUG_ENTER("mysql_create_user"); DBUG_PRINT("entry", ("Handle as %s", handle_as_role ? "role" : "user")); @@ -9504,6 +9505,8 @@ bool mysql_create_user(THD *thd, List &list, bool handle_as_role) result= true; continue; } + else + some_users_dropped= true; // Proceed with the creation } else if (thd->lex->create_info.if_not_exists()) @@ -9573,9 +9576,17 @@ bool mysql_create_user(THD *thd, List &list, bool handle_as_role) mysql_mutex_unlock(&acl_cache->lock); if (result) + { + if (some_users_dropped && !handle_as_role) + { + /* Rebuild in-memory structs, since 'acl_users' has been modified */ + rebuild_check_host(); + rebuild_role_grants(); + } my_error(ER_CANNOT_USER, MYF(0), (handle_as_role) ? "CREATE ROLE" : "CREATE USER", wrong_users.c_ptr_safe()); + } if (binlog) result |= write_bin_log(thd, FALSE, thd->query(), thd->query_length());