PostgreSQLロールにリンクされたオブジェクトを検索する


12

以前、user1という名前のPostgreSQLユーザー(PostgreSQL 9.4.9)を作成しました。

このユーザーを削除します。そのため、最初に、テーブル、シーケンス、関数、デフォルトの権限、所有権のすべての権限も取り消します。

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;

ただし、1つのオブジェクトが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

それも関数のようです:

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

しかし、どのオブジェクトが所有されているのか、またはuser1に関連しているのかを特定できません。

私ならばpg_dump -s db1 | grep user1、私は何も結果を得ることはありません!それはグローバルオブジェクトでしょうか?

欠落しているオブジェクトを特定するにはどうすればよいですか?

各データベース(db1およびdb2)でコマンドを実行しました。が所有するオブジェクトを削除するのではなくuser1、このユーザーの権限を再割り当てまたは削除するだけです。

回答:


11

質問に対する回答

エラーメッセージとその所有者で関数を探すには:

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

関連:

実際の問題

エラーメッセージは言う:

詳細:関数テキストの権限(ブール値)

それ所有権についてではなく、特権についてです。

マニュアルDROP ROLE

ロールを削除する前に、そのロールが所有するすべてのオブジェクトを削除(またはその所有権を再割り当て)し、ロールが他のオブジェクトに対して付与されている特権を取り消す必要があります

そしてのためにALTER DEFAULT PRIVILEGES

デフォルトの権限が変更されたロールを削除する場合は、デフォルトの権限の変更を元に戻すか、DROP OWNEDBYを使用して、ロールのデフォルトの権限エントリを削除する必要があります

またREASSIGN OWNED、1つのDBでのみ実行されているように見えますが、マニュアルでは次のように指示されています。

REASSIGN OWNEDは他のデータベース内のオブジェクトには影響しないため、通常は、削除するロールが所有するオブジェクトを含む各データベースこのコマンド実行する必要があります。

大胆な強調鉱山。

そして、でコマンドを制限しましたIN SCHEMA public。その句を削除して、DB全体をターゲットにします。しかし、気にしないでください...

シンプルなソリューション DROP OWNED

REASSIGN OWNED BY user1 TO postgres;
DROP OWNED BY user1;

すべてのロールのオブジェクトpostgresは、最初のコマンドで所有権を変更し、現在は安全です。の言い回しDROP OWNEDは、すべての特権とデフォルトの特権も取り除くため、少し誤解を招くものです。マニュアルDROP OWNED

DROP OWNED指定されたロールの1つが所有する現在のデータベース内のすべてのオブジェクトを削除します。現在のデータベース内のオブジェクトおよび共有オブジェクト(データベース、テーブルスペース)の特定のロールに付与された特権もすべて取り消されます。

関連するすべてのDBで繰り返し、キルのために移動できます。

DROP ROLE user1;

6

以下のクエリは、所有者を持つオブジェクトをリストします。すべての特権について、実際にはさらに多くのものが必要です。

--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

私はまだこれで行方不明のオブジェクトを見つけません。
Nicolas Payart

@NicolasPayart:正しいデータベースでクエリを実行していますか?
Erwin Brandstetter 2016年

1

最初にデータベースに接続する必要があります。あなたのインスタンスでは

\c db1

そして

\c db2

次に、REVOKE ALL PRIVILEGESおよびREASSIGN OWNED / DROP OWNEDステートメントを再度実行してください。


1
ねえ、あなたの最初の答えをありがとう。ただし、投稿する前に、これが既存の回答に何を追加するかを考えて、回答にも説明してください。
dezso
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.