閱讀886 返回首頁    go 阿裏雲 go 技術社區[雲棲]


PostgreSQL服務器管理:數據庫角色

本文檔為PostgreSQL 9.6.0文檔,本轉載已得到原譯者彭煜瑋授權。

數據庫角色在概念上已經完全與操作係統用戶獨立開來。事實上可能維護一個對應關係會比較方便,但是這並非必需。數據庫角色在一個數據庫集簇安裝範圍內是全局的(而不是獨立數據庫內)。要創建一個角色,可使用CREATE ROLE SQL 命令:


CREATE ROLE name;

name遵循 SQL 標識符的規則:或是未經裝飾沒有特殊字符,或是用雙引號包圍(實際上,你將總是給該命令要加上額外選項,例如LOGIN。更多細節可見下文)。要移除一個已有的角色,使用相似的DROP ROLE命令:


DROP ROLE name;

為了方便,createuser和dropuser程序被提供作為這些 SQL 命令的包裝器,它們可以從 shell 命令行調用:


createuser name
dropuser name

要決定現有角色的集合,檢查pg_roles係統目錄,例如:


SELECT rolname FROM pg_roles;

psql程序的\du元命令也可以用來列出現有角色。

為了引導數據庫係統,一個剛剛被初始化好的係統總是包含一個預定義角色。這個角色總是一個"superuser",並且默認情況下(除非在運行initdb時修改)它的名字和初始化數據庫集簇的操作係統用戶相同。習慣上,這個角色將被命名為postgres。為了創建更多角色,你首先必須以初始角色的身份連接。

每一個到數據庫服務器的連接都是使用某個特定角色名建立的,並且這個角色決定發起連接的命令的初始訪問權限。要使用一個特定數據庫連接的角色名由客戶端指示,該客戶端以一種應用相關的風格發起連接請求。例如,psql程序使用-U命令行選項來指定要以哪個角色連接。很多應用假定該名字默認是當前操作係統用戶(包括createuser和psql)。因此在角色和操作係統用戶之間維護一個名字對應關係通常是很方便的。

一個給定客戶端連接能夠用來連接的數據庫角色的集合由該客戶端的認證設置決定,這些在Chapter 20中有解釋(因此,一個客戶端不止限於以匹配其操作係統用戶的角色連接,就像一個人的登錄名不需要匹配她的真實名字一樣)。因為角色身份決定一個已連接客戶端可用的權限集合,在設置一個多用戶環境時要小心地配置權限。

一個數據庫角色可以有一些屬性,它們定義角色的權限並且與客戶端認證係統交互。

login privilege

隻有具有LOGIN屬性的角色才能被用於一個數據庫連接的初始角色名稱。一個帶有LOGIN屬性的角色可以被認為和一個"數據庫用戶"相同。要創建一個帶有登錄權限的角色,使用兩者之一:


CREATE ROLE name LOGIN;
CREATE USER name;

(CREATE USER和CREATE ROLE等效,除了CREATE USER默認假定有LOGIN,而CREATE ROLE不這樣認為)。

superuser status

一個數據庫超級用戶會繞開所有權限檢查,除了登入的權利。這是一個危險的權限並且應該小心使用,最好用一個不是超級用戶的角色來完成你的大部分工作。要創建一個新數據庫超級用戶,使用CREATE ROLE name SUPERUSER。你必須作為一個超級用戶來完成這些。

database creation

一個角色必須被顯式給予權限才能創建數據庫(除了超級用戶,因為它們會繞開所有權限檢查)。要創建這樣一個角色,使用CREATE ROLE name CREATEDB。

role creation

一個角色必須被顯式給予權限才能創建更多角色(除了超級用戶,因為它們會繞開所有權限檢查)。要創建這樣一個角色,使用CREATE ROLE name CREATEROLE。一個帶有CREATEROLE權限的角色也可以修改和刪除其他角色,還可以授予或回收角色中的成員關係。然而,要創建、修改、刪除或修改一個超級用戶角色的成員關係,需要以超級用戶的身份操作。CREATEROLE不足以完成這一切。

initiating replication

一個角色必須被顯式給予權限才能發起流複製(除了超級用戶,因為它們會繞開所有權限檢查)。一個被用於流複製的角色必須也具有LOGIN權限。要創建這樣一個角色,使用CREATE ROLE name REPLICATION LOGIN。

