无法删除授予连接数据库的角色

时间:2018-06-24 12:15:04

标签: sql postgresql dependencies privileges revoke

我正在使用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

Documentation有点误导:

  

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"

当特权被撤销时,根本没有任何行。这至少可以解释为什么我们不能重新分配对象。

关于依赖关系类型,documentation指出:

  

SHARED_DEPENDENCY_ACL(a)

     

引用的对象(必须是角色)在   依赖项的ACL(访问控制列表,即特权列表)   宾语。 ({A SHARED_DEPENDENCY_ACL条目不是为   对象,因为所有者将有一个SHARED_DEPENDENCY_OWNER条目   无论如何。

但是我没有足够的洞察力来清楚地理解它。

我的问题是:

  • 在删除角色之前,Postgres是否总是需要撤销特权?
  • 如果没有,为什么此特定特权的行为如此?

1 个答案:

答案 0 :(得分:1)

使用type ReportName struct { Name string `xml:"name,attr"` } type ReportHost struct{ .... } d := xml.NewDecoder(f) for { tok, err := d.Token() if tok == nil || err == io.EOF { // EOF means we're done. break } else if err != nil { log.Fatalf("Error decoding token: %s", err) } // switch element := tok.(type) { case xml.StartElement: if element.Name.Local == "Report" { if err = d.DecodeElement(&reportName, &element); err != nil { log.Fatalf("Error decoding item: %s", err) } else if element.Name.Local == "ReportHost" { if err = d.DecodeElement(&reportHost, &element); err != nil { log.Fatalf("Error decoding item: %s", err) } } 时有一些非常不直观的权限要求。

我发现,当超级用户帐户不可用时(例如RDS或Cloud SQL),我必须将目标角色授予当前角色,以便从目标角色中重新分配或删除拥有的对象。例如,如果我的活动用户是REASSIGN,而我正在尝试删除postsgres

user_a

现在,如果> DROP OWNED BY user_a ERROR: permission denied to drop objects > GRANT user_a TO postgres; GRANT ROLE > DROP OWNED BY user_a; DROP OWNED 恰好是user_a的成员,这将变得有些棘手,尤其是如果它碰巧通过其他角色继承了该成员资格时,我们称之为postgres。 ..

schema_admin

Voila!

注意:这里还有另一个广泛引用的有效答案:https://sysadmintips.com/services/databases/postgresql-error-permission-denied-to-reassign-objects/,只要您能够以新的临时用户身份创建和登录,它就可以很好地工作。但是,在某些情况下,这本身就是一个问题(然后,您还需要进行额外的清理工作,以在完成后删除该临时角色),因此我在这里尝试避免这种情况。

相关问题