Skip to content

Commit 003d990

Browse files
committed
WL#14317: Offline_mode: checks for SYSTEM_USER and CONNECTION_ADMIN privileges
Description: ----------- When OFFLINE_MODE is activated, all connections without CONNECTION_ADMIN privilege are being terminated. The current implementation causes race conditions because sctx of one thread is accessed by another thread. This worklog solves the issue by introducing the atomic bool variable to cache the state of CONNECTION_ADMIN privilege. Using the variable avoids the need to check the sctx of another thread when activating OFFLINE_MODE. Additionally, a protection was added for the same operation, so that the user which only has SYSTEM_VARIABLES_ADMIN privilege (enough to perform the operation), must not kill the session of the user having SYSTEM_USER, but not CONNECTION_ADMIN privilege. Testing: ------- Test files added : - t/offline_mode_kill Approved by: Bharathy Satish <bharathy.x.satish@oracle.com> Approved by: Harin Vadodaria <harin.vadodaria@oracle.com> Approved by: Praveen Hulakund <praveenkumar.hulakund@oracle.com> RB: 27496 Change-Id: I52ee72124a61f6b92e4cb50595e541265bfcf5e2
1 parent 8ddb633 commit 003d990

13 files changed

+488
-22
lines changed

mysql-test/r/offline_mode_kill.result

