From 6f9d26f09fc5b75c20715233c20d06f07a089daf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Fri, 18 Oct 2013 06:42:59 -0700 Subject: [PATCH] Show grants now correctly prints procedure privileges. --- .../r/acl_roles_set_role-recursive.result | 4 ++ sql/sql_acl.cc | 56 +++++++++++++++++-- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/acl_roles_set_role-recursive.result b/mysql-test/r/acl_roles_set_role-recursive.result index 7ac932452f0..8971cd1bf8a 100644 --- a/mysql-test/r/acl_roles_set_role-recursive.result +++ b/mysql-test/r/acl_roles_set_role-recursive.result @@ -42,6 +42,7 @@ GRANT SELECT ON *.* TO 'test_role2' GRANT USAGE ON *.* TO 'test_role1' GRANT USAGE ON *.* TO 'test_user'@'localhost' GRANT test_role1 TO 'test_user'@'localhost' +GRANT test_role2 TO 'test_role1' select * from mysql.roles_mapping where HostFk=''; HostFk UserFk RoleFk test_role1 test_role2 @@ -51,6 +52,7 @@ GRANT SELECT ON *.* TO 'test_role2' GRANT USAGE ON *.* TO 'test_role1' GRANT USAGE ON *.* TO 'test_user'@'localhost' GRANT test_role1 TO 'test_user'@'localhost' +GRANT test_role2 TO 'test_role1' set role none; show grants; Grants for test_user@localhost @@ -81,6 +83,7 @@ GRANT SELECT ON *.* TO 'test_role2' GRANT USAGE ON *.* TO 'test_role1' GRANT USAGE ON *.* TO 'test_user'@'localhost' GRANT test_role1 TO 'test_user'@'localhost' +GRANT test_role2 TO 'test_role1' select * from mysql.roles_mapping where HostFk=''; HostFk UserFk RoleFk test_role1 test_role2 @@ -90,6 +93,7 @@ GRANT SELECT ON *.* TO 'test_role2' GRANT USAGE ON *.* TO 'test_role1' GRANT USAGE ON *.* TO 'test_user'@'localhost' GRANT test_role1 TO 'test_user'@'localhost' +GRANT test_role2 TO 'test_role1' set role none; show grants; Grants for test_user@localhost diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 29c402ee532..b75ecf1a440 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -4106,7 +4106,7 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs) fix_rights_for_column(priv)))) { /* Don't use this entry */ - privs= cols= 0; /* purecov: deadcode */ + privs= cols= init_privs= init_cols=0; /* purecov: deadcode */ return; /* purecov: deadcode */ } if (my_hash_insert(&hash_columns, (uchar *) mem_check)) @@ -5396,6 +5396,7 @@ static my_bool grant_load_procs_priv(TABLE *p_table) } mem_check->privs= fix_rights_for_procedure(mem_check->privs); + mem_check->init_privs= mem_check->privs; if (! mem_check->ok()) delete mem_check; else if (my_hash_insert(hash, (uchar*) mem_check)) @@ -5788,7 +5789,7 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, tl->get_table_name(), FALSE); if (sctx->priv_role[0]) - grant_table_role= table_hash_search("", "", tl->get_db_name(), + grant_table_role= table_hash_search("", NULL, tl->get_db_name(), sctx->priv_role, tl->get_table_name(), TRUE); @@ -5889,7 +5890,7 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant, sctx->priv_user, table_name, 0); /* purecov: inspected */ grant->grant_table_role= - sctx->priv_role[0] ? table_hash_search("", "", db_name, + sctx->priv_role[0] ? table_hash_search("", NULL, db_name, sctx->priv_role, table_name, TRUE) : NULL; grant->version= grant_version; /* purecov: inspected */ @@ -6061,7 +6062,7 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg, sctx->priv_user, table_name, 0); /* purecov: inspected */ grant->grant_table_role= - sctx->priv_role[0] ? table_hash_search("", "", db_name, + sctx->priv_role[0] ? table_hash_search("", NULL, db_name, sctx->priv_role, table_name, TRUE) : NULL; grant->version= grant_version; /* purecov: inspected */ @@ -6140,6 +6141,12 @@ static bool check_grant_db_routine(THD *thd, const char *db, HASH *hash) { return FALSE; } + if (sctx->priv_role[0] && strcmp(item->user, sctx->priv_role) == 0 && + strcmp(item->db, db) == 0 && + (!item->host.hostname || !item->host.hostname[0])) + { + return FALSE; /* Found current role match */ + } } return TRUE; @@ -6152,11 +6159,12 @@ static bool check_grant_db_routine(THD *thd, const char *db, HASH *hash) Return 1 if access is denied */ -bool check_grant_db(THD *thd,const char *db) +bool check_grant_db(THD *thd, const char *db) { Security_context *sctx= thd->security_ctx; char helping [SAFE_NAME_LEN + USERNAME_LENGTH+2], *end; - uint len; + char helping2 [SAFE_NAME_LEN + USERNAME_LENGTH+2]; + uint len, len2; bool error= TRUE; end= strmov(helping, sctx->priv_user) + 1; @@ -6167,6 +6175,18 @@ bool check_grant_db(THD *thd,const char *db) len= (uint) (end - helping) + 1; + /* + If a role is set, we need to check for privileges + here aswell + */ + if (sctx->priv_role[0]) + { + end= strmov(helping2, sctx->priv_role) + 1; + end= strnmov(end, db, helping2 + sizeof(helping2) - end); + len2= (uint) (end - helping2) + 1; + } + + mysql_rwlock_rdlock(&LOCK_grant); for (uint idx=0 ; idx < column_priv_hash.records ; idx++) @@ -6181,6 +6201,14 @@ bool check_grant_db(THD *thd,const char *db) error= FALSE; /* Found match. */ break; } + if (sctx->priv_role[0] && + len2 < grant_table->key_length && + !memcmp(grant_table->hash_key,helping,len) && + (!grant_table->host.hostname || !grant_table->host.hostname[0])) + { + error= FALSE; /* Found role match */ + break; + } } if (error) @@ -6217,6 +6245,7 @@ bool check_grant_routine(THD *thd, ulong want_access, Security_context *sctx= thd->security_ctx; char *user= sctx->priv_user; char *host= sctx->priv_host; + char *role= sctx->priv_role; DBUG_ENTER("check_grant_routine"); want_access&= ~sctx->master_access; @@ -6230,6 +6259,12 @@ bool check_grant_routine(THD *thd, ulong want_access, if ((grant_proc= routine_hash_search(host, sctx->ip, table->db, user, table->table_name, is_proc, 0))) table->grant.privilege|= grant_proc->privs; + if (role[0]) /* current role set check */ + { + if ((grant_proc= routine_hash_search("", NULL, table->db, role, + table->table_name, is_proc, 0))) + table->grant.privilege|= grant_proc->privs; + } if (want_access & ~table->grant.privilege) { @@ -6287,6 +6322,15 @@ bool check_routine_level_acl(THD *thd, const char *db, const char *name, sctx->priv_user, name, is_proc, 0))) no_routine_acl= !(grant_proc->privs & SHOW_PROC_ACLS); + + if (sctx->priv_role[0]) /* current set role check */ + { + if ((grant_proc= routine_hash_search("", + NULL, db, + sctx->priv_role, + name, is_proc, 0))) + no_routine_acl= !(grant_proc->privs & SHOW_PROC_ACLS); + } mysql_rwlock_unlock(&LOCK_grant); return no_routine_acl; }