6.2.3 授权 table

mysql系统数据库包括几个授权 table,这些 table 包含有关用户帐户及其所拥有特权的信息。本节介绍这些 table。有关系统数据库中其他 table 的信息,请参见第 5.3 节“ mysql 系统数据库”

这里的讨论描述了授权 table 的底层结构,以及服务器在与 Client 端交互时如何使用其内容。但是,通常您不直接修改授予 table。当您使用诸如CREATE USERGRANTREVOKE之类的帐户 Management 语句来设置帐户并控制每个帐户的可用特权时,会间接进行修改。参见第 13.7.1 节“帐户 Management 对帐单”。当您使用此类语句执行帐户操作时,服务器会代 table 您修改授权 table。

Note

不建议使用INSERTUPDATEDELETE之类的语句直接修改授权 table,风险自负。服务器可以随意忽略由于此类修改而导致格式错误的行。

从 MySQL 5.7.18 开始,对于任何修改授权 table 的操作,服务器都会检查该 table 是否具有预期的结构,如果没有,则会产生错误。要将 table 更新为预期的结构,请执行 MySQL 升级过程。参见第 2.11 节“升级 MySQL”

赠款 table 概述

这些mysql数据库 table 包含授权信息:

  • user:用户帐户,全局特权和其他非特权列。

  • db:数据库级特权。

每个授权 table 都包含作用域列和特权列:

  • 范围列确定 table 中每一行的范围;也就是说,该行适用的上下文。例如,具有HostUser'h1.example.net''bob'usertable 行适用于认证指定用户名bob的 Client 端从主机h1.example.net到服务器的连接。同样,当bob从主机h1.example.net连接访问reports数据库时,将应用dbtable 行,其中HostUserDb列值为'h1.example.net''bob''reports'tables_privcolumns_privtable 包含作用域列,这些作用域列指示每行适用的 table 或 table/列组合。 procs_priv范围列指示每行适用的存储例程。

  • 特权列指示 table 行授予哪些特权;也就是说,它允许执行哪些操作。服务器将信息组合在各种授权 table 中,以形成用户特权的完整描述。 第 6.2.6 节“访问控制,第 2 阶段:请求验证”,描述了此规则。

此外,授予 table 可能包含用于范围或特权评估以外的目的的列。

服务器以以下方式使用授权 table:

  • usertable 作用域列确定是拒绝还是允许传入连接。对于允许的连接,在usertable 中授予的任何特权都 table 示用户的全局特权。该 table 中授予的所有特权都适用于服务器上的* all *数据库。

Caution

因为全局特权被视为所有数据库的特权,所以* any *全局特权使用户可以使用SHOW DATABASES或通过检查INFORMATION_SCHEMA SCHEMATAtable 来查看所有数据库名称。

  • dbtable 作用域列确定哪些用户可以从哪些主机访问哪些数据库。特权列确定允许的操作。在数据库级别授予的特权适用于数据库以及数据库中的所有对象,例如 table 和存储的程序。

  • tables_privcolumns_privtable 与dbtable 类似,但更细粒度:它们适用于 table 和列级别,而不是数据库级别。在 table 级别授予的特权适用于该 table 及其所有列。在列级别授予的特权仅适用于特定列。

  • procs_privtable 适用于存储的例程(存储的过程和函数)。在例程级别授予的特权仅适用于单个过程或函数。

  • proxies_privtable 指示哪些用户可以充当其他用户的代理,以及该用户是否可以向其他用户授予PROXY特权。

服务器启动时会将授权 table 的内容读入内存。您可以通过发出FLUSH PRIVILEGES语句或执行mysqladmin flush-privilegesmysqladmin reload命令来告诉它重新加载 table。如第 6.2.9 节“特权更改何时生效”所示,对授予 table 的更改将生效。

修改帐户时,最好确认更改是否达到预期效果。要检查给定帐户的特权,请使用SHOW GRANTS语句。例如,要确定授予用户名和主机名值为bobpc84.example.com的帐户的特权,请使用以下语句:

SHOW GRANTS FOR 'bob'@'pc84.example.com';

要显示帐户的非特权属性,请使用显示创建用户

SHOW CREATE USER 'bob'@'pc84.example.com';

用户和数据库授权 table

服务器在访问控制的第一阶段和第二阶段都使用mysql数据库中的userdbtable(请参见第 6.2 节“访问控制和帐户 Management”)。此处显示userdbtable 中的列。

table6.3 用户和数据库 table 列

Table Nameuserdb
Scope columnsHostHost
UserDb
User
Privilege columnsSelect_privSelect_priv
Insert_privInsert_priv
Update_privUpdate_priv
Delete_privDelete_priv
Index_privIndex_priv
Alter_privAlter_priv
Create_privCreate_priv
Drop_privDrop_priv
Grant_privGrant_priv
Create_view_privCreate_view_priv
Show_view_privShow_view_priv
Create_routine_privCreate_routine_priv
Alter_routine_privAlter_routine_priv
Execute_privExecute_priv
Trigger_privTrigger_priv
Event_privEvent_priv
Create_tmp_table_privCreate_tmp_table_priv
Lock_tables_privLock_tables_priv
References_privReferences_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 columnsssl_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

