PostgreSQL GRANT
GRANT — 定义访问特权
大纲
GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
[, ...] | ALL [ PRIVILEGES ] }
ON { [ TABLE ] table_name
[, ...]
| ALL TABLES IN SCHEMA schema_name
[, ...] }
TO role_specification
[, ...] [ WITH GRANT OPTION ]
GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( column_name
[, ...] )
[, ...] | ALL [ PRIVILEGES ] ( column_name
[, ...] ) }
ON [ TABLE ] table_name
[, ...]
TO role_specification
[, ...] [ WITH GRANT OPTION ]
GRANT { { USAGE | SELECT | UPDATE }
[, ...] | ALL [ PRIVILEGES ] }
ON { SEQUENCE sequence_name
[, ...]
| ALL SEQUENCES IN SCHEMA schema_name
[, ...] }
TO role_specification
[, ...] [ WITH GRANT OPTION ]
GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] }
ON DATABASE database_name
[, ...]
TO role_specification
[, ...] [ WITH GRANT OPTION ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
ON DOMAIN domain_name
[, ...]
TO role_specification
[, ...] [ WITH GRANT OPTION ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
ON FOREIGN DATA WRAPPER fdw_name
[, ...]
TO role_specification
[, ...] [ WITH GRANT OPTION ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
ON FOREIGN SERVER server_name
[, ...]
TO role_specification
[, ...] [ WITH GRANT OPTION ]
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 ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
ON LANGUAGE lang_name
[, ...]
TO role_specification
[, ...] [ WITH GRANT OPTION ]
GRANT { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] }
ON LARGE OBJECT loid
[, ...]
TO role_specification
[, ...] [ WITH GRANT OPTION ]
GRANT { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }
ON SCHEMA schema_name
[, ...]
TO role_specification
[, ...] [ WITH GRANT OPTION ]
GRANT { CREATE | ALL [ PRIVILEGES ] }
ON TABLESPACE tablespace_name
[, ...]
TO role_specification
[, ...] [ WITH GRANT OPTION ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
ON TYPE type_name
[, ...]
TO role_specification
[, ...] [ WITH GRANT OPTION ]
其中role_specification
可以是:
[ GROUP ] role_name
| PUBLIC
| CURRENT_USER
| SESSION_USER
GRANT role_name
[, ...] TO role_name
[, ...] [ WITH ADMIN OPTION ]
描述
GRANT
命令由两种基本的变体:一种授予在一个数据库对象(表、列、视图、外部表、序列、数据库、外部数据包装器、外部服务器、函数、过程、过程语言、模式或表空间)上的特权,另一个授予一个角色中的成员关系。这些变体在很多方面都相似,但是也有很多不同,所以还是得分别描述它们。
在数据库对象上 GRANT
这种GRANT
命令的变体将一个数据库对象上的指定特权交给一个或多个角色。如果有一些已经被授予,这些特权会被加入到它们之中。
关键词PUBLIC
指示特权要被授予给所有角色,包括那些可能稍后会被创建的角色。PUBLIC
可以被认为是一个被隐式定义的总是包含所有角色的组。任何特定角色都将具有直接授予给它的特权、授予给它作为成员所在的任何角色的特权以及被授予给PUBLIC
的特权。
如果指定了WITH GRANT OPTION
,特权的接收者可以接着把它授予给其他人。如果没有授权选项,接收者就不能这样做。授权选项不能被授予给PUBLIC
。
没有必要把权限授予给一个对象的拥有者(通常就是创建该对象的用户), 因为拥有者默认具有所有的特权(不过拥有者可能为了安全选择撤回一些 它们自己的特权)。
删除一个对象或者以任何方式修改其定义的权力是不被当作一个可授予特权的,它被固化在拥有者中,并且不能被授予和撤回(不过,相似地效果可以通过授予或者撤回在拥有该对象的角色中的成员关系来实现,见下文)。拥有者也隐式地拥有该对象的所有授权选项。
The possible privileges are:
SELECT
INSERT
UPDATE
DELETE
TRUNCATE
REFERENCES
TRIGGER
CREATE
CONNECT
TEMPORARY
EXECUTE
USAGE
-
特定类型的权限,如 第 5.7 节中所定义。
TEMP
-
TEMPORARY
的替代拼写。 ALL PRIVILEGES
-
授予对象的类型可用的所有权限。
PRIVILEGES
关键词在PostgreSQL中是可选的,尽管它是严格的 SQL 所需要的。
FUNCTION
语法适用于简单函数、聚合函数和窗口函数,但不适用于过程;对过程使用PROCEDURE
。 或者,使用ROUTINE
来引用函数、聚合函数、窗口函数或过程而不管其精确类型。
还有一个选项,可以在一个或多个模式中对所有相同类型的对象授予特权。此功能当前仅支持表、序列、函数和过程。 ALL TABLES
也会影响视图和外表,就像特定对象 GRANT
命令。 ALL FUNCTIONS
也会影响聚合和窗口函数,但不影响过程,就像特定对象GRANT
命令一样。
使用 ALL ROUTINES
来包括过程。
角色上的 GRANT
GRANT
命令的这种变体把一个角色中的成员关系授予一个或者多个其他角色。一个角色中的成员关系是有意义的,因为它会把授予给一个角色的特权带给该角色的每一个成员。
如果指定了WITH ADMIN OPTION
,成员接着可以把该角色中的成员关系授予给其他用户,也可以撤回该角色中的成员关系。如果没有管理选项,普通用户就不能做这些工作。一个角色不被认为持有自身的WITH ADMIN OPTION
,但是它可以从一个会话用户匹配该角色的数据库会话中授予或撤回自身中的成员关系。数据库超级用户能够授予或撤回任何角色中任何人的成员关系。具有CREATEROLE
特权的角色能够授予或者撤回任何非超级用户角色中的成员关系。
如果指定了GRANTED BY
,则该授予被记录为已由指定角色完成。 只有数据库超级用户可以使用此选项,除非它为执行命令指定了相同的角色。
和特权的情况不同,一个角色中的成员关系不能被授予PUBLIC
。还要注意 这种形式的命令不允许role_specification
中的噪声词GROUP
。
注解
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
列上的序列。序列上的权限必须被独立设置。
有关特定的特权类型以及如何检查对象特权的更多信息,请参见第 5.7 节。
例子
把表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 只支持把授权选项授予给角色。
The SQL standard allows the GRANTED BY
option to be used in all forms of GRANT
. PostgreSQL only supports it when granting role membership, and even then only superusers may use it in nontrivial ways.
SQL标准允许在所有形式的GRANT
中使用GRANTED BY
选项。 PostgreSQL只在授予角色成员资格时才支持该选项,即使这样,也只有超级用户才能以非平凡的方式使用它。
SQL 标准提供了其他对象类型上的USAGE
特权:字符集、排序规则、翻译。
在 SQL 标准中,序列只有一个USAGE
特权,它控制NEXT VALUE FOR
表达式的使用,该表达式等效于 PostgreSQL 中的函数nextval
。序列的特权SELECT
和UPDATE
是 PostgreSQL
扩展。应用序列的USAGE
特权到currval
函数也是一个 PostgreSQL 扩展(该函数本身也是)。
数据库、表空间、模式和语言上的特权都是PostgreSQL扩展。
更多建议: