| PostgreSQL 8.0.0 中文文件(轉譯自 PostgreSQL 中國 製作的簡體中文版本) | ||||
|---|---|---|---|---|
| Prev | Fast Backward | Chapter 33. 規則系統 | Fast Forward | Next |
由於 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 的權限, 但這是對一個被撤消權限的用戶進行檢查的,所以除了用戶自己和秘書外沒有人可以使用它。
權限檢查是按規則逐條進行的。 所以此時的秘書是唯一的一個可以看到公共電話號碼的人。 但秘書可以設立另一個視圖並且賦予該視圖公共權限。 這樣,任何人都可以透過秘書的視圖看到 phone_number 資料。 秘書不能做的事情是建立一個直接訪問 phone_data 的視圖(實際上他是可以的,但沒有任何作用, 因為每個訪問都會因通不過權限檢查而被踢出交易)。 而且用戶很快會認識到,秘書開放了他的 phone_number 視圖後, 他還可以REVOKE(撤回)他的訪問權限。 這樣,所有對秘書視圖的訪問馬上就失效了。
有些人會認為這種逐條規則的檢查是一個安全漏洞,但事實上不是。 如果這樣做不能奏效, 秘書將必須建立一個與 phone_number 有相同字串的資料表並且每天一次的拷貝資料進去。 那麼這是他自己的資料因而他可以賦予他允許的任何人訪問的權力。 一個GRANT意味著 "我信任您"。如果某個您信任的人做了上面的事情, 那您就該想想是否該REVOKE了。
這個機制同樣可以用於更新規則。在上一章的例子裡, 例子資料庫裡的資料表的所有者可以把(賦予)shoelace視圖 的權限 SELECT,INSERT,UPDATE 和 DELETE 賦予其它人。 但對 shoelace 只有 SELECT 權限。 寫日誌記錄的規則動作(action)仍然可以成功的執行。 並且其它用戶可以看到日誌記錄。但他不能建立偽記錄, 而且他也不能對現有記錄進行修改或刪除。