Skip to content

Commit

Permalink
MDEV-8383 : "GRANT role TO user" does not replicate
Browse files Browse the repository at this point in the history
Enable replication of GRANT/REVOKE ROLE commands across
galera nodes.
  • Loading branch information
Nirbhay Choubey committed Jul 10, 2015
1 parent 5467b12 commit 6771b81
Show file tree
Hide file tree
Showing 3 changed files with 324 additions and 0 deletions.
156 changes: 156 additions & 0 deletions mysql-test/suite/galera/r/galera_roles.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
#
# Testing CREATE/GRANT role
#

# On node_1
CREATE DATABASE test1;
CREATE TABLE test1.t1 (a int, b int);
CREATE TABLE test1.t2 (a int, b int);
INSERT INTO test1.t1 values (1,2),(3,4);
INSERT INTO test1.t2 values (5,6),(7,8);
CREATE PROCEDURE test1.pr1() SELECT "pr1";
CREATE USER foo@localhost;
CREATE ROLE role1;
GRANT role1 TO foo@localhost;
GRANT RELOAD ON *.* TO role1;
GRANT SELECT ON mysql.* TO role1;
GRANT EXECUTE ON PROCEDURE test1.pr1 TO role1;
GRANT SELECT ON test1.t1 TO role1;
GRANT SELECT (a) ON test1.t2 TO role1;
# Open connections to the 2 nodes using 'foo' user.

# Connect with foo_node_1
SHOW GRANTS;
Grants for foo@localhost
GRANT role1 TO 'foo'@'localhost'
GRANT USAGE ON *.* TO 'foo'@'localhost'
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 'roles_mapping'
SHOW TABLES FROM test1;
ERROR 42000: Access denied for user 'foo'@'localhost' to database 'test1'
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 test1;
Tables_in_test1
t1
t2
SELECT * FROM test1.t1;
a b
1 2
3 4
SELECT * FROM test1.t2;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table 't2'
SELECT a FROM test1.t2;
a
5
7
CALL test1.pr1();
pr1
pr1

# Connect with foo_node_2
SHOW GRANTS;
Grants for foo@localhost
GRANT role1 TO 'foo'@'localhost'
GRANT USAGE ON *.* TO 'foo'@'localhost'
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 'roles_mapping'
SHOW TABLES FROM test1;
ERROR 42000: Access denied for user 'foo'@'localhost' to database 'test1'
SET ROLE role1;
FLUSH TABLES;
SELECT * FROM mysql.roles_mapping;
Host User Role Admin_option
role1 Y
localhost foo role1 N
SHOW TABLES FROM test1;
Tables_in_test1
t1
t2
SELECT * FROM test1.t1;
a b
1 2
3 4
SELECT * FROM test1.t2;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table 't2'
SELECT a FROM test1.t2;
a
5
7
CALL test1.pr1();
pr1
pr1
#
# Testing REVOKE role
#
#
# Connect with node_1
REVOKE EXECUTE ON PROCEDURE test1.pr1 FROM role1;

# Connect with foo_node_1
CALL test1.pr1();
ERROR 42000: execute command denied to user 'foo'@'localhost' for routine 'test1.pr1'

# Connect with foo_node_2
CALL test1.pr1();
ERROR 42000: execute command denied to user 'foo'@'localhost' for routine 'test1.pr1'
#
# Testing DROP role
#

# Connect with node_1
DROP ROLE role1;

# Connect with foo_node_1
FLUSH TABLES;
SELECT * FROM mysql.roles_mapping;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table 'roles_mapping'
SELECT * FROM test1.t1;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table 't1'
SELECT a FROM test1.t2;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table '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

# Connect with foo_node_2
FLUSH TABLES;
SELECT * FROM mysql.roles_mapping;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table 'roles_mapping'
SELECT * FROM test1.t1;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table 't1'
SELECT a FROM test1.t2;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table '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
# Connect with node_1
DROP USER foo@localhost;
DROP DATABASE test1;
# End of test
167 changes: 167 additions & 0 deletions mysql-test/suite/galera/t/galera_roles.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
#
# Test for CREATE/DROP/GRANT/REVOKE role.
#

--source include/galera_cluster.inc
--source include/have_innodb.inc

--echo #
--echo # Testing CREATE/GRANT role
--echo #

--echo
--echo # On node_1
--connection node_1

CREATE DATABASE test1;
CREATE TABLE test1.t1 (a int, b int);
CREATE TABLE test1.t2 (a int, b int);
INSERT INTO test1.t1 values (1,2),(3,4);
INSERT INTO test1.t2 values (5,6),(7,8);

