6.2.3 授权 table
mysql
系统数据库包括几个授权 table,这些 table 包含有关用户帐户及其所拥有特权的信息。本节介绍这些 table。有关系统数据库中其他 table 的信息,请参见第 5.3 节“ mysql 系统数据库”。
这里的讨论描述了授权 table 的底层结构,以及服务器在与 Client 端交互时如何使用其内容。但是,通常您不直接修改授予 table。当您使用诸如CREATE USER,GRANT和REVOKE之类的帐户 Management 语句来设置帐户并控制每个帐户的可用特权时,会间接进行修改。参见第 13.7.1 节“帐户 Management 对帐单”。当您使用此类语句执行帐户操作时,服务器会代 table 您修改授权 table。
Note
不建议使用INSERT,UPDATE或DELETE之类的语句直接修改授权 table,风险自负。服务器可以随意忽略由于此类修改而导致格式错误的行。
从 MySQL 5.7.18 开始,对于任何修改授权 table 的操作,服务器都会检查该 table 是否具有预期的结构,如果没有,则会产生错误。要将 table 更新为预期的结构,请执行 MySQL 升级过程。参见第 2.11 节“升级 MySQL”。
赠款 table 概述
这些mysql
数据库 table 包含授权信息:
- user:用户帐户,全局特权和其他非特权列。
- db:数据库级特权。
- tables_priv:table 级特权。
- columns_priv:列级特权。
- procs_priv:存储过程和函数特权。
- proxies_priv:代理用户权限。
每个授权 table 都包含作用域列和特权列:
-
范围列确定 table 中每一行的范围;也就是说,该行适用的上下文。例如,具有
Host
和User
值'h1.example.net'
和'bob'
的user
table 行适用于认证指定用户名bob
的 Client 端从主机h1.example.net
到服务器的连接。同样,当bob
从主机h1.example.net
连接访问reports
数据库时,将应用db
table 行,其中Host
,User
和Db
列值为'h1.example.net'
,'bob'
和'reports'
。tables_priv
和columns_priv
table 包含作用域列,这些作用域列指示每行适用的 table 或 table/列组合。procs_priv
范围列指示每行适用的存储例程。 -
特权列指示 table 行授予哪些特权;也就是说,它允许执行哪些操作。服务器将信息组合在各种授权 table 中,以形成用户特权的完整描述。 第 6.2.6 节“访问控制,第 2 阶段:请求验证”,描述了此规则。
此外,授予 table 可能包含用于范围或特权评估以外的目的的列。
服务器以以下方式使用授权 table:
user
table 作用域列确定是拒绝还是允许传入连接。对于允许的连接,在user
table 中授予的任何特权都 table 示用户的全局特权。该 table 中授予的所有特权都适用于服务器上的* all *数据库。
Caution
因为全局特权被视为所有数据库的特权,所以* any *全局特权使用户可以使用SHOW DATABASES或通过检查INFORMATION_SCHEMA
SCHEMATAtable 来查看所有数据库名称。
-
db
table 作用域列确定哪些用户可以从哪些主机访问哪些数据库。特权列确定允许的操作。在数据库级别授予的特权适用于数据库以及数据库中的所有对象,例如 table 和存储的程序。 -
tables_priv
和columns_priv
table 与db
table 类似,但更细粒度:它们适用于 table 和列级别,而不是数据库级别。在 table 级别授予的特权适用于该 table 及其所有列。在列级别授予的特权仅适用于特定列。 -
procs_priv
table 适用于存储的例程(存储的过程和函数)。在例程级别授予的特权仅适用于单个过程或函数。 -
proxies_priv
table 指示哪些用户可以充当其他用户的代理,以及该用户是否可以向其他用户授予PROXY特权。
服务器启动时会将授权 table 的内容读入内存。您可以通过发出FLUSH PRIVILEGES语句或执行mysqladmin flush-privileges或mysqladmin reload命令来告诉它重新加载 table。如第 6.2.9 节“特权更改何时生效”所示,对授予 table 的更改将生效。
修改帐户时,最好确认更改是否达到预期效果。要检查给定帐户的特权,请使用SHOW GRANTS语句。例如,要确定授予用户名和主机名值为bob
和pc84.example.com
的帐户的特权,请使用以下语句:
SHOW GRANTS FOR 'bob'@'pc84.example.com';
要显示帐户的非特权属性,请使用显示创建用户:
SHOW CREATE USER 'bob'@'pc84.example.com';
用户和数据库授权 table
服务器在访问控制的第一阶段和第二阶段都使用mysql
数据库中的user
和db
table(请参见第 6.2 节“访问控制和帐户 Management”)。此处显示user
和db
table 中的列。
table6.3 用户和数据库 table 列
Table Name | user | db |
---|---|---|
Scope columns | Host | Host |
User | Db | |
User | ||
Privilege columns | Select_priv | Select_priv |
Insert_priv | Insert_priv | |
Update_priv | Update_priv | |
Delete_priv | Delete_priv | |
Index_priv | Index_priv | |
Alter_priv | Alter_priv | |
Create_priv | Create_priv | |
Drop_priv | Drop_priv | |
Grant_priv | Grant_priv | |
Create_view_priv | Create_view_priv | |
Show_view_priv | Show_view_priv | |
Create_routine_priv | Create_routine_priv | |
Alter_routine_priv | Alter_routine_priv | |
Execute_priv | Execute_priv | |
Trigger_priv | Trigger_priv | |
Event_priv | Event_priv | |
Create_tmp_table_priv | Create_tmp_table_priv | |
Lock_tables_priv | Lock_tables_priv | |
References_priv | References_priv | |
Reload_priv | ||
Shutdown_priv | ||
Process_priv | ||
File_priv | ||
Show_db_priv | ||
Super_priv | ||
Repl_slave_priv | ||
Repl_client_priv | ||
Create_user_priv | ||
Create_tablespace_priv | ||
Security columns | ssl_type | |
ssl_cipher | ||
x509_issuer | ||
x509_subject | ||
plugin | ||
authentication_string | ||
password_expired | ||
password_last_changed | ||
password_lifetime | ||
account_locked | ||
资源控制列 | max_questions | |
max_updates | ||
max_connections | ||
max_user_connections |
user
tableplugin
和authentication_string
列存储身份验证插件和凭据信息。
服务器使用帐户行的plugin
列中命名的插件来验证帐户的连接尝试。
plugin
列必须为非空。在启动时以及在运行时执行FLUSH PRIVILEGES时,服务器将检查user
个 table 行。对于plugin
列为空的任何行,服务器都会向此格式的错误日志中写入警告:
[Warning] User entry 'user_name'@'host_name' has an empty plugin
value. The user will be ignored and no one can login with this user
anymore.
要解决此问题,请参阅第 6.4.1.3 节“迁移到 4.1 版之前的密码哈希和 mysql_old_password 插件”。
password_expired
列允许 DBA 终止帐户密码,并要求用户重置其密码。 password_expired
的默认值为'N'
,但可以使用ALTER USER语句设置为'Y'
。帐户密码到期后,该帐户在与服务器的后续 Connecting 执行的所有操作都会导致错误,直到用户发出ALTER USER语句以构建新的帐户密码为止。
Note
尽管可以通过将过期的密码设置为当前值来“重置”它,但出于良好的 Policy 考虑,最好选择其他密码。
password_last_changed
是TIMESTAMP
列,指示上次更改密码的时间。仅对于使用 MySQL 内置身份验证方法的帐户(使用mysql_native_password
或sha256_password
身份验证插件的帐户),该值不是NULL
。对于其他帐户,例如使用外部身份验证系统进行身份验证的帐户,该值为NULL
。
password_last_changed
由CREATE USER,ALTER USER和SET PASSWORD语句以及由GRANT语句创建帐户或更改帐户密码的更新。
password_lifetime
table 示帐户密码的有效期限,以天为单位。如果密码已过期(使用password_last_changed
列进行评估),则当 Client 端使用该帐户连接时,服务器认为密码已过期。 * N
的值大于零 table 示密码必须每 N
*天更改一次。值为 0 将禁用自动密码过期。如果值为NULL
(默认值),则应用全局失效策略,如default_password_lifetime系统变量所定义。
account_locked
指示该帐户是否被锁定(请参阅第 6.2.15 节“锁定帐户”)。
tables_priv 和 columns_priv 授权 table
在访问控制的第二阶段,服务器执行请求验证,以确保每个 Client 端对其发出的每个请求都具有足够的特权。除了user
和db
授予 table 之外,服务器还可以查询tables_priv
和columns_priv
table 以获取涉及 table 的请求。后面的 table 在 table 和列级别提供了更好的特权控制。它们具有下 table 中显示的列。
table6.4tables_priv 和 columns_privtable 列
Table Name | tables_priv | columns_priv |
---|---|---|
Scope columns | Host | Host |
Db | Db | |
User | User | |
Table_name | Table_name | |
Column_name | ||
Privilege columns | Table_priv | Column_priv |
Column_priv | ||
Other columns | Timestamp | Timestamp |
Grantor |
Timestamp
和Grantor
列分别设置为当前时间戳和CURRENT_USER值,但未使用。
procs_priv 授权 table
为了验证涉及存储例程的请求,服务器可以查询procs_priv
table,该 table 具有下 table 中显示的列。
table6.5 procs_privtable 列
Table Name | procs_priv |
---|---|
Scope columns | Host |
Db | |
User | |
Routine_name | |
Routine_type | |
Privilege columns | Proc_priv |
Other columns | Timestamp |
Grantor |
Routine_type
列是ENUM列,其值为'FUNCTION'
或'PROCEDURE'
来指示该行引用的例程的类型。该列使具有相同名称的函数和过程的特权可以分别授予。
Timestamp
和Grantor
列未使用。
proxies_priv 授权 table
proxies_priv
table 记录有关代理帐户的信息。它具有以下列:
-
Host
,User
:代理帐户;也就是说,具有PROXY特权的代理帐户。 -
Proxied_host
,Proxied_user
:代理帐户。 -
Grantor
,Timestamp
:未使用。 -
With_grant
:代理帐户是否可以向其他帐户授予PROXY特权。
为了使一个帐户能够向其他帐户授予PROXY特权,它必须在proxies_priv
table 中具有With_grant
设置为 1 且Proxied_host
和Proxied_user
设置为一行的行,以指示可以为其授予特权的一个或多个帐户。例如,在 MySQL 安装过程中创建的'root'@'localhost'
帐户在proxies_priv
table 中具有一行,该行允许授予''@''
(即所有用户和所有主机)的PROXY特权。这使root
可以设置代理用户,以及将设置代理用户的权限委托给其他帐户。参见第 6.2.14 节“代理用户”。
授予 table 作用域列属性
授权 table 中的范围列包含字符串。每个的默认值是空字符串。下 table 显示了每一列中允许的字符数。
table6.6 授予 table 范围列长度
Column Name | 允许的最大字符数 |
---|---|
Host , Proxied_host | 60 |
User , Proxied_user | 32 |
Password | 41 |
Db | 64 |
Table_name | 64 |
Column_name | 64 |
Routine_name | 64 |
Host
和Proxied_host
值在存储在授权 table 中之前已转换为小写。
出于访问检查的目的,User
,Proxied_user
,Password
,authentication_string
,Db
和Table_name
值的比较区分大小写。 Host
,Proxied_host
,Column_name
和Routine_name
值的比较不区分大小写。
授予 table 权限列属性
user
和db
table 在声明为ENUM('N','Y') DEFAULT 'N'
的单独列中列出了每个特权。换句话说,可以禁用或启用每个特权,默认状态为禁用。
tables_priv
,columns_priv
和procs_priv
table 将特权列声明为SET列。这些列中的值可以包含 table 控制的特权的任何组合。仅启用列值中列出的那些特权。
table6.7 Set-Type Privilege 列值
Table Name | Column Name | 可能的设置元素 |
---|---|---|
tables_priv | Table_priv | 'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter', 'Create View', 'Show view', 'Trigger' |
tables_priv | Column_priv | 'Select', 'Insert', 'Update', 'References' |
columns_priv | Column_priv | 'Select', 'Insert', 'Update', 'References' |
procs_priv | Proc_priv | 'Execute', 'Alter Routine', 'Grant' |
仅user
table 指定 Management 特权,例如RELOAD和SHUTDOWN。Management 操作是服务器本身的操作,并且不是特定于数据库的操作,因此没有理由在其他授权 table 中列出这些特权。因此,服务器仅需要查询user
table 来确定用户是否可以执行 Management 操作。
FILE特权也仅在user
table 中指定。它本身不是 Management 特权,但是用户在服务器主机上读取或写入文件的能力与正在访问的数据库无关。