撤销权限
下面的非超级用户可以撤销对象的权限:
-
对象所有者
-
对象权限的授予者
用户还必须具有对对象架构的 USAGE 权限。
例如,针对系统表 V_CATALOG.GRANTS
执行以下查询将显示用户 u1
、u2
和 u3
对架构 s1
和表 s1.t1
具有以下权限:
=> SELECT object_type, object_name, grantee, grantor, privileges_description FROM v_catalog.grants
WHERE object_name IN ('s1', 't1') AND grantee IN ('u1', 'u2', 'u3');
object_type | object_name | grantee | grantor | privileges_description
-------------+-------------+---------+---------+---------------------------
SCHEMA | s1 | u1 | dbadmin | USAGE, CREATE
SCHEMA | s1 | u2 | dbadmin | USAGE, CREATE
SCHEMA | s1 | u3 | dbadmin | USAGE
TABLE | t1 | u1 | dbadmin | INSERT*, SELECT*, UPDATE*
TABLE | t1 | u2 | u1 | INSERT*, SELECT*, UPDATE*
TABLE | t1 | u3 | u2 | SELECT*
(6 rows)
注意
privileges_description
下权限上的星号 (*) 表示被授予者可以将这些权限授予其他用户。
在以下语句中,u2
撤销它在 s1.t1
上授予 u3
的 SELECT 权限。u3
随后尝试查询此表时返回错误:
=> \c - u2
You are now connected as user "u2".
=> REVOKE SELECT ON s1.t1 FROM u3;
REVOKE PRIVILEGE
=> \c - u3
You are now connected as user "u2".
=> SELECT * FROM s1.t1;
ERROR 4367: Permission denied for relation t1
撤销授予选项
如果您撤销用户对某个对象的权限,则该用户不能再将这些相同权限授予其他用户。如果该用户先前已将撤销的权限授予其他用户,则 REVOKE
语句还必须包含 CASCADE
选项才能撤销这些其他用户的权限;否则,它会返回错误。
例如,用户 u2
可以授予 SELECT、INSERT 和 UPDATE 权限,并将这些权限授予用户 u4
:
=> \c - u2
You are now connected as user "u2".
=> GRANT SELECT, INSERT, UPDATE on TABLE s1.t1 to u4;
GRANT PRIVILEGE
如果您通过查询 V_CATALOG.GRANTS
来查看是否拥有表 s1.t1
的权限,它会返回以下结果集:
=> \ c
You are now connected as user "dbadmin".
=> SELECT object_type, object_name, grantee, grantor, privileges_description FROM v_catalog.grants
WHERE object_name IN ('t1') ORDER BY grantee;
object_type | object_name | grantee | grantor | privileges_description
-------------+-------------+---------+---------+------------------------------------------------------------
TABLE | t1 | dbadmin | dbadmin | INSERT*, SELECT*, UPDATE*, DELETE*, REFERENCES*, TRUNCATE*
TABLE | t1 | u1 | dbadmin | INSERT*, SELECT*, UPDATE*
TABLE | t1 | u2 | u1 | INSERT*, SELECT*, UPDATE*
TABLE | t1 | u4 | u2 | INSERT, SELECT, UPDATE
(3 rows)
现在,如果用户 u1
想要撤销用户 u2
的 UPDATE 权限,则撤销操作必须级联到用户 u4
(该用户也拥有 u2
授予的 UPDATE 权限);否则,REVOKE
语句返回错误:
=> \c - u1
=> REVOKE update ON TABLE s1.t1 FROM u2;
ROLLBACK 3052: Dependent privileges exist
HINT: Use CASCADE to revoke them too
=> REVOKE update ON TABLE s1.t1 FROM u2 CASCADE;
REVOKE PRIVILEGE
=> \c
You are now connected as user "dbadmin".
=> SELECT object_type, object_name, grantee, grantor, privileges_description FROM v_catalog.grants
WHERE object_name IN ('t1') ORDER BY grantee;
object_type | object_name | grantee | grantor | privileges_description
-------------+-------------+---------+---------+------------------------------------------------------------
TABLE | t1 | dbadmin | dbadmin | INSERT*, SELECT*, UPDATE*, DELETE*, REFERENCES*, TRUNCATE*
TABLE | t1 | u1 | dbadmin | INSERT*, SELECT*, UPDATE*
TABLE | t1 | u2 | u1 | INSERT*, SELECT*
TABLE | t1 | u4 | u2 | INSERT, SELECT
(4 rows)
您还可以撤销用户的授予者权限而不撤销这些权限。例如,用户 u1
可以阻止用户 u2
将 INSERT 权限授予其他用户,但允许用户 u2
保留该权限:
=> \c - u1
You are now connected as user "u1".
=> REVOKE GRANT OPTION FOR INSERT ON TABLE s1.t1 FROM U2 CASCADE;
REVOKE PRIVILEGE
注意
REVOKE 语句必须包含 CASCADE,因为用户u2
先前授予用户 u4
对表 s1.t1
的 INSERT 权限。当您撤销 u2
授予此权限的能力时,必须从其任何被授予者(在本例中为用户 u4
)中移除该权限。
您可以通过查询 V_CATALOG.GRANTS
表来查看是否拥有 s1.t1
表的权限,从而确认撤销操作的结果:
=> \c
You are now connected as user "dbadmin".
=> SELECT object_type, object_name, grantee, grantor, privileges_description FROM v_catalog.grants
WHERE object_name IN ('t1') ORDER BY grantee;
object_type | object_name | grantee | grantor | privileges_description
-------------+-------------+---------+---------+------------------------------------------------------------
TABLE | t1 | dbadmin | dbadmin | INSERT*, SELECT*, UPDATE*, DELETE*, REFERENCES*, TRUNCATE*
TABLE | t1 | u1 | dbadmin | INSERT*, SELECT*, UPDATE*
TABLE | t1 | u2 | u1 | INSERT, SELECT*
TABLE | t1 | u4 | u2 | SELECT
(4 rows)
查询结果显示:
-
用户
u2
保留对表的 INSERT 权限,但不能再将 INSERT 权限授予其他用户(没有星号)。 -
撤销操作向下级联到被授予者
u4
,该用户现在失去 INSERT 权限。