CREATE PROCEDURE test1.pr1() SELECT "pr1";

CREATE USER foo@localhost;
CREATE ROLE role1;

GRANT role1 TO foo@localhost;
GRANT RELOAD ON *.* TO role1;
GRANT SELECT ON mysql.* TO role1;
GRANT EXECUTE ON PROCEDURE test1.pr1 TO role1;
GRANT SELECT ON test1.t1 TO role1;
GRANT SELECT (a) ON test1.t2 TO role1;

--echo # Open connections to the 2 nodes using 'foo' user.
--let $port_1= \$NODE_MYPORT_1
--connect(foo_node_1,127.0.0.1,foo,,test,$port_1,)

--let $port_2= \$NODE_MYPORT_2
--connect(foo_node_2,127.0.0.1,foo,,test,$port_2,)

--echo
--echo # Connect with foo_node_1
--connection foo_node_1

SHOW GRANTS;

--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 test1;

SET ROLE role1;

FLUSH TABLES;
--sorted_result
SELECT * FROM mysql.roles_mapping;
SHOW TABLES FROM test1;
SELECT * FROM test1.t1;
--error ER_TABLEACCESS_DENIED_ERROR
SELECT * FROM test1.t2;
SELECT a FROM test1.t2;
CALL test1.pr1();

--echo
--echo # Connect with foo_node_2
--connection foo_node_2

SHOW GRANTS;

--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 test1;

SET ROLE role1;

FLUSH TABLES;
--sorted_result
SELECT * FROM mysql.roles_mapping;
SHOW TABLES FROM test1;
SELECT * FROM test1.t1;
--error ER_TABLEACCESS_DENIED_ERROR
SELECT * FROM test1.t2;
SELECT a FROM test1.t2;
CALL test1.pr1();

--echo #
--echo # Testing REVOKE role
--echo #

--echo #
--echo # Connect with node_1
--connection node_1
REVOKE EXECUTE ON PROCEDURE test1.pr1 FROM role1;

--echo
--echo # Connect with foo_node_1
--connection foo_node_1

--error ER_PROCACCESS_DENIED_ERROR
CALL test1.pr1();

--echo
--echo # Connect with foo_node_2
--connection foo_node_2

--error ER_PROCACCESS_DENIED_ERROR
CALL test1.pr1();

--echo #
--echo # Testing DROP role
--echo #

--echo
--echo # Connect with node_1
--connection node_1

DROP ROLE role1;

--echo
--echo # Connect with foo_node_1
--connection foo_node_1

FLUSH TABLES;
--error ER_TABLEACCESS_DENIED_ERROR
SELECT * FROM mysql.roles_mapping;
--error ER_TABLEACCESS_DENIED_ERROR
SELECT * FROM test1.t1;
--error ER_TABLEACCESS_DENIED_ERROR
SELECT a FROM test1.t2;

SHOW GRANTS;
SELECT * FROM INFORMATION_SCHEMA.ENABLED_ROLES;
SELECT * FROM INFORMATION_SCHEMA.ENABLED_ROLES; # yes, repeat it twice
SELECT CURRENT_ROLE();

--echo
--echo # Connect with foo_node_2
--connection foo_node_2

FLUSH TABLES;
--error ER_TABLEACCESS_DENIED_ERROR
SELECT * FROM mysql.roles_mapping;
--error ER_TABLEACCESS_DENIED_ERROR
SELECT * FROM test1.t1;
--error ER_TABLEACCESS_DENIED_ERROR
SELECT a FROM test1.t2;

SHOW GRANTS;
SELECT * FROM INFORMATION_SCHEMA.ENABLED_ROLES;
SELECT * FROM INFORMATION_SCHEMA.ENABLED_ROLES; # yes, repeat it twice
SELECT CURRENT_ROLE();

# Cleanup
disconnect foo_node_2;
--echo # Connect with node_1
--connection node_1

DROP USER foo@localhost;
DROP DATABASE test1;

--source include/galera_end.inc
--echo # End of test
1 change: 1 addition & 0 deletions sql/sql_parse.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4626,6 +4626,7 @@ case SQLCOM_PREPARE:
case SQLCOM_REVOKE_ROLE:
case SQLCOM_GRANT_ROLE:
{
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
if (!(res= mysql_grant_role(thd, lex->users_list,
lex->sql_command != SQLCOM_GRANT_ROLE)))
my_ok(thd);
Expand Down

0 comments on commit 6771b81

Please sign in to comment.