# # This test is to check various cases of account lock functionality # # This test makes no sense with the embedded server --source include/not_embedded.inc # Save the initial number of concurrent sessions --source include/count_sessions.inc connection default; CREATE USER unlocked_user@localhost IDENTIFIED BY 'pas'; SELECT account_locked FROM mysql.user WHERE user='unlocked_user' and host = 'localhost'; --connect(unlocked_user_con, localhost, unlocked_user, pas) SELECT CURRENT_USER(); connection default; --echo # lock the user in the database UPDATE mysql.user SET account_locked='Y' WHERE user='unlocked_user' and host = 'localhost'; --echo # without FLUSH the field has no effect disconnect unlocked_user_con; --connect(unlocked_user_con, localhost, unlocked_user, pas) --echo # must not throw an error SELECT CURRENT_USER(); connection default; FLUSH PRIVILEGES; --echo # existing connections continue as before even after flush connection unlocked_user_con; --echo # must not throw an error SELECT CURRENT_USER(); disconnect unlocked_user_con; --echo # Lowercase 'y' should disable login as well connection default; UPDATE mysql.user SET account_locked='y' WHERE user='unlocked_user' and host = 'localhost'; FLUSH PRIVILEGES; --replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT --error ER_ACCOUNT_HAS_BEEN_LOCKED --connect(unlocked_user_con, localhost, unlocked_user, pas) --echo # new connections are blocked connection default; --replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT --error ER_ACCOUNT_HAS_BEEN_LOCKED --connect(unlocked_user_con, localhost, unlocked_user, pas) --echo # unlock the user using ALTER USER command ALTER USER unlocked_user@localhost ACCOUNT UNLOCK; SELECT account_locked FROM mysql.user WHERE user = 'unlocked_user' and host = 'localhost'; --echo # connection should work now connect(unlocked_user_con, localhost, unlocked_user, pas); SELECT CURRENT_USER(); disconnect unlocked_user_con; --echo # lock the user account using ALTER USER command connection default; ALTER USER unlocked_user@localhost ACCOUNT LOCK; SELECT account_locked FROM mysql.user WHERE user = 'unlocked_user' and host = 'localhost'; --echo # connection should not work --replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT --error ER_ACCOUNT_HAS_BEEN_LOCKED connect(unlocked_user_con, localhost, unlocked_user, pas); --echo # create another user connection default; CREATE USER unlocked_user2@localhost IDENTIFIED BY 'pas'; --echo # newly created user should be able to log in connect(unlocked_user_con, localhost, unlocked_user2, pas); SELECT CURRENT_USER(); disconnect unlocked_user_con; --echo # toogle access permission with one SQL statement connection default; ALTER USER unlocked_user@localhost, unlocked_user2@localhost ACCOUNT UNLOCK; SELECT user, account_locked FROM mysql.user WHERE (user = 'unlocked_user' and host = 'localhost') or (user = 'unlocked_user2' and host = 'localhost') ORDER BY user; --echo # unlocked_user2 should be able to log in connect(unlocked_user_con, localhost, unlocked_user2, pas); SELECT CURRENT_USER(); disconnect unlocked_user_con; --echo # unlocked_user should be able to log in connect(unlocked_user_con, localhost, unlocked_user, pas); SELECT CURRENT_USER(); disconnect unlocked_user_con; --echo # Basic SHOW CREATE USER connection default; -- echo # Should appear without ACCOUNT UNLOCK SHOW CREATE USER unlocked_user@localhost; ALTER USER unlocked_user@localhost ACCOUNT LOCK; --echo # Should appear with ACCOUNT LOCK SHOW CREATE USER unlocked_user@localhost; --echo # roll back changes connection default; DROP USER unlocked_user@localhost; DROP USER unlocked_user2@localhost; --echo # Create anonymous user connection default; CREATE USER ''@localhost IDENTIFIED BY 'pass'; connect(anonymous_user_con, localhost, '', pass); SELECT CURRENT_USER(); disconnect anonymous_user_con; connection default; DROP USER ''@localhost; --echo # Create anonymous user - explicit UNLOCK connection default; CREATE USER ''@localhost IDENTIFIED BY 'pass' ACCOUNT UNLOCK; connect(anonymous_user_con, localhost, '', pass); SELECT CURRENT_USER(); disconnect anonymous_user_con; connection default; DROP USER ''@localhost; --echo # Create anonymous user - LOCK connection default; CREATE USER ''@localhost IDENTIFIED BY 'pass' ACCOUNT LOCK; --replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT --error ER_ACCOUNT_HAS_BEEN_LOCKED connect(anonymous_user_con, localhost, '', pass); connection default; DROP USER ''@localhost; --echo # Disabling anonymous user connection default; CREATE USER ''@localhost IDENTIFIED BY 'pass'; ALTER USER ''@localhost ACCOUNT LOCK; --replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT --error ER_ACCOUNT_HAS_BEEN_LOCKED connect(anonymous_user_con, localhost, '', pass); connection default; DROP USER ''@localhost; --echo # Enabling anonymous user connection default; CREATE USER ''@localhost IDENTIFIED BY 'pass' ACCOUNT LOCK; ALTER USER ''@localhost ACCOUNT UNLOCK; connect(anonymous_user_con, localhost, '', pass); SELECT CURRENT_USER(); disconnect anonymous_user_con; connection default; DROP USER ''@localhost; --echo # Expiring password and disabing anynymous user connection default; CREATE USER ''@localhost IDENTIFIED BY 'pass'; --replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT --error ER_PASSWORD_EXPIRE_ANONYMOUS_USER ALTER USER ''@localhost PASSWORD EXPIRE ACCOUNT LOCK; DROP USER ''@localhost; --echo # Login as anonymous user and try to manipulate mysql.user table --echo # and users. connection default; CREATE user ''@localhost IDENTIFIED BY 'pass'; CREATE USER 'unlocked_user'@localhost IDENTIFIED BY 'pass'; connect(anonymous_user_con, localhost, '', pass); --error ER_TABLEACCESS_DENIED_ERROR UPDATE mysql.user SET account_locked='Y' WHERE user='unlocked_user' and host = 'localhost'; connect(unlocked_user_con, localhost, unlocked_user, pass); disconnect unlocked_user_con; connection anonymous_user_con; --error ER_SPECIFIC_ACCESS_DENIED_ERROR ALTER USER unlocked_user@localhost ACCOUNT LOCK; connect(unlocked_user_con, localhost, unlocked_user, pass); disconnect unlocked_user_con; disconnect anonymous_user_con; # Perform cleanup connection default; DROP USER unlocked_user@localhost; DROP USER ''@localhost; --echo # Create stored procedure and users for test connection default; CREATE USER u1@localhost IDENTIFIED BY 'pass'; CREATE USER u2@localhost IDENTIFIED BY 'pass'; GRANT ALL ON *.* TO u1@localhost; DELIMITER |; CREATE TABLE mysql.t1(counter INT)| INSERT INTO mysql.t1 VALUES(0)| CREATE DEFINER = u1@localhost PROCEDURE mysql.p1() BEGIN UPDATE mysql.t1 SET counter = counter + 1; SELECT counter FROM mysql.t1; END| DELIMITER ;| CALL mysql.p1(); GRANT EXECUTE ON PROCEDURE mysql.p1 TO u2@localhost; ALTER USER u1@localhost ACCOUNT LOCK; --echo # Login for u1@localhost should fail --replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT --error ER_ACCOUNT_HAS_BEEN_LOCKED connect(u1_con,localhost,u1,pass); --echo # Login as u2 and run stored procedure as u1 connect(u2_con,localhost,u2,pass); SELECT CURRENT_USER(); CALL mysql.p1(); disconnect u2_con; --echo # Locked_connects STATUS VARIABLE connection default; FLUSH STATUS; CREATE USER 'u3'@'localhost' IDENTIFIED BY 'pass' ACCOUNT LOCK; SHOW STATUS LIKE 'Locked_connects'; let $1 = 10; disable_query_log; while ($1) { --replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT --error ER_ACCOUNT_HAS_BEEN_LOCKED connect(unlocked_user_con, localhost, u3, pass); connection default; ALTER USER u3@localhost ACCOUNT UNLOCK; connect(unlocked_user_con, localhost, u3, pass); disconnect unlocked_user_con; connection default; ALTER USER u3@localhost ACCOUNT LOCK; dec $1; } enable_query_log; connection default; SHOW STATUS LIKE 'Locked_connects'; FLUSH STATUS; --echo # Invalid SQL syntax should fail connection default; --error ER_PARSE_ERROR CREATE USER u1@localhost REQUIRE NONE ACCOUNT LOCK WITH MAX_QUERIES_PER_HOUR 100; --echo # CREATE USER SQL syntax check DROP USER u1@localhost; CREATE USER u1@localhost REQUIRE NONE WITH MAX_QUERIES_PER_HOUR 100 ACCOUNT LOCK; SHOW CREATE USER u1@localhost; --echo # ALTER USER correct SQL syntax 1 ALTER USER u1@localhost PASSWORD EXPIRE ACCOUNT UNLOCK; SHOW CREATE USER u1@localhost; --echo # ALTER USER correct SQL syntax 2 ALTER USER u1@localhost ACCOUNT LOCK PASSWORD EXPIRE; SHOW CREATE USER u1@localhost; --echo # ALTER USER correct SQL syntax 3 ALTER USER u1@localhost REQUIRE NONE WITH MAX_QUERIES_PER_HOUR 99 ACCOUNT UNLOCK PASSWORD EXPIRE NEVER; SHOW CREATE USER u1@localhost; --echo # ALTER USER correct SQL syntax 4 ALTER USER u1@localhost REQUIRE NONE WITH MAX_QUERIES_PER_HOUR 98 PASSWORD EXPIRE INTERVAL 5 DAY ACCOUNT LOCK; SHOW CREATE USER u1@localhost; --echo # ALTER USER invalid SQL syntax --error ER_PARSE_ERROR ALTER USER u1@localhost ACCOUNT UNLOCK WITH MAX_QUERIES_PER_HOUR 97 PASSWORD EXPIRE; DROP USER u1@localhost; --echo # Duplicated ACCOUNT statement 1 CREATE USER u1@localhost IDENTIFIED BY 'PASS' ACCOUNT LOCK ACCOUNT UNLOCK; SHOW CREATE USER u1@localhost; DROP USER u1@localhost; --echo # Duplicated ACCOUNT statement 2 CREATE USER u1@localhost ACCOUNT UNLOCK ACCOUNT LOCK; SHOW CREATE USER u1@localhost; DROP USER u1@localhost; --echo # Duplicated ACCOUNT statement 3 CREATE USER u1@localhost ACCOUNT LOCK PASSWORD EXPIRE ACCOUNT LOCK; SHOW CREATE USER u1@localhost; --echo # Duplicated ACCOUNT statement 4 ALTER USER u1@localhost IDENTIFIED BY 'PASS' ACCOUNT LOCK ACCOUNT UNLOCK; SHOW CREATE USER u1@localhost; --echo # Duplicated ACCOUNT statement 5 ALTER USER u1@localhost ACCOUNT UNLOCK ACCOUNT LOCK; SHOW CREATE USER u1@localhost; --echo # Duplicated ACCOUNT statement 6 ALTER USER u1@localhost ACCOUNT LOCK PASSWORD EXPIRE ACCOUNT LOCK; SHOW CREATE USER u1@localhost; --echo # Duplicated ACCOUNT statement 7 ALTER USER u1@localhost PASSWORD EXPIRE ACCOUNT LOCK PASSWORD EXPIRE NEVER; SHOW CREATE USER u1@localhost; --echo # Duplicated ACCOUNT statement 8 ALTER USER u1@localhost PASSWORD EXPIRE NEVER ACCOUNT LOCK PASSWORD EXPIRE INTERVAL 5 DAY ACCOUNT LOCK; SHOW CREATE USER u1@localhost; --echo # MySQL user table layout from the before ACCOUNT LOCK option call mtr.add_suppression("Column count of mysql.* is wrong. " "Expected .*, found .*. " "The table is probably corrupted"); connection default; CREATE TABLE temp_user LIKE mysql.user; INSERT INTO temp_user SELECT * FROM mysql.user; ALTER TABLE mysql.user DROP COLUMN account_locked; --error ER_COL_COUNT_DOESNT_MATCH_CORRUPTED_V2 CREATE USER backuser@localhost IDENTIFIED BY 'pass' ACCOUNT LOCK; SELECT COUNT(*) FROM mysql.user WHERE (user = 'backuser' and host = 'localhost'); --error ER_COL_COUNT_DOESNT_MATCH_CORRUPTED_V2 CREATE USER backuser@localhost IDENTIFIED BY 'pass' ACCOUNT UNLOCK; SELECT COUNT(*) FROM mysql.user WHERE (user = 'backuser' and host = 'localhost'); --error ER_COL_COUNT_DOESNT_MATCH_CORRUPTED_V2 CREATE USER backuser@localhost IDENTIFIED BY 'pass'; SELECT COUNT(*) FROM mysql.user WHERE (user = 'backuser' and host = 'localhost'); --error ER_BAD_FIELD_ERROR SELECT user, account_locked FROM mysql.user WHERE (user = 'backuser' and host = 'localhost'); connection default; --error ER_COL_COUNT_DOESNT_MATCH_CORRUPTED_V2 ALTER USER backuser@localhost ACCOUNT LOCK; --error ER_COL_COUNT_DOESNT_MATCH_CORRUPTED_V2 ALTER USER backuser@localhost ACCOUNT UNLOCK; --error ER_COL_COUNT_DOESNT_MATCH_CORRUPTED_V2 DROP USER backuser@localhost; DROP TABLE mysql.user; ALTER TABLE temp_user RENAME mysql.user; FLUSH PRIVILEGES; --echo # Check whether 'account' can be used as the identifier. connection default; CREATE DATABASE account; CREATE TABLE account.`account` (account text(20)); INSERT INTO `account`.account VALUES("account"); SELECT account FROM account.account WHERE account = 'account'; SET @account = "account_before"; delimiter |; CREATE PROCEDURE account.account(OUT ac CHAR(20)) BEGIN SELECT account.`account`.account INTO ac FROM account.account; END| delimiter ;| CALL account.account(@account); SELECT @account; DROP DATABASE account; CREATE USER ACCOUNT@localhost ACCOUNT LOCK; DROP USER ACCOUNT@localhost; # Perform cleanup connection default; DROP PROCEDURE mysql.p1; DROP TABLE mysql.t1; DROP USER u1@localhost; DROP USER u2@localhost; DROP USER u3@localhost; --echo # --echo # Bug #20814051 CREATE USER BINLOG EVENTS INCLUDE NEW ACCOUNT KEYWORD --echo # --echo # test general log with log_builtin_as_identified_by_password ON SHOW GLOBAL VARIABLES LIKE 'log_builtin_as_identified_by_password'; --echo # SHOW CREATE USER should always show ACCOUNT LOCK clause SET GLOBAL log_builtin_as_identified_by_password = ON; CREATE USER u1 IDENTIFIED BY 'pass'; SHOW CREATE USER u1; ALTER USER u1 ACCOUNT LOCK; SHOW CREATE USER u1; DROP USER u1; --echo # restarting the server with log_builtin_as_identified_by_password ON # Write file to make mysql-test-run.pl wait for the server to stop --exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect # Request shutdown -- send_shutdown # Call script that will poll the server waiting for it to disapear -- source include/wait_until_disconnected.inc --echo # Restart server. --exec echo "restart:--log-builtin-as-identified-by-password=ON" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect # Turn on reconnect --enable_reconnect # Call script that will poll the server waiting for it to be back online again --source include/wait_until_connected_again.inc SHOW GLOBAL VARIABLES LIKE 'log_builtin_as_identified_by_password'; # make sure we start with a clean slate. log_tables.test says this is OK. TRUNCATE TABLE mysql.general_log; --echo --------------- general log --------------------------------------- SET @old_log_output= @@global.log_output; SET @old_general_log= @@global.general_log; SET @old_general_log_file= @@global.general_log_file; --replace_result $MYSQLTEST_VARDIR ... eval SET GLOBAL general_log_file = '$MYSQLTEST_VARDIR/log/rewrite_general.log'; SET GLOBAL log_output = 'FILE,TABLE'; SET GLOBAL general_log= 'ON'; CREATE USER u1 IDENTIFIED BY 'pass'; CREATE USER u2 IDENTIFIED BY 'pass' ACCOUNT LOCK; CREATE USER u3 IDENTIFIED BY 'pass' ACCOUNT UNLOCK; ALTER USER u1 IDENTIFIED BY 'pass'; ALTER USER u1 IDENTIFIED BY 'pass' ACCOUNT LOCK; ALTER USER u1 IDENTIFIED BY 'pass' ACCOUNT UNLOCK; --echo # --echo # BUG #20996273 ALTER USER REWRITE CAUSES DIFFERENCES ON SLAVE --echo # ALTER USER u2 IDENTIFIED BY 'pass'; CREATE TABLE test_log (argument TEXT); --replace_result $MYSQLTEST_VARDIR ... eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/log/rewrite_general.log' INTO TABLE test_log FIELDS TERMINATED BY '\n' LINES TERMINATED BY '\n'; --echo Show what is logged: --echo ------ rewrite ------ SELECT argument FROM mysql.general_log WHERE argument LIKE 'CREATE USER %'; SELECT argument FROM mysql.general_log WHERE argument LIKE 'ALTER USER %'; --echo ------ done ------ # cleanup DROP USER u1, u2, u3; --remove_file $MYSQLTEST_VARDIR/log/rewrite_general.log SET GLOBAL general_log_file= @old_general_log_file; SET GLOBAL general_log= @old_general_log; SET GLOBAL log_output= @old_log_output; # Wait till all disconnects are completed --source include/wait_until_count_sessions.inc