mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
MDEV-7597 Expiration of user passwords
post-merge changes: * handle password expiration on old tables like everything else - make changes in memory, even if they cannot be done on disk * merge "debug" tests with non-debug tests, they don't use dbug anyway * only run rpl password expiration in MIXED mode, it doesn't replicate anything, so no need to repeat it thrice * restore update_user_table_password() prototype, it should not change ACL_USER, this is done in acl_user_update() * don't parse json twice in get_password_lifetime and get_password_expired * remove LEX_USER::is_changing_password, see if there was any auth instead * avoid overflow in expiration calculations * don't initialize Account_options in the constructor, it's bzero-ed later * don't create ulong sysvars - they're not portable, prefer uint or ulonglong * misc simplifications
This commit is contained in:
parent
90ad4dbd17
commit
1e6210161d
21 changed files with 251 additions and 359 deletions
|
@ -596,7 +596,7 @@ drop view mysql.user_bak;
|
|||
create user 'user3'@'localhost' identified with mysql_native_password as password('a_password');
|
||||
show create user user3@localhost;
|
||||
CREATE USER for user3@localhost
|
||||
CREATE USER 'user3'@'localhost' IDENTIFIED BY PASSWORD '*5DC1D11F45824A9DD613961F05C1EC1E7A1601AA' PASSWORD EXPIRE NEVER
|
||||
CREATE USER 'user3'@'localhost' IDENTIFIED BY PASSWORD '*5DC1D11F45824A9DD613961F05C1EC1E7A1601AA'
|
||||
update mysql.user set password=authentication_string, authentication_string='' where user='user3';
|
||||
select password,plugin,authentication_string from mysql.user where user='user3';
|
||||
password plugin authentication_string
|
||||
|
|
|
@ -141,7 +141,7 @@ ERROR HY000: Incorrect DAY value: '0'
|
|||
create user user1@localhost;
|
||||
show create user user1@localhost;
|
||||
CREATE USER for user1@localhost
|
||||
CREATE USER 'user1'@'localhost' PASSWORD EXPIRE NEVER
|
||||
CREATE USER 'user1'@'localhost'
|
||||
flush privileges;
|
||||
show create user user1@localhost;
|
||||
CREATE USER for user1@localhost
|
||||
|
@ -158,7 +158,7 @@ set password for user1@localhost= password('');
|
|||
alter user user1@localhost password expire default;
|
||||
show create user user1@localhost;
|
||||
CREATE USER for user1@localhost
|
||||
CREATE USER 'user1'@'localhost' PASSWORD EXPIRE NEVER
|
||||
CREATE USER 'user1'@'localhost'
|
||||
flush privileges;
|
||||
show create user user1@localhost;
|
||||
CREATE USER for user1@localhost
|
||||
|
@ -174,7 +174,7 @@ CREATE USER 'user1'@'localhost' PASSWORD EXPIRE NEVER
|
|||
alter user user1@localhost password expire interval 123 day;
|
||||
show create user user1@localhost;
|
||||
CREATE USER for user1@localhost
|
||||
CREATE USER 'user1'@'localhost' PASSWORD EXPIRE NEVER
|
||||
CREATE USER 'user1'@'localhost' PASSWORD EXPIRE INTERVAL 123 DAY
|
||||
flush privileges;
|
||||
show create user user1@localhost;
|
||||
CREATE USER for user1@localhost
|
||||
|
@ -205,3 +205,55 @@ connection default;
|
|||
drop user user1@localhost;
|
||||
set global disconnect_on_expired_password=default;
|
||||
set global default_password_lifetime=default;
|
||||
#
|
||||
# PASSWORD EXPIRE DEFAULT should use the default_password_lifetime
|
||||
# system var to set the number of days till expiration
|
||||
#
|
||||
set global disconnect_on_expired_password= ON;
|
||||
set global default_password_lifetime= 2;
|
||||
create user user1@localhost password expire default;
|
||||
set @tstamp_expired= UNIX_TIMESTAMP(NOW() - INTERVAL 3 DAY);
|
||||
update mysql.global_priv set
|
||||
priv=json_set(priv, '$.password_last_changed', @tstamp_expired)
|
||||
where user='user1';
|
||||
flush privileges;
|
||||
connect(localhost,user1,,test,MYSQL_PORT,MYSQL_SOCK);
|
||||
connect con1,localhost,user1;
|
||||
ERROR HY000: Your password has expired. To log in you must change it using a client that supports expired passwords
|
||||
drop user user1@localhost;
|
||||
#
|
||||
# PASSWORD EXPIRE INTERVAL should expire a client's password after
|
||||
# X days and not before
|
||||
#
|
||||
set global disconnect_on_expired_password= ON;
|
||||
create user user1@localhost password expire interval 2 day;
|
||||
connect con1,localhost,user1;
|
||||
disconnect con1;
|
||||
connection default;
|
||||
set @tstamp_expired= UNIX_TIMESTAMP(NOW() - INTERVAL 3 DAY);
|
||||
update mysql.global_priv set
|
||||
priv=json_set(priv, '$.password_last_changed', @tstamp_expired)
|
||||
where user='user1';
|
||||
flush privileges;
|
||||
connect(localhost,user1,,test,MYSQL_PORT,MYSQL_SOCK);
|
||||
connect con1,localhost,user1;
|
||||
ERROR HY000: Your password has expired. To log in you must change it using a client that supports expired passwords
|
||||
drop user user1@localhost;
|
||||
#
|
||||
# PASSWORD EXPIRE NEVER should override the other policies and never
|
||||
# expire a client's password
|
||||
#
|
||||
set global disconnect_on_expired_password= ON;
|
||||
create user user1@localhost password expire interval 2 day;
|
||||
alter user user1@localhost password expire never;
|
||||
set @tstamp_expired= UNIX_TIMESTAMP() - 3;
|
||||
update mysql.global_priv set
|
||||
priv=json_set(priv, '$.password_last_changed', @tstamp_expired)
|
||||
where user='user1';
|
||||
flush privileges;
|
||||
connect con1,localhost,user1;
|
||||
disconnect con1;
|
||||
connection default;
|
||||
drop user user1@localhost;
|
||||
set global disconnect_on_expired_password= default;
|
||||
set global default_password_lifetime= default;
|
||||
|
|
|
@ -194,3 +194,70 @@ set global disconnect_on_expired_password=default;
|
|||
set global default_password_lifetime=default;
|
||||
--source include/switch_to_mysql_global_priv.inc
|
||||
|
||||
#
|
||||
# Test password expiration INTERVAL and default_password_lifetime options
|
||||
#
|
||||
|
||||
--echo #
|
||||
--echo # PASSWORD EXPIRE DEFAULT should use the default_password_lifetime
|
||||
--echo # system var to set the number of days till expiration
|
||||
--echo #
|
||||
set global disconnect_on_expired_password= ON;
|
||||
set global default_password_lifetime= 2;
|
||||
create user user1@localhost password expire default;
|
||||
|
||||
set @tstamp_expired= UNIX_TIMESTAMP(NOW() - INTERVAL 3 DAY);
|
||||
update mysql.global_priv set
|
||||
priv=json_set(priv, '$.password_last_changed', @tstamp_expired)
|
||||
where user='user1';
|
||||
flush privileges;
|
||||
|
||||
--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK
|
||||
--error ER_MUST_CHANGE_PASSWORD_LOGIN
|
||||
connect(con1,localhost,user1);
|
||||
drop user user1@localhost;
|
||||
|
||||
--echo #
|
||||
--echo # PASSWORD EXPIRE INTERVAL should expire a client's password after
|
||||
--echo # X days and not before
|
||||
--echo #
|
||||
set global disconnect_on_expired_password= ON;
|
||||
create user user1@localhost password expire interval 2 day;
|
||||
--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK
|
||||
connect(con1,localhost,user1);
|
||||
disconnect con1;
|
||||
connection default;
|
||||
|
||||
set @tstamp_expired= UNIX_TIMESTAMP(NOW() - INTERVAL 3 DAY);
|
||||
update mysql.global_priv set
|
||||
priv=json_set(priv, '$.password_last_changed', @tstamp_expired)
|
||||
where user='user1';
|
||||
flush privileges;
|
||||
|
||||
--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK
|
||||
--error ER_MUST_CHANGE_PASSWORD_LOGIN
|
||||
connect(con1,localhost,user1);
|
||||
drop user user1@localhost;
|
||||
|
||||
--echo #
|
||||
--echo # PASSWORD EXPIRE NEVER should override the other policies and never
|
||||
--echo # expire a client's password
|
||||
--echo #
|
||||
set global disconnect_on_expired_password= ON;
|
||||
create user user1@localhost password expire interval 2 day;
|
||||
alter user user1@localhost password expire never;
|
||||
|
||||
set @tstamp_expired= UNIX_TIMESTAMP() - 3;
|
||||
update mysql.global_priv set
|
||||
priv=json_set(priv, '$.password_last_changed', @tstamp_expired)
|
||||
where user='user1';
|
||||
flush privileges;
|
||||
|
||||
--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK
|
||||
connect(con1,localhost,user1);
|
||||
disconnect con1;
|
||||
connection default;
|
||||
drop user user1@localhost;
|
||||
|
||||
set global disconnect_on_expired_password= default;
|
||||
set global default_password_lifetime= default;
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
set @old_dbug= @@global.debug_dbug;
|
||||
set global debug_dbug= "+d,password_expiration_interval_sec";
|
||||
#
|
||||
# PASSWORD EXPIRE DEFAULT should use the default_password_lifetime
|
||||
# system var to set the number of days till expiration
|
||||
#
|
||||
set global disconnect_on_expired_password= ON;
|
||||
set global default_password_lifetime= 2;
|
||||
create user user1@localhost password expire default;
|
||||
set @tstamp_expired= UNIX_TIMESTAMP() - 3;
|
||||
update mysql.global_priv set
|
||||
priv=json_set(priv, '$.password_last_changed', @tstamp_expired)
|
||||
where user='user1';
|
||||
flush privileges;
|
||||
connect(localhost,user1,,test,MYSQL_PORT,MYSQL_SOCK);
|
||||
connect con1,localhost,user1;
|
||||
ERROR HY000: Your password has expired. To log in you must change it using a client that supports expired passwords
|
||||
drop user user1@localhost;
|
||||
#
|
||||
# PASSWORD EXPIRE INTERVAL should expire a client's password after
|
||||
# X seconds and not before
|
||||
#
|
||||
set global disconnect_on_expired_password= ON;
|
||||
create user user1@localhost password expire interval 2 day;
|
||||
connect con1,localhost,user1;
|
||||
disconnect con1;
|
||||
connection default;
|
||||
set @tstamp_expired= UNIX_TIMESTAMP() - 3;
|
||||
update mysql.global_priv set
|
||||
priv=json_set(priv, '$.password_last_changed', @tstamp_expired)
|
||||
where user='user1';
|
||||
flush privileges;
|
||||
connect(localhost,user1,,test,MYSQL_PORT,MYSQL_SOCK);
|
||||
connect con1,localhost,user1;
|
||||
ERROR HY000: Your password has expired. To log in you must change it using a client that supports expired passwords
|
||||
drop user user1@localhost;
|
||||
#
|
||||
# PASSWORD EXPIRE NEVER should override the other policies and never
|
||||
# expire a client's password
|
||||
#
|
||||
set global disconnect_on_expired_password= ON;
|
||||
create user user1@localhost password expire interval 2 day;
|
||||
alter user user1@localhost password expire never;
|
||||
set @tstamp_expired= UNIX_TIMESTAMP() - 3;
|
||||
update mysql.global_priv set
|
||||
priv=json_set(priv, '$.password_last_changed', @tstamp_expired)
|
||||
where user='user1';
|
||||
flush privileges;
|
||||
connect con1,localhost,user1;
|
||||
disconnect con1;
|
||||
connection default;
|
||||
drop user user1@localhost;
|
||||
set global debug_dbug= @old_dbug;
|
||||
set global disconnect_on_expired_password= default;
|
||||
set global default_password_lifetime= default;
|
|
@ -1,75 +0,0 @@
|
|||
#
|
||||
# Test password expiration INTERVAL and default_password_lifetime options
|
||||
#
|
||||
|
||||
--source include/have_debug.inc
|
||||
--source include/not_embedded.inc
|
||||
|
||||
set @old_dbug= @@global.debug_dbug;
|
||||
set global debug_dbug= "+d,password_expiration_interval_sec";
|
||||
|
||||
--echo #
|
||||
--echo # PASSWORD EXPIRE DEFAULT should use the default_password_lifetime
|
||||
--echo # system var to set the number of days till expiration
|
||||
--echo #
|
||||
set global disconnect_on_expired_password= ON;
|
||||
set global default_password_lifetime= 2;
|
||||
create user user1@localhost password expire default;
|
||||
|
||||
set @tstamp_expired= UNIX_TIMESTAMP() - 3;
|
||||
update mysql.global_priv set
|
||||
priv=json_set(priv, '$.password_last_changed', @tstamp_expired)
|
||||
where user='user1';
|
||||
flush privileges;
|
||||
|
||||
--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK
|
||||
--error ER_MUST_CHANGE_PASSWORD_LOGIN
|
||||
connect(con1,localhost,user1);
|
||||
drop user user1@localhost;
|
||||
|
||||
--echo #
|
||||
--echo # PASSWORD EXPIRE INTERVAL should expire a client's password after
|
||||
--echo # X seconds and not before
|
||||
--echo #
|
||||
set global disconnect_on_expired_password= ON;
|
||||
create user user1@localhost password expire interval 2 day;
|
||||
--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK
|
||||
connect(con1,localhost,user1);
|
||||
disconnect con1;
|
||||
connection default;
|
||||
|
||||
set @tstamp_expired= UNIX_TIMESTAMP() - 3;
|
||||
update mysql.global_priv set
|
||||
priv=json_set(priv, '$.password_last_changed', @tstamp_expired)
|
||||
where user='user1';
|
||||
flush privileges;
|
||||
|
||||
--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK
|
||||
--error ER_MUST_CHANGE_PASSWORD_LOGIN
|
||||
connect(con1,localhost,user1);
|
||||
drop user user1@localhost;
|
||||
|
||||
--echo #
|
||||
--echo # PASSWORD EXPIRE NEVER should override the other policies and never
|
||||
--echo # expire a client's password
|
||||
--echo #
|
||||
set global disconnect_on_expired_password= ON;
|
||||
create user user1@localhost password expire interval 2 day;
|
||||
alter user user1@localhost password expire never;
|
||||
|
||||
set @tstamp_expired= UNIX_TIMESTAMP() - 3;
|
||||
update mysql.global_priv set
|
||||
priv=json_set(priv, '$.password_last_changed', @tstamp_expired)
|
||||
where user='user1';
|
||||
flush privileges;
|
||||
|
||||
--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK
|
||||
connect(con1,localhost,user1);
|
||||
disconnect con1;
|
||||
connection default;
|
||||
drop user user1@localhost;
|
||||
|
||||
set global debug_dbug= @old_dbug;
|
||||
set global disconnect_on_expired_password= default;
|
||||
set global default_password_lifetime= default;
|
||||
|
|
@ -92,8 +92,7 @@ json_detailed(priv) {
|
|||
"access": 0,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
host localhost
|
||||
user testuser2
|
||||
|
@ -101,8 +100,7 @@ json_detailed(priv) {
|
|||
"access": 6,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
host localhost
|
||||
user testuser3
|
||||
|
@ -110,8 +108,7 @@ json_detailed(priv) {
|
|||
"access": 0,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
#
|
||||
# Add GRANT OPTION db_datadict.* to testuser1;
|
||||
|
@ -143,8 +140,7 @@ json_detailed(priv) {
|
|||
"access": 0,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
host localhost
|
||||
user testuser2
|
||||
|
@ -152,8 +148,7 @@ json_detailed(priv) {
|
|||
"access": 6,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
host localhost
|
||||
user testuser3
|
||||
|
@ -161,8 +156,7 @@ json_detailed(priv) {
|
|||
"access": 0,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
connect testuser1, localhost, testuser1, , db_datadict;
|
||||
SELECT * FROM information_schema.user_privileges
|
||||
|
@ -180,8 +174,7 @@ json_detailed(priv) {
|
|||
"access": 0,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
host localhost
|
||||
user testuser2
|
||||
|
@ -189,8 +182,7 @@ json_detailed(priv) {
|
|||
"access": 6,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
host localhost
|
||||
user testuser3
|
||||
|
@ -198,8 +190,7 @@ json_detailed(priv) {
|
|||
"access": 0,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
SHOW GRANTS;
|
||||
Grants for testuser1@localhost
|
||||
|
@ -239,8 +230,7 @@ json_detailed(priv) {
|
|||
"access": 1,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
host localhost
|
||||
user testuser2
|
||||
|
@ -248,8 +238,7 @@ json_detailed(priv) {
|
|||
"access": 6,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
host localhost
|
||||
user testuser3
|
||||
|
@ -257,8 +246,7 @@ json_detailed(priv) {
|
|||
"access": 0,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
GRANT SELECT ON *.* TO 'testuser1'@'localhost' WITH GRANT OPTION;
|
||||
#
|
||||
|
@ -290,8 +278,7 @@ json_detailed(priv) {
|
|||
"access": 1025,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
host localhost
|
||||
user testuser2
|
||||
|
@ -299,8 +286,7 @@ json_detailed(priv) {
|
|||
"access": 6,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
host localhost
|
||||
user testuser3
|
||||
|
@ -308,8 +294,7 @@ json_detailed(priv) {
|
|||
"access": 0,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
connection testuser1;
|
||||
SELECT * FROM information_schema.user_privileges
|
||||
|
@ -327,8 +312,7 @@ json_detailed(priv) {
|
|||
"access": 1025,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
host localhost
|
||||
user testuser2
|
||||
|
@ -336,8 +320,7 @@ json_detailed(priv) {
|
|||
"access": 6,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
host localhost
|
||||
user testuser3
|
||||
|
@ -345,8 +328,7 @@ json_detailed(priv) {
|
|||
"access": 0,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
SHOW GRANTS;
|
||||
Grants for testuser1@localhost
|
||||
|
@ -416,8 +398,7 @@ json_detailed(priv) {
|
|||
"access": 0,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
host localhost
|
||||
user testuser2
|
||||
|
@ -425,8 +406,7 @@ json_detailed(priv) {
|
|||
"access": 6,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
host localhost
|
||||
user testuser3
|
||||
|
@ -434,8 +414,7 @@ json_detailed(priv) {
|
|||
"access": 0,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
connection testuser1;
|
||||
SELECT * FROM information_schema.user_privileges
|
||||
|
@ -500,8 +479,7 @@ json_detailed(priv) {
|
|||
"access": 0,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
host localhost
|
||||
user testuser2
|
||||
|
@ -509,8 +487,7 @@ json_detailed(priv) {
|
|||
"access": 6,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
host localhost
|
||||
user testuser3
|
||||
|
@ -518,8 +495,7 @@ json_detailed(priv) {
|
|||
"access": 0,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
connection testuser1;
|
||||
SELECT * FROM information_schema.user_privileges
|
||||
|
@ -537,8 +513,7 @@ json_detailed(priv) {
|
|||
"access": 0,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
host localhost
|
||||
user testuser2
|
||||
|
@ -546,8 +521,7 @@ json_detailed(priv) {
|
|||
"access": 6,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
host localhost
|
||||
user testuser3
|
||||
|
@ -555,8 +529,7 @@ json_detailed(priv) {
|
|||
"access": 0,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
SHOW GRANTS;
|
||||
Grants for testuser1@localhost
|
||||
|
@ -581,8 +554,7 @@ json_detailed(priv) {
|
|||
"access": 0,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
host localhost
|
||||
user testuser2
|
||||
|
@ -590,8 +562,7 @@ json_detailed(priv) {
|
|||
"access": 6,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
host localhost
|
||||
user testuser3
|
||||
|
@ -599,8 +570,7 @@ json_detailed(priv) {
|
|||
"access": 0,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
SHOW GRANTS;
|
||||
Grants for testuser1@localhost
|
||||
|
@ -640,8 +610,7 @@ json_detailed(priv) {
|
|||
"access": 0,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
host localhost
|
||||
user testuser2
|
||||
|
@ -649,8 +618,7 @@ json_detailed(priv) {
|
|||
"access": 6,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
host localhost
|
||||
user testuser3
|
||||
|
@ -658,8 +626,7 @@ json_detailed(priv) {
|
|||
"access": 0,
|
||||
"plugin": "mysql_native_password",
|
||||
"authentication_string": "",
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
connection testuser1;
|
||||
SELECT * FROM information_schema.user_privileges
|
||||
|
|
|
@ -103,7 +103,7 @@ WHERE user LIKE 'testuser%' ORDER BY host, user;
|
|||
let $my_show= SHOW GRANTS;
|
||||
--vertical_results
|
||||
eval $my_select1;
|
||||
--replace_regex /password_last_changed": [0-9]*/password_last_changed": 0/
|
||||
--replace_regex /password_last_changed": [0-9]*/password_last_changed": #/
|
||||
eval $my_select2;
|
||||
--horizontal_results
|
||||
|
||||
|
@ -112,7 +112,7 @@ eval $my_select2;
|
|||
GRANT UPDATE ON db_datadict.* TO 'testuser1'@'localhost' WITH GRANT OPTION;
|
||||
--vertical_results
|
||||
eval $my_select1;
|
||||
--replace_regex /password_last_changed": [0-9]*/password_last_changed": 0/
|
||||
--replace_regex /password_last_changed": [0-9]*/password_last_changed": #/
|
||||
eval $my_select2;
|
||||
--horizontal_results
|
||||
|
||||
|
@ -120,7 +120,7 @@ eval $my_select2;
|
|||
connect (testuser1, localhost, testuser1, , db_datadict);
|
||||
--vertical_results
|
||||
eval $my_select1;
|
||||
--replace_regex /password_last_changed": [0-9]*/password_last_changed": 0/
|
||||
--replace_regex /password_last_changed": [0-9]*/password_last_changed": #/
|
||||
eval $my_select2;
|
||||
--horizontal_results
|
||||
eval $my_show;
|
||||
|
@ -134,7 +134,7 @@ GRANT SELECT ON *.* TO 'testuser1'@'localhost';
|
|||
--echo # Here <SELECT NO> is shown correctly for testuser1;
|
||||
--vertical_results
|
||||
eval $my_select1;
|
||||
--replace_regex /password_last_changed": [0-9]*/password_last_changed": 0/
|
||||
--replace_regex /password_last_changed": [0-9]*/password_last_changed": #/
|
||||
eval $my_select2;
|
||||
--horizontal_results
|
||||
|
||||
|
@ -143,7 +143,7 @@ GRANT SELECT ON *.* TO 'testuser1'@'localhost' WITH GRANT OPTION;
|
|||
--echo # Here <SELECT YES> is shown correctly for testuser1;
|
||||
--vertical_results
|
||||
eval $my_select1;
|
||||
--replace_regex /password_last_changed": [0-9]*/password_last_changed": 0/
|
||||
--replace_regex /password_last_changed": [0-9]*/password_last_changed": #/
|
||||
eval $my_select2;
|
||||
--horizontal_results
|
||||
|
||||
|
@ -151,7 +151,7 @@ eval $my_select2;
|
|||
connection testuser1;
|
||||
--vertical_results
|
||||
eval $my_select1;
|
||||
--replace_regex /password_last_changed": [0-9]*/password_last_changed": 0/
|
||||
--replace_regex /password_last_changed": [0-9]*/password_last_changed": #/
|
||||
eval $my_select2;
|
||||
--horizontal_results
|
||||
eval $my_show;
|
||||
|
@ -180,7 +180,7 @@ connection default;
|
|||
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'testuser1'@'localhost';
|
||||
--vertical_results
|
||||
eval $my_select1;
|
||||
--replace_regex /password_last_changed": [0-9]*/password_last_changed": 0/
|
||||
--replace_regex /password_last_changed": [0-9]*/password_last_changed": #/
|
||||
eval $my_select2;
|
||||
--horizontal_results
|
||||
|
||||
|
@ -213,14 +213,14 @@ GRANT ALL ON db_datadict.* TO 'testuser1'@'localhost' WITH GRANT OPTION;
|
|||
GRANT SELECT ON mysql.global_priv TO 'testuser1'@'localhost';
|
||||
--vertical_results
|
||||
eval $my_select1;
|
||||
--replace_regex /password_last_changed": [0-9]*/password_last_changed": 0/
|
||||
--replace_regex /password_last_changed": [0-9]*/password_last_changed": #/
|
||||
eval $my_select2;
|
||||
--horizontal_results
|
||||
|
||||
connection testuser1;
|
||||
--vertical_results
|
||||
eval $my_select1;
|
||||
--replace_regex /password_last_changed": [0-9]*/password_last_changed": 0/
|
||||
--replace_regex /password_last_changed": [0-9]*/password_last_changed": #/
|
||||
eval $my_select2;
|
||||
--horizontal_results
|
||||
eval $my_show;
|
||||
|
@ -233,7 +233,7 @@ CREATE TABLE db_datadict.tb_56 ( c1 TEXT );
|
|||
USE db_datadict;
|
||||
--vertical_results
|
||||
eval $my_select1;
|
||||
--replace_regex /password_last_changed": [0-9]*/password_last_changed": 0/
|
||||
--replace_regex /password_last_changed": [0-9]*/password_last_changed": #/
|
||||
eval $my_select2;
|
||||
--horizontal_results
|
||||
eval $my_show;
|
||||
|
@ -248,7 +248,7 @@ connection default;
|
|||
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'testuser1'@'localhost';
|
||||
--vertical_results
|
||||
eval $my_select1;
|
||||
--replace_regex /password_last_changed": [0-9]*/password_last_changed": 0/
|
||||
--replace_regex /password_last_changed": [0-9]*/password_last_changed": #/
|
||||
eval $my_select2;
|
||||
--horizontal_results
|
||||
|
||||
|
|
|
@ -123,8 +123,7 @@ json_detailed(priv)
|
|||
{
|
||||
}
|
||||
],
|
||||
"password_last_changed": 0,
|
||||
"password_lifetime": -1
|
||||
"password_last_changed": #
|
||||
}
|
||||
select password,plugin,authentication_string from mysql.user where user='mysqltest1';
|
||||
Password plugin authentication_string
|
||||
|
|
|
@ -130,7 +130,7 @@ drop user mysqltest1;
|
|||
#
|
||||
create user mysqltest1 identified via ed25519 as password("good") OR unix_socket OR mysql_native_password as password("works");
|
||||
show grants for mysqltest1;
|
||||
--replace_regex /password_last_changed": [0-9]*/password_last_changed": 0/
|
||||
--replace_regex /password_last_changed": [0-9]*/password_last_changed": #/
|
||||
select json_detailed(priv) from mysql.global_priv where user='mysqltest1';
|
||||
select password,plugin,authentication_string from mysql.user where user='mysqltest1';
|
||||
flush privileges;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#
|
||||
|
||||
--source include/not_embedded.inc
|
||||
--source include/have_binlog_format_mixed.inc
|
||||
--source include/master-slave.inc
|
||||
|
||||
--connection slave
|
|
@ -718,7 +718,7 @@ GLOBAL_VALUE 0
|
|||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 0
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
VARIABLE_TYPE BIGINT UNSIGNED
|
||||
VARIABLE_TYPE INT UNSIGNED
|
||||
VARIABLE_COMMENT This defines the global password expiration policy. 0 means automatic password expiration is disabled. If the value is a positive integer N, the passwords must be changed every N days. This behavior can be overriden using the password expiration options in ALTER USER.
|
||||
NUMERIC_MIN_VALUE 0
|
||||
NUMERIC_MAX_VALUE 4294967295
|
||||
|
|
|
@ -732,7 +732,7 @@ GLOBAL_VALUE 0
|
|||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE 0
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
VARIABLE_TYPE BIGINT UNSIGNED
|
||||
VARIABLE_TYPE INT UNSIGNED
|
||||
VARIABLE_COMMENT This defines the global password expiration policy. 0 means automatic password expiration is disabled. If the value is a positive integer N, the passwords must be changed every N days. This behavior can be overriden using the password expiration options in ALTER USER.
|
||||
NUMERIC_MIN_VALUE 0
|
||||
NUMERIC_MAX_VALUE 4294967295
|
||||
|
|
|
@ -511,7 +511,7 @@ ulong feature_files_opened_with_delayed_keys= 0, feature_check_constraint= 0;
|
|||
ulonglong denied_connections;
|
||||
my_decimal decimal_zero;
|
||||
long opt_secure_timestamp;
|
||||
ulong default_password_lifetime;
|
||||
uint default_password_lifetime;
|
||||
my_bool disconnect_on_expired_password;
|
||||
|
||||
/*
|
||||
|
|
|
@ -310,7 +310,7 @@ extern my_bool encrypt_tmp_disk_tables, encrypt_tmp_files;
|
|||
extern ulong encryption_algorithm;
|
||||
extern const char *encryption_algorithm_names[];
|
||||
extern long opt_secure_timestamp;
|
||||
extern ulong default_password_lifetime;
|
||||
extern uint default_password_lifetime;
|
||||
extern my_bool disconnect_on_expired_password;
|
||||
|
||||
enum secure_timestamp { SECTIME_NO, SECTIME_SUPER, SECTIME_REPL, SECTIME_YES };
|
||||
|
|
173
sql/sql_acl.cc
173
sql/sql_acl.cc
|
@ -647,8 +647,7 @@ static ACL_USER *find_user_wild(const char *host, const char *user, const char *
|
|||
static ACL_ROLE *find_acl_role(const char *user);
|
||||
static ROLE_GRANT_PAIR *find_role_grant_pair(const LEX_CSTRING *u, const LEX_CSTRING *h, const LEX_CSTRING *r);
|
||||
static ACL_USER_BASE *find_acl_user_base(const char *user, const char *host);
|
||||
static bool update_user_table_password(THD *, const User_table&,
|
||||
ACL_USER*);
|
||||
static bool update_user_table_password(THD *, const User_table&, const ACL_USER&);
|
||||
static bool acl_load(THD *thd, const Grant_tables& grant_tables);
|
||||
static inline void get_grantor(THD *thd, char* grantor);
|
||||
static bool add_role_user_mapping(const char *uname, const char *hname, const char *rname);
|
||||
|
@ -873,7 +872,7 @@ class User_table: public Grant_table_base
|
|||
virtual bool get_password_expired () const = 0;
|
||||
virtual int set_password_expired (bool x) const = 0;
|
||||
virtual my_time_t get_password_last_changed () const = 0;
|
||||
virtual int set_password_last_changed (const my_time_t &x) const = 0;
|
||||
virtual int set_password_last_changed (my_time_t x) const = 0;
|
||||
virtual longlong get_password_lifetime () const = 0;
|
||||
virtual int set_password_lifetime (longlong x) const = 0;
|
||||
|
||||
|
@ -1165,7 +1164,6 @@ class User_table_tabular: public User_table
|
|||
|
||||
if (Field *f= get_field(field_num, MYSQL_TYPE_ENUM))
|
||||
return f->store(x+1, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
my_time_t get_password_last_changed () const
|
||||
|
@ -1173,17 +1171,15 @@ class User_table_tabular: public User_table
|
|||
ulong unused_dec;
|
||||
if (Field *f= get_field(end_priv_columns + 11, MYSQL_TYPE_TIMESTAMP2))
|
||||
return f->get_timestamp(&unused_dec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int set_password_last_changed (const my_time_t &x) const
|
||||
int set_password_last_changed (my_time_t x) const
|
||||
{
|
||||
if (Field *f= get_field(end_priv_columns + 11, MYSQL_TYPE_TIMESTAMP2))
|
||||
{
|
||||
f->set_notnull();
|
||||
return f->store_timestamp(x, 0);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
longlong get_password_lifetime () const
|
||||
|
@ -1192,10 +1188,8 @@ class User_table_tabular: public User_table
|
|||
{
|
||||
if (f->is_null())
|
||||
return -1;
|
||||
|
||||
return f->val_int();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int set_password_lifetime (longlong x) const
|
||||
|
@ -1210,7 +1204,6 @@ class User_table_tabular: public User_table
|
|||
f->set_notnull();
|
||||
return f->store(x, 0);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1511,33 +1504,19 @@ class User_table_json: public User_table
|
|||
{ return set_bool_value("account_locked", x); }
|
||||
my_time_t get_password_last_changed () const
|
||||
{ return static_cast<my_time_t>(get_int_value("password_last_changed")); }
|
||||
int set_password_last_changed (const my_time_t &x) const
|
||||
int set_password_last_changed (my_time_t x) const
|
||||
{ return set_int_value("password_last_changed", static_cast<longlong>(x)); }
|
||||
int set_password_lifetime (longlong x) const
|
||||
{ return set_int_value("password_lifetime", x); }
|
||||
longlong get_password_lifetime () const
|
||||
{
|
||||
size_t value_len;
|
||||
const char *value_start;
|
||||
const char *key= "password_lifetime";
|
||||
if (get_value(key, JSV_NUMBER, &value_start, &value_len))
|
||||
return -1;
|
||||
return get_int_value(key);
|
||||
}
|
||||
{ return get_int_value("password_lifetime", -1); }
|
||||
/*
|
||||
password_last_changed=0 means the password is manually expired.
|
||||
In MySQL 5.7+ this state is described using the password_expired column
|
||||
in mysql.user
|
||||
*/
|
||||
bool get_password_expired () const
|
||||
{
|
||||
size_t value_len;
|
||||
const char *value_start;
|
||||
const char *key= "password_last_changed";
|
||||
if (get_value(key, JSV_NUMBER, &value_start, &value_len))
|
||||
return false;
|
||||
return get_password_last_changed() == 0;
|
||||
}
|
||||
{ return get_int_value("password_last_changed", -1) == 0; }
|
||||
int set_password_expired (bool x) const
|
||||
{ return x ? set_password_last_changed(0) : 0; }
|
||||
|
||||
|
@ -1581,13 +1560,13 @@ class User_table_json: public User_table
|
|||
return NULL;
|
||||
return strmake_root(root, ptr, len);
|
||||
}
|
||||
longlong get_int_value(const char *key) const
|
||||
longlong get_int_value(const char *key, longlong def_val= 0) const
|
||||
{
|
||||
int err;
|
||||
size_t value_len;
|
||||
const char *value_start;
|
||||
if (get_value(key, JSV_NUMBER, &value_start, &value_len))
|
||||
return 0;
|
||||
return def_val;
|
||||
const char *value_end= value_start + value_len;
|
||||
return my_strtoll10(value_start, (char**)&value_end, &err);
|
||||
}
|
||||
|
@ -3156,6 +3135,8 @@ static int acl_user_update(THD *thd, ACL_USER *acl_user, uint nauth,
|
|||
update_hostname(&acl_user->host, safe_strdup_root(&acl_memroot, combo.host.str));
|
||||
acl_user->hostname_length= combo.host.length;
|
||||
acl_user->sort= get_sort(2, acl_user->host.hostname, acl_user->user.str);
|
||||
acl_user->password_last_changed= thd->query_start();
|
||||
acl_user->password_lifetime= -1;
|
||||
my_init_dynamic_array(&acl_user->role_grants, sizeof(ACL_USER *),
|
||||
0, 8, MYF(0));
|
||||
}
|
||||
|
@ -3201,6 +3182,31 @@ static int acl_user_update(THD *thd, ACL_USER *acl_user, uint nauth,
|
|||
}
|
||||
if (options.account_locked != ACCOUNTLOCK_UNSPECIFIED)
|
||||
acl_user->account_locked= options.account_locked == ACCOUNTLOCK_LOCKED;
|
||||
|
||||
/* Unexpire the user password */
|
||||
if (nauth)
|
||||
{
|
||||
acl_user->password_expired= false;
|
||||
acl_user->password_last_changed= thd->query_start();;
|
||||
}
|
||||
|
||||
switch (options.password_expire) {
|
||||
case PASSWORD_EXPIRE_UNSPECIFIED:
|
||||
break;
|
||||
case PASSWORD_EXPIRE_NOW:
|
||||
acl_user->password_expired= true;
|
||||
break;
|
||||
case PASSWORD_EXPIRE_NEVER:
|
||||
acl_user->password_lifetime= 0;
|
||||
break;
|
||||
case PASSWORD_EXPIRE_DEFAULT:
|
||||
acl_user->password_lifetime= -1;
|
||||
break;
|
||||
case PASSWORD_EXPIRE_INTERVAL:
|
||||
acl_user->password_lifetime= options.num_expiration_days;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3767,7 +3773,16 @@ bool change_password(THD *thd, LEX_USER *user)
|
|||
goto end;
|
||||
}
|
||||
|
||||
if (update_user_table_password(thd, tables.user_table(), acl_user))
|
||||
/* Update the acl password expired state of user */
|
||||
acl_user->password_last_changed= thd->query_start();
|
||||
acl_user->password_expired= false;
|
||||
|
||||
/* If user is the connected user, reset the password expired field on sctx
|
||||
and allow the user to exit sandbox mode */
|
||||
if (thd->security_ctx->is_priv_user(user->user.str, user->host.str))
|
||||
thd->security_ctx->password_expired= false;
|
||||
|
||||
if (update_user_table_password(thd, tables.user_table(), *acl_user))
|
||||
goto end;
|
||||
|
||||
acl_cache->clear(1); // Clear locked hostname cache
|
||||
|
@ -4211,7 +4226,7 @@ bool hostname_requires_resolving(const char *hostname)
|
|||
*/
|
||||
|
||||
static bool update_user_table_password(THD *thd, const User_table& user_table,
|
||||
ACL_USER *user)
|
||||
const ACL_USER &user)
|
||||
{
|
||||
char user_key[MAX_KEY_LENGTH];
|
||||
int error;
|
||||
|
@ -4219,8 +4234,8 @@ static bool update_user_table_password(THD *thd, const User_table& user_table,
|
|||
|
||||
TABLE *table= user_table.table();
|
||||
table->use_all_columns();
|
||||
user_table.set_host(user->host.hostname, user->hostname_length);
|
||||
user_table.set_user(user->user.str, user->user.length);
|
||||
user_table.set_host(user.host.hostname, user.hostname_length);
|
||||
user_table.set_user(user.user.str, user.user.length);
|
||||
key_copy((uchar *) user_key, table->record[0], table->key_info,
|
||||
table->key_info->key_length);
|
||||
|
||||
|
@ -4234,7 +4249,7 @@ static bool update_user_table_password(THD *thd, const User_table& user_table,
|
|||
}
|
||||
store_record(table, record[1]);
|
||||
|
||||
if (user_table.set_auth(*user))
|
||||
if (user_table.set_auth(user))
|
||||
{
|
||||
my_error(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE, MYF(0),
|
||||
user_table.name().str, 3, user_table.num_fields(),
|
||||
|
@ -4242,10 +4257,8 @@ static bool update_user_table_password(THD *thd, const User_table& user_table,
|
|||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
/* Update the persistent password expired state of user */
|
||||
user_table.set_password_expired(false);
|
||||
my_time_t now= thd->query_start();
|
||||
int rv= user_table.set_password_last_changed(now);
|
||||
user_table.set_password_expired(user.password_expired);
|
||||
user_table.set_password_last_changed(user.password_last_changed);
|
||||
|
||||
if (unlikely(error= table->file->ha_update_row(table->record[1],
|
||||
table->record[0])) &&
|
||||
|
@ -4255,16 +4268,6 @@ static bool update_user_table_password(THD *thd, const User_table& user_table,
|
|||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
/* Update the acl password expired state of user */
|
||||
if (!rv)
|
||||
user->password_last_changed= now;
|
||||
user->password_expired= false;
|
||||
|
||||
/* If user is the connected user, reset the password expired field on sctx
|
||||
and allow the user to exit sandbox mode */
|
||||
if (thd->security_ctx->is_priv_user(user->user.str, user->host.hostname))
|
||||
thd->security_ctx->password_expired= false;
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -4368,9 +4371,9 @@ static int replace_user_table(THD *thd, const User_table &user_table,
|
|||
combo->auth= &auth_no_password;
|
||||
|
||||
old_row_exists = 0;
|
||||
restore_record(table,s->default_values);
|
||||
user_table.set_host(combo->host.str,combo->host.length);
|
||||
user_table.set_user(combo->user.str,combo->user.length);
|
||||
restore_record(table, s->default_values);
|
||||
user_table.set_host(combo->host.str, combo->host.length);
|
||||
user_table.set_user(combo->user.str, combo->user.length);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4482,44 +4485,12 @@ static int replace_user_table(THD *thd, const User_table &user_table,
|
|||
if (lex->account_options.account_locked != ACCOUNTLOCK_UNSPECIFIED)
|
||||
user_table.set_account_locked(new_acl_user.account_locked);
|
||||
|
||||
my_time_t now= thd->query_start();
|
||||
if (!old_row_exists)
|
||||
if (nauth)
|
||||
user_table.set_password_last_changed(new_acl_user.password_last_changed);
|
||||
if (lex->account_options.password_expire != PASSWORD_EXPIRE_UNSPECIFIED)
|
||||
{
|
||||
if (!user_table.set_password_last_changed(now))
|
||||
new_acl_user.password_last_changed= now;
|
||||
if (!user_table.set_password_lifetime(-1))
|
||||
new_acl_user.password_lifetime= -1;
|
||||
}
|
||||
|
||||
/* Unexpire the user password */
|
||||
if (combo->is_changing_password)
|
||||
{
|
||||
user_table.set_password_expired(false);
|
||||
new_acl_user.password_expired= false;
|
||||
if (user_table.set_password_last_changed(now))
|
||||
new_acl_user.password_last_changed= now;
|
||||
}
|
||||
|
||||
switch (lex->account_options.password_expire) {
|
||||
case PASSWORD_EXPIRE_UNSPECIFIED:
|
||||
break;
|
||||
case PASSWORD_EXPIRE_NOW:
|
||||
user_table.set_password_expired(true);
|
||||
new_acl_user.password_expired= true;
|
||||
break;
|
||||
case PASSWORD_EXPIRE_NEVER:
|
||||
if (!user_table.set_password_lifetime(0))
|
||||
new_acl_user.password_lifetime= 0;
|
||||
break;
|
||||
case PASSWORD_EXPIRE_DEFAULT:
|
||||
if (!user_table.set_password_lifetime(-1))
|
||||
new_acl_user.password_lifetime= -1;
|
||||
break;
|
||||
case PASSWORD_EXPIRE_INTERVAL:
|
||||
longlong interval= lex->account_options.num_expiration_days;
|
||||
if (!user_table.set_password_lifetime(interval))
|
||||
new_acl_user.password_lifetime= interval;
|
||||
break;
|
||||
user_table.set_password_lifetime(new_acl_user.password_lifetime);
|
||||
user_table.set_password_expired(new_acl_user.password_expired);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8984,9 +8955,7 @@ bool mysql_show_create_user(THD *thd, LEX_USER *lex_user)
|
|||
else if (acl_user->password_lifetime > 0)
|
||||
{
|
||||
result.append(STRING_WITH_LEN(" PASSWORD EXPIRE INTERVAL "));
|
||||
char days[MAX_BIGINT_WIDTH + 1];
|
||||
my_snprintf(days, sizeof(days), "%lu", acl_user->password_lifetime);
|
||||
result.append(days);
|
||||
result.append_longlong(acl_user->password_lifetime);
|
||||
result.append(STRING_WITH_LEN(" DAY"));
|
||||
}
|
||||
|
||||
|
@ -13627,14 +13596,14 @@ static void handle_password_errors(const char *user, const char *hostname, PASSW
|
|||
#endif
|
||||
}
|
||||
|
||||
bool check_password_lifetime(THD *thd, const ACL_USER *acl_user)
|
||||
static bool check_password_lifetime(THD *thd, const ACL_USER &acl_user)
|
||||
{
|
||||
/* the password should never expire */
|
||||
if (!acl_user->password_lifetime)
|
||||
if (!acl_user.password_lifetime)
|
||||
return false;
|
||||
|
||||
longlong interval= acl_user->password_lifetime;
|
||||
if (acl_user->password_lifetime < 0)
|
||||
longlong interval= acl_user.password_lifetime;
|
||||
if (interval < 0)
|
||||
{
|
||||
interval= default_password_lifetime;
|
||||
|
||||
|
@ -13644,12 +13613,8 @@ bool check_password_lifetime(THD *thd, const ACL_USER *acl_user)
|
|||
}
|
||||
|
||||
thd->set_time();
|
||||
longlong interval_sec= 3600 * 24 * interval;
|
||||
|
||||
/* this helps test set a testable password lifetime in seconds not days */
|
||||
DBUG_EXECUTE_IF("password_expiration_interval_sec", { interval_sec= interval; });
|
||||
|
||||
if (thd->query_start() - acl_user->password_last_changed > interval_sec)
|
||||
if ((thd->query_start() - acl_user.password_last_changed)/3600/24 >= interval)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -13878,18 +13843,18 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len)
|
|||
|
||||
bool client_can_handle_exp_pass= thd->client_capabilities &
|
||||
CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS;
|
||||
bool password_lifetime_due= check_password_lifetime(thd, acl_user);
|
||||
bool password_expired= acl_user->password_expired ||
|
||||
check_password_lifetime(thd, *acl_user);
|
||||
|
||||
if (!client_can_handle_exp_pass && disconnect_on_expired_password &&
|
||||
(acl_user->password_expired || password_lifetime_due))
|
||||
password_expired)
|
||||
{
|
||||
status_var_increment(denied_connections);
|
||||
my_error(ER_MUST_CHANGE_PASSWORD_LOGIN, MYF(0));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
sctx->password_expired= acl_user->password_expired ||
|
||||
password_lifetime_due;
|
||||
sctx->password_expired= password_expired;
|
||||
|
||||
/*
|
||||
Don't allow the user to connect if he has done too many queries.
|
||||
|
|
|
@ -2955,14 +2955,14 @@ public:
|
|||
|
||||
enum account_lock_type
|
||||
{
|
||||
ACCOUNTLOCK_UNSPECIFIED,
|
||||
ACCOUNTLOCK_UNSPECIFIED= 0,
|
||||
ACCOUNTLOCK_LOCKED,
|
||||
ACCOUNTLOCK_UNLOCKED
|
||||
};
|
||||
|
||||
enum password_exp_type
|
||||
{
|
||||
PASSWORD_EXPIRE_UNSPECIFIED,
|
||||
PASSWORD_EXPIRE_UNSPECIFIED= 0,
|
||||
PASSWORD_EXPIRE_NOW,
|
||||
PASSWORD_EXPIRE_NEVER,
|
||||
PASSWORD_EXPIRE_DEFAULT,
|
||||
|
@ -2971,11 +2971,7 @@ enum password_exp_type
|
|||
|
||||
struct Account_options: public USER_RESOURCES
|
||||
{
|
||||
Account_options()
|
||||
: account_locked(ACCOUNTLOCK_UNSPECIFIED)
|
||||
, password_expire(PASSWORD_EXPIRE_UNSPECIFIED)
|
||||
, num_expiration_days(0)
|
||||
{ }
|
||||
Account_options() { }
|
||||
|
||||
void reset()
|
||||
{
|
||||
|
|
|
@ -8061,17 +8061,9 @@ opt_password_expiration:
|
|||
}
|
||||
| PASSWORD_SYM EXPIRE_SYM INTERVAL_SYM NUM DAY_SYM
|
||||
{
|
||||
int error;
|
||||
longlong interval= my_strtoll10($4.str, (char**) 0, &error);
|
||||
if (!interval)
|
||||
{
|
||||
char num[MAX_BIGINT_WIDTH + 1];
|
||||
my_snprintf(num, sizeof(num), "%lu", interval);
|
||||
my_yyabort_error((ER_WRONG_VALUE, MYF(0), "DAY", num));
|
||||
}
|
||||
|
||||
Lex->account_options.password_expire= PASSWORD_EXPIRE_INTERVAL;
|
||||
Lex->account_options.num_expiration_days= interval;
|
||||
if (!(Lex->account_options.num_expiration_days= atoi($4.str)))
|
||||
my_yyabort_error((ER_WRONG_VALUE, MYF(0), "DAY", $4.str));
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -17300,25 +17292,21 @@ grant_user:
|
|||
$$= $1;
|
||||
$1->auth= new (thd->mem_root) USER_AUTH();
|
||||
$1->auth->pwtext= $4;
|
||||
$1->is_changing_password= true;
|
||||
}
|
||||
| user IDENTIFIED_SYM BY PASSWORD_SYM TEXT_STRING
|
||||
{
|
||||
$$= $1;
|
||||
$1->auth= new (thd->mem_root) USER_AUTH();
|
||||
$1->auth->auth_str= $5;
|
||||
$1->is_changing_password= true;
|
||||
}
|
||||
| user IDENTIFIED_SYM via_or_with auth_expression
|
||||
{
|
||||
$$= $1;
|
||||
$1->auth= $4;
|
||||
$1->is_changing_password= false;
|
||||
}
|
||||
| user_or_role
|
||||
{
|
||||
$$= $1;
|
||||
$1->is_changing_password= false;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
@ -8091,17 +8091,9 @@ opt_password_expiration:
|
|||
}
|
||||
| PASSWORD_SYM EXPIRE_SYM INTERVAL_SYM NUM DAY_SYM
|
||||
{
|
||||
int error;
|
||||
longlong interval= my_strtoll10($4.str, (char**) 0, &error);
|
||||
if (!interval)
|
||||
{
|
||||
char num[MAX_BIGINT_WIDTH + 1];
|
||||
my_snprintf(num, sizeof(num), "%lu", interval);
|
||||
my_yyabort_error((ER_WRONG_VALUE, MYF(0), "DAY", num));
|
||||
}
|
||||
|
||||
Lex->account_options.password_expire= PASSWORD_EXPIRE_INTERVAL;
|
||||
Lex->account_options.num_expiration_days= interval;
|
||||
if (!(Lex->account_options.num_expiration_days= atoi($4.str)))
|
||||
my_yyabort_error((ER_WRONG_VALUE, MYF(0), "DAY", $4.str));
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -17438,25 +17430,21 @@ grant_user:
|
|||
$$= $1;
|
||||
$1->auth= new (thd->mem_root) USER_AUTH();
|
||||
$1->auth->pwtext= $4;
|
||||
$1->is_changing_password= true;
|
||||
}
|
||||
| user IDENTIFIED_SYM BY PASSWORD_SYM TEXT_STRING
|
||||
{
|
||||
$$= $1;
|
||||
$1->auth= new (thd->mem_root) USER_AUTH();
|
||||
$1->auth->auth_str= $5;
|
||||
$1->is_changing_password= true;
|
||||
}
|
||||
| user IDENTIFIED_SYM via_or_with auth_expression
|
||||
{
|
||||
$$= $1;
|
||||
$1->auth= $4;
|
||||
$1->is_changing_password= false;
|
||||
}
|
||||
| user_or_role
|
||||
{
|
||||
$$= $1;
|
||||
$1->is_changing_password= false;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
@ -255,7 +255,6 @@ struct AUTHID
|
|||
struct LEX_USER: public AUTHID
|
||||
{
|
||||
USER_AUTH *auth;
|
||||
bool is_changing_password;
|
||||
bool has_auth()
|
||||
{
|
||||
return auth && (auth->plugin.length || auth->auth_str.length || auth->pwtext.length);
|
||||
|
|
|
@ -1517,7 +1517,7 @@ static Sys_var_ulong Sys_max_connections(
|
|||
DEFAULT(MAX_CONNECTIONS_DEFAULT), BLOCK_SIZE(1), NO_MUTEX_GUARD,
|
||||
NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(fix_max_connections));
|
||||
|
||||
static Sys_var_ulong Sys_default_password_lifetime(
|
||||
static Sys_var_uint Sys_default_password_lifetime(
|
||||
"default_password_lifetime",
|
||||
"This defines the global password expiration policy. 0 means "
|
||||
"automatic password expiration is disabled. If the value is a "
|
||||
|
|
Loading…
Reference in a new issue