--source include/not_embedded.inc --source include/have_validate_password_plugin.inc call mtr.add_suppression("Dictionary file not specified"); let $MYSQL_ERRMSG_BASEDIR=`select @@lc_messages_dir`; # plugin is not installed so even 'pass' (very weak) # is accepted as a password CREATE USER 'base_user'@'localhost' IDENTIFIED BY 'pass'; GRANT ALL ON mysql.* TO 'user1'@'localhost' IDENTIFIED BY 'pass'; --replace_regex /\.dll/.so/ eval INSTALL PLUGIN validate_password SONAME '$VALIDATE_PASSWORD'; # test for all the three password policy # policy: LOW, MEDIUM, STRONG --echo # password policy LOW (which only check for password length) --echo # default case: password length should be minimum 8 SET @@global.validate_password_policy=LOW; --error ER_NOT_VALID_PASSWORD CREATE USER 'user'@'localhost' IDENTIFIED BY ''; --error ER_NOT_VALID_PASSWORD SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('aweg'); SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password3'); SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password'); --error ER_NOT_VALID_PASSWORD SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('passwor'); SET @@global.validate_password_length= 12; --error ER_NOT_VALID_PASSWORD UPDATE mysql.user SET PASSWORD= PASSWORD('password') WHERE user='base_user'; --error ER_NOT_VALID_PASSWORD UPDATE mysql.user SET PASSWORD= PASSWORD('afrgtyhlp98') WHERE user='base_user'; UPDATE mysql.user SET PASSWORD= PASSWORD('iuyt567nbvfA') WHERE user='base_user'; GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1234'; SET @@global.validate_password_mixed_case_count= 0; SET @@global.validate_password_number_count= 0; SET @@global.validate_password_special_char_count= 0; SET @@global.validate_password_length= 0; UPDATE mysql.user SET PASSWORD= PASSWORD('') WHERE user='base_user'; UPDATE mysql.user SET PASSWORD= PASSWORD('p') WHERE user='base_user'; UPDATE mysql.user SET PASSWORD= PASSWORD('password') WHERE user='base_user'; SET @@global.validate_password_length= -2; -- Error ER_WRONG_TYPE_FOR_VAR SET @@global.validate_password_length= 3.5; # test to check maximum value of password_length SET @@global.validate_password_length= 2147483647; SET @@global.validate_password_length= 2147483648; PREPARE stmt1 FROM 'UPDATE mysql.user SET PASSWORD=(?) where USER = ?'; SET @a = REPEAT('a',2147483647); SET @b = 'user@localhost'; EXECUTE stmt1 USING @a,@b; DEALLOCATE PREPARE stmt1; SET @@global.validate_password_length= 4294967295; SET @@global.validate_password_length= 8; PREPARE stmt1 FROM 'UPDATE mysql.user SET PASSWORD=(?) where USER = ?'; SET @a = REPEAT('a',1048576); SET @b = 'user@localhost'; EXECUTE stmt1 USING @a,@b; DEALLOCATE PREPARE stmt1; --echo # password policy MEDIUM (check for mixed_case, digits, special_chars) --echo # default case : atleast 1 mixed_case, 1 digit, 1 special_char SET @@global.validate_password_mixed_case_count= 1; SET @@global.validate_password_number_count= 1; SET @@global.validate_password_special_char_count= 1; SET @@global.validate_password_policy=MEDIUM; SET @@global.validate_password_number_count= 0; CREATE USER 'user'@'localhost' IDENTIFIED BY 'aedfoiASE$%'; --error ER_NOT_VALID_PASSWORD SET PASSWORD FOR 'user'@'localhost'= PASSWORD('foiuiuytd78'); SET PASSWORD FOR 'user'@'localhost'= PASSWORD('pasretryFRGH&^98'); SET @@global.validate_password_mixed_case_count= 0; --error ER_NOT_VALID_PASSWORD CREATE USER 'user'@'localhost' IDENTIFIED BY 'aedSWEhjui'; SET PASSWORD FOR 'user'@'localhost'= PASSWORD('gruyuHOIU&*('); SET PASSWORD FOR 'user'@'localhost'= PASSWORD('passwor0987**&'); SET @@global.validate_password_special_char_count= 0; SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('piufgklol'); SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A#'); SET @@global.validate_password_special_char_count= 1; SET @@global.validate_password_number_count= 1; SET @@global.validate_password_mixed_case_count= 1; --error ER_NOT_VALID_PASSWORD SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('erftuiik'); SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A#'); SET @@global.validate_password_number_count= 2; --error ER_NOT_VALID_PASSWORD UPDATE mysql.user SET PASSWORD= PASSWORD('password1A#') WHERE user='base_user'; UPDATE mysql.user SET PASSWORD= PASSWORD('password12A#') WHERE user='base_user'; SET @@global.validate_password_number_count= 1; SET @@global.validate_password_mixed_case_count= 2; --error ER_NOT_VALID_PASSWORD UPDATE mysql.user SET PASSWORD= PASSWORD('password1A#') WHERE user='base_user'; UPDATE mysql.user SET PASSWORD= PASSWORD('password1AB#') WHERE user='base_user'; SET @@global.validate_password_mixed_case_count= 1; SET @@global.validate_password_special_char_count= 2; --error ER_NOT_VALID_PASSWORD GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1A#'; GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1A#$'; SET @@global.validate_password_special_char_count= 1; --echo # No dictionary file present, no dictionary check SET @@global.validate_password_policy=STRONG; SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A#'); UPDATE mysql.user SET PASSWORD= PASSWORD('password1A#') WHERE user='base_user'; --replace_result $MYSQL_ERRMSG_BASEDIR MYSQL_ERRMSG_BASEDIR eval SET @@global.validate_password_dictionary_file="$MYSQL_ERRMSG_BASEDIR/dictionary.txt"; --echo # password policy strong --echo # default_file : dictionary.txt # file should contain 1 word per line # error if substring of password is a dictionary word SET @@global.validate_password_policy=STRONG; --error ER_NOT_VALID_PASSWORD CREATE USER 'user'@'localhost' IDENTIFIED BY 'password'; --error ER_NOT_VALID_PASSWORD SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A#'); --error ER_NOT_VALID_PASSWORD UPDATE mysql.user SET PASSWORD= PASSWORD('pass12345A#') WHERE user='base_user'; --error ER_NOT_VALID_PASSWORD UPDATE mysql.user SET PASSWORD= PASSWORD('pass0000A#') WHERE user='base_user'; GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'PA00wrd!#'; --echo # test for password_validate_strength function --error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT SELECT VALIDATE_PASSWORD_STRENGTH('password', 0); --error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT SELECT VALIDATE_PASSWORD_STRENGTH(); SELECT VALIDATE_PASSWORD_STRENGTH(''); SELECT VALIDATE_PASSWORD_STRENGTH('pass'); SELECT VALIDATE_PASSWORD_STRENGTH('password'); SELECT VALIDATE_PASSWORD_STRENGTH('password0000'); SELECT VALIDATE_PASSWORD_STRENGTH('password1A#'); SELECT VALIDATE_PASSWORD_STRENGTH('PA12wrd!#'); SELECT VALIDATE_PASSWORD_STRENGTH('PA00wrd!#'); # Test for multibyte character set that have greater size when converted # from uppercase to lowercase. SET NAMES 'ujis'; SELECT VALIDATE_PASSWORD_STRENGTH('PA12wrd!#'); # default policy is set, all other plugin variables set to default # Test to ensure that only the privileged user can access the plugin variables SET @@global.validate_password_policy=MEDIUM; # New connection connect (plug_con,localhost,user1,pass); --error ER_SPECIFIC_ACCESS_DENIED_ERROR SET @@global.validate_password_policy=LOW; --error ER_SPECIFIC_ACCESS_DENIED_ERROR SET @@global.validate_password_length= 4; --error ER_SPECIFIC_ACCESS_DENIED_ERROR SET @@global.validate_password_special_char_count= 0; --error ER_SPECIFIC_ACCESS_DENIED_ERROR SET @@global.validate_password_mixed_case_count= 0; # user has the update/create privilege but needs to satisfy password policy # to update/create new account --error ER_NOT_VALID_PASSWORD CREATE USER 'user2'@'localhost' IDENTIFIED BY 'password'; CREATE USER 'user2'@'localhost' IDENTIFIED BY 'PA00wrd!#'; --error ER_NOT_VALID_PASSWORD UPDATE mysql.user SET PASSWORD= PASSWORD('password') WHERE user='user2'; UPDATE mysql.user SET PASSWORD= PASSWORD('PA00wrd!#') WHERE user='user2'; DROP USER 'user2'@'localhost'; disconnect plug_con; --source include/wait_until_disconnected.inc connection default; DROP USER 'base_user'@'localhost'; DROP USER 'user1'@'localhost'; DROP USER 'user'@'localhost'; SET @@global.validate_password_length=default; SET @@global.validate_password_number_count=default; SET @@global.validate_password_mixed_case_count=default; SET @@global.validate_password_special_char_count=default; SET @@global.validate_password_policy=default; SET @@global.validate_password_dictionary_file=default; SELECT @@validate_password_length, @@validate_password_number_count, @@validate_password_mixed_case_count, @@validate_password_special_char_count, @@validate_password_policy, @@validate_password_dictionary_file; --echo # --echo # Bug#14588145 - NEED ABILITY TO FLUSH PASSWORD VALIDATION DICTIONARY FILE --echo # SET @@global.validate_password_policy=STRONG; --write_file $MYSQLTEST_VARDIR/tmp/dictionary.txt password validate EOF --write_file $MYSQLTEST_VARDIR/tmp/dictionary2.txt password validate monkey EOF --echo # No dictionary file, password is accepted CREATE USER 'user1'@'localhost' IDENTIFIED BY 'passWORD123#'; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR eval SET @@global.validate_password_dictionary_file="$MYSQLTEST_VARDIR/tmp/dictionary2.txt"; # Dictionary file loaded --echo # must return 3 SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'validate_password_dictionary_file_words_count'; SELECT VARIABLE_VALUE into @ts1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = "validate_password_dictionary_file_last_parsed"; --echo # check format of the TS --replace_regex /[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]/0000-00-00 00:00:00/ SELECT @ts1; --echo # must return 19 SELECT LENGTH(@ts1); --echo # must sleep for at least 1 sec so that the timestamps differ --sleep 1 --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR eval SET @@global.validate_password_dictionary_file="$MYSQLTEST_VARDIR/tmp/dictionary.txt"; --echo # must return 2 SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'validate_password_dictionary_file_words_count'; SELECT VARIABLE_VALUE into @ts2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = "validate_password_dictionary_file_last_parsed"; --echo # must return 1 SELECT @ts1 <> @ts2; --error ER_NOT_VALID_PASSWORD CREATE USER 'user2'@'localhost' IDENTIFIED BY 'passWORD123#'; SET @@global.validate_password_dictionary_file=NULL; --echo # Cache flushed and no dictionary file is loaded CREATE USER 'user2'@'localhost' IDENTIFIED BY 'passWORD123#'; --echo # Select commands to show that the validate_password lock is instrumented SELECT NAME FROM performance_schema.setup_instruments WHERE NAME LIKE '%validate%'; SELECT NAME FROM performance_schema.rwlock_instances WHERE NAME LIKE '%validate%'; --echo # cleanup DROP USER 'user1'@'localhost', 'user2'@'localhost'; SET @@global.validate_password_policy=DEFAULT; remove_file $MYSQLTEST_VARDIR/tmp/dictionary.txt; remove_file $MYSQLTEST_VARDIR/tmp/dictionary2.txt; --echo # --echo # Bug#21616496: CREATE USER ACCEPTS PLUGIN AND PASSWORD HASH, --echo # BUT IGNORES THE PASSWORD HASH --echo # --error ER_NOT_VALID_PASSWORD CREATE USER 'user1'@'localhost' IDENTIFIED WITH 'mysql_native_password'; --error ER_NOT_VALID_PASSWORD CREATE USER 'user1'@'localhost' IDENTIFIED WITH 'mysql_old_password'; --error ER_NOT_VALID_PASSWORD CREATE USER 'user1'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*0D3CED9BEC10A777AEC23CCC353A8C08A633045E'; --error ER_NOT_VALID_PASSWORD CREATE USER 'user1'@'localhost' IDENTIFIED WITH 'mysql_old_password' AS '*0D3CED9BEC10A777AEC23CCC353A8C08A633045E'; --echo # clean up after the test UNINSTALL PLUGIN validate_password; --echo End of tests