diff options
Diffstat (limited to 'mysql-test/suite/roles')
114 files changed, 10129 insertions, 0 deletions
diff --git a/mysql-test/suite/roles/acl_load_mutex-5170.result b/mysql-test/suite/roles/acl_load_mutex-5170.result new file mode 100644 index 00000000..775541b9 --- /dev/null +++ b/mysql-test/suite/roles/acl_load_mutex-5170.result @@ -0,0 +1,9 @@ +create user user1@localhost; +create role r1 with admin user1@localhost; +grant all on test.* to r1; +flush tables; +select 1; +1 +1 +drop role r1; +drop user user1@localhost; diff --git a/mysql-test/suite/roles/acl_load_mutex-5170.test b/mysql-test/suite/roles/acl_load_mutex-5170.test new file mode 100644 index 00000000..76d817be --- /dev/null +++ b/mysql-test/suite/roles/acl_load_mutex-5170.test @@ -0,0 +1,25 @@ +--source include/not_embedded.inc +# +# MDEV-5170 Assertion `(&(&acl_cache->lock)->m_mutex)->count > 0 && pthread_equal(pthread_self(), (&(&acl_cache->lock)->m_mutex)->thread)' fails after restarting server with a pre-created role grants +# +create user user1@localhost; +create role r1 with admin user1@localhost; +grant all on test.* to r1; +flush tables; + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait +EOF +--shutdown_server +--source include/wait_until_disconnected.inc +--enable_reconnect +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +restart +EOF +--source include/wait_until_connected_again.inc + +select 1; + +drop role r1; +drop user user1@localhost; + diff --git a/mysql-test/suite/roles/acl_statistics.opt b/mysql-test/suite/roles/acl_statistics.opt new file mode 100644 index 00000000..24307596 --- /dev/null +++ b/mysql-test/suite/roles/acl_statistics.opt @@ -0,0 +1 @@ +--disable-skip-name-resolve diff --git a/mysql-test/suite/roles/acl_statistics.result b/mysql-test/suite/roles/acl_statistics.result new file mode 100644 index 00000000..003bc263 --- /dev/null +++ b/mysql-test/suite/roles/acl_statistics.result @@ -0,0 +1,110 @@ +SHOW STATUS LIKE 'Acl%'; +Variable_name Value +Acl_column_grants 0 +Acl_database_grants 0 +Acl_function_grants 0 +Acl_procedure_grants 0 +Acl_package_spec_grants 0 +Acl_package_body_grants 0 +Acl_proxy_users 4 +Acl_role_grants 0 +Acl_roles 0 +Acl_table_grants 1 +Acl_users 5 +SELECT count(*) COLUMN_GRANTS from mysql.columns_priv; +COLUMN_GRANTS +0 +SELECT count(*) DATABASE_GRANTS from mysql.db; +DATABASE_GRANTS +0 +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 +4 +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 +1 +SELECT count(*) USERS from mysql.user where is_role='N'; +USERS +5 +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 2 +Acl_function_grants 3 +Acl_procedure_grants 2 +Acl_package_spec_grants 0 +Acl_package_body_grants 0 +Acl_proxy_users 5 +Acl_role_grants 4 +Acl_roles 2 +Acl_table_grants 3 +Acl_users 6 +SELECT count(*) COLUMN_GRANTS from mysql.columns_priv; +COLUMN_GRANTS +2 +SELECT count(*) DATABASE_GRANTS from mysql.db; +DATABASE_GRANTS +2 +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 +5 +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 +3 +SELECT count(*) USERS from mysql.user where is_role='N'; +USERS +6 +DROP PROCEDURE mysql.test_proc; +DROP FUNCTION mysql.test_func; +DROP ROLE r2; +DROP ROLE r1; +DROP USER u1; diff --git a/mysql-test/suite/roles/acl_statistics.test b/mysql-test/suite/roles/acl_statistics.test new file mode 100644 index 00000000..c76d3760 --- /dev/null +++ b/mysql-test/suite/roles/acl_statistics.test @@ -0,0 +1,66 @@ +# 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; diff --git a/mysql-test/suite/roles/admin.result b/mysql-test/suite/roles/admin.result new file mode 100644 index 00000000..2ecbfae4 --- /dev/null +++ b/mysql-test/suite/roles/admin.result @@ -0,0 +1,155 @@ +create user foo@localhost; +grant create user on *.* to foo@localhost; +create role role1; +create role role2 with admin current_user; +create role role3 with admin current_role; +ERROR 0L000: Invalid definer +create role role3 with admin role1; +create role role4 with admin root@localhost; +connect c1, localhost, foo,,; +create role role5 with admin root@localhost; +ERROR 42000: Access denied; you need (at least one of) the SUPER, SET USER privilege(s) for this operation +create role role5 with admin role3; +ERROR 42000: Access denied; you need (at least one of) the SUPER, SET USER privilege(s) for this operation +create role role5 with admin foo@localhost; +connection default; +call mtr.add_suppression("Invalid roles_mapping table entry user:'foo@bar', rolename:'role6'"); +create role role6 with admin foo@bar; +Warnings: +Note 1449 The user specified as a definer ('foo'@'bar') does not exist +create user bar with admin current_user; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'admin current_user' at line 1 +grant role1 to foo@localhost with admin option; +grant role2 to foo@localhost; +grant role2 to role1; +grant role4 to role3 with admin option; +grant select on *.* to foo@localhost with admin option; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'admin option' at line 1 +show grants for foo@localhost; +Grants for foo@localhost +GRANT CREATE USER ON *.* TO `foo`@`localhost` +GRANT `role1` TO `foo`@`localhost` WITH ADMIN OPTION +GRANT `role2` TO `foo`@`localhost` +GRANT `role5` TO `foo`@`localhost` WITH ADMIN OPTION +show grants for role1; +Grants for role1 +GRANT USAGE ON *.* TO `role1` +GRANT USAGE ON *.* TO `role2` +GRANT USAGE ON *.* TO `role3` +GRANT USAGE ON *.* TO `role4` +GRANT `role2` TO `role1` +GRANT `role3` TO `role1` WITH ADMIN OPTION +GRANT `role4` TO `role3` WITH ADMIN OPTION +show grants for role4; +Grants for role4 +GRANT USAGE ON *.* TO `role4` +select * from mysql.roles_mapping; +Host User Role Admin_option + role1 role2 N + role1 role3 Y + role3 role4 Y +bar foo role6 Y +localhost foo role1 Y +localhost foo role2 N +localhost foo role5 Y +localhost root role1 Y +localhost root role2 Y +localhost root role4 Y +flush privileges; +show grants for foo@localhost; +Grants for foo@localhost +GRANT CREATE USER ON *.* TO `foo`@`localhost` +GRANT `role1` TO `foo`@`localhost` WITH ADMIN OPTION +GRANT `role2` TO `foo`@`localhost` +GRANT `role5` TO `foo`@`localhost` WITH ADMIN OPTION +show grants for role1; +Grants for role1 +GRANT USAGE ON *.* TO `role1` +GRANT USAGE ON *.* TO `role2` +GRANT USAGE ON *.* TO `role3` +GRANT USAGE ON *.* TO `role4` +GRANT `role2` TO `role1` +GRANT `role3` TO `role1` WITH ADMIN OPTION +GRANT `role4` TO `role3` WITH ADMIN OPTION +show grants for role4; +Grants for role4 +GRANT USAGE ON *.* TO `role4` +select * from information_schema.applicable_roles; +GRANTEE ROLE_NAME IS_GRANTABLE IS_DEFAULT +role1 role2 NO NULL +role1 role3 YES NULL +role3 role4 YES NULL +root@localhost role1 YES NO +root@localhost role2 YES NO +root@localhost role4 YES NO +grant role2 to role1 with admin option; +revoke role1 from foo@localhost; +revoke admin option for role4 from role3; +revoke admin option for role2 from foo@localhost; +revoke admin option for role1 from root@localhost; +show grants for foo@localhost; +Grants for foo@localhost +GRANT CREATE USER ON *.* TO `foo`@`localhost` +GRANT `role2` TO `foo`@`localhost` +GRANT `role5` TO `foo`@`localhost` WITH ADMIN OPTION +show grants for role1; +Grants for role1 +GRANT USAGE ON *.* TO `role1` +GRANT USAGE ON *.* TO `role2` +GRANT USAGE ON *.* TO `role3` +GRANT USAGE ON *.* TO `role4` +GRANT `role2` TO `role1` WITH ADMIN OPTION +GRANT `role3` TO `role1` WITH ADMIN OPTION +GRANT `role4` TO `role3` +show grants for role4; +Grants for role4 +GRANT USAGE ON *.* TO `role4` +select * from mysql.roles_mapping; +Host User Role Admin_option + role1 role2 Y + role1 role3 Y + role3 role4 N +bar foo role6 Y +localhost foo role2 N +localhost foo role5 Y +localhost root role1 N +localhost root role2 Y +localhost root role4 Y +flush privileges; +show grants for foo@localhost; +Grants for foo@localhost +GRANT CREATE USER ON *.* TO `foo`@`localhost` +GRANT `role2` TO `foo`@`localhost` +GRANT `role5` TO `foo`@`localhost` WITH ADMIN OPTION +show grants for role1; +Grants for role1 +GRANT USAGE ON *.* TO `role1` +GRANT USAGE ON *.* TO `role2` +GRANT USAGE ON *.* TO `role3` +GRANT USAGE ON *.* TO `role4` +GRANT `role2` TO `role1` WITH ADMIN OPTION +GRANT `role3` TO `role1` WITH ADMIN OPTION +GRANT `role4` TO `role3` +show grants for role4; +Grants for role4 +GRANT USAGE ON *.* TO `role4` +select * from information_schema.applicable_roles; +GRANTEE ROLE_NAME IS_GRANTABLE IS_DEFAULT +role1 role2 YES NULL +role1 role3 YES NULL +role3 role4 NO NULL +root@localhost role1 NO NO +root@localhost role2 YES NO +root@localhost role4 YES NO +grant role1 to role4; +ERROR 28000: Access denied for user 'root'@'localhost' +grant role1 to role4 with admin option; +ERROR 28000: Access denied for user 'root'@'localhost' +grant role3 to role2; +revoke role3 from role2; +grant role4 to role2 with admin option; +revoke role2 from current_user; +revoke role4 from current_user; +grant role4 to current_user; +drop role role1, role2, role3, role4, role5, role6; +drop user foo@localhost; diff --git a/mysql-test/suite/roles/admin.test b/mysql-test/suite/roles/admin.test new file mode 100644 index 00000000..242518eb --- /dev/null +++ b/mysql-test/suite/roles/admin.test @@ -0,0 +1,102 @@ +source include/not_embedded.inc; + +create user foo@localhost; +grant create user on *.* to foo@localhost; + +######################################## +# syntax tests +######################################## + +create role role1; +create role role2 with admin current_user; +--error ER_MALFORMED_DEFINER +create role role3 with admin current_role; +create role role3 with admin role1; +create role role4 with admin root@localhost; + +# privilege checks, one needs SUPER to specify an arbitrary admin +connect (c1, localhost, foo,,); +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +create role role5 with admin root@localhost; +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +create role role5 with admin role3; +create role role5 with admin foo@localhost; + +connection default; +# non-existing admin. works. warning. error in the log on acl_load. +call mtr.add_suppression("Invalid roles_mapping table entry user:'foo@bar', rolename:'role6'"); +create role role6 with admin foo@bar; + +--error ER_PARSE_ERROR +create user bar with admin current_user; + +grant role1 to foo@localhost with admin option; +grant role2 to foo@localhost; +grant role2 to role1; +grant role4 to role3 with admin option; +--error ER_PARSE_ERROR +grant select on *.* to foo@localhost with admin option; + +--sorted_result +show grants for foo@localhost; +--sorted_result +show grants for role1; +--sorted_result +show grants for role4; +--sorted_result +select * from mysql.roles_mapping; +flush privileges; +--sorted_result +show grants for foo@localhost; +--sorted_result +show grants for role1; +--sorted_result +show grants for role4; +--sorted_result +select * from information_schema.applicable_roles; + +grant role2 to role1 with admin option; +revoke role1 from foo@localhost; +revoke admin option for role4 from role3; +revoke admin option for role2 from foo@localhost; +revoke admin option for role1 from root@localhost; + +--sorted_result +show grants for foo@localhost; +--sorted_result +show grants for role1; +--sorted_result +show grants for role4; +--sorted_result +select * from mysql.roles_mapping; +flush privileges; +--sorted_result +show grants for foo@localhost; +--sorted_result +show grants for role1; +--sorted_result +show grants for role4; +--sorted_result +select * from information_schema.applicable_roles; + +# Now, root@localhost don't have admin option for role1: +--error ER_ACCESS_DENIED_NO_PASSWORD_ERROR +grant role1 to role4; +--error ER_ACCESS_DENIED_NO_PASSWORD_ERROR +grant role1 to role4 with admin option; +# but role3 is grantable +grant role3 to role2; +revoke role3 from role2; + +# now, a diamond +grant role4 to role2 with admin option; +revoke role2 from current_user; +revoke role4 from current_user; +grant role4 to current_user; + + +######################################## +# cleanup +######################################## +drop role role1, role2, role3, role4, role5, role6; +drop user foo@localhost; diff --git a/mysql-test/suite/roles/create_and_drop_current.result b/mysql-test/suite/roles/create_and_drop_current.result new file mode 100644 index 00000000..7e847677 --- /dev/null +++ b/mysql-test/suite/roles/create_and_drop_current.result @@ -0,0 +1,34 @@ +create user foo@localhost; +grant create user on *.* to foo@localhost; +create user current_user; +ERROR HY000: Operation CREATE USER failed for CURRENT_USER +create user current_role; +ERROR HY000: Operation CREATE USER failed for CURRENT_ROLE +create role current_user; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'current_user' at line 1 +create role current_role; +ERROR HY000: Operation CREATE ROLE failed for CURRENT_ROLE +drop user current_user; +drop user current_role; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'current_role' at line 1 +drop role current_user; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'current_user' at line 1 +drop role current_role; +ERROR HY000: Operation DROP ROLE failed for CURRENT_ROLE +show warnings; +Level Code Message +Error 1446 Invalid definer +Error 1396 Operation DROP ROLE failed for CURRENT_ROLE +create role r1; +grant r1 to current_user; +set role r1; +select current_role(); +current_role() +r1 +create user current_role; +ERROR HY000: Operation CREATE USER failed for CURRENT_ROLE +create role current_role; +ERROR HY000: Operation CREATE ROLE failed for CURRENT_ROLE +drop user current_role; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'current_role' at line 1 +drop role current_role; diff --git a/mysql-test/suite/roles/create_and_drop_current.test b/mysql-test/suite/roles/create_and_drop_current.test new file mode 100644 index 00000000..7ca8161a --- /dev/null +++ b/mysql-test/suite/roles/create_and_drop_current.test @@ -0,0 +1,51 @@ +# +# MDEV-5225 Server crashes on CREATE USER|ROLE CURRENT_ROLE or DROP ROLE CURRENT_ROLE +# + +# Where CURRENT_USER/CURRENT_ROLE is explicitly allowed by the grammar +# the error (if any) should be ER_CANNOT_USER +# +# Where it's not explicitly allowed, the error is ER_PARSE_ERROR, +# because CURRENT_USER/CURRENT_ROLE are reserved words and cannot be +# accepted as an identifier. +# + +--source include/not_embedded.inc + +create user foo@localhost; +grant create user on *.* to foo@localhost; +--change_user foo + +--error ER_CANNOT_USER +create user current_user; +--error ER_CANNOT_USER +create user current_role; +--error ER_PARSE_ERROR +create role current_user; +--error ER_CANNOT_USER +create role current_role; +# this works +drop user current_user; +--error ER_PARSE_ERROR +drop user current_role; +--error ER_PARSE_ERROR +drop role current_user; +--error ER_CANNOT_USER +drop role current_role; +show warnings; + +--change_user root + +create role r1; +grant r1 to current_user; +set role r1; +select current_role(); + +--error ER_CANNOT_USER +create user current_role; +--error ER_CANNOT_USER +create role current_role; +--error ER_PARSE_ERROR +drop user current_role; +drop role current_role; + diff --git a/mysql-test/suite/roles/create_and_drop_role.result b/mysql-test/suite/roles/create_and_drop_role.result new file mode 100644 index 00000000..90bf1506 --- /dev/null +++ b/mysql-test/suite/roles/create_and_drop_role.result @@ -0,0 +1,89 @@ +connect mysql, localhost, root,,; +use mysql; +create role test_role1@host1; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '@host1' at line 1 +create role test_role2@host2, test_role1@host1; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '@host2, test_role1@host1' at line 1 +create role test_role1; +create role test_role2, test_role3; +select user, host, is_role from user where user like 'test%'; +User Host is_role +test_role1 Y +test_role2 Y +test_role3 Y +drop role test_role1; +drop role test_role2, test_role3; +create role test_role1; +create role test_role1; +ERROR HY000: Operation CREATE ROLE failed for 'test_role1' +create role test_role1, test_role2; +ERROR HY000: Operation CREATE ROLE failed for 'test_role1' +select user, host, is_role from user where user like 'test%'; +User Host is_role +test_role1 Y +test_role2 Y +drop role test_role1; +drop role test_role1; +ERROR HY000: Operation DROP ROLE failed for 'test_role1' +drop role test_role1, test_role2; +ERROR HY000: Operation DROP ROLE failed for 'test_role1' +drop role root; +ERROR HY000: Operation DROP ROLE failed for 'root' +create user dummy@''; +drop role dummy; +ERROR HY000: Operation DROP ROLE failed for 'dummy' +drop user dummy@''; +select user, host, is_role from user where user like 'test%'; +User Host is_role +disconnect mysql; +connection default; +create role ''; +ERROR OP000: Invalid role specification `` +create role ' '; +ERROR OP000: Invalid role specification `` +create role 'foo '; +drop role foo; +create role r1; +drop user r1; +ERROR HY000: Operation DROP USER failed for 'r1'@'%' +drop role r1; +create role r1 with admin u1; +Warnings: +Note 1449 The user specified as a definer ('u1'@'%') does not exist +create user foo@bar; +drop user foo@bar; +drop role r1; +CREATE USER u1; +CREATE ROLE r1; +CREATE USER r1@localhost; +CREATE ROLE r2; +GRANT r2 to r1; +GRANT r2 to r1@localhost; +DROP ROLE r1; +SELECT * FROM mysql.roles_mapping; +Host User Role Admin_option +localhost r1 r2 N +localhost root r2 Y +SHOW GRANTS FOR r1@localhost; +Grants for r1@localhost +GRANT `r2` TO `r1`@`localhost` +GRANT USAGE ON *.* TO `r1`@`localhost` +DROP USER u1; +DROP ROLE r2; +DROP USER r1@localhost; +create role 'foo '; +select concat(user, '__'), is_role from mysql.user where user like 'foo%'; +concat(user, '__') is_role +foo__ Y +select * from mysql.roles_mapping; +Host User Role Admin_option +localhost root foo Y +drop role foo; +select concat(user, '__'), is_role from mysql.user where user like 'foo%'; +concat(user, '__') is_role +select * from mysql.roles_mapping; +Host User Role Admin_option +show grants; +Grants for root@localhost +GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` WITH GRANT OPTION +GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION diff --git a/mysql-test/suite/roles/create_and_drop_role.test b/mysql-test/suite/roles/create_and_drop_role.test new file mode 100644 index 00000000..b6e5bd2b --- /dev/null +++ b/mysql-test/suite/roles/create_and_drop_role.test @@ -0,0 +1,109 @@ +source include/not_embedded.inc; + +connect (mysql, localhost, root,,); +use mysql; + +#test valid syntax +--error ER_PARSE_ERROR +create role test_role1@host1; +--error ER_PARSE_ERROR +create role test_role2@host2, test_role1@host1; + +create role test_role1; +create role test_role2, test_role3; + +--sorted_result +select user, host, is_role from user where user like 'test%'; + +drop role test_role1; +drop role test_role2, test_role3; + +create role test_role1; +--error ER_CANNOT_USER +create role test_role1; +--error ER_CANNOT_USER +create role test_role1, test_role2; + +--sorted_result +select user, host, is_role from user where user like 'test%'; + +drop role test_role1; +--error ER_CANNOT_USER +drop role test_role1; +--error ER_CANNOT_USER +drop role test_role1, test_role2; + +#test that we can not drop users when calling drop role +--error ER_CANNOT_USER +drop role root; +create user dummy@''; +--error ER_CANNOT_USER +drop role dummy; +drop user dummy@''; + +--sorted_result +select user, host, is_role from user where user like 'test%'; +disconnect mysql; +connection default; + +# +# MDEV-5520 Connection lost on wrong CREATE ROLE +# +--error ER_INVALID_ROLE +create role ''; + +# +# MDEV-8609 Server crashes in is_invalid_role_name on reloading ACL with a blank role name +# +--error ER_INVALID_ROLE +create role ' '; +create role 'foo '; +drop role foo; + +# +# MDEV-5523 Server crashes on DROP USER <rolename> +# +create role r1; +--error ER_CANNOT_USER +drop user r1; +drop role r1; + +# +# MDEV-5525 Assertion `status == 0' fails on creating user after granting it role admin option +# +create role r1 with admin u1; +create user foo@bar; +drop user foo@bar; +drop role r1; + +# +# MDEV-7774 Assertion `status == 0' fails when dropping in this order: +# +CREATE USER u1; +CREATE ROLE r1; +CREATE USER r1@localhost; +CREATE ROLE r2; +GRANT r2 to r1; +GRANT r2 to r1@localhost; +# MDEV-7774: Dropping in this order caused the crash. +DROP ROLE r1; +--sorted_result +SELECT * FROM mysql.roles_mapping; +SHOW GRANTS FOR r1@localhost; # Related to MDEV-7774, also caused a crash, by + # not updating the internal acl_roles_mapping + # data structure correctly; +DROP USER u1; +DROP ROLE r2; +DROP USER r1@localhost; + +# +# MDEV-11533: Roles with trailing white spaces are not cleared correctly +# +create role 'foo '; +select concat(user, '__'), is_role from mysql.user where user like 'foo%'; +select * from mysql.roles_mapping; +drop role foo; +select concat(user, '__'), is_role from mysql.user where user like 'foo%'; +select * from mysql.roles_mapping; +--sorted_result +show grants; diff --git a/mysql-test/suite/roles/create_and_drop_role_invalid_user_table.result b/mysql-test/suite/roles/create_and_drop_role_invalid_user_table.result new file mode 100644 index 00000000..dfad83e4 --- /dev/null +++ b/mysql-test/suite/roles/create_and_drop_role_invalid_user_table.result @@ -0,0 +1,30 @@ +# switching from mysql.global_priv to mysql.user +connect mysql, localhost, root,,; +use mysql; +alter table user drop column is_role; +alter table user drop column default_role; +alter table user drop column max_statement_time; +flush privileges; +create role test_role; +ERROR HY000: Column count of mysql.user is wrong. Expected 45, found 44. Created with MariaDB MYSQL_VERSION_ID, now running MYSQL_VERSION_ID. Please use mariadb-upgrade to fix this error +drop role test_role; +ERROR HY000: Operation DROP ROLE failed for 'test_role' +alter table user add column is_role enum('N', 'Y') default 'N' not null +COLLATE utf8_general_ci +after password_expired; +create role test_role; +create user test_user@localhost; +grant test_role to test_user@localhost; +set default role test_role for root@localhost; +drop role test_role; +drop user test_user@localhost; +alter table user add column default_role char(80) default '' not null +COLLATE utf8_general_ci +after is_role; +alter table user add max_statement_time decimal(12,6) default 0 not null +after default_role; +update user set is_role='N'; +flush privileges; +create role test_role; +drop role test_role; +# switching back from mysql.user to mysql.global_priv diff --git a/mysql-test/suite/roles/create_and_drop_role_invalid_user_table.test b/mysql-test/suite/roles/create_and_drop_role_invalid_user_table.test new file mode 100644 index 00000000..dac6eab2 --- /dev/null +++ b/mysql-test/suite/roles/create_and_drop_role_invalid_user_table.test @@ -0,0 +1,51 @@ +# +# Test that SET DEFAULT ROLE doesn't work on old privilege tables +# that don't have 'default_role' column +# +source include/not_embedded.inc; +source include/switch_to_mysql_user.inc; + +connect (mysql, localhost, root,,); +use mysql; + +# +# downgrade the table to pre-default-role structure +# +alter table user drop column is_role; +alter table user drop column default_role; +alter table user drop column max_statement_time; + +flush privileges; + +--replace_regex /10\d\d\d\d/MYSQL_VERSION_ID/ +--error ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE +create role test_role; +--error ER_CANNOT_USER +drop role test_role; +alter table user add column is_role enum('N', 'Y') default 'N' not null + COLLATE utf8_general_ci +after password_expired; + +# Test default role column +create role test_role; +create user test_user@localhost; +grant test_role to test_user@localhost; +#--replace_regex /10\d\d\d\d/MYSQL_VERSION_ID/ +#--error ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE +set default role test_role for root@localhost; +drop role test_role; +drop user test_user@localhost; + +alter table user add column default_role char(80) default '' not null + COLLATE utf8_general_ci +after is_role; +alter table user add max_statement_time decimal(12,6) default 0 not null +after default_role; + +update user set is_role='N'; + +flush privileges; +create role test_role; +drop role test_role; + +source include/switch_to_mysql_global_priv.inc; diff --git a/mysql-test/suite/roles/create_and_grant_role.result b/mysql-test/suite/roles/create_and_grant_role.result new file mode 100644 index 00000000..2a676115 --- /dev/null +++ b/mysql-test/suite/roles/create_and_grant_role.result @@ -0,0 +1,26 @@ +create role r1; +grant r1 to root@localhost; +create user u1; +set role r1; +grant r1 to u1; +select * from mysql.roles_mapping; +Host User Role Admin_option +% u1 r1 N +localhost root r1 Y +drop user u1; +select * from mysql.roles_mapping; +Host User Role Admin_option +localhost root r1 Y +show grants; +Grants for root@localhost +GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` WITH GRANT OPTION +GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION +GRANT USAGE ON *.* TO `r1` +GRANT `r1` TO `root`@`localhost` WITH ADMIN OPTION +drop role r1; +select * from mysql.roles_mapping; +Host User Role Admin_option +show grants; +Grants for root@localhost +GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` WITH GRANT OPTION +GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION diff --git a/mysql-test/suite/roles/create_and_grant_role.test b/mysql-test/suite/roles/create_and_grant_role.test new file mode 100644 index 00000000..5b321503 --- /dev/null +++ b/mysql-test/suite/roles/create_and_grant_role.test @@ -0,0 +1,21 @@ +source include/not_embedded.inc; + +create role r1; +grant r1 to root@localhost; +create user u1; +set role r1; + +grant r1 to u1; +--sorted_result +select * from mysql.roles_mapping; + +drop user u1; +--sorted_result +select * from mysql.roles_mapping; +--sorted_result +show grants; +drop role r1; +--sorted_result +select * from mysql.roles_mapping; +--sorted_result +show grants; diff --git a/mysql-test/suite/roles/current_role_view-12666.result b/mysql-test/suite/roles/current_role_view-12666.result new file mode 100644 index 00000000..1d7a8b05 --- /dev/null +++ b/mysql-test/suite/roles/current_role_view-12666.result @@ -0,0 +1,103 @@ +CREATE USER has_role@'localhost'; +GRANT ALL PRIVILEGES ON *.* TO has_role@'localhost'; +CREATE ROLE test_role; +GRANT test_role TO has_role@'localhost'; +CREATE USER no_role@'localhost'; +GRANT ALL PRIVILEGES ON *.* TO no_role@'localhost'; +CREATE TABLE view_role_test ( +id int primary key, +role_name varchar(50) +); +INSERT INTO view_role_test VALUES (1, 'test_role'); +# +# Use the same logic for stored procedures. +# +PREPARE prepared_no_current_role FROM "SELECT * from view_role_test WHERE role_name = CURRENT_ROLE()"; +# +# Creating a view with no CURRENT_ROLE() set and one with CURRENT_ROLE() +# set. Both should produce the same SHOW CREATE VIEW output. +# +CREATE +DEFINER = no_role@localhost +SQL SECURITY INVOKER +VIEW v_view_role_test_no_current_role +AS +SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE(); +SHOW CREATE VIEW v_view_role_test_no_current_role; +View Create View character_set_client collation_connection +v_view_role_test_no_current_role CREATE ALGORITHM=UNDEFINED DEFINER=`no_role`@`localhost` SQL SECURITY INVOKER VIEW `v_view_role_test_no_current_role` AS select `view_role_test`.`id` AS `id`,`view_role_test`.`role_name` AS `role_name` from `view_role_test` where `view_role_test`.`role_name` = current_role() latin1 latin1_swedish_ci +# +# No values should be returned +# +EXECUTE prepared_no_current_role; +id role_name +SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE(); +id role_name +SELECT * FROM v_view_role_test_no_current_role; +id role_name +# +# Now let's set the role. Create identical views as before. See if +# their behaviour is different. It should not be. +# +SET ROLE test_role; +SELECT CURRENT_USER(); +CURRENT_USER() +root@localhost +SELECT CURRENT_ROLE(); +CURRENT_ROLE() +test_role +# +# Create the VIEW and prepared Statement with a CURRENT_ROLE() set. +# +CREATE +DEFINER = no_role@localhost +SQL SECURITY INVOKER +VIEW v_view_role_test_with_current_role +AS +SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE(); +PREPARE prepared_with_current_role FROM "SELECT * from view_role_test WHERE role_name = CURRENT_ROLE()"; +SHOW CREATE VIEW v_view_role_test_with_current_role; +View Create View character_set_client collation_connection +v_view_role_test_with_current_role CREATE ALGORITHM=UNDEFINED DEFINER=`no_role`@`localhost` SQL SECURITY INVOKER VIEW `v_view_role_test_with_current_role` AS select `view_role_test`.`id` AS `id`,`view_role_test`.`role_name` AS `role_name` from `view_role_test` where `view_role_test`.`role_name` = current_role() latin1 latin1_swedish_ci +# +# Values should be returned for all select statements as we do have +# a CURRENT_ROLE() active; +# +EXECUTE prepared_no_current_role; +id role_name +1 test_role +EXECUTE prepared_with_current_role; +id role_name +1 test_role +SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE(); +id role_name +1 test_role +SELECT * FROM v_view_role_test_no_current_role; +id role_name +1 test_role +SELECT * FROM v_view_role_test_with_current_role; +id role_name +1 test_role +SET ROLE NONE; +# +# No values should be returned for all select statements as we do not have +# a CURRENT_ROLE() active; +# +EXECUTE prepared_no_current_role; +id role_name +EXECUTE prepared_with_current_role; +id role_name +SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE(); +id role_name +SELECT * FROM v_view_role_test_no_current_role; +id role_name +SELECT * FROM v_view_role_test_with_current_role; +id role_name +DROP USER has_role@'localhost'; +DROP USER no_role@'localhost'; +DROP ROLE test_role; +DROP table view_role_test; +DROP VIEW v_view_role_test_no_current_role; +DROP VIEW v_view_role_test_with_current_role; +DROP PREPARE prepared_no_current_role; +DROP PREPARE prepared_with_current_role; diff --git a/mysql-test/suite/roles/current_role_view-12666.test b/mysql-test/suite/roles/current_role_view-12666.test new file mode 100644 index 00000000..32039ffe --- /dev/null +++ b/mysql-test/suite/roles/current_role_view-12666.test @@ -0,0 +1,102 @@ +# +# MDEV-12666 CURRENT_ROLE() does not work in a view +# +--source include/not_embedded.inc + +CREATE USER has_role@'localhost'; +GRANT ALL PRIVILEGES ON *.* TO has_role@'localhost'; + +CREATE ROLE test_role; +GRANT test_role TO has_role@'localhost'; + +CREATE USER no_role@'localhost'; +GRANT ALL PRIVILEGES ON *.* TO no_role@'localhost'; + +CREATE TABLE view_role_test ( + id int primary key, + role_name varchar(50) + ); + +INSERT INTO view_role_test VALUES (1, 'test_role'); + +--echo # +--echo # Use the same logic for stored procedures. +--echo # +PREPARE prepared_no_current_role FROM "SELECT * from view_role_test WHERE role_name = CURRENT_ROLE()"; + +--echo # +--echo # Creating a view with no CURRENT_ROLE() set and one with CURRENT_ROLE() +--echo # set. Both should produce the same SHOW CREATE VIEW output. +--echo # +CREATE +DEFINER = no_role@localhost +SQL SECURITY INVOKER +VIEW v_view_role_test_no_current_role +AS +SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE(); + +SHOW CREATE VIEW v_view_role_test_no_current_role; + + +--echo # +--echo # No values should be returned +--echo # +EXECUTE prepared_no_current_role; +SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE(); +SELECT * FROM v_view_role_test_no_current_role; + +--echo # +--echo # Now let's set the role. Create identical views as before. See if +--echo # their behaviour is different. It should not be. +--echo # +SET ROLE test_role; + +SELECT CURRENT_USER(); +SELECT CURRENT_ROLE(); + +--echo # +--echo # Create the VIEW and prepared Statement with a CURRENT_ROLE() set. +--echo # +CREATE +DEFINER = no_role@localhost +SQL SECURITY INVOKER +VIEW v_view_role_test_with_current_role +AS +SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE(); + +PREPARE prepared_with_current_role FROM "SELECT * from view_role_test WHERE role_name = CURRENT_ROLE()"; + +SHOW CREATE VIEW v_view_role_test_with_current_role; + + +--echo # +--echo # Values should be returned for all select statements as we do have +--echo # a CURRENT_ROLE() active; +--echo # +EXECUTE prepared_no_current_role; +EXECUTE prepared_with_current_role; +SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE(); +SELECT * FROM v_view_role_test_no_current_role; +SELECT * FROM v_view_role_test_with_current_role; + +SET ROLE NONE; +--echo # +--echo # No values should be returned for all select statements as we do not have +--echo # a CURRENT_ROLE() active; +--echo # +EXECUTE prepared_no_current_role; +EXECUTE prepared_with_current_role; +SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE(); +SELECT * FROM v_view_role_test_no_current_role; +SELECT * FROM v_view_role_test_with_current_role; + + +DROP USER has_role@'localhost'; +DROP USER no_role@'localhost'; +DROP ROLE test_role; + +DROP table view_role_test; +DROP VIEW v_view_role_test_no_current_role; +DROP VIEW v_view_role_test_with_current_role; +DROP PREPARE prepared_no_current_role; +DROP PREPARE prepared_with_current_role; diff --git a/mysql-test/suite/roles/default_create_user_not_role.result b/mysql-test/suite/roles/default_create_user_not_role.result new file mode 100644 index 00000000..3f32329b --- /dev/null +++ b/mysql-test/suite/roles/default_create_user_not_role.result @@ -0,0 +1,8 @@ +connect mysql, localhost, root,,; +use mysql; +create user 'test'@'localhost'; +select user, host, is_role from user where user='test' and host='localhost'; +User Host is_role +test localhost N +drop user 'test'@'localhost'; +disconnect mysql; diff --git a/mysql-test/suite/roles/default_create_user_not_role.test b/mysql-test/suite/roles/default_create_user_not_role.test new file mode 100644 index 00000000..d3a43289 --- /dev/null +++ b/mysql-test/suite/roles/default_create_user_not_role.test @@ -0,0 +1,11 @@ +source include/not_embedded.inc; + +connect (mysql, localhost, root,,); +use mysql; +create user 'test'@'localhost'; + +#check to see if a created user is not a role by default +select user, host, is_role from user where user='test' and host='localhost'; + +drop user 'test'@'localhost'; +disconnect mysql; diff --git a/mysql-test/suite/roles/definer.result b/mysql-test/suite/roles/definer.result new file mode 100644 index 00000000..091ba255 --- /dev/null +++ b/mysql-test/suite/roles/definer.result @@ -0,0 +1,754 @@ +create database mysqltest1; +use mysqltest1; +create table t1 (a int, b int, c int); +insert t1 values (1,10,100),(2,20,200); +create role role1; +grant select (a) on mysqltest1.t1 to role1; +grant event,execute,trigger on mysqltest1.* to role1; +grant select on test.* to role1; +grant role1 to current_user; +create role role2; +grant insert,select on mysqltest1.t1 to role2; +grant event,execute,trigger on mysqltest1.* to role2; +grant select on test.* to role2; +create user foo@localhost; +grant create view on mysqltest1.* to foo@localhost; +grant select, create view on test.* to foo@localhost; +create role role4; +grant select on mysqltest1.t1 to role4; +grant role4 to foo@localhost; +grant select on test.* to role4; +create definer=current_role view test.v1 as select a+b,c from t1; +ERROR 0L000: Invalid definer +set role role1; +create definer=current_role view test.v1 as select a+b,c from t1; +show create view test.v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`role1` SQL SECURITY DEFINER VIEW `test`.`v1` AS select `mysqltest1`.`t1`.`a` + `mysqltest1`.`t1`.`b` AS `a+b`,`mysqltest1`.`t1`.`c` AS `c` from `mysqltest1`.`t1` latin1 latin1_swedish_ci +set role none; +create definer=role2 view test.v2 as select a+b,c,current_role() from t1; +show create view test.v2; +View Create View character_set_client collation_connection +v2 CREATE ALGORITHM=UNDEFINED DEFINER=`role2` SQL SECURITY DEFINER VIEW `test`.`v2` AS select `mysqltest1`.`t1`.`a` + `mysqltest1`.`t1`.`b` AS `a+b`,`mysqltest1`.`t1`.`c` AS `c`,current_role() AS `current_role()` from `mysqltest1`.`t1` latin1 latin1_swedish_ci +create definer=role3 view test.v3 as select a+b,c from t1; +Warnings: +Note 1449 The user specified as a definer ('role3'@'%') does not exist +show create view test.v3; +View Create View character_set_client collation_connection +v3 CREATE ALGORITHM=UNDEFINED DEFINER=`role3`@`%` SQL SECURITY DEFINER VIEW `test`.`v3` AS select `mysqltest1`.`t1`.`a` + `mysqltest1`.`t1`.`b` AS `a+b`,`mysqltest1`.`t1`.`c` AS `c` from `mysqltest1`.`t1` latin1 latin1_swedish_ci +Warnings: +Note 1449 The user specified as a definer ('role3'@'%') does not exist +connect c1, localhost, foo,,mysqltest1; +connection c1; +show grants; +Grants for foo@localhost +GRANT `role4` TO `foo`@`localhost` +GRANT USAGE ON *.* TO `foo`@`localhost` +GRANT CREATE VIEW ON `mysqltest1`.* TO `foo`@`localhost` +GRANT SELECT, CREATE VIEW ON `test`.* TO `foo`@`localhost` +select * from test.v1; +ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +select * from test.v2; +a+b c current_role() +11 100 role2 +22 200 role2 +select * from test.v3; +ERROR 28000: Access denied for user 'foo'@'localhost' (using password: NO) +create definer=role4 view test.v4 as select a+b,c from t1; +ERROR 42000: ANY command denied to user 'foo'@'localhost' for table `mysqltest1`.`t1` +select * from t1; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysqltest1`.`t1` +set role role4; +select * from t1; +a b c +1 10 100 +2 20 200 +create view test.v4 as select a+b,c from t1; +create definer=role4 view test.v5 as select a+b,c from t1; +select * from test.v4; +ERROR HY000: View 'test.v4' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +select * from test.v5; +a+b c +11 100 +22 200 +set role none; +select * from test.v4; +ERROR HY000: View 'test.v4' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +select * from test.v5; +a+b c +11 100 +22 200 +connection default; +drop role role4; +show create view test.v5; +View Create View character_set_client collation_connection +v5 CREATE ALGORITHM=UNDEFINED DEFINER=`role4` SQL SECURITY DEFINER VIEW `test`.`v5` AS select `mysqltest1`.`t1`.`a` + `mysqltest1`.`t1`.`b` AS `a+b`,`mysqltest1`.`t1`.`c` AS `c` from `mysqltest1`.`t1` latin1 latin1_swedish_ci +Warnings: +Note 1449 The user specified as a definer ('role4'@'') does not exist +select * from test.v5; +ERROR HY000: The user specified as a definer ('role4'@'') does not exist +create user role4; +grant select on mysqltest1.t1 to role4; +show create view test.v5; +View Create View character_set_client collation_connection +v5 CREATE ALGORITHM=UNDEFINED DEFINER=`role4` SQL SECURITY DEFINER VIEW `test`.`v5` AS select `mysqltest1`.`t1`.`a` + `mysqltest1`.`t1`.`b` AS `a+b`,`mysqltest1`.`t1`.`c` AS `c` from `mysqltest1`.`t1` latin1 latin1_swedish_ci +Warnings: +Note 1449 The user specified as a definer ('role4'@'') does not exist +select * from test.v5; +ERROR HY000: The user specified as a definer ('role4'@'') does not exist +flush tables; +show create view test.v5; +View Create View character_set_client collation_connection +v5 CREATE ALGORITHM=UNDEFINED DEFINER=`role4`@`%` SQL SECURITY DEFINER VIEW `test`.`v5` AS select `mysqltest1`.`t1`.`a` + `mysqltest1`.`t1`.`b` AS `a+b`,`mysqltest1`.`t1`.`c` AS `c` from `mysqltest1`.`t1` latin1 latin1_swedish_ci +select * from test.v5; +a+b c +11 100 +22 200 +drop user role4; +create table t2 select * from t1; +create definer=current_role trigger tr1 before insert on t2 for each row +insert t1 values (111, 222, 333); +ERROR 0L000: Invalid definer +set role role1; +create definer=current_role trigger tr1 before insert on t2 for each row +insert t1 values (111, 222, 333); +show create trigger tr1; +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +tr1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`role1` trigger tr1 before insert on t2 for each row +insert t1 values (111, 222, 333) latin1 latin1_swedish_ci latin1_swedish_ci # +set role none; +insert t2 values (11,22,33); +ERROR 42000: INSERT command denied to user ''@'' for table `mysqltest1`.`t1` +select * from t1; +a b c +1 10 100 +2 20 200 +select * from t2; +a b c +1 10 100 +2 20 200 +create definer=role2 trigger tr2 before delete on t2 for each row +insert t1 values (111, 222, 333); +show create trigger tr2; +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +tr2 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`role2` trigger tr2 before delete on t2 for each row +insert t1 values (111, 222, 333) latin1 latin1_swedish_ci latin1_swedish_ci # +delete from t2 where a=1; +select * from t1; +a b c +1 10 100 +2 20 200 +111 222 333 +select * from t2; +a b c +2 20 200 +delete from t1 where a=111; +create definer=role3 trigger tr3 before update on t2 for each row +insert t1 values (111, 222, 333); +Warnings: +Note 1449 The user specified as a definer ('role3'@'%') does not exist +show create trigger tr3; +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +tr3 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`role3`@`%` trigger tr3 before update on t2 for each row +insert t1 values (111, 222, 333) latin1 latin1_swedish_ci latin1_swedish_ci # +update t2 set b=2 where a=2; +ERROR HY000: The user specified as a definer ('role3'@'%') does not exist +select * from t1; +a b c +1 10 100 +2 20 200 +select * from t2; +a b c +2 20 200 +flush tables; +show create trigger tr2; +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +tr2 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`role2`@`` trigger tr2 before delete on t2 for each row +insert t1 values (111, 222, 333) latin1 latin1_swedish_ci latin1_swedish_ci # +delete from t2 where a=2; +ERROR HY000: The user specified as a definer ('role2'@'%') does not exist +select * from t1; +a b c +1 10 100 +2 20 200 +select * from t2; +a b c +2 20 200 +create definer=current_role procedure pr1() insert t1 values (111, 222, 333); +ERROR 0L000: Invalid definer +set role role1; +create definer=current_role procedure pr1() insert t1 values (111, 222, 333); +show create procedure pr1; +Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation +pr1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`role1` PROCEDURE `pr1`() +insert t1 values (111, 222, 333) latin1 latin1_swedish_ci latin1_swedish_ci +set role none; +call pr1(); +ERROR 42000: INSERT command denied to user ''@'' for table `mysqltest1`.`t1` +select * from t1; +a b c +1 10 100 +2 20 200 +create definer=role2 procedure pr2() insert t1 values (111, 222, 333); +show create procedure pr2; +Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation +pr2 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`role2` PROCEDURE `pr2`() +insert t1 values (111, 222, 333) latin1 latin1_swedish_ci latin1_swedish_ci +call pr2(); +select * from t1; +a b c +1 10 100 +2 20 200 +111 222 333 +delete from t1 where a=111; +create definer=role3 procedure pr3() insert t1 values (111, 222, 333); +Warnings: +Note 1449 The user specified as a definer ('role3'@'%') does not exist +show create procedure pr3; +Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation +pr3 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`role3`@`%` PROCEDURE `pr3`() +insert t1 values (111, 222, 333) latin1 latin1_swedish_ci latin1_swedish_ci +call pr3(); +ERROR HY000: The user specified as a definer ('role3'@'%') does not exist +select * from t1; +a b c +1 10 100 +2 20 200 +update mysql.proc set definer='role2@' where definer='role2'; +call pr2(); +ERROR HY000: The user specified as a definer ('role2'@'%') does not exist +create definer=current_role function fn1() returns int return (select sum(a+b) from t1); +ERROR 0L000: Invalid definer +set role role1; +create definer=current_role function fn1() returns int return (select sum(a+b) from t1); +show create function fn1; +Function sql_mode Create Function character_set_client collation_connection Database Collation +fn1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`role1` FUNCTION `fn1`() RETURNS int(11) +return (select sum(a+b) from t1) latin1 latin1_swedish_ci latin1_swedish_ci +set role none; +select fn1(); +ERROR 42000: SELECT command denied to user ''@'' for column 'b' in table 't1' +select * from t1; +a b c +1 10 100 +2 20 200 +create definer=role2 function fn2() returns int return (select sum(a+b) from t1); +show create function fn2; +Function sql_mode Create Function character_set_client collation_connection Database Collation +fn2 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`role2` FUNCTION `fn2`() RETURNS int(11) +return (select sum(a+b) from t1) latin1 latin1_swedish_ci latin1_swedish_ci +select fn2(); +fn2() +33 +create definer=role3 function fn3() returns int return (select sum(a+b) from t1); +Warnings: +Note 1449 The user specified as a definer ('role3'@'%') does not exist +show create function fn3; +Function sql_mode Create Function character_set_client collation_connection Database Collation +fn3 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`role3`@`%` FUNCTION `fn3`() RETURNS int(11) +return (select sum(a+b) from t1) latin1 latin1_swedish_ci latin1_swedish_ci +select fn3(); +ERROR HY000: The user specified as a definer ('role3'@'%') does not exist +set global event_scheduler=on; +create definer=current_role event e1 on schedule every 1 second starts '2000-01-01' do +insert t1 values (111, 1, 0); +ERROR 0L000: Invalid definer +set role role1; +create definer=current_role event e1 on schedule every 1 second starts '2000-01-01' do +insert t1 values (111, 2, 0); +show create event e1; +Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation +e1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION SYSTEM CREATE DEFINER=`role1` EVENT `e1` ON SCHEDULE EVERY 1 SECOND STARTS '2000-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO insert t1 values (111, 2, 0) latin1 latin1_swedish_ci latin1_swedish_ci +set role none; +create definer=role3 event e3 on schedule every 1 second starts '2000-01-01' do +insert t1 values (111, 3, 0); +Warnings: +Note 1449 The user specified as a definer ('role3'@'%') does not exist +show create event e3; +Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation +e3 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION SYSTEM CREATE DEFINER=`role3`@`%` EVENT `e3` ON SCHEDULE EVERY 1 SECOND STARTS '2000-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO insert t1 values (111, 3, 0) latin1 latin1_swedish_ci latin1_swedish_ci +create definer=role2 event e2 on schedule every 1 second starts '2000-01-01' do +insert t1 values (111, 4, 0); +show create event e2; +Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation +e2 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION SYSTEM CREATE DEFINER=`role2` EVENT `e2` ON SCHEDULE EVERY 1 SECOND STARTS '2000-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO insert t1 values (111, 4, 0) latin1 latin1_swedish_ci latin1_swedish_ci +set global event_scheduler=off; +select distinct * from t1; +a b c +1 10 100 +111 4 0 +2 20 200 +delete from t1 where a=111; + +CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */; + +USE `test`; +SET @saved_cs_client = @@character_set_client; +SET character_set_client = utf8; +/*!50001 CREATE VIEW `v1` AS SELECT + 1 AS `a+b`, + 1 AS `c` */; +SET character_set_client = @saved_cs_client; +SET @saved_cs_client = @@character_set_client; +SET character_set_client = utf8; +/*!50001 CREATE VIEW `v2` AS SELECT + 1 AS `a+b`, + 1 AS `c`, + 1 AS `current_role()` */; +SET character_set_client = @saved_cs_client; +SET @saved_cs_client = @@character_set_client; +SET character_set_client = utf8; +/*!50001 CREATE VIEW `v3` AS SELECT + 1 AS `a+b`, + 1 AS `c` */; +SET character_set_client = @saved_cs_client; +SET @saved_cs_client = @@character_set_client; +SET character_set_client = utf8; +/*!50001 CREATE VIEW `v4` AS SELECT + 1 AS `a+b`, + 1 AS `c` */; +SET character_set_client = @saved_cs_client; +SET @saved_cs_client = @@character_set_client; +SET character_set_client = utf8; +/*!50001 CREATE VIEW `v5` AS SELECT + 1 AS `a+b`, + 1 AS `c` */; +SET character_set_client = @saved_cs_client; + +CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */; + +USE `mysqltest1`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +INSERT INTO `t1` VALUES +(1,10,100), +(2,20,200); +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +INSERT INTO `t2` VALUES +(2,20,200); +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = latin1 */ ; +/*!50003 SET character_set_results = latin1 */ ; +/*!50003 SET collation_connection = latin1_swedish_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`role1`*/ /*!50003 trigger tr1 before insert on t2 for each row +insert t1 values (111, 222, 333) */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = latin1 */ ; +/*!50003 SET character_set_results = latin1 */ ; +/*!50003 SET collation_connection = latin1_swedish_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`role3`@`%`*/ /*!50003 trigger tr3 before update on t2 for each row +insert t1 values (111, 222, 333) */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = latin1 */ ; +/*!50003 SET character_set_results = latin1 */ ; +/*!50003 SET collation_connection = latin1_swedish_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`role2`@``*/ /*!50003 trigger tr2 before delete on t2 for each row +insert t1 values (111, 222, 333) */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50106 SET @save_time_zone= @@TIME_ZONE */ ; +DELIMITER ;; +/*!50003 SET @saved_cs_client = @@character_set_client */ ;; +/*!50003 SET @saved_cs_results = @@character_set_results */ ;; +/*!50003 SET @saved_col_connection = @@collation_connection */ ;; +/*!50003 SET character_set_client = latin1 */ ;; +/*!50003 SET character_set_results = latin1 */ ;; +/*!50003 SET collation_connection = latin1_swedish_ci */ ;; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ;; +/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;; +/*!50003 SET @saved_time_zone = @@time_zone */ ;; +/*!50003 SET time_zone = 'SYSTEM' */ ;; +/*!50106 CREATE*/ /*!50117 DEFINER=`role1`*/ /*!50106 EVENT `e1` ON SCHEDULE EVERY 1 SECOND STARTS '2000-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO insert t1 values (111, 2, 0) */ ;; +/*!50003 SET time_zone = @saved_time_zone */ ;; +/*!50003 SET sql_mode = @saved_sql_mode */ ;; +/*!50003 SET character_set_client = @saved_cs_client */ ;; +/*!50003 SET character_set_results = @saved_cs_results */ ;; +/*!50003 SET collation_connection = @saved_col_connection */ ;; +DELIMITER ;; +/*!50003 SET @saved_cs_client = @@character_set_client */ ;; +/*!50003 SET @saved_cs_results = @@character_set_results */ ;; +/*!50003 SET @saved_col_connection = @@collation_connection */ ;; +/*!50003 SET character_set_client = latin1 */ ;; +/*!50003 SET character_set_results = latin1 */ ;; +/*!50003 SET collation_connection = latin1_swedish_ci */ ;; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ;; +/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;; +/*!50003 SET @saved_time_zone = @@time_zone */ ;; +/*!50003 SET time_zone = 'SYSTEM' */ ;; +/*!50106 CREATE*/ /*!50117 DEFINER=`role2`*/ /*!50106 EVENT `e2` ON SCHEDULE EVERY 1 SECOND STARTS '2000-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO insert t1 values (111, 4, 0) */ ;; +/*!50003 SET time_zone = @saved_time_zone */ ;; +/*!50003 SET sql_mode = @saved_sql_mode */ ;; +/*!50003 SET character_set_client = @saved_cs_client */ ;; +/*!50003 SET character_set_results = @saved_cs_results */ ;; +/*!50003 SET collation_connection = @saved_col_connection */ ;; +DELIMITER ;; +/*!50003 SET @saved_cs_client = @@character_set_client */ ;; +/*!50003 SET @saved_cs_results = @@character_set_results */ ;; +/*!50003 SET @saved_col_connection = @@collation_connection */ ;; +/*!50003 SET character_set_client = latin1 */ ;; +/*!50003 SET character_set_results = latin1 */ ;; +/*!50003 SET collation_connection = latin1_swedish_ci */ ;; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ;; +/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;; +/*!50003 SET @saved_time_zone = @@time_zone */ ;; +/*!50003 SET time_zone = 'SYSTEM' */ ;; +/*!50106 CREATE*/ /*!50117 DEFINER=`role3`@`%`*/ /*!50106 EVENT `e3` ON SCHEDULE EVERY 1 SECOND STARTS '2000-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO insert t1 values (111, 3, 0) */ ;; +/*!50003 SET time_zone = @saved_time_zone */ ;; +/*!50003 SET sql_mode = @saved_sql_mode */ ;; +/*!50003 SET character_set_client = @saved_cs_client */ ;; +/*!50003 SET character_set_results = @saved_cs_results */ ;; +/*!50003 SET collation_connection = @saved_col_connection */ ;; +DELIMITER ; +/*!50106 SET TIME_ZONE= @save_time_zone */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = latin1 */ ; +/*!50003 SET character_set_results = latin1 */ ; +/*!50003 SET collation_connection = latin1_swedish_ci */ ; +DELIMITER ;; +CREATE DEFINER=`role1` FUNCTION `fn1`() RETURNS int(11) +return (select sum(a+b) from t1) ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = latin1 */ ; +/*!50003 SET character_set_results = latin1 */ ; +/*!50003 SET collation_connection = latin1_swedish_ci */ ; +DELIMITER ;; +CREATE DEFINER=`role2` FUNCTION `fn2`() RETURNS int(11) +return (select sum(a+b) from t1) ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = latin1 */ ; +/*!50003 SET character_set_results = latin1 */ ; +/*!50003 SET collation_connection = latin1_swedish_ci */ ; +DELIMITER ;; +CREATE DEFINER=`role3`@`%` FUNCTION `fn3`() RETURNS int(11) +return (select sum(a+b) from t1) ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = latin1 */ ; +/*!50003 SET character_set_results = latin1 */ ; +/*!50003 SET collation_connection = latin1_swedish_ci */ ; +DELIMITER ;; +CREATE DEFINER=`role1` PROCEDURE `pr1`() +insert t1 values (111, 222, 333) ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = latin1 */ ; +/*!50003 SET character_set_results = latin1 */ ; +/*!50003 SET collation_connection = latin1_swedish_ci */ ; +DELIMITER ;; +CREATE DEFINER=`role2`@`%` PROCEDURE `pr2`() +insert t1 values (111, 222, 333) ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = latin1 */ ; +/*!50003 SET character_set_results = latin1 */ ; +/*!50003 SET collation_connection = latin1_swedish_ci */ ; +DELIMITER ;; +CREATE DEFINER=`role3`@`%` PROCEDURE `pr3`() +insert t1 values (111, 222, 333) ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; + +USE `test`; +/*!50001 DROP VIEW IF EXISTS `v1`*/; +/*!50001 SET @saved_cs_client = @@character_set_client */; +/*!50001 SET @saved_cs_results = @@character_set_results */; +/*!50001 SET @saved_col_connection = @@collation_connection */; +/*!50001 SET character_set_client = latin1 */; +/*!50001 SET character_set_results = latin1 */; +/*!50001 SET collation_connection = latin1_swedish_ci */; +/*!50001 CREATE ALGORITHM=UNDEFINED DEFINER=`role1` SQL SECURITY DEFINER VIEW `v1` AS select `mysqltest1`.`t1`.`a` + `mysqltest1`.`t1`.`b` AS `a+b`,`mysqltest1`.`t1`.`c` AS `c` from `mysqltest1`.`t1` */; +/*!50001 SET character_set_client = @saved_cs_client */; +/*!50001 SET character_set_results = @saved_cs_results */; +/*!50001 SET collation_connection = @saved_col_connection */; +/*!50001 DROP VIEW IF EXISTS `v2`*/; +/*!50001 SET @saved_cs_client = @@character_set_client */; +/*!50001 SET @saved_cs_results = @@character_set_results */; +/*!50001 SET @saved_col_connection = @@collation_connection */; +/*!50001 SET character_set_client = latin1 */; +/*!50001 SET character_set_results = latin1 */; +/*!50001 SET collation_connection = latin1_swedish_ci */; +/*!50001 CREATE ALGORITHM=UNDEFINED DEFINER=`role2` SQL SECURITY DEFINER VIEW `v2` AS select `mysqltest1`.`t1`.`a` + `mysqltest1`.`t1`.`b` AS `a+b`,`mysqltest1`.`t1`.`c` AS `c`,current_role() AS `current_role()` from `mysqltest1`.`t1` */; +/*!50001 SET character_set_client = @saved_cs_client */; +/*!50001 SET character_set_results = @saved_cs_results */; +/*!50001 SET collation_connection = @saved_col_connection */; +/*!50001 DROP VIEW IF EXISTS `v3`*/; +/*!50001 SET @saved_cs_client = @@character_set_client */; +/*!50001 SET @saved_cs_results = @@character_set_results */; +/*!50001 SET @saved_col_connection = @@collation_connection */; +/*!50001 SET character_set_client = latin1 */; +/*!50001 SET character_set_results = latin1 */; +/*!50001 SET collation_connection = latin1_swedish_ci */; +/*!50001 CREATE ALGORITHM=UNDEFINED */ +/*!50013 DEFINER=`role3`@`%` SQL SECURITY DEFINER */ +/*!50001 VIEW `v3` AS select `mysqltest1`.`t1`.`a` + `mysqltest1`.`t1`.`b` AS `a+b`,`mysqltest1`.`t1`.`c` AS `c` from `mysqltest1`.`t1` */; +/*!50001 SET character_set_client = @saved_cs_client */; +/*!50001 SET character_set_results = @saved_cs_results */; +/*!50001 SET collation_connection = @saved_col_connection */; +/*!50001 DROP VIEW IF EXISTS `v4`*/; +/*!50001 SET @saved_cs_client = @@character_set_client */; +/*!50001 SET @saved_cs_results = @@character_set_results */; +/*!50001 SET @saved_col_connection = @@collation_connection */; +/*!50001 SET character_set_client = latin1 */; +/*!50001 SET character_set_results = latin1 */; +/*!50001 SET collation_connection = latin1_swedish_ci */; +/*!50001 CREATE ALGORITHM=UNDEFINED */ +/*!50013 DEFINER=`foo`@`localhost` SQL SECURITY DEFINER */ +/*!50001 VIEW `v4` AS select `mysqltest1`.`t1`.`a` + `mysqltest1`.`t1`.`b` AS `a+b`,`mysqltest1`.`t1`.`c` AS `c` from `mysqltest1`.`t1` */; +/*!50001 SET character_set_client = @saved_cs_client */; +/*!50001 SET character_set_results = @saved_cs_results */; +/*!50001 SET collation_connection = @saved_col_connection */; +/*!50001 DROP VIEW IF EXISTS `v5`*/; +/*!50001 SET @saved_cs_client = @@character_set_client */; +/*!50001 SET @saved_cs_results = @@character_set_results */; +/*!50001 SET @saved_col_connection = @@collation_connection */; +/*!50001 SET character_set_client = latin1 */; +/*!50001 SET character_set_results = latin1 */; +/*!50001 SET collation_connection = latin1_swedish_ci */; +/*!50001 CREATE ALGORITHM=UNDEFINED */ +/*!50013 DEFINER=`role4`@`%` SQL SECURITY DEFINER */ +/*!50001 VIEW `v5` AS select `mysqltest1`.`t1`.`a` + `mysqltest1`.`t1`.`b` AS `a+b`,`mysqltest1`.`t1`.`c` AS `c` from `mysqltest1`.`t1` */; +/*!50001 SET character_set_client = @saved_cs_client */; +/*!50001 SET character_set_results = @saved_cs_results */; +/*!50001 SET collation_connection = @saved_col_connection */; + +USE `mysqltest1`; +drop trigger tr1; +drop trigger tr2; +drop trigger tr3; +drop procedure pr1; +drop procedure pr2; +drop procedure pr3; +drop function fn1; +drop function fn2; +drop function fn3; +drop event e1; +drop event e2; +drop event e3; +drop view test.v1, test.v2, test.v3, test.v4, test.v5; +drop table t1, t2; +drop role role1, role2; +drop user foo@localhost; +drop database mysqltest1; +use test; +create user utest; +prepare stmt1 from 'grant select on *.* to utest'; +execute stmt1; +show grants for utest; +Grants for utest@% +GRANT SELECT ON *.* TO `utest`@`%` +drop user utest; +create role utest; +execute stmt1; +show grants for utest; +Grants for utest +GRANT SELECT ON *.* TO `utest` +drop role utest; +# +# MDEV-13676: Field "create Procedure" is NULL, even if the the user +# has role which is the definer. (SHOW CREATE PROCEDURE) +# +create database rtest; +create role r1; +create role r2; +create role r3; +grant all privileges on rtest.* to r1; +create user user1; +grant r1 to user1; +grant r1 to r2; +grant r2 to user1; +grant r3 to user1; +connect user1, localhost,user1,,"*NO-ONE*",,,; +set role r2; +use rtest; +CREATE DEFINER=current_role() PROCEDURE user1_proc() SQL SECURITY INVOKER +BEGIN +SELECT NOW(), VERSION(); +END;// +set role r2; +show create procedure user1_proc; +Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation +user1_proc STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`r2` PROCEDURE `user1_proc`() + SQL SECURITY INVOKER +BEGIN +SELECT NOW(), VERSION(); +END latin1 latin1_swedish_ci latin1_swedish_ci +# +# Currently one can not use as definer any role except CURRENT_ROLE +# +CREATE DEFINER='r1' PROCEDURE user1_proc2() SQL SECURITY INVOKER +BEGIN +SELECT NOW(), VERSION(); +END;// +ERROR 42000: Access denied; you need (at least one of) the SUPER, SET USER privilege(s) for this operation +set role r1; +CREATE DEFINER='r1' PROCEDURE user1_proc2() SQL SECURITY INVOKER +BEGIN +SELECT NOW(), VERSION(); +END;// +show create procedure user1_proc2; +Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation +user1_proc2 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`r1` PROCEDURE `user1_proc2`() + SQL SECURITY INVOKER +BEGIN +SELECT NOW(), VERSION(); +END latin1 latin1_swedish_ci latin1_swedish_ci +# +# Test to see if the user can still see the procedure code if the +# role that owns it is granted to him indirectly. +# +set role r2; +show create procedure user1_proc2; +Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation +user1_proc2 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`r1` PROCEDURE `user1_proc2`() + SQL SECURITY INVOKER +BEGIN +SELECT NOW(), VERSION(); +END latin1 latin1_swedish_ci latin1_swedish_ci +# +# One should not be able to see the procedure code if the role that owns +# the procedure is not set by the user or is not in the subgraph of the +# currently active role. +# +set role r3; +show create procedure user1_proc2; +ERROR 42000: PROCEDURE user1_proc2 does not exist +connection default; +use rtest; +# +# Try a few edge cases, with usernames identical to role name; +# +create user user_like_role; +create user foo; +create role user_like_role; +grant select on rtest.* to user_like_role; +grant select on rtest.* to foo; +grant select on rtest.* to user_like_role@'%'; +grant user_like_role to foo; +# +# Here we have a procedure that is owned by user_like_role USER +# We don't want user_like_role ROLE to have access to its code. +# +CREATE DEFINER=`user_like_role`@`%` PROCEDURE sensitive_proc() SQL SECURITY INVOKER +BEGIN +SELECT NOW(), VERSION(); +END;// +connect user_like_role, localhost, user_like_role,,"*NO-ONE*",,,; +use rtest; +show create procedure sensitive_proc; +Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation +sensitive_proc STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`user_like_role`@`%` PROCEDURE `sensitive_proc`() + SQL SECURITY INVOKER +BEGIN +SELECT NOW(), VERSION(); +END latin1 latin1_swedish_ci latin1_swedish_ci +connect foo, localhost, foo,,"*NO-ONE*",,,; +set role user_like_role; +use rtest; +# +# Foo has the set rolename identical to the procedure's definer's username. +# Foo should not have access to this procedure. +# +show create procedure sensitive_proc; +ERROR 42000: PROCEDURE sensitive_proc does not exist +connection default; +drop role r1; +drop role r2; +drop role r3; +drop role user_like_role; +drop user user1; +drop user foo; +drop user user_like_role; +drop procedure user1_proc; +drop procedure user1_proc2; +drop procedure sensitive_proc; +drop database rtest; diff --git a/mysql-test/suite/roles/definer.test b/mysql-test/suite/roles/definer.test new file mode 100644 index 00000000..4cd42d59 --- /dev/null +++ b/mysql-test/suite/roles/definer.test @@ -0,0 +1,466 @@ +# create view +# create trigger +# create procedure +# create event +# mysqldump dumping the definer + +--source include/not_embedded.inc +--source include/default_charset.inc + +let MYSQLD_DATADIR=`select @@datadir`; + +create database mysqltest1; +use mysqltest1; + +create table t1 (a int, b int, c int); +insert t1 values (1,10,100),(2,20,200); + +# non-priv role granted +create role role1; +grant select (a) on mysqltest1.t1 to role1; +grant event,execute,trigger on mysqltest1.* to role1; +grant select on test.* to role1; + +grant role1 to current_user; + +# priv role +create role role2; +grant insert,select on mysqltest1.t1 to role2; +grant event,execute,trigger on mysqltest1.* to role2; +grant select on test.* to role2; + +# create a non-priv user and a priv role granted to him +create user foo@localhost; +grant create view on mysqltest1.* to foo@localhost; +grant select, create view on test.* to foo@localhost; +create role role4; +grant select on mysqltest1.t1 to role4; +grant role4 to foo@localhost; +grant select on test.* to role4; + +################################################## +# views +################################################## + +# no curent role = error +--error ER_MALFORMED_DEFINER +create definer=current_role view test.v1 as select a+b,c from t1; + +# definer=current_role, but it has doesn't have enough privileges +set role role1; +create definer=current_role view test.v1 as select a+b,c from t1; +show create view test.v1; +set role none; + +# definer=role_name, privileges ok +create definer=role2 view test.v2 as select a+b,c,current_role() from t1; +show create view test.v2; + +# definer=non_existent_role +create definer=role3 view test.v3 as select a+b,c from t1; +show create view test.v3; + +connect (c1, localhost, foo,,mysqltest1); +connection c1; +show grants; + +# role1 doesn't have enough privileges for v1 to work +--error ER_VIEW_INVALID +select * from test.v1; + +# role2 is ok, v2 is ok +select * from test.v2; + +# role3 is treated as a user name role3@%, doesn't exist, v3 fails +--error ER_ACCESS_DENIED_ERROR +select * from test.v3; + +# fails, no SUPER - cannot specify a definer arbitrarily +--error ER_TABLEACCESS_DENIED_ERROR +create definer=role4 view test.v4 as select a+b,c from t1; + +--error ER_TABLEACCESS_DENIED_ERROR +select * from t1; +set role role4; +select * from t1; + +# can select from t1, but the view won't work, by default definer=current_user +create view test.v4 as select a+b,c from t1; + +# now role4 is the current_role, can be specified as a definer +create definer=role4 view test.v5 as select a+b,c from t1; + +--error ER_VIEW_INVALID +select * from test.v4; +select * from test.v5; +set role none; +--error ER_VIEW_INVALID +select * from test.v4; +select * from test.v5; + +connection default; + +drop role role4; + +show create view test.v5; +--error ER_NO_SUCH_USER +select * from test.v5; + +create user role4; +grant select on mysqltest1.t1 to role4; +show create view test.v5; +--error ER_NO_SUCH_USER +select * from test.v5; + +# pretend it's an old view from before 10.0.5 +perl; +local $/; +my $f= "$ENV{MYSQLD_DATADIR}/test/v5.frm"; +open(F, '<', $f) or die "open(<$f): $!"; +$_=<F>; +s/create-version=2/create-version=1/; +open(F, '>', $f) or die "open(>$f): $!"; +syswrite F, $_ or die "syswrite($f): $!" +EOF + +flush tables; +show create view test.v5; +select * from test.v5; +drop user role4; + + +################################################## +# trigger +################################################## + +create table t2 select * from t1; + +# no curent role = error +--error ER_MALFORMED_DEFINER +create definer=current_role trigger tr1 before insert on t2 for each row + insert t1 values (111, 222, 333); + +# definer=current_role, but it has doesn't have enough privileges +set role role1; +create definer=current_role trigger tr1 before insert on t2 for each row + insert t1 values (111, 222, 333); +--replace_column 7 # +show create trigger tr1; +set role none; + +--error ER_TABLEACCESS_DENIED_ERROR +insert t2 values (11,22,33); +select * from t1; +select * from t2; + +# definer=role_name, privileges ok +create definer=role2 trigger tr2 before delete on t2 for each row + insert t1 values (111, 222, 333); +--replace_column 7 # +show create trigger tr2; +delete from t2 where a=1; +select * from t1; +select * from t2; +delete from t1 where a=111; + +# definer=non_existent_role +create definer=role3 trigger tr3 before update on t2 for each row + insert t1 values (111, 222, 333); +--replace_column 7 # +show create trigger tr3; +--error ER_NO_SUCH_USER +update t2 set b=2 where a=2; +select * from t1; +select * from t2; + +flush tables; + +# change triggers to use pre-10.0.5 definer with an empty hostname +perl; +local $/; +my $f= "$ENV{MYSQLD_DATADIR}/mysqltest1/t2.TRG"; +open(F, '<', $f) or die "open(<$f): $!"; +$_=<F>; +s/'role2'/'role2\@'/; +s/`role2`/$&\@``/; +open(F, '>', $f) or die "open(>$f): $!"; +syswrite F, $_ or die "syswrite($f): $!" +EOF + +--replace_column 7 # +show create trigger tr2; +--error ER_NO_SUCH_USER +delete from t2 where a=2; +select * from t1; +select * from t2; + +################################################## +# stored procedures +################################################## + +# no curent role = error +--error ER_MALFORMED_DEFINER +create definer=current_role procedure pr1() insert t1 values (111, 222, 333); + +# definer=current_role, but it has doesn't have enough privileges +set role role1; +create definer=current_role procedure pr1() insert t1 values (111, 222, 333); +show create procedure pr1; +set role none; + +--error ER_TABLEACCESS_DENIED_ERROR +call pr1(); +select * from t1; + +# definer=role_name, privileges ok +create definer=role2 procedure pr2() insert t1 values (111, 222, 333); +show create procedure pr2; +call pr2(); +select * from t1; +delete from t1 where a=111; + +# definer=non_existent_role +create definer=role3 procedure pr3() insert t1 values (111, 222, 333); +show create procedure pr3; +--error ER_NO_SUCH_USER +call pr3(); +select * from t1; + +# change a procedure to use pre-10.0.5 definer with an empty hostname +update mysql.proc set definer='role2@' where definer='role2'; +--error ER_NO_SUCH_USER +call pr2(); + +################################################## +# stored functions +################################################## + +# no curent role = error +--error ER_MALFORMED_DEFINER +create definer=current_role function fn1() returns int return (select sum(a+b) from t1); + +# definer=current_role, but it has doesn't have enough privileges +set role role1; +create definer=current_role function fn1() returns int return (select sum(a+b) from t1); +show create function fn1; +set role none; + +--error ER_COLUMNACCESS_DENIED_ERROR +select fn1(); +select * from t1; + +# definer=role_name, privileges ok +create definer=role2 function fn2() returns int return (select sum(a+b) from t1); +show create function fn2; +select fn2(); + +# definer=non_existent_role +create definer=role3 function fn3() returns int return (select sum(a+b) from t1); +show create function fn3; +--error ER_NO_SUCH_USER +select fn3(); + +################################################## +# events +################################################## + +set global event_scheduler=on; + +# no curent role = error +--error ER_MALFORMED_DEFINER +create definer=current_role event e1 on schedule every 1 second starts '2000-01-01' do + insert t1 values (111, 1, 0); + +# definer=current_role, but it has doesn't have enough privileges +set role role1; +create definer=current_role event e1 on schedule every 1 second starts '2000-01-01' do + insert t1 values (111, 2, 0); +show create event e1; +set role none; + +# definer=non_existent_role +create definer=role3 event e3 on schedule every 1 second starts '2000-01-01' do + insert t1 values (111, 3, 0); +show create event e3; + +# definer=role_name, privileges ok +create definer=role2 event e2 on schedule every 1 second starts '2000-01-01' do + insert t1 values (111, 4, 0); +show create event e2; + +let $wait_condition=select count(*) >= 4 from t1; +--source include/wait_condition.inc + +set global event_scheduler=off; + +--sorted_result +select distinct * from t1; +delete from t1 where a=111; + +################################################## +# mysqldump +################################################## + +# note that LOCK TABLES won't work because v3 has invalid definer + +--exec $MYSQL_DUMP --compact --events --routines --skip-lock-tables --databases test mysqltest1 + +################################################## +# cleanup +################################################## + +drop trigger tr1; +drop trigger tr2; +drop trigger tr3; +drop procedure pr1; +drop procedure pr2; +drop procedure pr3; +drop function fn1; +drop function fn2; +drop function fn3; +drop event e1; +drop event e2; +drop event e3; +drop view test.v1, test.v2, test.v3, test.v4, test.v5; +drop table t1, t2; +drop role role1, role2; +drop user foo@localhost; +drop database mysqltest1; +use test; + +################################################## +# reexecution +################################################## + +create user utest; +prepare stmt1 from 'grant select on *.* to utest'; +execute stmt1; +show grants for utest; +drop user utest; +create role utest; +execute stmt1; +show grants for utest; +drop role utest; + +--echo # +--echo # MDEV-13676: Field "create Procedure" is NULL, even if the the user +--echo # has role which is the definer. (SHOW CREATE PROCEDURE) +--echo # + +create database rtest; +create role r1; +create role r2; +create role r3; +grant all privileges on rtest.* to r1; + +create user user1; +grant r1 to user1; +grant r1 to r2; +grant r2 to user1; +grant r3 to user1; + +connect (user1, localhost,user1,,"*NO-ONE*",,,); +set role r2; +use rtest; + +DELIMITER //; +CREATE DEFINER=current_role() PROCEDURE user1_proc() SQL SECURITY INVOKER + BEGIN + SELECT NOW(), VERSION(); + END;// +DELIMITER ;// + +set role r2; +show create procedure user1_proc; + +--echo # +--echo # Currently one can not use as definer any role except CURRENT_ROLE +--echo # +DELIMITER //; +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +CREATE DEFINER='r1' PROCEDURE user1_proc2() SQL SECURITY INVOKER + BEGIN + SELECT NOW(), VERSION(); + END;// +DELIMITER ;// + +set role r1; +DELIMITER //; +CREATE DEFINER='r1' PROCEDURE user1_proc2() SQL SECURITY INVOKER + BEGIN + SELECT NOW(), VERSION(); + END;// +DELIMITER ;// + +show create procedure user1_proc2; +--echo # +--echo # Test to see if the user can still see the procedure code if the +--echo # role that owns it is granted to him indirectly. +--echo # +set role r2; +show create procedure user1_proc2; + +--echo # +--echo # One should not be able to see the procedure code if the role that owns +--echo # the procedure is not set by the user or is not in the subgraph of the +--echo # currently active role. +--echo # +set role r3; +--error ER_SP_DOES_NOT_EXIST +show create procedure user1_proc2; + +connection default; + +use rtest; + +--echo # +--echo # Try a few edge cases, with usernames identical to role name; +--echo # + +create user user_like_role; +create user foo; +create role user_like_role; +grant select on rtest.* to user_like_role; +grant select on rtest.* to foo; +grant select on rtest.* to user_like_role@'%'; + +grant user_like_role to foo; + +--echo # +--echo # Here we have a procedure that is owned by user_like_role USER +--echo # We don't want user_like_role ROLE to have access to its code. +--echo # +DELIMITER //; +CREATE DEFINER=`user_like_role`@`%` PROCEDURE sensitive_proc() SQL SECURITY INVOKER + BEGIN + SELECT NOW(), VERSION(); + END;// +DELIMITER ;// + +connect (user_like_role, localhost, user_like_role,,"*NO-ONE*",,,); +use rtest; +show create procedure sensitive_proc; + +connect (foo, localhost, foo,,"*NO-ONE*",,,); +set role user_like_role; +use rtest; + +--echo # +--echo # Foo has the set rolename identical to the procedure's definer's username. +--echo # Foo should not have access to this procedure. +--echo # +--error ER_SP_DOES_NOT_EXIST +show create procedure sensitive_proc; + +connection default; +drop role r1; +drop role r2; +drop role r3; +drop role user_like_role; +drop user user1; +drop user foo; +drop user user_like_role; +drop procedure user1_proc; +drop procedure user1_proc2; +drop procedure sensitive_proc; +drop database rtest; diff --git a/mysql-test/suite/roles/drop_current_role.result b/mysql-test/suite/roles/drop_current_role.result new file mode 100644 index 00000000..b6de0304 --- /dev/null +++ b/mysql-test/suite/roles/drop_current_role.result @@ -0,0 +1,5 @@ +create role r; +set role r; +drop role r; +revoke all on *.* from current_role; +ERROR OP000: Invalid role specification `r` diff --git a/mysql-test/suite/roles/drop_current_role.test b/mysql-test/suite/roles/drop_current_role.test new file mode 100644 index 00000000..c8d6fc5d --- /dev/null +++ b/mysql-test/suite/roles/drop_current_role.test @@ -0,0 +1,9 @@ +--source include/not_embedded.inc +# +# MDEV-22521 Server crashes in traverse_role_graph_up or Assertion `user' fails in traverse_role_graph_impl +# +create role r; +set role r; +drop role r; +error ER_INVALID_ROLE; +revoke all on *.* from current_role; diff --git a/mysql-test/suite/roles/drop_current_user-5176.result b/mysql-test/suite/roles/drop_current_user-5176.result new file mode 100644 index 00000000..9c4041a0 --- /dev/null +++ b/mysql-test/suite/roles/drop_current_user-5176.result @@ -0,0 +1,11 @@ +create user foo@localhost; +grant create user on *.* to foo@localhost; +connect foo,localhost,foo,,; +drop user foo@localhost; +select * from information_schema.applicable_roles; +GRANTEE ROLE_NAME IS_GRANTABLE IS_DEFAULT +show grants; +ERROR 42000: There is no such grant defined for user 'foo' on host 'localhost' +select current_user(); +current_user() +foo@localhost diff --git a/mysql-test/suite/roles/drop_current_user-5176.test b/mysql-test/suite/roles/drop_current_user-5176.test new file mode 100644 index 00000000..27051345 --- /dev/null +++ b/mysql-test/suite/roles/drop_current_user-5176.test @@ -0,0 +1,14 @@ +# +# MDEV-5176 Server crashes in fill_schema_applicable_roles on select from APPLICABLE_ROLES after a suicide +# +--source include/not_embedded.inc + +create user foo@localhost; +grant create user on *.* to foo@localhost; +--connect (foo,localhost,foo,,) +drop user foo@localhost; +select * from information_schema.applicable_roles; +--error ER_NONEXISTING_GRANT +show grants; +select current_user(); + diff --git a/mysql-test/suite/roles/drop_routines.result b/mysql-test/suite/roles/drop_routines.result new file mode 100644 index 00000000..7facb9fd --- /dev/null +++ b/mysql-test/suite/roles/drop_routines.result @@ -0,0 +1,81 @@ +create role r1; +create role r2; +create role r3; +create user u1; +grant r2 to r1; +grant r3 to r2; +grant r1 to u1; +show grants for u1; +Grants for u1@% +GRANT USAGE ON *.* TO `u1`@`%` +GRANT `r1` TO `u1`@`%` +show grants for r1; +Grants for r1 +GRANT USAGE ON *.* TO `r1` +GRANT USAGE ON *.* TO `r2` +GRANT USAGE ON *.* TO `r3` +GRANT `r2` TO `r1` +GRANT `r3` TO `r2` +grant SELECT on *.* to u1; +grant INSERT on mysql.* to r1; +grant DELETE on mysql.roles_mapping to r2; +grant UPDATE on mysql.user to r3; +create function mysql.test_func (s CHAR(20)) +returns CHAR(50) DETERMINISTIC +return concat('Test string: ',s); +create procedure mysql.test_proc (OUT param1 INT) +begin +select COUNT(*) into param1 from mysql.roles_mapping; +end| +grant execute on function mysql.test_func to r2; +grant execute on procedure mysql.test_proc to r3; +revoke execute on procedure mysql.test_proc from r2; +ERROR 42000: There is no such grant defined for user 'r2' on host '' on routine 'test_proc' +show grants for r1; +Grants for r1 +GRANT DELETE ON `mysql`.`roles_mapping` TO `r2` +GRANT EXECUTE ON FUNCTION `mysql`.`test_func` TO `r2` +GRANT EXECUTE ON PROCEDURE `mysql`.`test_proc` TO `r3` +GRANT INSERT ON `mysql`.* TO `r1` +GRANT UPDATE ON `mysql`.`user` TO `r3` +GRANT USAGE ON *.* TO `r1` +GRANT USAGE ON *.* TO `r2` +GRANT USAGE ON *.* TO `r3` +GRANT `r2` TO `r1` +GRANT `r3` TO `r2` +show grants for r2; +Grants for r2 +GRANT DELETE ON `mysql`.`roles_mapping` TO `r2` +GRANT EXECUTE ON FUNCTION `mysql`.`test_func` TO `r2` +GRANT EXECUTE ON PROCEDURE `mysql`.`test_proc` TO `r3` +GRANT UPDATE ON `mysql`.`user` TO `r3` +GRANT USAGE ON *.* TO `r2` +GRANT USAGE ON *.* TO `r3` +GRANT `r3` TO `r2` +show grants for r3; +Grants for r3 +GRANT EXECUTE ON PROCEDURE `mysql`.`test_proc` TO `r3` +GRANT UPDATE ON `mysql`.`user` TO `r3` +GRANT USAGE ON *.* TO `r3` +drop function mysql.test_func; +drop procedure mysql.test_proc; +create function mysql.test_func (s CHAR(20)) +returns CHAR(50) DETERMINISTIC +return concat('Test string: ',s); +show grants for r2; +Grants for r2 +GRANT DELETE ON `mysql`.`roles_mapping` TO `r2` +GRANT UPDATE ON `mysql`.`user` TO `r3` +GRANT USAGE ON *.* TO `r2` +GRANT USAGE ON *.* TO `r3` +GRANT `r3` TO `r2` +connect u1,localhost,u1,,; +select mysql.test_func("none"); +ERROR 42000: execute command denied to user 'u1'@'%' for routine 'mysql.test_func' +set role r1; +select mysql.test_func("r1"); +ERROR 42000: execute command denied to user 'u1'@'%' for routine 'mysql.test_func' +connection default; +drop function mysql.test_func; +drop role r1, r2, r3; +drop user u1; diff --git a/mysql-test/suite/roles/drop_routines.test b/mysql-test/suite/roles/drop_routines.test new file mode 100644 index 00000000..b5972d8d --- /dev/null +++ b/mysql-test/suite/roles/drop_routines.test @@ -0,0 +1,69 @@ +source include/not_embedded.inc; + +create role r1; +create role r2; +create role r3; +create user u1; + +#CREATE A CHAIN OF ROLES +grant r2 to r1; +grant r3 to r2; +grant r1 to u1; + +--sorted_result +show grants for u1; +--sorted_result +show grants for r1; + +grant SELECT on *.* to u1; +grant INSERT on mysql.* to r1; +grant DELETE on mysql.roles_mapping to r2; +grant UPDATE on mysql.user to r3; + +create function mysql.test_func (s CHAR(20)) +returns CHAR(50) DETERMINISTIC +return concat('Test string: ',s); + +delimiter |; +create procedure mysql.test_proc (OUT param1 INT) +begin + select COUNT(*) into param1 from mysql.roles_mapping; +end| +delimiter ;| + +grant execute on function mysql.test_func to r2; +grant execute on procedure mysql.test_proc to r3; + +--error ER_NONEXISTING_PROC_GRANT +revoke execute on procedure mysql.test_proc from r2; + +--sorted_result +show grants for r1; +--sorted_result +show grants for r2; +--sorted_result +show grants for r3; + +drop function mysql.test_func; +drop procedure mysql.test_proc; + +create function mysql.test_func (s CHAR(20)) +returns CHAR(50) DETERMINISTIC +return concat('Test string: ',s); + +--sorted_result +show grants for r2; + +--connect (u1,localhost,u1,,) + +--error ER_PROCACCESS_DENIED_ERROR +select mysql.test_func("none"); +set role r1; +--error ER_PROCACCESS_DENIED_ERROR +select mysql.test_func("r1"); + +connection default; + +drop function mysql.test_func; +drop role r1, r2, r3; +drop user u1; diff --git a/mysql-test/suite/roles/flush_roles-12366.result b/mysql-test/suite/roles/flush_roles-12366.result new file mode 100644 index 00000000..043f79f8 --- /dev/null +++ b/mysql-test/suite/roles/flush_roles-12366.result @@ -0,0 +1,539 @@ +# +# MDEV-12366: FLUSH PRIVILEGES can break hierarchy of roles +# +# This testcase contains a user, who is granted a master role +# operations_cluster. operations_cluster is granted 8 different roles +# who in turn each have 4 different roles granted to them. +# +# Only the leaf roles contain privileges to access databases. +# Make sure the user has access to all databases if the master role +# is granted to him. +# +CREATE USER u; +CREATE ROLE operations_cluster; +GRANT operations_cluster TO u; +CREATE DATABASE bob_live_sg; +CREATE TABLE bob_live_sg.a (i INT(10)); +CREATE TABLE bob_live_sg.b (i INT(10)); +CREATE TABLE bob_live_sg.c (i INT(10)); +CREATE TABLE bob_live_sg.d (i INT(10)); +CREATE DATABASE oms_live_sg; +CREATE TABLE oms_live_sg.a (i INT(10)); +CREATE TABLE oms_live_sg.b (i INT(10)); +CREATE TABLE oms_live_sg.c (i INT(10)); +CREATE TABLE oms_live_sg.d (i INT(10)); +CREATE DATABASE bob_live_ph; +CREATE TABLE bob_live_ph.a (i INT(10)); +CREATE TABLE bob_live_ph.b (i INT(10)); +CREATE TABLE bob_live_ph.c (i INT(10)); +CREATE TABLE bob_live_ph.d (i INT(10)); +CREATE DATABASE oms_live_ph; +CREATE TABLE oms_live_ph.a (i INT(10)); +CREATE TABLE oms_live_ph.b (i INT(10)); +CREATE TABLE oms_live_ph.c (i INT(10)); +CREATE TABLE oms_live_ph.d (i INT(10)); +CREATE DATABASE bob_live_id; +CREATE TABLE bob_live_id.a (i INT(10)); +CREATE TABLE bob_live_id.b (i INT(10)); +CREATE TABLE bob_live_id.c (i INT(10)); +CREATE TABLE bob_live_id.d (i INT(10)); +CREATE DATABASE oms_live_id; +CREATE TABLE oms_live_id.a (i INT(10)); +CREATE TABLE oms_live_id.b (i INT(10)); +CREATE TABLE oms_live_id.c (i INT(10)); +CREATE TABLE oms_live_id.d (i INT(10)); +CREATE DATABASE bob_live_hk; +CREATE TABLE bob_live_hk.a (i INT(10)); +CREATE TABLE bob_live_hk.b (i INT(10)); +CREATE TABLE bob_live_hk.c (i INT(10)); +CREATE TABLE bob_live_hk.d (i INT(10)); +CREATE DATABASE oms_live_hk; +CREATE TABLE oms_live_hk.a (i INT(10)); +CREATE TABLE oms_live_hk.b (i INT(10)); +CREATE TABLE oms_live_hk.c (i INT(10)); +CREATE TABLE oms_live_hk.d (i INT(10)); +CREATE DATABASE bob_live_vn; +CREATE TABLE bob_live_vn.a (i INT(10)); +CREATE TABLE bob_live_vn.b (i INT(10)); +CREATE TABLE bob_live_vn.c (i INT(10)); +CREATE TABLE bob_live_vn.d (i INT(10)); +CREATE DATABASE oms_live_vn; +CREATE TABLE oms_live_vn.a (i INT(10)); +CREATE TABLE oms_live_vn.b (i INT(10)); +CREATE TABLE oms_live_vn.c (i INT(10)); +CREATE TABLE oms_live_vn.d (i INT(10)); +CREATE DATABASE bob_live_tw; +CREATE TABLE bob_live_tw.a (i INT(10)); +CREATE TABLE bob_live_tw.b (i INT(10)); +CREATE TABLE bob_live_tw.c (i INT(10)); +CREATE TABLE bob_live_tw.d (i INT(10)); +CREATE DATABASE oms_live_tw; +CREATE TABLE oms_live_tw.a (i INT(10)); +CREATE TABLE oms_live_tw.b (i INT(10)); +CREATE TABLE oms_live_tw.c (i INT(10)); +CREATE TABLE oms_live_tw.d (i INT(10)); +CREATE DATABASE bob_live_my; +CREATE TABLE bob_live_my.a (i INT(10)); +CREATE TABLE bob_live_my.b (i INT(10)); +CREATE TABLE bob_live_my.c (i INT(10)); +CREATE TABLE bob_live_my.d (i INT(10)); +CREATE DATABASE oms_live_my; +CREATE TABLE oms_live_my.a (i INT(10)); +CREATE TABLE oms_live_my.b (i INT(10)); +CREATE TABLE oms_live_my.c (i INT(10)); +CREATE TABLE oms_live_my.d (i INT(10)); +CREATE DATABASE bob_live_th; +CREATE TABLE bob_live_th.a (i INT(10)); +CREATE TABLE bob_live_th.b (i INT(10)); +CREATE TABLE bob_live_th.c (i INT(10)); +CREATE TABLE bob_live_th.d (i INT(10)); +CREATE DATABASE oms_live_th; +CREATE TABLE oms_live_th.a (i INT(10)); +CREATE TABLE oms_live_th.b (i INT(10)); +CREATE TABLE oms_live_th.c (i INT(10)); +CREATE TABLE oms_live_th.d (i INT(10)); +CREATE ROLE a_sg; +CREATE ROLE b_sg; +CREATE ROLE c_sg; +CREATE ROLE d_sg; +CREATE ROLE operations_sg; +GRANT a_sg TO operations_sg; +GRANT b_sg TO operations_sg; +GRANT c_sg TO operations_sg; +GRANT d_sg TO operations_sg; +GRANT SELECT ON bob_live_sg.a TO a_sg; +GRANT SELECT ON bob_live_sg.b TO b_sg; +GRANT SELECT ON bob_live_sg.c TO c_sg; +GRANT SELECT ON bob_live_sg.d TO d_sg; +GRANT SELECT ON oms_live_sg.a TO a_sg; +GRANT SELECT ON oms_live_sg.b TO b_sg; +GRANT SELECT ON oms_live_sg.c TO c_sg; +GRANT SELECT ON oms_live_sg.d TO d_sg; +CREATE ROLE a_ph; +CREATE ROLE b_ph; +CREATE ROLE c_ph; +CREATE ROLE d_ph; +CREATE ROLE operations_ph; +GRANT a_ph TO operations_ph; +GRANT b_ph TO operations_ph; +GRANT c_ph TO operations_ph; +GRANT d_ph TO operations_ph; +GRANT SELECT ON bob_live_ph.a TO a_ph; +GRANT SELECT ON bob_live_ph.b TO b_ph; +GRANT SELECT ON bob_live_ph.c TO c_ph; +GRANT SELECT ON bob_live_ph.d TO d_ph; +GRANT SELECT ON oms_live_ph.a TO a_ph; +GRANT SELECT ON oms_live_ph.b TO b_ph; +GRANT SELECT ON oms_live_ph.c TO c_ph; +GRANT SELECT ON oms_live_ph.d TO d_ph; +CREATE ROLE a_id; +CREATE ROLE b_id; +CREATE ROLE c_id; +CREATE ROLE d_id; +CREATE ROLE operations_id; +GRANT a_id TO operations_id; +GRANT b_id TO operations_id; +GRANT c_id TO operations_id; +GRANT d_id TO operations_id; +GRANT SELECT ON bob_live_id.a TO a_id; +GRANT SELECT ON bob_live_id.b TO b_id; +GRANT SELECT ON bob_live_id.c TO c_id; +GRANT SELECT ON bob_live_id.d TO d_id; +GRANT SELECT ON oms_live_id.a TO a_id; +GRANT SELECT ON oms_live_id.b TO b_id; +GRANT SELECT ON oms_live_id.c TO c_id; +GRANT SELECT ON oms_live_id.d TO d_id; +CREATE ROLE a_hk; +CREATE ROLE b_hk; +CREATE ROLE c_hk; +CREATE ROLE d_hk; +CREATE ROLE operations_hk; +GRANT a_hk TO operations_hk; +GRANT b_hk TO operations_hk; +GRANT c_hk TO operations_hk; +GRANT d_hk TO operations_hk; +GRANT SELECT ON bob_live_hk.a TO a_hk; +GRANT SELECT ON bob_live_hk.b TO b_hk; +GRANT SELECT ON bob_live_hk.c TO c_hk; +GRANT SELECT ON bob_live_hk.d TO d_hk; +GRANT SELECT ON oms_live_hk.a TO a_hk; +GRANT SELECT ON oms_live_hk.b TO b_hk; +GRANT SELECT ON oms_live_hk.c TO c_hk; +GRANT SELECT ON oms_live_hk.d TO d_hk; +CREATE ROLE a_vn; +CREATE ROLE b_vn; +CREATE ROLE c_vn; +CREATE ROLE d_vn; +CREATE ROLE operations_vn; +GRANT a_vn TO operations_vn; +GRANT b_vn TO operations_vn; +GRANT c_vn TO operations_vn; +GRANT d_vn TO operations_vn; +GRANT SELECT ON bob_live_vn.a TO a_vn; +GRANT SELECT ON bob_live_vn.b TO b_vn; +GRANT SELECT ON bob_live_vn.c TO c_vn; +GRANT SELECT ON bob_live_vn.d TO d_vn; +GRANT SELECT ON oms_live_vn.a TO a_vn; +GRANT SELECT ON oms_live_vn.b TO b_vn; +GRANT SELECT ON oms_live_vn.c TO c_vn; +GRANT SELECT ON oms_live_vn.d TO d_vn; +CREATE ROLE a_tw; +CREATE ROLE b_tw; +CREATE ROLE c_tw; +CREATE ROLE d_tw; +CREATE ROLE operations_tw; +GRANT a_tw TO operations_tw; +GRANT b_tw TO operations_tw; +GRANT c_tw TO operations_tw; +GRANT d_tw TO operations_tw; +GRANT SELECT ON bob_live_tw.a TO a_tw; +GRANT SELECT ON bob_live_tw.b TO b_tw; +GRANT SELECT ON bob_live_tw.c TO c_tw; +GRANT SELECT ON bob_live_tw.d TO d_tw; +GRANT SELECT ON oms_live_tw.a TO a_tw; +GRANT SELECT ON oms_live_tw.b TO b_tw; +GRANT SELECT ON oms_live_tw.c TO c_tw; +GRANT SELECT ON oms_live_tw.d TO d_tw; +CREATE ROLE a_my; +CREATE ROLE b_my; +CREATE ROLE c_my; +CREATE ROLE d_my; +CREATE ROLE operations_my; +GRANT a_my TO operations_my; +GRANT b_my TO operations_my; +GRANT c_my TO operations_my; +GRANT d_my TO operations_my; +GRANT SELECT ON bob_live_my.a TO a_my; +GRANT SELECT ON bob_live_my.b TO b_my; +GRANT SELECT ON bob_live_my.c TO c_my; +GRANT SELECT ON bob_live_my.d TO d_my; +GRANT SELECT ON oms_live_my.a TO a_my; +GRANT SELECT ON oms_live_my.b TO b_my; +GRANT SELECT ON oms_live_my.c TO c_my; +GRANT SELECT ON oms_live_my.d TO d_my; +CREATE ROLE a_th; +CREATE ROLE b_th; +CREATE ROLE c_th; +CREATE ROLE d_th; +CREATE ROLE operations_th; +GRANT a_th TO operations_th; +GRANT b_th TO operations_th; +GRANT c_th TO operations_th; +GRANT d_th TO operations_th; +GRANT SELECT ON bob_live_th.a TO a_th; +GRANT SELECT ON bob_live_th.b TO b_th; +GRANT SELECT ON bob_live_th.c TO c_th; +GRANT SELECT ON bob_live_th.d TO d_th; +GRANT SELECT ON oms_live_th.a TO a_th; +GRANT SELECT ON oms_live_th.b TO b_th; +GRANT SELECT ON oms_live_th.c TO c_th; +GRANT SELECT ON oms_live_th.d TO d_th; +GRANT operations_sg TO operations_cluster; +GRANT operations_ph TO operations_cluster; +GRANT operations_id TO operations_cluster; +GRANT operations_hk TO operations_cluster; +GRANT operations_vn TO operations_cluster; +GRANT operations_tw TO operations_cluster; +GRANT operations_my TO operations_cluster; +GRANT operations_th TO operations_cluster; +connect con1,localhost,u,,; +SHOW DATABASES; +Database +information_schema +SET ROLE operations_cluster; +SHOW DATABASES; +Database +bob_live_hk +bob_live_id +bob_live_my +bob_live_ph +bob_live_sg +bob_live_th +bob_live_tw +bob_live_vn +information_schema +oms_live_hk +oms_live_id +oms_live_my +oms_live_ph +oms_live_sg +oms_live_th +oms_live_tw +oms_live_vn +SELECT COUNT(1) FROM oms_live_sg.a; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_sg.b; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_sg.c; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_sg.d; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_ph.a; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_ph.b; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_ph.c; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_ph.d; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_id.a; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_id.b; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_id.c; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_id.d; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_hk.a; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_hk.b; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_hk.c; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_hk.d; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_vn.a; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_vn.b; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_vn.c; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_vn.d; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_tw.a; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_tw.b; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_tw.c; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_tw.d; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_my.a; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_my.b; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_my.c; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_my.d; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_th.a; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_th.b; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_th.c; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_th.d; +COUNT(1) +0 +connect con2,localhost,root,,; +FLUSH PRIVILEGES; +connect con3,localhost,u,,; +SHOW DATABASES; +Database +information_schema +SET ROLE operations_cluster; +SHOW DATABASES; +Database +bob_live_hk +bob_live_id +bob_live_my +bob_live_ph +bob_live_sg +bob_live_th +bob_live_tw +bob_live_vn +information_schema +oms_live_hk +oms_live_id +oms_live_my +oms_live_ph +oms_live_sg +oms_live_th +oms_live_tw +oms_live_vn +SELECT COUNT(1) FROM oms_live_sg.a; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_sg.b; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_sg.c; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_sg.d; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_ph.a; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_ph.b; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_ph.c; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_ph.d; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_id.a; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_id.b; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_id.c; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_id.d; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_hk.a; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_hk.b; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_hk.c; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_hk.d; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_vn.a; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_vn.b; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_vn.c; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_vn.d; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_tw.a; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_tw.b; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_tw.c; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_tw.d; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_my.a; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_my.b; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_my.c; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_my.d; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_th.a; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_th.b; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_th.c; +COUNT(1) +0 +SELECT COUNT(1) FROM oms_live_th.d; +COUNT(1) +0 +connect con4,localhost,root,,; +DROP DATABASE bob_live_sg; +DROP DATABASE oms_live_sg; +DROP DATABASE bob_live_ph; +DROP DATABASE oms_live_ph; +DROP DATABASE bob_live_id; +DROP DATABASE oms_live_id; +DROP DATABASE bob_live_hk; +DROP DATABASE oms_live_hk; +DROP DATABASE bob_live_vn; +DROP DATABASE oms_live_vn; +DROP DATABASE bob_live_tw; +DROP DATABASE oms_live_tw; +DROP DATABASE bob_live_my; +DROP DATABASE oms_live_my; +DROP DATABASE bob_live_th; +DROP DATABASE oms_live_th; +DROP ROLE operations_sg; +DROP ROLE a_sg; +DROP ROLE b_sg; +DROP ROLE c_sg; +DROP ROLE d_sg; +DROP ROLE operations_ph; +DROP ROLE a_ph; +DROP ROLE b_ph; +DROP ROLE c_ph; +DROP ROLE d_ph; +DROP ROLE operations_id; +DROP ROLE a_id; +DROP ROLE b_id; +DROP ROLE c_id; +DROP ROLE d_id; +DROP ROLE operations_hk; +DROP ROLE a_hk; +DROP ROLE b_hk; +DROP ROLE c_hk; +DROP ROLE d_hk; +DROP ROLE operations_vn; +DROP ROLE a_vn; +DROP ROLE b_vn; +DROP ROLE c_vn; +DROP ROLE d_vn; +DROP ROLE operations_tw; +DROP ROLE a_tw; +DROP ROLE b_tw; +DROP ROLE c_tw; +DROP ROLE d_tw; +DROP ROLE operations_my; +DROP ROLE a_my; +DROP ROLE b_my; +DROP ROLE c_my; +DROP ROLE d_my; +DROP ROLE operations_th; +DROP ROLE a_th; +DROP ROLE b_th; +DROP ROLE c_th; +DROP ROLE d_th; +DROP USER u; +DROP ROLE operations_cluster; diff --git a/mysql-test/suite/roles/flush_roles-12366.test b/mysql-test/suite/roles/flush_roles-12366.test new file mode 100644 index 00000000..343ac4ab --- /dev/null +++ b/mysql-test/suite/roles/flush_roles-12366.test @@ -0,0 +1,379 @@ +--source include/not_embedded.inc +--echo # +--echo # MDEV-12366: FLUSH PRIVILEGES can break hierarchy of roles +--echo # +--echo # This testcase contains a user, who is granted a master role +--echo # operations_cluster. operations_cluster is granted 8 different roles +--echo # who in turn each have 4 different roles granted to them. +--echo # +--echo # Only the leaf roles contain privileges to access databases. +--echo # Make sure the user has access to all databases if the master role +--echo # is granted to him. +--echo # +CREATE USER u; +CREATE ROLE operations_cluster; +GRANT operations_cluster TO u; +CREATE DATABASE bob_live_sg; +CREATE TABLE bob_live_sg.a (i INT(10)); +CREATE TABLE bob_live_sg.b (i INT(10)); +CREATE TABLE bob_live_sg.c (i INT(10)); +CREATE TABLE bob_live_sg.d (i INT(10)); +CREATE DATABASE oms_live_sg; +CREATE TABLE oms_live_sg.a (i INT(10)); +CREATE TABLE oms_live_sg.b (i INT(10)); +CREATE TABLE oms_live_sg.c (i INT(10)); +CREATE TABLE oms_live_sg.d (i INT(10)); +CREATE DATABASE bob_live_ph; +CREATE TABLE bob_live_ph.a (i INT(10)); +CREATE TABLE bob_live_ph.b (i INT(10)); +CREATE TABLE bob_live_ph.c (i INT(10)); +CREATE TABLE bob_live_ph.d (i INT(10)); +CREATE DATABASE oms_live_ph; +CREATE TABLE oms_live_ph.a (i INT(10)); +CREATE TABLE oms_live_ph.b (i INT(10)); +CREATE TABLE oms_live_ph.c (i INT(10)); +CREATE TABLE oms_live_ph.d (i INT(10)); +CREATE DATABASE bob_live_id; +CREATE TABLE bob_live_id.a (i INT(10)); +CREATE TABLE bob_live_id.b (i INT(10)); +CREATE TABLE bob_live_id.c (i INT(10)); +CREATE TABLE bob_live_id.d (i INT(10)); +CREATE DATABASE oms_live_id; +CREATE TABLE oms_live_id.a (i INT(10)); +CREATE TABLE oms_live_id.b (i INT(10)); +CREATE TABLE oms_live_id.c (i INT(10)); +CREATE TABLE oms_live_id.d (i INT(10)); +CREATE DATABASE bob_live_hk; +CREATE TABLE bob_live_hk.a (i INT(10)); +CREATE TABLE bob_live_hk.b (i INT(10)); +CREATE TABLE bob_live_hk.c (i INT(10)); +CREATE TABLE bob_live_hk.d (i INT(10)); +CREATE DATABASE oms_live_hk; +CREATE TABLE oms_live_hk.a (i INT(10)); +CREATE TABLE oms_live_hk.b (i INT(10)); +CREATE TABLE oms_live_hk.c (i INT(10)); +CREATE TABLE oms_live_hk.d (i INT(10)); +CREATE DATABASE bob_live_vn; +CREATE TABLE bob_live_vn.a (i INT(10)); +CREATE TABLE bob_live_vn.b (i INT(10)); +CREATE TABLE bob_live_vn.c (i INT(10)); +CREATE TABLE bob_live_vn.d (i INT(10)); +CREATE DATABASE oms_live_vn; +CREATE TABLE oms_live_vn.a (i INT(10)); +CREATE TABLE oms_live_vn.b (i INT(10)); +CREATE TABLE oms_live_vn.c (i INT(10)); +CREATE TABLE oms_live_vn.d (i INT(10)); +CREATE DATABASE bob_live_tw; +CREATE TABLE bob_live_tw.a (i INT(10)); +CREATE TABLE bob_live_tw.b (i INT(10)); +CREATE TABLE bob_live_tw.c (i INT(10)); +CREATE TABLE bob_live_tw.d (i INT(10)); +CREATE DATABASE oms_live_tw; +CREATE TABLE oms_live_tw.a (i INT(10)); +CREATE TABLE oms_live_tw.b (i INT(10)); +CREATE TABLE oms_live_tw.c (i INT(10)); +CREATE TABLE oms_live_tw.d (i INT(10)); +CREATE DATABASE bob_live_my; +CREATE TABLE bob_live_my.a (i INT(10)); +CREATE TABLE bob_live_my.b (i INT(10)); +CREATE TABLE bob_live_my.c (i INT(10)); +CREATE TABLE bob_live_my.d (i INT(10)); +CREATE DATABASE oms_live_my; +CREATE TABLE oms_live_my.a (i INT(10)); +CREATE TABLE oms_live_my.b (i INT(10)); +CREATE TABLE oms_live_my.c (i INT(10)); +CREATE TABLE oms_live_my.d (i INT(10)); +CREATE DATABASE bob_live_th; +CREATE TABLE bob_live_th.a (i INT(10)); +CREATE TABLE bob_live_th.b (i INT(10)); +CREATE TABLE bob_live_th.c (i INT(10)); +CREATE TABLE bob_live_th.d (i INT(10)); +CREATE DATABASE oms_live_th; +CREATE TABLE oms_live_th.a (i INT(10)); +CREATE TABLE oms_live_th.b (i INT(10)); +CREATE TABLE oms_live_th.c (i INT(10)); +CREATE TABLE oms_live_th.d (i INT(10)); +CREATE ROLE a_sg; +CREATE ROLE b_sg; +CREATE ROLE c_sg; +CREATE ROLE d_sg; +CREATE ROLE operations_sg; +GRANT a_sg TO operations_sg; +GRANT b_sg TO operations_sg; +GRANT c_sg TO operations_sg; +GRANT d_sg TO operations_sg; +GRANT SELECT ON bob_live_sg.a TO a_sg; +GRANT SELECT ON bob_live_sg.b TO b_sg; +GRANT SELECT ON bob_live_sg.c TO c_sg; +GRANT SELECT ON bob_live_sg.d TO d_sg; +GRANT SELECT ON oms_live_sg.a TO a_sg; +GRANT SELECT ON oms_live_sg.b TO b_sg; +GRANT SELECT ON oms_live_sg.c TO c_sg; +GRANT SELECT ON oms_live_sg.d TO d_sg; +CREATE ROLE a_ph; +CREATE ROLE b_ph; +CREATE ROLE c_ph; +CREATE ROLE d_ph; +CREATE ROLE operations_ph; +GRANT a_ph TO operations_ph; +GRANT b_ph TO operations_ph; +GRANT c_ph TO operations_ph; +GRANT d_ph TO operations_ph; +GRANT SELECT ON bob_live_ph.a TO a_ph; +GRANT SELECT ON bob_live_ph.b TO b_ph; +GRANT SELECT ON bob_live_ph.c TO c_ph; +GRANT SELECT ON bob_live_ph.d TO d_ph; +GRANT SELECT ON oms_live_ph.a TO a_ph; +GRANT SELECT ON oms_live_ph.b TO b_ph; +GRANT SELECT ON oms_live_ph.c TO c_ph; +GRANT SELECT ON oms_live_ph.d TO d_ph; +CREATE ROLE a_id; +CREATE ROLE b_id; +CREATE ROLE c_id; +CREATE ROLE d_id; +CREATE ROLE operations_id; +GRANT a_id TO operations_id; +GRANT b_id TO operations_id; +GRANT c_id TO operations_id; +GRANT d_id TO operations_id; +GRANT SELECT ON bob_live_id.a TO a_id; +GRANT SELECT ON bob_live_id.b TO b_id; +GRANT SELECT ON bob_live_id.c TO c_id; +GRANT SELECT ON bob_live_id.d TO d_id; +GRANT SELECT ON oms_live_id.a TO a_id; +GRANT SELECT ON oms_live_id.b TO b_id; +GRANT SELECT ON oms_live_id.c TO c_id; +GRANT SELECT ON oms_live_id.d TO d_id; +CREATE ROLE a_hk; +CREATE ROLE b_hk; +CREATE ROLE c_hk; +CREATE ROLE d_hk; +CREATE ROLE operations_hk; +GRANT a_hk TO operations_hk; +GRANT b_hk TO operations_hk; +GRANT c_hk TO operations_hk; +GRANT d_hk TO operations_hk; +GRANT SELECT ON bob_live_hk.a TO a_hk; +GRANT SELECT ON bob_live_hk.b TO b_hk; +GRANT SELECT ON bob_live_hk.c TO c_hk; +GRANT SELECT ON bob_live_hk.d TO d_hk; +GRANT SELECT ON oms_live_hk.a TO a_hk; +GRANT SELECT ON oms_live_hk.b TO b_hk; +GRANT SELECT ON oms_live_hk.c TO c_hk; +GRANT SELECT ON oms_live_hk.d TO d_hk; +CREATE ROLE a_vn; +CREATE ROLE b_vn; +CREATE ROLE c_vn; +CREATE ROLE d_vn; +CREATE ROLE operations_vn; +GRANT a_vn TO operations_vn; +GRANT b_vn TO operations_vn; +GRANT c_vn TO operations_vn; +GRANT d_vn TO operations_vn; +GRANT SELECT ON bob_live_vn.a TO a_vn; +GRANT SELECT ON bob_live_vn.b TO b_vn; +GRANT SELECT ON bob_live_vn.c TO c_vn; +GRANT SELECT ON bob_live_vn.d TO d_vn; +GRANT SELECT ON oms_live_vn.a TO a_vn; +GRANT SELECT ON oms_live_vn.b TO b_vn; +GRANT SELECT ON oms_live_vn.c TO c_vn; +GRANT SELECT ON oms_live_vn.d TO d_vn; +CREATE ROLE a_tw; +CREATE ROLE b_tw; +CREATE ROLE c_tw; +CREATE ROLE d_tw; +CREATE ROLE operations_tw; +GRANT a_tw TO operations_tw; +GRANT b_tw TO operations_tw; +GRANT c_tw TO operations_tw; +GRANT d_tw TO operations_tw; +GRANT SELECT ON bob_live_tw.a TO a_tw; +GRANT SELECT ON bob_live_tw.b TO b_tw; +GRANT SELECT ON bob_live_tw.c TO c_tw; +GRANT SELECT ON bob_live_tw.d TO d_tw; +GRANT SELECT ON oms_live_tw.a TO a_tw; +GRANT SELECT ON oms_live_tw.b TO b_tw; +GRANT SELECT ON oms_live_tw.c TO c_tw; +GRANT SELECT ON oms_live_tw.d TO d_tw; +CREATE ROLE a_my; +CREATE ROLE b_my; +CREATE ROLE c_my; +CREATE ROLE d_my; +CREATE ROLE operations_my; +GRANT a_my TO operations_my; +GRANT b_my TO operations_my; +GRANT c_my TO operations_my; +GRANT d_my TO operations_my; +GRANT SELECT ON bob_live_my.a TO a_my; +GRANT SELECT ON bob_live_my.b TO b_my; +GRANT SELECT ON bob_live_my.c TO c_my; +GRANT SELECT ON bob_live_my.d TO d_my; +GRANT SELECT ON oms_live_my.a TO a_my; +GRANT SELECT ON oms_live_my.b TO b_my; +GRANT SELECT ON oms_live_my.c TO c_my; +GRANT SELECT ON oms_live_my.d TO d_my; +CREATE ROLE a_th; +CREATE ROLE b_th; +CREATE ROLE c_th; +CREATE ROLE d_th; +CREATE ROLE operations_th; +GRANT a_th TO operations_th; +GRANT b_th TO operations_th; +GRANT c_th TO operations_th; +GRANT d_th TO operations_th; +GRANT SELECT ON bob_live_th.a TO a_th; +GRANT SELECT ON bob_live_th.b TO b_th; +GRANT SELECT ON bob_live_th.c TO c_th; +GRANT SELECT ON bob_live_th.d TO d_th; +GRANT SELECT ON oms_live_th.a TO a_th; +GRANT SELECT ON oms_live_th.b TO b_th; +GRANT SELECT ON oms_live_th.c TO c_th; +GRANT SELECT ON oms_live_th.d TO d_th; +GRANT operations_sg TO operations_cluster; +GRANT operations_ph TO operations_cluster; +GRANT operations_id TO operations_cluster; +GRANT operations_hk TO operations_cluster; +GRANT operations_vn TO operations_cluster; +GRANT operations_tw TO operations_cluster; +GRANT operations_my TO operations_cluster; +GRANT operations_th TO operations_cluster; + +connect(con1,localhost,u,,); +SHOW DATABASES; +SET ROLE operations_cluster; +SHOW DATABASES; +SELECT COUNT(1) FROM oms_live_sg.a; +SELECT COUNT(1) FROM oms_live_sg.b; +SELECT COUNT(1) FROM oms_live_sg.c; +SELECT COUNT(1) FROM oms_live_sg.d; +SELECT COUNT(1) FROM oms_live_ph.a; +SELECT COUNT(1) FROM oms_live_ph.b; +SELECT COUNT(1) FROM oms_live_ph.c; +SELECT COUNT(1) FROM oms_live_ph.d; +SELECT COUNT(1) FROM oms_live_id.a; +SELECT COUNT(1) FROM oms_live_id.b; +SELECT COUNT(1) FROM oms_live_id.c; +SELECT COUNT(1) FROM oms_live_id.d; +SELECT COUNT(1) FROM oms_live_hk.a; +SELECT COUNT(1) FROM oms_live_hk.b; +SELECT COUNT(1) FROM oms_live_hk.c; +SELECT COUNT(1) FROM oms_live_hk.d; +SELECT COUNT(1) FROM oms_live_vn.a; +SELECT COUNT(1) FROM oms_live_vn.b; +SELECT COUNT(1) FROM oms_live_vn.c; +SELECT COUNT(1) FROM oms_live_vn.d; +SELECT COUNT(1) FROM oms_live_tw.a; +SELECT COUNT(1) FROM oms_live_tw.b; +SELECT COUNT(1) FROM oms_live_tw.c; +SELECT COUNT(1) FROM oms_live_tw.d; +SELECT COUNT(1) FROM oms_live_my.a; +SELECT COUNT(1) FROM oms_live_my.b; +SELECT COUNT(1) FROM oms_live_my.c; +SELECT COUNT(1) FROM oms_live_my.d; +SELECT COUNT(1) FROM oms_live_th.a; +SELECT COUNT(1) FROM oms_live_th.b; +SELECT COUNT(1) FROM oms_live_th.c; +SELECT COUNT(1) FROM oms_live_th.d; + + +connect(con2,localhost,root,,); +FLUSH PRIVILEGES; + +connect(con3,localhost,u,,); +SHOW DATABASES; +SET ROLE operations_cluster; +SHOW DATABASES; +SELECT COUNT(1) FROM oms_live_sg.a; +SELECT COUNT(1) FROM oms_live_sg.b; +SELECT COUNT(1) FROM oms_live_sg.c; +SELECT COUNT(1) FROM oms_live_sg.d; +SELECT COUNT(1) FROM oms_live_ph.a; +SELECT COUNT(1) FROM oms_live_ph.b; +SELECT COUNT(1) FROM oms_live_ph.c; +SELECT COUNT(1) FROM oms_live_ph.d; +SELECT COUNT(1) FROM oms_live_id.a; +SELECT COUNT(1) FROM oms_live_id.b; +SELECT COUNT(1) FROM oms_live_id.c; +SELECT COUNT(1) FROM oms_live_id.d; +SELECT COUNT(1) FROM oms_live_hk.a; +SELECT COUNT(1) FROM oms_live_hk.b; +SELECT COUNT(1) FROM oms_live_hk.c; +SELECT COUNT(1) FROM oms_live_hk.d; +SELECT COUNT(1) FROM oms_live_vn.a; +SELECT COUNT(1) FROM oms_live_vn.b; +SELECT COUNT(1) FROM oms_live_vn.c; +SELECT COUNT(1) FROM oms_live_vn.d; +SELECT COUNT(1) FROM oms_live_tw.a; +SELECT COUNT(1) FROM oms_live_tw.b; +SELECT COUNT(1) FROM oms_live_tw.c; +SELECT COUNT(1) FROM oms_live_tw.d; +SELECT COUNT(1) FROM oms_live_my.a; +SELECT COUNT(1) FROM oms_live_my.b; +SELECT COUNT(1) FROM oms_live_my.c; +SELECT COUNT(1) FROM oms_live_my.d; +SELECT COUNT(1) FROM oms_live_th.a; +SELECT COUNT(1) FROM oms_live_th.b; +SELECT COUNT(1) FROM oms_live_th.c; +SELECT COUNT(1) FROM oms_live_th.d; + + +connect(con4,localhost,root,,); + +DROP DATABASE bob_live_sg; +DROP DATABASE oms_live_sg; +DROP DATABASE bob_live_ph; +DROP DATABASE oms_live_ph; +DROP DATABASE bob_live_id; +DROP DATABASE oms_live_id; +DROP DATABASE bob_live_hk; +DROP DATABASE oms_live_hk; +DROP DATABASE bob_live_vn; +DROP DATABASE oms_live_vn; +DROP DATABASE bob_live_tw; +DROP DATABASE oms_live_tw; +DROP DATABASE bob_live_my; +DROP DATABASE oms_live_my; +DROP DATABASE bob_live_th; +DROP DATABASE oms_live_th; +DROP ROLE operations_sg; +DROP ROLE a_sg; +DROP ROLE b_sg; +DROP ROLE c_sg; +DROP ROLE d_sg; +DROP ROLE operations_ph; +DROP ROLE a_ph; +DROP ROLE b_ph; +DROP ROLE c_ph; +DROP ROLE d_ph; +DROP ROLE operations_id; +DROP ROLE a_id; +DROP ROLE b_id; +DROP ROLE c_id; +DROP ROLE d_id; +DROP ROLE operations_hk; +DROP ROLE a_hk; +DROP ROLE b_hk; +DROP ROLE c_hk; +DROP ROLE d_hk; +DROP ROLE operations_vn; +DROP ROLE a_vn; +DROP ROLE b_vn; +DROP ROLE c_vn; +DROP ROLE d_vn; +DROP ROLE operations_tw; +DROP ROLE a_tw; +DROP ROLE b_tw; +DROP ROLE c_tw; +DROP ROLE d_tw; +DROP ROLE operations_my; +DROP ROLE a_my; +DROP ROLE b_my; +DROP ROLE c_my; +DROP ROLE d_my; +DROP ROLE operations_th; +DROP ROLE a_th; +DROP ROLE b_th; +DROP ROLE c_th; +DROP ROLE d_th; +DROP USER u; +DROP ROLE operations_cluster; diff --git a/mysql-test/suite/roles/flush_roles-17898.result b/mysql-test/suite/roles/flush_roles-17898.result new file mode 100644 index 00000000..85aeca36 --- /dev/null +++ b/mysql-test/suite/roles/flush_roles-17898.result @@ -0,0 +1,36 @@ +use mysql; +insert db (db,user,select_priv) values ('foo','dwr_foo','Y'), ('bar','dwr_bar','Y'); +insert roles_mapping (user,role) values ('dwr_qux_dev','dwr_foo'),('dwr_qux_dev','dwr_bar'); +insert global_priv values ('','dwr_foo','{"is_role":true}'), ('','dwr_bar','{"is_role":true}'), +('','dwr_qux_dev','{"access":16384,"is_role":true}'); +flush privileges; +drop role dwr_foo; +drop role dwr_bar; +drop role dwr_qux_dev; +use test; +create table db_copy as select * from mysql.db; +delete from mysql.db; +flush privileges; +create user u1@localhost; +create role r1; +create role r2; +grant r1 to u1@localhost; +grant select on test.* to r2; +grant select on m_.* to r2; +grant r2 to r1; +show grants for u1@localhost; +Grants for u1@localhost +GRANT `r1` TO `u1`@`localhost` +GRANT USAGE ON *.* TO `u1`@`localhost` +show grants for r1; +Grants for r1 +GRANT `r2` TO `r1` +GRANT USAGE ON *.* TO `r1` +GRANT USAGE ON *.* TO `r2` +GRANT SELECT ON `test`.* TO `r2` +GRANT SELECT ON `m_`.* TO `r2` +drop user u1@localhost; +drop role r1, r2; +insert mysql.db select * from db_copy; +flush privileges; +drop table db_copy; diff --git a/mysql-test/suite/roles/flush_roles-17898.test b/mysql-test/suite/roles/flush_roles-17898.test new file mode 100644 index 00000000..8dc55a87 --- /dev/null +++ b/mysql-test/suite/roles/flush_roles-17898.test @@ -0,0 +1,37 @@ +source include/not_embedded.inc; +# +# MDEV-17898 FLUSH PRIVILEGES crashes server with segfault +# +use mysql; +insert db (db,user,select_priv) values ('foo','dwr_foo','Y'), ('bar','dwr_bar','Y'); +insert roles_mapping (user,role) values ('dwr_qux_dev','dwr_foo'),('dwr_qux_dev','dwr_bar'); +insert global_priv values ('','dwr_foo','{"is_role":true}'), ('','dwr_bar','{"is_role":true}'), + ('','dwr_qux_dev','{"access":16384,"is_role":true}'); +flush privileges; +drop role dwr_foo; +drop role dwr_bar; +drop role dwr_qux_dev; +use test; + +# +# MDEV-18298 Crashes server with segfault during role grants +# +create table db_copy as select * from mysql.db; +delete from mysql.db; +flush privileges; + +create user u1@localhost; +create role r1; +create role r2; +grant r1 to u1@localhost; +grant select on test.* to r2; +grant select on m_.* to r2; +grant r2 to r1; +show grants for u1@localhost; +show grants for r1; +drop user u1@localhost; +drop role r1, r2; + +insert mysql.db select * from db_copy; +flush privileges; +drop table db_copy; diff --git a/mysql-test/suite/roles/grant-5771.result b/mysql-test/suite/roles/grant-5771.result new file mode 100644 index 00000000..14e033f4 --- /dev/null +++ b/mysql-test/suite/roles/grant-5771.result @@ -0,0 +1,36 @@ +create database mysqltest1; +create database mysqltest2; +create user foo@localhost; +create role r1, r2; +grant all on mysqltest1.* to r1; +grant all on mysqltest2.* to r2; +grant r1 to r2; +grant r2 to foo@localhost; +connect foo,localhost,foo,,; +select current_user; +current_user +foo@localhost +show tables in mysqltest1; +ERROR 42000: Access denied for user 'foo'@'localhost' to database 'mysqltest1' +show tables in mysqltest2; +ERROR 42000: Access denied for user 'foo'@'localhost' to database 'mysqltest2' +set role r2; +show tables in mysqltest1; +Tables_in_mysqltest1 +show tables in mysqltest2; +Tables_in_mysqltest2 +show grants; +Grants for foo@localhost +GRANT `r2` TO `foo`@`localhost` +GRANT USAGE ON *.* TO `foo`@`localhost` +GRANT `r1` TO `r2` +GRANT USAGE ON *.* TO `r2` +GRANT ALL PRIVILEGES ON `mysqltest2`.* TO `r2` +GRANT USAGE ON *.* TO `r1` +GRANT ALL PRIVILEGES ON `mysqltest1`.* TO `r1` +connection default; +drop user foo@localhost; +drop role r1; +drop role r2; +drop database mysqltest1; +drop database mysqltest2; diff --git a/mysql-test/suite/roles/grant-5771.test b/mysql-test/suite/roles/grant-5771.test new file mode 100644 index 00000000..3c8f5d2f --- /dev/null +++ b/mysql-test/suite/roles/grant-5771.test @@ -0,0 +1,32 @@ +# +# MDEV-5771 Privileges acquired via roles depend on the order of granting +# +--source include/not_embedded.inc + +create database mysqltest1; +create database mysqltest2; + +create user foo@localhost; +create role r1, r2; +grant all on mysqltest1.* to r1; +grant all on mysqltest2.* to r2; +grant r1 to r2; +grant r2 to foo@localhost; + +--connect (foo,localhost,foo,,) +select current_user; +--error ER_DBACCESS_DENIED_ERROR +show tables in mysqltest1; +--error ER_DBACCESS_DENIED_ERROR +show tables in mysqltest2; +set role r2; +show tables in mysqltest1; +show tables in mysqltest2; +show grants; + +connection default; +drop user foo@localhost; +drop role r1; +drop role r2; +drop database mysqltest1; +drop database mysqltest2; diff --git a/mysql-test/suite/roles/grant_empty.result b/mysql-test/suite/roles/grant_empty.result new file mode 100644 index 00000000..2e454299 --- /dev/null +++ b/mysql-test/suite/roles/grant_empty.result @@ -0,0 +1,16 @@ +grant '' to foo@localhost; +ERROR OP000: Invalid role specification `` +create user ''@localhost; +create role r1; +grant r1 to ''@localhost; +connect con1,localhost,nonexisting_user,,; +select current_user; +current_user +@localhost +show grants; +Grants for @localhost +GRANT `r1` TO ``@`localhost` +GRANT USAGE ON *.* TO ``@`localhost` +connection default; +drop role r1; +drop user ''@localhost; diff --git a/mysql-test/suite/roles/grant_empty.test b/mysql-test/suite/roles/grant_empty.test new file mode 100644 index 00000000..e419fffa --- /dev/null +++ b/mysql-test/suite/roles/grant_empty.test @@ -0,0 +1,23 @@ +# +# MDEV-5668 Assertion `granted_role->is_role()' fails on granting role with empty name +# +--error ER_INVALID_ROLE +grant '' to foo@localhost; + +# +# MDEV-5238 Server crashes in find_role_grant_pair on SHOW GRANTS for an anonymous user +# +--source include/not_embedded.inc + +create user ''@localhost; +create role r1; +grant r1 to ''@localhost; + +--connect (con1,localhost,nonexisting_user,,) +select current_user; +show grants; + +connection default; +drop role r1; +drop user ''@localhost; + diff --git a/mysql-test/suite/roles/grant_proxy-5526.result b/mysql-test/suite/roles/grant_proxy-5526.result new file mode 100644 index 00000000..8bfa8e39 --- /dev/null +++ b/mysql-test/suite/roles/grant_proxy-5526.result @@ -0,0 +1,9 @@ +create role r1; +create user user; +grant proxy on r1 to user; +show grants for user; +Grants for user@% +GRANT USAGE ON *.* TO `user`@`%` +GRANT PROXY ON 'r1'@'%' TO 'user'@'%' +drop user user; +drop role r1; diff --git a/mysql-test/suite/roles/grant_proxy-5526.test b/mysql-test/suite/roles/grant_proxy-5526.test new file mode 100644 index 00000000..eadc763b --- /dev/null +++ b/mysql-test/suite/roles/grant_proxy-5526.test @@ -0,0 +1,11 @@ +--source include/not_embedded.inc +# +# MDEV-5526 Assertion `proxied_user->host.length' fails on GRANT PROXY ON <role> +# +create role r1; +create user user; +grant proxy on r1 to user; +show grants for user; +drop user user; +drop role r1; + diff --git a/mysql-test/suite/roles/grant_revoke_current.result b/mysql-test/suite/roles/grant_revoke_current.result new file mode 100644 index 00000000..329cab64 --- /dev/null +++ b/mysql-test/suite/roles/grant_revoke_current.result @@ -0,0 +1,44 @@ +select priv into @root_priv from mysql.global_priv where user='root' and host='localhost'; +grant select on *.* to current_role; +ERROR 0L000: Invalid definer +revoke select on *.* from current_role; +ERROR 0L000: Invalid definer +revoke all, grant option from current_role; +ERROR 0L000: Invalid definer +create role r1; +grant insert on test.* to r1; +grant r1 to current_user; +set role r1; +select current_role(); +current_role() +r1 +grant select on *.* to current_role; +show grants for current_role; +Grants for r1 +GRANT SELECT ON *.* TO `r1` +GRANT INSERT ON `test`.* TO `r1` +revoke insert on test.* from current_role; +show grants for current_role; +Grants for r1 +GRANT SELECT ON *.* TO `r1` +revoke all, grant option from current_role; +show grants for current_role; +Grants for r1 +GRANT USAGE ON *.* TO `r1` +set password=password('foobar'); +show grants; +Grants for root@localhost +GRANT `r1` TO `root`@`localhost` WITH ADMIN OPTION +GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` IDENTIFIED BY PASSWORD '*9B500343BC52E2911172EB52AE5CF4847604C6E5' WITH GRANT OPTION +GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION +GRANT USAGE ON *.* TO `r1` +grant r1 to current_user() identified by 'barfoo'; +show grants; +Grants for root@localhost +GRANT `r1` TO `root`@`localhost` WITH ADMIN OPTION +GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` IDENTIFIED BY PASSWORD '*343915A8181B5728EADBDC73E1F7E6B0C3998483' WITH GRANT OPTION +GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION +GRANT USAGE ON *.* TO `r1` +set password=''; +drop role r1; +update mysql.global_priv set priv=@root_priv where user='root' and host='localhost'; diff --git a/mysql-test/suite/roles/grant_revoke_current.test b/mysql-test/suite/roles/grant_revoke_current.test new file mode 100644 index 00000000..fda55358 --- /dev/null +++ b/mysql-test/suite/roles/grant_revoke_current.test @@ -0,0 +1,32 @@ +--source include/not_embedded.inc +select priv into @root_priv from mysql.global_priv where user='root' and host='localhost'; + +--error ER_MALFORMED_DEFINER +grant select on *.* to current_role; +--error ER_MALFORMED_DEFINER +revoke select on *.* from current_role; +--error ER_MALFORMED_DEFINER +revoke all, grant option from current_role; + +create role r1; +grant insert on test.* to r1; +grant r1 to current_user; +set role r1; +select current_role(); + +grant select on *.* to current_role; +show grants for current_role; +revoke insert on test.* from current_role; +show grants for current_role; +revoke all, grant option from current_role; +show grants for current_role; + +set password=password('foobar'); +show grants; +grant r1 to current_user() identified by 'barfoo'; +show grants; +set password=''; + +#cleanup +drop role r1; +update mysql.global_priv set priv=@root_priv where user='root' and host='localhost'; diff --git a/mysql-test/suite/roles/grant_role_auto_create_user.result b/mysql-test/suite/roles/grant_role_auto_create_user.result new file mode 100644 index 00000000..61ce0359 --- /dev/null +++ b/mysql-test/suite/roles/grant_role_auto_create_user.result @@ -0,0 +1,83 @@ +create database db; +create role auto_create; +create user auto_create; +grant all on db.* to auto_create; +create user foo@localhost; +grant auto_create to foo@localhost; +create user bar@localhost identified by 'baz'; +grant auto_create to bar@localhost; +connect con1,localhost,foo,,; +set role 'auto_create'; +use db; +create table t1 (i int); +disconnect con1; +connect con1,localhost,bar,baz,; +set role auto_create; +use db; +insert into t1 values (1); +disconnect con1; +connection default; +drop user foo@localhost, bar@localhost; +set sql_mode = 'no_auto_create_user'; +grant auto_create to foo@localhost; +ERROR 28000: Can't find any matching row in the user table +grant auto_create to bar@localhost identified by 'baz'; +select user, host from mysql.user where user = 'bar'; +User Host +bar localhost +set sql_mode = ''; +connect con1,localhost,bar,baz,; +set role auto_create; +use db; +drop table t1; +disconnect con1; +connection default; +create user foo@localhost; +connect con1, localhost, foo,,; +set sql_mode = ''; +grant auto_create to bar2@localhost; +ERROR 28000: Access denied for user 'foo'@'localhost' +grant auto_create to foo2@localhost; +ERROR 28000: Access denied for user 'foo'@'localhost' +set sql_mode = 'no_auto_create_user'; +grant auto_create to bar2@localhost; +ERROR 28000: Access denied for user 'foo'@'localhost' +grant auto_create to foo2@localhost identified by 'pass'; +ERROR 28000: Access denied for user 'foo'@'localhost' +disconnect con1; +connection default; +grant auto_create to foo@localhost; +connect con1, localhost, foo,,; +set sql_mode = ''; +grant auto_create to bar@localhost; +ERROR 28000: Access denied for user 'foo'@'localhost' +grant auto_create to bar2@localhost; +ERROR 28000: Access denied for user 'foo'@'localhost' +grant auto_create to foo2@localhost identified by 'pass'; +ERROR 28000: Access denied for user 'foo'@'localhost' +set sql_mode = 'no_auto_create_user'; +grant auto_create to bar2@localhost; +ERROR 28000: Access denied for user 'foo'@'localhost' +grant auto_create to foo2@localhost identified by 'pass'; +ERROR 28000: Access denied for user 'foo'@'localhost' +connection default; +grant auto_create to foo@localhost with admin option; +disconnect con1; +connect con1, localhost, foo,,; +set sql_mode = ''; +grant auto_create to bar@localhost; +grant auto_create to bar2@localhost; +ERROR 42000: You are not allowed to create a user with GRANT +grant auto_create to foo2@localhost identified by 'pass'; +ERROR 42000: You are not allowed to create a user with GRANT +set sql_mode = 'no_auto_create_user'; +grant auto_create to bar2@localhost; +ERROR 28000: Can't find any matching row in the user table +grant auto_create to foo2@localhost identified by 'pass'; +ERROR 42000: You are not allowed to create a user with GRANT +connection default; +drop user foo@localhost; +drop user bar@localhost; +drop role auto_create; +drop user auto_create; +drop database db; diff --git a/mysql-test/suite/roles/grant_role_auto_create_user.test b/mysql-test/suite/roles/grant_role_auto_create_user.test new file mode 100644 index 00000000..e6739347 --- /dev/null +++ b/mysql-test/suite/roles/grant_role_auto_create_user.test @@ -0,0 +1,123 @@ +# +# MDEV-5221 User auto-creation does not work upon GRANT <role> +# +--source include/not_embedded.inc + +create database db; +create role auto_create; +create user auto_create; +grant all on db.* to auto_create; +create user foo@localhost; +grant auto_create to foo@localhost; +create user bar@localhost identified by 'baz'; +grant auto_create to bar@localhost; + +# Test if the users have been created and the role has been granted to them +--connect (con1,localhost,foo,,) +set role 'auto_create'; +use db; +create table t1 (i int); +--disconnect con1 + +--connect (con1,localhost,bar,baz,) +set role auto_create; +use db; +insert into t1 values (1); +--disconnect con1 + +--connection default +drop user foo@localhost, bar@localhost; + +set sql_mode = 'no_auto_create_user'; +--error ER_PASSWORD_NO_MATCH +grant auto_create to foo@localhost; +grant auto_create to bar@localhost identified by 'baz'; +select user, host from mysql.user where user = 'bar'; +set sql_mode = ''; + +--connect (con1,localhost,bar,baz,) +set role auto_create; +use db; +drop table t1; +--disconnect con1 + +--connection default + +create user foo@localhost; + +# test all possible cases with a user who has no rights to grant the role +--connect (con1, localhost, foo,,) + +set sql_mode = ''; +#try and grant roles, no rights however +--error ER_ACCESS_DENIED_NO_PASSWORD_ERROR +grant auto_create to bar2@localhost; +--error ER_ACCESS_DENIED_NO_PASSWORD_ERROR +grant auto_create to foo2@localhost; + +set sql_mode = 'no_auto_create_user'; +#try and grant roles, no rights however +--error ER_ACCESS_DENIED_NO_PASSWORD_ERROR +grant auto_create to bar2@localhost; +--error ER_ACCESS_DENIED_NO_PASSWORD_ERROR +grant auto_create to foo2@localhost identified by 'pass'; +--disconnect con1 +--connection default +grant auto_create to foo@localhost; + +--connect (con1, localhost, foo,,) + +#we now have the role granted to us, but we don't have insert privileges, +#we should not be able to create a new user + +set sql_mode = ''; +#also test that we can not grant a role without admin option +--error ER_ACCESS_DENIED_NO_PASSWORD_ERROR +grant auto_create to bar@localhost; + +--error ER_ACCESS_DENIED_NO_PASSWORD_ERROR +grant auto_create to bar2@localhost; +--error ER_ACCESS_DENIED_NO_PASSWORD_ERROR +grant auto_create to foo2@localhost identified by 'pass'; + +set sql_mode = 'no_auto_create_user'; +--error ER_ACCESS_DENIED_NO_PASSWORD_ERROR +grant auto_create to bar2@localhost; +--error ER_ACCESS_DENIED_NO_PASSWORD_ERROR +grant auto_create to foo2@localhost identified by 'pass'; + +#test that we can grant a role with admin option to an existing user, but not +#create one + +--connection default +grant auto_create to foo@localhost with admin option; + +--disconnect con1 +--connect (con1, localhost, foo,,) + +#we now have the role granted to us, but we don't have insert privileges, +#we should not be able to create a new user + +set sql_mode = ''; +#also test that we can grant a role with admin option +grant auto_create to bar@localhost; + +#test that we don't create users if we don't have insert privileges +--error ER_CANT_CREATE_USER_WITH_GRANT +grant auto_create to bar2@localhost; +--error ER_CANT_CREATE_USER_WITH_GRANT +grant auto_create to foo2@localhost identified by 'pass'; + +set sql_mode = 'no_auto_create_user'; +--error ER_PASSWORD_NO_MATCH +grant auto_create to bar2@localhost; +--error ER_CANT_CREATE_USER_WITH_GRANT +grant auto_create to foo2@localhost identified by 'pass'; + + +--connection default +drop user foo@localhost; +drop user bar@localhost; +drop role auto_create; +drop user auto_create; +drop database db; diff --git a/mysql-test/suite/roles/i_s_applicable_roles_is_default.result b/mysql-test/suite/roles/i_s_applicable_roles_is_default.result new file mode 100644 index 00000000..ee7d17f3 --- /dev/null +++ b/mysql-test/suite/roles/i_s_applicable_roles_is_default.result @@ -0,0 +1,81 @@ +create user foo; +create role role1; +create role role2; +create role role3; +grant role1 to foo; +grant role2 to role1; +grant role3 to foo; +connect foo, localhost, foo; +select * from information_schema.applicable_roles; +GRANTEE ROLE_NAME IS_GRANTABLE IS_DEFAULT +foo@% role1 NO NO +foo@% role3 NO NO +role1 role2 NO NULL +set default role role3; +select * from information_schema.applicable_roles; +GRANTEE ROLE_NAME IS_GRANTABLE IS_DEFAULT +foo@% role1 NO NO +foo@% role3 NO YES +role1 role2 NO NULL +set default role role1; +select * from information_schema.applicable_roles; +GRANTEE ROLE_NAME IS_GRANTABLE IS_DEFAULT +foo@% role1 NO YES +foo@% role3 NO NO +role1 role2 NO NULL +disconnect foo; +connection default; +select * from information_schema.applicable_roles; +GRANTEE ROLE_NAME IS_GRANTABLE IS_DEFAULT +role1 role2 NO NULL +root@localhost role1 YES NO +root@localhost role2 YES NO +root@localhost role3 YES NO +set default role none for foo; +connect foo, localhost, foo; +select * from information_schema.applicable_roles; +GRANTEE ROLE_NAME IS_GRANTABLE IS_DEFAULT +foo@% role1 NO NO +foo@% role3 NO NO +role1 role2 NO NULL +disconnect foo; +connection default; +select * from information_schema.applicable_roles; +GRANTEE ROLE_NAME IS_GRANTABLE IS_DEFAULT +role1 role2 NO NULL +root@localhost role1 YES NO +root@localhost role2 YES NO +root@localhost role3 YES NO +set default role role1; +select * from information_schema.applicable_roles; +GRANTEE ROLE_NAME IS_GRANTABLE IS_DEFAULT +role1 role2 NO NULL +root@localhost role1 YES YES +root@localhost role2 YES NO +root@localhost role3 YES NO +set default role role2; +select * from information_schema.applicable_roles; +GRANTEE ROLE_NAME IS_GRANTABLE IS_DEFAULT +role1 role2 NO NULL +root@localhost role1 YES NO +root@localhost role2 YES YES +root@localhost role3 YES NO +set default role role3; +select * from information_schema.applicable_roles; +GRANTEE ROLE_NAME IS_GRANTABLE IS_DEFAULT +role1 role2 NO NULL +root@localhost role1 YES NO +root@localhost role2 YES NO +root@localhost role3 YES YES +set default role none; +select * from information_schema.applicable_roles; +GRANTEE ROLE_NAME IS_GRANTABLE IS_DEFAULT +role1 role2 NO NULL +root@localhost role1 YES NO +root@localhost role2 YES NO +root@localhost role3 YES NO +drop role role3; +drop role role2; +drop role role1; +drop user foo; +update mysql.global_priv set priv=json_compact(json_remove(priv, '$.default_role')); diff --git a/mysql-test/suite/roles/i_s_applicable_roles_is_default.test b/mysql-test/suite/roles/i_s_applicable_roles_is_default.test new file mode 100644 index 00000000..0e643692 --- /dev/null +++ b/mysql-test/suite/roles/i_s_applicable_roles_is_default.test @@ -0,0 +1,62 @@ +--source include/not_embedded.inc +create user foo; +create role role1; +create role role2; +create role role3; + +grant role1 to foo; +grant role2 to role1; +grant role3 to foo; + + +connect (foo, localhost, foo); +--sorted_result +select * from information_schema.applicable_roles; + +set default role role3; +--sorted_result +select * from information_schema.applicable_roles; + +set default role role1; +--sorted_result +select * from information_schema.applicable_roles; + + +disconnect foo; +connection default; + +--sorted_result +select * from information_schema.applicable_roles; + +set default role none for foo; +connect (foo, localhost, foo); +--sorted_result +select * from information_schema.applicable_roles; + +disconnect foo; +connection default; + +--sorted_result +select * from information_schema.applicable_roles; + +set default role role1; +--sorted_result +select * from information_schema.applicable_roles; + +set default role role2; +--sorted_result +select * from information_schema.applicable_roles; + +set default role role3; +--sorted_result +select * from information_schema.applicable_roles; + +set default role none; +--sorted_result +select * from information_schema.applicable_roles; + +drop role role3; +drop role role2; +drop role role1; +drop user foo; +update mysql.global_priv set priv=json_compact(json_remove(priv, '$.default_role')); diff --git a/mysql-test/suite/roles/ip-6401.result b/mysql-test/suite/roles/ip-6401.result new file mode 100644 index 00000000..723916f9 --- /dev/null +++ b/mysql-test/suite/roles/ip-6401.result @@ -0,0 +1,15 @@ +create role r1; +create user foo@'127.0.0.1'; +grant r1 to foo@'127.0.0.1'; +connect con1,127.0.0.1,foo,,; +show grants; +Grants for foo@127.0.0.1 +GRANT `r1` TO `foo`@`127.0.0.1` +GRANT USAGE ON *.* TO `foo`@`127.0.0.1` +set role r1; +select * from information_schema.enabled_roles; +ROLE_NAME +r1 +connection default; +drop user foo@'127.0.0.1'; +drop role r1; diff --git a/mysql-test/suite/roles/ip-6401.test b/mysql-test/suite/roles/ip-6401.test new file mode 100644 index 00000000..b7d4b168 --- /dev/null +++ b/mysql-test/suite/roles/ip-6401.test @@ -0,0 +1,16 @@ +# +# MDEV-6401 SET ROLE returning ERROR 1959 Invalid role specification for valid role +# +--source include/not_embedded.inc +create role r1; +create user foo@'127.0.0.1'; +grant r1 to foo@'127.0.0.1'; + +--connect (con1,127.0.0.1,foo,,) +show grants; +set role r1; +select * from information_schema.enabled_roles; + +connection default; +drop user foo@'127.0.0.1'; +drop role r1; diff --git a/mysql-test/suite/roles/none_public.result b/mysql-test/suite/roles/none_public.result new file mode 100644 index 00000000..a6c896c9 --- /dev/null +++ b/mysql-test/suite/roles/none_public.result @@ -0,0 +1,72 @@ +create role role1; +create role none; +ERROR OP000: Invalid role specification `NONE` +create role public; +ERROR OP000: Invalid role specification `PUBLIC` +drop role none; +ERROR HY000: Operation DROP ROLE failed for 'NONE' +drop role public; +ERROR HY000: Operation DROP ROLE failed for PUBLIC +grant none to role1; +ERROR OP000: Invalid role specification `NONE` +grant role1 to none; +ERROR OP000: Invalid role specification `none` +grant select on *.* to none; +ERROR OP000: Invalid role specification `none` +grant public to role1; +ERROR OP000: Invalid role specification `PUBLIC` +grant role1 to public; +grant select on *.* to public; +grant role1 to current_role; +ERROR OP000: Invalid role specification `NONE` +revoke none from role1; +ERROR OP000: Invalid role specification `NONE` +revoke role1 from none; +ERROR OP000: Invalid role specification `none` +revoke select on *.* from none; +ERROR OP000: Invalid role specification `none` +revoke public from role1; +ERROR OP000: Invalid role specification `PUBLIC` +revoke role1 from public; +revoke select on *.* from public; +show grants for none; +ERROR OP000: Invalid role specification `none` +show grants for public; +Grants for PUBLIC +create definer=none view test.v1 as select 1; +ERROR OP000: Invalid role specification `none` +create definer=public view test.v1 as select 1; +ERROR OP000: Invalid role specification `public` +drop role role1; +create user foo@localhost; +connect foo,localhost,foo; +set default role public; +ERROR OP000: Invalid role specification `PUBLIC` +disconnect foo; +connection default; +update mysql.global_priv set priv=json_insert(priv, '$.default_role', 'none') where user='foo'; +connect foo,localhost,foo; +show grants; +Grants for foo@localhost +GRANT USAGE ON *.* TO `foo`@`localhost` +select * from information_schema.enabled_roles; +ROLE_NAME +NULL +disconnect foo; +connection default; +update mysql.global_priv set priv=json_insert(priv, '$.default_role', 'public') where user='foo'; +connect foo,localhost,foo; +show grants; +Grants for foo@localhost +GRANT USAGE ON *.* TO `foo`@`localhost` +select * from information_schema.enabled_roles; +ROLE_NAME +NULL +disconnect foo; +connection default; +drop user foo@localhost; +insert mysql.global_priv values ('', 'none', '{"is_role":true}'); +flush privileges; +Warnings: +Error 1959 Invalid role specification `none` +delete from mysql.global_priv where host=''; diff --git a/mysql-test/suite/roles/none_public.test b/mysql-test/suite/roles/none_public.test new file mode 100644 index 00000000..e88ed45c --- /dev/null +++ b/mysql-test/suite/roles/none_public.test @@ -0,0 +1,75 @@ +source include/not_embedded.inc; + +create role role1; + +--error ER_INVALID_ROLE +create role none; +--error ER_INVALID_ROLE +create role public; +--error ER_CANNOT_USER +drop role none; +--error ER_CANNOT_USER +drop role public; + +--error ER_INVALID_ROLE +grant none to role1; +--error ER_INVALID_ROLE +grant role1 to none; +--error ER_INVALID_ROLE +grant select on *.* to none; +--error ER_INVALID_ROLE +grant public to role1; +grant role1 to public; +grant select on *.* to public; + +--error ER_INVALID_ROLE +grant role1 to current_role; + +--error ER_INVALID_ROLE +revoke none from role1; +--error ER_INVALID_ROLE +revoke role1 from none; +--error ER_INVALID_ROLE +revoke select on *.* from none; +--error ER_INVALID_ROLE +revoke public from role1; +revoke role1 from public; +revoke select on *.* from public; + +--error ER_INVALID_ROLE +show grants for none; +show grants for public; + +--error ER_INVALID_ROLE +create definer=none view test.v1 as select 1; +--error ER_INVALID_ROLE +create definer=public view test.v1 as select 1; + +drop role role1; + +create user foo@localhost; +connect foo,localhost,foo; +--error ER_INVALID_ROLE +set default role public; +disconnect foo; + +connection default; +update mysql.global_priv set priv=json_insert(priv, '$.default_role', 'none') where user='foo'; +connect foo,localhost,foo; +show grants; +select * from information_schema.enabled_roles; +disconnect foo; + +connection default; +update mysql.global_priv set priv=json_insert(priv, '$.default_role', 'public') where user='foo'; +connect foo,localhost,foo; +show grants; +select * from information_schema.enabled_roles; +disconnect foo; + +connection default; +drop user foo@localhost; + +insert mysql.global_priv values ('', 'none', '{"is_role":true}'); +flush privileges; +delete from mysql.global_priv where host=''; diff --git a/mysql-test/suite/roles/password.result b/mysql-test/suite/roles/password.result new file mode 100644 index 00000000..2d54db2c --- /dev/null +++ b/mysql-test/suite/roles/password.result @@ -0,0 +1,35 @@ +set sql_mode=''; +create role r1; +grant select on *.* to r1 identified by 'foobar'; +drop user r1; +grant select on *.* to r1 identified by ''; +drop user r1; +grant select on mysql.user to r1 identified by password '00000000000000000000000000000000000000000'; +drop user r1; +grant select on *.* to r1 identified via plugin; +ERROR HY000: Plugin 'plugin' is not loaded +grant select on mysql.user to r1 identified via plugin using 'param'; +ERROR HY000: Plugin 'plugin' is not loaded +grant select on *.* to r1 require subject 'foobar'; +drop user r1; +grant select on mysql.user to r1 require issuer 'foobar'; +drop user r1; +grant select on *.* to r1 require cipher 'foobar'; +drop user r1; +grant select on mysql.user to r1 require ssl; +drop user r1; +grant select on *.* to r1 require x509; +drop user r1; +grant select on mysql.user to r1 require none; +drop user r1; +grant select on *.* to r1 with max_queries_per_hour 10; +drop user r1; +grant select on mysql.user to r1 with max_updates_per_hour 10; +drop user r1; +grant select on *.* to r1 with max_connections_per_hour 10; +drop user r1; +grant select on mysql.user to r1 with max_user_connections 10; +drop user r1; +set password for r1 = '00000000000000000000000000000000000000000'; +ERROR 28000: Can't find any matching row in the user table +drop role r1; diff --git a/mysql-test/suite/roles/password.test b/mysql-test/suite/roles/password.test new file mode 100644 index 00000000..e5fff01d --- /dev/null +++ b/mysql-test/suite/roles/password.test @@ -0,0 +1,53 @@ +# +# setting authentication for roles +# + +--source include/not_embedded.inc + +#identified by [password]... +#identified with ... [using ...] +#require [subject][issuer][cipher][ssl][x509] +# max_queries_per_hour | max_updates_per_hour | max_connections_per_hour | max_user_connections +#set password for ... = ... + +set sql_mode=''; +create role r1; + +# IDENTIFIED does not apply to roles, using it forces username context +grant select on *.* to r1 identified by 'foobar'; +drop user r1; +grant select on *.* to r1 identified by ''; +drop user r1; +grant select on mysql.user to r1 identified by password '00000000000000000000000000000000000000000'; +drop user r1; +--error ER_PLUGIN_IS_NOT_LOADED +grant select on *.* to r1 identified via plugin; +--error ER_PLUGIN_IS_NOT_LOADED +grant select on mysql.user to r1 identified via plugin using 'param'; + +# same for REQUIRE and mqh +grant select on *.* to r1 require subject 'foobar'; +drop user r1; +grant select on mysql.user to r1 require issuer 'foobar'; +drop user r1; +grant select on *.* to r1 require cipher 'foobar'; +drop user r1; +grant select on mysql.user to r1 require ssl; +drop user r1; +grant select on *.* to r1 require x509; +drop user r1; +grant select on mysql.user to r1 require none; +drop user r1; +grant select on *.* to r1 with max_queries_per_hour 10; +drop user r1; +grant select on mysql.user to r1 with max_updates_per_hour 10; +drop user r1; +grant select on *.* to r1 with max_connections_per_hour 10; +drop user r1; +grant select on mysql.user to r1 with max_user_connections 10; +drop user r1; + +--error ER_PASSWORD_NO_MATCH +set password for r1 = '00000000000000000000000000000000000000000'; + +drop role r1; diff --git a/mysql-test/suite/roles/prepare_stmt_with_role.result b/mysql-test/suite/roles/prepare_stmt_with_role.result new file mode 100644 index 00000000..10387936 --- /dev/null +++ b/mysql-test/suite/roles/prepare_stmt_with_role.result @@ -0,0 +1,107 @@ +# +# Test user to check if we can grant the created role to it. +# +create user test_user; +# +# First create the role. +# +SET @createRole = 'CREATE ROLE developers'; +PREPARE stmtCreateRole FROM @createRole; +EXECUTE stmtCreateRole; +# +# Test to see if the role is created. +# +SELECT user, host,is_role FROM mysql.user +WHERE user = 'developers'; +User Host is_role +developers Y +SHOW GRANTS; +Grants for root@localhost +GRANT `developers` TO `root`@`localhost` WITH ADMIN OPTION +GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` WITH GRANT OPTION +GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION +# Test reexecution. +EXECUTE stmtCreateRole; +ERROR HY000: Operation CREATE ROLE failed for 'developers' +# +# Now grant the role to the test user. +# +SET @grantRole = 'GRANT developers to test_user'; +PREPARE stmtGrantRole FROM @grantRole; +EXECUTE stmtGrantRole; +# Test reexecution. +EXECUTE stmtGrantRole; +# +# We should see 2 entries in the roles_mapping table. +# +SELECT * FROM mysql.roles_mapping; +Host User Role Admin_option +% test_user developers N +localhost root developers Y +SHOW GRANTS FOR test_user; +Grants for test_user@% +GRANT `developers` TO `test_user`@`%` +GRANT USAGE ON *.* TO `test_user`@`%` +# +# Test revoking a role. +# +SET @revokeRole = 'REVOKE developers FROM test_user'; +PREPARE stmtRevokeRole FROM @revokeRole; +EXECUTE stmtRevokeRole; +EXECUTE stmtRevokeRole; +ERROR HY000: Cannot revoke role 'developers' from: 'test_user'@'%' +SHOW GRANTS FOR test_user; +Grants for test_user@% +GRANT USAGE ON *.* TO `test_user`@`%` +EXECUTE stmtGrantRole; +SHOW GRANTS FOR test_user; +Grants for test_user@% +GRANT `developers` TO `test_user`@`%` +GRANT USAGE ON *.* TO `test_user`@`%` +EXECUTE stmtRevokeRole; +SHOW GRANTS FOR test_user; +Grants for test_user@% +GRANT USAGE ON *.* TO `test_user`@`%` +# +# Now drop the role. +# +SET @dropRole = 'DROP ROLE developers'; +PREPARE stmtDropRole FROM @dropRole; +EXECUTE stmtDropRole; +# +# Check both user and roles_mapping table for traces of our role. +# +SELECT user, host,is_role FROM mysql.user +WHERE user = 'developers'; +User Host is_role +SELECT * FROM mysql.roles_mapping; +Host User Role Admin_option +SHOW GRANTS; +Grants for root@localhost +GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` WITH GRANT OPTION +GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION +SHOW GRANTS FOR test_user; +Grants for test_user@% +GRANT USAGE ON *.* TO `test_user`@`%` +# +# Test reexecution. +# +EXECUTE stmtCreateRole; +SELECT user, host,is_role FROM mysql.user +WHERE user = 'developers'; +User Host is_role +developers Y +SELECT * FROM mysql.roles_mapping; +Host User Role Admin_option +localhost root developers Y +SHOW GRANTS; +Grants for root@localhost +GRANT `developers` TO `root`@`localhost` WITH ADMIN OPTION +GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` WITH GRANT OPTION +GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION +SHOW GRANTS FOR test_user; +Grants for test_user@% +GRANT USAGE ON *.* TO `test_user`@`%` +EXECUTE stmtDropRole; +# Cleanup. +DROP USER test_user; diff --git a/mysql-test/suite/roles/prepare_stmt_with_role.test b/mysql-test/suite/roles/prepare_stmt_with_role.test new file mode 100644 index 00000000..516e9dda --- /dev/null +++ b/mysql-test/suite/roles/prepare_stmt_with_role.test @@ -0,0 +1,85 @@ +--source include/not_embedded.inc + + +--echo # +--echo # Test user to check if we can grant the created role to it. +--echo # +create user test_user; +--echo # +--echo # First create the role. +--echo # +SET @createRole = 'CREATE ROLE developers'; +PREPARE stmtCreateRole FROM @createRole; +EXECUTE stmtCreateRole; +--echo # +--echo # Test to see if the role is created. +--echo # +SELECT user, host,is_role FROM mysql.user +WHERE user = 'developers'; +SHOW GRANTS; + +--echo # Test reexecution. +--error ER_CANNOT_USER +EXECUTE stmtCreateRole; + +--echo # +--echo # Now grant the role to the test user. +--echo # +SET @grantRole = 'GRANT developers to test_user'; +PREPARE stmtGrantRole FROM @grantRole; +EXECUTE stmtGrantRole; +--echo # Test reexecution. +EXECUTE stmtGrantRole; + +--echo # +--echo # We should see 2 entries in the roles_mapping table. +--echo # +--sorted_result +SELECT * FROM mysql.roles_mapping; +SHOW GRANTS FOR test_user; + +--echo # +--echo # Test revoking a role. +--echo # +SET @revokeRole = 'REVOKE developers FROM test_user'; +PREPARE stmtRevokeRole FROM @revokeRole; +EXECUTE stmtRevokeRole; +--error ER_CANNOT_REVOKE_ROLE +EXECUTE stmtRevokeRole; +SHOW GRANTS FOR test_user; + +EXECUTE stmtGrantRole; +SHOW GRANTS FOR test_user; +EXECUTE stmtRevokeRole; +SHOW GRANTS FOR test_user; + +--echo # +--echo # Now drop the role. +--echo # +SET @dropRole = 'DROP ROLE developers'; +PREPARE stmtDropRole FROM @dropRole; +EXECUTE stmtDropRole; + +--echo # +--echo # Check both user and roles_mapping table for traces of our role. +--echo # +SELECT user, host,is_role FROM mysql.user +WHERE user = 'developers'; +SELECT * FROM mysql.roles_mapping; +SHOW GRANTS; +SHOW GRANTS FOR test_user; + +--echo # +--echo # Test reexecution. +--echo # +EXECUTE stmtCreateRole; +SELECT user, host,is_role FROM mysql.user +WHERE user = 'developers'; +SELECT * FROM mysql.roles_mapping; + +SHOW GRANTS; +SHOW GRANTS FOR test_user; +EXECUTE stmtDropRole; + +--echo # Cleanup. +DROP USER test_user; diff --git a/mysql-test/suite/roles/ps.result b/mysql-test/suite/roles/ps.result new file mode 100644 index 00000000..694dcb94 --- /dev/null +++ b/mysql-test/suite/roles/ps.result @@ -0,0 +1 @@ +PREPARE stmt FROM 'SET ROLE NONE'; diff --git a/mysql-test/suite/roles/ps.test b/mysql-test/suite/roles/ps.test new file mode 100644 index 00000000..f9bb6aaf --- /dev/null +++ b/mysql-test/suite/roles/ps.test @@ -0,0 +1,4 @@ +# +# MDEV-5521 SET ROLE as prepared statement crashes the server +# +PREPARE stmt FROM 'SET ROLE NONE'; diff --git a/mysql-test/suite/roles/rebuild_role_grants.result b/mysql-test/suite/roles/rebuild_role_grants.result new file mode 100644 index 00000000..b8d74753 --- /dev/null +++ b/mysql-test/suite/roles/rebuild_role_grants.result @@ -0,0 +1,333 @@ +create role r1; +create user u1; +grant r1 to u1; +show grants for u1; +Grants for u1@% +GRANT USAGE ON *.* TO `u1`@`%` +GRANT `r1` TO `u1`@`%` +create user u2; +show grants for u1; +Grants for u1@% +GRANT USAGE ON *.* TO `u1`@`%` +GRANT `r1` TO `u1`@`%` +show grants for u2; +Grants for u2@% +GRANT USAGE ON *.* TO `u2`@`%` +select * from mysql.roles_mapping; +Host User Role Admin_option +% u1 r1 N +localhost root r1 Y +revoke r1 from u1; +revoke r1 from u1; +ERROR HY000: Cannot revoke role 'r1' from: 'u1'@'%' +show grants for u1; +Grants for u1@% +GRANT USAGE ON *.* TO `u1`@`%` +select * from mysql.roles_mapping; +Host User Role Admin_option +localhost root r1 Y +grant r1 to u1; +grant r1 to u1; +show grants for u1; +Grants for u1@% +GRANT USAGE ON *.* TO `u1`@`%` +GRANT `r1` TO `u1`@`%` +select * from mysql.roles_mapping; +Host User Role Admin_option +% u1 r1 N +localhost root r1 Y +drop role r1; +show grants for u1; +Grants for u1@% +GRANT USAGE ON *.* TO `u1`@`%` +select * from mysql.roles_mapping; +Host User Role Admin_option +create role r1; +grant r1 to u1; +select * from mysql.roles_mapping; +Host User Role Admin_option +% u1 r1 N +localhost root r1 Y +drop user u1; +show grants for u1; +ERROR 42000: There is no such grant defined for user 'u1' on host '%' +select * from mysql.roles_mapping; +Host User Role Admin_option +localhost root r1 Y +drop role r1; +drop user u2; +create user foo@localhost; +grant create user on *.* to foo@localhost; +connect con1, localhost, foo,,; +create role look, isp, xxx, ppp; +rename user current_user to nnnn@'%'; +drop role look, isp, xxx, ppp; +connection default; +disconnect con1; +drop user nnnn@'%'; +CREATE USER u@localhost; +CREATE ROLE r1; +CREATE ROLE r2; +CREATE ROLE r3; +CREATE ROLE r4; +CREATE ROLE r5; +CREATE ROLE r6; +CREATE ROLE r7; +CREATE ROLE r8; +CREATE ROLE r9; +CREATE ROLE r10; +CREATE ROLE r11; +CREATE ROLE r12; +CREATE ROLE r13; +CREATE ROLE r14; +CREATE ROLE r15; +CREATE ROLE r16; +CREATE ROLE r17; +CREATE ROLE r18; +CREATE ROLE r19; +CREATE ROLE r20; +CREATE ROLE r21; +CREATE ROLE r22; +CREATE ROLE r23; +CREATE ROLE r24; +CREATE ROLE r25; +CREATE ROLE r26; +CREATE ROLE r27; +CREATE ROLE r28; +CREATE ROLE r29; +CREATE ROLE r30; +CREATE ROLE r31; +CREATE ROLE r32; +CREATE ROLE r33; +CREATE ROLE r34; +CREATE ROLE r35; +CREATE ROLE r36; +CREATE ROLE r37; +CREATE ROLE r38; +CREATE ROLE r39; +CREATE ROLE r40; +CREATE ROLE r41; +CREATE ROLE r42; +CREATE ROLE r43; +CREATE ROLE r44; +CREATE ROLE r45; +CREATE ROLE r46; +CREATE ROLE r47; +CREATE ROLE r48; +CREATE ROLE r49; +CREATE ROLE r50; +CREATE ROLE r51; +CREATE ROLE r52; +CREATE ROLE r53; +CREATE ROLE r54; +CREATE ROLE r55; +CREATE ROLE r56; +CREATE ROLE r57; +CREATE ROLE r58; +CREATE ROLE r59; +CREATE ROLE r60; +CREATE ROLE r61; +CREATE ROLE r62; +CREATE ROLE r63; +CREATE ROLE r64; +CREATE ROLE r65; +CREATE ROLE r66; +CREATE ROLE r67; +CREATE ROLE r68; +CREATE ROLE r69; +CREATE ROLE r70; +CREATE ROLE r71; +CREATE ROLE r72; +CREATE ROLE r73; +CREATE ROLE r74; +CREATE ROLE r75; +CREATE ROLE r76; +CREATE ROLE r77; +CREATE ROLE r78; +CREATE ROLE r79; +CREATE ROLE r80; +CREATE ROLE r81; +CREATE ROLE r82; +CREATE ROLE r83; +CREATE ROLE r84; +CREATE ROLE r85; +CREATE ROLE r86; +CREATE ROLE r87; +CREATE ROLE r88; +CREATE ROLE r89; +CREATE ROLE r90; +CREATE ROLE r91; +CREATE ROLE r92; +CREATE ROLE r93; +CREATE ROLE r94; +CREATE ROLE r95; +CREATE ROLE r96; +CREATE ROLE r97; +CREATE ROLE r98; +CREATE ROLE r99; +CREATE ROLE r100; +CREATE ROLE r101; +CREATE ROLE r102; +CREATE ROLE r103; +CREATE ROLE r104; +CREATE ROLE r105; +CREATE ROLE r106; +CREATE ROLE r107; +CREATE ROLE r108; +CREATE ROLE r109; +CREATE ROLE r110; +CREATE ROLE r111; +CREATE ROLE r112; +CREATE ROLE r113; +CREATE ROLE r114; +CREATE ROLE r115; +CREATE ROLE r116; +CREATE ROLE r117; +CREATE ROLE r118; +CREATE ROLE r119; +CREATE ROLE r120; +CREATE ROLE r121; +CREATE ROLE r122; +CREATE ROLE r123; +CREATE ROLE r124; +CREATE ROLE r125; +CREATE ROLE r126; +CREATE ROLE r127; +CREATE ROLE r128; +CREATE ROLE n; +CREATE ROLE d WITH ADMIN n; +CREATE ROLE '%' WITH ADMIN u@localhost; +DROP ROLE n; +CREATE USER 't'; +DROP ROLE r1; +DROP ROLE r2; +DROP ROLE r3; +DROP ROLE r4; +DROP ROLE r5; +DROP ROLE r6; +DROP ROLE r7; +DROP ROLE r8; +DROP ROLE r9; +DROP ROLE r10; +DROP ROLE r11; +DROP ROLE r12; +DROP ROLE r13; +DROP ROLE r14; +DROP ROLE r15; +DROP ROLE r16; +DROP ROLE r17; +DROP ROLE r18; +DROP ROLE r19; +DROP ROLE r20; +DROP ROLE r21; +DROP ROLE r22; +DROP ROLE r23; +DROP ROLE r24; +DROP ROLE r25; +DROP ROLE r26; +DROP ROLE r27; +DROP ROLE r28; +DROP ROLE r29; +DROP ROLE r30; +DROP ROLE r31; +DROP ROLE r32; +DROP ROLE r33; +DROP ROLE r34; +DROP ROLE r35; +DROP ROLE r36; +DROP ROLE r37; +DROP ROLE r38; +DROP ROLE r39; +DROP ROLE r40; +DROP ROLE r41; +DROP ROLE r42; +DROP ROLE r43; +DROP ROLE r44; +DROP ROLE r45; +DROP ROLE r46; +DROP ROLE r47; +DROP ROLE r48; +DROP ROLE r49; +DROP ROLE r50; +DROP ROLE r51; +DROP ROLE r52; +DROP ROLE r53; +DROP ROLE r54; +DROP ROLE r55; +DROP ROLE r56; +DROP ROLE r57; +DROP ROLE r58; +DROP ROLE r59; +DROP ROLE r60; +DROP ROLE r61; +DROP ROLE r62; +DROP ROLE r63; +DROP ROLE r64; +DROP ROLE r65; +DROP ROLE r66; +DROP ROLE r67; +DROP ROLE r68; +DROP ROLE r69; +DROP ROLE r70; +DROP ROLE r71; +DROP ROLE r72; +DROP ROLE r73; +DROP ROLE r74; +DROP ROLE r75; +DROP ROLE r76; +DROP ROLE r77; +DROP ROLE r78; +DROP ROLE r79; +DROP ROLE r80; +DROP ROLE r81; +DROP ROLE r82; +DROP ROLE r83; +DROP ROLE r84; +DROP ROLE r85; +DROP ROLE r86; +DROP ROLE r87; +DROP ROLE r88; +DROP ROLE r89; +DROP ROLE r90; +DROP ROLE r91; +DROP ROLE r92; +DROP ROLE r93; +DROP ROLE r94; +DROP ROLE r95; +DROP ROLE r96; +DROP ROLE r97; +DROP ROLE r98; +DROP ROLE r99; +DROP ROLE r100; +DROP ROLE r101; +DROP ROLE r102; +DROP ROLE r103; +DROP ROLE r104; +DROP ROLE r105; +DROP ROLE r106; +DROP ROLE r107; +DROP ROLE r108; +DROP ROLE r109; +DROP ROLE r110; +DROP ROLE r111; +DROP ROLE r112; +DROP ROLE r113; +DROP ROLE r114; +DROP ROLE r115; +DROP ROLE r116; +DROP ROLE r117; +DROP ROLE r118; +DROP ROLE r119; +DROP ROLE r120; +DROP ROLE r121; +DROP ROLE r122; +DROP ROLE r123; +DROP ROLE r124; +DROP ROLE r125; +DROP ROLE r126; +DROP ROLE r127; +DROP ROLE r128; +DROP ROLE d; +DROP ROLE '%'; +DROP USER 't'; +DROP USER u@localhost; diff --git a/mysql-test/suite/roles/rebuild_role_grants.test b/mysql-test/suite/roles/rebuild_role_grants.test new file mode 100644 index 00000000..7007df0e --- /dev/null +++ b/mysql-test/suite/roles/rebuild_role_grants.test @@ -0,0 +1,100 @@ +source include/not_embedded.inc; + +create role r1; +create user u1; +grant r1 to u1; + +#CHECK IF GRANTS ARE UPDATED ON GRANT +--sorted_result +show grants for u1; + +create user u2; + +#CHECK THAT GRANTS ARE UPDATED ON ACL_USERS CHANGE +--sorted_result +show grants for u1; +--sorted_result +show grants for u2; +--sorted_result +select * from mysql.roles_mapping; + +revoke r1 from u1; +#TEST ERROR MESSAGE +--error ER_CANNOT_REVOKE_ROLE +revoke r1 from u1; +--sorted_result +show grants for u1; +--sorted_result +select * from mysql.roles_mapping; + +# granting twice is ok +grant r1 to u1; +grant r1 to u1; +--sorted_result +show grants for u1; +--sorted_result +select * from mysql.roles_mapping; + +drop role r1; +--sorted_result +show grants for u1; +--sorted_result +select * from mysql.roles_mapping; + +create role r1; +grant r1 to u1; +--sorted_result +select * from mysql.roles_mapping; + +drop user u1; +--error ER_NONEXISTING_GRANT +show grants for u1; +--sorted_result +select * from mysql.roles_mapping; + +drop role r1; +drop user u2; + +# +# MDEV-8614 Assertion `status == 0' failed in add_role_user_mapping_action on RENAME USER +# +create user foo@localhost; +grant create user on *.* to foo@localhost; +--connect (con1, localhost, foo,,) +create role look, isp, xxx, ppp; +rename user current_user to nnnn@'%'; +drop role look, isp, xxx, ppp; +connection default; +disconnect con1; +drop user nnnn@'%'; + +# +# MDEV-17964 Assertion `status == 0' failed in add_role_user_mapping_action +# upon CREATE USER and DROP ROLE +# +CREATE USER u@localhost; + +--let $n= 1 +while ($n < 129) +{ + eval CREATE ROLE r$n; + inc $n; +} + +CREATE ROLE n; +CREATE ROLE d WITH ADMIN n; +CREATE ROLE '%' WITH ADMIN u@localhost; +DROP ROLE n; +CREATE USER 't'; + +--let $n= 1 +while ($n < 129) +{ + eval DROP ROLE r$n; + inc $n; +} + +DROP ROLE d; +DROP ROLE '%'; +DROP USER 't'; +DROP USER u@localhost; diff --git a/mysql-test/suite/roles/recursive.inc b/mysql-test/suite/roles/recursive.inc new file mode 100644 index 00000000..7642f2d6 --- /dev/null +++ b/mysql-test/suite/roles/recursive.inc @@ -0,0 +1,259 @@ +# +# This file tests how privilege are propagated through a complex role graph. +# Here's a graph +# +# role1 ->- role2 -->- role4 -->- role6 ->- role8 +# \ / \ +# \->- role5 ->-/ \->- role9 ->- role10 ->- foo@localhost +# / \ / +# role3 ->-/ \->- role7 ->-/ +# +# privilege checks verify that grants/revokes are propagated correctly +# from the role1 to role10. additionally debug status variables verify +# that propagation doesn't do unnecessary work (only touches the +# smallest possible number of nodes and doesn't merge privileges that +# didn't change) +# +source include/not_embedded.inc; + +create user foo@localhost; +grant select on test.* to foo@localhost; +create role role1; +create role role2; +create role role3; +create role role4; +create role role5; +create role role6; +create role role7; +create role role8; +create role role9; +create role role10; + +grant role1 to role2; +grant role2 to role4; +grant role2 to role5; +grant role3 to role5; +grant role4 to role6; +grant role5 to role6; +grant role5 to role7; +grant role6 to role8; +grant role6 to role9; +grant role7 to role9; +grant role9 to role10; +grant role10 to foo@localhost; + +# try to create a cycle +--error ER_CANNOT_GRANT_ROLE +grant role10 to role2; + +connect (foo, localhost, foo); +--sorted_result +show grants; +--sorted_result +select * from information_schema.applicable_roles; + +show status like 'debug%'; + +# +# global privileges +# +connection default; +grant select on *.* to role1; +show status like 'debug%'; +connection foo; +--error ER_TABLEACCESS_DENIED_ERROR +select count(*) from mysql.roles_mapping; +set role role10; +select count(*) from mysql.roles_mapping; +--sorted_result +show grants; +--sorted_result +select * from information_schema.enabled_roles; + +connection default; +revoke select on *.* from role1; +show status like 'debug%'; +connection foo; +# global privileges are cached in the THD, changes don't take effect immediately +select count(*) from mysql.roles_mapping; +set role none; +set role role10; +--error ER_TABLEACCESS_DENIED_ERROR +select count(*) from mysql.roles_mapping; +set role none; + +# +# database privileges +# +connection default; +grant select on mysql.* to role1; +show status like 'debug%'; +connection foo; +--error ER_TABLEACCESS_DENIED_ERROR +select count(*) from mysql.roles_mapping; +set role role10; +select count(*) from mysql.roles_mapping; +--sorted_result +show grants; + +connection default; +revoke select on mysql.* from role1; +show status like 'debug%'; +connection foo; +--error ER_TABLEACCESS_DENIED_ERROR +select count(*) from mysql.roles_mapping; +set role none; + +# +# table privileges +# + +connection default; +grant select on mysql.roles_mapping to role1; +show status like 'debug%'; +connection foo; +--error ER_TABLEACCESS_DENIED_ERROR +select count(*) from mysql.roles_mapping; +set role role10; +select count(*) from mysql.roles_mapping; +--sorted_result +show grants; + +connection default; +revoke select on mysql.roles_mapping from role1; +show status like 'debug%'; +connection foo; +--error ER_TABLEACCESS_DENIED_ERROR +select count(*) from mysql.roles_mapping; +set role none; + +# +# column privileges +# + +connection default; +grant select(User) on mysql.roles_mapping to role1; +show status like 'debug%'; +connection foo; +--error ER_TABLEACCESS_DENIED_ERROR +select count(*) from mysql.roles_mapping; +set role role10; +--error ER_COLUMNACCESS_DENIED_ERROR +select count(concat(User,Host,Role)) from mysql.roles_mapping; +select count(concat(User)) from mysql.roles_mapping; +--sorted_result +show grants; + +connection default; +grant select(Host) on mysql.roles_mapping to role3; +show status like 'debug%'; +connection foo; +--error ER_COLUMNACCESS_DENIED_ERROR +select count(concat(User,Host,Role)) from mysql.roles_mapping; +select count(concat(User,Host)) from mysql.roles_mapping; +--sorted_result +show grants; + +connection default; +revoke select(User) on mysql.roles_mapping from role1; +show status like 'debug%'; +connection foo; +--error ER_COLUMNACCESS_DENIED_ERROR +select count(concat(User,Host)) from mysql.roles_mapping; +select count(concat(Host)) from mysql.roles_mapping; + +connection default; +revoke select(Host) on mysql.roles_mapping from role3; +show status like 'debug%'; +connection foo; +--error ER_TABLEACCESS_DENIED_ERROR +select count(concat(Host)) from mysql.roles_mapping; +set role none; + +# +# routine privileges +# + +connection default; +create procedure pr1() select "pr1"; +create function fn1() returns char(10) return "fn1"; +grant execute on procedure test.pr1 to role1; +show status like 'debug%'; +connection foo; +--error ER_PROCACCESS_DENIED_ERROR +call pr1(); +set role role10; +call pr1(); +--error ER_PROCACCESS_DENIED_ERROR +select fn1(); + +connection default; +grant execute on function test.fn1 to role5; +show status like 'debug%'; +connection foo; +select fn1(); + +connection default; +revoke execute on procedure test.pr1 from role1; +show status like 'debug%'; +connection foo; +--error ER_PROCACCESS_DENIED_ERROR +call pr1(); +select fn1(); + +connection default; +revoke execute on function test.fn1 from role5; +show status like 'debug%'; +connection foo; +--error ER_PROCACCESS_DENIED_ERROR +select fn1(); +set role none; + +connection default; +drop procedure pr1; +drop function fn1; + +# +# test shortcuts +# + +grant select on mysql.roles_mapping to role3; +show status like 'debug%'; +# this grant only propagates to roles role2 and role4, +# and tries to propagate to role5, discovering that it already has it +grant select on mysql.roles_mapping to role1; +show status like 'debug%'; +# this only tries to propagate to role5 and exits early +revoke select on mysql.roles_mapping from role3; +show status like 'debug%'; +# propagates to all 8 roles, normally +revoke select on mysql.roles_mapping from role1; +show status like 'debug%'; + +grant select on mysql.* to role1; +show status like 'debug%'; +# only entries for `test` are merged, not for `mysql` +grant select on test.* to role1; +show status like 'debug%'; +revoke select on mysql.* from role1; +show status like 'debug%'; +revoke select on test.* from role1; +show status like 'debug%'; + +# +# cleanup +# + +connection default; +drop user foo@localhost; +drop role role1; +drop role role2; +drop role role3; +drop role role4; +drop role role5; +drop role role6; +drop role role7; +drop role role8; +drop role role9; +drop role role10; + diff --git a/mysql-test/suite/roles/recursive.result b/mysql-test/suite/roles/recursive.result new file mode 100644 index 00000000..0706b0a5 --- /dev/null +++ b/mysql-test/suite/roles/recursive.result @@ -0,0 +1,366 @@ +create user foo@localhost; +grant select on test.* to foo@localhost; +create role role1; +create role role2; +create role role3; +create role role4; +create role role5; +create role role6; +create role role7; +create role role8; +create role role9; +create role role10; +grant role1 to role2; +grant role2 to role4; +grant role2 to role5; +grant role3 to role5; +grant role4 to role6; +grant role5 to role6; +grant role5 to role7; +grant role6 to role8; +grant role6 to role9; +grant role7 to role9; +grant role9 to role10; +grant role10 to foo@localhost; +grant role10 to role2; +ERROR HY000: Cannot grant role 'role10' to: 'role2' +connect foo, localhost, foo; +show grants; +Grants for foo@localhost +GRANT SELECT ON `test`.* TO `foo`@`localhost` +GRANT USAGE ON *.* TO `foo`@`localhost` +GRANT `role10` TO `foo`@`localhost` +select * from information_schema.applicable_roles; +GRANTEE ROLE_NAME IS_GRANTABLE IS_DEFAULT +foo@localhost role10 NO NO +role10 role9 NO NULL +role2 role1 NO NULL +role4 role2 NO NULL +role5 role2 NO NULL +role5 role3 NO NULL +role6 role4 NO NULL +role6 role5 NO NULL +role7 role5 NO NULL +role9 role6 NO NULL +role9 role7 NO NULL +show status like 'debug%'; +Variable_name Value +connection default; +grant select on *.* to role1; +show status like 'debug%'; +Variable_name Value +connection foo; +select count(*) from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysql`.`roles_mapping` +set role role10; +select count(*) from mysql.roles_mapping; +count(*) +22 +show grants; +Grants for foo@localhost +GRANT SELECT ON *.* TO `role1` +GRANT SELECT ON `test`.* TO `foo`@`localhost` +GRANT USAGE ON *.* TO `foo`@`localhost` +GRANT USAGE ON *.* TO `role10` +GRANT USAGE ON *.* TO `role2` +GRANT USAGE ON *.* TO `role3` +GRANT USAGE ON *.* TO `role4` +GRANT USAGE ON *.* TO `role5` +GRANT USAGE ON *.* TO `role6` +GRANT USAGE ON *.* TO `role7` +GRANT USAGE ON *.* TO `role9` +GRANT `role10` TO `foo`@`localhost` +GRANT `role1` TO `role2` +GRANT `role2` TO `role4` +GRANT `role2` TO `role5` +GRANT `role3` TO `role5` +GRANT `role4` TO `role6` +GRANT `role5` TO `role6` +GRANT `role5` TO `role7` +GRANT `role6` TO `role9` +GRANT `role7` TO `role9` +GRANT `role9` TO `role10` +select * from information_schema.enabled_roles; +ROLE_NAME +role1 +role10 +role2 +role3 +role4 +role5 +role6 +role7 +role9 +connection default; +revoke select on *.* from role1; +show status like 'debug%'; +Variable_name Value +connection foo; +select count(*) from mysql.roles_mapping; +count(*) +22 +set role none; +set role role10; +select count(*) from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysql`.`roles_mapping` +set role none; +connection default; +grant select on mysql.* to role1; +show status like 'debug%'; +Variable_name Value +connection foo; +select count(*) from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysql`.`roles_mapping` +set role role10; +select count(*) from mysql.roles_mapping; +count(*) +22 +show grants; +Grants for foo@localhost +GRANT SELECT ON `mysql`.* TO `role1` +GRANT SELECT ON `test`.* TO `foo`@`localhost` +GRANT USAGE ON *.* TO `foo`@`localhost` +GRANT USAGE ON *.* TO `role10` +GRANT USAGE ON *.* TO `role1` +GRANT USAGE ON *.* TO `role2` +GRANT USAGE ON *.* TO `role3` +GRANT USAGE ON *.* TO `role4` +GRANT USAGE ON *.* TO `role5` +GRANT USAGE ON *.* TO `role6` +GRANT USAGE ON *.* TO `role7` +GRANT USAGE ON *.* TO `role9` +GRANT `role10` TO `foo`@`localhost` +GRANT `role1` TO `role2` +GRANT `role2` TO `role4` +GRANT `role2` TO `role5` +GRANT `role3` TO `role5` +GRANT `role4` TO `role6` +GRANT `role5` TO `role6` +GRANT `role5` TO `role7` +GRANT `role6` TO `role9` +GRANT `role7` TO `role9` +GRANT `role9` TO `role10` +connection default; +revoke select on mysql.* from role1; +show status like 'debug%'; +Variable_name Value +connection foo; +select count(*) from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysql`.`roles_mapping` +set role none; +connection default; +grant select on mysql.roles_mapping to role1; +show status like 'debug%'; +Variable_name Value +connection foo; +select count(*) from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysql`.`roles_mapping` +set role role10; +select count(*) from mysql.roles_mapping; +count(*) +22 +show grants; +Grants for foo@localhost +GRANT SELECT ON `mysql`.`roles_mapping` TO `role1` +GRANT SELECT ON `test`.* TO `foo`@`localhost` +GRANT USAGE ON *.* TO `foo`@`localhost` +GRANT USAGE ON *.* TO `role10` +GRANT USAGE ON *.* TO `role1` +GRANT USAGE ON *.* TO `role2` +GRANT USAGE ON *.* TO `role3` +GRANT USAGE ON *.* TO `role4` +GRANT USAGE ON *.* TO `role5` +GRANT USAGE ON *.* TO `role6` +GRANT USAGE ON *.* TO `role7` +GRANT USAGE ON *.* TO `role9` +GRANT `role10` TO `foo`@`localhost` +GRANT `role1` TO `role2` +GRANT `role2` TO `role4` +GRANT `role2` TO `role5` +GRANT `role3` TO `role5` +GRANT `role4` TO `role6` +GRANT `role5` TO `role6` +GRANT `role5` TO `role7` +GRANT `role6` TO `role9` +GRANT `role7` TO `role9` +GRANT `role9` TO `role10` +connection default; +revoke select on mysql.roles_mapping from role1; +show status like 'debug%'; +Variable_name Value +connection foo; +select count(*) from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysql`.`roles_mapping` +set role none; +connection default; +grant select(User) on mysql.roles_mapping to role1; +show status like 'debug%'; +Variable_name Value +connection foo; +select count(*) from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysql`.`roles_mapping` +set role role10; +select count(concat(User,Host,Role)) from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'Host' in table 'roles_mapping' +select count(concat(User)) from mysql.roles_mapping; +count(concat(User)) +22 +show grants; +Grants for foo@localhost +GRANT SELECT (`User`) ON `mysql`.`roles_mapping` TO `role1` +GRANT SELECT ON `test`.* TO `foo`@`localhost` +GRANT USAGE ON *.* TO `foo`@`localhost` +GRANT USAGE ON *.* TO `role10` +GRANT USAGE ON *.* TO `role1` +GRANT USAGE ON *.* TO `role2` +GRANT USAGE ON *.* TO `role3` +GRANT USAGE ON *.* TO `role4` +GRANT USAGE ON *.* TO `role5` +GRANT USAGE ON *.* TO `role6` +GRANT USAGE ON *.* TO `role7` +GRANT USAGE ON *.* TO `role9` +GRANT `role10` TO `foo`@`localhost` +GRANT `role1` TO `role2` +GRANT `role2` TO `role4` +GRANT `role2` TO `role5` +GRANT `role3` TO `role5` +GRANT `role4` TO `role6` +GRANT `role5` TO `role6` +GRANT `role5` TO `role7` +GRANT `role6` TO `role9` +GRANT `role7` TO `role9` +GRANT `role9` TO `role10` +connection default; +grant select(Host) on mysql.roles_mapping to role3; +show status like 'debug%'; +Variable_name Value +connection foo; +select count(concat(User,Host,Role)) from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'Role' in table 'roles_mapping' +select count(concat(User,Host)) from mysql.roles_mapping; +count(concat(User,Host)) +22 +show grants; +Grants for foo@localhost +GRANT SELECT (`Host`) ON `mysql`.`roles_mapping` TO `role3` +GRANT SELECT (`User`) ON `mysql`.`roles_mapping` TO `role1` +GRANT SELECT ON `test`.* TO `foo`@`localhost` +GRANT USAGE ON *.* TO `foo`@`localhost` +GRANT USAGE ON *.* TO `role10` +GRANT USAGE ON *.* TO `role1` +GRANT USAGE ON *.* TO `role2` +GRANT USAGE ON *.* TO `role3` +GRANT USAGE ON *.* TO `role4` +GRANT USAGE ON *.* TO `role5` +GRANT USAGE ON *.* TO `role6` +GRANT USAGE ON *.* TO `role7` +GRANT USAGE ON *.* TO `role9` +GRANT `role10` TO `foo`@`localhost` +GRANT `role1` TO `role2` +GRANT `role2` TO `role4` +GRANT `role2` TO `role5` +GRANT `role3` TO `role5` +GRANT `role4` TO `role6` +GRANT `role5` TO `role6` +GRANT `role5` TO `role7` +GRANT `role6` TO `role9` +GRANT `role7` TO `role9` +GRANT `role9` TO `role10` +connection default; +revoke select(User) on mysql.roles_mapping from role1; +show status like 'debug%'; +Variable_name Value +connection foo; +select count(concat(User,Host)) from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'User' in table 'roles_mapping' +select count(concat(Host)) from mysql.roles_mapping; +count(concat(Host)) +22 +connection default; +revoke select(Host) on mysql.roles_mapping from role3; +show status like 'debug%'; +Variable_name Value +connection foo; +select count(concat(Host)) from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysql`.`roles_mapping` +set role none; +connection default; +create procedure pr1() select "pr1"; +create function fn1() returns char(10) return "fn1"; +grant execute on procedure test.pr1 to role1; +show status like 'debug%'; +Variable_name Value +connection foo; +call pr1(); +ERROR 42000: execute command denied to user 'foo'@'localhost' for routine 'test.pr1' +set role role10; +call pr1(); +pr1 +pr1 +select fn1(); +ERROR 42000: execute command denied to user 'foo'@'localhost' for routine 'test.fn1' +connection default; +grant execute on function test.fn1 to role5; +show status like 'debug%'; +Variable_name Value +connection foo; +select fn1(); +fn1() +fn1 +connection default; +revoke execute on procedure test.pr1 from role1; +show status like 'debug%'; +Variable_name Value +connection foo; +call pr1(); +ERROR 42000: execute command denied to user 'foo'@'localhost' for routine 'test.pr1' +select fn1(); +fn1() +fn1 +connection default; +revoke execute on function test.fn1 from role5; +show status like 'debug%'; +Variable_name Value +connection foo; +select fn1(); +ERROR 42000: execute command denied to user 'foo'@'localhost' for routine 'test.fn1' +set role none; +connection default; +drop procedure pr1; +drop function fn1; +grant select on mysql.roles_mapping to role3; +show status like 'debug%'; +Variable_name Value +grant select on mysql.roles_mapping to role1; +show status like 'debug%'; +Variable_name Value +revoke select on mysql.roles_mapping from role3; +show status like 'debug%'; +Variable_name Value +revoke select on mysql.roles_mapping from role1; +show status like 'debug%'; +Variable_name Value +grant select on mysql.* to role1; +show status like 'debug%'; +Variable_name Value +grant select on test.* to role1; +show status like 'debug%'; +Variable_name Value +revoke select on mysql.* from role1; +show status like 'debug%'; +Variable_name Value +revoke select on test.* from role1; +show status like 'debug%'; +Variable_name Value +connection default; +drop user foo@localhost; +drop role role1; +drop role role2; +drop role role3; +drop role role4; +drop role role5; +drop role role6; +drop role role7; +drop role role8; +drop role role9; +drop role role10; diff --git a/mysql-test/suite/roles/recursive.test b/mysql-test/suite/roles/recursive.test new file mode 100644 index 00000000..0858f868 --- /dev/null +++ b/mysql-test/suite/roles/recursive.test @@ -0,0 +1,4 @@ + +source include/not_debug.inc; +source recursive.inc; + diff --git a/mysql-test/suite/roles/recursive_dbug.result b/mysql-test/suite/roles/recursive_dbug.result new file mode 100644 index 00000000..f6abc406 --- /dev/null +++ b/mysql-test/suite/roles/recursive_dbug.result @@ -0,0 +1,486 @@ +show status like 'debug%'; +Variable_name Value +set @old_dbug=@@global.debug_dbug; +set global debug_dbug="+d,role_merge_stats"; +create user foo@localhost; +grant select on test.* to foo@localhost; +create role role1; +create role role2; +create role role3; +create role role4; +create role role5; +create role role6; +create role role7; +create role role8; +create role role9; +create role role10; +grant role1 to role2; +grant role2 to role4; +grant role2 to role5; +grant role3 to role5; +grant role4 to role6; +grant role5 to role6; +grant role5 to role7; +grant role6 to role8; +grant role6 to role9; +grant role7 to role9; +grant role9 to role10; +grant role10 to foo@localhost; +grant role10 to role2; +ERROR HY000: Cannot grant role 'role10' to: 'role2' +connect foo, localhost, foo; +show grants; +Grants for foo@localhost +GRANT SELECT ON `test`.* TO `foo`@`localhost` +GRANT USAGE ON *.* TO `foo`@`localhost` +GRANT `role10` TO `foo`@`localhost` +select * from information_schema.applicable_roles; +GRANTEE ROLE_NAME IS_GRANTABLE IS_DEFAULT +foo@localhost role10 NO NO +role10 role9 NO NULL +role2 role1 NO NULL +role4 role2 NO NULL +role5 role2 NO NULL +role5 role3 NO NULL +role6 role4 NO NULL +role6 role5 NO NULL +role7 role5 NO NULL +role9 role6 NO NULL +role9 role7 NO NULL +show status like 'debug%'; +Variable_name Value +Debug_role_merges_global 11 +Debug_role_merges_db 0 +Debug_role_merges_table 0 +Debug_role_merges_column 0 +Debug_role_merges_routine 0 +connection default; +grant select on *.* to role1; +show status like 'debug%'; +Variable_name Value +Debug_role_merges_global 20 +Debug_role_merges_db 0 +Debug_role_merges_table 0 +Debug_role_merges_column 0 +Debug_role_merges_routine 0 +connection foo; +select count(*) from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysql`.`roles_mapping` +set role role10; +select count(*) from mysql.roles_mapping; +count(*) +22 +show grants; +Grants for foo@localhost +GRANT SELECT ON *.* TO `role1` +GRANT SELECT ON `test`.* TO `foo`@`localhost` +GRANT USAGE ON *.* TO `foo`@`localhost` +GRANT USAGE ON *.* TO `role10` +GRANT USAGE ON *.* TO `role2` +GRANT USAGE ON *.* TO `role3` +GRANT USAGE ON *.* TO `role4` +GRANT USAGE ON *.* TO `role5` +GRANT USAGE ON *.* TO `role6` +GRANT USAGE ON *.* TO `role7` +GRANT USAGE ON *.* TO `role9` +GRANT `role10` TO `foo`@`localhost` +GRANT `role1` TO `role2` +GRANT `role2` TO `role4` +GRANT `role2` TO `role5` +GRANT `role3` TO `role5` +GRANT `role4` TO `role6` +GRANT `role5` TO `role6` +GRANT `role5` TO `role7` +GRANT `role6` TO `role9` +GRANT `role7` TO `role9` +GRANT `role9` TO `role10` +select * from information_schema.enabled_roles; +ROLE_NAME +role1 +role10 +role2 +role3 +role4 +role5 +role6 +role7 +role9 +connection default; +revoke select on *.* from role1; +show status like 'debug%'; +Variable_name Value +Debug_role_merges_global 29 +Debug_role_merges_db 0 +Debug_role_merges_table 0 +Debug_role_merges_column 0 +Debug_role_merges_routine 0 +connection foo; +select count(*) from mysql.roles_mapping; +count(*) +22 +set role none; +set role role10; +select count(*) from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysql`.`roles_mapping` +set role none; +connection default; +grant select on mysql.* to role1; +show status like 'debug%'; +Variable_name Value +Debug_role_merges_global 29 +Debug_role_merges_db 9 +Debug_role_merges_table 0 +Debug_role_merges_column 0 +Debug_role_merges_routine 0 +connection foo; +select count(*) from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysql`.`roles_mapping` +set role role10; +select count(*) from mysql.roles_mapping; +count(*) +22 +show grants; +Grants for foo@localhost +GRANT SELECT ON `mysql`.* TO `role1` +GRANT SELECT ON `test`.* TO `foo`@`localhost` +GRANT USAGE ON *.* TO `foo`@`localhost` +GRANT USAGE ON *.* TO `role10` +GRANT USAGE ON *.* TO `role1` +GRANT USAGE ON *.* TO `role2` +GRANT USAGE ON *.* TO `role3` +GRANT USAGE ON *.* TO `role4` +GRANT USAGE ON *.* TO `role5` +GRANT USAGE ON *.* TO `role6` +GRANT USAGE ON *.* TO `role7` +GRANT USAGE ON *.* TO `role9` +GRANT `role10` TO `foo`@`localhost` +GRANT `role1` TO `role2` +GRANT `role2` TO `role4` +GRANT `role2` TO `role5` +GRANT `role3` TO `role5` +GRANT `role4` TO `role6` +GRANT `role5` TO `role6` +GRANT `role5` TO `role7` +GRANT `role6` TO `role9` +GRANT `role7` TO `role9` +GRANT `role9` TO `role10` +connection default; +revoke select on mysql.* from role1; +show status like 'debug%'; +Variable_name Value +Debug_role_merges_global 29 +Debug_role_merges_db 17 +Debug_role_merges_table 0 +Debug_role_merges_column 0 +Debug_role_merges_routine 0 +connection foo; +select count(*) from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysql`.`roles_mapping` +set role none; +connection default; +grant select on mysql.roles_mapping to role1; +show status like 'debug%'; +Variable_name Value +Debug_role_merges_global 29 +Debug_role_merges_db 17 +Debug_role_merges_table 9 +Debug_role_merges_column 0 +Debug_role_merges_routine 0 +connection foo; +select count(*) from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysql`.`roles_mapping` +set role role10; +select count(*) from mysql.roles_mapping; +count(*) +22 +show grants; +Grants for foo@localhost +GRANT SELECT ON `mysql`.`roles_mapping` TO `role1` +GRANT SELECT ON `test`.* TO `foo`@`localhost` +GRANT USAGE ON *.* TO `foo`@`localhost` +GRANT USAGE ON *.* TO `role10` +GRANT USAGE ON *.* TO `role1` +GRANT USAGE ON *.* TO `role2` +GRANT USAGE ON *.* TO `role3` +GRANT USAGE ON *.* TO `role4` +GRANT USAGE ON *.* TO `role5` +GRANT USAGE ON *.* TO `role6` +GRANT USAGE ON *.* TO `role7` +GRANT USAGE ON *.* TO `role9` +GRANT `role10` TO `foo`@`localhost` +GRANT `role1` TO `role2` +GRANT `role2` TO `role4` +GRANT `role2` TO `role5` +GRANT `role3` TO `role5` +GRANT `role4` TO `role6` +GRANT `role5` TO `role6` +GRANT `role5` TO `role7` +GRANT `role6` TO `role9` +GRANT `role7` TO `role9` +GRANT `role9` TO `role10` +connection default; +revoke select on mysql.roles_mapping from role1; +show status like 'debug%'; +Variable_name Value +Debug_role_merges_global 29 +Debug_role_merges_db 17 +Debug_role_merges_table 17 +Debug_role_merges_column 0 +Debug_role_merges_routine 0 +connection foo; +select count(*) from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysql`.`roles_mapping` +set role none; +connection default; +grant select(User) on mysql.roles_mapping to role1; +show status like 'debug%'; +Variable_name Value +Debug_role_merges_global 29 +Debug_role_merges_db 17 +Debug_role_merges_table 26 +Debug_role_merges_column 9 +Debug_role_merges_routine 0 +connection foo; +select count(*) from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysql`.`roles_mapping` +set role role10; +select count(concat(User,Host,Role)) from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'Host' in table 'roles_mapping' +select count(concat(User)) from mysql.roles_mapping; +count(concat(User)) +22 +show grants; +Grants for foo@localhost +GRANT SELECT (`User`) ON `mysql`.`roles_mapping` TO `role1` +GRANT SELECT ON `test`.* TO `foo`@`localhost` +GRANT USAGE ON *.* TO `foo`@`localhost` +GRANT USAGE ON *.* TO `role10` +GRANT USAGE ON *.* TO `role1` +GRANT USAGE ON *.* TO `role2` +GRANT USAGE ON *.* TO `role3` +GRANT USAGE ON *.* TO `role4` +GRANT USAGE ON *.* TO `role5` +GRANT USAGE ON *.* TO `role6` +GRANT USAGE ON *.* TO `role7` +GRANT USAGE ON *.* TO `role9` +GRANT `role10` TO `foo`@`localhost` +GRANT `role1` TO `role2` +GRANT `role2` TO `role4` +GRANT `role2` TO `role5` +GRANT `role3` TO `role5` +GRANT `role4` TO `role6` +GRANT `role5` TO `role6` +GRANT `role5` TO `role7` +GRANT `role6` TO `role9` +GRANT `role7` TO `role9` +GRANT `role9` TO `role10` +connection default; +grant select(Host) on mysql.roles_mapping to role3; +show status like 'debug%'; +Variable_name Value +Debug_role_merges_global 29 +Debug_role_merges_db 17 +Debug_role_merges_table 33 +Debug_role_merges_column 16 +Debug_role_merges_routine 0 +connection foo; +select count(concat(User,Host,Role)) from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'Role' in table 'roles_mapping' +select count(concat(User,Host)) from mysql.roles_mapping; +count(concat(User,Host)) +22 +show grants; +Grants for foo@localhost +GRANT SELECT (`Host`) ON `mysql`.`roles_mapping` TO `role3` +GRANT SELECT (`User`) ON `mysql`.`roles_mapping` TO `role1` +GRANT SELECT ON `test`.* TO `foo`@`localhost` +GRANT USAGE ON *.* TO `foo`@`localhost` +GRANT USAGE ON *.* TO `role10` +GRANT USAGE ON *.* TO `role1` +GRANT USAGE ON *.* TO `role2` +GRANT USAGE ON *.* TO `role3` +GRANT USAGE ON *.* TO `role4` +GRANT USAGE ON *.* TO `role5` +GRANT USAGE ON *.* TO `role6` +GRANT USAGE ON *.* TO `role7` +GRANT USAGE ON *.* TO `role9` +GRANT `role10` TO `foo`@`localhost` +GRANT `role1` TO `role2` +GRANT `role2` TO `role4` +GRANT `role2` TO `role5` +GRANT `role3` TO `role5` +GRANT `role4` TO `role6` +GRANT `role5` TO `role6` +GRANT `role5` TO `role7` +GRANT `role6` TO `role9` +GRANT `role7` TO `role9` +GRANT `role9` TO `role10` +connection default; +revoke select(User) on mysql.roles_mapping from role1; +show status like 'debug%'; +Variable_name Value +Debug_role_merges_global 29 +Debug_role_merges_db 17 +Debug_role_merges_table 41 +Debug_role_merges_column 24 +Debug_role_merges_routine 0 +connection foo; +select count(concat(User,Host)) from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'User' in table 'roles_mapping' +select count(concat(Host)) from mysql.roles_mapping; +count(concat(Host)) +22 +connection default; +revoke select(Host) on mysql.roles_mapping from role3; +show status like 'debug%'; +Variable_name Value +Debug_role_merges_global 29 +Debug_role_merges_db 17 +Debug_role_merges_table 47 +Debug_role_merges_column 30 +Debug_role_merges_routine 0 +connection foo; +select count(concat(Host)) from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysql`.`roles_mapping` +set role none; +connection default; +create procedure pr1() select "pr1"; +create function fn1() returns char(10) return "fn1"; +grant execute on procedure test.pr1 to role1; +show status like 'debug%'; +Variable_name Value +Debug_role_merges_global 29 +Debug_role_merges_db 17 +Debug_role_merges_table 47 +Debug_role_merges_column 30 +Debug_role_merges_routine 9 +connection foo; +call pr1(); +ERROR 42000: execute command denied to user 'foo'@'localhost' for routine 'test.pr1' +set role role10; +call pr1(); +pr1 +pr1 +select fn1(); +ERROR 42000: execute command denied to user 'foo'@'localhost' for routine 'test.fn1' +connection default; +grant execute on function test.fn1 to role5; +show status like 'debug%'; +Variable_name Value +Debug_role_merges_global 29 +Debug_role_merges_db 17 +Debug_role_merges_table 47 +Debug_role_merges_column 30 +Debug_role_merges_routine 15 +connection foo; +select fn1(); +fn1() +fn1 +connection default; +revoke execute on procedure test.pr1 from role1; +show status like 'debug%'; +Variable_name Value +Debug_role_merges_global 29 +Debug_role_merges_db 17 +Debug_role_merges_table 47 +Debug_role_merges_column 30 +Debug_role_merges_routine 23 +connection foo; +call pr1(); +ERROR 42000: execute command denied to user 'foo'@'localhost' for routine 'test.pr1' +select fn1(); +fn1() +fn1 +connection default; +revoke execute on function test.fn1 from role5; +show status like 'debug%'; +Variable_name Value +Debug_role_merges_global 29 +Debug_role_merges_db 17 +Debug_role_merges_table 47 +Debug_role_merges_column 30 +Debug_role_merges_routine 28 +connection foo; +select fn1(); +ERROR 42000: execute command denied to user 'foo'@'localhost' for routine 'test.fn1' +set role none; +connection default; +drop procedure pr1; +drop function fn1; +grant select on mysql.roles_mapping to role3; +show status like 'debug%'; +Variable_name Value +Debug_role_merges_global 29 +Debug_role_merges_db 17 +Debug_role_merges_table 54 +Debug_role_merges_column 30 +Debug_role_merges_routine 28 +grant select on mysql.roles_mapping to role1; +show status like 'debug%'; +Variable_name Value +Debug_role_merges_global 29 +Debug_role_merges_db 17 +Debug_role_merges_table 58 +Debug_role_merges_column 30 +Debug_role_merges_routine 28 +revoke select on mysql.roles_mapping from role3; +show status like 'debug%'; +Variable_name Value +Debug_role_merges_global 29 +Debug_role_merges_db 17 +Debug_role_merges_table 59 +Debug_role_merges_column 30 +Debug_role_merges_routine 28 +revoke select on mysql.roles_mapping from role1; +show status like 'debug%'; +Variable_name Value +Debug_role_merges_global 29 +Debug_role_merges_db 17 +Debug_role_merges_table 67 +Debug_role_merges_column 30 +Debug_role_merges_routine 28 +grant select on mysql.* to role1; +show status like 'debug%'; +Variable_name Value +Debug_role_merges_global 29 +Debug_role_merges_db 26 +Debug_role_merges_table 67 +Debug_role_merges_column 30 +Debug_role_merges_routine 28 +grant select on test.* to role1; +show status like 'debug%'; +Variable_name Value +Debug_role_merges_global 29 +Debug_role_merges_db 35 +Debug_role_merges_table 67 +Debug_role_merges_column 30 +Debug_role_merges_routine 28 +revoke select on mysql.* from role1; +show status like 'debug%'; +Variable_name Value +Debug_role_merges_global 29 +Debug_role_merges_db 43 +Debug_role_merges_table 67 +Debug_role_merges_column 30 +Debug_role_merges_routine 28 +revoke select on test.* from role1; +show status like 'debug%'; +Variable_name Value +Debug_role_merges_global 29 +Debug_role_merges_db 51 +Debug_role_merges_table 67 +Debug_role_merges_column 30 +Debug_role_merges_routine 28 +connection default; +drop user foo@localhost; +drop role role1; +drop role role2; +drop role role3; +drop role role4; +drop role role5; +drop role role6; +drop role role7; +drop role role8; +drop role role9; +drop role role10; +set global debug_dbug=@old_dbug; diff --git a/mysql-test/suite/roles/recursive_dbug.test b/mysql-test/suite/roles/recursive_dbug.test new file mode 100644 index 00000000..81169599 --- /dev/null +++ b/mysql-test/suite/roles/recursive_dbug.test @@ -0,0 +1,14 @@ +# +# run acl_roles_recursive and count the number of merges +# +source include/have_debug.inc; + +show status like 'debug%'; + +set @old_dbug=@@global.debug_dbug; +set global debug_dbug="+d,role_merge_stats"; + +source recursive.inc; + +set global debug_dbug=@old_dbug; + diff --git a/mysql-test/suite/roles/rename_user.result b/mysql-test/suite/roles/rename_user.result new file mode 100644 index 00000000..367f6e4b --- /dev/null +++ b/mysql-test/suite/roles/rename_user.result @@ -0,0 +1,36 @@ +create user test_user@localhost; +create role test_role1; +grant test_role1 to test_user@localhost; +create role test_role2; +grant test_role2 to test_role1; +use mysql; +select * from roles_mapping; +Host User Role Admin_option + test_role1 test_role2 N +localhost root test_role1 Y +localhost root test_role2 Y +localhost test_user test_role1 N +rename user 'test_user'@'localhost' to 'test_user_rm'@'newhost'; +select user, host from user where user like 'test%'; +User Host +test_role1 +test_role2 +test_user_rm newhost +select * from roles_mapping; +Host User Role Admin_option + test_role1 test_role2 N +localhost root test_role1 Y +localhost root test_role2 Y +newhost test_user_rm test_role1 N +delete from mysql.roles_mapping; +delete from mysql.user where user like 'test%'; +flush privileges; +# +# MDEV-29131 Assertion `status == 0' failed when renaming user after deleting table roles_mapping +# +create role r; +rename table mysql.roles_mapping to test.t1; +rename user current_user to a@a; +rename user a@a to root@localhost; +rename table test.t1 to mysql.roles_mapping; +drop role r; diff --git a/mysql-test/suite/roles/rename_user.test b/mysql-test/suite/roles/rename_user.test new file mode 100644 index 00000000..8c899352 --- /dev/null +++ b/mysql-test/suite/roles/rename_user.test @@ -0,0 +1,48 @@ +source include/not_embedded.inc; + +#create a user with no privileges +create user test_user@localhost; +create role test_role1; +grant test_role1 to test_user@localhost; +create role test_role2; +grant test_role2 to test_role1; + +use mysql; +--sorted_result +select * from roles_mapping; + +#regular user rename +rename user 'test_user'@'localhost' to 'test_user_rm'@'newhost'; +--sorted_result +select user, host from user where user like 'test%'; +--sorted_result +select * from roles_mapping; + +######### role rename does not work yet +#rename user 'test_role2'@'' to 'test_role2_rm'@''; +#--sorted_result +#select user, host from user where user like 'test%'; +#--sorted_result +#select * from roles_mapping; +# +##role rename +#rename user 'test_role1'@'' to 'test_role1_rm'@''; +#--sorted_result +#select user, host from user where user like 'test%'; +#--sorted_result +#select * from roles_mapping; + +delete from mysql.roles_mapping; +delete from mysql.user where user like 'test%'; +flush privileges; + +--echo # +--echo # MDEV-29131 Assertion `status == 0' failed when renaming user after deleting table roles_mapping +--echo # +create role r; +rename table mysql.roles_mapping to test.t1; +rename user current_user to a@a; +rename user a@a to root@localhost; +rename table test.t1 to mysql.roles_mapping; +drop role r; + diff --git a/mysql-test/suite/roles/revoke_all.result b/mysql-test/suite/roles/revoke_all.result new file mode 100644 index 00000000..864cc57a --- /dev/null +++ b/mysql-test/suite/roles/revoke_all.result @@ -0,0 +1,183 @@ +create role r1; +create role r2; +create role r3; +create role r4; +create user u1; +grant r2 to r1; +grant r3 to r2; +grant r4 to r3; +grant r1 to u1; +grant r4 to r1; +show grants for u1; +Grants for u1@% +GRANT USAGE ON *.* TO `u1`@`%` +GRANT `r1` TO `u1`@`%` +show grants for r1; +Grants for r1 +GRANT USAGE ON *.* TO `r1` +GRANT USAGE ON *.* TO `r2` +GRANT USAGE ON *.* TO `r3` +GRANT USAGE ON *.* TO `r4` +GRANT `r2` TO `r1` +GRANT `r3` TO `r2` +GRANT `r4` TO `r1` +GRANT `r4` TO `r3` +grant SELECT on *.* to u1; +grant INSERT on mysql.* to r1; +grant DELETE on mysql.roles_mapping to r2; +grant UPDATE on mysql.user to r3; +create function mysql.test_func (s CHAR(20)) +returns CHAR(50) DETERMINISTIC +return concat('Test string: ',s); +create procedure mysql.test_proc (OUT param1 INT) +begin +select COUNT(*) into param1 from mysql.roles_mapping; +end| +grant execute on function mysql.test_func to r2; +grant execute on procedure mysql.test_proc to r3; +grant execute on mysql.* to r4; +show grants for r1; +Grants for r1 +GRANT DELETE ON `mysql`.`roles_mapping` TO `r2` +GRANT EXECUTE ON FUNCTION `mysql`.`test_func` TO `r2` +GRANT EXECUTE ON PROCEDURE `mysql`.`test_proc` TO `r3` +GRANT EXECUTE ON `mysql`.* TO `r4` +GRANT INSERT ON `mysql`.* TO `r1` +GRANT UPDATE ON `mysql`.`user` TO `r3` +GRANT USAGE ON *.* TO `r1` +GRANT USAGE ON *.* TO `r2` +GRANT USAGE ON *.* TO `r3` +GRANT USAGE ON *.* TO `r4` +GRANT `r2` TO `r1` +GRANT `r3` TO `r2` +GRANT `r4` TO `r1` +GRANT `r4` TO `r3` +show grants for r2; +Grants for r2 +GRANT DELETE ON `mysql`.`roles_mapping` TO `r2` +GRANT EXECUTE ON FUNCTION `mysql`.`test_func` TO `r2` +GRANT EXECUTE ON PROCEDURE `mysql`.`test_proc` TO `r3` +GRANT EXECUTE ON `mysql`.* TO `r4` +GRANT UPDATE ON `mysql`.`user` TO `r3` +GRANT USAGE ON *.* TO `r2` +GRANT USAGE ON *.* TO `r3` +GRANT USAGE ON *.* TO `r4` +GRANT `r3` TO `r2` +GRANT `r4` TO `r3` +show grants for r3; +Grants for r3 +GRANT EXECUTE ON PROCEDURE `mysql`.`test_proc` TO `r3` +GRANT EXECUTE ON `mysql`.* TO `r4` +GRANT UPDATE ON `mysql`.`user` TO `r3` +GRANT USAGE ON *.* TO `r3` +GRANT USAGE ON *.* TO `r4` +GRANT `r4` TO `r3` +show grants for r4; +Grants for r4 +GRANT EXECUTE ON `mysql`.* TO `r4` +GRANT USAGE ON *.* TO `r4` +revoke all privileges, grant option from r4; +show grants for r1; +Grants for r1 +GRANT DELETE ON `mysql`.`roles_mapping` TO `r2` +GRANT EXECUTE ON FUNCTION `mysql`.`test_func` TO `r2` +GRANT EXECUTE ON PROCEDURE `mysql`.`test_proc` TO `r3` +GRANT INSERT ON `mysql`.* TO `r1` +GRANT UPDATE ON `mysql`.`user` TO `r3` +GRANT USAGE ON *.* TO `r1` +GRANT USAGE ON *.* TO `r2` +GRANT USAGE ON *.* TO `r3` +GRANT USAGE ON *.* TO `r4` +GRANT `r2` TO `r1` +GRANT `r3` TO `r2` +GRANT `r4` TO `r1` +GRANT `r4` TO `r3` +show grants for r2; +Grants for r2 +GRANT DELETE ON `mysql`.`roles_mapping` TO `r2` +GRANT EXECUTE ON FUNCTION `mysql`.`test_func` TO `r2` +GRANT EXECUTE ON PROCEDURE `mysql`.`test_proc` TO `r3` +GRANT UPDATE ON `mysql`.`user` TO `r3` +GRANT USAGE ON *.* TO `r2` +GRANT USAGE ON *.* TO `r3` +GRANT USAGE ON *.* TO `r4` +GRANT `r3` TO `r2` +GRANT `r4` TO `r3` +show grants for r3; +Grants for r3 +GRANT EXECUTE ON PROCEDURE `mysql`.`test_proc` TO `r3` +GRANT UPDATE ON `mysql`.`user` TO `r3` +GRANT USAGE ON *.* TO `r3` +GRANT USAGE ON *.* TO `r4` +GRANT `r4` TO `r3` +show grants for r4; +Grants for r4 +GRANT USAGE ON *.* TO `r4` +revoke all privileges, grant option from r3; +show grants for r1; +Grants for r1 +GRANT DELETE ON `mysql`.`roles_mapping` TO `r2` +GRANT EXECUTE ON FUNCTION `mysql`.`test_func` TO `r2` +GRANT INSERT ON `mysql`.* TO `r1` +GRANT USAGE ON *.* TO `r1` +GRANT USAGE ON *.* TO `r2` +GRANT USAGE ON *.* TO `r3` +GRANT USAGE ON *.* TO `r4` +GRANT `r2` TO `r1` +GRANT `r3` TO `r2` +GRANT `r4` TO `r1` +show grants for r2; +Grants for r2 +GRANT DELETE ON `mysql`.`roles_mapping` TO `r2` +GRANT EXECUTE ON FUNCTION `mysql`.`test_func` TO `r2` +GRANT USAGE ON *.* TO `r2` +GRANT USAGE ON *.* TO `r3` +GRANT `r3` TO `r2` +show grants for r3; +Grants for r3 +GRANT USAGE ON *.* TO `r3` +show grants for r4; +Grants for r4 +GRANT USAGE ON *.* TO `r4` +revoke all privileges, grant option from r2; +show grants for r1; +Grants for r1 +GRANT INSERT ON `mysql`.* TO `r1` +GRANT USAGE ON *.* TO `r1` +GRANT USAGE ON *.* TO `r2` +GRANT USAGE ON *.* TO `r4` +GRANT `r2` TO `r1` +GRANT `r4` TO `r1` +show grants for r2; +Grants for r2 +GRANT USAGE ON *.* TO `r2` +show grants for r3; +Grants for r3 +GRANT USAGE ON *.* TO `r3` +show grants for r4; +Grants for r4 +GRANT USAGE ON *.* TO `r4` +revoke all privileges, grant option from r1; +show grants for r1; +Grants for r1 +GRANT USAGE ON *.* TO `r1` +show grants for r2; +Grants for r2 +GRANT USAGE ON *.* TO `r2` +show grants for r3; +Grants for r3 +GRANT USAGE ON *.* TO `r3` +show grants for r4; +Grants for r4 +GRANT USAGE ON *.* TO `r4` +revoke all privileges, grant option from u1; +show grants for u1; +Grants for u1@% +GRANT USAGE ON *.* TO `u1`@`%` +drop function mysql.test_func; +drop procedure mysql.test_proc; +show grants for r1; +Grants for r1 +GRANT USAGE ON *.* TO `r1` +drop role r1, r2, r3, r4; +drop user u1; diff --git a/mysql-test/suite/roles/revoke_all.test b/mysql-test/suite/roles/revoke_all.test new file mode 100644 index 00000000..a3dee981 --- /dev/null +++ b/mysql-test/suite/roles/revoke_all.test @@ -0,0 +1,103 @@ +source include/not_embedded.inc; + +create role r1; +create role r2; +create role r3; +create role r4; +create user u1; + +#CREATE A CHAIN OF ROLES +grant r2 to r1; +grant r3 to r2; +grant r4 to r3; +grant r1 to u1; +grant r4 to r1; + +--sorted_result +show grants for u1; +--sorted_result +show grants for r1; + +grant SELECT on *.* to u1; +grant INSERT on mysql.* to r1; +grant DELETE on mysql.roles_mapping to r2; +grant UPDATE on mysql.user to r3; + +create function mysql.test_func (s CHAR(20)) +returns CHAR(50) DETERMINISTIC +return concat('Test string: ',s); + + +delimiter |; +create procedure mysql.test_proc (OUT param1 INT) +begin + select COUNT(*) into param1 from mysql.roles_mapping; +end| +delimiter ;| + +grant execute on function mysql.test_func to r2; +grant execute on procedure mysql.test_proc to r3; +grant execute on mysql.* to r4; + +--sorted_result +show grants for r1; +--sorted_result +show grants for r2; +--sorted_result +show grants for r3; +--sorted_result +show grants for r4; + +revoke all privileges, grant option from r4; + +--sorted_result +show grants for r1; +--sorted_result +show grants for r2; +--sorted_result +show grants for r3; +--sorted_result +show grants for r4; + +revoke all privileges, grant option from r3; +--sorted_result +show grants for r1; +--sorted_result +show grants for r2; +--sorted_result +show grants for r3; +--sorted_result +show grants for r4; + +revoke all privileges, grant option from r2; +--sorted_result +show grants for r1; +--sorted_result +show grants for r2; +--sorted_result +show grants for r3; +--sorted_result +show grants for r4; + +revoke all privileges, grant option from r1; +--sorted_result +show grants for r1; +--sorted_result +show grants for r2; +--sorted_result +show grants for r3; +--sorted_result +show grants for r4; + +revoke all privileges, grant option from u1; + +show grants for u1; + +drop function mysql.test_func; +drop procedure mysql.test_proc; + +--sorted_result +show grants for r1; + +drop role r1, r2, r3, r4; +drop user u1; diff --git a/mysql-test/suite/roles/role_case_sensitive-10744.result b/mysql-test/suite/roles/role_case_sensitive-10744.result new file mode 100644 index 00000000..8cb45b13 --- /dev/null +++ b/mysql-test/suite/roles/role_case_sensitive-10744.result @@ -0,0 +1,60 @@ +# +# MDEV-10744 Roles are not fully case-sensitive +# +# +# Test creating two case-different roles. +# +create user test_user@'%'; +create role test_ROLE; +create role test_role; +# +# Test if mysql.user has the roles created. +# +select user, host from mysql.user where is_role='y' and user like 'test%'; +User Host +test_ROLE +test_role +create database secret_db; +create table secret_db.t1 (secret varchar(100)); +insert into secret_db.t1 values ("Some Secret P4ssw0rd"); +grant select on secret_db.* to test_role; +grant test_role to test_user; +show grants for test_user; +Grants for test_user@% +GRANT `test_role` TO `test_user`@`%` +GRANT USAGE ON *.* TO `test_user`@`%` +# +# Now test the UPPER case role. +# +grant test_ROLE to test_user; +grant insert on secret_db.t1 to test_ROLE; +show grants for test_user; +Grants for test_user@% +GRANT `test_role` TO `test_user`@`%` +GRANT `test_ROLE` TO `test_user`@`%` +GRANT USAGE ON *.* TO `test_user`@`%` +connect test_user,localhost,test_user; +# +# Test users privileges when interacting with those roles; +# +show tables from secret_db; +ERROR 42000: Access denied for user 'test_user'@'%' to database 'secret_db' +set role test_ROLE; +show tables from secret_db; +Tables_in_secret_db +t1 +select * from secret_db.t1; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `secret_db`.`t1` +insert into secret_db.t1 values ("|-|4><"); +set role test_role; +select * from secret_db.t1 order by secret; +secret +Some Secret P4ssw0rd +|-|4>< +insert into secret_db.t1 values ("|_33T|-|4><"); +ERROR 42000: INSERT command denied to user 'test_user'@'localhost' for table `secret_db`.`t1` +connection default; +drop role test_ROLE; +drop role test_role; +drop user test_user; +drop database secret_db; diff --git a/mysql-test/suite/roles/role_case_sensitive-10744.test b/mysql-test/suite/roles/role_case_sensitive-10744.test new file mode 100644 index 00000000..281d61bc --- /dev/null +++ b/mysql-test/suite/roles/role_case_sensitive-10744.test @@ -0,0 +1,54 @@ +--source include/not_embedded.inc +--echo # +--echo # MDEV-10744 Roles are not fully case-sensitive +--echo # + +--echo # +--echo # Test creating two case-different roles. +--echo # +create user test_user@'%'; +create role test_ROLE; +create role test_role; +--echo # +--echo # Test if mysql.user has the roles created. +--echo # +--sorted_result +select user, host from mysql.user where is_role='y' and user like 'test%'; + +create database secret_db; +create table secret_db.t1 (secret varchar(100)); +insert into secret_db.t1 values ("Some Secret P4ssw0rd"); + +grant select on secret_db.* to test_role; +grant test_role to test_user; +show grants for test_user; +--echo # +--echo # Now test the UPPER case role. +--echo # +grant test_ROLE to test_user; +grant insert on secret_db.t1 to test_ROLE; +show grants for test_user; +connect (test_user,localhost,test_user); + +--echo # +--echo # Test users privileges when interacting with those roles; +--echo # +--error ER_DBACCESS_DENIED_ERROR +show tables from secret_db; +set role test_ROLE; +show tables from secret_db; +--error ER_TABLEACCESS_DENIED_ERROR +select * from secret_db.t1; +insert into secret_db.t1 values ("|-|4><"); +set role test_role; +select * from secret_db.t1 order by secret; +--error ER_TABLEACCESS_DENIED_ERROR +insert into secret_db.t1 values ("|_33T|-|4><"); + +connection default; + + +drop role test_ROLE; +drop role test_role; +drop user test_user; +drop database secret_db; diff --git a/mysql-test/suite/roles/role_grant_propagate.result b/mysql-test/suite/roles/role_grant_propagate.result new file mode 100644 index 00000000..111fd4db --- /dev/null +++ b/mysql-test/suite/roles/role_grant_propagate.result @@ -0,0 +1,180 @@ +# +# MDEV-29458 Role grant commands do not propagate all grants +# +create user foo; +create database some_db; +create table some_db.t1 (a int, b int, secret int); +CREATE PROCEDURE some_db.p1 (OUT param1 INT) +BEGIN +SELECT COUNT(*) INTO param1 FROM some_db.t1; +END; +// +CREATE FUNCTION some_db.f1 (param1 INT) RETURNS INT +BEGIN +DECLARE c INT; +SET c = 100; +RETURN param1 + c; +END; +// +# +# These roles will form a two level hierarchy. +# The "select" role will have the select privilege, while +# the active role will inherit the select role. +# +# The active role will be granted a different privilege but on the same +# level (global, database, table, proc respectively) *after* the 'select' +# role has been granted its select privilege. +# +create role r_select_global; +create role r_active_global; +create role r_select_database; +create role r_active_database; +create role r_select_table; +create role r_active_table; +create role r_select_column; +create role r_active_column; +create role r_execute_proc; +create role r_active_proc; +create role r_execute_func; +create role r_active_func; +grant r_select_global to r_active_global; +grant r_select_database to r_active_database; +grant r_select_table to r_active_table; +grant r_select_column to r_active_column; +grant r_execute_proc to r_active_proc; +grant r_execute_func to r_active_func; +# +# These 3 roles form a chain, where only the upper level has select +# privileges and the middle level will receive a grant for the same level +# privilege, but different kind (for example select on upper and insert +# on middle). +# +# The lower level should inherit both rights. +# +create role upper_level; +create role middle_level; +create role lower_level; +grant upper_level to middle_level; +grant middle_level to lower_level; +grant r_active_global to foo; +grant r_active_database to foo; +grant r_active_table to foo; +grant r_active_column to foo; +grant r_active_proc to foo; +grant r_active_func to foo; +grant lower_level to foo; +grant select on *.* to r_select_global; +grant select on some_db.* to r_select_database; +grant select on some_db.t1 to r_select_table; +grant select(a) on some_db.t1 to r_select_column; +grant select on *.* to upper_level; +grant execute on procedure some_db.p1 to r_execute_proc; +grant execute on function some_db.f1 to r_execute_func; +# +# Granting a privilege different than select on the corresponding level. +# This tests that the base role correctly inherits its granted roles +# privileges. +# +grant insert on *.* to r_active_global; +grant insert on some_db.* to r_active_database; +grant insert on some_db.t1 to r_active_table; +grant insert(a) on some_db.t1 to r_active_column; +grant insert on *.* to middle_level; +grant alter routine on procedure some_db.p1 to r_active_proc; +grant alter routine on function some_db.f1 to r_active_func; +connect con1, localhost, foo,,; +select * from some_db.t1; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `some_db`.`t1` +# +# Before MDEV-29458 fix, all these commands would return +# ER_TABLEACCESS_DENIED_ERROR +# +set role r_active_global; +select * from some_db.t1; +a b secret +set role r_active_database; +select * from some_db.t1; +a b secret +set role r_active_table; +select * from some_db.t1; +a b secret +set role r_active_column; +select a from some_db.t1; +a +set role lower_level; +select * from some_db.t1; +a b secret +set role r_active_proc; +set @var=100; +call some_db.p1(@var); +set role r_active_func; +select some_db.f1(10); +some_db.f1(10) +110 +disconnect con1; +# +# Cleanup. +# +connection default; +drop database some_db; +drop role r_select_global, r_select_database, r_select_table, r_select_column; +drop role r_active_global, r_active_database, r_active_table, r_active_column; +drop role r_execute_proc, r_execute_func; +drop role r_active_proc, r_active_func; +drop role upper_level, middle_level, lower_level; +drop user foo; +# +# Test that dropping of roles clears the intermediate generated +# (such as an `acl_dbs` element with 0 init_access, but with access != 0) +# datastructures. +# +create role test_role1; +create role test_role2; +grant test_role2 to test_role1; +grant select on mysql.* to test_role2; +grant select on mysql.user to test_role2; +grant select(user) on mysql.user to test_role2; +drop role test_role1, test_role2; +create role test_role1; +drop role test_role1; +# +# MDEV-29851 Cached role privileges are not invalidated when needed +# +create role admin; +create role student; +create database crm; +grant create on crm.* to admin; +grant select on crm.* to student; +create user intern@localhost; +grant student to intern@localhost; +set default role student for intern@localhost; +connect con1, localhost, intern; +use crm; +disconnect con1; +connection default; +grant admin to student; +connect con1, localhost, intern; +use crm; +create table t1 (a int); +disconnect con1; +connection default; +drop user intern@localhost; +drop role student; +drop role admin; +drop database crm; +# +# MDEV-30526 Assertion `rights == merged->cols' failed in update_role_columns +# +create table t1 ( pk int, i int); +create role a; +grant select (i), update (pk) on t1 to a; +revoke update (pk) on t1 from a; +show grants for a; +Grants for a +GRANT USAGE ON *.* TO `a` +GRANT SELECT (`i`) ON `test`.`t1` TO `a` +drop role a; +drop table t1; +# +# End of 10.3 tests +# diff --git a/mysql-test/suite/roles/role_grant_propagate.test b/mysql-test/suite/roles/role_grant_propagate.test new file mode 100644 index 00000000..02d451f0 --- /dev/null +++ b/mysql-test/suite/roles/role_grant_propagate.test @@ -0,0 +1,212 @@ +--source include/not_embedded.inc + +--echo # +--echo # MDEV-29458 Role grant commands do not propagate all grants +--echo # + +create user foo; +create database some_db; +create table some_db.t1 (a int, b int, secret int); + +delimiter //; +CREATE PROCEDURE some_db.p1 (OUT param1 INT) + BEGIN + SELECT COUNT(*) INTO param1 FROM some_db.t1; + END; +// +delimiter ;// + +delimiter //; +CREATE FUNCTION some_db.f1 (param1 INT) RETURNS INT + BEGIN + DECLARE c INT; + SET c = 100; + RETURN param1 + c; + END; +// +delimiter ;// + +--echo # +--echo # These roles will form a two level hierarchy. +--echo # The "select" role will have the select privilege, while +--echo # the active role will inherit the select role. +--echo # +--echo # The active role will be granted a different privilege but on the same +--echo # level (global, database, table, proc respectively) *after* the 'select' +--echo # role has been granted its select privilege. +--echo # + +create role r_select_global; +create role r_active_global; + +create role r_select_database; +create role r_active_database; + +create role r_select_table; +create role r_active_table; + +create role r_select_column; +create role r_active_column; + +create role r_execute_proc; +create role r_active_proc; + +create role r_execute_func; +create role r_active_func; + +grant r_select_global to r_active_global; +grant r_select_database to r_active_database; +grant r_select_table to r_active_table; +grant r_select_column to r_active_column; +grant r_execute_proc to r_active_proc; +grant r_execute_func to r_active_func; + +--echo # +--echo # These 3 roles form a chain, where only the upper level has select +--echo # privileges and the middle level will receive a grant for the same level +--echo # privilege, but different kind (for example select on upper and insert +--echo # on middle). +--echo # +--echo # The lower level should inherit both rights. +--echo # +create role upper_level; +create role middle_level; +create role lower_level; + +grant upper_level to middle_level; +grant middle_level to lower_level; + +grant r_active_global to foo; +grant r_active_database to foo; +grant r_active_table to foo; +grant r_active_column to foo; +grant r_active_proc to foo; +grant r_active_func to foo; +grant lower_level to foo; + +grant select on *.* to r_select_global; +grant select on some_db.* to r_select_database; +grant select on some_db.t1 to r_select_table; +grant select(a) on some_db.t1 to r_select_column; +grant select on *.* to upper_level; + +grant execute on procedure some_db.p1 to r_execute_proc; +grant execute on function some_db.f1 to r_execute_func; + + +--echo # +--echo # Granting a privilege different than select on the corresponding level. +--echo # This tests that the base role correctly inherits its granted roles +--echo # privileges. +--echo # +grant insert on *.* to r_active_global; +grant insert on some_db.* to r_active_database; +grant insert on some_db.t1 to r_active_table; +grant insert(a) on some_db.t1 to r_active_column; +grant insert on *.* to middle_level; + +grant alter routine on procedure some_db.p1 to r_active_proc; +grant alter routine on function some_db.f1 to r_active_func; + +--connect (con1, localhost, foo,,) +--error ER_TABLEACCESS_DENIED_ERROR +select * from some_db.t1; + +--echo # +--echo # Before MDEV-29458 fix, all these commands would return +--echo # ER_TABLEACCESS_DENIED_ERROR +--echo # +set role r_active_global; +select * from some_db.t1; +set role r_active_database; +select * from some_db.t1; +set role r_active_table; +select * from some_db.t1; +set role r_active_column; +select a from some_db.t1; +set role lower_level; +select * from some_db.t1; + +set role r_active_proc; +set @var=100; +call some_db.p1(@var); + +set role r_active_func; +select some_db.f1(10); + +disconnect con1; + +--echo # +--echo # Cleanup. +--echo # +connection default; + +drop database some_db; +drop role r_select_global, r_select_database, r_select_table, r_select_column; +drop role r_active_global, r_active_database, r_active_table, r_active_column; +drop role r_execute_proc, r_execute_func; +drop role r_active_proc, r_active_func; +drop role upper_level, middle_level, lower_level; +drop user foo; + +--echo # +--echo # Test that dropping of roles clears the intermediate generated +--echo # (such as an `acl_dbs` element with 0 init_access, but with access != 0) +--echo # datastructures. +--echo # +create role test_role1; +create role test_role2; + +grant test_role2 to test_role1; +grant select on mysql.* to test_role2; +grant select on mysql.user to test_role2; +grant select(user) on mysql.user to test_role2; +drop role test_role1, test_role2; + +create role test_role1; +drop role test_role1; + +--echo # +--echo # MDEV-29851 Cached role privileges are not invalidated when needed +--echo # +create role admin; +create role student; +create database crm; +grant create on crm.* to admin; +grant select on crm.* to student; +create user intern@localhost; +grant student to intern@localhost; +set default role student for intern@localhost; + +connect con1, localhost, intern; +use crm; +disconnect con1; + +connection default; +grant admin to student; + +connect con1, localhost, intern; +use crm; +create table t1 (a int); +disconnect con1; + +connection default; +drop user intern@localhost; +drop role student; +drop role admin; +drop database crm; + +--echo # +--echo # MDEV-30526 Assertion `rights == merged->cols' failed in update_role_columns +--echo # +create table t1 ( pk int, i int); +create role a; +grant select (i), update (pk) on t1 to a; +revoke update (pk) on t1 from a; +show grants for a; +drop role a; +drop table t1; + +--echo # +--echo # End of 10.3 tests +--echo # diff --git a/mysql-test/suite/roles/roles_tables_priv-29465.result b/mysql-test/suite/roles/roles_tables_priv-29465.result new file mode 100644 index 00000000..85ab1881 --- /dev/null +++ b/mysql-test/suite/roles/roles_tables_priv-29465.result @@ -0,0 +1,38 @@ +create user foo; +create database some_db; +create table some_db.t1 (a int, b int, secret int); +create role r_select_column; +create role r_active_column; +grant r_select_column to r_active_column; +grant r_active_column to foo; +grant select(a) on some_db.t1 to r_select_column; +select * from mysql.tables_priv order by user; +Host Db User Table_name Grantor Timestamp Table_priv Column_priv +localhost mysql mariadb.sys global_priv root@localhost 0000-00-00 00:00:00 Select,Delete + some_db r_select_column t1 root@localhost 0000-00-00 00:00:00 Select +grant insert(a) on some_db.t1 to r_active_column; +select * from mysql.tables_priv order by user; +Host Db User Table_name Grantor Timestamp Table_priv Column_priv +localhost mysql mariadb.sys global_priv root@localhost 0000-00-00 00:00:00 Select,Delete + some_db r_active_column t1 root@localhost 0000-00-00 00:00:00 Insert + some_db r_select_column t1 root@localhost 0000-00-00 00:00:00 Select +connect con1, localhost, foo,,; +insert into some_db.t1(a) values (1); +ERROR 42000: INSERT command denied to user 'foo'@'localhost' for table `some_db`.`t1` +set role r_active_column; +insert into some_db.t1(a) values (1); +disconnect con1; +connection default; +revoke insert(a) on some_db.t1 from r_active_column; +connect con1, localhost, foo,,; +insert into some_db.t1(a) values (1); +ERROR 42000: INSERT command denied to user 'foo'@'localhost' for table `some_db`.`t1` +set role r_active_column; +insert into some_db.t1(a) values (1); +ERROR 42000: INSERT command denied to user 'foo'@'localhost' for table `some_db`.`t1` +disconnect con1; +connection default; +drop role r_select_column; +drop role r_active_column; +drop user foo; +drop database some_db; diff --git a/mysql-test/suite/roles/roles_tables_priv-29465.test b/mysql-test/suite/roles/roles_tables_priv-29465.test new file mode 100644 index 00000000..550b05a4 --- /dev/null +++ b/mysql-test/suite/roles/roles_tables_priv-29465.test @@ -0,0 +1,40 @@ +--source include/not_embedded.inc + +create user foo; +create database some_db; +create table some_db.t1 (a int, b int, secret int); + +create role r_select_column; +create role r_active_column; +grant r_select_column to r_active_column; +grant r_active_column to foo; + +grant select(a) on some_db.t1 to r_select_column; +select * from mysql.tables_priv order by user; +grant insert(a) on some_db.t1 to r_active_column; +select * from mysql.tables_priv order by user; + +--connect (con1, localhost, foo,,) +--error ER_TABLEACCESS_DENIED_ERROR +insert into some_db.t1(a) values (1); +set role r_active_column; +insert into some_db.t1(a) values (1); +disconnect con1; + +connection default; +revoke insert(a) on some_db.t1 from r_active_column; + +--connect (con1, localhost, foo,,) +--error ER_TABLEACCESS_DENIED_ERROR +insert into some_db.t1(a) values (1); +set role r_active_column; +--error ER_TABLEACCESS_DENIED_ERROR +insert into some_db.t1(a) values (1); +disconnect con1; + +connection default; + +drop role r_select_column; +drop role r_active_column; +drop user foo; +drop database some_db; diff --git a/mysql-test/suite/roles/rpl_definer.result b/mysql-test/suite/roles/rpl_definer.result new file mode 100644 index 00000000..185b17fd --- /dev/null +++ b/mysql-test/suite/roles/rpl_definer.result @@ -0,0 +1,73 @@ +include/master-slave.inc +[connection master] +create role role1; +create role role2; +grant execute on test.* to role2; +grant role2 to role1; +set role role1; +show grants; +Grants for root@localhost +GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` WITH GRANT OPTION +GRANT EXECUTE ON `test`.* TO `role2` +GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION +GRANT USAGE ON *.* TO `role1` +GRANT USAGE ON *.* TO `role2` +GRANT `role1` TO `root`@`localhost` WITH ADMIN OPTION +GRANT `role2` TO `role1` +GRANT `role2` TO `root`@`localhost` WITH ADMIN OPTION +create definer=current_user procedure pcu() select current_user; +create definer=root@localhost procedure pu() select "root@localhost"; +create definer=current_role procedure pcr() select current_role; +create definer=role1 procedure pr() select "role1"; +show create procedure pcu; +Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation +pcu STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `pcu`() +select current_user latin1 latin1_swedish_ci latin1_swedish_ci +show create procedure pu; +Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation +pu STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `pu`() +select "root@localhost" latin1 latin1_swedish_ci latin1_swedish_ci +show create procedure pcr; +Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation +pcr STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`role1` PROCEDURE `pcr`() +select current_role latin1 latin1_swedish_ci latin1_swedish_ci +show create procedure pr; +Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation +pr STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`role1` PROCEDURE `pr`() +select "role1" latin1 latin1_swedish_ci latin1_swedish_ci +connection slave; +set role role1; +show grants; +Grants for root@localhost +GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` WITH GRANT OPTION +GRANT EXECUTE ON `test`.* TO `role2` +GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION +GRANT USAGE ON *.* TO `role1` +GRANT USAGE ON *.* TO `role2` +GRANT `role1` TO `root`@`localhost` WITH ADMIN OPTION +GRANT `role2` TO `role1` +GRANT `role2` TO `root`@`localhost` WITH ADMIN OPTION +show create procedure pcu; +Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation +pcu STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `pcu`() +select current_user latin1 latin1_swedish_ci latin1_swedish_ci +show create procedure pu; +Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation +pu STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `pu`() +select "root@localhost" latin1 latin1_swedish_ci latin1_swedish_ci +show create procedure pcr; +Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation +pcr STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`role1` PROCEDURE `pcr`() +select current_role latin1 latin1_swedish_ci latin1_swedish_ci +show create procedure pr; +Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation +pr STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`role1` PROCEDURE `pr`() +select "role1" latin1 latin1_swedish_ci latin1_swedish_ci +connection master; +drop procedure pcu; +drop procedure pu; +drop procedure pcr; +drop procedure pr; +drop role role1; +drop role role2; +include/rpl_end.inc diff --git a/mysql-test/suite/roles/rpl_definer.test b/mysql-test/suite/roles/rpl_definer.test new file mode 100644 index 00000000..8e19bd16 --- /dev/null +++ b/mysql-test/suite/roles/rpl_definer.test @@ -0,0 +1,46 @@ +# +# replication of the DEFINER=current_role +# + +--source include/master-slave.inc + +create role role1; +create role role2; +grant execute on test.* to role2; +grant role2 to role1; +set role role1; +--sorted_result +show grants; + +create definer=current_user procedure pcu() select current_user; +create definer=root@localhost procedure pu() select "root@localhost"; +create definer=current_role procedure pcr() select current_role; +create definer=role1 procedure pr() select "role1"; + +show create procedure pcu; +show create procedure pu; +show create procedure pcr; +show create procedure pr; + +sync_slave_with_master; + +set role role1; +--sorted_result +show grants; + +show create procedure pcu; +show create procedure pu; +show create procedure pcr; +show create procedure pr; + +connection master; + +drop procedure pcu; +drop procedure pu; +drop procedure pcr; +drop procedure pr; +drop role role1; +drop role role2; + +--source include/rpl_end.inc + diff --git a/mysql-test/suite/roles/rpl_grant_revoke_current_role-8638.result b/mysql-test/suite/roles/rpl_grant_revoke_current_role-8638.result new file mode 100644 index 00000000..ef2b9648 --- /dev/null +++ b/mysql-test/suite/roles/rpl_grant_revoke_current_role-8638.result @@ -0,0 +1,8 @@ +include/master-slave.inc +[connection master] +create role r1; +set role r1; +grant select on db.* to current_role; +revoke all privileges, grant option from current_role; +drop role r1; +include/rpl_end.inc diff --git a/mysql-test/suite/roles/rpl_grant_revoke_current_role-8638.test b/mysql-test/suite/roles/rpl_grant_revoke_current_role-8638.test new file mode 100644 index 00000000..10e5e938 --- /dev/null +++ b/mysql-test/suite/roles/rpl_grant_revoke_current_role-8638.test @@ -0,0 +1,12 @@ +--source include/have_binlog_format_mixed.inc +--source include/master-slave.inc + +--enable_connect_log + +create role r1; +set role r1; +grant select on db.* to current_role; +revoke all privileges, grant option from current_role; +drop role r1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/roles/set_and_drop.result b/mysql-test/suite/roles/set_and_drop.result new file mode 100644 index 00000000..e52a82bd --- /dev/null +++ b/mysql-test/suite/roles/set_and_drop.result @@ -0,0 +1,128 @@ +create database mysqltest1; +create table mysqltest1.t1 (a int, b int); +create table mysqltest1.t2 (a int, b int); +insert mysqltest1.t1 values (1,2),(3,4); +insert mysqltest1.t2 values (5,6),(7,8); +create procedure mysqltest1.pr1() select "pr1"; +create user foo@localhost; +create role role1; +create role role2; +grant role2 to role1; +grant role1 to foo@localhost; +grant reload on *.* to role2; +grant select on mysql.* to role2; +grant execute on procedure mysqltest1.pr1 to role2; +grant select on mysqltest1.t1 to role2; +grant select (a) on mysqltest1.t2 to role2; +connect foo,localhost,foo; +flush tables; +ERROR 42000: Access denied; you need (at least one of) the RELOAD privilege(s) for this operation +select * from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysql`.`roles_mapping` +show tables from mysqltest1; +ERROR 42000: Access denied for user 'foo'@'localhost' to database 'mysqltest1' +set role role1; +flush tables; +select * from mysql.roles_mapping; +Host User Role Admin_option + role1 role2 N +localhost foo role1 N +localhost root role1 Y +localhost root role2 Y +show tables from mysqltest1; +Tables_in_mysqltest1 +t1 +t2 +select * from mysqltest1.t1; +a b +1 2 +3 4 +select * from mysqltest1.t2; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysqltest1`.`t2` +select a from mysqltest1.t2; +a +5 +7 +call mysqltest1.pr1(); +pr1 +pr1 +connection default; +revoke execute on procedure mysqltest1.pr1 from role2; +connection foo; +call mysqltest1.pr1(); +ERROR 42000: execute command denied to user 'foo'@'localhost' for routine 'mysqltest1.pr1' +connection default; +drop role role2; +connection foo; +show grants; +Grants for foo@localhost +GRANT `role1` TO `foo`@`localhost` +GRANT USAGE ON *.* TO `foo`@`localhost` +GRANT USAGE ON *.* TO `role1` +select * from information_schema.enabled_roles; +ROLE_NAME +role1 +flush tables; +select * from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysql`.`roles_mapping` +select * from mysqltest1.t1; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysqltest1`.`t1` +select a from mysqltest1.t2; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysqltest1`.`t2` +set role none; +connection default; +grant reload on *.* to role1; +grant select on mysql.* to role1; +grant execute on procedure mysqltest1.pr1 to role1; +grant select on mysqltest1.t1 to role1; +grant select (a) on mysqltest1.t2 to role1; +connection foo; +set role role1; +flush tables; +select * from mysql.roles_mapping; +Host User Role Admin_option +localhost foo role1 N +localhost root role1 Y +show tables from mysqltest1; +Tables_in_mysqltest1 +t1 +t2 +select * from mysqltest1.t1; +a b +1 2 +3 4 +select * from mysqltest1.t2; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysqltest1`.`t2` +select a from mysqltest1.t2; +a +5 +7 +call mysqltest1.pr1(); +pr1 +pr1 +connection default; +drop role role1; +connection foo; +flush tables; +select * from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysql`.`roles_mapping` +select * from mysqltest1.t1; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysqltest1`.`t1` +select a from mysqltest1.t2; +ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table `mysqltest1`.`t2` +show grants; +Grants for foo@localhost +GRANT USAGE ON *.* TO `foo`@`localhost` +select * from information_schema.enabled_roles; +ROLE_NAME +NULL +select * from information_schema.enabled_roles; +ROLE_NAME +NULL +select current_role(); +current_role() +role1 +disconnect foo; +connection default; +drop user foo@localhost; +drop database mysqltest1; diff --git a/mysql-test/suite/roles/set_and_drop.test b/mysql-test/suite/roles/set_and_drop.test new file mode 100644 index 00000000..852e79fd --- /dev/null +++ b/mysql-test/suite/roles/set_and_drop.test @@ -0,0 +1,113 @@ +--source include/not_embedded.inc +# +# test setting and dropping a role +# + +create database mysqltest1; +create table mysqltest1.t1 (a int, b int); +create table mysqltest1.t2 (a int, b int); +insert mysqltest1.t1 values (1,2),(3,4); +insert mysqltest1.t2 values (5,6),(7,8); + +create procedure mysqltest1.pr1() select "pr1"; + +create user foo@localhost; +create role role1; +create role role2; + +grant role2 to role1; +grant role1 to foo@localhost; +grant reload on *.* to role2; +grant select on mysql.* to role2; +grant execute on procedure mysqltest1.pr1 to role2; +grant select on mysqltest1.t1 to role2; +grant select (a) on mysqltest1.t2 to role2; + +connect (foo,localhost,foo); + +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +flush tables; +--error ER_TABLEACCESS_DENIED_ERROR +select * from mysql.roles_mapping; +--error ER_DBACCESS_DENIED_ERROR +show tables from mysqltest1; + +set role role1; + +flush tables; +--sorted_result +select * from mysql.roles_mapping; +show tables from mysqltest1; +select * from mysqltest1.t1; +--error ER_TABLEACCESS_DENIED_ERROR +select * from mysqltest1.t2; +select a from mysqltest1.t2; +call mysqltest1.pr1(); + +connection default; +revoke execute on procedure mysqltest1.pr1 from role2; +connection foo; + +--error ER_PROCACCESS_DENIED_ERROR +call mysqltest1.pr1(); + +connection default; +drop role role2; +connection foo; + +show grants; +select * from information_schema.enabled_roles; + +flush tables; +--error ER_TABLEACCESS_DENIED_ERROR +select * from mysql.roles_mapping; +--error ER_TABLEACCESS_DENIED_ERROR +select * from mysqltest1.t1; +--error ER_TABLEACCESS_DENIED_ERROR +select a from mysqltest1.t2; + +set role none; + +connection default; + +grant reload on *.* to role1; +grant select on mysql.* to role1; +grant execute on procedure mysqltest1.pr1 to role1; +grant select on mysqltest1.t1 to role1; +grant select (a) on mysqltest1.t2 to role1; + +connection foo; +set role role1; + +flush tables; +--sorted_result +select * from mysql.roles_mapping; +show tables from mysqltest1; +select * from mysqltest1.t1; +--error ER_TABLEACCESS_DENIED_ERROR +select * from mysqltest1.t2; +select a from mysqltest1.t2; +call mysqltest1.pr1(); + +connection default; +drop role role1; +connection foo; + +flush tables; +--error ER_TABLEACCESS_DENIED_ERROR +select * from mysql.roles_mapping; +--error ER_TABLEACCESS_DENIED_ERROR +select * from mysqltest1.t1; +--error ER_TABLEACCESS_DENIED_ERROR +select a from mysqltest1.t2; + +show grants; +select * from information_schema.enabled_roles; +select * from information_schema.enabled_roles; # yes, repeat it twice +select current_role(); + +disconnect foo; +connection default; + +drop user foo@localhost; +drop database mysqltest1; diff --git a/mysql-test/suite/roles/set_default_role_clear.result b/mysql-test/suite/roles/set_default_role_clear.result new file mode 100644 index 00000000..8a3ae908 --- /dev/null +++ b/mysql-test/suite/roles/set_default_role_clear.result @@ -0,0 +1,36 @@ +create user test_user@localhost; +create role test_role; +grant select on *.* to test_role; +grant test_role to test_user@localhost; +show grants; +Grants for test_user@localhost +GRANT `test_role` TO `test_user`@`localhost` +GRANT USAGE ON *.* TO `test_user`@`localhost` +set default role test_role; +select user, host, default_role from mysql.user; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `mysql`.`user` +select user, host, default_role from mysql.user where user='test_user'; +User Host default_role +test_user localhost test_role +show grants; +Grants for test_user@localhost +GRANT `test_role` TO `test_user`@`localhost` +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT SELECT ON *.* TO `test_role` +SET DEFAULT ROLE `test_role` FOR `test_user`@`localhost` +select user, host, default_role from mysql.user where user='test_user'; +User Host default_role +test_user localhost test_role +set default role NONE; +select user, host, default_role from mysql.user where user='test_user'; +User Host default_role +test_user localhost +set default role invalid_role; +ERROR OP000: Invalid role specification `invalid_role` +select user, host, default_role from mysql.user where user='test_user'; +User Host default_role +test_user localhost +select user, host, default_role from mysql.user; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `mysql`.`user` +drop role test_role; +drop user test_user@localhost; diff --git a/mysql-test/suite/roles/set_default_role_clear.test b/mysql-test/suite/roles/set_default_role_clear.test new file mode 100644 index 00000000..32c9661c --- /dev/null +++ b/mysql-test/suite/roles/set_default_role_clear.test @@ -0,0 +1,52 @@ +source include/not_embedded.inc; + +# This test checks clearing a default role from a user. + +# Create a user with no privileges +create user test_user@localhost; + +create role test_role; + +grant select on *.* to test_role; +grant test_role to test_user@localhost; + +change_user 'test_user'; +show grants; +set default role test_role; + +# Even though a user has the default role set, without reconnecting, we should +# not already have the roles privileges. +--error ER_TABLEACCESS_DENIED_ERROR +select user, host, default_role from mysql.user; + +change_user 'root'; +select user, host, default_role from mysql.user where user='test_user'; + +change_user 'test_user'; +# This should show that the new test_user has the role's grants enabled. +show grants; +select user, host, default_role from mysql.user where user='test_user'; + +set default role NONE; + +# We should still have the role set right now. +select user, host, default_role from mysql.user where user='test_user'; + +# Make sure we do not somehow get privileges to set an invalid role +--error ER_INVALID_ROLE +set default role invalid_role; + +change_user 'root'; +select user, host, default_role from mysql.user where user='test_user'; + +change_user 'test_user'; +# The user does not have a default role set anymore. Make sure we don't still +# get the privileges. +--error ER_TABLEACCESS_DENIED_ERROR +select user, host, default_role from mysql.user; + +change_user 'root'; + +# Cleanup +drop role test_role; +drop user test_user@localhost; diff --git a/mysql-test/suite/roles/set_default_role_for.result b/mysql-test/suite/roles/set_default_role_for.result new file mode 100644 index 00000000..57a14711 --- /dev/null +++ b/mysql-test/suite/roles/set_default_role_for.result @@ -0,0 +1,60 @@ +create user user_a@localhost; +create user user_b@localhost; +create role role_a; +create role role_b; +grant role_a to user_a@localhost; +grant role_b to user_b@localhost; +grant role_a to user_a@localhost; +grant select on *.* to role_a; +grant role_b to user_b@localhost; +grant insert, update on *.* to role_b; +set default role role_a for user_b@localhost; +ERROR 42000: Access denied for user 'user_a'@'localhost' to database 'mysql' +set default role role_a for user_a@localhost; +set default role invalid_role for user_a@localhost; +ERROR OP000: Invalid role specification `invalid_role` +set default role role_b for user_a@localhost; +ERROR OP000: User `root`@`localhost` has not been granted role `role_b` +set default role role_b for user_b@localhost; +show grants; +Grants for user_a@localhost +GRANT `role_a` TO `user_a`@`localhost` +GRANT USAGE ON *.* TO `user_a`@`localhost` +GRANT SELECT ON *.* TO `role_a` +SET DEFAULT ROLE `role_a` FOR `user_a`@`localhost` +select user, host, default_role from mysql.user where user like 'user_%'; +User Host default_role +user_a localhost role_a +user_b localhost role_b +set default role NONE for current_user; +select user, host, default_role from mysql.user where user like 'user_%'; +User Host default_role +user_a localhost +user_b localhost role_b +set default role current_role for current_user; +select user, host, default_role from mysql.user where user like 'user_%'; +User Host default_role +user_a localhost role_a +user_b localhost role_b +set default role role_b for current_user; +ERROR OP000: User `user_a`@`localhost` has not been granted role `role_b` +show grants; +Grants for user_b@localhost +GRANT `role_b` TO `user_b`@`localhost` +GRANT USAGE ON *.* TO `user_b`@`localhost` +GRANT INSERT, UPDATE ON *.* TO `role_b` +SET DEFAULT ROLE `role_b` FOR `user_b`@`localhost` +select user, host, default_role from mysql.user where user like 'user_%'; +ERROR 42000: SELECT command denied to user 'user_b'@'localhost' for table `mysql`.`user` +set default role NONE for user_a@localhost; +show grants; +Grants for user_a@localhost +GRANT `role_a` TO `user_a`@`localhost` +GRANT USAGE ON *.* TO `user_a`@`localhost` +GRANT INSERT, UPDATE ON *.* TO `role_b` +select user, host, default_role from mysql.user where user like 'user_%'; +ERROR 42000: SELECT command denied to user 'user_a'@'localhost' for table `mysql`.`user` +drop role role_a; +drop role role_b; +drop user user_a@localhost; +drop user user_b@localhost; diff --git a/mysql-test/suite/roles/set_default_role_for.test b/mysql-test/suite/roles/set_default_role_for.test new file mode 100644 index 00000000..eff999a5 --- /dev/null +++ b/mysql-test/suite/roles/set_default_role_for.test @@ -0,0 +1,84 @@ +source include/not_embedded.inc; + +# This test checks setting a default role to a different user; + + +create user user_a@localhost; +create user user_b@localhost; + +create role role_a; +create role role_b; + +grant role_a to user_a@localhost; +grant role_b to user_b@localhost; + +grant role_a to user_a@localhost; +grant select on *.* to role_a; + +grant role_b to user_b@localhost; +grant insert, update on *.* to role_b; + +change_user 'user_a'; + +# A user should not be a able to set a default role for someone else, +# if he hasn't got write access to the database. +--error ER_DBACCESS_DENIED_ERROR +set default role role_a for user_b@localhost; + +# Should have the same effect as set default role role_a. +set default role role_a for user_a@localhost; + +change_user 'root'; + +# Not even a 'root' user should be able to set an invalid role for a user. +--error ER_INVALID_ROLE +set default role invalid_role for user_a@localhost; + +--error ER_INVALID_ROLE +set default role role_b for user_a@localhost; + +# Make sure we can set a default role for a different user than the one that +# is actually running the command. +set default role role_b for user_b@localhost; + +change_user 'user_a'; + +show grants; +--sorted_result +select user, host, default_role from mysql.user where user like 'user_%'; + +set default role NONE for current_user; +--sorted_result +select user, host, default_role from mysql.user where user like 'user_%'; + +set default role current_role for current_user; +--sorted_result +select user, host, default_role from mysql.user where user like 'user_%'; + +# Make sure we can't set a default role not granted to us, using current_user +--error ER_INVALID_ROLE +set default role role_b for current_user; + +change_user 'user_b'; + +show grants; +--error ER_TABLEACCESS_DENIED_ERROR +select user, host, default_role from mysql.user where user like 'user_%'; + +# Since we have update privileges on the mysql.user table, we should +# be able to set a default role for a different user. +set default role NONE for user_a@localhost; + +change_user 'user_a'; + +# There is no default role set any more. +show grants; +--error ER_TABLEACCESS_DENIED_ERROR +select user, host, default_role from mysql.user where user like 'user_%'; + +change_user 'root'; + +drop role role_a; +drop role role_b; +drop user user_a@localhost; +drop user user_b@localhost; diff --git a/mysql-test/suite/roles/set_default_role_invalid.result b/mysql-test/suite/roles/set_default_role_invalid.result new file mode 100644 index 00000000..12e2c035 --- /dev/null +++ b/mysql-test/suite/roles/set_default_role_invalid.result @@ -0,0 +1,130 @@ +create user test_user@localhost; +create role test_role; +create role not_granted_role; +grant select on *.* to test_role; +grant test_role to test_user@localhost; +show grants; +Grants for test_user@localhost +GRANT `test_role` TO `test_user`@`localhost` +GRANT USAGE ON *.* TO `test_user`@`localhost` +select user, host, default_role from mysql.user; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `mysql`.`user` +set default role invalid_role; +ERROR OP000: Invalid role specification `invalid_role` +set default role not_granted_role; +ERROR OP000: Invalid role specification `not_granted_role` +set default role test_role; +select user, host, default_role from mysql.user; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `mysql`.`user` +select user, host, default_role from mysql.user where user='test_user'; +User Host default_role +test_user localhost test_role +show grants; +Grants for test_user@localhost +GRANT `test_role` TO `test_user`@`localhost` +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT SELECT ON *.* TO `test_role` +SET DEFAULT ROLE `test_role` FOR `test_user`@`localhost` +select user, host, default_role from mysql.user where user='test_user'; +User Host default_role +test_user localhost test_role +set default role invalid_role; +ERROR OP000: Invalid role specification `invalid_role` +select user, host, default_role from mysql.user where user='test_user'; +User Host default_role +test_user localhost test_role +revoke test_role from test_user@localhost; +select user, host, default_role from mysql.user where user='test_user'; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `mysql`.`user` +drop role test_role; +drop role not_granted_role; +drop user test_user@localhost; +# +# MDEV-22312: Bad error message for SET DEFAULT ROLE when user account +# is not granted the role +# +CREATE USER a; +CREATE USER b; +CREATE ROLE r1; +CREATE ROLE r2; +SET DEFAULT ROLE r1 FOR a; +ERROR OP000: User `root`@`localhost` has not been granted role `r1` +GRANT r1 TO b; +GRANT r2 TO b; +SET DEFAULT ROLE r1 FOR b; +# Change user b +SELECT CURRENT_ROLE; +CURRENT_ROLE +r1 +SET ROLE r2; +SELECT CURRENT_ROLE; +CURRENT_ROLE +r2 +SET DEFAULT ROLE r1 FOR a; +ERROR 42000: Access denied for user 'b'@'%' to database 'mysql' +SET DEFAULT ROLE r2; +# Change user root (session 1: select_priv to b) +GRANT SELECT ON mysql.* TO b; +# Change user b (session 1: select_priv) +SHOW GRANTS FOR b; +Grants for b@% +GRANT `r1` TO `b`@`%` +GRANT `r2` TO `b`@`%` +GRANT USAGE ON *.* TO `b`@`%` +GRANT SELECT ON `mysql`.* TO `b`@`%` +SET DEFAULT ROLE `r2` FOR `b`@`%` +SET DEFAULT ROLE r1 FOR a; +ERROR 42000: Access denied for user 'b'@'%' to database 'mysql' +SELECT CURRENT_ROLE; +CURRENT_ROLE +r2 +SET DEFAULT ROLE NONE; +SELECT CURRENT_ROLE; +CURRENT_ROLE +r2 +SET DEFAULT ROLE current_role FOR current_user; +SET DEFAULT ROLE invalid_role; +ERROR OP000: Invalid role specification `invalid_role` +SET DEFAULT ROLE invalid_role FOR a; +ERROR 42000: Access denied for user 'b'@'%' to database 'mysql' +SET DEFAULT ROLE none FOR a; +ERROR 42000: Access denied for user 'b'@'%' to database 'mysql' +# Change user root (session 2: adding update_priv to user b) +GRANT UPDATE ON mysql.* TO b; +# Change user b +SHOW GRANTS FOR b; +Grants for b@% +GRANT `r1` TO `b`@`%` +GRANT `r2` TO `b`@`%` +GRANT USAGE ON *.* TO `b`@`%` +GRANT SELECT, UPDATE ON `mysql`.* TO `b`@`%` +SET DEFAULT ROLE `r2` FOR `b`@`%` +SET DEFAULT ROLE r1 FOR a; +ERROR OP000: User `b`@`%` has not been granted role `r1` +SET DEFAULT ROLE invalid_role; +ERROR OP000: Invalid role specification `invalid_role` +SET DEFAULT ROLE invalid_role FOR a; +ERROR OP000: Invalid role specification `invalid_role` +SET DEFAULT ROLE none FOR a; +# Change user root (session 3: Grant role to user a) +GRANT r1 TO a; +SET DEFAULT ROLE r1 FOR a; +# Change user a (verify session 3) +SELECT CURRENT_ROLE; +CURRENT_ROLE +r1 +SET DEFAULT ROLE None; +# Change user b (session 3: role granted to user a) +SET DEFAULT ROLE r1 FOR a; +SET DEFAULT ROLE r2 FOR a; +ERROR OP000: User `b`@`%` has not been granted role `r2` +SET DEFAULT ROLE invalid_role; +ERROR OP000: Invalid role specification `invalid_role` +SET DEFAULT ROLE invalid_role FOR a; +ERROR OP000: Invalid role specification `invalid_role` +SELECT user, host, default_role FROM mysql.user where user='a' or user='b'; +User Host default_role +a % r1 +b % r2 +DROP ROLE r1, r2; +DROP USER a, b; diff --git a/mysql-test/suite/roles/set_default_role_invalid.test b/mysql-test/suite/roles/set_default_role_invalid.test new file mode 100644 index 00000000..02fca110 --- /dev/null +++ b/mysql-test/suite/roles/set_default_role_invalid.test @@ -0,0 +1,169 @@ +source include/not_embedded.inc; + +# This test checks the error paths possible during set default role. + +# Create a user with no privileges +create user test_user@localhost; + +create role test_role; +create role not_granted_role; + +grant select on *.* to test_role; +grant test_role to test_user@localhost; + +change_user 'test_user'; +show grants; +--error ER_TABLEACCESS_DENIED_ERROR +select user, host, default_role from mysql.user; + +# A user can not set a default role that does not exist in the database. +--error ER_INVALID_ROLE +set default role invalid_role; + +# A user can not set a default role if he can not call set role <role>. +--error ER_INVALID_ROLE +set default role not_granted_role; + +set default role test_role; + +# Even though a user has the default role set, without reconnecting, we should +# not already have the roles privileges. +--error ER_TABLEACCESS_DENIED_ERROR +select user, host, default_role from mysql.user; + +change_user 'root'; +select user, host, default_role from mysql.user where user='test_user'; + +change_user 'test_user'; +# This should show that the new test_user has the role's grants enabled. +show grants; +select user, host, default_role from mysql.user where user='test_user'; + +# If we have a failed set default role attempt, don't change the already set +# default role. +--error ER_INVALID_ROLE +set default role invalid_role; +select user, host, default_role from mysql.user where user='test_user'; + +change_user 'root'; +# Now, even though a default role is still set for test_user, make sure the +# user does not get the rights, if he can not set the role. +revoke test_role from test_user@localhost; + +change_user 'test_user'; +--error ER_TABLEACCESS_DENIED_ERROR +select user, host, default_role from mysql.user where user='test_user'; + +change_user 'root'; + +# Cleanup +drop role test_role; +drop role not_granted_role; +drop user test_user@localhost; + +--echo # +--echo # MDEV-22312: Bad error message for SET DEFAULT ROLE when user account +--echo # is not granted the role +--echo # + +CREATE USER a; +CREATE USER b; +CREATE ROLE r1; +CREATE ROLE r2; +# Role has not been granted to user a, but the role is visible to current_user +--error ER_INVALID_ROLE +SET DEFAULT ROLE r1 FOR a; +# Granting roles to user b +GRANT r1 TO b; +GRANT r2 TO b; +# After granting the role, role can be set as default +SET DEFAULT ROLE r1 FOR b; + +--echo # Change user b +change_user b; +SELECT CURRENT_ROLE; +SET ROLE r2; +SELECT CURRENT_ROLE; +# User b has no UPDATE_PRIV for mysql.user +--error ER_DBACCESS_DENIED_ERROR +SET DEFAULT ROLE r1 FOR a; +SET DEFAULT ROLE r2; + +--echo # Change user root (session 1: select_priv to b) +change_user root; +# Let's grant select_priv to user b +GRANT SELECT ON mysql.* TO b; + +--echo # Change user b (session 1: select_priv) +change_user b; +SHOW GRANTS FOR b; +# User must have update_priv before setting the role +--error ER_DBACCESS_DENIED_ERROR +SET DEFAULT ROLE r1 FOR a; +# Testing the `CURRENT_ROLE` as a special case +SELECT CURRENT_ROLE; +SET DEFAULT ROLE NONE; +SELECT CURRENT_ROLE; +SET DEFAULT ROLE current_role FOR current_user; +# Testing of non-existing role +--error ER_INVALID_ROLE +SET DEFAULT ROLE invalid_role; +# Testing of non-existing role for different user +--error ER_DBACCESS_DENIED_ERROR +SET DEFAULT ROLE invalid_role FOR a; +# Testing the `None` role for different user +-- error ER_DBACCESS_DENIED_ERROR +SET DEFAULT ROLE none FOR a; + +--echo # Change user root (session 2: adding update_priv to user b) +change_user root; +# update_priv are enough +GRANT UPDATE ON mysql.* TO b; + +--echo # Change user b +change_user b; +SHOW GRANTS FOR b; +# In all tests in session user a has not been granted the role +# Testing setting role for different user, should fail with new error +--error ER_INVALID_ROLE +SET DEFAULT ROLE r1 FOR a; +# Testing of non-existing role +--error ER_INVALID_ROLE +SET DEFAULT ROLE invalid_role; +# Testing of non-existing role for different user with update_priv +--error ER_INVALID_ROLE +SET DEFAULT ROLE invalid_role FOR a; +# Testing the `None` role for different user with update_priv +SET DEFAULT ROLE none FOR a; + +--echo # Change user root (session 3: Grant role to user a) +change_user root; +# After granting the privilege for a, user b can set default role +GRANT r1 TO a; +SET DEFAULT ROLE r1 FOR a; + +--echo # Change user a (verify session 3) +change_user a; +SELECT CURRENT_ROLE; +SET DEFAULT ROLE None; + +--echo # Change user b (session 3: role granted to user a) +change_user b; +# This should set role because b has update_priv +SET DEFAULT ROLE r1 FOR a; +# Testing non-granted role r2 still should fail +-- error ER_INVALID_ROLE +SET DEFAULT ROLE r2 FOR a; +# Testing of non-existing role +--error ER_INVALID_ROLE +SET DEFAULT ROLE invalid_role; +# Testing of non-existing role for different user +--error ER_INVALID_ROLE +SET DEFAULT ROLE invalid_role FOR a; + +# Clear the workspace +change_user root; +--sorted_result +SELECT user, host, default_role FROM mysql.user where user='a' or user='b'; +DROP ROLE r1, r2; +DROP USER a, b; diff --git a/mysql-test/suite/roles/set_default_role_new_connection.result b/mysql-test/suite/roles/set_default_role_new_connection.result new file mode 100644 index 00000000..95c71274 --- /dev/null +++ b/mysql-test/suite/roles/set_default_role_new_connection.result @@ -0,0 +1,62 @@ +create user test_user@localhost; +create role test_role; +grant select on *.* to test_role; +grant test_role to test_user@localhost; +connect c1, localhost, test_user,,; +show grants; +Grants for test_user@localhost +GRANT `test_role` TO `test_user`@`localhost` +GRANT USAGE ON *.* TO `test_user`@`localhost` +select user, host, default_role from mysql.user where user = 'test_user'; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `mysql`.`user` +set default role test_role; +select user, host, default_role from mysql.user where user = 'test_user'; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `mysql`.`user` +disconnect c1; +connection default; +select user, host, default_role from mysql.user where user = 'test_user'; +User Host default_role +test_user localhost test_role +connect c1, localhost, test_user,,; +show grants; +Grants for test_user@localhost +GRANT `test_role` TO `test_user`@`localhost` +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT SELECT ON *.* TO `test_role` +SET DEFAULT ROLE `test_role` FOR `test_user`@`localhost` +select user, host, default_role from mysql.user where user = 'test_user'; +User Host default_role +test_user localhost test_role +set default role NONE; +disconnect c1; +connection default; +select user, host, default_role from mysql.user where user = 'test_user'; +User Host default_role +test_user localhost +connect c1, localhost, test_user,,; +show grants; +Grants for test_user@localhost +GRANT `test_role` TO `test_user`@`localhost` +GRANT USAGE ON *.* TO `test_user`@`localhost` +select user, host, default_role from mysql.user where user = 'test_user'; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `mysql`.`user` +disconnect c1; +connection default; +select user, host, default_role from mysql.user where user = 'test_user'; +User Host default_role +test_user localhost +set default role test_role for test_user@localhost; +connect c1, localhost, test_user,,; +show grants; +Grants for test_user@localhost +GRANT `test_role` TO `test_user`@`localhost` +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT SELECT ON *.* TO `test_role` +SET DEFAULT ROLE `test_role` FOR `test_user`@`localhost` +select user, host, default_role from mysql.user where user = 'test_user'; +User Host default_role +test_user localhost test_role +disconnect c1; +connection default; +drop role test_role; +drop user test_user@localhost; diff --git a/mysql-test/suite/roles/set_default_role_new_connection.test b/mysql-test/suite/roles/set_default_role_new_connection.test new file mode 100644 index 00000000..81f7f2ff --- /dev/null +++ b/mysql-test/suite/roles/set_default_role_new_connection.test @@ -0,0 +1,47 @@ +source include/not_embedded.inc; + +create user test_user@localhost; +create role test_role; +grant select on *.* to test_role; +grant test_role to test_user@localhost; + +--connect (c1, localhost, test_user,,) +show grants; +--error ER_TABLEACCESS_DENIED_ERROR +select user, host, default_role from mysql.user where user = 'test_user'; +set default role test_role; +--error ER_TABLEACCESS_DENIED_ERROR +select user, host, default_role from mysql.user where user = 'test_user'; +disconnect c1; + +connection default; +select user, host, default_role from mysql.user where user = 'test_user'; + + +--connect (c1, localhost, test_user,,) +show grants; +select user, host, default_role from mysql.user where user = 'test_user'; +set default role NONE; +disconnect c1; + +connection default; +select user, host, default_role from mysql.user where user = 'test_user'; + +--connect (c1, localhost, test_user,,) +show grants; +--error ER_TABLEACCESS_DENIED_ERROR +select user, host, default_role from mysql.user where user = 'test_user'; +disconnect c1; + +connection default; +select user, host, default_role from mysql.user where user = 'test_user'; +set default role test_role for test_user@localhost; + +--connect (c1, localhost, test_user,,) +show grants; +select user, host, default_role from mysql.user where user = 'test_user'; +disconnect c1; + +connection default; +drop role test_role; +drop user test_user@localhost; diff --git a/mysql-test/suite/roles/set_default_role_ps-6960.result b/mysql-test/suite/roles/set_default_role_ps-6960.result new file mode 100644 index 00000000..505861e8 --- /dev/null +++ b/mysql-test/suite/roles/set_default_role_ps-6960.result @@ -0,0 +1,10 @@ +select priv into @root_priv from mysql.global_priv where user='root' and host='localhost'; +create role r1; +prepare stmt from "set password = '11111111111111111111111111111111111111111'"; +execute stmt; +prepare stmt from "set default role r1"; +execute stmt; +set password = ''; +set default role NONE; +drop role r1; +update mysql.global_priv set priv=@root_priv where user='root' and host='localhost'; diff --git a/mysql-test/suite/roles/set_default_role_ps-6960.test b/mysql-test/suite/roles/set_default_role_ps-6960.test new file mode 100644 index 00000000..fd965c2a --- /dev/null +++ b/mysql-test/suite/roles/set_default_role_ps-6960.test @@ -0,0 +1,20 @@ +# +# MDEV-6960 Server crashes in check_alter_user on setting a default role via PS +# + +--source include/not_embedded.inc + +select priv into @root_priv from mysql.global_priv where user='root' and host='localhost'; + +create role r1; +prepare stmt from "set password = '11111111111111111111111111111111111111111'"; +execute stmt; +prepare stmt from "set default role r1"; +execute stmt; + +set password = ''; +set default role NONE; +drop role r1; + +#cleanup +update mysql.global_priv set priv=@root_priv where user='root' and host='localhost'; diff --git a/mysql-test/suite/roles/set_role-13655.result b/mysql-test/suite/roles/set_role-13655.result new file mode 100644 index 00000000..9da16c1d --- /dev/null +++ b/mysql-test/suite/roles/set_role-13655.result @@ -0,0 +1,52 @@ +# +# MDEV-13655: SET ROLE does not properly grant privileges. +# +# We must test that if aditional db privileges get granted to a role +# which previously inherited privileges from another granted role +# keep the internal memory structures intact. +# +create role simple; +# +# First we create an entry with privileges for databases for the simple role. +# +grant select, insert, update, delete, lock tables, execute on t.* to simple; +create role admin; +# +# Now we grant the simple role to admin. This means that db privileges +# should propagate to admin. +# +grant simple to admin; +show grants for admin; +Grants for admin +GRANT `simple` TO `admin` +GRANT USAGE ON *.* TO `admin` +GRANT USAGE ON *.* TO `simple` +GRANT SELECT, INSERT, UPDATE, DELETE, LOCK TABLES, EXECUTE ON `t`.* TO `simple` +# +# Finally, we give the admin all the available privileges for the db. +# +grant all on t.* to admin; +# +# Create a user to test out the new roles; +# +create user foo; +grant admin to foo; +connect foo,localhost,foo,,,,,; +create database t; +ERROR 42000: Access denied for user 'foo'@'%' to database 't' +set role admin; +show grants; +Grants for foo@% +GRANT `admin` TO `foo`@`%` +GRANT USAGE ON *.* TO `foo`@`%` +GRANT `simple` TO `admin` +GRANT USAGE ON *.* TO `admin` +GRANT ALL PRIVILEGES ON `t`.* TO `admin` +GRANT USAGE ON *.* TO `simple` +GRANT SELECT, INSERT, UPDATE, DELETE, LOCK TABLES, EXECUTE ON `t`.* TO `simple` +create database t; +drop database t; +connection default; +drop role simple; +drop role admin; +drop user foo; diff --git a/mysql-test/suite/roles/set_role-13655.test b/mysql-test/suite/roles/set_role-13655.test new file mode 100644 index 00000000..97a82109 --- /dev/null +++ b/mysql-test/suite/roles/set_role-13655.test @@ -0,0 +1,49 @@ +source include/not_embedded.inc; + +--echo # +--echo # MDEV-13655: SET ROLE does not properly grant privileges. +--echo # +--echo # We must test that if aditional db privileges get granted to a role +--echo # which previously inherited privileges from another granted role +--echo # keep the internal memory structures intact. +--echo # + +create role simple; + +--echo # +--echo # First we create an entry with privileges for databases for the simple role. +--echo # +grant select, insert, update, delete, lock tables, execute on t.* to simple; +create role admin; + +--echo # +--echo # Now we grant the simple role to admin. This means that db privileges +--echo # should propagate to admin. +--echo # +grant simple to admin; +show grants for admin; + +--echo # +--echo # Finally, we give the admin all the available privileges for the db. +--echo # +grant all on t.* to admin; + +--echo # +--echo # Create a user to test out the new roles; +--echo # +create user foo; +grant admin to foo; + +connect (foo,localhost,foo,,,,,); +--error ER_DBACCESS_DENIED_ERROR +create database t; +set role admin; +show grants; +create database t; +drop database t; + +connection default; + +drop role simple; +drop role admin; +drop user foo; diff --git a/mysql-test/suite/roles/set_role-5232.result b/mysql-test/suite/roles/set_role-5232.result new file mode 100644 index 00000000..6158c95e --- /dev/null +++ b/mysql-test/suite/roles/set_role-5232.result @@ -0,0 +1,18 @@ +create user ''@localhost; +create user c; +grant select on mysql.* to c; +create role r1; +grant r1 to c; +connect c,localhost,c,,,,,; +select user(), current_user(); +user() current_user() +c@localhost @localhost +select user from mysql.user group by user; +ERROR 42000: SELECT command denied to user ''@'localhost' for table `mysql`.`user` +set role r1; +ERROR OP000: Invalid role specification `r1` +disconnect c; +connection default; +drop role r1; +drop user c; +drop user ''@localhost; diff --git a/mysql-test/suite/roles/set_role-5232.test b/mysql-test/suite/roles/set_role-5232.test new file mode 100644 index 00000000..c6cb3d92 --- /dev/null +++ b/mysql-test/suite/roles/set_role-5232.test @@ -0,0 +1,20 @@ +# +# MDEV-5232 SET ROLE checks privileges differently from check_access() +# +--source include/not_embedded.inc +create user ''@localhost; +create user c; +grant select on mysql.* to c; +create role r1; +grant r1 to c; +connect (c,localhost,c,,,,,); +select user(), current_user(); +--error ER_TABLEACCESS_DENIED_ERROR +select user from mysql.user group by user; +--error ER_INVALID_ROLE +set role r1; +disconnect c; +connection default; +drop role r1; +drop user c; +drop user ''@localhost; diff --git a/mysql-test/suite/roles/set_role-9614.result b/mysql-test/suite/roles/set_role-9614.result new file mode 100644 index 00000000..d4d689b8 --- /dev/null +++ b/mysql-test/suite/roles/set_role-9614.result @@ -0,0 +1,96 @@ +# +# MDEV-9614 Roles and Users Longer than 6 characters +# +# This test case checks the edge case presented in the MDEV. The +# real issue is actually apparent when the username is longer than the +# rolename. +# +# We need a separate database not including test or test_% names. Due to +# default privileges given on these databases. +# +DROP DATABASE IF EXISTS `bug_db`; +Warnings: +Note 1008 Can't drop database 'bug_db'; database doesn't exist +# +# The first user did not show the bug as john's length is smaller +# than client. The bug is apparent most of the time for usertestjohn. +# +CREATE USER `john`@`%`; +CREATE USER `usertestjohn`@`%`; +CREATE ROLE `client`; +# +# Setup the required tables. +# +CREATE DATABASE `bug_db`; +CREATE TABLE `bug_db`.`t0`(`c0` INT); +# +# Setup select privileges only on the role. Setting the role should give +# select access to bug_db.t0. +# +GRANT SELECT ON `bug_db`.`t0` TO `client`; +GRANT `client` TO `john`@`%`; +GRANT `client` TO `usertestjohn`@`%`; +# +# Check to see grants are set. +# +SHOW GRANTS FOR `john`@`%`; +Grants for john@% +GRANT `client` TO `john`@`%` +GRANT USAGE ON *.* TO `john`@`%` +SHOW GRANTS FOR `usertestjohn`@`%`; +Grants for usertestjohn@% +GRANT `client` TO `usertestjohn`@`%` +GRANT USAGE ON *.* TO `usertestjohn`@`%` +SHOW GRANTS FOR `client`; +Grants for client +GRANT USAGE ON *.* TO `client` +GRANT SELECT ON `bug_db`.`t0` TO `client` +show databases; +Database +bug_db +information_schema +mtr +mysql +performance_schema +sys +test +# +# Try using the database as john. +# +connect john, localhost, john,,information_schema; +show databases; +Database +information_schema +set role client; +show databases; +Database +bug_db +information_schema +use bug_db; +# +# Try using the database as usertestjohn. +# +connect usertestjohn, localhost, usertestjohn,,information_schema; +show databases; +Database +information_schema +set role client; +show databases; +Database +bug_db +information_schema +show grants; +Grants for usertestjohn@% +GRANT `client` TO `usertestjohn`@`%` +GRANT USAGE ON *.* TO `usertestjohn`@`%` +GRANT USAGE ON *.* TO `client` +GRANT SELECT ON `bug_db`.`t0` TO `client` +use bug_db; +# +# Cleanup +# +connection default; +drop user john; +drop user usertestjohn; +drop role client; +drop database bug_db; diff --git a/mysql-test/suite/roles/set_role-9614.test b/mysql-test/suite/roles/set_role-9614.test new file mode 100644 index 00000000..5e9f7dac --- /dev/null +++ b/mysql-test/suite/roles/set_role-9614.test @@ -0,0 +1,79 @@ +--source include/not_embedded.inc + +--echo # +--echo # MDEV-9614 Roles and Users Longer than 6 characters +--echo # +--echo # This test case checks the edge case presented in the MDEV. The +--echo # real issue is actually apparent when the username is longer than the +--echo # rolename. + +--enable_connect_log +--echo # +--echo # We need a separate database not including test or test_% names. Due to +--echo # default privileges given on these databases. +--echo # +DROP DATABASE IF EXISTS `bug_db`; + +--echo # +--echo # The first user did not show the bug as john's length is smaller +--echo # than client. The bug is apparent most of the time for usertestjohn. +--echo # +CREATE USER `john`@`%`; +CREATE USER `usertestjohn`@`%`; +CREATE ROLE `client`; + +--echo # +--echo # Setup the required tables. +--echo # +CREATE DATABASE `bug_db`; +CREATE TABLE `bug_db`.`t0`(`c0` INT); + +--echo # +--echo # Setup select privileges only on the role. Setting the role should give +--echo # select access to bug_db.t0. +--echo # +GRANT SELECT ON `bug_db`.`t0` TO `client`; +GRANT `client` TO `john`@`%`; +GRANT `client` TO `usertestjohn`@`%`; + +--echo # +--echo # Check to see grants are set. +--echo # +SHOW GRANTS FOR `john`@`%`; +SHOW GRANTS FOR `usertestjohn`@`%`; +SHOW GRANTS FOR `client`; + +show databases; + +--echo # +--echo # Try using the database as john. +--echo # +connect (john, localhost, john,,information_schema); + +show databases; +set role client; +show databases; +use bug_db; + +--echo # +--echo # Try using the database as usertestjohn. +--echo # +connect (usertestjohn, localhost, usertestjohn,,information_schema); + +show databases; +set role client; +show databases; + +show grants; +use bug_db; + + +--echo # +--echo # Cleanup +--echo # +connection default; +drop user john; +drop user usertestjohn; +drop role client; +drop database bug_db; +--disable_connect_log diff --git a/mysql-test/suite/roles/set_role-database-recursive.result b/mysql-test/suite/roles/set_role-database-recursive.result new file mode 100644 index 00000000..594ea059 --- /dev/null +++ b/mysql-test/suite/roles/set_role-database-recursive.result @@ -0,0 +1,82 @@ +create user test_user@localhost; +create role test_role1; +create role test_role2; +grant test_role1 to test_user@localhost; +grant test_role2 to test_user@localhost; +grant test_role2 to test_role1; +select user, host from mysql.user where user not like 'root'; +User Host +mariadb.sys localhost +test_role1 +test_role2 +test_user localhost +select * from mysql.roles_mapping; +Host User Role Admin_option + test_role1 test_role2 N +localhost root test_role1 Y +localhost root test_role2 Y +localhost test_user test_role1 N +localhost test_user test_role2 N +select user, host from mysql.db; +user host +grant select on mysql.* to test_role2; +flush privileges; +select * from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `mysql`.`roles_mapping` +select current_user(), current_role(); +current_user() current_role() +test_user@localhost NULL +set role test_role1; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost test_role1 +select * from mysql.roles_mapping; +Host User Role Admin_option + test_role1 test_role2 N +localhost root test_role1 Y +localhost root test_role2 Y +localhost test_user test_role1 N +localhost test_user test_role2 N +set role none; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost NULL +select * from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `mysql`.`roles_mapping` +set role test_role2; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost test_role2 +select * from mysql.roles_mapping; +Host User Role Admin_option + test_role1 test_role2 N +localhost root test_role1 Y +localhost root test_role2 Y +localhost test_user test_role1 N +localhost test_user test_role2 N +create role test_role3; +grant test_role3 to test_role2; +create role test_role4; +grant test_role4 to test_role3; +set role test_role1; +delete from mysql.user where user='no such user'; +ERROR 42000: DELETE command denied to user 'test_user'@'localhost' for table `mysql`.`user` +grant delete on mysql.* to test_role4; +set role test_role1; +delete from mysql.user where user='no such user'; +show grants; +Grants for test_user@localhost +GRANT DELETE ON `mysql`.* TO `test_role4` +GRANT SELECT ON `mysql`.* TO `test_role2` +GRANT USAGE ON *.* TO `test_role1` +GRANT USAGE ON *.* TO `test_role2` +GRANT USAGE ON *.* TO `test_role3` +GRANT USAGE ON *.* TO `test_role4` +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +GRANT `test_role2` TO `test_role1` +GRANT `test_role2` TO `test_user`@`localhost` +GRANT `test_role3` TO `test_role2` +GRANT `test_role4` TO `test_role3` +drop user test_user@localhost; +drop role test_role1, test_role2, test_role3, test_role4; diff --git a/mysql-test/suite/roles/set_role-database-recursive.test b/mysql-test/suite/roles/set_role-database-recursive.test new file mode 100644 index 00000000..17c93d45 --- /dev/null +++ b/mysql-test/suite/roles/set_role-database-recursive.test @@ -0,0 +1,64 @@ +source include/not_embedded.inc; + +#create a user with no privileges +create user test_user@localhost; +create role test_role1; +create role test_role2; + +grant test_role1 to test_user@localhost; +grant test_role2 to test_user@localhost; +grant test_role2 to test_role1; +--sorted_result +select user, host from mysql.user where user not like 'root'; +--sorted_result +select * from mysql.roles_mapping; + +--sorted_result +select user, host from mysql.db; + +grant select on mysql.* to test_role2; +flush privileges; + +change_user 'test_user'; + +--error ER_TABLEACCESS_DENIED_ERROR +select * from mysql.roles_mapping; + +select current_user(), current_role(); +set role test_role1; +select current_user(), current_role(); +--sorted_result +select * from mysql.roles_mapping; +set role none; +select current_user(), current_role(); +--error ER_TABLEACCESS_DENIED_ERROR +select * from mysql.roles_mapping; +set role test_role2; +select current_user(), current_role(); +--sorted_result +select * from mysql.roles_mapping; + +change_user 'root'; + +create role test_role3; +grant test_role3 to test_role2; +create role test_role4; +grant test_role4 to test_role3; + +change_user 'test_user'; +set role test_role1; +--error ER_TABLEACCESS_DENIED_ERROR +delete from mysql.user where user='no such user'; + +change_user 'root'; +grant delete on mysql.* to test_role4; + +change_user 'test_user'; +set role test_role1; +delete from mysql.user where user='no such user'; +--sorted_result +show grants; + +change_user 'root'; +drop user test_user@localhost; +drop role test_role1, test_role2, test_role3, test_role4; diff --git a/mysql-test/suite/roles/set_role-database-simple.result b/mysql-test/suite/roles/set_role-database-simple.result new file mode 100644 index 00000000..969a7ab1 --- /dev/null +++ b/mysql-test/suite/roles/set_role-database-simple.result @@ -0,0 +1,53 @@ +create user 'test_user'@'localhost'; +create role test_role1; +grant test_role1 to test_user@localhost; +select user, host from mysql.user where user not like 'root'; +User Host +mariadb.sys localhost +test_role1 +test_user localhost +select * from mysql.roles_mapping; +Host User Role Admin_option +localhost root test_role1 Y +localhost test_user test_role1 N +grant select on mysql.* to test_role1; +grant insert, delete on mysql.roles_mapping to test_role1; +grant reload on *.* to test_role1; +select * from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `mysql`.`roles_mapping` +select current_user(), current_role(); +current_user() current_role() +test_user@localhost NULL +set role test_role1; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost test_role1 +select * from mysql.roles_mapping; +Host User Role Admin_option +localhost root test_role1 Y +localhost test_user test_role1 N +insert into mysql.user (user, host) values ('Dummy', 'Dummy'); +ERROR 42000: INSERT command denied to user 'test_user'@'localhost' for table `mysql`.`user` +insert into mysql.roles_mapping values ('localhost', 'test_user', 'test_role2', 'N'); +delete from mysql.roles_mapping where Role='test_role2'; +use mysql; +set role none; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost NULL +use mysql; +ERROR 42000: Access denied for user 'test_user'@'localhost' to database 'mysql' +select * from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `mysql`.`roles_mapping` +insert into mysql.user (user, host) values ('Dummy', 'Dummy'); +ERROR 42000: INSERT command denied to user 'test_user'@'localhost' for table `mysql`.`user` +insert into mysql.roles_mapping values ('localhost', 'test_user', 'test_role2', 'N'); +ERROR 42000: INSERT command denied to user 'test_user'@'localhost' for table `mysql`.`roles_mapping` +delete from mysql.roles_mapping where Role='test_role2'; +ERROR 42000: DELETE command denied to user 'test_user'@'localhost' for table `mysql`.`roles_mapping` +drop user 'test_user'@'localhost'; +revoke select on mysql.* from test_role1; +revoke insert, delete on mysql.roles_mapping from test_role1; +drop role test_role1; +delete from mysql.roles_mapping where Role='test_role1'; +flush privileges; diff --git a/mysql-test/suite/roles/set_role-database-simple.test b/mysql-test/suite/roles/set_role-database-simple.test new file mode 100644 index 00000000..daac13a0 --- /dev/null +++ b/mysql-test/suite/roles/set_role-database-simple.test @@ -0,0 +1,56 @@ +source include/not_embedded.inc; + +#create a user with no privileges +create user 'test_user'@'localhost'; +create role test_role1; + +grant test_role1 to test_user@localhost; +--sorted_result +select user, host from mysql.user where user not like 'root'; +--sorted_result +select * from mysql.roles_mapping; + +grant select on mysql.* to test_role1; +grant insert, delete on mysql.roles_mapping to test_role1; + +grant reload on *.* to test_role1; + +change_user 'test_user'; + +--error ER_TABLEACCESS_DENIED_ERROR +select * from mysql.roles_mapping; + +select current_user(), current_role(); +set role test_role1; +select current_user(), current_role(); +--sorted_result +select * from mysql.roles_mapping; +--error ER_TABLEACCESS_DENIED_ERROR +insert into mysql.user (user, host) values ('Dummy', 'Dummy'); +insert into mysql.roles_mapping values ('localhost', 'test_user', 'test_role2', 'N'); +delete from mysql.roles_mapping where Role='test_role2'; + +use mysql; + +set role none; +select current_user(), current_role(); + +--error ER_DBACCESS_DENIED_ERROR +use mysql; +--error ER_TABLEACCESS_DENIED_ERROR +select * from mysql.roles_mapping; +--error ER_TABLEACCESS_DENIED_ERROR +insert into mysql.user (user, host) values ('Dummy', 'Dummy'); +--error ER_TABLEACCESS_DENIED_ERROR +insert into mysql.roles_mapping values ('localhost', 'test_user', 'test_role2', 'N'); +--error ER_TABLEACCESS_DENIED_ERROR +delete from mysql.roles_mapping where Role='test_role2'; + +change_user 'root'; +drop user 'test_user'@'localhost'; +revoke select on mysql.* from test_role1; +revoke insert, delete on mysql.roles_mapping from test_role1; +drop role test_role1; +delete from mysql.roles_mapping where Role='test_role1'; +flush privileges; + diff --git a/mysql-test/suite/roles/set_role-multiple-role.result b/mysql-test/suite/roles/set_role-multiple-role.result new file mode 100644 index 00000000..e4cb3b85 --- /dev/null +++ b/mysql-test/suite/roles/set_role-multiple-role.result @@ -0,0 +1,147 @@ +create user 'test_user'@'localhost'; +create role r_sel; +create role r_ins; +create role r_upd; +create role r_del; +create role r_crt; +create role r_drp; +create role r_rld; +grant select on *.* to r_sel; +grant insert on *.* to r_ins; +grant update on *.* to r_upd; +grant delete on *.* to r_del; +grant create on *.* to r_crt; +grant drop on *.* to r_drp; +grant reload on *.* to r_rld; +grant r_sel to test_user@localhost; +grant r_ins to test_user@localhost; +grant r_upd to test_user@localhost; +grant r_del to test_user@localhost; +grant r_crt to test_user@localhost; +grant r_drp to test_user@localhost; +grant r_rld to test_user@localhost; +flush privileges; +select * from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `mysql`.`roles_mapping` +show grants; +Grants for test_user@localhost +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `r_crt` TO `test_user`@`localhost` +GRANT `r_del` TO `test_user`@`localhost` +GRANT `r_drp` TO `test_user`@`localhost` +GRANT `r_ins` TO `test_user`@`localhost` +GRANT `r_rld` TO `test_user`@`localhost` +GRANT `r_sel` TO `test_user`@`localhost` +GRANT `r_upd` TO `test_user`@`localhost` +select current_user(), current_role(); +current_user() current_role() +test_user@localhost NULL +set role r_sel; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost r_sel +show grants; +Grants for test_user@localhost +GRANT SELECT ON *.* TO `r_sel` +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `r_crt` TO `test_user`@`localhost` +GRANT `r_del` TO `test_user`@`localhost` +GRANT `r_drp` TO `test_user`@`localhost` +GRANT `r_ins` TO `test_user`@`localhost` +GRANT `r_rld` TO `test_user`@`localhost` +GRANT `r_sel` TO `test_user`@`localhost` +GRANT `r_upd` TO `test_user`@`localhost` +select * from mysql.roles_mapping; +Host User Role Admin_option +localhost root r_crt Y +localhost root r_del Y +localhost root r_drp Y +localhost root r_ins Y +localhost root r_rld Y +localhost root r_sel Y +localhost root r_upd Y +localhost test_user r_crt N +localhost test_user r_del N +localhost test_user r_drp N +localhost test_user r_ins N +localhost test_user r_rld N +localhost test_user r_sel N +localhost test_user r_upd N +set role r_ins; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost r_ins +show grants; +Grants for test_user@localhost +GRANT INSERT ON *.* TO `r_ins` +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `r_crt` TO `test_user`@`localhost` +GRANT `r_del` TO `test_user`@`localhost` +GRANT `r_drp` TO `test_user`@`localhost` +GRANT `r_ins` TO `test_user`@`localhost` +GRANT `r_rld` TO `test_user`@`localhost` +GRANT `r_sel` TO `test_user`@`localhost` +GRANT `r_upd` TO `test_user`@`localhost` +select * from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `mysql`.`roles_mapping` +insert into mysql.roles_mapping values ('', 'r_sel', 'r_rld', 'N'); +flush privileges; +ERROR 42000: Access denied; you need (at least one of) the RELOAD privilege(s) for this operation +set role r_rld; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost r_rld +flush privileges; +set role r_sel; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost r_sel +flush privileges; +set role none; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost NULL +flush privileges; +ERROR 42000: Access denied; you need (at least one of) the RELOAD privilege(s) for this operation +set role r_ins; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost r_ins +insert into mysql.roles_mapping values ('', 'r_sel', 'r_upd', 'N'); +insert into mysql.roles_mapping values ('', 'r_sel', 'r_del', 'N'); +insert into mysql.roles_mapping values ('', 'r_sel', 'r_crt', 'N'); +insert into mysql.roles_mapping values ('', 'r_sel', 'r_drp', 'N'); +insert into mysql.roles_mapping values ('', 'r_del', 'r_ins', 'N'); +set role r_rld; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost r_rld +flush privileges; +set role r_sel; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost r_sel +update mysql.roles_mapping set Role='r_ins' where Role='r_ins_wrong'; +flush privileges; +set role r_sel; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost r_sel +create table mysql.random_test_table (id INT); +insert into mysql.random_test_table values (1); +select * from mysql.random_test_table; +id +1 +delete from mysql.roles_mapping where Role='r_ins'; +flush privileges; +set role r_sel; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost r_sel +insert into mysql.random_test_table values (1); +ERROR 42000: INSERT command denied to user 'test_user'@'localhost' for table `mysql`.`random_test_table` +drop table mysql.random_test_table; +delete from mysql.user where user like 'r\_%'; +delete from mysql.roles_mapping where Role like 'r\_%'; +flush privileges; +drop user 'test_user'@'localhost'; diff --git a/mysql-test/suite/roles/set_role-multiple-role.test b/mysql-test/suite/roles/set_role-multiple-role.test new file mode 100644 index 00000000..ecfe8869 --- /dev/null +++ b/mysql-test/suite/roles/set_role-multiple-role.test @@ -0,0 +1,102 @@ +source include/not_embedded.inc; + +#create a user with no privileges +create user 'test_user'@'localhost'; + +create role r_sel; +create role r_ins; +create role r_upd; +create role r_del; +create role r_crt; +create role r_drp; +create role r_rld; + +grant select on *.* to r_sel; +grant insert on *.* to r_ins; +grant update on *.* to r_upd; +grant delete on *.* to r_del; +grant create on *.* to r_crt; +grant drop on *.* to r_drp; +grant reload on *.* to r_rld; + +##################################### +#set up roles mapping +##################################### +grant r_sel to test_user@localhost; +grant r_ins to test_user@localhost; +grant r_upd to test_user@localhost; +grant r_del to test_user@localhost; +grant r_crt to test_user@localhost; +grant r_drp to test_user@localhost; +grant r_rld to test_user@localhost; +flush privileges; + +change_user 'test_user'; + +--error ER_TABLEACCESS_DENIED_ERROR +select * from mysql.roles_mapping; + +--sorted_result +show grants; +select current_user(), current_role(); +set role r_sel; +select current_user(), current_role(); +--sorted_result +show grants; +--sorted_result +select * from mysql.roles_mapping; + +set role r_ins; +select current_user(), current_role(); +--sorted_result +show grants; +--error ER_TABLEACCESS_DENIED_ERROR +select * from mysql.roles_mapping; +insert into mysql.roles_mapping values ('', 'r_sel', 'r_rld', 'N'); +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +flush privileges; +set role r_rld; +select current_user(), current_role(); +flush privileges; +set role r_sel; +select current_user(), current_role(); +flush privileges; +set role none; +select current_user(), current_role(); +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +flush privileges; + +set role r_ins; +select current_user(), current_role(); +insert into mysql.roles_mapping values ('', 'r_sel', 'r_upd', 'N'); +insert into mysql.roles_mapping values ('', 'r_sel', 'r_del', 'N'); +insert into mysql.roles_mapping values ('', 'r_sel', 'r_crt', 'N'); +insert into mysql.roles_mapping values ('', 'r_sel', 'r_drp', 'N'); +insert into mysql.roles_mapping values ('', 'r_del', 'r_ins', 'N'); +set role r_rld; +select current_user(), current_role(); +flush privileges; +set role r_sel; +select current_user(), current_role(); +update mysql.roles_mapping set Role='r_ins' where Role='r_ins_wrong'; +flush privileges; +set role r_sel; +select current_user(), current_role(); + +create table mysql.random_test_table (id INT); +insert into mysql.random_test_table values (1); +--sorted_result +select * from mysql.random_test_table; +delete from mysql.roles_mapping where Role='r_ins'; +flush privileges; +set role r_sel; +select current_user(), current_role(); +--error ER_TABLEACCESS_DENIED_ERROR +insert into mysql.random_test_table values (1); +drop table mysql.random_test_table; + +change_user 'root'; +delete from mysql.user where user like 'r\_%'; +delete from mysql.roles_mapping where Role like 'r\_%'; +flush privileges; +drop user 'test_user'@'localhost'; diff --git a/mysql-test/suite/roles/set_role-recursive.result b/mysql-test/suite/roles/set_role-recursive.result new file mode 100644 index 00000000..f93a731b --- /dev/null +++ b/mysql-test/suite/roles/set_role-recursive.result @@ -0,0 +1,119 @@ +create user test_user@localhost; +create role test_role1; +grant test_role1 to test_user@localhost; +create role test_role2; +grant test_role2 to test_role1; +select user, host from mysql.user where user not like 'root'; +User Host +mariadb.sys localhost +test_role1 +test_role2 +test_user localhost +select * from mysql.roles_mapping where User like 'test_user'; +Host User Role Admin_option +localhost test_user test_role1 N +select * from mysql.roles_mapping where User like 'test_role1'; +Host User Role Admin_option + test_role1 test_role2 N +grant select on *.* to test_role2; +select * from mysql.user where user like 'test_role1'; +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time + test_role1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 N Y 0.000000 +select * from mysql.user where user like 'test_role2'; +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time + test_role2 Y N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 N Y 0.000000 +select * from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `mysql`.`roles_mapping` +show grants; +Grants for test_user@localhost +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +select current_user(), current_role(); +current_user() current_role() +test_user@localhost NULL +set role test_role1; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost test_role1 +show grants; +Grants for test_user@localhost +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 Host=''; +Host User Role Admin_option + test_role1 test_role2 N +show grants; +Grants for test_user@localhost +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; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost NULL +show grants; +Grants for test_user@localhost +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +select * from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `mysql`.`roles_mapping` +show grants; +Grants for test_user@localhost +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +set role test_role2; +ERROR OP000: User `test_user`@`localhost` has not been granted role `test_role2` +select current_user(), current_role(); +current_user() current_role() +test_user@localhost NULL +show grants; +Grants for test_user@localhost +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +select * from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `mysql`.`roles_mapping` +show grants; +Grants for test_user@localhost +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +set role test_role1; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost test_role1 +show grants; +Grants for test_user@localhost +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 Host=''; +Host User Role Admin_option + test_role1 test_role2 N +show grants; +Grants for test_user@localhost +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; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost NULL +show grants; +Grants for test_user@localhost +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +select * from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `mysql`.`roles_mapping` +delete from mysql.user where user='test_role1'; +delete from mysql.user where user='test_role2'; +delete from mysql.roles_mapping; +flush privileges; +drop user 'test_user'@'localhost'; diff --git a/mysql-test/suite/roles/set_role-recursive.test b/mysql-test/suite/roles/set_role-recursive.test new file mode 100644 index 00000000..23d623e1 --- /dev/null +++ b/mysql-test/suite/roles/set_role-recursive.test @@ -0,0 +1,79 @@ +source include/not_embedded.inc; + +#create a user with no privileges +create user test_user@localhost; +create role test_role1; +grant test_role1 to test_user@localhost; +create role test_role2; +grant test_role2 to test_role1; + +--sorted_result +select user, host from mysql.user where user not like 'root'; +--sorted_result +select * from mysql.roles_mapping where User like 'test_user'; +--sorted_result +select * from mysql.roles_mapping where User like 'test_role1'; +grant select on *.* to test_role2; +--sorted_result +select * from mysql.user where user like 'test_role1'; +--sorted_result +select * from mysql.user where user like 'test_role2'; + +change_user 'test_user'; + +--error ER_TABLEACCESS_DENIED_ERROR +select * from mysql.roles_mapping; + +--sorted_result +show grants; +select current_user(), current_role(); +set role test_role1; +select current_user(), current_role(); +--sorted_result +show grants; +select * from mysql.roles_mapping where Host=''; + +--sorted_result +show grants; +set role none; +select current_user(), current_role(); +--sorted_result +show grants; +--error ER_TABLEACCESS_DENIED_ERROR +select * from mysql.roles_mapping; + +--sorted_result +show grants; +--error ER_INVALID_ROLE +set role test_role2; +select current_user(), current_role(); +--sorted_result +show grants; +--error ER_TABLEACCESS_DENIED_ERROR +select * from mysql.roles_mapping; + +#Make sure that this still works after an ER_INVALID_ROLE error +--sorted_result +show grants; +set role test_role1; +select current_user(), current_role(); +--sorted_result +show grants; +--sorted_result +select * from mysql.roles_mapping where Host=''; + +--sorted_result +show grants; +set role none; +select current_user(), current_role(); +--sorted_result +show grants; +--error ER_TABLEACCESS_DENIED_ERROR +select * from mysql.roles_mapping; + +change_user 'root'; +delete from mysql.user where user='test_role1'; +delete from mysql.user where user='test_role2'; +delete from mysql.roles_mapping; +flush privileges; +drop user 'test_user'@'localhost'; diff --git a/mysql-test/suite/roles/set_role-routine-simple.result b/mysql-test/suite/roles/set_role-routine-simple.result new file mode 100644 index 00000000..eaa630f4 --- /dev/null +++ b/mysql-test/suite/roles/set_role-routine-simple.result @@ -0,0 +1,104 @@ +create user 'test_user'@'localhost'; +create role test_role1; +create role test_role2; +create role test_role3; +grant test_role1 to test_user@localhost; +grant test_role3 to test_user@localhost; +grant test_role2 to test_role1; +select user, host from mysql.user where user not like 'root'; +User Host +mariadb.sys localhost +test_role1 +test_role2 +test_role3 +test_user localhost +select * from mysql.roles_mapping; +Host User Role Admin_option + test_role1 test_role2 N +localhost root test_role1 Y +localhost root test_role2 Y +localhost root test_role3 Y +localhost test_user test_role1 N +localhost test_user test_role3 N +create function mysql.test_func (s CHAR(20)) +returns CHAR(50) DETERMINISTIC +return concat('Test string: ',s); +create procedure mysql.test_proc (OUT param1 INT) +begin +select COUNT(*) into param1 from mysql.roles_mapping; +end| +grant execute on function mysql.test_func to test_role2; +grant execute on procedure mysql.test_proc to test_role2; +grant execute on mysql.* to test_role3; +show grants; +Grants for test_user@localhost +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +GRANT `test_role3` TO `test_user`@`localhost` +use mysql; +ERROR 42000: Access denied for user 'test_user'@'localhost' to database 'mysql' +select current_user(), current_role(); +current_user() current_role() +test_user@localhost NULL +set role test_role1; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost test_role1 +use mysql; +call test_proc(@a); +SELECT @a; +@a +6 +SELECT test_func('AABBCCDD'); +test_func('AABBCCDD') +Test string: AABBCCDD +show grants; +Grants for test_user@localhost +GRANT EXECUTE ON FUNCTION `mysql`.`test_func` TO `test_role2` +GRANT EXECUTE ON PROCEDURE `mysql`.`test_proc` TO `test_role2` +GRANT USAGE ON *.* TO `test_role1` +GRANT USAGE ON *.* TO `test_role2` +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +GRANT `test_role2` TO `test_role1` +GRANT `test_role3` TO `test_user`@`localhost` +set role none; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost NULL +show grants; +Grants for test_user@localhost +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +GRANT `test_role3` TO `test_user`@`localhost` +call test_proc(@a); +ERROR 42000: execute command denied to user 'test_user'@'localhost' for routine 'mysql.test_proc' +SELECT test_func('AABBCCDD'); +ERROR 42000: execute command denied to user 'test_user'@'localhost' for routine 'mysql.test_func' +set role test_role3; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost test_role3 +show grants; +Grants for test_user@localhost +GRANT EXECUTE ON `mysql`.* TO `test_role3` +GRANT USAGE ON *.* TO `test_role3` +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +GRANT `test_role3` TO `test_user`@`localhost` +call test_proc(@a); +SELECT @a; +@a +6 +SELECT test_func('AABBCCDD'); +test_func('AABBCCDD') +Test string: AABBCCDD +drop user 'test_user'@'localhost'; +revoke execute on function mysql.test_func from test_role2; +revoke execute on procedure mysql.test_proc from test_role2; +revoke execute on mysql.* from test_role3; +delete from mysql.user where user like'test_%'; +delete from mysql.roles_mapping where Role like 'test%'; +drop function mysql.test_func; +drop procedure mysql.test_proc; +flush privileges; diff --git a/mysql-test/suite/roles/set_role-routine-simple.test b/mysql-test/suite/roles/set_role-routine-simple.test new file mode 100644 index 00000000..0e808d19 --- /dev/null +++ b/mysql-test/suite/roles/set_role-routine-simple.test @@ -0,0 +1,81 @@ +source include/not_embedded.inc; + +create user 'test_user'@'localhost'; +create role test_role1; +create role test_role2; +create role test_role3; + +grant test_role1 to test_user@localhost; +grant test_role3 to test_user@localhost; +grant test_role2 to test_role1; + +--sorted_result +select user, host from mysql.user where user not like 'root'; +--sorted_result +select * from mysql.roles_mapping; + +create function mysql.test_func (s CHAR(20)) +returns CHAR(50) DETERMINISTIC +return concat('Test string: ',s); + + +delimiter |; +create procedure mysql.test_proc (OUT param1 INT) +begin + select COUNT(*) into param1 from mysql.roles_mapping; +end| +delimiter ;| + +grant execute on function mysql.test_func to test_role2; +grant execute on procedure mysql.test_proc to test_role2; + +grant execute on mysql.* to test_role3; + +change_user 'test_user'; +--sorted_result +show grants; + +--error ER_DBACCESS_DENIED_ERROR +use mysql; +select current_user(), current_role(); +set role test_role1; +select current_user(), current_role(); +use mysql; + +call test_proc(@a); +SELECT @a; + +SELECT test_func('AABBCCDD'); + +--sorted_result +show grants; +set role none; +select current_user(), current_role(); +--sorted_result +show grants; + +--error ER_PROCACCESS_DENIED_ERROR +call test_proc(@a); + +--error ER_PROCACCESS_DENIED_ERROR +SELECT test_func('AABBCCDD'); + +set role test_role3; +select current_user(), current_role(); +--sorted_result +show grants; +call test_proc(@a); +SELECT @a; + +SELECT test_func('AABBCCDD'); + +change_user 'root'; +drop user 'test_user'@'localhost'; +revoke execute on function mysql.test_func from test_role2; +revoke execute on procedure mysql.test_proc from test_role2; +revoke execute on mysql.* from test_role3; +delete from mysql.user where user like'test_%'; +delete from mysql.roles_mapping where Role like 'test%'; +drop function mysql.test_func; +drop procedure mysql.test_proc; +flush privileges; diff --git a/mysql-test/suite/roles/set_role-simple.result b/mysql-test/suite/roles/set_role-simple.result new file mode 100644 index 00000000..c603f727 --- /dev/null +++ b/mysql-test/suite/roles/set_role-simple.result @@ -0,0 +1,59 @@ +create user test_user@localhost; +create role test_role1; +grant test_role1 to test_user@localhost; +select user, host from mysql.user where user not like 'root'; +User Host +mariadb.sys localhost +test_role1 +test_user localhost +select * from mysql.roles_mapping; +Host User Role Admin_option +localhost root test_role1 Y +localhost test_user test_role1 N +grant select on *.* to test_role1; +select * from mysql.user where user='test_role1'; +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time + test_role1 Y N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 N Y 0.000000 +select * from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `mysql`.`roles_mapping` +show grants; +Grants for test_user@localhost +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +select current_user(), current_role(); +current_user() current_role() +test_user@localhost NULL +set role test_role1; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost test_role1 +show grants; +Grants for test_user@localhost +GRANT SELECT ON *.* TO `test_role1` +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +select * from mysql.roles_mapping; +Host User Role Admin_option +localhost root test_role1 Y +localhost test_user test_role1 N +set role none; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost NULL +select * from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `mysql`.`roles_mapping` +delete from mysql.user where user='test_role1'; +delete from mysql.roles_mapping where Role='test_role1'; +flush privileges; +drop user 'test_user'@'localhost'; +create user user1; +connect con1,localhost,user1,,; +select current_user; +current_user +user1@% +show grants; +Grants for user1@% +GRANT USAGE ON *.* TO `user1`@`%` +set role none; +connection default; +drop user user1; diff --git a/mysql-test/suite/roles/set_role-simple.test b/mysql-test/suite/roles/set_role-simple.test new file mode 100644 index 00000000..ed884fa2 --- /dev/null +++ b/mysql-test/suite/roles/set_role-simple.test @@ -0,0 +1,54 @@ +source include/not_embedded.inc; + +#create a user with no privileges +create user test_user@localhost; +create role test_role1; +grant test_role1 to test_user@localhost; +--sorted_result +select user, host from mysql.user where user not like 'root'; +--sorted_result +select * from mysql.roles_mapping; +grant select on *.* to test_role1; +--sorted_result +select * from mysql.user where user='test_role1'; + +change_user 'test_user'; + +--error ER_TABLEACCESS_DENIED_ERROR +select * from mysql.roles_mapping; + +--sorted_result +show grants; +select current_user(), current_role(); +set role test_role1; +select current_user(), current_role(); +--sorted_result +show grants; +--sorted_result +select * from mysql.roles_mapping; + +set role none; +select current_user(), current_role(); +--error ER_TABLEACCESS_DENIED_ERROR +select * from mysql.roles_mapping; + +change_user 'root'; +delete from mysql.user where user='test_role1'; +delete from mysql.roles_mapping where Role='test_role1'; +flush privileges; +drop user 'test_user'@'localhost'; + +# +# MDEV-9898 SET ROLE NONE can crash mysqld. +# + +create user user1; + +--connect (con1,localhost,user1,,) +select current_user; +show grants; +set role none; + +connection default; +drop user user1; + diff --git a/mysql-test/suite/roles/set_role-table-column-priv.result b/mysql-test/suite/roles/set_role-table-column-priv.result new file mode 100644 index 00000000..a680e3ff --- /dev/null +++ b/mysql-test/suite/roles/set_role-table-column-priv.result @@ -0,0 +1,71 @@ +create user test_user@localhost; +create role test_role1; +create role test_role2; +grant test_role1 to test_user@localhost; +grant test_role2 to test_role1; +select user, host from mysql.user where user not like 'root'; +User Host +mariadb.sys localhost +test_role1 +test_role2 +test_user localhost +select * from mysql.roles_mapping; +Host User Role Admin_option + test_role1 test_role2 N +localhost root test_role1 Y +localhost root test_role2 Y +localhost test_user test_role1 N +grant select (Role) on mysql.roles_mapping to test_role2; +select * from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `mysql`.`roles_mapping` +show grants; +Grants for test_user@localhost +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +select current_user(), current_role(); +current_user() current_role() +test_user@localhost NULL +set role test_role1; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost test_role1 +show grants; +Grants for test_user@localhost +GRANT SELECT (`Role`) ON `mysql`.`roles_mapping` TO `test_role2` +GRANT USAGE ON *.* TO `test_role1` +GRANT USAGE ON *.* TO `test_role2` +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; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for column 'Host' in table 'roles_mapping' +select Role from mysql.roles_mapping; +Role +test_role1 +test_role1 +test_role2 +test_role2 +show grants; +Grants for test_user@localhost +GRANT SELECT (`Role`) ON `mysql`.`roles_mapping` TO `test_role2` +GRANT USAGE ON *.* TO `test_role1` +GRANT USAGE ON *.* TO `test_role2` +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +GRANT `test_role2` TO `test_role1` +use mysql; +set role none; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost NULL +select Role from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `mysql`.`roles_mapping` +drop user 'test_user'@'localhost'; +select * from mysql.tables_priv; +Host Db User Table_name Grantor Timestamp Table_priv Column_priv +localhost mysql mariadb.sys global_priv root@localhost 0000-00-00 00:00:00 Select,Delete + mysql test_role2 roles_mapping root@localhost 0000-00-00 00:00:00 Select +revoke select on mysql.roles_mapping from test_role2; +delete from mysql.user where user like'test_%'; +delete from mysql.roles_mapping where Role like 'test%'; +flush privileges; diff --git a/mysql-test/suite/roles/set_role-table-column-priv.test b/mysql-test/suite/roles/set_role-table-column-priv.test new file mode 100644 index 00000000..e154b259 --- /dev/null +++ b/mysql-test/suite/roles/set_role-table-column-priv.test @@ -0,0 +1,56 @@ +source include/not_embedded.inc; + +create user test_user@localhost; +create role test_role1; +create role test_role2; + +grant test_role1 to test_user@localhost; +grant test_role2 to test_role1; +--sorted_result +select user, host from mysql.user where user not like 'root'; +--sorted_result +select * from mysql.roles_mapping; + +grant select (Role) on mysql.roles_mapping to test_role2; + +change_user 'test_user'; + +--error ER_TABLEACCESS_DENIED_ERROR +select * from mysql.roles_mapping; + +--sorted_result +show grants; + +select current_user(), current_role(); +set role test_role1; +select current_user(), current_role(); + +--sorted_result +show grants; + +--error ER_COLUMNACCESS_DENIED_ERROR +select * from mysql.roles_mapping; + +--sorted_result +select Role from mysql.roles_mapping; + +--sorted_result +show grants; + +use mysql; + +set role none; +select current_user(), current_role(); + +--sorted_result +--error ER_TABLEACCESS_DENIED_ERROR +select Role from mysql.roles_mapping; + +change_user 'root'; +drop user 'test_user'@'localhost'; +select * from mysql.tables_priv; +revoke select on mysql.roles_mapping from test_role2; +delete from mysql.user where user like'test_%'; +delete from mysql.roles_mapping where Role like 'test%'; + +flush privileges; diff --git a/mysql-test/suite/roles/set_role-table-simple.result b/mysql-test/suite/roles/set_role-table-simple.result new file mode 100644 index 00000000..3f1a68ee --- /dev/null +++ b/mysql-test/suite/roles/set_role-table-simple.result @@ -0,0 +1,69 @@ +create user test_user@localhost; +create role test_role1; +create role test_role2; +grant test_role1 to test_user@localhost; +grant test_role2 to test_role1; +select user, host from mysql.user where user not like 'root'; +User Host +mariadb.sys localhost +test_role1 +test_role2 +test_user localhost +select * from mysql.roles_mapping; +Host User Role Admin_option + test_role1 test_role2 N +localhost root test_role1 Y +localhost root test_role2 Y +localhost test_user test_role1 N +grant select on mysql.roles_mapping to test_role2; +select * from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `mysql`.`roles_mapping` +show grants; +Grants for test_user@localhost +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +select current_user(), current_role(); +current_user() current_role() +test_user@localhost NULL +set role test_role1; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost test_role1 +show grants; +Grants for test_user@localhost +GRANT SELECT ON `mysql`.`roles_mapping` TO `test_role2` +GRANT USAGE ON *.* TO `test_role1` +GRANT USAGE ON *.* TO `test_role2` +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; +Host User Role Admin_option + test_role1 test_role2 N +localhost root test_role1 Y +localhost root test_role2 Y +localhost test_user test_role1 N +show grants; +Grants for test_user@localhost +GRANT SELECT ON `mysql`.`roles_mapping` TO `test_role2` +GRANT USAGE ON *.* TO `test_role1` +GRANT USAGE ON *.* TO `test_role2` +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +GRANT `test_role2` TO `test_role1` +use mysql; +set role none; +select current_user(), current_role(); +current_user() current_role() +test_user@localhost NULL +select * from mysql.roles_mapping; +ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table `mysql`.`roles_mapping` +drop user 'test_user'@'localhost'; +select * from mysql.tables_priv; +Host Db User Table_name Grantor Timestamp Table_priv Column_priv +localhost mysql mariadb.sys global_priv root@localhost 0000-00-00 00:00:00 Select,Delete + mysql test_role2 roles_mapping root@localhost 0000-00-00 00:00:00 Select +revoke select on mysql.roles_mapping from test_role2; +delete from mysql.user where user like'test_%'; +delete from mysql.roles_mapping where Role like 'test%'; +flush privileges; diff --git a/mysql-test/suite/roles/set_role-table-simple.test b/mysql-test/suite/roles/set_role-table-simple.test new file mode 100644 index 00000000..8de77819 --- /dev/null +++ b/mysql-test/suite/roles/set_role-table-simple.test @@ -0,0 +1,53 @@ +source include/not_embedded.inc; + +create user test_user@localhost; +create role test_role1; +create role test_role2; + +grant test_role1 to test_user@localhost; +grant test_role2 to test_role1; +--sorted_result +select user, host from mysql.user where user not like 'root'; +--sorted_result +select * from mysql.roles_mapping; + +grant select on mysql.roles_mapping to test_role2; + +change_user 'test_user'; + +--error ER_TABLEACCESS_DENIED_ERROR +select * from mysql.roles_mapping; + +--sorted_result +show grants; + +select current_user(), current_role(); +set role test_role1; +select current_user(), current_role(); + +--sorted_result +show grants; + +--sorted_result +select * from mysql.roles_mapping; + +--sorted_result +show grants; + +use mysql; + +set role none; +select current_user(), current_role(); + +--sorted_result +--error ER_TABLEACCESS_DENIED_ERROR +select * from mysql.roles_mapping; + +change_user 'root'; +drop user 'test_user'@'localhost'; +select * from mysql.tables_priv; +revoke select on mysql.roles_mapping from test_role2; +delete from mysql.user where user like'test_%'; +delete from mysql.roles_mapping where Role like 'test%'; + +flush privileges; diff --git a/mysql-test/suite/roles/show_create_database-10463.result b/mysql-test/suite/roles/show_create_database-10463.result new file mode 100644 index 00000000..94f7d7e9 --- /dev/null +++ b/mysql-test/suite/roles/show_create_database-10463.result @@ -0,0 +1,65 @@ +drop database if exists db; +Warnings: +Note 1008 Can't drop database 'db'; database doesn't exist +create role r1; +create user beep@'%'; +create database db; +create table db.t1 (i int); +create table db.t2 (b int); +grant select on db.* to r1; +grant r1 to beep@'%'; +connect con1,localhost,beep,,; +show databases; +Database +information_schema +show create database db; +ERROR 42000: Access denied for user 'beep'@'localhost' to database 'db' +select table_schema, table_name from information_schema.tables +where table_schema = 'db' order by table_name; +table_schema table_name +set role r1; +show databases; +Database +db +information_schema +show create database db; +Database Create Database +db CREATE DATABASE `db` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */ +select table_schema, table_name from information_schema.tables +where table_schema = 'db' order by table_name; +table_schema table_name +db t1 +db t2 +connection default; +create role r2; +create user beep2@'%'; +grant update on db.* to r2; +grant r2 to beep2; +connect con2,localhost,beep2,,; +show databases; +Database +information_schema +show create database db; +ERROR 42000: Access denied for user 'beep2'@'localhost' to database 'db' +select table_schema, table_name from information_schema.tables +where table_schema = 'db' order by table_name; +table_schema table_name +set role r2; +show databases; +Database +db +information_schema +show create database db; +Database Create Database +db CREATE DATABASE `db` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */ +select table_schema, table_name from information_schema.tables +where table_schema = 'db' order by table_name; +table_schema table_name +db t1 +db t2 +connection default; +drop database db; +drop role r1; +drop user beep; +drop role r2; +drop user beep2; diff --git a/mysql-test/suite/roles/show_create_database-10463.test b/mysql-test/suite/roles/show_create_database-10463.test new file mode 100644 index 00000000..b1eaaf5f --- /dev/null +++ b/mysql-test/suite/roles/show_create_database-10463.test @@ -0,0 +1,56 @@ +--source include/not_embedded.inc +--source include/default_charset.inc + +drop database if exists db; + +create role r1; +create user beep@'%'; + +create database db; +create table db.t1 (i int); +create table db.t2 (b int); +grant select on db.* to r1; +grant r1 to beep@'%'; + +--connect (con1,localhost,beep,,) +show databases; +--error ER_DBACCESS_DENIED_ERROR +show create database db; +select table_schema, table_name from information_schema.tables +where table_schema = 'db' order by table_name; + +set role r1; +show databases; +show create database db; +select table_schema, table_name from information_schema.tables +where table_schema = 'db' order by table_name; + + +connection default; +create role r2; +create user beep2@'%'; + +grant update on db.* to r2; +grant r2 to beep2; +--connect (con2,localhost,beep2,,) +show databases; +--error ER_DBACCESS_DENIED_ERROR +show create database db; +select table_schema, table_name from information_schema.tables +where table_schema = 'db' order by table_name; + +set role r2; +show databases; + +show create database db; +select table_schema, table_name from information_schema.tables +where table_schema = 'db' order by table_name; + + +connection default; + +drop database db; +drop role r1; +drop user beep; +drop role r2; +drop user beep2; diff --git a/mysql-test/suite/roles/show_grants.result b/mysql-test/suite/roles/show_grants.result new file mode 100644 index 00000000..21c5a74e --- /dev/null +++ b/mysql-test/suite/roles/show_grants.result @@ -0,0 +1,162 @@ +create user test_user@localhost; +create role test_role1; +create role test_role2; +grant test_role1 to test_user@localhost; +grant test_role2 to test_user@localhost; +grant test_role2 to test_role1; +select user, host from mysql.user where user not like 'root'; +User Host +mariadb.sys localhost +test_role1 +test_role2 +test_user localhost +select * from mysql.roles_mapping; +Host User Role Admin_option + test_role1 test_role2 N +localhost root test_role1 Y +localhost root test_role2 Y +localhost test_user test_role1 N +localhost test_user test_role2 N +select user, host from mysql.db; +user host +grant select on mysql.* to test_role2; +flush privileges; +select * from information_schema.applicable_roles; +GRANTEE ROLE_NAME IS_GRANTABLE IS_DEFAULT +root@localhost test_role1 YES NO +root@localhost test_role2 YES NO +test_role1 test_role2 NO NULL +select * from information_schema.applicable_roles; +GRANTEE ROLE_NAME IS_GRANTABLE IS_DEFAULT +test_role1 test_role2 NO NULL +test_user@localhost test_role1 NO NO +test_user@localhost test_role2 NO NO +show grants; +Grants for test_user@localhost +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +GRANT `test_role2` TO `test_user`@`localhost` +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_role1 +test_role2 +select current_user(), current_role(); +current_user() current_role() +test_user@localhost test_role1 +show grants; +Grants for test_user@localhost +GRANT SELECT ON `mysql`.* TO `test_role2` +GRANT USAGE ON *.* TO `test_role1` +GRANT USAGE ON *.* TO `test_role2` +GRANT USAGE ON *.* TO `test_user`@`localhost` +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 +show grants; +Grants for test_user@localhost +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +GRANT `test_role2` TO `test_user`@`localhost` +show grants for test_user@localhost; +Grants for test_user@localhost +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +GRANT `test_role2` TO `test_user`@`localhost` +show grants for test_role1; +ERROR 42000: Access denied for user 'test_user'@'localhost' to database 'mysql' +show grants for test_role2; +ERROR 42000: Access denied for user 'test_user'@'localhost' to database 'mysql' +show grants for CURRENT_USER; +Grants for test_user@localhost +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +GRANT `test_role2` TO `test_user`@`localhost` +show grants for CURRENT_USER(); +Grants for test_user@localhost +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +GRANT `test_role2` TO `test_user`@`localhost` +show grants for CURRENT_ROLE; +ERROR 42000: There is no such grant defined for user 'test_user' on host 'localhost' +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 +show grants; +Grants for test_user@localhost +GRANT SELECT ON `mysql`.* TO `test_role2` +GRANT USAGE ON *.* TO `test_role2` +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +GRANT `test_role2` TO `test_user`@`localhost` +show grants for test_user@localhost; +Grants for test_user@localhost +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +GRANT `test_role2` TO `test_user`@`localhost` +show grants for test_role1; +Grants for test_role1 +GRANT SELECT ON `mysql`.* TO `test_role2` +GRANT USAGE ON *.* TO `test_role1` +GRANT USAGE ON *.* TO `test_role2` +GRANT `test_role2` TO `test_role1` +show grants for test_role2; +Grants for test_role2 +GRANT SELECT ON `mysql`.* TO `test_role2` +GRANT USAGE ON *.* TO `test_role2` +show grants for CURRENT_USER; +Grants for test_user@localhost +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +GRANT `test_role2` TO `test_user`@`localhost` +show grants for CURRENT_USER(); +Grants for test_user@localhost +GRANT USAGE ON *.* TO `test_user`@`localhost` +GRANT `test_role1` TO `test_user`@`localhost` +GRANT `test_role2` TO `test_user`@`localhost` +show grants for CURRENT_ROLE; +Grants for test_role2 +GRANT SELECT ON `mysql`.* TO `test_role2` +GRANT USAGE ON *.* TO `test_role2` +show grants for CURRENT_ROLE(); +Grants for test_role2 +GRANT SELECT ON `mysql`.* TO `test_role2` +GRANT USAGE ON *.* TO `test_role2` +drop user 'test_user'@'localhost'; +revoke select on mysql.* from test_role2; +drop role test_role1; +drop role test_role2; +delete from mysql.roles_mapping where Role='test_role1'; +delete from mysql.roles_mapping where Role='test_role2'; +flush privileges; +# +# MDEV-24289: show grants missing with grant option +# +create role anel; +GRANT SELECT, UPDATE, DELETE, ALTER ON *.* TO 'anel'; +SHOW GRANTS for 'anel'; +Grants for anel +GRANT SELECT, UPDATE, DELETE, ALTER ON *.* TO `anel` +create role MariaDB_admin; +GRANT SELECT, UPDATE, DELETE, ALTER ON *.* TO 'MariaDB_admin' WITH GRANT OPTION; +SHOW GRANTS for 'MariaDB_admin'; +Grants for MariaDB_admin +GRANT SELECT, UPDATE, DELETE, ALTER ON *.* TO `MariaDB_admin` WITH GRANT OPTION +drop role MariaDB_admin; +drop role anel; diff --git a/mysql-test/suite/roles/show_grants.test b/mysql-test/suite/roles/show_grants.test new file mode 100644 index 00000000..fc2165ac --- /dev/null +++ b/mysql-test/suite/roles/show_grants.test @@ -0,0 +1,103 @@ +source include/not_embedded.inc; + +#create a user with no privileges +create user test_user@localhost; +create role test_role1; +create role test_role2; + +grant test_role1 to test_user@localhost; +grant test_role2 to test_user@localhost; +grant test_role2 to test_role1; +--sorted_result +select user, host from mysql.user where user not like 'root'; +--sorted_result +select * from mysql.roles_mapping; + +--sorted_result +select user, host from mysql.db; + +grant select on mysql.* to test_role2; +flush privileges; + +--sorted_result +select * from information_schema.applicable_roles; + +change_user 'test_user'; + +--sorted_result +select * from information_schema.applicable_roles; + +--sorted_result +show grants; +select current_user(), current_role(); +set role test_role1; +--sorted_result +select * from information_schema.enabled_roles; +select current_user(), current_role(); +--sorted_result +show grants; +set role none; +--sorted_result +select * from information_schema.enabled_roles; +select current_user(), current_role(); +--sorted_result +show grants; + +--sorted_result +show grants for test_user@localhost; +--error ER_DBACCESS_DENIED_ERROR +show grants for test_role1; +--error ER_DBACCESS_DENIED_ERROR +show grants for test_role2; +--sorted_result +show grants for CURRENT_USER; +--sorted_result +show grants for CURRENT_USER(); +--error ER_NONEXISTING_GRANT +show grants for CURRENT_ROLE; +--error ER_NONEXISTING_GRANT +show grants for CURRENT_ROLE(); + +set role test_role2; +--sorted_result +select * from information_schema.enabled_roles; +select current_user(), current_role(); +--sorted_result +show grants; +--sorted_result +show grants for test_user@localhost; +--sorted_result +show grants for test_role1; +--sorted_result +show grants for test_role2; +--sorted_result +show grants for CURRENT_USER; +--sorted_result +show grants for CURRENT_USER(); +--sorted_result +show grants for CURRENT_ROLE; +--sorted_result +show grants for CURRENT_ROLE(); + + +change_user 'root'; +drop user 'test_user'@'localhost'; +revoke select on mysql.* from test_role2; +drop role test_role1; +drop role test_role2; +delete from mysql.roles_mapping where Role='test_role1'; +delete from mysql.roles_mapping where Role='test_role2'; +flush privileges; + +--echo # +--echo # MDEV-24289: show grants missing with grant option +--echo # +create role anel; +GRANT SELECT, UPDATE, DELETE, ALTER ON *.* TO 'anel'; +SHOW GRANTS for 'anel'; + +create role MariaDB_admin; +GRANT SELECT, UPDATE, DELETE, ALTER ON *.* TO 'MariaDB_admin' WITH GRANT OPTION; +SHOW GRANTS for 'MariaDB_admin'; +drop role MariaDB_admin; +drop role anel; diff --git a/mysql-test/suite/roles/show_grants_replicated.result b/mysql-test/suite/roles/show_grants_replicated.result new file mode 100644 index 00000000..9438939b --- /dev/null +++ b/mysql-test/suite/roles/show_grants_replicated.result @@ -0,0 +1,58 @@ +include/master-slave.inc +[connection master] +create user u1; +create role r1; +# +# On master SHOW GRANTS work both for the user and the role: +show grants for u1; +Grants for u1@% +GRANT USAGE ON *.* TO `u1`@`%` +show grants for r1; +Grants for r1 +GRANT USAGE ON *.* TO `r1` +# +connection slave; +# +# The role has been replicated, +# it's visible in mysql.user and I_S: +# +select user, host, is_role from mysql.user where user in ('u1', 'r1'); +User Host is_role +r1 Y +u1 % N +select * from information_schema.applicable_roles; +GRANTEE ROLE_NAME IS_GRANTABLE IS_DEFAULT +root@localhost r1 YES NO +# +# Check show grants for the new user. +show grants for u1; +Grants for u1@% +GRANT USAGE ON *.* TO `u1`@`%` +# +# Check show grants for the new role. +show grants for r1; +Grants for r1 +GRANT USAGE ON *.* TO `r1` +# +# Check if flushing privileges preserves the state. +flush privileges; +show grants for r1; +Grants for r1 +GRANT USAGE ON *.* TO `r1` +# +# Check SHOW GRANTS after setting the role. +set role r1; +show grants; +Grants for root@localhost +GRANT `r1` TO `root`@`localhost` WITH ADMIN OPTION +GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` WITH GRANT OPTION +GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION +GRANT USAGE ON *.* TO `r1` +show grants for r1; +Grants for r1 +GRANT USAGE ON *.* TO `r1` +connection master; +drop role r1; +drop user u1; +connection slave; +include/rpl_end.inc diff --git a/mysql-test/suite/roles/show_grants_replicated.test b/mysql-test/suite/roles/show_grants_replicated.test new file mode 100644 index 00000000..91129c43 --- /dev/null +++ b/mysql-test/suite/roles/show_grants_replicated.test @@ -0,0 +1,38 @@ +--source include/master-slave.inc + +create user u1; +create role r1; +--echo # +--echo # On master SHOW GRANTS work both for the user and the role: +show grants for u1; +show grants for r1; +--echo # +--sync_slave_with_master +--echo # +--echo # The role has been replicated, +--echo # it's visible in mysql.user and I_S: +--echo # +--sorted_result +select user, host, is_role from mysql.user where user in ('u1', 'r1'); +select * from information_schema.applicable_roles; +--echo # +--echo # Check show grants for the new user. +show grants for u1; +--echo # +--echo # Check show grants for the new role. +show grants for r1; +--echo # +--echo # Check if flushing privileges preserves the state. +flush privileges; +show grants for r1; +--echo # +--echo # Check SHOW GRANTS after setting the role. +set role r1; +show grants; +show grants for r1; + +connection master; +drop role r1; +drop user u1; +--sync_slave_with_master +--source include/rpl_end.inc |