web-dev-qa-db-ja.com

GRANT SELECT ON SEQUENCEは成功しましたが、効果はありませんか?

あるユーザー/ロールから別のユーザー/ロールへのシーケンスへの選択アクセスを許可しようとしています。コマンドを実行してもエラーは発生しませんが、一度実行すると、2番目のロールでシーケンスを表示できません。成功した他のいくつかのサービス/データベースインスタンスでまったく同じコマンドを実行しましたが、これは1つだけ誤動作しています。

私は両方を実行しました:

GRANT SELECT ON ALL SEQUENCES IN SCHEMA schema_name TO new_role;

ここの推奨に従って:

そして、前述したように、これは別のマシン上の他のデータベーススキーマでも成功しています。私も個別に試しました:

GRANT SELECT ON SEQUENCE some_id_sequence TO new_role;

そして

GRANT SELECT ON SEQUENCE public.some_id_sequence TO new_role;

これも影響しません。 new_roleからログインすると、次のように表示されます。

select * from information_schema.role_usage_grants ; 
...
(0 rows)

\dsを実行したときの同様の結果(またはその欠如)。

前の役割から、シーケンスが「付与可能」であることがわかります(それが何であれ、ドキュメントは見つかりません)

live@live ~ => select * from information_schema.role_usage_grants limit 1;
┌──────────┬──────────┬────────────────┬───────────────┬──────────────┬─────────────┬────────────────┬──────────────┐
│ grantor  │ grantee  │ object_catalog │ object_schema │  object_name │ object_type │ privilege_type │ is_grantable │
├──────────┼──────────┼────────────────┼───────────────┼──────────────┼─────────────┼────────────────┼──────────────┤
│ old_role │ old_role │ old_role       │ public        │ some_id_seq  │ SEQUENCE    │ USAGE          │ YES          │
└──────────┴──────────┴────────────────┴───────────────┴──────────────┴─────────────┴────────────────┴──────────────┘
(1 row) 

そのため、この時点でどこを見ればよいのか本当にわかりません。古い役割は他の役割に選択を許可する機能を持っているように見え、コマンドを実行しようとしたときにエラーになりませんが、新しい役割はまだアクセスできません。

\dn+の結果

\dn+
                  List of schemas
┌───────────┬──────────┬────────────────────────┬─────────────┐
│  Name     │ Owner    │ Access privileges      │ Description │
├───────────┼──────────┼────────────────────────┼─────────────┤
│ new_role  │ old_role │ old_role=UC/old_role  ↵│             │
│           │          │ new_role=U/old_role    │             │
│ public    │ old_role │                        │             │
└───────────┴──────────┴────────────────────────┴─────────────┘
(2 rows)

\du+ new_role
                   List of roles
┌───────────┬────────────┬───────────┬─────────────┐
│ Role name │ Attributes │ Member of │ Description │
├───────────┼────────────┼───────────┼─────────────┤
│ new_role  │            │ {}        │             │
└───────────┴────────────┴───────────┴─────────────┘

\dpの結果

\dp some_id_sequence
                                     Access privileges
┌────────┬──────────────────┬──────────┬───────────────────────┬───────────────────┬──────────┐
│ Schema │       Name       │   Type   │ Access privileges     │ Column privileges │ Policies │
├────────┼──────────────────┼──────────┼───────────────────────┼───────────────────┼──────────┤
│ public │ some_id_sequence │ sequence │ old_role=rwU/old_role │                   │          │
│        │                  │          │ new_role=r/old_role   │                   │          │
└────────┴──────────────────┴──────────┴───────────────────────┴───────────────────┴──────────┘

質問:シーケンスの付与が適用されない原因を特定するにはどうすればよいですか?

3
Mitch Kent

ユーザーが権限を持たないスキーマに含まれている場合、シーケンスに対するSELECT(またはUSAGE)の付与は十分ではありません。 publicという名前のスキーマは公開されていないので、それは事実だと思います。許可されている場合は、次のような権限が付与されます。

test=> \dn+
                          List of schemas
  Name  |  Owner   |  Access privileges   |      Description       
--------+----------+----------------------+------------------------
 public | postgres | postgres=UC/postgres+| standard public schema
        |          | =UC/postgres         | 

