Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16 / 17

5.8. 权限 #

创建对象后,会为其指定一个所有者。所有者通常是执行创建语句的角色。对于大多数种类的对象来说,其初始状态是只有所有者(或超级用户)可以使用该对象。为允许其他角色使用该对象,必须授予权限

有不同种类的权限:SELECTINSERTUPDATEDELETETRUNCATEREFERENCESTRIGGERCREATECONNECTTEMPORARYEXECUTEUSAGESETALTER SYSTEMMAINTAIN。适用于特定对象的权限因对象的类型(表、函数等)而异。以下内容会更详细地介绍这些权限的含义。以下部分和章节还将向您展示如何使用这些权限。

修改或销毁对象的权限是对象所有者固有的,不能在对象本身上授予或撤销。(但与所有权限一样,该权限可以通过所有者角色的成员继承;请参见第 21.3 节。)

可以使用对对象适用类型的 ALTER 命令将对象分配给新的所有者,例如

ALTER TABLE table_name OWNER TO new_owner;

超级用户始终可以执行此操作;普通角色只能在他们是对象的当前所有者(或继承所有者角色的权限)且能够将 SET ROLE 设置为新的所有者角色时执行此操作。

为分配权限,需使用 GRANT 命令。例如,如果 joe 是现有角色,accounts 是现有表,则可以使用以下命令授予更新该表的权限

GRANT UPDATE ON accounts TO joe;

在特定权限的位置编写 ALL 将授予对象类型相关的所有权限。

可以使用特殊 role 名称 PUBLIC 为系统上的每个角色授予权限。此外,在数据库用户较多时,还可以设置 group 角色来帮助管理权限 — 有关详细信息,请参见第 21 章

为撤销先前授予的权限,请使用恰如其名的 REVOKE 命令

REVOKE ALL ON accounts FROM PUBLIC;

通常,只有对象的所有者(或超级用户)可以授予或吊销对对象的权限。但是,有可能授予一个“带授予选项”的权限,该权限授予接收者向他人再次授予该权限的权利。如果其后吊销了授予选项,那么从该接收者(直接或通过一系列的授予)接收该权限的所有人都将丢失该权限。有关详细信息,请参阅 GRANTREVOKE 引用页面。

对象的拥有者可以选择吊销他们自己普通权限,例如同时为自己和其他用户将某个表设为只读。但所有者始终会被视为持有所有授予选项,以便他们始终可以重新授予自己的权限。

可用的权限有

SELECT #

允许从某个表、视图、物化视图或其他表类对象的任意列,或特定列,SELECT。还允许使用 COPY TO。在 UPDATEDELETEMERGE 中引用现有列值时,此权限也是必须的。对于序列,此特权还允许使用 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 #

对于数据库,允许在数据库中创建新的架构和发布,并允许在数据库中安装受信任的扩展。

对于架构,允许在架构中创建新对象。要重命名字现有的对象,你必须拥有该对象 为包含该对象的架构拥有此权限。

对于表空间,允许在表空间中创建表、索引和临时文件,并允许创建具有表空间作为其默认表空间的数据库。

请注意,撤销此权限不会改变现有对象的存在或位置。

CONNECT #

允许被授予者连接到数据库。此权限在连接启动时检查(除了检查 pg_hba.conf 强制的任何限制)。

TEMPORARY #

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

EXECUTE #

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

USAGE #

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

对于架构,允许访问架构中包含的对象(假定对象的拥有权限要求也得到满足)。这本质上允许获取者在架构中“查找”对象。如果没有此权限,仍然有可能看到对象名,例如查询系统目录。此外,撤销此权限后,现有会话可能具有先前执行此查找的语句,因此这不是一种完全安全的方式来阻止对象访问。

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

对于类型和域,允许在表、函数和其他架构对象的创建中使用类型或域。(请注意,此权限并不控制类型的全部“用法”,例如在查询中出现的类型值。它只阻止创建依赖于该类型的对象。此权限的主要目的是控制哪些用户可以创建对类型的依赖关系,从而可以防止所有者以后更改类型。)

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

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

SET #

允许在当前会话中将服务器配置参数设置为新值。(虽然可以在任何参数上授予此权限,但它仅对通常需要超级用户权限才能设置的参数有意义。)

ALTER SYSTEM #

允许使用 ALTER SYSTEM 命令将服务器配置参数配置为新值。

MAINTAIN #

允许在关联上执行 VACUUMANALYZECLUSTERREFRESH MATERIALIZED VIEWREINDEXLOCK TABLE

其他命令需要的权限在相应命令的参考页面中列出。

PostgreSQL 在创建某些类型的对象时,默认会向 PUBLIC 授予特权。默认情况下,不会向 PUBLIC 授予表、表列、序列、外部数据封装器、外部服务器、大对象、模式、表空间或配置参数的特权。对于其他类型的对象,授予 PUBLIC 的默认特权如下:数据库的 CONNECTTEMPORARY(创建临时表)特权;函数和过程的 EXECUTE 特权;以及语言和数据类型(包括域)的 USAGE 特权。当然,对象所有者可以 REVOKE 默认授予的特权和明确授予的特权。(为了最大程度地提高安全性,请在创建对象的同一事务中执行 REVOKE;此处没有其他用户可以使用该对象的时间段。)此外,可以使用 ALTER DEFAULT PRIVILEGES 命令来覆盖这些默认特权设置。

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

表 5.1 ACL 特权缩写

特权 缩写 适用的对象类型
SELECT r (read) LARGE OBJECTSEQUENCETABLE(以及类似于表的对象)、表列
INSERT a (append) TABLE、表列
UPDATE w (write) LARGE OBJECTSEQUENCETABLE、表列
DELETE d TABLE
TRUNCATE D TABLE
REFERENCES x TABLE、表列
TRIGGER t TABLE
CREATE C DATABASESCHEMATABLESPACE
CONNECT c DATABASE
TEMPORARY T DATABASE
EXECUTE X FUNCTIONPROCEDURE
USAGE U DOMAINFOREIGN DATA WRAPPERFOREIGN SERVERLANGUAGESCHEMASEQUENCETYPE
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 具有特权 SELECTr)以及授予选项(*),以及由角色 hobbes 授予的不可授予的特权 UPDATEw)。如果 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 的一些权限,具体取决于上面说明的对象类型。针对一个对象的第一个 GRANTREVOKE 会实例化默认权限(例如,生成 miriam=arwdDxt/miriam),然后按照指定的请求对其进行修改。同样,仅针对具有非默认权限的列才在 列权限 中显示条目。(注意:在此,默认权限 总是指针对该对象的类型的内置默认权限。已通过 ALTER DEFAULT PRIVILEGES 命令影响其权限的对象总是会显示一个明确的权限条目,其中包含有 ALTER 的影响。)

请注意,所有者的隐式授予选项并未在访问权限显示中标记。仅当已明确授予某人授予选项时,* 才会出现。

当对象的权限条目为非空但为空时,访问权限 栏会显示 (none)。这意味着根本未授予任何权限,即使是对对象的拥有者也是如此 — 这是罕见的情况。(在这种情况下,所有者仍有隐式授予选项,因此可以重新授予其自己的权限;但目前没有任何权限。)