+151
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
##
2+
## WL#14317: Offline_mode: checks for SYSTEM_USER and CONNECTION_ADMIN privileges
3+
##
4+
## Each of the following clients can activate server OFFLINE_MODE:
5+
## - regular_session: having SYSTEM_VARIABLES_ADMIN privilege
6+
## - power_session: having SYSTEM_VARIABLES_ADMIN and SYSTEM_USER privileges
7+
## - super_session: having SYSTEM_VARIABLES_ADMIN and CONNECTION_ADMIN privileges
8+
## - sysadmin_session: having SYSTEM_VARIABLES_ADMIN, CONNECTION_ADMIN, SYSTEM_USER privileges
9+
## Test that activating OFFLINE_MODE action performed by:
10+
## 1. regular_session only kills regular_sessions (including itself)
11+
## 2. power_session kills regular_sessions and power_sessions (including itself), but not super_session or sysadmin_session
12+
## 3. super_session kills regular_sessions, but not power_session or super_session or sysadmin_session
13+
## 4. sysadmin_session kills regular_sessions and power_sessions, but not super_session or sysadmin_session
14+
##
15+
SET @original_offline_mode = @@global.offline_mode;
16+
17+
### Setup ###
18+
19+
# Create regular_session user
20+
create user regular@localhost identified by 'regular';
21+
grant SYSTEM_VARIABLES_ADMIN on *.* to regular@localhost;
22+
23+
# Create power_session user
24+
create user power@localhost identified by 'power';
25+
grant SYSTEM_USER, SYSTEM_VARIABLES_ADMIN on *.* to power@localhost;
26+
27+
# Create super_session user (switches off OFFLINE_MODE)
28+
create user super@localhost identified by 'super';
29+
grant SYSTEM_VARIABLES_ADMIN, CONNECTION_ADMIN on *.* to super@localhost;
30+
31+
# Create sysadmin_session user (max privileges)
32+
create user sysadmin@localhost identified by 'sysadmin';
33+
grant SYSTEM_VARIABLES_ADMIN, CONNECTION_ADMIN, SYSTEM_USER on *.* to sysadmin@localhost;
34+
35+
flush privileges;
36+
37+
## TEST 1: regular_session activates OFFLINE_MODE
38+
39+
# Create power_session connection
40+
# Create regular_session connection
41+
# Create super_session connection (switches off OFFLINE_MODE)
42+
# Create sysadmin_session connection (max privileges)
43+
# Activate regular_session connection
44+
# Activate OFFLINE_MODE (with regular_session)
45+
SET GLOBAL OFFLINE_MODE=ON;
46+
# Verify that the regular_session killed itself
47+
SELECT USER();
48+
ERROR HY000: Lost connection to MySQL server during query
49+
# Verify that the power_session is kept alive
50+
SELECT USER();
51+
USER()
52+
power@localhost
53+
# Verify that the super_session is kept alive
54+
SELECT USER();
55+
USER()
56+
super@localhost
57+
# Verify that the sysadmin_session is kept alive
58+
SELECT USER();
59+
USER()
60+
sysadmin@localhost
61+
62+
## TEST 2: power_session activates OFFLINE_MODE
63+
64+
# Setup - activate super_session connection
65+
# Setup - deactivate OFFLINE_MODE
66+
SET GLOBAL OFFLINE_MODE=OFF;
67+
# Setup - create additional regular_session connection
68+
# Setup - create additional power_session connection
69+
# Activate power_session connection
70+
# Activate OFFLINE_MODE (with power_session)
71+
SET GLOBAL OFFLINE_MODE=ON;
72+
# Verify that the power_session killed itself
73+
SELECT USER();
74+
ERROR HY000: Lost connection to MySQL server during query
75+
# Verify that the regular_session has been killed
76+
SELECT USER();
77+
ERROR HY000: Lost connection to MySQL server during query
78+
# Verify that the additional power_session has been killed
79+
SELECT USER();
80+
ERROR HY000: Lost connection to MySQL server during query
81+
# Verify that the super_session is kept alive
82+
SELECT USER();
83+
USER()
84+
super@localhost
85+
# Verify that the sysadmin_session is kept alive
86+
SELECT USER();
87+
USER()
88+
sysadmin@localhost
89+
90+
## TEST 3: super_session activates OFFLINE_MODE
91+
92+
# Setup - activate super_session connection
93+
# Setup - deactivate OFFLINE_MODE
94+
SET GLOBAL OFFLINE_MODE=OFF;
95+
# Setup - create additional super_session connection
96+
# Setup - create additional regular_session connection
97+
# Setup - create additional power_session connection
98+
# Activate super_session connection
99+
# Activate OFFLINE_MODE (with super_session)
100+
SET GLOBAL OFFLINE_MODE=ON;
101+
# Verify that the regular_session has been killed
102+
SELECT USER();
103+
ERROR HY000: Lost connection to MySQL server during query
104+
# Verify that the power_session is kept alive
105+
SELECT USER();
106+
USER()
107+
power@localhost
108+
# Verify that the super_session is kept alive
109+
SELECT USER();
110+
USER()
111+
super@localhost
112+
# Verify that the additional super_session is kept alive
113+
SELECT USER();
114+
USER()
115+
super@localhost
116+
# Verify that the sysadmin_session is kept alive
117+
SELECT USER();
118+
USER()
119+
sysadmin@localhost
120+
121+
## TEST 4: sysadmin_session activates OFFLINE_MODE
122+
123+
# Setup - activate super_session connection
124+
# Setup - deactivate OFFLINE_MODE
125+
SET GLOBAL OFFLINE_MODE=OFF;
126+
# Setup - create additional regular_session connection
127+
# Activate sysadmin_session connection
128+
# Activate OFFLINE_MODE (with super_session)
129+
SET GLOBAL OFFLINE_MODE=ON;
130+
# Verify that the sysadmin_session did not kill itself
131+
SELECT USER();
132+
USER()
133+
sysadmin@localhost
134+
# Verify that the regular_session has been killed
135+
SELECT USER();
136+
ERROR HY000: Lost connection to MySQL server during query
137+
# Verify that the power_session has been killed
138+
SELECT USER();
139+
ERROR HY000: Lost connection to MySQL server during query
140+
# Verify that the super_session is kept alive
141+
SELECT USER();
142+
USER()
143+
super@localhost
144+
145+
# CLEAN UP
146+
147+
DROP USER regular@localhost;
148+
DROP USER power@localhost;
149+
DROP USER super@localhost;
150+
DROP USER sysadmin@localhost;
151+
SET @@global.offline_mode = @original_offline_mode;

mysql-test/t/offline_mode_kill.test