password

隻有當客戶端認證方法要求用戶在連接數據庫時提供一個口令時,一個口令才有意義。password和md5認證方法使用口令。數據庫口令與操作係統命令獨立。在角色創建時指定一個口令:CREATE ROLE name PASSWORD 'string'。

Tip: 一個好習慣是創建一個具有CREATEDB和CREATEROLE權限的角色,而不是創建一個超級用戶,並且然後用這個角色來完成對數據庫和角色的例行管理。這種方法避免了在非必要時作為超級用戶操作任務的風險。

對於Chapter 19中描述的運行時配置設置,一個角色也可以有角色相關的默認值。例如,如果出於某些原因你希望在每次連接時禁用索引掃描(提示:不是好主意),你可以使用:


ALTER ROLE myname SET enable_indexscan TO off;

這將保存設置(但是不會立刻設置它)。在這個角色的後續連接中,它就表現得像在會話開始之前執行過SET enable_indexscan TO off。你也可以在會話期間改變該設置,它將隻是作為默認值。要移除一個角色相關的默認設置,使用ALTER ROLE rolename RESET varname。注意附加到沒有LOGIN權限的角色的角色相關默認值相當無用,因為它們從不會被調用。

把用戶分組在一起來便於管理權限常常很方便:那樣,權限可以被授予一整個組或從一整個組回收。在PostgreSQL中通過創建一個表示組的角色來實現,並且然後將在該組角色中的成員關係授予給單獨的用戶角色。

要建立一個組角色,首先創建該角色:


CREATE ROLE name;

通常被用作一個組的角色不需要有LOGIN屬性,不過如果你希望你也可以設置它。

一旦組角色存在,你可以使用GRANT和REVOKE命令增加和移除成員:


GRANT group_role TO role1, ... ;
REVOKE group_role FROM role1, ... ;

你也可以為其他組角色授予成員關係(因為組角色和非組角色之間其實沒有任何區別)。數據庫將不會讓你設置環狀的成員關係。另外,不允許把一個角色中的成員關係授予給PUBLIC。

組角色的成員可以以兩種方式使用角色的權限。第一,一個組的每一個成員可以顯式地做SET ROLE來臨時"稱為"組角色。在這種狀態中,數據庫會話可以訪問組角色而不是原始登錄角色的權限,並且任何被創建的數據庫對象被認為屬於組角色而不是登錄角色。第二,有INHERIT屬性的成員角色自動地具有它們所屬角色的權限,包括任何組角色繼承得到的權限。作為一個例子,假設我們已經有:


CREATE ROLE joe LOGIN INHERIT;
CREATE ROLE admin NOINHERIT;
CREATE ROLE wheel NOINHERIT;
GRANT admin TO joe;
GRANT wheel TO admin;

在作為角色joe連接後,一個數據庫會話將立即擁有直接授予給joe的權限,外加任何授予給admin的權限,因為joe"繼承了" admin的權限。然而,授予給wheel的權限不可用,因為即使joe是wheel的一個間接成員,但是該成員關係是通過帶NOINHERIT屬性的admin得到的。在:


SET ROLE admin;

之後,該會話將隻擁有授予給admin的權限,但是沒有授予給joe的權限。在執行:


SET ROLE wheel;

之後,該會話將隻擁有授予給wheel的權限,但是沒有授予給joe或admin的權限。初始的權限狀態可以使用下麵命令之一恢複:


SET ROLE joe;
SET ROLE NONE;
RESET ROLE;

Note:
SET ROLE命令總是允許選擇原始登錄角色的直接或間接組角色。因此,在上麵的例子中,在成為wheel之前不必先成為admin。

Note:
在 SQL 標準中,用戶和角色之間的區別很清楚,並且用戶不會自動繼承權限而角色會繼承。這種行為在PostgreSQL中也可以實現:為要用作 SQL 角色的角色給予INHERIT屬性,而為要用作 SQL 用戶的角色給予NOINHERIT屬性。不過,為了向後兼容 8.1 以前的發布(在其中用戶總是擁有它們所在組的權限),PostgreSQL默認給所有的角色INHERIT屬性。

