PostgreSQLはオブジェクトパーミッションをどの順序でチェックしますか?


16

データベースロール、、ストアドプロシージャとして定義されたuser1関数、something()および次のように作成されたビューを指定します。

CREATE VIEW view1 AS select * from something()

そして、この許可が与えられた場合:

REVOKE ALL ON FUNCTION something FROM user1
REVOKE SELECT ON view1 FROM user1

実行するSELECT * FROM view1と、エラーが発生しますpermission denied for function something()

私の質問は、ビューの選択権限を取り消すと、なぜ関数が呼び出されるのですか?私は次のようなものを受け取ることを期待していました:

permission denied for relation view1

ありがとうございました!


2
知っている限り、権限がチェックされる順序は定義されていません。
クレイグリンガー

@CraigRingerありがとうございます!私はそれが予想される動作だと思います。APIでビューを公開しているので、ビューの実装の詳細が表示されるのを避けようとしました(ビューの代わりに関数のアクセス許可についてエラーメッセージが表示された場合)。
サンティアス

1
クエリプランとほぼ同じ方法で(たとえば、ボトムアップから)アクセス許可が評価され、そのため、最も低いオブジェクトが最初に評価されますsomething()。これは関数です。簡単なテストは、クエリを変更して別のEXPLAIN PLANを取得し、それに応じてアクセス許可を調整し、アクセス許可エラーがsomething()関数でスローされるかどうか、または新しい実行プランの再評価方法に従っているかどうかを確認することです。
ジョンイスブレナー

関数へのアクセス許可を付与し、ビューでそれらを取り消す場合、基礎となる関数への言及を省略する必要があります
-amenadiel

回答:


3

その場合の問題は、許可の順序ではなく、実行の順序に関するものです。

履歴書では、PostgreSQLの場合:

1-テーブルにアクセスしているビューは、テーブルのアクセス許可をオーバーライドします

2-ビューにアクセスする関数は、チェックする前にすべての関数を評価する必要があります-したがって、ビューに選択権限がない場合でも、ビューにアクセスする前に関数を実行する必要があります...

どうやってそれを証明できますか?

postgresqlでは、ユーザーがこのアクセス許可を持っていなくても、ビューはテーブルで選択を行うためのアクセス許可を与えることができます。

例えば:

create view view2 as select * from table1;
revoke all on table1 from user1;
grant select on view2 to user1; 

ユーザー1としてログインします。

select * from table1 (permission denied) 
select * from view2 (sucess - the query executes)

この場合、ユーザーはテーブルを選択する権限を持っていなくてもview2を選択できます。

しかし関数で同じことを行うとどうなりますか?動作は同じではありません。5秒待ってから1を返す関数を作成します(したがって、ビューを呼び出すたびにpostgresqlが関数を実行しているかどうかをデバッグできます)

CREATE OR REPLACE FUNCTION something() RETURNS integer
AS 'select 1 from pg_sleep(5);'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT; --this function will delay 5 seconds

create view view1 as select * from something();
revoke all on function something() from user1;
grant select on view1 to user1; 

ユーザー1としてログインします。

select * from something(); (permission denied for something) 
select * from view1 (permission denied for something )

ビューで選択を行う許可は関数の許可をオーバーライドしません。さらに、view1から許可を取り消すと最悪の場合でも、メッセージは、ビューの許可に関係なく、関数のためにpostgresqlがクエリを停止したことを示しています。 (それはまさに質問で起こっていることです)

しかし、実際に機能が最初にチェックされていますか?関数に「すべて」の権限を付与し、表示権限を取り消す場合...

grant all on function something to user1; 
revoke all on view1 from user1; 
select * from view1;
Delayed 5 seconds... (the function executed!) 
Permission denied for select on view1

postgresql がviewを出力する許可を持っていないと言う前にWAITED 5 SECONDS を見ると、「something()」関数が実行されていることを示しています。したがって、関数データの戻り値は、ビューのチェックの前に存在する必要があります。

したがって、このテストでは、PostgreSQLはクエリを続行する前に最初にすべての関数を評価する必要があることがわかりました。すべての関数が完全に完了するまでクエリが存在しないのと同じです選択する権限があるかどうかを確認します。

これは「許可順序」の観点からあなたの質問に答えると思いますが、なぜpostgresqlは続行する前にすべての関数を評価する必要があるのですか、それは別の質問です...

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.