创建对象后,会为其指定一个所有者。所有者通常是执行创建语句的角色。对于大多数种类的对象来说,其初始状态是只有所有者(或超级用户)可以使用该对象。为允许其他角色使用该对象,必须授予权限。
有不同种类的权限:SELECT
、INSERT
、UPDATE
、DELETE
、TRUNCATE
、REFERENCES
、TRIGGER
、CREATE
、CONNECT
、TEMPORARY
、EXECUTE
、USAGE
、SET
、ALTER SYSTEM
和MAINTAIN
。适用于特定对象的权限因对象的类型(表、函数等)而异。以下内容会更详细地介绍这些权限的含义。以下部分和章节还将向您展示如何使用这些权限。
修改或销毁对象的权限是对象所有者固有的,不能在对象本身上授予或撤销。(但与所有权限一样,该权限可以通过所有者角色的成员继承;请参见第 21.3 节。)
可以使用对对象适用类型的 ALTER
命令将对象分配给新的所有者,例如
ALTER TABLEtable_name
OWNER TOnew_owner
;
超级用户始终可以执行此操作;普通角色只能在他们是对象的当前所有者(或继承所有者角色的权限)且能够将 SET ROLE
设置为新的所有者角色时执行此操作。
为分配权限,需使用 GRANT 命令。例如,如果 joe
是现有角色,accounts
是现有表,则可以使用以下命令授予更新该表的权限
GRANT UPDATE ON accounts TO joe;
在特定权限的位置编写 ALL
将授予对象类型相关的所有权限。
可以使用特殊 “role” 名称 PUBLIC
为系统上的每个角色授予权限。此外,在数据库用户较多时,还可以设置 “group” 角色来帮助管理权限 — 有关详细信息,请参见第 21 章。
为撤销先前授予的权限,请使用恰如其名的 REVOKE 命令
REVOKE ALL ON accounts FROM PUBLIC;
通常,只有对象的所有者(或超级用户)可以授予或吊销对对象的权限。但是,有可能授予一个““带授予选项””的权限,该权限授予接收者向他人再次授予该权限的权利。如果其后吊销了授予选项,那么从该接收者(直接或通过一系列的授予)接收该权限的所有人都将丢失该权限。有关详细信息,请参阅 GRANT 和 REVOKE 引用页面。
对象的拥有者可以选择吊销他们自己普通权限,例如同时为自己和其他用户将某个表设为只读。但所有者始终会被视为持有所有授予选项,以便他们始终可以重新授予自己的权限。
可用的权限有
SELECT
#允许从某个表、视图、物化视图或其他表类对象的任意列,或特定列,SELECT
。还允许使用 COPY TO
。在 UPDATE
、DELETE
或 MERGE
中引用现有列值时,此权限也是必须的。对于序列,此特权还允许使用 currval
函数。对于大型对象,此特权允许读取对象。
INSERT
#允许向某个表、视图等中 INSERT
新行。可在特定列上授予,在这种情况下,只有那些列可以被分配到 INSERT
命令中(因此其他列将接收默认值)。还允许使用 COPY FROM
。
UPDATE
#允许 UPDATE
某个表、视图等的任何列,或特定列。(实际上,任何非琐碎的 UPDATE
命令都需要 SELECT
特权,因为它必须引用表列以确定要更新哪些行,和/或以计算列的新值。) SELECT ... FOR UPDATE
和 SELECT ... FOR SHARE
除了 SELECT
特权之外,还需要对至少一列拥有此特权。对于序列,此特权允许使用 nextval
和 setval
函数。对于大型对象,此特权允许写入或截断对象。
DELETE
#允许对表、视图等中的行进行 DELETE
操作。(实际上,任何非平凡的 DELETE
命令还将需要 SELECT
权限,因为它必须引用表列以确定要删除哪些行。)
TRUNCATE
#允许对表执行 TRUNCATE
操作。
REFERENCES
#允许创建外键约束,引用表或表的特定列。
TRIGGER
#允许在表、视图等上创建触发器。
CREATE
#对于数据库,允许在数据库中创建新的架构和发布,并允许在数据库中安装受信任的扩展。
对于架构,允许在架构中创建新对象。要重命名字现有的对象,你必须拥有该对象 和 为包含该对象的架构拥有此权限。
对于表空间,允许在表空间中创建表、索引和临时文件,并允许创建具有表空间作为其默认表空间的数据库。
请注意,撤销此权限不会改变现有对象的存在或位置。
CONNECT
#允许被授予者连接到数据库。此权限在连接启动时检查(除了检查 pg_hba.conf
强制的任何限制)。
TEMPORARY
#允许在使用数据库时创建临时表。
EXECUTE
#允许调用函数或过程,包括在函数之上实现的任何运算符的使用。这是唯一适用于函数和过程的权限类型。
USAGE
#对于程序语言,允许使用该语言创建该语言中的函数。这是唯一适用于程序语言的权限类型。
对于架构,允许访问架构中包含的对象(假定对象的拥有权限要求也得到满足)。这本质上允许获取者在架构中“查找”对象。如果没有此权限,仍然有可能看到对象名,例如查询系统目录。此外,撤销此权限后,现有会话可能具有先前执行此查找的语句,因此这不是一种完全安全的方式来阻止对象访问。
对于序列,允许使用 currval
和 nextval
函数。
对于类型和域,允许在表、函数和其他架构对象的创建中使用类型或域。(请注意,此权限并不控制类型的全部“用法”,例如在查询中出现的类型值。它只阻止创建依赖于该类型的对象。此权限的主要目的是控制哪些用户可以创建对类型的依赖关系,从而可以防止所有者以后更改类型。)
对于外置数据封装器,允许使用外置数据封装器创建新服务器。
对于外置服务器,允许使用服务器创建外置表。获取者还可以创建、修改或删除与该服务器关联的自己的用户映射。
SET
#允许在当前会话中将服务器配置参数设置为新值。(虽然可以在任何参数上授予此权限,但它仅对通常需要超级用户权限才能设置的参数有意义。)
ALTER SYSTEM
#允许使用 ALTER SYSTEM 命令将服务器配置参数配置为新值。
MAINTAIN
#允许在关联上执行 VACUUM
、ANALYZE
、CLUSTER
、REFRESH MATERIALIZED VIEW
、REINDEX
和 LOCK TABLE
。
其他命令需要的权限在相应命令的参考页面中列出。
PostgreSQL 在创建某些类型的对象时,默认会向 PUBLIC
授予特权。默认情况下,不会向 PUBLIC
授予表、表列、序列、外部数据封装器、外部服务器、大对象、模式、表空间或配置参数的特权。对于其他类型的对象,授予 PUBLIC
的默认特权如下:数据库的 CONNECT
和 TEMPORARY
(创建临时表)特权;函数和过程的 EXECUTE
特权;以及语言和数据类型(包括域)的 USAGE
特权。当然,对象所有者可以 REVOKE
默认授予的特权和明确授予的特权。(为了最大程度地提高安全性,请在创建对象的同一事务中执行 REVOKE
;此处没有其他用户可以使用该对象的时间段。)此外,可以使用 ALTER DEFAULT PRIVILEGES 命令来覆盖这些默认特权设置。
表 5.1 显示了 ACL(访问控制列表) 值中用于这些特权类型的单字母缩写。您将在下面列出的 psql 命令的输出中或在查看系统目录的 ACL 列时看到这些字母。
表 5.1 ACL 特权缩写
特权 | 缩写 | 适用的对象类型 |
---|---|---|
SELECT |
r (“read”) |
LARGE OBJECT 、SEQUENCE 、TABLE (以及类似于表的对象)、表列 |
INSERT |
a (“append”) |
TABLE 、表列 |
UPDATE |
w (“write”) |
LARGE OBJECT 、SEQUENCE 、TABLE 、表列 |
DELETE |
d |
TABLE |
TRUNCATE |
D |
TABLE |
REFERENCES |
x |
TABLE 、表列 |
TRIGGER |
t |
TABLE |
CREATE |
C |
DATABASE 、SCHEMA 、TABLESPACE |
CONNECT |
c |
DATABASE |
TEMPORARY |
T |
DATABASE |
EXECUTE |
X |
FUNCTION 、PROCEDURE |
USAGE |
U |
DOMAIN 、FOREIGN DATA WRAPPER 、FOREIGN SERVER 、LANGUAGE 、SCHEMA 、SEQUENCE 、TYPE |
SET |
s |
参数 |
ALTER SYSTEM |
A |
参数 |
MAINTAIN |
m |
TABLE |
表 5.2 汇总了对每种 SQL 对象可用权限,使用的缩写符号如上所示。它还显示了可用于检查每种对象类型的权限设置的 psql 命令。
表 5.2。权限摘要
对象类型 | 所有权限 | 默认 PUBLIC 权限 |
psql 命令 |
---|---|---|---|
DATABASE |
CTc |
Tc |
\l |
域 |
U |
U |
\dD+ |
函数 或 过程 |
X |
X |
\df+ |
外接数据封装器 |
U |
无 | \dew+ |
外来服务器 |
U |
无 | \des+ |
语言 |
U |
U |
\dL+ |
大对象 |
rw |
无 | \dl+ |
参数 |
sA |
无 | \dconfig+ |
架构 |
UC |
无 | \dn+ |
序列 |
rwU |
无 | \dp |
表 (以及类似表的对象) |
arwdDxtm |
无 | \dp |
表列 | arwx |
无 | \dp |
表空间 |
C |
无 | \db+ |
类型 |
U |
U |
\dT+ |
已授予某个特定对象的特权显示为 aclitem
条目列表,每个条目的格式如下
grantee
=
privilege-abbreviation
[*
].../
grantor
每个 aclitem
列出特定授权者授权的一个授予者的所有权限。具体特权由 表 5.1 中的单字母缩写表示,如果特权通过授予选项授予,则附加 *
。例如,calvin=r*w/hobbes
指定角色 calvin
具有特权 SELECT
(r
)以及授予选项(*
),以及由角色 hobbes
授予的不可授予的特权 UPDATE
(w
)。如果 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=arwdDxtm/miriam+| col1: +| | | | =r/miriam +| miriam_rw=rw/miriam | | | | admin=arw/miriam | | (1 row)
针对给定对象,如果 “访问权限” 栏为空,说明该对象有默认权限(即,它在相关系统目录中的权限条目为空)。默认权限总是包含所有者的所有权限,还能包含针对 PUBLIC
的一些权限,具体取决于上面说明的对象类型。针对一个对象的第一个 GRANT
或 REVOKE
会实例化默认权限(例如,生成 miriam=arwdDxt/miriam
),然后按照指定的请求对其进行修改。同样,仅针对具有非默认权限的列才在 “列权限” 中显示条目。(注意:在此,“默认权限” 总是指针对该对象的类型的内置默认权限。已通过 ALTER DEFAULT PRIVILEGES
命令影响其权限的对象总是会显示一个明确的权限条目,其中包含有 ALTER
的影响。)
请注意,所有者的隐式授予选项并未在访问权限显示中标记。仅当已明确授予某人授予选项时,*
才会出现。
当对象的权限条目为非空但为空时,“访问权限” 栏会显示 (none)
。这意味着根本未授予任何权限,即使是对对象的拥有者也是如此 — 这是罕见的情况。(在这种情况下,所有者仍有隐式授予选项,因此可以重新授予其自己的权限;但目前没有任何权限。)