角色屬性LOGIN、SUPERUSER、CREATEDB和CREATEROLE可以被認為是一種特殊權限,但是它們從來不會像數據庫對象上的普通權限那樣被繼承。要使用這些屬性,你必須實際SET ROLE到一個有這些屬性之一的特定角色。繼續上述例子,我們可以選擇授予CREATEDB和CREATEROLE給admin角色。然後一個以joe角色連接的會話將不會立即有這些權限,隻有在執行了SET ROLE admin之後才會擁有。

要銷毀一個組角色,使用DROP ROLE:


DROP ROLE name;

任何在該組角色中的成員關係會被自動撤銷(但是成員角色不會受到影響)。

由於角色可以擁有數據庫對象並且能持有訪問其他對象的特權,刪除一個角色 常常並非一次DROP ROLE就能解決。任何被該用戶所擁有 的對象必須首先被刪除或者轉移給其他擁有者,並且任何已被授予給該角色的 權限必須被收回。

對象的擁有關係可以使用ALTER命令一次轉移出去,例如:


ALTER TABLE bobs_table OWNER TO alice;

此外,REASSIGN OWNED命令可以被用來把要被刪除的 角色所擁有的所有對象的擁有關係轉移給另一個角色。由於 REASSIGN OWNED不能訪問其他數據庫中的對象,有必要 在每一個包含該角色所擁有對象的數據庫中運行該命令(注意第一個這樣的 REASSIGN OWNED將更改任何在數據庫間共享的該角色擁 有的對象的擁有關係,即數據庫或者表空間)。

一旦任何有價值的對象已經被轉移給新的擁有者,任何由被刪除角色擁有的剩餘對象 就可以用DROP OWNED命令刪除。再次,由於這個命令不能 訪問其他數據庫中的對象, 有必要在每一個包含該角色所擁有對象的數據庫中運行 該命令。還有,DROP OWNED將不會刪除整個數據庫或者表空間, 因此如果該角色擁有任何還沒有被轉移給新擁有者的數據庫或者表空間,有必要手工 刪除它們。

DROP OWNED也會注意移除為不屬於目標角色的對象授予給目標 角色的任何特權。因為REASSIGN OWNED不會觸碰這類對象,通 常有必要運行REASSIGN OWNED和 DROP OWNED(按照這個順序!)以完全地移除要被刪除對象的 從屬物。

總之,移除曾經擁有過對象的角色的方法是:


REASSIGN OWNED BY doomed_role TO successor_role;
DROP OWNED BY doomed_role;
-- 在集簇中的每一個數據庫中重複上述命令
DROP ROLE doomed_role;

如果不是所有的擁有對象都被轉移給了同一個後繼擁有者,最好手工處理異常 然後執行上述步驟直到結束。

如果在依賴對象還存在時嚐試了DROP ROLE,它將發出 消息標識哪些對象需要被重新授予或者刪除。

=====PostgreSQL provides a set of default roles which provide access to certain, commonly needed, privileged capabilities and information. Administrators can GRANT these roles to users and/or other roles in their environment, providing those users with access to the specified capabilities and information.

The default roles are described in Table 21-1. Note that the specific permissions for each of the default roles may change in the future as additional capabilities are added. Administrators should monitor the release notes for changes.

Table 21-1. Default Roles


image

Administrators can grant access to these roles to users using the GRANT command:


GRANT pg_signal_backend TO admin_user;

函數和觸發器允許用戶在後端服務器中插入代碼,其他用戶不會注意到這些代碼的執行。因此,兩種機製允許用戶相對容易地為其他人設置"特洛伊木馬"。唯一真正的保護是收緊對能定義函數的用戶的控製。

在後端服務器進程中運行的函數帶有數據庫服務器守護進程的操作係統權限。如果用於函數的編程語言允許非檢查的內存訪問,它就可能改變服務器的內部數據結構。因此,在很多其他事情中,這些函數可能繞開任何係統訪問控製。允許這種訪問的函數語言被認為是"不可信的",並且PostgreSQL隻允許超級用戶創建用這些語言編寫的函數。

最後更新:2017-08-21 17:32:39

  上一篇:go  String源碼簡析
  下一篇:go  mongodb續