diff --git a/mysql-test/r/acl_roles_show_grants.result b/mysql-test/r/acl_roles_show_grants.result index cfe93392f41..a9faee58fb9 100644 --- a/mysql-test/r/acl_roles_show_grants.result +++ b/mysql-test/r/acl_roles_show_grants.result @@ -36,6 +36,10 @@ select current_user(), current_role(); current_user() current_role() test_user@localhost NULL set role test_role1; +select * from information_schema.enabled_roles; +ROLE_NAME +test_role2 +test_role1 select current_user(), current_role(); current_user() current_role() test_user@localhost test_role1 @@ -49,6 +53,9 @@ GRANT test_role1 TO 'test_user'@'localhost' GRANT test_role2 TO 'test_role1' GRANT test_role2 TO 'test_user'@'localhost' set role none; +select * from information_schema.enabled_roles; +ROLE_NAME +NULL select current_user(), current_role(); current_user() current_role() test_user@localhost NULL @@ -81,6 +88,9 @@ ERROR 42000: There is no such grant defined for user 'test_user' on host 'localh show grants for CURRENT_ROLE(); ERROR 42000: There is no such grant defined for user 'test_user' on host 'localhost' set role test_role2; +select * from information_schema.enabled_roles; +ROLE_NAME +test_role2 select current_user(), current_role(); current_user() current_role() test_user@localhost test_role2 diff --git a/mysql-test/suite/funcs_1/r/is_tables_is.result b/mysql-test/suite/funcs_1/r/is_tables_is.result index 5d3770c42de..93c1a51e9ed 100644 --- a/mysql-test/suite/funcs_1/r/is_tables_is.result +++ b/mysql-test/suite/funcs_1/r/is_tables_is.result @@ -177,6 +177,29 @@ user_comment Separator ----------------------------------------------------- TABLE_CATALOG def TABLE_SCHEMA information_schema +TABLE_NAME ENABLED_ROLES +TABLE_TYPE SYSTEM VIEW +ENGINE MEMORY +VERSION 10 +ROW_FORMAT Fixed +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG def +TABLE_SCHEMA information_schema TABLE_NAME ENGINES TABLE_TYPE SYSTEM VIEW ENGINE MEMORY @@ -1000,6 +1023,29 @@ user_comment Separator ----------------------------------------------------- TABLE_CATALOG def TABLE_SCHEMA information_schema +TABLE_NAME ENABLED_ROLES +TABLE_TYPE SYSTEM VIEW +ENGINE MEMORY +VERSION 10 +ROW_FORMAT Fixed +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG def +TABLE_SCHEMA information_schema TABLE_NAME ENGINES TABLE_TYPE SYSTEM VIEW ENGINE MEMORY diff --git a/mysql-test/t/acl_roles_show_grants.test b/mysql-test/t/acl_roles_show_grants.test index bae9865d98d..157458b5c79 100644 --- a/mysql-test/t/acl_roles_show_grants.test +++ b/mysql-test/t/acl_roles_show_grants.test @@ -30,10 +30,12 @@ change_user 'test_user'; show grants; select current_user(), current_role(); set role test_role1; +select * from information_schema.enabled_roles; select current_user(), current_role(); --sorted_result show grants; set role none; +select * from information_schema.enabled_roles; select current_user(), current_role(); --sorted_result show grants; @@ -54,6 +56,7 @@ show grants for CURRENT_ROLE; show grants for CURRENT_ROLE(); set role test_role2; +select * from information_schema.enabled_roles; select current_user(), current_role(); --sorted_result show grants; diff --git a/sql/handler.h b/sql/handler.h index 416808a74e1..6427edb01a6 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -593,12 +593,14 @@ struct TABLE; */ enum enum_schema_tables { - SCH_CHARSETS= 0, + SCH_ALL_PLUGINS, + SCH_CHARSETS, SCH_CLIENT_STATS, SCH_COLLATIONS, SCH_COLLATION_CHARACTER_SET_APPLICABILITY, SCH_COLUMNS, SCH_COLUMN_PRIVILEGES, + SCH_ENABLED_ROLES, SCH_ENGINES, SCH_EVENTS, SCH_EXPLAIN, @@ -612,7 +614,6 @@ enum enum_schema_tables SCH_PARAMETERS, SCH_PARTITIONS, SCH_PLUGINS, - SCH_ALL_PLUGINS, SCH_PROCESSLIST, SCH_PROFILES, SCH_REFERENTIAL_CONSTRAINTS, diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 3711c1a7f66..5c39722d009 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -759,8 +759,7 @@ static void role_explore_set_final_access_bits(ACL_ROLE *parent, static bool role_explore_detect_cycle(ACL_ROLE *current, ACL_ROLE *neighbour, void *context_data); -static int traverse_role_graph(ACL_ROLE *role, - void *context_data, +static int traverse_role_graph(ACL_ROLE *role, void *context_data, bool (*on_start) (ACL_ROLE *role, void *context_data), bool (*on_open) (ACL_ROLE *current, @@ -2557,6 +2556,7 @@ static int traverse_role_graph(ACL_ROLE *role, */ DBUG_ASSERT(!(role->flags & ROLE_VISITED)); DBUG_ASSERT(!(role->flags & ROLE_EXPLORED)); + mysql_mutex_assert_owner(&acl_cache->lock); if (on_start && on_start(role, context_data)) DBUG_RETURN(1); @@ -7385,6 +7385,7 @@ static int show_routine_grants(THD* thd, return error; } + static void reset_role_db_privileges(ACL_ROLE *role) { char *rolename= role->user.str; @@ -9459,8 +9460,43 @@ show_proxy_grants(THD *thd, const char *username, const char *hostname, } +static void +fill_schema_enabled_roles_insert(ACL_ROLE *unused __attribute__((unused)), + ACL_ROLE *role, void *context_data) +{ + TABLE *table= (TABLE*) context_data; + restore_record(table, s->default_values); + table->field[0]->set_notnull(); + table->field[0]->store(role->user.str, role->user.length, + system_charset_info); + /*return*/ schema_table_store_record(table->in_use, table); +} + #endif /*NO_EMBEDDED_ACCESS_CHECKS */ +int fill_schema_enabled_roles(THD *thd, TABLE_LIST *tables, COND *cond) +{ + TABLE *table= tables->table; +#ifndef NO_EMBEDDED_ACCESS_CHECKS + if (thd->security_ctx->priv_role[0]) + { + mysql_rwlock_rdlock(&LOCK_grant); + mysql_mutex_lock(&acl_cache->lock); + ACL_ROLE *acl_role= find_acl_role(thd->security_ctx->priv_role); + DBUG_ASSERT(acl_role); + traverse_role_graph(acl_role, table, NULL, NULL, NULL, + fill_schema_enabled_roles_insert); + mysql_mutex_unlock(&acl_cache->lock); + mysql_rwlock_unlock(&LOCK_grant); + return 0; + } +#endif + + restore_record(table, s->default_values); + table->field[0]->set_null(); + return schema_table_store_record(table->in_use, table); +} + int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr) { diff --git a/sql/sql_acl.h b/sql/sql_acl.h index 8a6c6cba307..64370f8705f 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -233,6 +233,7 @@ ulong get_column_grant(THD *thd, GRANT_INFO *grant, const char *db_name, const char *table_name, const char *field_name); bool mysql_show_grants(THD *thd, LEX_USER *user); +int fill_schema_enabled_roles(THD *thd, TABLE_LIST *tables, COND *cond); void get_privilege_desc(char *to, uint max_length, ulong access); void get_mqh(const char *user, const char *host, USER_CONN *uc); bool mysql_create_user(THD *thd, List &list, bool handle_as_role); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 72796cb096c..184f94f5b5c 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -8369,6 +8369,13 @@ ST_FIELD_INFO collation_fields_info[]= }; +ST_FIELD_INFO enabled_roles_fields_info[]= +{ + {"ROLE_NAME", USERNAME_CHAR_LENGTH, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL, 0, 0}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} +}; + + ST_FIELD_INFO engines_fields_info[]= { {"ENGINE", 64, MYSQL_TYPE_STRING, 0, 0, "Engine", SKIP_OPEN_TABLE}, @@ -8964,6 +8971,8 @@ ST_FIELD_INFO show_explain_fields_info[]= ST_SCHEMA_TABLE schema_tables[]= { + {"ALL_PLUGINS", plugin_fields_info, create_schema_table, + fill_all_plugins, make_old_format, 0, 5, -1, 0, 0}, {"CHARACTER_SETS", charsets_fields_info, create_schema_table, fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0}, {"CLIENT_STATISTICS", client_stats_fields_info, create_schema_table, @@ -8977,6 +8986,8 @@ ST_SCHEMA_TABLE schema_tables[]= OPTIMIZE_I_S_TABLE|OPEN_VIEW_FULL}, {"COLUMN_PRIVILEGES", column_privileges_fields_info, create_schema_table, fill_schema_column_privileges, 0, 0, -1, -1, 0, 0}, + {"ENABLED_ROLES", enabled_roles_fields_info, create_schema_table, + fill_schema_enabled_roles, 0, 0, -1, -1, 0, 0}, {"ENGINES", engines_fields_info, create_schema_table, fill_schema_engines, make_old_format, 0, -1, -1, 0, 0}, #ifdef HAVE_EVENT_SCHEDULER @@ -9010,8 +9021,6 @@ ST_SCHEMA_TABLE schema_tables[]= OPTIMIZE_I_S_TABLE|OPEN_TABLE_ONLY}, {"PLUGINS", plugin_fields_info, create_schema_table, fill_plugins, make_old_format, 0, -1, -1, 0, 0}, - {"ALL_PLUGINS", plugin_fields_info, create_schema_table, - fill_all_plugins, make_old_format, 0, 5, -1, 0, 0}, {"PROCESSLIST", processlist_fields_info, create_schema_table, fill_schema_processlist, make_old_format, 0, -1, -1, 0, 0}, {"PROFILING", query_profile_statistics_info, create_schema_table,