MySQL 5.6 引入了密码过期功能,使数据库管理员能够要求用户重置密码。紧随其后的讨论描述了当前密码过期的工作原理。稍后,将详细介绍此功能的开发,因为它发生在多个版本中,作为帮助您了解什么功能可用的背景。但是,为确保您可以利用所有功能,请尽可能使用最新版本的 MySQL。
该ALTER USER
语句启用帐户密码过期。例如:
ALTER USER 'myuser'@'localhost' PASSWORD EXPIRE;
对于使用密码过期帐户的每个连接,服务器要么断开客户端连接,要么将客户端限制为“沙盒模式”,在该模式下,服务器只允许客户端执行重置过期密码所需的操作。服务器采取何种操作取决于客户端和服务器设置,如后所述。
如果服务器断开客户端连接,它会返回一个
ER_MUST_CHANGE_PASSWORD_LOGIN
错误:
$> mysql -u myuser -p
Password: ******
ERROR 1862 (HY000): Your password has expired. To log in you must
change it using a client that supports expired passwords.
如果服务器将客户端限制为沙盒模式,则在客户端会话中允许执行以下操作:
客户端可以通过 重置账户密码
SET PASSWORD
。完成后,服务器恢复会话的正常访问,以及使用该帐户的后续连接。笔记虽然可以通过将过期的密码设置为当前值来“重置”该密码,但作为一种好的策略,最好选择一个不同的密码。
客户端可以使用该
SET
语句。 如果帐户使用身份验证插件,则必须首先将系统变量设置为非默认值才能以特定方式执行密码散列, 这在使用SET PASSWORD
重置密码之前可能是必要 的。old_passwords
对于会话中不允许的任何操作,服务器返回
ER_MUST_CHANGE_PASSWORD
错误:
mysql> USE performance_schema;
ERROR 1820 (HY000): You must SET PASSWORD before executing this statement
mysql> SELECT 1;
ERROR 1820 (HY000): You must SET PASSWORD before executing this statement
这是 mysql客户端的交互式调用通常发生的情况,因为默认情况下此类调用处于沙盒模式。要恢复正常功能,请选择一个新密码。
对于mysql
客户端的非交互式调用(例如,在批处理模式下),如果密码过期,服务器通常会断开客户端连接。要允许非交互式mysql调用保持连接以便可以更改密码(使用沙盒模式中允许的语句),请将
--connect-expired-password
选项添加到mysql命令。
如前所述,服务器是断开密码过期客户端的连接还是将其限制为沙盒模式取决于客户端和服务器设置的组合。以下讨论描述了相关设置以及它们如何交互。
此讨论仅适用于密码过期的帐户。如果客户端使用未过期的密码进行连接,则服务器会正常处理客户端。
在客户端,给定的客户端指示它是否可以处理过期密码的沙箱模式。对于使用 C 客户端库的客户端,有两种方法可以做到这一点:
在连接之前 将
MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS
标志 传递 给:mysql_options()
my_bool arg = 1; mysql_options(mysql, MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, &arg);
这是在 mysql客户端中 使用的技术,
MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS
如果以交互方式调用或使用--connect-expired-password
选项,则启用该技术。在连接时 将
CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS
标志 传递 给:mysql_real_connect()
MYSQL mysql; mysql_init(&mysql); if (!mysql_real_connect(&mysql, host, user, password, db, port, unix_socket, CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS)) { ... handle error ... }
其他 MySQL 连接器有自己的约定来指示准备好处理沙盒模式。请参阅您感兴趣的连接器的文档。
在服务器端,如果客户端指示它可以处理过期密码,则服务器会将其置于沙盒模式。
如果客户端未指示它可以处理过期密码(或使用无法指示的旧版本客户端库),则服务器操作取决于
disconnect_on_expired_password
系统变量的值:
如果
disconnect_on_expired_password
启用(默认),服务器将断开与客户端的连接并ER_MUST_CHANGE_PASSWORD_LOGIN
出错。如果
disconnect_on_expired_password
禁用,服务器会将客户端置于沙盒模式。
以下时间线描述了添加各种密码过期功能的版本。
MySQL 5.6.6:密码过期的初始实现。
在系统表中引入该
password_expired
列是mysql.user
为了使 DBA 能够使帐户密码过期。列默认值为'N'
(未过期)。该语句作为用于将列
ALTER USER ... PASSWORD EXPIRE
设置为的 SQL 接口引入 。password_expired
'Y'
使用密码过期帐户的连接进入“沙盒模式”,只允许
SET PASSWORD
语句。对于其他语句,服务器返回ER_MUST_CHANGE_PASSWORD
错误。目的是强制客户端在服务器允许任何其他操作之前重置密码。SET PASSWORD
重置帐户密码并设置password_expired
为'N'
。初始实现中的一个错误是 将系统表中的列
ALTER USER
设置 为空字符串。言下之意,用户要等到MySQL 5.6.7才能使用这条语句。Password
mysql.user
MySQL 5.6.7:
ALTER USER
固定为不将Password
列设置为空字符串。MySQL 5.6.8:
ALTER USER
可用作准备语句。mysqladmin 密码能够为使用
mysql_native_password
或mysql_old_password
身份验证插件的帐户重置过期密码。沙盒模式更改为允许客户端执行
SET
语句,此外还SET PASSWORD
禁止SET
需要设置old_passwords
的客户端重置其密码。它还破坏了一些连接器,这些连接器SET
在连接时广泛用于初始化会话环境。MySQL 5.6.9:沙箱模式更改为
SET PASSWORD
仅当语句中指定的帐户与客户端身份验证的帐户匹配时才允许。MySQL 5.6.10:沙盒模式已更改,以允许更好地控制服务器如何处理具有过期密码的帐户的客户端连接,并允许客户端发出它们是否能够处理过期密码的信号:
添加了
disconnect_on_expired_password
系统变量,它控制服务器如何处理过期密码帐户。C API 客户端库中添加了两个标志:
MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS
formysql_options()
和CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS
formysql_real_connect()
。每个标志使客户端程序能够指示它是否可以处理密码过期帐户的沙盒模式。MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS
无条件地 为mysqltest启用,对于交互模式下的mysql , 如果第一个命令是mysqladminpassword
。ER_MUST_CHANGE_PASSWORD_LOGIN
错误已添加 。 服务器在断开密码过期的客户端时返回此错误。MySQL 5.6.12: mysql
--connect-expired-password
客户端 新增选项,允许对密码过期的账户以批处理模式执行密码更改语句。
在对 MySQL 服务器和 C API 客户端库中的沙箱模式进行这些更改的同时,开始修改连接器以符合这些更改。