Commit fe2d2657 authored by Sergei Golubchik's avatar Sergei Golubchik

INFORMATION_SCHEMA.APPLICABLE_ROLES table

parent 7f0965f4
......@@ -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'
......
......@@ -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
......
......@@ -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();
......
......@@ -594,6 +594,7 @@ struct TABLE;
enum enum_schema_tables
{
SCH_ALL_PLUGINS,
SCH_APPLICABLE_ROLES,
SCH_CHARSETS,
SCH_CLIENT_STATS,
SCH_COLLATIONS,
......
......@@ -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;
......
......@@ -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);
......
......@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment