Skip to content

Commit

Permalink
MDEV-32218 PASSWORD_EXPIRATION_TIME column
Browse files Browse the repository at this point in the history
* show it as a datetime, not number of seconds
* show all users
* show manually expired users as 0000-00-00 00:00:00
* show default expiration interval correctly
* numerous test fixes, add more tests
* fix compilation of embedded
  • Loading branch information
vuvova authored and FooBarrior committed May 27, 2024
1 parent d229b4a commit 173edf6
Show file tree
Hide file tree
Showing 12 changed files with 384 additions and 179 deletions.
2 changes: 2 additions & 0 deletions mysql-test/main/information_schema-big.result
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ TABLE_CONSTRAINTS CONSTRAINT_SCHEMA
TABLE_PRIVILEGES TABLE_SCHEMA
TABLE_STATISTICS TABLE_SCHEMA
TRIGGERS TRIGGER_SCHEMA
USERS USER
USER_PRIVILEGES GRANTEE
USER_STATISTICS USER
VIEWS TABLE_SCHEMA
Expand Down Expand Up @@ -126,6 +127,7 @@ TABLE_CONSTRAINTS CONSTRAINT_SCHEMA
TABLE_PRIVILEGES TABLE_SCHEMA
TABLE_STATISTICS TABLE_SCHEMA
TRIGGERS TRIGGER_SCHEMA
USERS USER
USER_PRIVILEGES GRANTEE
USER_STATISTICS USER
VIEWS TABLE_SCHEMA
2 changes: 2 additions & 0 deletions mysql-test/main/information_schema.result
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ TABLE_CONSTRAINTS
TABLE_PRIVILEGES
TABLE_STATISTICS
TRIGGERS
USERS
USER_PRIVILEGES
USER_STATISTICS
VIEWS
Expand Down Expand Up @@ -963,6 +964,7 @@ TABLES CREATE_TIME datetime
TABLES UPDATE_TIME datetime
TABLES CHECK_TIME datetime
TRIGGERS CREATED datetime
USERS PASSWORD_EXPIRATION_TIME datetime
event execute_at datetime
event last_executed datetime
event starts datetime
Expand Down
8 changes: 7 additions & 1 deletion mysql-test/main/information_schema_all_engines.result
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ TABLE_CONSTRAINTS
TABLE_PRIVILEGES
TABLE_STATISTICS
TRIGGERS
USERS
USER_PRIVILEGES
USER_STATISTICS
VIEWS
Expand Down Expand Up @@ -153,6 +154,7 @@ TABLE_CONSTRAINTS CONSTRAINT_SCHEMA
TABLE_PRIVILEGES TABLE_SCHEMA
TABLE_STATISTICS TABLE_SCHEMA
TRIGGERS TRIGGER_SCHEMA
USERS USER
USER_PRIVILEGES GRANTEE
USER_STATISTICS USER
VIEWS TABLE_SCHEMA
Expand Down Expand Up @@ -238,6 +240,7 @@ TABLE_CONSTRAINTS CONSTRAINT_SCHEMA
TABLE_PRIVILEGES TABLE_SCHEMA
TABLE_STATISTICS TABLE_SCHEMA
TRIGGERS TRIGGER_SCHEMA
USERS USER
USER_PRIVILEGES GRANTEE
USER_STATISTICS USER
VIEWS TABLE_SCHEMA
Expand Down Expand Up @@ -326,6 +329,7 @@ TABLE_CONSTRAINTS information_schema.TABLE_CONSTRAINTS 1
TABLE_PRIVILEGES information_schema.TABLE_PRIVILEGES 1
TABLE_STATISTICS information_schema.TABLE_STATISTICS 1
TRIGGERS information_schema.TRIGGERS 1
USERS information_schema.USERS 1
USER_PRIVILEGES information_schema.USER_PRIVILEGES 1
USER_STATISTICS information_schema.USER_STATISTICS 1
VIEWS information_schema.VIEWS 1
Expand Down Expand Up @@ -401,6 +405,7 @@ Database: information_schema
| TABLE_PRIVILEGES |
| TABLE_STATISTICS |
| TRIGGERS |
| USERS |
| USER_PRIVILEGES |
| USER_STATISTICS |
| VIEWS |
Expand Down Expand Up @@ -476,6 +481,7 @@ Database: INFORMATION_SCHEMA
| TABLE_PRIVILEGES |
| TABLE_STATISTICS |
| TRIGGERS |
| USERS |
| USER_PRIVILEGES |
| USER_STATISTICS |
| VIEWS |
Expand All @@ -487,5 +493,5 @@ Wildcard: inf_rmation_schema
| information_schema |
SELECT table_schema, count(*) FROM information_schema.TABLES WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') GROUP BY TABLE_SCHEMA;
table_schema count(*)
information_schema 70
information_schema 71
mysql 31
131 changes: 131 additions & 0 deletions mysql-test/main/information_schema_db.result
Original file line number Diff line number Diff line change
Expand Up @@ -382,3 +382,134 @@ drop database db;
#
# End of 10.4 tests
#
#
# MDEV-23729 INFORMATION_SCHEMA Table info. about user locked due to
# max_password_errors
#
# MDEV-32218 message to notify end-user N-days prior the password get
# expired
#
set @old_max_password_errors=@@max_password_errors;
set global max_password_errors=2;
set timestamp= unix_timestamp('2020-01-02 2:3:4');
create user nice_user;
create user naughty_user identified by 'naughty_user_passwd';
alter user naughty_user password expire interval 10 day;
select * from information_schema.users;
USER PASSWORD_ERRORS PASSWORD_EXPIRATION_TIME
'mariadb.sys'@'localhost' 0 0000-00-00 00:00:00
'naughty_user'@'%' 0 2020-01-12 02:03:04
'nice_user'@'%' 0 NULL
'root'@'127.0.0.1' NULL NULL
'root'@'::1' NULL NULL
'root'@'localhost' NULL NULL
'root'@HOSTNAME 0 NULL
alter user nice_user password expire interval 10 day;
select * from information_schema.users;
USER PASSWORD_ERRORS PASSWORD_EXPIRATION_TIME
'mariadb.sys'@'localhost' 0 0000-00-00 00:00:00
'naughty_user'@'%' 0 2020-01-12 02:03:04
'nice_user'@'%' 0 2020-01-12 02:03:04
'root'@'127.0.0.1' NULL NULL
'root'@'::1' NULL NULL
'root'@'localhost' NULL NULL
'root'@HOSTNAME 0 NULL
connect(localhost,naughty_user,wrong_passwd,test,MASTER_PORT,MASTER_SOCKET);
connect con1, localhost, naughty_user, wrong_passwd;
ERROR 28000: Access denied for user 'naughty_user'@'localhost' (using password: YES)
select * from information_schema.users;
USER PASSWORD_ERRORS PASSWORD_EXPIRATION_TIME
'mariadb.sys'@'localhost' 0 0000-00-00 00:00:00
'naughty_user'@'%' 1 2020-01-12 02:03:04
'nice_user'@'%' 0 2020-01-12 02:03:04
'root'@'127.0.0.1' NULL NULL
'root'@'::1' NULL NULL
'root'@'localhost' NULL NULL
'root'@HOSTNAME 0 NULL
connect(localhost,naughty_user,wrong_passwd,test,MASTER_PORT,MASTER_SOCKET);
connect con1, localhost, naughty_user, wrong_passwd;
ERROR 28000: Access denied for user 'naughty_user'@'localhost' (using password: YES)
select * from information_schema.users;
USER PASSWORD_ERRORS PASSWORD_EXPIRATION_TIME
'mariadb.sys'@'localhost' 0 0000-00-00 00:00:00
'naughty_user'@'%' 2 2020-01-12 02:03:04
'nice_user'@'%' 0 2020-01-12 02:03:04
'root'@'127.0.0.1' NULL NULL
'root'@'::1' NULL NULL
'root'@'localhost' NULL NULL
'root'@HOSTNAME 0 NULL
# Show all users that are blocked due to max_password_errors reached.
select user from information_schema.users
where password_errors >= @@global.max_password_errors;
user
'naughty_user'@'%'
set global max_password_errors=3;
connect con1, localhost, naughty_user, naughty_user_passwd;
connection default;
select * from information_schema.users;
USER PASSWORD_ERRORS PASSWORD_EXPIRATION_TIME
'mariadb.sys'@'localhost' 0 0000-00-00 00:00:00
'naughty_user'@'%' 0 2020-01-12 02:03:04
'nice_user'@'%' 0 2020-01-12 02:03:04
'root'@'127.0.0.1' NULL NULL
'root'@'::1' NULL NULL
'root'@'localhost' NULL NULL
'root'@HOSTNAME 0 NULL
disconnect con1;
# test FLUSH PRIVILEGES
connect(localhost,naughty_user,wrong_passwd,test,MASTER_PORT,MASTER_SOCKET);
connect con1, localhost, naughty_user, wrong_passwd;
ERROR 28000: Access denied for user 'naughty_user'@'localhost' (using password: YES)
select * from information_schema.users where user like '''naughty%';
USER PASSWORD_ERRORS PASSWORD_EXPIRATION_TIME
'naughty_user'@'%' 1 2020-01-12 02:03:04
flush privileges;
select * from information_schema.users where user like '''naughty%';
USER PASSWORD_ERRORS PASSWORD_EXPIRATION_TIME
'naughty_user'@'%' 0 2020-01-12 02:03:04
# Test unprivileged output
connect con2, localhost, nice_user;
set timestamp= unix_timestamp('2020-01-02 2:3:4');
set password= password('nice_passwd');
select * from information_schema.users;
USER PASSWORD_ERRORS PASSWORD_EXPIRATION_TIME
'nice_user'@'%' 0 2020-01-12 02:03:04
# Delete user while some connection is still alive, then select.
connection default;
drop user nice_user;
connection con2;
select * from information_schema.users;
ERROR 0L000: The current user is invalid
disconnect con2;
connection default;
drop user naughty_user;
set global max_password_errors=@old_max_password_errors;
# more password expiration tests
set global default_password_lifetime= 2;
create user u1@localhost password expire;
create user u2@localhost password expire default;
create user u3@localhost password expire interval 10 day;
create user u4@localhost password expire interval 20 day;
create user u5@localhost password expire never;
set timestamp= unix_timestamp('2020-01-17 2:3:4');
select * from information_schema.users where user like '''u_''%';
USER PASSWORD_ERRORS PASSWORD_EXPIRATION_TIME
'u1'@'localhost' 0 0000-00-00 00:00:00
'u2'@'localhost' 0 2020-01-04 02:03:04
'u3'@'localhost' 0 2020-01-12 02:03:04
'u4'@'localhost' 0 2020-01-22 02:03:04
'u5'@'localhost' 0 NULL
set global default_password_lifetime= default;
select * from information_schema.users where user like '''u_''%';
USER PASSWORD_ERRORS PASSWORD_EXPIRATION_TIME
'u1'@'localhost' 0 0000-00-00 00:00:00
'u2'@'localhost' 0 NULL
'u3'@'localhost' 0 2020-01-12 02:03:04
'u4'@'localhost' 0 2020-01-22 02:03:04
'u5'@'localhost' 0 NULL
drop user u1@localhost;
drop user u2@localhost;
drop user u3@localhost;
drop user u4@localhost;
drop user u5@localhost;
# End of 10.0 tests
118 changes: 118 additions & 0 deletions mysql-test/main/information_schema_db.test
Original file line number Diff line number Diff line change
Expand Up @@ -331,3 +331,121 @@ drop database db;
--echo #
--echo # End of 10.4 tests
--echo #

