GRANT — 定义访问特权
GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER | MAINTAIN }
[, ...] | ALL [ PRIVILEGES ] }
ON { [ TABLE ] table_name [, ...]
| ALL TABLES IN SCHEMA schema_name [, ...] }
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( column_name [, ...] )
[, ...] | ALL [ PRIVILEGES ] ( column_name [, ...] ) }
ON [ TABLE ] table_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { { USAGE | SELECT | UPDATE }
[, ...] | ALL [ PRIVILEGES ] }
ON { SEQUENCE sequence_name [, ...]
| ALL SEQUENCES IN SCHEMA schema_name [, ...] }
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] }
ON DATABASE database_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
ON DOMAIN domain_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
ON FOREIGN DATA WRAPPER fdw_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
ON FOREIGN SERVER server_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { EXECUTE | ALL [ PRIVILEGES ] }
ON { { FUNCTION | PROCEDURE | ROUTINE } routine_name [ ( [ [ argmode ] [ arg_name ] arg_type [, ...] ] ) ] [, ...]
| ALL { FUNCTIONS | PROCEDURES | ROUTINES } IN SCHEMA schema_name [, ...] }
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
ON LANGUAGE lang_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] }
ON LARGE OBJECT loid [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { { SET | ALTER SYSTEM } [, ... ] | ALL [ PRIVILEGES ] }
ON PARAMETER configuration_parameter [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }
ON SCHEMA schema_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { CREATE | ALL [ PRIVILEGES ] }
ON TABLESPACE tablespace_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
ON TYPE type_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT role_name [, ...] TO role_specification [, ...]
[ WITH { ADMIN | INHERIT | SET } { OPTION | TRUE | FALSE } ]
[ GRANTED BY role_specification ]
where role_specification can be:
[ GROUP ] role_name
| PUBLIC
| CURRENT_ROLE
| CURRENT_USER
| SESSION_USER
GRANT 命令有两种基本变体:一种授予数据库对象(表、列、视图、外部表、序列、数据库、外部数据封装器、外部服务器、函数、过程、过程语言、大对象、配置参数、模式、表空间或类型)上的特权;另一种授予角色中的成员关系。这些变体在许多方面相似,但差异足以需要分别描述。
GRANT 命令的这种变体把一个数据库对象上的特定特权授予一个或多个角色。这些特权会被追加到已授予的特权(如果有的话)之上。
关键字 PUBLIC 表示特权将被授予所有角色,包括以后可能创建的角色。PUBLIC 可以被视为一个隐式定义的组,它总是包含所有角色。任何特定角色拥有的特权是直接授予它的特权、授予它当前所属角色的特权以及授予 PUBLIC 的特权的总和。
如果指定了 WITH GRANT OPTION,特权的接收者就可以依次把它授予其他人。没有授权选项时,接收者不能这样做。授权选项不能被授予 PUBLIC。
如果指定了 GRANTED BY,指定的授权者必须是当前用户。当前这个子句以这种形式存在只是为了 SQL 兼容性。
不需要把特权授予对象的拥有者(通常是创建它的用户),因为拥有者默认拥有所有特权。(不过,为了安全起见,拥有者可以选择回收自己的一些特权。)
删除对象或者以任何方式修改其定义的权力并不被视为可授予的特权;它是拥有者固有的,不能被授予或回收。(不过,通过授予或回收拥有该对象的角色中的成员关系可以获得类似的效果;见下文。)拥有者也隐式地拥有对该对象的所有授权选项。
可能的特权有:
SELECTINSERTUPDATEDELETETRUNCATEREFERENCESTRIGGERCREATECONNECTTEMPORARYEXECUTEUSAGESETALTER SYSTEMMAINTAIN特定的特权类型,如 Section 5.8 中所定义。
TEMP
TEMPORARY 的另一种拼写。
ALL PRIVILEGES 授予该对象类型可用的所有特权。PRIVILEGES 关键字在 PostgreSQL 中是可选的,尽管严格的 SQL 要求使用它。
FUNCTION 语法适用于普通函数、聚集函数和窗口函数,但不适用于过程;对于过程请使用 PROCEDURE。或者,使用 ROUTINE 来指代函数、聚集函数、窗口函数或过程,而不管其确切类型。
还有一个选项可以授予一个或多个模式内同一类型的所有对象上的特权。目前只有表、序列、函数和过程支持此功能。ALL TABLES 还会影响视图和外部表,就像针对特定对象的 GRANT 命令一样。ALL FUNCTIONS 也会影响聚集函数和窗口函数,但不影响过程,这同样与针对特定对象的 GRANT 命令一致。使用 ALL ROUTINES 可以把过程包括进来。
GRANT 命令的这种变体把一个角色中的成员关系授予一个或多个其他角色,并修改成员关系选项 SET、INHERIT 和 ADMIN;详见 Section 21.3。角色中的成员关系很重要,因为它可能允许角色的每个成员访问授予该角色的特权,还可能允许对该角色本身进行更改。不过,实际赋予的权限取决于与授予相关联的选项。要修改现有成员关系的选项,只需用更新后的选项值指定该成员关系即可。
下面描述的每个选项都可以被设置为 TRUE 或 FALSE。关键字 OPTION 被接受为 TRUE 的同义词,因此 WITH ADMIN OPTION 是 WITH ADMIN TRUE 的同义词。在修改现有成员关系时,省略某个选项会使当前值被保留。
ADMIN 选项允许该成员依次把角色中的成员关系授予其他人,也可以回收该角色中的成员关系。没有 admin 选项时,普通用户不能这样做。一个角色不被认为对其自身持有 WITH ADMIN OPTION。数据库超级用户可以向任何人授予或回收任何角色中的成员关系。这个选项默认为 FALSE。
INHERIT 选项控制新成员关系的继承状态;有关继承的详细信息,请参见 Section 21.3。如果它被设置为 TRUE,新成员将从被授予的角色继承。如果设置为 FALSE,新成员不继承。在创建新的角色成员关系时如果没有指定,则默认为新成员的继承属性。
SET 选项(如果它被设置为 TRUE)允许成员使用 SET ROLE 命令切换到被授予的角色。如果一个角色是另一个角色的间接成员,只有当存在一条每一步都有 SET TRUE 的授予链时,它才能使用 SET ROLE 切换到那个角色。这个选项默认为 TRUE。
要创建由另一个角色拥有的对象,或者把一个现有对象的所有权给予另一个角色,你必须有能力 SET ROLE 到那个角色;否则,诸如 ALTER ... OWNER TO 或 CREATE DATABASE ... OWNER 之类的命令将会失败。不过,一个继承了某角色特权但不具备 SET ROLE 到该角色的能力的用户,也许能够通过操纵该角色拥有的现有对象来获得对该角色的完全访问(例如,他们可以重新定义一个现有函数,使其充当特洛伊木马)。因此,如果一个角色的特权要被继承但不应当能够通过 SET ROLE 访问,那么它就不应该拥有任何 SQL 对象。
如果指定了 GRANTED BY,该授予将被记录为由指定的角色完成。只有当用户拥有另一个角色的特权时,才能把一次授予归于该角色。被记录为授权者的角色必须对目标角色持有 ADMIN OPTION,除非它是引导超级用户。当一次授予被记录为其授权者不是引导超级用户时,它依赖于授权者继续持有该角色的 ADMIN OPTION;因此,如果 ADMIN OPTION 被回收,依赖于它的授予也必须被回收。
与特权的情况不同,角色中的成员关系不能被授予 PUBLIC。还要注意,这种形式的命令不允许把噪声词 GROUP 放在 role_specification 中。
REVOKE 命令用于回收访问特权。
从 PostgreSQL 8.1 开始,用户和组的概念已被统一为一种称为角色的实体。因此不再需要使用关键字 GROUP 来区分被授予者是用户还是组。命令中仍然允许使用 GROUP,但它只是一个噪声词。
如果用户对特定列或其整个表持有某种特权,他们就可以对该列执行 SELECT、INSERT 等操作。在表级别授予特权然后对一列回收它,并不会达到人们可能期望的效果:表级别的授予不受列级别操作的影响。
当对象的非拥有者试图对该对象 GRANT 特权时,如果该用户对该对象毫无特权,命令会直接失败。只要拥有某种特权,命令就会继续执行,但它只会授予用户持有授权选项的那些特权。GRANT ALL PRIVILEGES 形式在没有持有任何授权选项时会发出警告消息,而其他形式则在命令中明确指定的特权中任何一项的授权选项未被持有时发出警告。(原则上这些说法也适用于对象拥有者,但由于拥有者总是被视为持有所有授权选项,这些情况永远不会发生。)
应当注意,数据库超级用户可以访问所有对象,而不受对象特权设置的影响。这可以与 Unix 系统中 root 的权利相类比。与 root 一样,除非绝对必要,以超级用户身份操作是不明智的。
如果超级用户选择发出 GRANT 或 REVOKE 命令,该命令的执行就好像它是由受影响对象的拥有者发出的一样。特别是,通过这种命令授予的特权将显示为由对象拥有者授予。(对于角色成员关系,该成员关系显示为由引导超级用户授予。)
GRANT 和 REVOKE 也可以由并非受影响对象拥有者的角色来执行,只要该角色是拥有该对象的角色的成员,或者是持有该对象上 WITH GRANT OPTION 特权的角色的成员。在这种情况下,特权将被记录为由实际拥有该对象或持有 WITH GRANT OPTION 特权的角色授予。例如,如果表 t1 由角色 g1 拥有,而角色 u1 是其成员,那么 u1 可以把 t1 上的特权授予 u2,但这些特权将显示为直接由 g1 授予。角色 g1 的任何其他成员之后都可以回收它们。
如果执行 GRANT 的角色通过多于一条的角色成员关系路径间接持有所需的特权,则未指定哪个包含角色将被记录为完成了该授予。在这种情况下,最佳实践是使用 SET ROLE 变成你希望以其身份执行 GRANT 的那个特定角色。
在表上授予权限并不会自动把权限扩展到该表使用的任何序列,包括与 SERIAL 列相关联的序列。序列上的权限必须单独设置。
有关特定特权类型以及如何检查对象特权的更多信息,请参见 Section 5.8。
把表 films 上的插入特权授予所有用户:
GRANT INSERT ON films TO PUBLIC;
把视图 kinds 上所有可用的特权授予用户 manuel:
GRANT ALL PRIVILEGES ON kinds TO manuel;
注意,虽然上面的语句如果由超级用户或 kinds 的拥有者执行确实会授予所有特权,但当由其他人执行时,它只会授予该其他人持有授权选项的那些权限。
把角色 admins 中的成员关系授予用户 joe:
GRANT admins TO joe;
根据 SQL 标准,ALL PRIVILEGES 中的 PRIVILEGES 关键字是必需的。SQL 标准不支持在一条命令中为多于一个对象设置特权。
PostgreSQL 允许对象拥有者回收自己的普通特权:例如,表拥有者可以通过回收自己的 INSERT、UPDATE、DELETE 和 TRUNCATE 特权,使该表对他们自己变成只读。根据 SQL 标准这是不可能的。原因在于 PostgreSQL 把拥有者的特权视为由拥有者授予自己;因此拥有者也可以回收它们。在 SQL 标准中,拥有者的特权由一个假定的实体 “_SYSTEM” 授予。由于不是 “_SYSTEM”,拥有者无法回收这些权利。
根据 SQL 标准,授权选项可以被授予 PUBLIC;PostgreSQL 只支持把授权选项授予角色。
SQL 标准只允许 GRANTED BY 选项指定 CURRENT_USER 或 CURRENT_ROLE。其他变体是 PostgreSQL 的扩展。
SQL 标准为其他类型的对象规定了 USAGE 特权:字符集、排序规则、转换。
在 SQL 标准中,序列只有一种 USAGE 特权,它控制 NEXT VALUE FOR 表达式的使用,该表达式等价于 PostgreSQL 中的 nextval 函数。序列特权 SELECT 和 UPDATE 是 PostgreSQL 的扩展。把序列的 USAGE 特权应用于 currval 函数也是 PostgreSQL 的扩展(该函数本身也是扩展)。
数据库、表空间、模式、语言和配置参数上的特权是 PostgreSQL 的扩展。