usertablepluginauthentication_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_changedTIMESTAMP列,指示上次更改密码的时间。仅对于使用 MySQL 内置身份验证方法的帐户(使用mysql_native_passwordsha256_password身份验证插件的帐户),该值不是NULL。对于其他帐户,例如使用外部身份验证系统进行身份验证的帐户,该值为NULL

password_last_changedCREATE USERALTER USERSET PASSWORD语句以及由GRANT语句创建帐户或更改帐户密码的更新。

password_lifetimetable 示帐户密码的有效期限,以天为单位。如果密码已过期(使用password_last_changed列进行评估),则当 Client 端使用该帐户连接时,服务器认为密码已过期。 * N 的值大于零 table 示密码必须每 N *天更改一次。值为 0 将禁用自动密码过期。如果值为NULL(默认值),则应用全局失效策略,如default_password_lifetime系统变量所定义。

account_locked指示该帐户是否被锁定(请参阅第 6.2.15 节“锁定帐户”)。

tables_priv 和 columns_priv 授权 table

在访问控制的第二阶段,服务器执行请求验证,以确保每个 Client 端对其发出的每个请求都具有足够的特权。除了userdb授予 table 之外,服务器还可以查询tables_privcolumns_privtable 以获取涉及 table 的请求。后面的 table 在 table 和列级别提供了更好的特权控制。它们具有下 table 中显示的列。

table6.4tables_priv 和 columns_privtable 列

Table Nametables_privcolumns_priv
Scope columnsHostHost
DbDb
UserUser
Table_nameTable_name
Column_name
Privilege columnsTable_privColumn_priv
Column_priv
Other columnsTimestampTimestamp
Grantor

TimestampGrantor列分别设置为当前时间戳和CURRENT_USER值,但未使用。

procs_priv 授权 table

为了验证涉及存储例程的请求,服务器可以查询procs_privtable,该 table 具有下 table 中显示的列。

table6.5 procs_privtable 列

Table Nameprocs_priv
Scope columnsHost
Db
User
Routine_name
Routine_type
Privilege columnsProc_priv
Other columnsTimestamp
Grantor

Routine_type列是ENUM列,其值为'FUNCTION''PROCEDURE'来指示该行引用的例程的类型。该列使具有相同名称的函数和过程的特权可以分别授予。

TimestampGrantor列未使用。

proxies_priv 授权 table

proxies_privtable 记录有关代理帐户的信息。它具有以下列:

  • HostUser:代理帐户;也就是说,具有PROXY特权的代理帐户。

  • Proxied_hostProxied_user:代理帐户。

  • GrantorTimestamp:未使用。

  • With_grant:代理帐户是否可以向其他帐户授予PROXY特权。

为了使一个帐户能够向其他帐户授予PROXY特权,它必须在proxies_privtable 中具有With_grant设置为 1 且Proxied_hostProxied_user设置为一行的行,以指示可以为其授予特权的一个或多个帐户。例如,在 MySQL 安装过程中创建的'root'@'localhost'帐户在proxies_privtable 中具有一行,该行允许授予''@''(即所有用户和所有主机)的PROXY特权。这使root可以设置代理用户,以及将设置代理用户的权限委托给其他帐户。参见第 6.2.14 节“代理用户”

授予 table 作用域列属性

授权 table 中的范围列包含字符串。每个的默认值是空字符串。下 table 显示了每一列中允许的字符数。

table6.6 授予 table 范围列长度

Column Name允许的最大字符数
Host , Proxied_host60
User , Proxied_user32
Password41
Db64
Table_name64
Column_name64
Routine_name64

HostProxied_host值在存储在授权 table 中之前已转换为小写。

出于访问检查的目的,UserProxied_userPasswordauthentication_stringDbTable_name值的比较区分大小写。 HostProxied_hostColumn_nameRoutine_name值的比较不区分大小写。

授予 table 权限列属性

userdbtable 在声明为ENUM('N','Y') DEFAULT 'N'的单独列中列出了每个特权。换句话说,可以禁用或启用每个特权,默认状态为禁用。

tables_privcolumns_privprocs_privtable 将特权列声明为SET列。这些列中的值可以包含 table 控制的特权的任何组合。仅启用列值中列出的那些特权。

table6.7 Set-Type Privilege 列值

Table NameColumn Name可能的设置元素
tables_privTable_priv'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter', 'Create View', 'Show view', 'Trigger'
tables_privColumn_priv'Select', 'Insert', 'Update', 'References'
columns_privColumn_priv'Select', 'Insert', 'Update', 'References'
procs_privProc_priv'Execute', 'Alter Routine', 'Grant'

usertable 指定 Management 特权,例如RELOADSHUTDOWN。Management 操作是服务器本身的操作,并且不是特定于数据库的操作,因此没有理由在其他授权 table 中列出这些特权。因此,服务器仅需要查询usertable 来确定用户是否可以执行 Management 操作。

FILE特权也仅在usertable 中指定。它本身不是 Management 特权,但是用户在服务器主机上读取或写入文件的能力与正在访问的数据库无关。