質問に示されたアクセス権限の欠如とは対照的に。これは、同じコマンドが他のインスタンスでも機能するという事実とも一致します。おそらく、これらの他のデータベースのスキーマパブリックは元のバージョンであり、ドロップ/再作成されたバージョンとは異なり、または権限が削除されています。

可能な解決策として、スキーマの所有者として次のことを検討してください。

 GRANT ALL ON SCHEMA public TO public;

またはより限定的

 GRANT ALL ON SCHEMA public TO new_role;

またはさらに制限された

 GRANT USAGE ON SCHEMA public TO new_role;
2
Daniel Vérité

マニュアル:

ビューrole_usage_grantsは、付与者または被付与者が現在有効になっているロールであるさまざまな種類のオブジェクトに対して付与されたUSAGE特権を識別します。

GRANT SELECT ...の後には何も表示されません。代わりに試してください:

GRANT USAGE ON SEQUENCE public.some_id_sequence TO new_role;

..それが本当に、あなたが望んでいることなら。 SELECT特権はSEQUENCEの使用に制限があり、 currval()およびlastval() を許可します。
通常、USAGE権限が必要です。これにより、重要な nextval()も許可されます 上記に加えて。たとえば、serial列を操作する場合。見る:

では、SELECTを付与した後、テストでこの紛らわしい行が表示されるのはなぜですか?

live@live ~ => select * from information_schema.role_usage_grants limit 1;
┌──────────┬──────────┬────────────────┬───────────────┬──────────────┬─────────────┬────────────────┬──────────────┐
│ grantor  │ grantee  │ object_catalog │ object_schema │  object_name │ object_type │ privilege_type │ is_grantable │
├──────────┼──────────┼────────────────┼───────────────┼──────────────┼─────────────┼────────────────┼──────────────┤
│ old_role │ old_role │ old_role       │ public        │ some_id_seq  │ SEQUENCE    │ USAGE          │ YES          │
└──────────┴──────────┴────────────────┴───────────────┴──────────────┴─────────────┴────────────────┴──────────────┘

オブジェクトの所有者は、そのオブジェクトに対するすべての特権を自動的に持っています。したがって、pg_class.relaclはNULLから始まり、default特権を示します。その所有者が別のロールに特権を付与すると、その所有者の特権がさらに明示的に入力され、情報スキーマビューにもポップアップ表示されます。または、 ソースを引用

特定のオブジェクトの「アクセス権」列が空の場合、そのオブジェクトにはデフォルトの特権があることを意味します(つまり、その特権列はnullです)。デフォルトの権限には、常に所有者のすべての権限が含まれ、上記で説明したように、オブジェクトタイプに応じてPUBLICの一部の権限を含めることができます。オブジェクトの最初のGRANTまたはREVOKEは、デフォルトの特権をインスタンス化し(たとえば、{miriam=arwdDxt/miriam}を生成)、指定されたリクエストごとにそれらを変更します。

一般的に、重要なものをデバッグするには、pg_catalogテーブルを確認します。これらのテーブルは、真実の主要な情報源です。 pg_class.relacl この特定の場合:

SELECT relnamespace::regnamespace, relname, relacl
FROM   pg_class
WHERE  relname = 'some_id_sequence';

または\z\dpの短縮形) psql

\z some_id_sequence

old_roleが所有者であるとすると、次のように表示されます。

{old_role=rwU/old_role,new_role=r/old_role}-GRANT SELECT...の後
{old_role=rwU/old_role,new_role=U/old_role}-GRANT USAGE ...の後
{old_role=rwU/old_role,new_role=rU/old_role}-両方を許可した後

そして、何も許可する前にNULL(psqlでは空)。

追加された出力は、new_roleが実際にSELECT権限を持っていることを示しています。間違ったビューを調べただけです。 new_roleには、パブリックスキーマに対する権限が不足しているようです-通常、デフォルトでPUBLICに付与されています。


余談:Postgres 11以降のIDENTITY列は混乱を避けます。これらは内部でもシーケンスを使用しますが、IDENTITY列によって暗黙的に所有され、適切な権限が自動的に付与されます。その後、シーケンスに個別の付与を行う必要はありません。見る:

2