35.4. ルールと権限

PostgreSQLのルールシステムによる問い合わせの書き換えによって、オリジナルの問い合わせで使われたものではない他のテーブル/ビューがアクセスされます。 更新ルールを使うことによってテーブルへの書き込みアクセスを包含することができます。

書き換えルールに別々の所有者はいません。 リレーション(テーブルまたはビュー)の所有者は自動的にそれに定義された書き換えルールの所有者となります。 PostgreSQLのルールシステムはデフォルトのアクセス制御システムの振舞いを変更します。 ルールによって使用されるリレーションは、ルールを起動したユーザの権限ではなく、ルール所有者の権限でチェックされます。 このことは、ユーザは問い合わせで明記するテーブル/ビューに対しての権限だけあればよいことを示しています。

例えば、以下のようにします。 あるユーザが、いくつかは個人用の、その他は事務所で秘書が利用するための、電話番号のリストを持っていたとします。 ユーザは次のようにして構築することができます。

CREATE TABLE phone_data (person text, phone text, private boolean);
CREATE VIEW phone_number AS
    SELECT person, phone FROM phone_data WHERE NOT private;
GRANT SELECT ON phone_number TO secretary;

そのユーザ(とデータベースのスーパーユーザ)以外はphone_dataテーブルにアクセスできません。 しかし、GRANTにより秘書はphone_numberビューに対しSELECTできます。 ルールシステムはphone_numberからのSELECT操作をphone_dataからのSELECT操作に書き換え、privateが偽となっている項目のみを使用するという条件を付け加えます。 そのユーザはphone_numberの所有者、したがってルールの所有者ですから、phone_dataの読み込みに対するアクセスはそのユーザの権限に従ってチェックされ、問い合わせを受け付けてもよいことになります。 phone_numberへのアクセスもチェックされますが、これは呼び出したユーザに対して行われますので、秘書とユーザ以外は使うことができません。

権限はルールごとにチェックされます。 ですから秘書だけが今のところ一般の電話番号を参照することができます。 しかし、秘書は別のビューを作成し、それにPUBLICに対するアクセス許可を与えることができます。 こうすると秘書のビューを通して誰もがphone_numberデータを見ることができます。 秘書ができないことはphone_dataに直接アクセスするビューを作ることです (実際には作成はできますが、アクセスは全て、権限チェックで拒絶されます)。 そして、秘書が独自のphone_numberビューを開いたことにユーザが気付いた時点で、秘書の権限を取り上げることができます。 秘書のビューへのアクセスは即座に失敗に終わります。

このルールごとのチェックがセキュリティホールになると考える人がいるかもしれませんが、実際にはそうではありません。 もし機能しないと秘書は1日1回phone_numberと同じ列を持ったテーブルを用意して、データをそこにコピーしなければなりません。 データはそのユーザのものですから、誰にアクセス権を与えようが彼の自由です。 GRANT"あなたを信用しています"ということです。 信用している誰かがこのようなことを行った場合は、考えを変えてREVOKEしてください。

この機構は更新ルールにも適用できます。 前節の例において、データベースのテーブルの所有者はshoelaceビューに対し、誰かにSELECTINSERTUPDATEDELETE権限を与えることができます。 しかし、shoelace_logに対してはSELECTだけです。 ログ項目を書き込むルールアクションは支障なく実行され、また、他のユーザはログ項目を見ることができます。 しかし、他のユーザは項目を捏造したり、既に存在する項目を操作する、あるいは削除することはできません。