Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 193 additions & 0 deletions mysql-test/main/deny_revoke_public.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
#
# MDEV-40656 REVOKE DENY FROM PUBLIC can lock itself out
#
# DENY TO PUBLIC denies everyone, including whoever tries to revoke
# it. Allowed anyway when the revoker can UPDATE mysql.global_priv,
# same as hand-editing it. Checked at every scope: global, db, table,
# column, routine.
#
CREATE TABLE test.t1 (id INT, data INT);
INSERT INTO test.t1 VALUES (1, 100);
CREATE PROCEDURE test.p1() BEGIN SELECT 1; END|
#
# Same session: no bypass needed, privileges aren't re-read yet
#
DENY SELECT ON test.t1 TO PUBLIC;
REVOKE DENY SELECT ON test.t1 FROM PUBLIC;
#
# Table level
#
CREATE USER u_table@localhost;
GRANT SELECT ON test.t1 TO u_table@localhost;
DENY SELECT ON test.t1 TO PUBLIC;
connect con_table1, localhost, u_table,,test;
SELECT * FROM t1;
ERROR 42000: SELECT command denied to user 'u_table'@'localhost' for table `test`.`t1`
REVOKE DENY SELECT ON test.t1 FROM PUBLIC;
ERROR 42000: SELECT, GRANT command denied to user 'u_table'@'localhost' for table `test`.`t1`
disconnect con_table1;
connection default;
GRANT UPDATE ON mysql.global_priv TO u_table@localhost;
connect con_table2, localhost, u_table,,test;
SELECT * FROM t1;
ERROR 42000: SELECT command denied to user 'u_table'@'localhost' for table `test`.`t1`
REVOKE DENY SELECT ON test.t1 FROM PUBLIC;
SELECT * FROM t1;
id data
1 100
disconnect con_table2;
connection default;
REVOKE UPDATE ON mysql.global_priv FROM u_table@localhost;
DROP USER u_table@localhost;
#
# Column level
#
CREATE USER u_col@localhost;
GRANT SELECT ON test.t1 TO u_col@localhost;
DENY SELECT (data) ON test.t1 TO PUBLIC;
connect con_col1, localhost, u_col,,test;
SELECT data FROM t1;
ERROR 42000: SELECT command denied to user 'u_col'@'localhost' for column 'data' in table 't1'
REVOKE DENY SELECT (data) ON test.t1 FROM PUBLIC;
ERROR 42000: GRANT command denied to user 'u_col'@'localhost' for table `test`.`t1`
disconnect con_col1;
connection default;
GRANT UPDATE ON mysql.global_priv TO u_col@localhost;
connect con_col2, localhost, u_col,,test;
SELECT data FROM t1;
ERROR 42000: SELECT command denied to user 'u_col'@'localhost' for column 'data' in table 't1'
REVOKE DENY SELECT (data) ON test.t1 FROM PUBLIC;
SELECT data FROM t1;
data
100
disconnect con_col2;
connection default;
REVOKE UPDATE ON mysql.global_priv FROM u_col@localhost;
DROP USER u_col@localhost;
#
# DB level
#
CREATE USER u_db@localhost;
GRANT SELECT ON test.* TO u_db@localhost;
DENY SELECT ON test.* TO PUBLIC;
connect con_db1, localhost, u_db,,;
SELECT * FROM test.t1;
ERROR 42000: SELECT command denied to user 'u_db'@'localhost' for table `test`.`t1`
REVOKE DENY SELECT ON test.* FROM PUBLIC;
ERROR 42000: Access denied for user 'u_db'@'localhost' to database 'test'
disconnect con_db1;
connection default;
GRANT UPDATE ON mysql.global_priv TO u_db@localhost;
connect con_db2, localhost, u_db,,;
SELECT * FROM test.t1;
ERROR 42000: SELECT command denied to user 'u_db'@'localhost' for table `test`.`t1`
REVOKE DENY SELECT ON test.* FROM PUBLIC;
SELECT * FROM test.t1;
id data
1 100
disconnect con_db2;
connection default;
REVOKE UPDATE ON mysql.global_priv FROM u_db@localhost;
DROP USER u_db@localhost;
#
# Global level
#
CREATE USER u_global@localhost;
GRANT SELECT ON *.* TO u_global@localhost;
DENY SELECT ON *.* TO PUBLIC;
connect con_global1, localhost, u_global,,;
SELECT * FROM test.t1;
ERROR 42000: SELECT command denied to user 'u_global'@'localhost' for table `test`.`t1`
REVOKE DENY SELECT ON *.* FROM PUBLIC;
ERROR 28000: Access denied for user 'u_global'@'localhost' (using password: NO)
disconnect con_global1;
connection default;
GRANT UPDATE ON mysql.global_priv TO u_global@localhost;
connect con_global2, localhost, u_global,,;
SELECT * FROM test.t1;
ERROR 42000: SELECT command denied to user 'u_global'@'localhost' for table `test`.`t1`
REVOKE DENY SELECT ON *.* FROM PUBLIC;
disconnect con_global2;
connection default;
# master_access is cached at connect; needs a reconnect to take effect
connect con_global3, localhost, u_global,,;
SELECT * FROM test.t1;
id data
1 100
disconnect con_global3;
connection default;
REVOKE UPDATE ON mysql.global_priv FROM u_global@localhost;
DROP USER u_global@localhost;
#
# Routine level
#
CREATE USER u_proc@localhost;
GRANT EXECUTE ON PROCEDURE test.p1 TO u_proc@localhost;
DENY EXECUTE ON PROCEDURE test.p1 TO PUBLIC;
connect con_proc1, localhost, u_proc,,test;
CALL p1();
ERROR 42000: execute command denied to user 'u_proc'@'localhost' for routine 'test.p1'
REVOKE DENY EXECUTE ON PROCEDURE test.p1 FROM PUBLIC;
ERROR 42000: execute command denied to user 'u_proc'@'localhost' for routine 'test.p1'
disconnect con_proc1;
connection default;
GRANT UPDATE ON mysql.global_priv TO u_proc@localhost;
connect con_proc2, localhost, u_proc,,test;
CALL p1();
ERROR 42000: execute command denied to user 'u_proc'@'localhost' for routine 'test.p1'
REVOKE DENY EXECUTE ON PROCEDURE test.p1 FROM PUBLIC;
CALL p1();
1
1
disconnect con_proc2;
connection default;
REVOKE UPDATE ON mysql.global_priv FROM u_proc@localhost;
DROP USER u_proc@localhost;
#
# A role is not PUBLIC: no bypass, even with UPDATE on mysql.global_priv
#
CREATE ROLE r1;
CREATE USER u_role@localhost;
GRANT r1 TO u_role@localhost;
GRANT SELECT ON test.t1 TO r1;
DENY SELECT ON test.t1 TO r1;
GRANT UPDATE ON mysql.global_priv TO u_role@localhost;
connect con_role, localhost, u_role,,;
SET ROLE r1;
SELECT * FROM test.t1;
ERROR 42000: SELECT command denied to user 'u_role'@'localhost' for table `test`.`t1`
REVOKE DENY SELECT ON test.t1 FROM r1;
ERROR 42000: SELECT, GRANT command denied to user 'u_role'@'localhost' for table `test`.`t1`
disconnect con_role;
connection default;
REVOKE UPDATE ON mysql.global_priv FROM u_role@localhost;
REVOKE DENY SELECT ON test.t1 FROM r1;
DROP USER u_role@localhost;
DROP ROLE r1;
#
# Known limitation: denying the bypass's own privilege is unrecoverable
#
DENY UPDATE ON *.* TO PUBLIC;
disconnect default;
connect default, localhost, root,,;
# Should FAIL - root can't UPDATE anywhere either, including this table
UPDATE mysql.global_priv SET Priv=Priv WHERE User='PUBLIC';
ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table `mysql`.`global_priv`
# Should FAIL - no recovery via REVOKE DENY once UPDATE itself is denied
REVOKE DENY UPDATE ON *.* FROM PUBLIC;
ERROR 28000: Access denied for user 'root'@'localhost' (using password: NO)
# Recovery: DELETE was never denied
DELETE FROM mysql.global_priv WHERE User='PUBLIC';
FLUSH PRIVILEGES;
disconnect default;
connect default, localhost, root,,;
# UPDATE works again after reconnecting
UPDATE mysql.global_priv SET Priv=Priv WHERE User='root' AND Host='localhost';
#
# Cleanup
#
DROP PROCEDURE test.p1;
DROP TABLE test.t1;
DELETE FROM mysql.global_priv WHERE User='PUBLIC';
FLUSH PRIVILEGES;
# End of 13.1 tests
Loading
Loading