1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439
|
# FR 1.2, FR 2.2 Test a user with password history checks off
CREATE USER no_pwd_history@localhost
PASSWORD HISTORY 0 PASSWORD REUSE INTERVAL 0 DAY;
# Check the mysql.user columns. Must be zeroes.
SELECT Password_reuse_history, Password_reuse_time
FROM mysql.user
WHERE Host='localhost' AND User='no_pwd_history';
Password_reuse_history Password_reuse_time
0 0
# Must return 0 rows
SELECT COUNT(*) FROM mysql.password_history WHERE
User='no_pwd_history' AND Host='localhost';
COUNT(*)
0
SET PASSWORD FOR no_pwd_history@localhost = 'changeme';
# SET PASSWORD FOR should not produce rows
SELECT COUNT(*) FROM mysql.password_history WHERE
User='no_pwd_history' AND Host='localhost';
COUNT(*)
0
ALTER USER no_pwd_history@localhost IDENTIFIED BY 'changemeagain';
# ALTER USER IDENTIFIED BY should not produce rows
SELECT COUNT(*) FROM mysql.password_history WHERE
User='no_pwd_history' AND Host='localhost';
COUNT(*)
0
ALTER USER no_pwd_history@localhost IDENTIFIED WITH "mysql_native_password"
AS '*C40F578E1A9D8D1146AFD04AFCB0228EED9D45FB';
# ALTER USER IDENTIFIED WITH .. AS .. should not produce rows
SELECT COUNT(*) FROM mysql.password_history WHERE
User='no_pwd_history' AND Host='localhost';
COUNT(*)
0
# try 2 statements in a row in a quick succession
SET PASSWORD='pwd1'; SET PASSWORD='pwd2';;
# 2 SET PASSWORD should not produce rows
SELECT COUNT(*) FROM mysql.password_history WHERE
User='no_pwd_history' AND Host='localhost';
COUNT(*)
0
# FR 1.1.1: must succeed
SET GLOBAL password_history= 1;
# FR 1.1.2: must succeed. No history tracked so far
SET PASSWORD FOR no_pwd_history@localhost = 'tracked';
# must be 0: unaffected by the global
SELECT COUNT(*) FROM mysql.password_history WHERE
User='no_pwd_history' AND Host='localhost';
COUNT(*)
0
# FR 1.1.2: must succeed again: no tracking
SET PASSWORD FOR no_pwd_history@localhost = 'tracked';
# must be 0: unaffected by the global again
SELECT COUNT(*) FROM mysql.password_history WHERE
User='no_pwd_history' AND Host='localhost';
COUNT(*)
0
SET GLOBAL password_history= default;
# FR 2.1.1: must be settable at runtime
SET GLOBAL password_reuse_interval= 100;
# FR 2.1.2: Must succeed: no history tracked
SET PASSWORD FOR no_pwd_history@localhost = 'tracked';
# must be 0: unaffected by the global password reuse interval
SELECT COUNT(*) FROM mysql.password_history WHERE
User='no_pwd_history' AND Host='localhost';
COUNT(*)
0
# FR 2.1.2: password still not tracked: must succeed
SET PASSWORD FOR no_pwd_history@localhost = 'tracked';
# must be 0: still unaffected by the global password reuse interval
SELECT COUNT(*) FROM mysql.password_history WHERE
User='no_pwd_history' AND Host='localhost';
COUNT(*)
0
# FR6: Must have the password history clauses
SHOW CREATE USER no_pwd_history@localhost;
CREATE USER for no_pwd_history@localhost
CREATE USER `no_pwd_history`@`localhost` IDENTIFIED WITH 'mysql_native_password' AS '<non-deterministic-password-hash>' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY 0 PASSWORD REUSE INTERVAL 0 DAY PASSWORD REQUIRE CURRENT DEFAULT
# NF 1.3 NF 2.3: Must have 0 and 0 for the password history columns
SELECT Password_reuse_history, Password_reuse_time FROM mysql.user
WHERE User='no_pwd_history' AND Host='localhost';
Password_reuse_history Password_reuse_time
0 0
SET GLOBAL password_reuse_interval= DEFAULT;
DROP USER no_pwd_history@localhost;
# Test the effect of reuse interval on regular users
CREATE USER default_def@localhost IDENTIFIED BY 'haha';
# FR6: must have the history clauses
SHOW CREATE USER default_def@localhost;
CREATE USER for default_def@localhost
CREATE USER `default_def`@`localhost` IDENTIFIED WITH 'caching_sha2_password' AS '<non-deterministic-password-hash>' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT PASSWORD REQUIRE CURRENT DEFAULT
# NF 1.3 NF 2.3 Must have NULL and NULL for the password history columns
SELECT Password_reuse_history, Password_reuse_time FROM mysql.user
WHERE User='default_def' AND Host='localhost';
Password_reuse_history Password_reuse_time
NULL NULL
# FR1.1.2: must be 0: default is 0 and it's effective for default users
SELECT COUNT(*) FROM mysql.password_history WHERE
User='default_def' AND Host='localhost';
COUNT(*)
0
# FR1.1.2: set a global of 1 and see if it affects the default users
SET GLOBAL password_history=1;
# Must work: first change
ALTER USER default_def@localhost IDENTIFIED BY 'haha';
# FR1.1.2: must be 1: global is 1 and it's effective for default users
SELECT COUNT(*) FROM mysql.password_history WHERE
User='default_def' AND Host='localhost';
COUNT(*)
1
# Must fail: change to the same password and global is 1 for default users
ALTER USER default_def@localhost IDENTIFIED BY 'haha';
ERROR HY000: Cannot use these credentials for 'default_def@localhost' because they contradict the password history policy
SET GLOBAL password_history=default;
# Must pass: change to the same password and global is 0
ALTER USER default_def@localhost IDENTIFIED BY 'haha';
# FR3.3: must be 0: global is 0 and it's effective for default users
SELECT COUNT(*) FROM mysql.password_history WHERE
User='default_def' AND Host='localhost';
COUNT(*)
0
# FR3.4: set a global of 1 record history and then remove the user
SET GLOBAL password_history=1;
# Must pass: change to the same password and global is 0
ALTER USER default_def@localhost IDENTIFIED BY 'haha';
# must be 1: global is 1 and it's effective for default users
SELECT COUNT(*) FROM mysql.password_history WHERE
User='default_def' AND Host='localhost';
COUNT(*)
1
DROP USER default_def@localhost;
# FR3.4: must be 0: global is 0 and the user is dropped
SELECT COUNT(*) FROM mysql.password_history WHERE
User='default_def' AND Host='localhost';
COUNT(*)
0
SET GLOBAL password_history=default;
# FR3.5: set a global of 1, record history and then change auth
SET GLOBAL password_history=1;
CREATE USER method_alter@localhost IDENTIFIED BY 'haha';
# must be 1: global is 1 and create user should have logged the password
SELECT COUNT(*) FROM mysql.password_history WHERE
User='method_alter' AND Host='localhost';
COUNT(*)
1
# FR3.6: must be 1: at least 1 hash is equal in history and in mysql.user
SELECT COUNT(*) FROM mysql.password_history, mysql.user WHERE
mysql.user.User='method_alter' AND mysql.user.host='localhost' AND
mysql.user.User=mysql.password_history.user AND
mysql.user.host=mysql.password_history.host;
COUNT(*)
1
ALTER USER method_alter@localhost IDENTIFIED WITH 'sha256_password';
# must be 0: changing the auth method prunes history
SELECT COUNT(*) FROM mysql.password_history WHERE
User='method_alter' AND Host='localhost';
COUNT(*)
0
DROP USER method_alter@localhost;
SET GLOBAL password_history=default;
# FR 3.7: RENAME USER renames the entries in history
CREATE USER to_be_renamed@localhost IDENTIFIED BY 'haha' PASSWORD HISTORY 1;
# must be 1: user created with password history
SELECT COUNT(*) FROM mysql.password_history WHERE
User='to_be_renamed' AND Host='localhost';
COUNT(*)
1
RENAME USER to_be_renamed@localhost TO now_renamed@localhost;
# must be 0: user renamed
SELECT COUNT(*) FROM mysql.password_history WHERE
User='to_be_renamed' AND Host='localhost';
COUNT(*)
0
# must be 1: this is what the user is renamed to
SELECT COUNT(*) FROM mysql.password_history WHERE
User='now_renamed' AND Host='localhost';
COUNT(*)
1
# must fail: password is in history
SET PASSWORD FOR now_renamed@localhost = 'haha';
ERROR HY000: Cannot use these credentials for 'now_renamed@localhost' because they contradict the password history policy
# FR3.8: changes to the history table take effect immediately
DELETE FROM mysql.password_history WHERE
User='now_renamed' AND Host='localhost';
# must pass: password history is empty
SET PASSWORD FOR now_renamed@localhost = 'haha';
# must be 1: history added back again
SELECT COUNT(*) FROM mysql.password_history WHERE
User='now_renamed' AND Host='localhost';
COUNT(*)
1
DROP USER now_renamed@localhost;
# FR3.9: when history table absent updates pass, reads read empty
CREATE USER no_pwd_history@localhost IDENTIFIED BY 'haha';
RENAME TABLE mysql.password_history TO mysql.password_history_backup;
# must fail: eventual write operation to history
CREATE USER no_pwd_history_err@localhost IDENTIFIED BY 'haha'
PASSWORD HISTORY 0 PASSWORD REUSE INTERVAL 0 DAY;
ERROR 42S02: Table 'mysql.password_history' doesn't exist
# Must fail: SET PASSWORD can write to history
SET PASSWORD FOR no_pwd_history@localhost = 'hehe';
ERROR 42S02: Table 'mysql.password_history' doesn't exist
# Must fail: ALTER USER IDENTIFIED BY can write to history
ALTER USER no_pwd_history@localhost IDENTIFIED BY 'hihi';
ERROR 42S02: Table 'mysql.password_history' doesn't exist
# Must fail: ALTER USER IDENTIFIED WITH can add to history
ALTER USER no_pwd_history@localhost IDENTIFIED WITH 'sha256_password';
ERROR 42S02: Table 'mysql.password_history' doesn't exist
# Must fail: DROP USER can write to history
DROP USER no_pwd_history@localhost;
ERROR 42S02: Table 'mysql.password_history' doesn't exist
RENAME TABLE mysql.password_history_backup TO mysql.password_history;
DROP USER no_pwd_history@localhost;
#FR4: new clauses can be specified more than once
# With duplicate PASSWORD HISTORY the last one takes precedence
CREATE USER dup_history@localhost IDENTIFIED BY 'haha'
PASSWORD HISTORY 1 PASSWORD HISTORY DEFAULT;
# must be 0: global is 0 and last option takes precendence
SELECT COUNT(*) FROM mysql.password_history WHERE
User='dup_history' AND Host='localhost';
COUNT(*)
0
DROP USER dup_history@localhost;
# With duplicate PASSWORD REUSE INTERVAL the last one takes precedence
CREATE USER dup_interval@localhost IDENTIFIED BY 'haha'
PASSWORD REUSE INTERVAL 10 DAY PASSWORD REUSE INTERVAL DEFAULT;
# must be 0: global is 0 and last option takes precendence
SELECT COUNT(*) FROM mysql.password_history WHERE
User='dup_interval' AND Host='localhost';
COUNT(*)
0
DROP USER dup_interval@localhost;
# FR7: Empty passwords are not verified nor stored in password history.
CREATE USER empty_pwd@localhost IDENTIFIED BY ''
PASSWORD HISTORY 1;
# must be 0: empty passwords not recorded after CREATE USER
SELECT COUNT(*) FROM mysql.password_history WHERE
User='empty_pwd' AND Host='localhost';
COUNT(*)
0
# Must pass: it's ok to set again an empty password
SET PASSWORD FOR empty_pwd@localhost = '';
# must be 0: empty passwords not recorded after SET PASSWORD
SELECT COUNT(*) FROM mysql.password_history WHERE
User='empty_pwd' AND Host='localhost';
COUNT(*)
0
DROP USER empty_pwd@localhost;
# FR2.1: A new global only system variable password_reuse_interval
SET SESSION password_reuse_interval= 0;
ERROR HY000: Variable 'password_reuse_interval' is a GLOBAL variable and should be set with SET GLOBAL
SET GLOBAL password_history=0;
SET GLOBAL password_reuse_interval=1;
CREATE USER def_interval@localhost IDENTIFIED BY 'haha';
# must be 1: password recorded due to interval in CREATE USER
SELECT COUNT(*) FROM mysql.password_history WHERE
User='def_interval' AND Host='localhost';
COUNT(*)
1
# Must fail: password reused too soon
SET PASSWORD FOR def_interval@localhost = 'haha';
ERROR HY000: Cannot use these credentials for 'def_interval@localhost' because they contradict the password history policy
# Rewind back the history record with 1 day
UPDATE mysql.password_history
SET Password_timestamp = TIMESTAMPADD(DAY, -1, Password_timestamp)
WHERE User='def_interval' AND Host='localhost';
# Must pass now: the password was used yesterday
SET PASSWORD FOR def_interval@localhost = 'haha';
# must be 1: password reused in SET PASSWORD today
SELECT COUNT(*) FROM mysql.password_history WHERE
User='def_interval' AND Host='localhost' AND
TO_DAYS(Password_timestamp)=TO_DAYS(NOW());
COUNT(*)
1
SET PASSWORD FOR def_interval@localhost = 'hihi';
# must be 2: a new password added in SET PASSWORD today
SELECT COUNT(*) FROM mysql.password_history WHERE
User='def_interval' AND Host='localhost' AND
TO_DAYS(Password_timestamp)=TO_DAYS(NOW());
COUNT(*)
2
# Rewind back the history records with 1 month
UPDATE mysql.password_history
SET Password_timestamp = TIMESTAMPADD(MONTH, -1, Password_timestamp)
WHERE User='def_interval' AND Host='localhost';
# Must pass: password in SET PASSWORD not used for a month
SET PASSWORD FOR def_interval@localhost = 'hoho';
# must be 1: old history records purged from history
SELECT COUNT(*) FROM mysql.password_history WHERE
User='def_interval' AND Host='localhost' AND
TO_DAYS(Password_timestamp)=TO_DAYS(NOW());
COUNT(*)
1
SET GLOBAL password_reuse_interval = default;
DROP USER def_interval@localhost;
#
# Bug #26364229: PASSWORD CHANGE FROM A USER SESSION
# DOES NOT PRESERVE THE PASSWORD_HISTORY VALUE
#
SET GLOBAL password_history=5;
SET GLOBAL password_reuse_interval=5;
CREATE USER mohit@localhost IDENTIFIED BY 'mohit'
PASSWORD HISTORY 1 PASSWORD REUSE INTERVAL 2 DAY;
# Must have PASSWORD HISTORY 1 and PASSWORD REUSE INTERVAL 2
SHOW CREATE USER mohit@localhost;
CREATE USER for mohit@localhost
CREATE USER `mohit`@`localhost` IDENTIFIED WITH 'caching_sha2_password' AS '<non-deterministic-password-hash>' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY 1 PASSWORD REUSE INTERVAL 2 DAY PASSWORD REQUIRE CURRENT DEFAULT
# Must fail: password history is 1
ALTER USER mohit@localhost IDENTIFIED BY 'mohit';
ERROR HY000: Cannot use these credentials for 'mohit@localhost' because they contradict the password history policy
# Must pass: new password
ALTER USER mohit@localhost IDENTIFIED BY 'mohit1';
# Must have PASSWORD HISTORY 1 and PASSWORD REUSE INTERVAL 2
SHOW CREATE USER mohit@localhost;
CREATE USER for mohit@localhost
CREATE USER `mohit`@`localhost` IDENTIFIED WITH 'caching_sha2_password' AS '<non-deterministic-password-hash>' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY 1 PASSWORD REUSE INTERVAL 2 DAY PASSWORD REQUIRE CURRENT DEFAULT
DROP USER mohit@localhost;
SET GLOBAL password_reuse_interval= default;
CREATE USER mohit@localhost IDENTIFIED BY 'mohit' PASSWORD HISTORY 1;
# Must have PASSWORD HISTORY 1
SHOW CREATE USER mohit@localhost;
CREATE USER for mohit@localhost
CREATE USER `mohit`@`localhost` IDENTIFIED WITH 'caching_sha2_password' AS '<non-deterministic-password-hash>' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY 1 PASSWORD REUSE INTERVAL DEFAULT PASSWORD REQUIRE CURRENT DEFAULT
# must be 1: password recorded due to interval in CREATE USER
SELECT COUNT(*) FROM mysql.password_history WHERE
User='mohit' AND Host='localhost';
COUNT(*)
1
# Must fail: password history is 1
ALTER USER mohit@localhost IDENTIFIED BY 'mohit';
ERROR HY000: Cannot use these credentials for 'mohit@localhost' because they contradict the password history policy
# Must pass: new password
ALTER USER mohit@localhost IDENTIFIED BY 'mohit1';
# must be 1: new password bumped the old one
SELECT COUNT(*) FROM mysql.password_history WHERE
User='mohit' AND Host='localhost';
COUNT(*)
1
# Must pass: password history set to 1
ALTER USER mohit@localhost IDENTIFIED BY 'mohit';
DROP USER mohit@localhost;
SET GLOBAL password_history= default;
SET GLOBAL password_reuse_interval= default;
#
# Bug #26410591: ASSERT FAIL IN COMPARE_NATIVE_PASSWORD_WITH_HASH
#
CREATE USER mohit@localhost
IDENTIFIED WITH sha256_password BY 'mohit' PASSWORD HISTORY 1;
# must be 1: SHA256 password recorded due to history
SELECT COUNT(*) FROM mysql.password_history WHERE
User='mohit' AND Host='localhost';
COUNT(*)
1
# Save the SH256 password for later
CREATE TABLE pwd_history_backup AS
SELECT * FROM mysql.password_history
WHERE User='mohit' AND Host='localhost';
# Must not crash
ALTER USER mohit@localhost IDENTIFIED WITH mysql_native_password BY 'mohit';
# Must be 1: the native password
SELECT COUNT(*) FROM mysql.password_history WHERE
User='mohit' AND Host='localhost';
COUNT(*)
1
# Restore the SHA256 password (invalid hash) into the history table
UPDATE mysql.password_history
SET Password=(
SELECT Password FROM pwd_history_backup
WHERE User='mohit' AND Host='localhost')
WHERE User='mohit' AND Host='localhost';
# Must not crash
ALTER USER mohit@localhost IDENTIFIED WITH mysql_native_password BY 'mohit';
DROP TABLE pwd_history_backup;
DROP USER mohit@localhost;
#
# Bug #26410846: PASSWORD ROTATION POLICY IS NOT WORKING FOR SHA256
# AUTHENTICATED USERS
#
CREATE USER mohit_sha@localhost IDENTIFIED WITH sha256_password BY 'mohit_sha'
PASSWORD HISTORY 1;
# Must fail: same password
ALTER USER mohit_sha@localhost IDENTIFIED BY 'mohit_sha';
ERROR HY000: Cannot use these credentials for 'mohit_sha@localhost' because they contradict the password history policy
# Must pass: different password
ALTER USER mohit_sha@localhost IDENTIFIED BY 'mohit_sha2';
DROP USER mohit_sha@localhost;
#
# Altering a user with PASSWORD REUSE INTERVAL
#
SET GLOBAL password_history=0;
SET GLOBAL password_reuse_interval= 1;
CREATE USER amar@localhost IDENTIFIED BY 'amar'
PASSWORD REUSE INTERVAL 1 DAY;
# Must be 1: due to INTERVAL 1 day
SELECT COUNT(*) FROM mysql.password_history WHERE
User='amar' AND Host='localhost';
COUNT(*)
1
# Must fail: duplicate password
ALTER USER amar@localhost IDENTIFIED BY 'amar';
ERROR HY000: Cannot use these credentials for 'amar@localhost' because they contradict the password history policy
# Must still be 1: due to INTERVAL 1 day again
SELECT COUNT(*) FROM mysql.password_history WHERE
User='amar' AND Host='localhost';
COUNT(*)
1
DROP USER amar@localhost;
SET GLOBAL password_history=default;
SET GLOBAL password_reuse_interval=default;
#
# Tests for caching_sha2_password plugin
#
CREATE USER mohit_sha@localhost IDENTIFIED WITH caching_sha2_password BY 'mohit_sha'
PASSWORD HISTORY 1;
# Must fail: same password
ALTER USER mohit_sha@localhost IDENTIFIED BY 'mohit_sha';
ERROR HY000: Cannot use these credentials for 'mohit_sha@localhost' because they contradict the password history policy
# Must pass: different password
ALTER USER mohit_sha@localhost IDENTIFIED BY 'mohit_sha2';
ALTER USER mohit_sha@localhost PASSWORD HISTORY 2;
# Must pass: We do not record for the password
ALTER USER mohit_sha@localhost IDENTIFIED BY 'mohit_sha';
# Must fail: passwords present in history table
ALTER USER mohit_sha@localhost IDENTIFIED BY 'mohit_sha';
ERROR HY000: Cannot use these credentials for 'mohit_sha@localhost' because they contradict the password history policy
ALTER USER mohit_sha@localhost IDENTIFIED BY 'mohit_sha2';
ERROR HY000: Cannot use these credentials for 'mohit_sha@localhost' because they contradict the password history policy
# Must pass: different password
ALTER USER mohit_sha@localhost IDENTIFIED BY 'mohit_sha3';
DROP USER mohit_sha@localhost;
#
# Bug #34918740: mysqld_multi mishandling password_history
# and password_require_current settings
#
--password-history=5
--password_require_current=ON
--password=*****
# ------------------------------------------------------------------
# -- End of 8.0 tests
# ------------------------------------------------------------------
|