由于 PostgreSQL 规则系统对查询的重写, 非初始查询指定的其他表/视图被访问. 使用更新规则,这可能包括对表的写权限.
重写规则并不拥有一个独立的所有者. 关系(表或视图)的所有者自动成为重写规则的缺省所有者. PostgreSQL 规则系统改变缺省的访问控制系统的特性. 因规则而使用的关系在 (规则)重写时要对定义规则的关系所有者的权限进行检查. 这意味着一个用户只需要对他的查询里指定的表/视图拥有所需的权限 就可进行操作.
例如:某用户有一个电话号码列表,其中一些是私人的, 另外的一些是办公室秘书需要的.他可以用下面方法构建(查询):
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 并将增加资格(条件). 只有私人条件为假的记录才可以选出.因为用户是 phone_number 的所有者, 他对 phone_data 的读访问的权限现在要进行检查,而这个查询是被赋予的. 所以对访问 phone_number 的权限检查仍然要进行, 所以除了秘书外没有人可以使用它.
权限检查是按规则逐条进行的. 所以此时的秘书是唯一的一个可以看到公共电话号码的人. 但秘书可以设立另一个视图并且赋予该视图公共权限. 这样,任何人都可以通过秘书的视图看到 phone_number 数据. 秘书不能做的事情是创建一个接访问 phone_data 的视图 (实际上他是可以的,但没有任何作用, 因为每个访问都会因通不过权限检查而被踢出事务). 而且用户很快会认识到,秘书开放了他的 phone_number 视图后, 他还可以 REVOKE (撤回)他的访问权限. 这样,所有对秘书视图的访问马上就失效了.
有些人会认为这种逐条规则的检查是一个安全漏洞,但事实上不是. 如果这样做不能奏效, 秘书将必须建立一个与 phone_number 有相同字段的表并且每天一次的拷贝数据进去. 那么这是他自己的数据因而他可以赋予他允许的任何人访问的权力. 一个 GRANT 意味着 "我信任你".如果某个你信任的人做了上面的事情, 那你就该想想是否该 REVOKE 了.
这个机制同样可以用于更新规则.在上一章的例子里, Al 的数据库里的表的所有者可以把(赋予)鞋带视图 GRANTSELECT,INSERT,UPDATE 和 DELETE 给 al. 但对 shoelace_log 只有SELECT 权限. 写日志记录的规则动作(action)仍然可以成功的执行. 并且 Al 可以看到日志记录.但他不能创建伪记录, 而且他也不能对现有记录进行修改或删除.
警告: GRANT ALL 目前包括 RULE (规则)权限. 这意味着赋予权限的用户可以删除规则, 做修改和重新安装之.我想这些可能很快就会改变.