polardbxengine/mysql-test/suite/auth_sec/t/system_user_priv.test

507 lines
18 KiB
Plaintext

###############################################################################
# WL#12098: MySQL system users #
# This test file covers the scenarios around the SYSTEM_USER dynamic #
# privilege. #
# #
###############################################################################
# Save the initial number of concurrent sessions
--source include/count_sessions.inc
--echo #------------------------------------------------------------------------
--echo # 1. Create the Users and Roles. Grant/REVOKE the SYSTEM_USER
--echo # privilege from them.
--echo #------------------------------------------------------------------------
--echo
--echo # 1.1 User is granted SYSTEM_USER priv only if it is granted explictly
CREATE USER sys_usr IDENTIFIED BY 'pwd';
SHOW GRANTS FOR sys_usr;
GRANT SYSTEM_USER ON *.* TO sys_usr WITH GRANT OPTION;
SHOW GRANTS FOR sys_usr;
--echo
--echo # 1.2 Revoke the SYSTEM_USER privilege from user;
CREATE USER non_sys_usr IDENTIFIED BY 'pwd';
GRANT ALL ON *.* TO non_sys_usr;
REVOKE SYSTEM_USER ON *.* FROM non_sys_usr;
# We shall partially revoke the update access from mysql.* once the former
# feature will be available.
REVOKE UPDATE ON *.* FROM non_sys_usr;
SHOW GRANTS FOR non_sys_usr;
--echo
--echo # 1.3 Role is granted SYSTEM_USER priv only if it is granted explictly
CREATE ROLE sys_role;
SHOW GRANTS FOR sys_role;
GRANT SYSTEM_USER ON *.* TO sys_role WITH GRANT OPTION;
SHOW GRANTS FOR sys_role;
--echo
--echo # 1.4 Revoke the SYSTEM_USER privilege from user;
CREATE USER non_sys_role;
GRANT ALL ON *.* TO non_sys_role;
REVOKE SYSTEM_USER ON *.* FROM non_sys_role;
SHOW GRANTS FOR non_sys_role;
--echo #------------------------------------------------------------------------
--echo # 2. sys_usr cannot modify the other users properties unless the former
--echo # is granted the relevant properties to do so
--echo #------------------------------------------------------------------------
connect(sys_usr_con,localhost,sys_usr,pwd,);
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
CREATE USER test_usr;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
ALTER USER non_sys_usr IDENTIFIED BY 'pwd';
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
RENAME USER non_sys_usr TO power_usr;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
DROP USER non_sys_usr;
connection default;
--echo #------------------------------------------------------------------------
--echo # 3. non_sys_usr cannot modify the other sys_usr even if former is
--echo # granted global privileges
--echo #------------------------------------------------------------------------
connect(non_sys_usr_con,localhost,non_sys_usr,pwd,);
CREATE USER test_user;
ALTER USER test_user IDENTIFIED BY 'pwd';
RENAME USER test_user TO temp_user;
DROP USER temp_user;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
ALTER USER sys_usr IDENTIFIED BY 'pwd';
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
RENAME USER sys_usr TO power_usr;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
DROP USER sys_usr;
connection default;
--echo #------------------------------------------------------------------------
--echo # 4. non_sys_usr cannot grant/revoke SYSTEM_USER privilege to /from
--echo # other users/roles
--echo #------------------------------------------------------------------------
connection non_sys_usr_con;
CREATE USER test_user;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
GRANT SYSTEM_USER ON *.* TO test_user;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
REVOKE SYSTEM_USER FROM sys_usr;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
GRANT SYSTEM_USER ON *.* TO sys_role;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
GRANT SYSTEM_USER ON *.* TO non_sys_role;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
REVOKE SYSTEM_USER ON *.* FROM sys_role;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
GRANT sys_role to test_user;
connection default;
GRANT sys_role TO test_user;
SHOW GRANTS FOR test_user;
connection non_sys_usr_con;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
REVOKE sys_role FROM test_user;
DROP USER test_user;
connection default;
--echo #------------------------------------------------------------------------
--echo # 5. Mandatory Roles
--echo #------------------------------------------------------------------------
--echo
--echo # 5.1 Check with root user
--error ER_DA_AUTH_ID_WITH_SYSTEM_USER_PRIV_IN_MANDATORY_ROLES
SET @@GLOBAL.MANDATORY_ROLES='sys_role,non_sys_role';
--error ER_DA_AUTH_ID_WITH_SYSTEM_USER_PRIV_IN_MANDATORY_ROLES
SET @@GLOBAL.MANDATORY_ROLES='sys_role';
SET @@GLOBAL.MANDATORY_ROLES='non_sys_role';
--echo
--echo # 5.2 Check with user who does not have system user privilege
connection non_sys_usr_con;
--error ER_DA_AUTH_ID_WITH_SYSTEM_USER_PRIV_IN_MANDATORY_ROLES
SET @@GLOBAL.MANDATORY_ROLES='sys_role,non_sys_role';
--error ER_DA_AUTH_ID_WITH_SYSTEM_USER_PRIV_IN_MANDATORY_ROLES
SET @@GLOBAL.MANDATORY_ROLES='sys_role';
SET @@GLOBAL.MANDATORY_ROLES='non_sys_role';
--echo
--echo # 5.3 Check with user who has system user privilege
connection sys_usr_con;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
SET @@GLOBAL.MANDATORY_ROLES='sys_role,non_sys_role';
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
SET @@GLOBAL.MANDATORY_ROLES='sys_role';
--echo
--echo # 5.4 Non existing mandatory_role which is granted the SYSTEM_USER priv
--echo # later
connection default;
SET @@GLOBAL.MANDATORY_ROLES='test_role';
CREATE ROLE test_role;
--error ER_CANNOT_GRANT_SYSTEM_PRIV_TO_MANDATORY_ROLE
GRANT SYSTEM_USER ON *.* TO 'test_role';
connection sys_usr_con;
--error ER_CANNOT_GRANT_SYSTEM_PRIV_TO_MANDATORY_ROLE
GRANT SYSTEM_USER ON *.* TO 'test_role';
connection non_sys_usr_con;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
GRANT SYSTEM_USER ON *.* TO 'test_role';
connection default;
# Clear the mandatory_role and delete the test_role
SET @@GLOBAL.MANDATORY_ROLES='';
DROP ROLE test_role;
--echo
--echo # 5.5 None of the roles in the role's hierarchy should have SYSTEM_USER
--echo # privilege if former is set as mandatory_role.
CREATE ROLE r1, r2;
GRANT r1 TO r2;
GRANT sys_role TO r1;
--error ER_DA_AUTH_ID_WITH_SYSTEM_USER_PRIV_IN_MANDATORY_ROLES
SET @@GLOBAL.MANDATORY_ROLES='r2';
--echo # 5.6 Set persist should fail too.
--error ER_DA_AUTH_ID_WITH_SYSTEM_USER_PRIV_IN_MANDATORY_ROLES
SET PERSIST MANDATORY_ROLES = 'r2';
--echo # 5.6 Set persist should fail too.
--error ER_DA_AUTH_ID_WITH_SYSTEM_USER_PRIV_IN_MANDATORY_ROLES
SET PERSIST MANDATORY_ROLES = 'r2';
--echo # 5.7 We do not check the SET PERSIST_ONLY, should succeed.
SET PERSIST_ONLY MANDATORY_ROLES = 'r2';
--echo # 5.8 On Server restart there should be a warning in the log file
--echo # Restart server.
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--shutdown_server
--source include/wait_until_disconnected.inc
# Remove the server log file so that we find the expected warning only once.
perl;
my $filetodelete = "$ENV{'MYSQLTEST_VARDIR'}/log/mysqld.1.err";
while (-e $filetodelete) {
unlink $filetodelete;
sleep 1;
}
EOF
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--enable_reconnect
--source include/wait_until_connected_again.inc
--let $assert_file=$MYSQLTEST_VARDIR/log/mysqld.1.err
--let $assert_select=.* \[Warning\] \[[^]]*\] \[[^]]*\] Cannot set mandatory_roles: AuthId .* has 'SYSTEM_USER' privilege.
--let $assert_text= Found the expected warning line in the server log.
--let $assert_count=1
--source include/assert_grep.inc
--echo # System variable should not have been set.
SELECT @@mandatory_roles;
# Clear the system variable in the .cnf file
SET PERSIST mandatory_roles = '';
--echo # 5.9 Set the system variable at the command line.
# Server should restart with a warning
--echo # Restart server.
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--shutdown_server
--source include/wait_until_disconnected.inc
# Remove the server log file so that we find the expected warning only once.
perl;
my $filetodelete = "$ENV{'MYSQLTEST_VARDIR'}/log/mysqld.1.err";
while (-e $filetodelete) {
unlink $filetodelete;
sleep 1;
}
EOF
--exec echo "restart:--mandatory_roles='r2'" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--enable_reconnect
--source include/wait_until_connected_again.inc
--let $assert_file=$MYSQLTEST_VARDIR/log/mysqld.1.err
--let $assert_select=.* \[Warning\] \[[^]]*\] \[[^]]*\] Cannot set mandatory_roles: AuthId .* has 'SYSTEM_USER' privilege.
--let $assert_text= Found the expected warning line in the server log.
--let $assert_count=1
--source include/assert_grep.inc
--echo # System variable should not have been set.
SELECT @@mandatory_roles;
--echo # 5.10 Set the system variable in the cnf file. Warning should be logged.
let $MYSQLD_DATADIR= `SELECT @@datadir`;
let $MYSQL_BASEDIR= `SELECT @@basedir`;
let $MYSQL_SOCKET= `SELECT @@socket`;
let $MYSQL_PIDFILE= `SELECT @@pid_file`;
let $MYSQL_PORT= `SELECT @@port`;
let $MYSQL_MESSAGESDIR= `SELECT @@lc_messages_dir`;
let $MYSQL_HOME=`SELECT @@basedir`;
let $MYSQL_SERVER_ID= `SELECT @@server_id`;
copy_file $MYSQLTEST_VARDIR/my.cnf $MYSQLTEST_VARDIR/tmp/temp_my.cnf;
append_file $MYSQLTEST_VARDIR/tmp/temp_my.cnf;
[mysqld]
mandatory_roles=r2
EOF
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--shutdown_server
--source include/wait_until_disconnected.inc
# Remove the server log file so that we find the expected warning only once.
perl;
my $filetodelete = "$ENV{'MYSQLTEST_VARDIR'}/log/mysqld.1.err";
while (-e $filetodelete) {
unlink $filetodelete;
sleep 1;
}
EOF
--exec echo "restart:--defaults-file=$MYSQLTEST_VARDIR/tmp/temp_my.cnf" --basedir=$MYSQL_BASEDIR --datadir=$MYSQLD_DATADIR --lc-messages-dir=$MYSQL_MESSAGESDIR --innodb_dedicated_server=OFF --skip-mysqlx > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--enable_reconnect
--source include/wait_until_connected_again.inc
--let $assert_file=$MYSQLTEST_VARDIR/log/mysqld.1.err
--let $assert_select=.* \[Warning\] \[[^]]*\] \[[^]]*\] Cannot set mandatory_roles: AuthId .* has 'SYSTEM_USER' privilege.
--let $assert_text= Found the expected warning line in the server log.
--let $assert_count=1
--source include/assert_grep.inc
--echo # System variable should not have been set.
SELECT @@mandatory_roles;
DROP ROLE r1, r2;
# Restart Server as usual
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--enable_reconnect
--source include/wait_until_connected_again.inc
--enable_reconnect
--source include/wait_until_connected_again.inc
remove_file $MYSQLTEST_VARDIR/tmp/temp_my.cnf;
# Reset the connections
disconnect sys_usr_con;
connect(sys_usr_con,localhost,sys_usr,pwd,);
disconnect non_sys_usr_con;
connect(non_sys_usr_con,localhost,non_sys_usr,pwd,);
connection default;
--echo #------------------------------------------------------------------------
--echo # 6. If the definer has SYSTEM_USER privilege then owner must also have
--echo # the SYSTEM_USER privilege.
--echo #------------------------------------------------------------------------
CREATE TABLE test.t1 (c1 INT);
CREATE DATABASE restricted;
CREATE TABLE restricted.t1 (c1 int, restricted int);
INSERT INTO restricted.t1 VALUES (1,2);
GRANT SET_USER_ID ON *.* TO sys_usr;
--echo
--echo # 6.1 Stored procedure and functions
connection sys_usr_con;
SELECT CURRENT_USER();
--error ER_TABLEACCESS_DENIED_ERROR
SELECT * FROM restricted.t1;
USE test;
CREATE DEFINER=root@localhost PROCEDURE p1() SELECT * FROM restricted.t1;
--echo # With the SET_USER_ID privilege we can escalate the authorization
CALL p1();
CREATE DEFINER=root@localhost FUNCTION f1(i INT) RETURNS INT(10) DETERMINISTIC
RETURN i*10;
--echo # With the SET_USER_ID privilege we can escalate the authorization
SELECT f1(2);
connection non_sys_usr_con;
--echo
SELECT CURRENT_USER();
USE test;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
CREATE DEFINER=root@localhost PROCEDURE p2() SELECT * FROM restricted.t1;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
CREATE DEFINER=root@localhost FUNCTION f2(i INT) RETURNS INT(10) DETERMINISTIC
RETURN i*10;
--echo # Invoker has EXECUTE privilege but not SYSTEM_USER privilege
CALL p1();
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
ALTER PROCEDURE test.p1 SQL SECURITY INVOKER;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
DROP PROCEDURE test.p1;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
ALTER FUNCTION test.f1 SQL SECURITY INVOKER;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
DROP FUNCTION test.f1;
--echo
--echo # 6.2 Create trigger
connection sys_usr_con;
SELECT CURRENT_USER();
CREATE DEFINER=root@localhost TRIGGER test.tr1 BEFORE INSERT ON test.t1
FOR EACH ROW INSERT INTO restricted.t1 VALUES (1,1);
--echo # Use trigger to escalate privileges
INSERT INTO test.t1 VALUES (1);
connection default;
SELECT * FROM restricted.t1;
connection non_sys_usr_con;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
CREATE DEFINER=root@localhost TRIGGER test.tr2 BEFORE INSERT ON test.t1
FOR EACH ROW INSERT INTO restricted.t1 VALUES (1,1);
--echo
--echo # 6.3 Create View
connection default;
--echo # We need some privilege on the column for CREATE VIEW to work
GRANT INSERT(restricted) ON restricted.t1 TO sys_usr;
connection sys_usr_con;
SHOW GRANTS FOR CURRENT_USER();
CREATE DEFINER=root@localhost SQL SECURITY DEFINER VIEW v1 AS
SELECT a.restricted FROM restricted.t1 as a;
--echo # Use escalated privileges to read restricted column.
SELECT * FROM v1;
connection non_sys_usr_con;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
CREATE DEFINER=root@localhost SQL SECURITY DEFINER VIEW v2 AS
SELECT a.restricted FROM restricted.t1 as a;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
ALTER ALGORITHM=MERGE VIEW v1 AS SELECT a.restricted FROM restricted.t1 as a;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
DROP VIEW v1;
--echo
--echo # 6.4 Create Event
connection sys_usr_con;
DELIMITER $$;
CREATE DEFINER=root@localhost EVENT test.eve1 ON SCHEDULE AT
CURRENT_TIMESTAMP + INTERVAL 2 HOUR
DO BEGIN
INSERT INTO restricted.t1 VALUES (5,5);
END ;$$
DELIMITER ;$$
connection non_sys_usr_con;
DELIMITER $$;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
CREATE DEFINER=root@localhost EVENT test.eve2 ON SCHEDULE AT
CURRENT_TIMESTAMP + INTERVAL 2 SECOND
DO BEGIN
INSERT INTO restricted.t1 VALUES (5,5);
END ;$$
DELIMITER ;$$
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
ALTER EVENT test.eve1 RENAME TO test.eve2;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
DROP EVENT test.eve1;
--echo # Cleanup
connection default;
DROP TRIGGER test.tr1;
DROP PROCEDURE p1;
DROP FUNCTION f1;
DROP DATABASE restricted;
DROP VIEW test.v1;
DROP TABLE test.t1;
DROP EVENT test.eve1;
--echo #------------------------------------------------------------------------
--echo # 7. If SYSTEM_USER privilege is granted to definer and invoker
--echo # through roles
--echo #------------------------------------------------------------------------
USE test;
CREATE TABLE test.t1 (c1 int, c2 int);
INSERT INTO test.t1 VALUES(1,2);
CREATE USER test_user@localhost;
GRANT sys_role TO test_user@localhost;
GRANT ALL ON test.* TO test_user@localhost;
GRANT EXECUTE ON *.* TO test_user@localhost;
--echo
--echo # 7.1 Invoker is not granted SYSTEM_USER priv through roles
--echo # 7.1.1 ALTER AND DROP STORED PROCEDURE
CREATE DEFINER=test_user@localhost PROCEDURE p1() SELECT * FROM test.t1;
SHOW GRANTS FOR test_user@localhost;
connection non_sys_usr_con;
CALL p1();
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
ALTER PROCEDURE test.p1 SQL SECURITY INVOKER;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
DROP PROCEDURE test.p1;
--echo # 7.1.2 ALTER and DROP FUNCTIONS
CREATE DEFINER=test_user@localhost FUNCTION f1(i INT) RETURNS INT(10) DETERMINISTIC
RETURN i*10;
connection non_sys_usr_con;
SELECT f1(2);
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
ALTER FUNCTION test.f1 SQL SECURITY INVOKER;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
DROP FUNCTION test.f1;
--echo # 7.1.3 ALTER and DROP View
connection default;
CREATE DEFINER=test_user@localhost SQL SECURITY DEFINER VIEW v1 AS
SELECT a.c1 FROM test.t1 as a;
SELECT * FROM v1;
connection non_sys_usr_con;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
ALTER VIEW v1 AS SELECT a.c1 FROM test.t1 as a;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
DROP VIEW v1;
--echo
--echo # 7.1.4 ALTER and DROP EVENT
connection default;
DELIMITER $$;
CREATE DEFINER=test_user@localhost EVENT test.eve1 ON SCHEDULE AT
CURRENT_TIMESTAMP + INTERVAL 2 HOUR
DO BEGIN
INSERT INTO test.t1 VALUES (5,5);
END ;$$
DELIMITER ;$$
connection non_sys_usr_con;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
ALTER EVENT test.eve1 RENAME TO test.eve2;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
DROP EVENT test.eve1;
--echo
--echo # 7.2 Invoker is also granted SYSTEM_USER priv through roles
connection default;
CREATE ROLE r1, r2;
GRANT SYSTEM_USER ON *.* TO r1;
GRANT r1 TO r2;
GRANT r2 TO non_sys_usr;
--echo # 7.2.1 ALTER and DROP PROCEDURE
connection non_sys_usr_con;
CALL p1();
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
ALTER PROCEDURE test.p1 SQL SECURITY INVOKER;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
DROP PROCEDURE test.p1;
--echo # Activate the role to get the SYSTEM_USER priv
SET ROLE r2;
ALTER PROCEDURE test.p1 SQL SECURITY INVOKER;
CALL p1();
DROP PROCEDURE test.p1;
SET ROLE NONE;
--echo # 7.2.2 ALTER and DROP FUNCTIONS
SELECT f1(2);
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
ALTER FUNCTION test.f1 SQL SECURITY INVOKER;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
DROP FUNCTION test.f1;
SELECT f1(2);
--echo # Activate the role to get the SYSTEM_USER priv
SET ROLE r2;
ALTER FUNCTION test.f1 SQL SECURITY INVOKER;
DROP FUNCTION test.f1;
SET ROLE NONE;
--echo # 7.2.3 ALTER and DROP VIEW
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
ALTER ALGORITHM=MERGE VIEW v1 AS SELECT a.c1 FROM test.t1 as a;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
DROP VIEW v1;
--echo # Activate the role to get the SYSTEM_USER priv
SET ROLE r2;
ALTER ALGORITHM=MERGE VIEW v1 AS SELECT a.c1 FROM test.t1 as a;
DROP VIEW v1;
SET ROLE NONE;
--echo
--echo # 7.2.4 ALTER and DROP EVENT
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
ALTER EVENT test.eve1 RENAME TO test.eve2;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
DROP EVENT test.eve1;
--echo # Activate the role to get the SYSTEM_USER priv
SET ROLE r2;
ALTER EVENT test.eve1 RENAME TO test.eve2;
DROP EVENT test.eve2;
SET ROLE NONE;
--echo # Cleanup
connection default;
DROP USER test_user@localhost;
DROP ROLE r1, r2;
DROP TABLE test.t1;
--echo #
--echo # Global clean up
--echo #
DROP USER sys_usr;
DROP USER non_sys_usr;
DROP USER sys_role;
DROP USER non_sys_role;
disconnect sys_usr_con;
disconnect non_sys_usr_con;
# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc
call mtr.add_suppression(".*Cannot set mandatory_roles: AuthId.* privilege.");