17.4. ルールと権限

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

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

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

    CREATE TABLE phone_data (person text, phone text, private bool);
    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 from できます。ルールシステムは SELECT from phone_number を SELECT from phone_data に書き換え、private が偽となっている項目 のみを使用するという条件を付け加えます。 そのユーザは phone_number の所有者ですから、 phone_data の読み込みに対するアクセスはそのユーザのパーミッション にしたがってチェックされ、問合せを受け付けてもいいことになります。 phone_number へのアクセスはチェックされ続けられますので、秘書とユーザ 以外は使うことが出来ません。

パーミッションはルール毎にチェックされます。ですから秘書だけが 今のところ一般の電話番号を参照することが出来ます。 しかし、秘書が別のビューを作成し、それを一般にたいしアクセス許可を 与えれば、秘書のビューを通して誰もが phone_number データを見る ことができます。秘書ができないことは phone_data に直接アクセス するビューを作ることです。(実際にはできますが、それぞれのアクセス についてのパーミッションチェックでトランザクションがアボート します。そしてユーザが気づいた時点で、秘書が開いた phone_number ビューを秘書から REVOKE できます。たちどころに、秘書の ビューへのアクセスは失敗に終ります。

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

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

警告: 現在 GRANT ALL には RULE パーミッションが含まれています。 ということは、認可されたユーザはルールを消去したり、変更したりまた 再インストールすることができます。著者はこれが早急に変更されるべきと 考えます。