Skip to content

Commit 4fbdffa

Browse files
committed
Bug#35471453: MySQL debug server stops when executing query
The error generation code was not prepared to handle CREATE/DROP ROLE as top level statements when checking for orphan SQL objects (views in this case). Added a case for the two new commands and also moved the code into the branch that needs it. Fixed the line endings of a test case. Added a test. Change-Id: I5ffbf3fc816529d506fd8e1a26a00917c1df1819
1 parent 567ab09 commit 4fbdffa

File tree

3 files changed

+174
-91
lines changed

3 files changed

+174
-91
lines changed

mysql-test/r/roles_bugs_debug.result

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,39 @@ SET DEBUG_SYNC= 'RESET';
4040
DROP DATABASE my_db;
4141
DROP USER foo, bar;
4242
DROP ROLE foo_role;
43+
#
44+
# Bug #35471453: MySQL debug server stops when executing query
45+
#
46+
CREATE USER b35471453@localhost;
47+
GRANT CREATE ROLE, DROP ROLE ON *.* TO b35471453@localhost;
48+
CREATE TABLE t35471453(c1 INT);
49+
# test1: should fail
50+
CREATE OR REPLACE DEFINER = 'role_35471453' VIEW v35471453
51+
AS TABLE t35471453;
52+
ERROR 42000: Access denied; you need (at least one of) the SUPER or SET_USER_ID privilege(s) for this operation
53+
# Now grant SET_USER_ID and retry
54+
GRANT SET_USER_ID ON *.* TO b35471453@localhost;
55+
# test2: should complete with a warning
56+
CREATE OR REPLACE DEFINER = 'role_35471453' VIEW v35471453
57+
AS TABLE t35471453;
58+
Warnings:
59+
Note 1449 The user specified as a definer ('role_35471453'@'%') does not exist
60+
# Now revoke SET_USER_ID and try dropping the role
61+
REVOKE SET_USER_ID ON *.* FROM b35471453@localhost;
62+
# test3: should fail
63+
DROP ROLE IF EXISTS role_35471453;
64+
ERROR HY000: Operation DROP ROLE failed for 'role_35471453'@'%' as it is referenced as a definer account in a view.
65+
# Now grant SET_USER_ID and retry
66+
GRANT SET_USER_ID ON *.* TO b35471453@localhost;
67+
# test4: should pass with a warning
68+
DROP ROLE IF EXISTS role_35471453;
69+
Warnings:
70+
Warning 4005 User 'role_35471453'@'%' is referenced as a definer account in a view.
71+
Note 3162 Authorization ID 'role_35471453'@'%' does not exist.
72+
DROP VIEW v35471453;
73+
DROP TABLE t35471453;
74+
REVOKE CREATE ROLE, DROP ROLE, SET_USER_ID ON *.* FROM b35471453@localhost;
75+
DROP USER b35471453@localhost;
4376

4477
# End of 8.0 tests
4578

mysql-test/t/roles_bugs_debug.test

