我正在使用 PostgreSQL 10.4,我发现了一个奇怪的行为。
如果我们创建一个角色并将其授予CONNECT
数据库:
CREATE ROLE dummy;
GRANT CONNECT ON DATABASE test TO dummy;
然后我们不能删除这个角色,即使它根本不拥有任何对象,这个命令:
DROP ROLE dummy;
提高:
ERROR: role "dummy" cannot be dropped because some objects depend on it
SQL state: 2BP01
Detail: privileges for database test
文档有点误导:
2B 类 — 依赖特权描述符仍然存在
2B000dependent_privilege_descriptors_still_exist
2BP01dependent_objects_still_exist
它说依赖对象仍然存在,但似乎没有依赖于这个特定角色的对象,它在数据库上没有任何东西。
无论如何,如果我们撤销CONNECT
特权,那么角色可以被删除:
REVOKE CONNECT ON DATABASE test FROM dummy;
DROP ROLE dummy;
我刚刚检查了 PostgreSQL 9.5 上也存在这种行为。我觉得这有点奇怪,我不明白为什么这个特定的特权会导致删除角色失败。
补充意见
这真的很阻塞,因为我们既不能重新分配这个对象:
REASSIGN OWNED BY dummy TO postgres;
也不丢弃对象:
DROP OWNED BY dummy;
两者都引发相关错误:
ERROR: permission denied to reassign objects
SQL state: 42501
ERROR: permission denied to drop objects
SQL state: 42501
正如@RaymondNijland 指出的那样,这一定是因为CONNECT
权限被视为角色相关对象。以下查询:
WITH
R AS (SELECT * FROM pg_roles WHERE rolname = 'dummy')
SELECT
D.*
FROM
R, pg_shdepend AS D
WHERE
refobjid = R.oid;
CONNECT
当被授予时返回单行:
"dbid";"classid";"objid";"objsubid";"refclassid";"refobjid";"deptype"
0;1262;27961;0;1260;27966;"a"
当特权被撤销时,根本没有任何争吵。这至少解释了为什么我们不能重新分配对象。
关于依赖类型,文档指出:
SHARED_DEPENDENCY_ACL
(一个)被引用对象(必须是角色)在依赖对象的ACL(访问控制列表,即权限列表)中被提及。(
A SHARED_DEPENDENCY_ACL
条目不是为对象的所有者创建的,因为所有者SHARED_DEPENDENCY_OWNER
无论如何都会有一个条目。)
但是我没有足够的洞察力来清楚地理解它。
我的问题是:
- Postgres 是否总是需要在删除角色之前撤销权限?
- 如果不是,为什么这个特定的特权会这样?