--echo #
--echo # MDEV-23729 INFORMATION_SCHEMA Table info. about user locked due to
--echo # max_password_errors
--echo #
--echo # MDEV-32218 message to notify end-user N-days prior the password get
--echo # expired
--echo #

--disable_service_connection
set @old_max_password_errors=@@max_password_errors;
set global max_password_errors=2;

# must use replace_regex for case insenstive replacement
let $hostname_re= `select concat('/@\'', @@hostname, '\'/@HOSTNAME/i')`;

# set the password_last_changed value
set timestamp= unix_timestamp('2020-01-02 2:3:4');

create user nice_user;
create user naughty_user identified by 'naughty_user_passwd';

alter user naughty_user password expire interval 10 day;

--sorted_result
--replace_regex $hostname_re
eval select * from information_schema.users;

alter user nice_user password expire interval 10 day;
--sorted_result
--replace_regex $hostname_re
select * from information_schema.users;

--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
--error ER_ACCESS_DENIED_ERROR
connect(con1, localhost, naughty_user, wrong_passwd);

--sorted_result
--replace_regex $hostname_re
select * from information_schema.users;

--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
--error ER_ACCESS_DENIED_ERROR
connect(con1, localhost, naughty_user, wrong_passwd);

--sorted_result
--replace_regex $hostname_re
select * from information_schema.users;