Lines changed: 121 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,121 @@
1-
# Save the initial number of concurrent sessions
2-
--source include/count_sessions.inc
3-
--source include/have_debug.inc
4-
5-
--echo #
6-
--echo # Bug#28395115: permission denied if grants are given through role
7-
--echo #
8-
# We are verifying the after effects of revoking a privilege from a user and
9-
# a role from another session while a user is in the middle of executing current
10-
# SQL statement. Expected Behavior :
11-
# 1. In case of privileges are revoked from a role changes are invisible
12-
# until next SQL statement is executed.
13-
# 2. In case of privileges are revokes from a user changes are visible
14-
# immediately to the current SQL statement.
15-
16-
# Setup
17-
CREATE DATABASE my_db;
18-
CREATE table my_db.t1 (id int primary key);
19-
CREATE ROLE foo_role;
20-
CREATE USER foo, bar;
21-
# Grant required column privileges to a role and user.
22-
GRANT INSERT(id), UPDATE(id), SELECT(id) ON my_db.t1 to foo_role, bar;
23-
GRANT EXECUTE, SYSTEM_VARIABLES_ADMIN ON *.* TO foo, bar;
24-
GRANT foo_role TO foo;
25-
SET DEFAULT ROLE foo_role TO foo;
26-
27-
--connect(foo_con, localhost, foo,,,)
28-
SET DEBUG_SYNC='in_check_grant_all_columns SIGNAL s1 WAIT_FOR s2';
29-
--echo # Inserts are now allowed if grants are given through role
30-
send INSERT into my_db.t1 values(8) on duplicate key UPDATE id = values(id) + 80;
31-
32-
connection default;
33-
--echo # Now revoke all privileges from the role
34-
SET DEBUG_SYNC='now WAIT_FOR s1';
35-
SET DEBUG_SYNC='after_table_grant_revoke SIGNAL s2';
36-
REVOKE ALL ON my_db.t1 FROM foo_role;
37-
connection foo_con;
38-
--echo # Despite all privileges are revoked current SQL statement will succeed.
39-
reap;
40-
SET DEBUG_SYNC= 'RESET';
41-
--echo # But the subsequent statement will fail.
42-
--error ER_TABLEACCESS_DENIED_ERROR
43-
INSERT into my_db.t1 values(9) on duplicate key UPDATE id = values(id) + 90;
44-
45-
46-
--connect(bar_con, localhost, bar,,,)
47-
SET DEBUG_SYNC='in_check_grant_all_columns SIGNAL s1 WAIT_FOR s2';
48-
--echo # Inserts are now allowed if grants are given through role
49-
send INSERT into my_db.t1 values(6) on duplicate key UPDATE id = values(id) + 60;
50-
connection default;
51-
--echo # Now revoke all privileges from the user
52-
SET DEBUG_SYNC='now WAIT_FOR s1';
53-
SET DEBUG_SYNC='after_table_grant_revoke SIGNAL s2';
54-
REVOKE ALL ON my_db.t1 FROM bar;
55-
connection bar_con;
56-
--echo # Since all privileges are revoked therefore current SQL statement will fail.
57-
--error ER_COLUMNACCESS_DENIED_ERROR
58-
reap;
59-
--echo # Subsequent statement will fail as well.
60-
--error ER_TABLEACCESS_DENIED_ERROR
61-
INSERT into my_db.t1 values(9) on duplicate key UPDATE id = values(id) + 90;
62-
63-
--echo # Cleanup
64-
connection default;
65-
SET DEBUG_SYNC= 'RESET';
66-
disconnect foo_con;
67-
disconnect bar_con;
68-
DROP DATABASE my_db;
69-
DROP USER foo, bar;
70-
DROP ROLE foo_role;
71-
72-
--echo
73-
--echo # End of 8.0 tests
74-
--echo
75-
76-
# Wait till we reached the initial number of concurrent sessions
77-
--source include/wait_until_count_sessions.inc
1+
# Save the initial number of concurrent sessions
2+
--source include/count_sessions.inc
3+
--source include/have_debug.inc
4+
5+
--echo #
6+
--echo # Bug#28395115: permission denied if grants are given through role
7+
--echo #
8+
# We are verifying the after effects of revoking a privilege from a user and
9+
# a role from another session while a user is in the middle of executing current
10+
# SQL statement. Expected Behavior :
11+
# 1. In case of privileges are revoked from a role changes are invisible
12+
# until next SQL statement is executed.
13+
# 2. In case of privileges are revokes from a user changes are visible
14+
# immediately to the current SQL statement.
15+
16+
# Setup
17+
CREATE DATABASE my_db;
18+
CREATE table my_db.t1 (id int primary key);
19+
CREATE ROLE foo_role;
20+
CREATE USER foo, bar;
21+
# Grant required column privileges to a role and user.
22+
GRANT INSERT(id), UPDATE(id), SELECT(id) ON my_db.t1 to foo_role, bar;
23+
GRANT EXECUTE, SYSTEM_VARIABLES_ADMIN ON *.* TO foo, bar;
24+
GRANT foo_role TO foo;
25+
SET DEFAULT ROLE foo_role TO foo;
26+
27+
--connect(foo_con, localhost, foo,,,)
28+
SET DEBUG_SYNC='in_check_grant_all_columns SIGNAL s1 WAIT_FOR s2';
29+
--echo # Inserts are now allowed if grants are given through role
30+
send INSERT into my_db.t1 values(8) on duplicate key UPDATE id = values(id) + 80;
31+
32+
connection default;
33+
--echo # Now revoke all privileges from the role
34+
SET DEBUG_SYNC='now WAIT_FOR s1';
35+
SET DEBUG_SYNC='after_table_grant_revoke SIGNAL s2';
36+
REVOKE ALL ON my_db.t1 FROM foo_role;
37+
connection foo_con;
38+
--echo # Despite all privileges are revoked current SQL statement will succeed.
39+
reap;
40+
SET DEBUG_SYNC= 'RESET';
41+
--echo # But the subsequent statement will fail.
42+
--error ER_TABLEACCESS_DENIED_ERROR
43+
INSERT into my_db.t1 values(9) on duplicate key UPDATE id = values(id) + 90;
44+
45+
46+
--connect(bar_con, localhost, bar,,,)
47+
SET DEBUG_SYNC='in_check_grant_all_columns SIGNAL s1 WAIT_FOR s2';
48+
--echo # Inserts are now allowed if grants are given through role
49+
send INSERT into my_db.t1 values(6) on duplicate key UPDATE id = values(id) + 60;
50+
connection default;
51+
--echo # Now revoke all privileges from the user
52+
SET DEBUG_SYNC='now WAIT_FOR s1';
53+
SET DEBUG_SYNC='after_table_grant_revoke SIGNAL s2';
54+
REVOKE ALL ON my_db.t1 FROM bar;
55+
connection bar_con;
56+
--echo # Since all privileges are revoked therefore current SQL statement will fail.
57+
--error ER_COLUMNACCESS_DENIED_ERROR
58+
reap;
59+
--echo # Subsequent statement will fail as well.
60+
--error ER_TABLEACCESS_DENIED_ERROR
61+
INSERT into my_db.t1 values(9) on duplicate key UPDATE id = values(id) + 90;
62+
63+
--echo # Cleanup
64+
connection default;
65+
SET DEBUG_SYNC= 'RESET';
66+
disconnect foo_con;
67+
disconnect bar_con;
68+
DROP DATABASE my_db;
69+
DROP USER foo, bar;
70+
DROP ROLE foo_role;
71+
72+
73+
--echo #
74+
--echo # Bug #35471453: MySQL debug server stops when executing query
75+
--echo #
76+
77+
CREATE USER b35471453@localhost;
78+
GRANT CREATE ROLE, DROP ROLE ON *.* TO b35471453@localhost;
79+
--connect(b35471453_con, localhost, b35471453,,,)
80+
CREATE TABLE t35471453(c1 INT);
81+
--echo # test1: should fail
82+
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
83+
CREATE OR REPLACE DEFINER = 'role_35471453' VIEW v35471453
84+
AS TABLE t35471453;
85+
--echo # Now grant SET_USER_ID and retry
86+
connection default;
87+
GRANT SET_USER_ID ON *.* TO b35471453@localhost;
88+
connection b35471453_con;
89+
--echo # test2: should complete with a warning
90+
CREATE OR REPLACE DEFINER = 'role_35471453' VIEW v35471453
91+
AS TABLE t35471453;
92+
--echo # Now revoke SET_USER_ID and try dropping the role
93+
connection default;
94+
REVOKE SET_USER_ID ON *.* FROM b35471453@localhost;
95+
connection b35471453_con;
96+
97+
--echo # test3: should fail
98+
--error ER_CANNOT_USER_REFERENCED_AS_DEFINER
99+
DROP ROLE IF EXISTS role_35471453;
100+
--echo # Now grant SET_USER_ID and retry
101+
connection default;
102+
GRANT SET_USER_ID ON *.* TO b35471453@localhost;
103+
connection b35471453_con;
104+
--echo # test4: should pass with a warning
105+
DROP ROLE IF EXISTS role_35471453;
106+
107+
DROP VIEW v35471453;
108+
DROP TABLE t35471453;
109+
connection default;
110+
disconnect b35471453_con;
111+
112+
REVOKE CREATE ROLE, DROP ROLE, SET_USER_ID ON *.* FROM b35471453@localhost;
113+
DROP USER b35471453@localhost;
114+
115+
116+
--echo
117+
--echo # End of 8.0 tests
118+
--echo
119+
120+
# Wait till we reached the initial number of concurrent sessions
121+
--source include/wait_until_count_sessions.inc

