查找链接到 PostgreSQL 角色的对象

Nic*_*art 17 postgresql permissions

前段时间我创建了一个名为user1(PostgreSQL 9.4.9)的 PostgreSQL 用户。

我想放弃这个用户。所以我首先撤销对表、序列、函数、默认权限和所有权的所有权限:

ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON SEQUENCES FROM user1;
ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON TABLES FROM user1;
ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON FUNCTIONS FROM user1;

REVOKE ALL ON ALL SEQUENCES IN SCHEMA public FROM user1;
REVOKE ALL ON ALL TABLES IN SCHEMA public FROM user1;
REVOKE ALL ON ALL FUNCTIONS IN SCHEMA public FROM user1;

REASSIGN OWNED BY user1 TO postgres;
Run Code Online (Sandbox Code Playgroud)

但是,似乎有一个对象在 2 个数据库中仍与该用户保持链接:

postgres=# DROP ROLE user1;
ERROR:  role "user1" cannot be dropped because some objects depend on it
DETAIL:  1 object in database db1
1 object in database db2
Run Code Online (Sandbox Code Playgroud)

它甚至似乎是一个函数:

postgres=# \c db1
You are now connected to database "db1" as user "postgres".
db1=# DROP ROLE user1;
ERROR:  role "user1" cannot be dropped because some objects depend on it
DETAIL:  privileges for function text(boolean)
1 object in database db2
Run Code Online (Sandbox Code Playgroud)

但我无法确定哪个对象属于 user1 或与 user1 相关。

如果我pg_dump -s db1 | grep user1没有结果!它可能是一个全局对象吗?

如何识别丢失的对象?

我已经执行了每个数据库(db1 和 db2)中的命令。我不想删除 拥有的对象user1,只想重新分配或删除此用户的授权。

Erw*_*ter 15

回答问题

要在错误消息中查找函数及其所有者:

SELECT oid::regprocedure AS function
     , pg_get_userbyid(proowner) AS owner
FROM   pg_proc
WHERE  oid = 'text(boolean)'::regprocedure;
Run Code Online (Sandbox Code Playgroud)

有关的:

实际问题

错误消息说:

详细信息:功能文本的权限(布尔值)

不是关于所有权,而是关于特权

手册DROP ROLE

在删除角色之前,您必须删除它拥有的所有对象(或重新分配其所有权)并撤销该角色在其他对象上授予的任何权限

而对于ALTER DEFAULT PRIVILEGES

如果您希望删除已更改默认权限的角色,则需要撤销其默认权限中的更改或使用DROP OWNEDBY删除角色的默认权限条目

看起来你只REASSIGN OWNED在一个数据库中执行,但手册指示:

由于REASSIGN OWNED不会影响其他数据库中的对象,因此通常需要包含要删除的角色拥有的对象的每个数据库执行此命令

大胆强调我的。

并且您使用IN SCHEMA public. 删除该子句以针对整个数据库。不过别担心,有一个...

简单的解决方案 DROP OWNED

REASSIGN OWNED BY user1 TO postgres;
DROP OWNED BY user1;
Run Code Online (Sandbox Code Playgroud)

所有角色的对象都postgres使用第一个命令将所有权更改为并且现在是安全的。的措辞DROP OWNED有点误导,因为它还摆脱了所有特权和默认特权。手册DROP OWNED

DROP OWNED删除当前数据库中由指定角色之一拥有的所有对象。在当前数据库中的对象和共享对象(数据库、表空间)上授予给定角色的任何权限也将被撤销。

在所有相关的数据库中重复,然后你可以进入杀戮:

DROP ROLE user1;
Run Code Online (Sandbox Code Playgroud)


Sah*_*sci 10

下面的查询列出了拥有所有者的对象。对于所有特权,我们实际上需要更多。

--r = ordinary table, i = index, S = sequence, v = view, m = materialized view, c = composite type, t = TOAST table, f = foreign table
SELECT 
    n.nspname AS schema_name,
    c.relname AS rel_name,
    c.relkind AS rel_kind,
    pg_get_userbyid(c.relowner) AS owner_name
  FROM pg_class c
  JOIN pg_namespace n ON n.oid = c.relnamespace

UNION ALL

-- functions (or procedures)
SELECT
    n.nspname AS schema_name,
    p.proname,
    'p',
    pg_get_userbyid(p.proowner)
  FROM pg_proc p
  JOIN pg_namespace n ON n.oid = p.pronamespace
Run Code Online (Sandbox Code Playgroud)

  • 我仍然没有找到丢失的对象。 (2认同)