--echo # Show all users that are blocked due to max_password_errors reached.
select user from information_schema.users
where password_errors >= @@global.max_password_errors;


set global max_password_errors=3;

connect(con1, localhost, naughty_user, naughty_user_passwd);
connection default;

--sorted_result
--replace_regex $hostname_re
select * from information_schema.users;
disconnect con1;

--echo # test FLUSH PRIVILEGES
--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
--error ER_ACCESS_DENIED_ERROR
connect(con1, localhost, naughty_user, wrong_passwd);
select * from information_schema.users where user like '''naughty%';
flush privileges;
select * from information_schema.users where user like '''naughty%';

--echo # Test unprivileged output

connect(con2, localhost, nice_user);
set timestamp= unix_timestamp('2020-01-02 2:3:4');
# timestamp was normal at the login moment, so the password was expired
set password= password('nice_passwd');

--sorted_result
--replace_regex $hostname_re
select * from information_schema.users;

--echo # Delete user while some connection is still alive, then select.
connection default;
drop user nice_user;
connection con2;
# and here you are, select from your table
--error ER_INVALID_CURRENT_USER
select * from information_schema.users;

disconnect con2;
connection default;
drop user naughty_user;
set global max_password_errors=@old_max_password_errors;

--echo # more password expiration tests
set global default_password_lifetime= 2;
create user u1@localhost password expire;
create user u2@localhost password expire default;
create user u3@localhost password expire interval 10 day;
create user u4@localhost password expire interval 20 day;
create user u5@localhost password expire never;
set timestamp= unix_timestamp('2020-01-17 2:3:4');

select * from information_schema.users where user like '''u_''%';
set global default_password_lifetime= default;
select * from information_schema.users where user like '''u_''%';

drop user u1@localhost;
drop user u2@localhost;
drop user u3@localhost;
drop user u4@localhost;
drop user u5@localhost;
--enable_service_connection

--echo # End of 10.0 tests
Loading

0 comments on commit 173edf6

Please sign in to comment.