sql/auth/sql_user.cc

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2575,24 +2575,30 @@ static int handle_grant_data(THD *thd, Table_ref *tables, bool drop,
25752575
bool check_set_user_id_priv(THD *thd, const LEX_USER *user_name,
25762576
const std::string &object_type) {
25772577
String wrong_user;
2578-
std::string operation;
2579-
switch (thd->lex->sql_command) {
2580-
case SQLCOM_CREATE_USER:
2581-
operation = "CREATE USER";
2582-
break;
2583-
case SQLCOM_DROP_USER:
2584-
operation = "DROP USER";
2585-
break;
2586-
case SQLCOM_RENAME_USER:
2587-
operation = "RENAME USER";
2588-
break;
2589-
default:
2590-
assert(0);
2591-
}
25922578
log_user(thd, &wrong_user, const_cast<LEX_USER *>(user_name), false);
25932579
if (!(thd->security_context()
25942580
->has_global_grant(STRING_WITH_LEN("SET_USER_ID"))
25952581
.first)) {
2582+
std::string operation;
2583+
switch (thd->lex->sql_command) {
2584+
case SQLCOM_CREATE_USER:
2585+
operation = "CREATE USER";
2586+
break;
2587+
case SQLCOM_DROP_USER:
2588+
operation = "DROP USER";
2589+
break;
2590+
case SQLCOM_RENAME_USER:
2591+
operation = "RENAME USER";
2592+
break;
2593+
case SQLCOM_CREATE_ROLE:
2594+
operation = "CREATE ROLE";
2595+
break;
2596+
case SQLCOM_DROP_ROLE:
2597+
operation = "DROP ROLE";
2598+
break;
2599+
default:
2600+
assert(0);
2601+
}
25962602
my_error(ER_CANNOT_USER_REFERENCED_AS_DEFINER, MYF(0), operation.c_str(),
25972603
wrong_user.c_ptr_safe(), object_type.c_str());
25982604
return true;

0 commit comments

Comments
 (0)