+227
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
--echo ##
2+
--echo ## WL#14317: Offline_mode: checks for SYSTEM_USER and CONNECTION_ADMIN privileges
3+
--echo ##
4+
--echo ## Each of the following clients can activate server OFFLINE_MODE:
5+
--echo ## - regular_session: having SYSTEM_VARIABLES_ADMIN privilege
6+
--echo ## - power_session: having SYSTEM_VARIABLES_ADMIN and SYSTEM_USER privileges
7+
--echo ## - super_session: having SYSTEM_VARIABLES_ADMIN and CONNECTION_ADMIN privileges
8+
--echo ## - sysadmin_session: having SYSTEM_VARIABLES_ADMIN, CONNECTION_ADMIN, SYSTEM_USER privileges
9+
--echo ## Test that activating OFFLINE_MODE action performed by:
10+
--echo ## 1. regular_session only kills regular_sessions (including itself)
11+
--echo ## 2. power_session kills regular_sessions and power_sessions (including itself), but not super_session or sysadmin_session
12+
--echo ## 3. super_session kills regular_sessions, but not power_session or super_session or sysadmin_session
13+
--echo ## 4. sysadmin_session kills regular_sessions and power_sessions, but not super_session or sysadmin_session
14+
--echo ##
15+
16+
SET @original_offline_mode = @@global.offline_mode;
17+
18+
--echo
19+
--echo ### Setup ###
20+
21+
--echo
22+
--echo # Create regular_session user
23+
create user regular@localhost identified by 'regular';
24+
grant SYSTEM_VARIABLES_ADMIN on *.* to regular@localhost;
25+
26+
--echo
27+
--echo # Create power_session user
28+
create user power@localhost identified by 'power';
29+
grant SYSTEM_USER, SYSTEM_VARIABLES_ADMIN on *.* to power@localhost;
30+
31+
--echo
32+
--echo # Create super_session user (switches off OFFLINE_MODE)
33+
create user super@localhost identified by 'super';
34+
grant SYSTEM_VARIABLES_ADMIN, CONNECTION_ADMIN on *.* to super@localhost;
35+
36+
--echo
37+
--echo # Create sysadmin_session user (max privileges)
38+
create user sysadmin@localhost identified by 'sysadmin';
39+
grant SYSTEM_VARIABLES_ADMIN, CONNECTION_ADMIN, SYSTEM_USER on *.* to sysadmin@localhost;
40+
41+
--echo
42+
flush privileges;
43+
44+
--echo
45+
--echo ## TEST 1: regular_session activates OFFLINE_MODE
46+
--echo
47+
48+
--echo # Create power_session connection
49+
connect (con_power, localhost, power, power, );
50+
51+
--echo # Create regular_session connection
52+
connect (con_regular, localhost, regular, regular, );
53+
54+
--echo # Create super_session connection (switches off OFFLINE_MODE)
55+
connect (con_super, localhost, super, super, );
56+
57+
--echo # Create sysadmin_session connection (max privileges)
58+
connect (con_sysadmin, localhost, sysadmin, sysadmin, );
59+
60+
--echo # Activate regular_session connection
61+
connection con_regular;
62+
63+
--echo # Activate OFFLINE_MODE (with regular_session)
64+
SET GLOBAL OFFLINE_MODE=ON;
65+
66+
--echo # Verify that the regular_session killed itself
67+
--error CR_SERVER_LOST
68+
SELECT USER();
69+
70+
--echo # Verify that the power_session is kept alive
71+
connection con_power;
72+
SELECT USER();
73+
74+
--echo # Verify that the super_session is kept alive
75+
connection con_super;
76+
SELECT USER();
77+
78+
--echo # Verify that the sysadmin_session is kept alive
79+
connection con_sysadmin;
80+
SELECT USER();
81+
82+
--echo
83+
--echo ## TEST 2: power_session activates OFFLINE_MODE
84+
--echo
85+
86+
--echo # Setup - activate super_session connection
87+
connection con_super;
88+
89+
--echo # Setup - deactivate OFFLINE_MODE
90+
SET GLOBAL OFFLINE_MODE=OFF;
91+
92+
--echo # Setup - create additional regular_session connection
93+
connect (con_regular1, localhost, regular, regular, );
94+
95+
--echo # Setup - create additional power_session connection
96+
connect (con_power1, localhost, power, power, );
97+
98+
--echo # Activate power_session connection
99+
connection con_power;
100+
101+
--echo # Activate OFFLINE_MODE (with power_session)
102+
SET GLOBAL OFFLINE_MODE=ON;
103+
104+
--echo # Verify that the power_session killed itself
105+
--error CR_SERVER_LOST
106+
SELECT USER();
107+
108+
--echo # Verify that the regular_session has been killed
109+
connection con_regular1;
110+
--error CR_SERVER_LOST
111+
SELECT USER();
112+
113+
--echo # Verify that the additional power_session has been killed
114+
connection con_power1;
115+
--error CR_SERVER_LOST
116+
SELECT USER();
117+
118+
--echo # Verify that the super_session is kept alive
119+
connection con_super;
120+
SELECT USER();
121+
122+
--echo # Verify that the sysadmin_session is kept alive
123+
connection con_sysadmin;
124+
SELECT USER();
125+
126+
--echo
127+
--echo ## TEST 3: super_session activates OFFLINE_MODE
128+
--echo
129+
130+
--echo # Setup - activate super_session connection
131+
connection con_super;
132+
133+
--echo # Setup - deactivate OFFLINE_MODE
134+
SET GLOBAL OFFLINE_MODE=OFF;
135+
136+
--echo # Setup - create additional super_session connection
137+
connect (con_super1, localhost, super, super, );
138+
139+
--echo # Setup - create additional regular_session connection
140+
connect (con_regular2, localhost, regular, regular, );
141+
142+
--echo # Setup - create additional power_session connection
143+
connect (con_power2, localhost, power, power, );
144+
145+
--echo # Activate super_session connection
146+
connection con_super;
147+
148+
--echo # Activate OFFLINE_MODE (with super_session)
149+
SET GLOBAL OFFLINE_MODE=ON;
150+
151+
--echo # Verify that the regular_session has been killed
152+
connection con_regular2;
153+
--error CR_SERVER_LOST
154+
SELECT USER();
155+
156+
--echo # Verify that the power_session is kept alive
157+
connection con_power2;
158+
SELECT USER();
159+
160+
--echo # Verify that the super_session is kept alive
161+
connection con_super;
162+
SELECT USER();
163+
164+
--echo # Verify that the additional super_session is kept alive
165+
connection con_super1;
166+
SELECT USER();
167+
168+
--echo # Verify that the sysadmin_session is kept alive
169+
connection con_sysadmin;
170+
SELECT USER();
171+
172+
--echo
173+
--echo ## TEST 4: sysadmin_session activates OFFLINE_MODE
174+
--echo
175+
176+
--echo # Setup - activate super_session connection
177+
connection con_super;
178+
179+
--echo # Setup - deactivate OFFLINE_MODE
180+
SET GLOBAL OFFLINE_MODE=OFF;
181+
182+
--echo # Setup - create additional regular_session connection
183+
connect (con_regular3, localhost, regular, regular, );
184+
185+
--echo # Activate sysadmin_session connection
186+
connection con_sysadmin;
187+
188+
--echo # Activate OFFLINE_MODE (with super_session)
189+
SET GLOBAL OFFLINE_MODE=ON;
190+
191+
--echo # Verify that the sysadmin_session did not kill itself
192+
SELECT USER();
193+
194+
--echo # Verify that the regular_session has been killed
195+
connection con_regular3;
196+
--error CR_SERVER_LOST
197+
SELECT USER();
198+
199+
--echo # Verify that the power_session has been killed
200+
connection con_power2;
201+
--error CR_SERVER_LOST
202+
SELECT USER();
203+
204+
--echo # Verify that the super_session is kept alive
205+
connection con_super;
206+
SELECT USER();
207+
208+
## Cleanup
209+
--echo
210+
--echo # CLEAN UP
211+
--echo
212+
connection default;
213+
disconnect con_super;
214+
disconnect con_super1;
215+
disconnect con_regular;
216+
disconnect con_regular1;
217+
disconnect con_regular2;
218+
disconnect con_regular3;
219+
disconnect con_power;
220+
disconnect con_power1;
221+
disconnect con_power2;
222+
disconnect con_sysadmin;
223+
DROP USER regular@localhost;
224+
DROP USER power@localhost;
225+
DROP USER super@localhost;
226+
DROP USER sysadmin@localhost;
227+
SET @@global.offline_mode = @original_offline_mode;

0 commit comments

Comments
 (0)