Commit 1a329935 authored by Vicențiu Ciorbaru's avatar Vicențiu Ciorbaru

MDEV-5214 Status variables for number of global/db/table/column/role grants

Implemented the status variables for use with the feedback plugin.
parent f8381d93
SHOW STATUS LIKE 'Acl%';
Variable_name Value
Acl_column_grants 0
Acl_database_grants 2
Acl_function_grants 0
Acl_procedure_grants 0
Acl_proxy_users 2
Acl_role_grants 0
Acl_roles 0
Acl_table_grants 0
Acl_users 4
SELECT count(*) COLUMN_GRANTS from mysql.columns_priv;
COLUMN_GRANTS
0
SELECT count(*) DATABASE_GRANTS from mysql.db;
DATABASE_GRANTS
2
SELECT count(*) FUNCTION_GRANTS from mysql.procs_priv where routine_type='FUNCTION';
FUNCTION_GRANTS
0
SELECT count(*) PROCEDURE_GRANTS from mysql.procs_priv where routine_type='PROCEDURE';
PROCEDURE_GRANTS
0
SELECT count(*) PROXY_USERS from mysql.proxies_priv;
PROXY_USERS
2
SELECT count(*) ROLE_GRANTS from mysql.roles_mapping;
ROLE_GRANTS
0
SELECT count(*) ROLES from mysql.user where is_role='Y';
ROLES
0
SELECT count(*) TABLE_GRANTS from mysql.tables_priv;
TABLE_GRANTS
0
SELECT count(*) USERS from mysql.user where is_role='N';
USERS
4
CREATE USER u1;
CREATE ROLE r1;
CREATE ROLE r2;
GRANT PROXY ON root TO u1;
GRANT SELECT ON *.* to u1;
GRANT SELECT ON *.* to r1;
GRANT DELETE ON mysql.* to u1;
GRANT DELETE ON mysql.* to r1;
GRANT INSERT ON mysql.user to u1;
GRANT INSERT ON mysql.user to r1;
GRANT UPDATE (host) ON mysql.user to u1;
GRANT UPDATE (host) ON mysql.user to r1;
GRANT r1 to u1;
GRANT r2 to r1;
create procedure mysql.test_proc (OUT param1 INT)
begin
select COUNT(*) into param1 from mysql.roles_mapping;
end|
GRANT EXECUTE ON PROCEDURE mysql.test_proc TO r1;
GRANT EXECUTE ON PROCEDURE mysql.test_proc TO u1;
CREATE FUNCTION mysql.test_func (param INT) RETURNS INT
RETURN (SELECT COUNT(*) FROM mysql.user);
GRANT EXECUTE ON FUNCTION mysql.test_func TO r1;
GRANT EXECUTE ON FUNCTION mysql.test_func TO u1;
GRANT EXECUTE ON FUNCTION mysql.test_func TO r2;
SHOW STATUS LIKE 'Acl%';
Variable_name Value
Acl_column_grants 2
Acl_database_grants 4
Acl_function_grants 3
Acl_procedure_grants 2
Acl_proxy_users 3
Acl_role_grants 4
Acl_roles 2
Acl_table_grants 2
Acl_users 5
SELECT count(*) COLUMN_GRANTS from mysql.columns_priv;
COLUMN_GRANTS
2
SELECT count(*) DATABASE_GRANTS from mysql.db;
DATABASE_GRANTS
4
SELECT count(*) FUNCTION_GRANTS from mysql.procs_priv where routine_type='FUNCTION';
FUNCTION_GRANTS
3
SELECT count(*) PROCEDURE_GRANTS from mysql.procs_priv where routine_type='PROCEDURE';
PROCEDURE_GRANTS
2
SELECT count(*) PROXY_USERS from mysql.proxies_priv;
PROXY_USERS
3
SELECT count(*) ROLE_GRANTS from mysql.roles_mapping;
ROLE_GRANTS
4
SELECT count(*) ROLES from mysql.user where is_role='Y';
ROLES
2
SELECT count(*) TABLE_GRANTS from mysql.tables_priv;
TABLE_GRANTS
2
SELECT count(*) USERS from mysql.user where is_role='N';
USERS
5
DROP PROCEDURE mysql.test_proc;
DROP FUNCTION mysql.test_func;
DROP ROLE r2;
DROP ROLE r1;
DROP USER u1;
# Test case for validating acl statistics for the feedback plugin.
--source include/not_embedded.inc
# First get a baseline of the initial statistics.
SHOW STATUS LIKE 'Acl%';
SELECT count(*) COLUMN_GRANTS from mysql.columns_priv;
SELECT count(*) DATABASE_GRANTS from mysql.db;
SELECT count(*) FUNCTION_GRANTS from mysql.procs_priv where routine_type='FUNCTION';
SELECT count(*) PROCEDURE_GRANTS from mysql.procs_priv where routine_type='PROCEDURE';
SELECT count(*) PROXY_USERS from mysql.proxies_priv;
SELECT count(*) ROLE_GRANTS from mysql.roles_mapping;
SELECT count(*) ROLES from mysql.user where is_role='Y';
SELECT count(*) TABLE_GRANTS from mysql.tables_priv;
SELECT count(*) USERS from mysql.user where is_role='N';
# Next add some users, roles and privileges to them.
CREATE USER u1;
CREATE ROLE r1;
CREATE ROLE r2;
GRANT PROXY ON root TO u1;
GRANT SELECT ON *.* to u1;
GRANT SELECT ON *.* to r1;
GRANT DELETE ON mysql.* to u1;
GRANT DELETE ON mysql.* to r1;
GRANT INSERT ON mysql.user to u1;
GRANT INSERT ON mysql.user to r1;
GRANT UPDATE (host) ON mysql.user to u1;
GRANT UPDATE (host) ON mysql.user to r1;
GRANT r1 to u1;
GRANT r2 to r1;
delimiter |;
create procedure mysql.test_proc (OUT param1 INT)
begin
select COUNT(*) into param1 from mysql.roles_mapping;
end|
delimiter ;|
GRANT EXECUTE ON PROCEDURE mysql.test_proc TO r1;
GRANT EXECUTE ON PROCEDURE mysql.test_proc TO u1;
CREATE FUNCTION mysql.test_func (param INT) RETURNS INT
RETURN (SELECT COUNT(*) FROM mysql.user);
GRANT EXECUTE ON FUNCTION mysql.test_func TO r1;
GRANT EXECUTE ON FUNCTION mysql.test_func TO u1;
# Extra grant to differentiate procedure from function grants.
GRANT EXECUTE ON FUNCTION mysql.test_func TO r2;
# Recheck how statistics are updated. Make sure that both the information
# schema and the actualy physical rows are the same.
SHOW STATUS LIKE 'Acl%';
SELECT count(*) COLUMN_GRANTS from mysql.columns_priv;
SELECT count(*) DATABASE_GRANTS from mysql.db;
SELECT count(*) FUNCTION_GRANTS from mysql.procs_priv where routine_type='FUNCTION';
SELECT count(*) PROCEDURE_GRANTS from mysql.procs_priv where routine_type='PROCEDURE';
SELECT count(*) PROXY_USERS from mysql.proxies_priv;
SELECT count(*) ROLE_GRANTS from mysql.roles_mapping;
SELECT count(*) ROLES from mysql.user where is_role='Y';
SELECT count(*) TABLE_GRANTS from mysql.tables_priv;
SELECT count(*) USERS from mysql.user where is_role='N';
DROP PROCEDURE mysql.test_proc;
DROP FUNCTION mysql.test_func;
DROP ROLE r2;
DROP ROLE r1;
DROP USER u1;
...@@ -8149,6 +8149,7 @@ int show_threadpool_idle_threads(THD *thd, SHOW_VAR *var, char *buff, ...@@ -8149,6 +8149,7 @@ int show_threadpool_idle_threads(THD *thd, SHOW_VAR *var, char *buff,
SHOW_VAR status_vars[]= { SHOW_VAR status_vars[]= {
{"Aborted_clients", (char*) &aborted_threads, SHOW_LONG}, {"Aborted_clients", (char*) &aborted_threads, SHOW_LONG},
{"Aborted_connects", (char*) &aborted_connects, SHOW_LONG}, {"Aborted_connects", (char*) &aborted_connects, SHOW_LONG},
{"Acl", (char*) acl_statistics, SHOW_ARRAY},
{"Access_denied_errors", (char*) offsetof(STATUS_VAR, access_denied_errors), SHOW_LONG_STATUS}, {"Access_denied_errors", (char*) offsetof(STATUS_VAR, access_denied_errors), SHOW_LONG_STATUS},
{"Binlog_bytes_written", (char*) offsetof(STATUS_VAR, binlog_bytes_written), SHOW_LONGLONG_STATUS}, {"Binlog_bytes_written", (char*) offsetof(STATUS_VAR, binlog_bytes_written), SHOW_LONGLONG_STATUS},
{"Binlog_cache_disk_use", (char*) &binlog_cache_disk_use, SHOW_LONG}, {"Binlog_cache_disk_use", (char*) &binlog_cache_disk_use, SHOW_LONG},
......
...@@ -10340,6 +10340,38 @@ applicable_roles_insert(ACL_USER_BASE *grantee, ACL_ROLE *role, void *ptr) ...@@ -10340,6 +10340,38 @@ applicable_roles_insert(ACL_USER_BASE *grantee, ACL_ROLE *role, void *ptr)
return 0; return 0;
} }
/**
Hash iterate function to count the number of total column privileges granted.
*/
static my_bool count_column_grants(void *grant_table,
void *current_count)
{
HASH hash_columns = ((GRANT_TABLE *)grant_table)->hash_columns;
*(ulong *)current_count+= hash_columns.records;
return 0;
}
/**
SHOW function that computes the number of column grants.
This must be performed under the mutex in order to make sure the
iteration does not fail.
*/
static int show_column_grants(THD *thd, SHOW_VAR *var, char *buff,
enum enum_var_type scope)
{
var->type= SHOW_ULONG;
var->value= buff;
*(ulong *)buff= 0;
mysql_rwlock_rdlock(&LOCK_grant);
mysql_mutex_lock(&acl_cache->lock);
my_hash_iterate(&column_priv_hash, count_column_grants, buff);
mysql_mutex_unlock(&acl_cache->lock);
mysql_rwlock_unlock(&LOCK_grant);
return 0;
}
#else #else
bool check_grant(THD *, ulong, TABLE_LIST *, bool, uint, bool) bool check_grant(THD *, ulong, TABLE_LIST *, bool, uint, bool)
{ {
...@@ -10347,6 +10379,23 @@ bool check_grant(THD *, ulong, TABLE_LIST *, bool, uint, bool) ...@@ -10347,6 +10379,23 @@ bool check_grant(THD *, ulong, TABLE_LIST *, bool, uint, bool)
} }
#endif /*NO_EMBEDDED_ACCESS_CHECKS */ #endif /*NO_EMBEDDED_ACCESS_CHECKS */
SHOW_VAR acl_statistics[] = {
#ifndef NO_EMBEDDED_ACCESS_CHECKS
{"column_grants", (char*)show_column_grants, SHOW_SIMPLE_FUNC},
{"database_grants", (char*)&acl_dbs.elements, SHOW_UINT},
{"function_grants", (char*)&func_priv_hash.records, SHOW_ULONG},
{"procedure_grants", (char*)&proc_priv_hash.records, SHOW_ULONG},
{"proxy_users", (char*)&acl_proxy_users.elements, SHOW_UINT},
{"role_grants", (char*)&acl_roles_mappings.records, SHOW_ULONG},
{"roles", (char*)&acl_roles.records, SHOW_ULONG},
{"table_grants", (char*)&column_priv_hash.records, SHOW_ULONG},
{"users", (char*)&acl_users.elements, SHOW_UINT},
#endif
{NullS, NullS, SHOW_LONG},
};
int fill_schema_enabled_roles(THD *thd, TABLE_LIST *tables, COND *cond) int fill_schema_enabled_roles(THD *thd, TABLE_LIST *tables, COND *cond)
{ {
TABLE *table= tables->table; TABLE *table= tables->table;
......
...@@ -402,6 +402,8 @@ int acl_check_set_default_role(THD *thd, const char *host, const char *user); ...@@ -402,6 +402,8 @@ int acl_check_set_default_role(THD *thd, const char *host, const char *user);
int acl_set_default_role(THD *thd, const char *host, const char *user, int acl_set_default_role(THD *thd, const char *host, const char *user,
const char *rolename); const char *rolename);
extern SHOW_VAR acl_statistics[];
#ifndef DBUG_OFF #ifndef DBUG_OFF
extern ulong role_global_merges, role_db_merges, role_table_merges, extern ulong role_global_merges, role_db_merges, role_table_merges,
role_column_merges, role_routine_merges; role_column_merges, role_routine_merges;
......
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