5.7. 权限

一旦一个对象被创建,它会被分配一个所有者。所有者通常是执行创建语句的角色。对于大部分类型的对象,初始状态下只有所有者(或者超级用户)能够对该对象做任何事情。为了允许其他角色使用它,必须分配权限

有多种不同的权限:SELECTINSERTUPDATEDELETETRUNCATEREFERENCESTRIGGERCREATECONNECTTEMPORARYEXECUTE以及USAGE。可以应用于一个特定对象的权限随着对象的类型(表、函数等)而不同。 有关这些权限含义的更多详细信息请参阅下文。后续的章节将介绍如何使用这些权限。

修改或销毁一个对象的权力通常是只有所有者才有的权限。

一个对象可以通过该对象类型相应的ALTER命令来重新分配所有者,例如

ALTER TABLE table_name OWNER TO new_owner;

超级用户总是可以做到这点,普通角色只有同时是对象的当前所有者(或者是拥有角色的一个成员)以及新拥有角色的一个成员时才能做同样的事。

要分配权限,可以使用GRANT命令。例如,如果joe是一个已有角色,而accounts是一个已有表,更新该表的权限可以按如下方式授权:

GRANT UPDATE ON accounts TO joe;

ALL取代特定权限会把与对象类型相关的所有权限全部授权。

一个特殊的名为PUBLIC角色可以用来向系统中的每一个角色授予一个权限。同时,在数据库中有很多用户时可以设置角色来帮助管理权限。详见第 21 章

为了撤销一个权限,使用REVOKE 命令:

REVOKE ALL ON accounts FROM PUBLIC;

对象拥有者的特殊权限(即执行DROPGRANTREVOKE等的权力)总是隐式地属于拥有者,并且不能被授予或撤销。但是对象拥有者可以选择撤销他们自己的普通权限,例如把一个表变得对他们自己和其他人只读。

一般情况下,只有对象拥有者(或者超级用户)可以授予或撤销一个对象上的权限。但是可以在授予权限时使用with grant option来允许接收人将权限转授给其他人。如果后来授予选项被撤销,则所有从接收人那里获得的权限(直接或者通过授权链获得)都将被撤销。更多详情请见GRANTREVOKE参考页。

The available privileges are:

SELECT

允许 SELECT 从任何列、或特定的列、表、视图、物化视图、或其他类似表格的对象。 也允许使用 COPY TO. 还需要这个权限来引用UPDATEDELETE中现有的列值。 对于序列,这个权限还允许使用currval 函数。对于大对象,此权限允许读取对象。

INSERT

允许将新行的 INSERT 加入表、视图等等。 可以在特定列上授予,在这种情况下INSERT命令中只有那些列可以被分配(其他列将因此而收到默认值)。 还允许使用COPY FROM。

UPDATE

允许 UPDATE 更新任何列、或指定列、表、视图等等。 (实际上,任何有效的UPDATE命令也需要SELECT权限,因为它必须引用表列来确定要更新的行,和/或计算列的新值。) SELECT ... FOR UPDATESELECT ... FOR SHARE除了SELECT权限外,还需要至少一列上的这个权限。 对于序列,这个权限允许使用 nextvalsetval 函数。对于大对象,此权限允许写入或截断对象。

DELETE

允许 DELETE 从表、视图等等中删除行. (实际上,任何有效的DELETE命令也需要SELECT权限,因为它必须引用表列来确定要删除的行。)

TRUNCATE

允许在表、视图等等上 TRUNCATE

REFERENCES

允许创建引用表或表的特定列的外键约束。

TRIGGER

允许在表、视图等等上创建触发器。

CREATE

对于数据库,允许在数据库中创建新的模式和发布。

对于模式,允许在模式中创建新对象。要重命名现有对象,你必须拥有对象 and所包含模式的此权限。

对于表空间,允许在表空间中创建表、索引和临时文件,并允许创建将表空间作为默认表空间的数据库。(注意,撤销此特权不会更改已有对象的位置。)

CONNECT

允许受让者连接到数据库。此权限在连接启动时进行检查(加之pg_hba.conf施加的任何约束).

TEMPORARY

允许在使用数据库时创建临时表。

EXECUTE

允许调用函数或过程,包括使用在函数之上实现的任何运算符。这是适用于函数和过程的唯一权限类型。

USAGE

对于程序语言,允许使用语言来创建该语言的函数。 这是适用于过程语言的唯一权限类型。

对于模式,允许访问模式中包含的对象(假设对象自己的权限要求也已得到满足)。 从本质上讲,这允许受让者look up模式中的对象。如果没有此权限,仍可以看到对象名称,例如通过查询系统目录。 此外,在撤消此权限后,现有会话可能还具有以前执行过此查找的语句,因此这不是阻止对象访问的彻底安全的方法。

对于序列, 允许使用currvalnextval 函数.

对于类型和域,允许在创建表、函数和其他模式对象时使用类型或域。 (注意,此权限不控制类型的全部 usage ,例如查询中出现的类型的值。 它仅防止创建依赖于类型的对象。 此权限的主要目的是控制哪些用户可以对类型创建依赖项,这可能会防止所有者以后更改类型。 )

