↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

不受支持的版本: 6.4 / 6.3
历史版本PostgreSQL 6.4 已于 2003 年 10 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本手册首页。

43.4. 规则和权限

由于 Postgres 规则系统会重写查询,因此可能访问原始查询中并未使用的其他表或视图。使用更新规则时,这甚至可能包括对表的写访问。

重写规则没有单独的所有者。关系(表或视图)的所有者会自动成为为其定义的重写规则的所有者。Postgres 规则系统改变了默认访问控制系统的行为。由于规则而使用的关系,会在重写期间根据其上定义了该规则的关系所有者的权限进行检查。这意味着,用户只需要对其查询中明确命名的表/视图具有所需的权限。

例如,某个用户有一份电话号码列表,其中一部分是私人的,另一部分对办公室秘书有用。该用户可以这样构造:

CREATE TABLE phone_data (person text, phone text, private bool);
CREATE VIEW phone_number AS
    SELECT person, phone FROM phone_data WHERE NOT private;
GRANT SELECT ON phone_number TO secretary;

除了该用户本人(以及数据库超级用户)之外,没有人可以访问 phone_data 表。但由于 GRANT 的存在,秘书可以对 phone_number 视图执行 SELECT。规则系统会把对 phone_number 的 SELECT 重写成对 phone_data 的 SELECT,并附加只选取 private 为假的项的条件。由于该用户是 phone_number 的所有者,对 phone_data 的读访问会按照该用户的权限进行检查,于是查询被判定为允许。对 phone_number 本身的访问检查仍会执行,因此除秘书之外没有人能使用它。

权限是逐条规则检查的。因此,目前秘书是唯一能看到公开电话号码的人。但秘书还可以再建立一个视图,并把该视图授予公众访问。这样,任何人都可以通过秘书的视图看到 phone_number 中的数据。秘书做不到的是创建一个直接访问 phone_data 的视图(其实可以创建,但它不会起作用,因为每次访问都会在权限检查时中止事务)。而且,一旦用户发现秘书开放了其 phone_number 视图,用户就可以 REVOKE 秘书的访问权限。那样一来,对秘书视图的任何访问都会立即失败。

有人可能会认为这种逐条规则的检查是一个安全漏洞,但实际上并不是。如果它不这样工作,秘书也可以建立一个与 phone_number 具有相同列的表,每天把数据复制进去。那样一来,这些就是秘书自己的数据,他同样可以把访问权限授予任何人。GRANT 的含义本来就是“我信任你”。如果某个你信任的人做了上面的事,那么该重新考虑这份信任,然后使用 REVOKE 了。

这种机制对更新规则同样有效。在上一节的示例中,Al 数据库中那些表的所有者可以把 shoelace 视图上的 SELECT、INSERT、UPDATE 和 DELETE 权限授予 al。但对 shoelace_log 只授予 SELECT 权限。写日志记录的规则动作仍会被成功执行,Al 也能看到日志记录。但他不能伪造记录,也不能操纵或删除已有记录。

警告

GRANT ALL 目前会包含 RULE 权限。这意味着被授权的用户可以先删除规则、做出更改、再把规则装回去。我认为这一点应该尽快改变。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。