summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2013-10-18 09:15:55 -0700
committerSergei Golubchik <sergii@pisem.net>2013-10-18 09:15:55 -0700
commitfe2d26570495c1f484b3f22fe7dfc38dd9d48193 (patch)
tree1e5b1d0e5e53df7a8e10d0ca68ee8383f0b451f7
parent7f0965f490163528a99ebc2f085087ea1c125ce2 (diff)
downloadmariadb-git-fe2d26570495c1f484b3f22fe7dfc38dd9d48193.tar.gz
INFORMATION_SCHEMA.APPLICABLE_ROLES table
-rw-r--r--mysql-test/r/acl_roles_show_grants.result7
-rw-r--r--mysql-test/suite/funcs_1/r/is_tables_is.result46
-rw-r--r--mysql-test/t/acl_roles_show_grants.test4
-rw-r--r--sql/handler.h1
-rw-r--r--sql/sql_acl.cc74
-rw-r--r--sql/sql_acl.h1
-rw-r--r--sql/sql_show.cc23
7 files changed, 146 insertions, 10 deletions
diff --git a/mysql-test/r/acl_roles_show_grants.result b/mysql-test/r/acl_roles_show_grants.result
index a9faee58fb9..63080ed1b38 100644
--- a/mysql-test/r/acl_roles_show_grants.result
+++ b/mysql-test/r/acl_roles_show_grants.result
@@ -27,6 +27,13 @@ user host
%
grant select on mysql.* to test_role2;
flush privileges;
+select * from information_schema.applicable_roles;
+GRANTEE ROLE_NAME IS_GRANTABLE
+select * from information_schema.applicable_roles;
+GRANTEE ROLE_NAME IS_GRANTABLE
+test_user@localhost test_role1 YES
+test_role1 test_role2 YES
+test_user@localhost test_role2 YES
show grants;
Grants for test_user@localhost
GRANT USAGE ON *.* TO 'test_user'@'localhost'
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 93c1a51e9ed..5ecac2f296f 100644
--- a/mysql-test/suite/funcs_1/r/is_tables_is.result
+++ b/mysql-test/suite/funcs_1/r/is_tables_is.result
@@ -39,6 +39,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
TABLE_SCHEMA information_schema
+TABLE_NAME APPLICABLE_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 CHARACTER_SETS
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -885,6 +908,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
TABLE_SCHEMA information_schema
+TABLE_NAME APPLICABLE_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 CHARACTER_SETS
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 157458b5c79..b520745128e 100644
--- a/mysql-test/t/acl_roles_show_grants.test
+++ b/mysql-test/t/acl_roles_show_grants.test
@@ -24,8 +24,12 @@ select user, host from mysql.db;
grant select on mysql.* to test_role2;
flush privileges;
+select * from information_schema.applicable_roles;
+
change_user 'test_user';
+select * from information_schema.applicable_roles;
+
--sorted_result
show grants;
select current_user(), current_role();
diff --git a/sql/handler.h b/sql/handler.h
index 6427edb01a6..e77d80e7668 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -594,6 +594,7 @@ struct TABLE;
enum enum_schema_tables
{
SCH_ALL_PLUGINS,
+ SCH_APPLICABLE_ROLES,
SCH_CHARSETS,
SCH_CLIENT_STATS,
SCH_COLLATIONS,
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 5c39722d009..bfd19f76b4b 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -318,8 +318,7 @@ static bool compare_hostname(const acl_host_and_ip *host, const char *hostname,
static bool show_proxy_grants (THD *thd,
const char *username, const char *hostname,
char *buff, size_t buffsize);
-static bool show_role_grants(THD *thd,
- const char *username, const char *hostname,
+static bool show_role_grants(THD *thd, const char *username, const char *hostname,
ACL_USER_BASE *acl_entry,
char *buff, size_t buffsize);
static bool show_global_privileges(THD *thd, ACL_USER_BASE *acl_entry,
@@ -726,8 +725,7 @@ static void rebuild_check_host(void);
static void rebuild_role_grants(void);
static void free_acl_user(ACL_USER *acl_user);
static void free_acl_role(ACL_ROLE *acl_role);
-static ACL_USER *find_user_no_anon(const char *host, const char *user,
- my_bool exact);
+static ACL_USER *find_user_no_anon(const char *host, const char *user, bool exact);
static ACL_USER *find_user(const char *host, const char *user, const char *ip);
static ACL_ROLE *find_acl_role(const char *user);
static bool update_user_table(THD *thd, TABLE *table, const char *host,
@@ -3034,7 +3032,7 @@ find_user(const char *host, const char *user, const char *ip)
Find first entry that matches the current user
*/
static ACL_USER *
-find_user_no_anon(const char *host, const char *user, my_bool exact)
+find_user_no_anon(const char *host, const char *user, bool exact)
{
DBUG_ENTER("find_user_no_anon");
DBUG_PRINT("enter",("host: '%s' user: '%s'",host,user));
@@ -9472,6 +9470,39 @@ fill_schema_enabled_roles_insert(ACL_ROLE *unused __attribute__((unused)),
/*return*/ schema_table_store_record(table->in_use, table);
}
+static int fill_schema_applicable_roles_insert_data(ACL_USER_BASE *grantee,
+ LEX_STRING *name, TABLE *table);
+
+static void
+fill_schema_applicable_roles_insert(ACL_ROLE *unused __attribute__((unused)),
+ ACL_ROLE *role, void *context_data)
+{
+ /*return*/ fill_schema_applicable_roles_insert_data(role, &role->user,
+ (TABLE*)context_data);
+}
+
+static int
+fill_schema_applicable_roles_insert_data(ACL_USER_BASE *grantee,
+ LEX_STRING *name, TABLE *table)
+{
+ CHARSET_INFO *cs= system_charset_info;
+
+ for (uint i= 0; i < grantee->role_grants.elements; i++)
+ {
+ ACL_ROLE *role= *(dynamic_element(&grantee->role_grants, i, ACL_ROLE**));
+ restore_record(table, s->default_values);
+ table->field[0]->store(name->str, name->length, cs);
+ table->field[1]->store(role->user.str, role->user.length, cs);
+ table->field[2]->store(STRING_WITH_LEN("YES"), cs); // TODO FIXME
+ if (schema_table_store_record(table->in_use, table))
+ return 1;
+ if (! (grantee->flags & IS_ROLE))
+ traverse_role_graph(role, table, NULL, NULL, NULL,
+ fill_schema_applicable_roles_insert);
+ }
+ return 0;
+}
+
#endif /*NO_EMBEDDED_ACCESS_CHECKS */
int fill_schema_enabled_roles(THD *thd, TABLE_LIST *tables, COND *cond)
@@ -9498,6 +9529,39 @@ int fill_schema_enabled_roles(THD *thd, TABLE_LIST *tables, COND *cond)
}
+/*
+ This shows all roles granted to current user
+ and recursively all roles granted to those roles
+*/
+int fill_schema_applicable_roles(THD *thd, TABLE_LIST *tables, COND *cond)
+{
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ if (initialized)
+ {
+ TABLE *table= tables->table;
+ Security_context *sctx= thd->security_ctx;
+ mysql_rwlock_rdlock(&LOCK_grant);
+ mysql_mutex_lock(&acl_cache->lock);
+ ACL_USER *user= find_user_no_anon(sctx->priv_host, sctx->priv_user, true);
+
+ char buff[USER_HOST_BUFF_SIZE+10];
+ DBUG_ASSERT(user->user.length + user->hostname_length +2 < sizeof(buff));
+ char *end= strxmov(buff, user->user.str, "@", user->host.hostname, NULL);
+ LEX_STRING name= { buff, end - buff };
+
+ int res= fill_schema_applicable_roles_insert_data(user, &name, table);
+
+ mysql_mutex_unlock(&acl_cache->lock);
+ mysql_rwlock_unlock(&LOCK_grant);
+
+ return res;
+ }
+#endif
+
+ return 0;
+}
+
+
int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr)
{
reg3 int flag;
diff --git a/sql/sql_acl.h b/sql/sql_acl.h
index 64370f8705f..506a1fe4d40 100644
--- a/sql/sql_acl.h
+++ b/sql/sql_acl.h
@@ -234,6 +234,7 @@ ulong get_column_grant(THD *thd, GRANT_INFO *grant,
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);
+int fill_schema_applicable_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 <LEX_USER> &list, bool handle_as_role);
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 184f94f5b5c..5fc5afcc0fd 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -90,6 +90,8 @@ enum enum_i_s_events_fields
ISE_DB_CL
};
+#define USERNAME_WITH_HOST_CHAR_LENGTH (USERNAME_CHAR_LENGTH + HOSTNAME_LENGTH + 2)
+
#ifndef NO_EMBEDDED_ACCESS_CHECKS
static const char *grant_names[]={
"select","insert","update","delete","create","drop","reload","shutdown",
@@ -8369,9 +8371,18 @@ ST_FIELD_INFO collation_fields_info[]=
};
+ST_FIELD_INFO applicable_roles_fields_info[]=
+{
+ {"GRANTEE", USERNAME_WITH_HOST_CHAR_LENGTH, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+ {"ROLE_NAME", USERNAME_CHAR_LENGTH, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+ {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
+};
+
+
ST_FIELD_INFO enabled_roles_fields_info[]=
{
- {"ROLE_NAME", USERNAME_CHAR_LENGTH, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL, 0, 0},
+ {"ROLE_NAME", USERNAME_CHAR_LENGTH, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL, 0, SKIP_OPEN_TABLE},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
};
@@ -8529,7 +8540,7 @@ ST_FIELD_INFO view_fields_info[]=
ST_FIELD_INFO user_privileges_fields_info[]=
{
- {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+ {"GRANTEE", USERNAME_WITH_HOST_CHAR_LENGTH, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
{"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
{"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
@@ -8539,7 +8550,7 @@ ST_FIELD_INFO user_privileges_fields_info[]=
ST_FIELD_INFO schema_privileges_fields_info[]=
{
- {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+ {"GRANTEE", USERNAME_WITH_HOST_CHAR_LENGTH, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
{"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
@@ -8550,7 +8561,7 @@ ST_FIELD_INFO schema_privileges_fields_info[]=
ST_FIELD_INFO table_privileges_fields_info[]=
{
- {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+ {"GRANTEE", USERNAME_WITH_HOST_CHAR_LENGTH, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
@@ -8562,7 +8573,7 @@ ST_FIELD_INFO table_privileges_fields_info[]=
ST_FIELD_INFO column_privileges_fields_info[]=
{
- {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
+ {"GRANTEE", USERNAME_WITH_HOST_CHAR_LENGTH, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
@@ -8973,6 +8984,8 @@ ST_SCHEMA_TABLE schema_tables[]=
{
{"ALL_PLUGINS", plugin_fields_info, create_schema_table,
fill_all_plugins, make_old_format, 0, 5, -1, 0, 0},
+ {"APPLICABLE_ROLES", applicable_roles_fields_info, create_schema_table,
+ fill_schema_applicable_roles, 0, 0, -1, -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,