对于外部数据包装器,允许使用外部数据包装器创建新服务器。

对于外部服务器,允许使用服务器创建外部表。受让者还可以创建、更改或删除与该服务器关联的自己的用户映射。

其他命令所需的权限罗列在相应命令的参考页上。

在创建对象时,PostgreSQL默认将某些类型对象的权限授予PUBLIC。 默认情况下,在表、表列、序列、外部数据包装器、外部服务器、大型对象、模式或表空间上,不向PUBLIC授予权限。 对于其他类型的对象,授予 PUBLIC的默认权限如下所示: 针对数据库的CONNECTTEMPORARY(创建临时表)权限; 针对函数和程序的EXECUTE权限;以及针对语言和数据类型(包括域)的USAGE权限。 当然,对象所有者可以REVOKE默认权限和特别授予的权限。 (为了最大程度的安全性,在创建对象的同一事务中发出REVOKE;那么就没有其他用户能够使用该对象的窗口。) 此外,可以使用ALTER DEFAULT PRIVILEGES命令取代这些默认权限设置。

表 5.1显示了ACL(访问控制列表)值中用于这些权限类型的单字母缩写。 你将在下面列出的 psql 命令的输出中,或者在查看系统目录的 ACL 列时看到这些字母。

表 5.1. ACL 权限缩写

权限缩写适用对象类型
SELECTr () LARGE OBJECT, SEQUENCE, TABLE (and table-like objects), table column
INSERTa (增补)TABLE, table column
UPDATEw () LARGE OBJECT, SEQUENCE, TABLE, table column
DELETEdTABLE
TRUNCATEDTABLE
REFERENCESxTABLE, table column
TRIGGERtTABLE
CREATEC DATABASE, SCHEMA, TABLESPACE
CONNECTcDATABASE
TEMPORARYTDATABASE
EXECUTEXFUNCTION, PROCEDURE
USAGEU DOMAIN, FOREIGN DATA WRAPPER, FOREIGN SERVER, LANGUAGE, SCHEMA, SEQUENCE, TYPE

表 5.2 使用上面所示的缩写总结了每种类型 SQL 对象可用的权限. 它还显示可用于检查每种对象类型的特权设置的 psql 命令。

表 5.2. 访问权限摘要

对象类型所有权限默认 PUBLIC 权限psql 命令
DATABASECTcTc\l
DOMAINUU\dD+
FUNCTION or PROCEDUREXX\df+
FOREIGN DATA WRAPPERUnone\dew+
FOREIGN SERVERUnone\des+
LANGUAGEUU\dL+
LARGE OBJECTrwnone 
SCHEMAUCnone\dn+
SEQUENCErwUnone\dp
TABLE (and table-like objects)arwdDxtnone\dp
Table columnarwxnone\dp
TABLESPACECnone\db+
TYPEUU\dT+

已授予特定对象的权限显示为aclitem项的列表,其中每个aclitem项描述了特定授予者授予给一个被授与者的权限。 例如,calvin=r*w/hobbes 指明角色calvin具有SELECTr)权限和授予选项(*)以及不可授予权限UPDATEw),均由角色hobbes授予。 如果calvin对由其他授予人授予的同一对象也具有一些权限,那将显示为单独的aclitem条目。 aclitem 中的空受赠方字段代表PUBLIC

例如,假设用户miriam创建了表mytable并且:

GRANT SELECT ON mytable TO PUBLIC;
GRANT SELECT, UPDATE, INSERT ON mytable TO admin;
GRANT SELECT (col1), UPDATE (col1) ON mytable TO miriam_rw;

psql\dp 命令将显示:

=> \dp mytable
                                  Access privileges
 Schema |  Name   | Type  |   Access privileges   |   Column privileges   | Policies
-−-−-−-−+-−-−-−-−-+-−-−-−-+-−-−-−-−-−-−-−-−-−-−-−-+-−-−-−-−-−-−-−-−-−-−-−-+-−-−-−-−-−
 public | mytable | table | miriam=arwdDxt/miriam+| col1:                +|
        |         |       | =r/miriam            +|   miriam_rw=rw/miriam |
        |         |       | admin=arw/miriam      |                       |
(1 row)

如果Access privileges列对于给定对象为空,则表示该对象具有默认权限(也就是说,它在相关系统目录中的权限条目为空)。 默认权限始终包含所有者的所有权限,并且可以包括 PUBLIC 的一些权限,具体取决于对象类型,如上所述。 对象上的第一个GRANTREVOKE将实例化默认权限(例如,生成miriam_arwdDxt/miriam),然后根据指定的请求修改它们。 类似的,只有具有非默认特权的列的条目才显示在Column privileges中。(注意:为此目的,default privileges始终表示对象类型的内置缺省权限。其权限受ALTER DEFAULT PRIVILEGES 命令影响的对象将始终显示一个显式权限条目,其中包含 ALTER。)

注意所有者的隐式授予选项没有在访问权限显示中标记。仅当授予选项被显式授予给某人时才会出现*