DBMS_RLS包可以使虛擬私人資料庫VPD(Virtual Private Database)執行於特定的PolarDB資料庫物件上。
| 函數/預存程序 | 類型 | 傳回型別 | 說明 |
| ADD POLICY(object schema, object name, policy name, function schema, policy function [, statement types [, update check [, enable [, static policy [, policy type [, long predicate [, sec relevant cols [, sec relevant cols opt ]]]]]]]]) | 預存程序 | N/A | 向資料庫物件添加安全性原則。 |
| DROP_POLICY(object_schema, object_name, policy_name) | 預存程序 | N/A | 從資料庫物件中刪除安全性原則。 |
| ENABLE_POLICY(object_schema, object_name, policy_name, enable) | 預存程序 | N/A | 啟用或禁用安全性原則。 |
與Oracle版本的DBMS_RLS包執行相比,PolarDB的DBMS_RLS包執行是一個部分執行。PolarDB僅支援上述表中列出的函數和預存程序。
虛擬私人資料庫是一種使用安全政策的細粒度存取控制。虛擬私人資料庫中的細粒度存取控制意味著對於資料的訪問可以控制到具體的行資訊。
在policy function中定義了編碼安全政策的規則。這個規則是一個SPL函數,有特定的輸入參數和傳回值。security policy是命名的政策函數聯合到特定的資料庫物件,尤其是表。
- 在PolarDB中,可以用任何PolarDB所支援的語言來編寫政策函數。例如,除了與Oracle相容的SPL語言外,您還可以使用SQL和PL/pgSQL語言。
- 目前PolarDB虛擬私人資料庫所支援的資料庫物件為表。政策不適用於視圖或同義字。
- 虛擬私人資料庫可以提供細粒度層級的安全訪問。GRANT命令授予的資料庫物件層級的許可權能夠決定存取權限是否能訪問資料庫物件中的整個執行個體。虛擬私人資料庫則為資料庫物件執行個體的個人記錄提供了存取控制。
- 根據SQL命令(INSERT、UPDATE、DELETE或SELECT)的類型,您可以應用不同的安全政策。
- 由於每個可應用的SQL命令影響的資料庫物件取決於一些因素(例如申請訪問資料庫物件的會話使用者),因此安全政策會動態變化。
- 安全政策的調用對所有資料庫物件的訪問申請都是透明的。因此,您不用為了應用安全政策去修改個人申請。
- 一旦啟用了安全政策,那麼任何申請(包括新申請)都無法繞過安全政策。除下列說明中列出的系統許可權以外。
- 除下列說明中列出的系統許可權以外,即使是超級使用者也不能繞過安全政策。
DBMS_RLS包提供的預存程序可用於建立、刪除、啟用及禁用安全政策。
- 首先要建立一個政策函數。這個函數必須有兩個類型為VARCHAR2的輸入參數。第一個輸入參數提供給包含資料庫物件(安全政策要應用於這個資料庫物件上)的模式。第二個輸入參數則提供給資料庫物件的名稱。所建立的這個政策函數還必須有一個VARCHAR2傳回型別,且返回的必須是一個WHERE謂語子句形式的字串。謂語將以AND條件動態附於對資料庫物件起作用的SQL命令之上。因此,不滿足政策函數謂語的記錄將從SQL命令的結果集中過濾掉。
- 使用ADD_POLICY預存程序來定義一個新政策,這是政策函數與資料庫物件的聯合。通過使用ADD_POLICY預存程序,您可以指定SQL命令(例如:INSERT、 UPDATE、 DELETE或SELECT,且政策要應用於這些SQL命令之上)的類型,也可以決定是否在建立政策的同時對它進行啟用,或決定政策函數是否可以應用於新插入的記錄上或更新記錄修改後的映像上。
- 使用ENABLE_POLICY預存程序來禁用或啟用現有的安全政策。
- 使用DROP_POLICY預存程序來刪除已有的政策。但DROP_POLICY預存程序不能刪除政策函數或聯合資料庫物件。
一旦政策建立之後,您就可以在與Oracle相容的目錄檢視下瀏覽所建立的政策。
SYS_CONTEXT(namespace, attribute) namespace是一個VARCHAR2值。唯一接受的值是USERENV。任何其他的值返回的都將是NULL。attribute是一個VARCHAR2值。屬性取值如下:屬性值 等效值 SESSION_USER pg_catalog.session_user CURRENT_USER pg_catalog.current_user CURRENT_SCHEMA pg_catalog.current_schema HOST pg_catalog.inet_host IP_ADDRESS pg_catalog.inet_client_addr SERVER_HOST pg_catalog.inet_server_addr
CREATE TABLE public.vpemp AS SELECT empno, ename, job, sal, comm, deptno FROM emp;
ALTER TABLE vpemp ADD authid VARCHAR2(12);
UPDATE vpemp SET authid = 'researchmgr' WHERE deptno = 20;
UPDATE vpemp SET authid = 'salesmgr' WHERE deptno = 30;
SELECT * FROM vpemp;
empno | ename | job | sal | comm | deptno | authid
-------+--------+-----------+---------+---------+--------+-------------
7782 | CLARK | MANAGER | 2450.00 | | 10 |
7839 | KING | PRESIDENT | 5000.00 | | 10 |
7934 | MILLER | CLERK | 1300.00 | | 10 |
7369 | SMITH | CLERK | 800.00 | | 20 | researchmgr
7566 | JONES | MANAGER | 2975.00 | | 20 | researchmgr
7788 | SCOTT | ANALYST | 3000.00 | | 20 | researchmgr
7876 | ADAMS | CLERK | 1100.00 | | 20 | researchmgr
7902 | FORD | ANALYST | 3000.00 | | 20 | researchmgr
7499 | ALLEN | SALESMAN | 1600.00 | 300.00 | 30 | salesmgr
7521 | WARD | SALESMAN | 1250.00 | 500.00 | 30 | salesmgr
7654 | MARTIN | SALESMAN | 1250.00 | 1400.00 | 30 | salesmgr
7698 | BLAKE | MANAGER | 2850.00 | | 30 | salesmgr
7844 | TURNER | SALESMAN | 1500.00 | 0.00 | 30 | salesmgr
7900 | JAMES | CLERK | 950.00 | | 30 | salesmgr
(14 rows)
CREATE ROLE salesmgr WITH LOGIN PASSWORD 'password';
GRANT ALL ON vpemp TO salesmgr;ADD_POLICY
ADD_POLICY預存程序通過聯合政策函數和資料庫物件來建立一個新政策。
只有超級使用者才能執行ADD_POLICY預存程序。
ADD_POLICY(object_schema VARCHAR2, object_name VARCHAR2,
policy_name VARCHAR2, function_schema VARCHAR2,
policy_function VARCHAR2
[, statement_types VARCHAR2
[, update_check BOOLEAN
[, enable BOOLEAN
[, static_policy BOOLEAN
[, policy_type INTEGER
[, long_predicate BOOLEAN
[, sec_relevant_cols VARCHAR2
[, sec_relevant_cols_opt INTEGER ]]]]]]]])參數
| 參數名稱 | 描述 |
| object_schema | 包含資料庫物件(政策將應用於這個資料庫物件上)的模式名稱。 |
| object_name | 政策所要應用於的資料庫物件的名稱。也許會有1個以上的政策應用於一個指定的資料庫物件上。 |
| policy_name | 分配給政策的名稱。資料庫物件(由object_schema 和object_name 標識)的聯結與政策名稱在資料庫中必須是唯一的。 |
| function_schema | 包含政策函數的模式名稱。 說明 政策函數也許屬於一個包。在這種情況下, function_schema必須含有定義包的模式名稱。 |
| policy_function | SPL函數的名稱,用於定義安全政策的規則。相同的函數也許會指定於多個政策中。 說明 政策函數也許屬於一個包。在這種情況下, policy_function必須也包含點符號的包名稱(也就是package_name. function_name) |
| statement_types | 逗號分隔的SQL命令列表,且政策應用於SQL命令之上。有效SQL命令是INSERT、UPDATE、DELETE和SELECT。預設為INSERT,UPDATE,DELETE,SELECT。 說明 PolarDB接受INDEX為語句類型,但會忽略。在PolarDB中,政策不能應用於索引操作中。 |
| update_check | update_check只能應用於INSERT和UPDATE的SQL命令中。
|
| enable |
|
| static_policy |
說明
|
| policy_type | 在Oracle環境下,policy_type用於決定重新評估政策函數的時間。預設值為NULL。說明 PolarDB僅執行動態政策,無需進行 policy_type參數的設定。 |
| longpredicate | 在Oracle環境下,如果將longpredicate設定為TRUE,則允許謂語達到32KB位元組。 否則,謂語就限制於4000位元組。預設值為FALSE。 說明 longpredicate參數的設定會被PolarDB忽略。一個PolarDB政策函數能返回一個對於所有實際用途不限長度的謂語。 |
| sec_relevant_cols | sec_relevant_cols是object_name列的逗號分隔的列表。它可以給列出的列提供列層級的虛擬私人資料庫。如果所列出的列引用於statement_types中列出的SQL命令類型中,那麼政策將被執行。如果沒有引用這樣的列,則不會執行政策。 預設值為NULL,預設值和 |
| sec_relevant_cols_opt | 在Oracle環境下,如果將sec_relevant_cols_opt設為DBMS_RLS.ALL_ROWS(INTEGER常量值1),那麼在sec_relevant_cols中列出的列就會返回所有記錄的NULL值。其中,記錄中應用的政策謂語為假。如果沒有把sec_relevant_cols_opt設為DBMS_RLS.ALL_ROWS,那麼結果集中將不會有這些記錄返回。,預設值為NULL。 說明 PolarDB不支援 DBMS_RLS.ALL_ROWS函數。如果將sec_relevant_cols_opt設為DBMS_RLS.ALL_ROWS(INTEGER常量值1),那麼PolarDB就會產生錯誤。 |
樣本
CREATE OR REPLACE FUNCTION verify_session_user (
p_schema VARCHAR2,
p_object VARCHAR2
)
RETURN VARCHAR2
IS
BEGIN
RETURN 'authid = SYS_CONTEXT(''USERENV'', ''SESSION_USER'')';
END;此函數產生的謂語authid = SYS_CONTEXT('USERENV', 'SESSION_USER')被添加到在ADD_POLICY預存程序中指定類型的任何SQL命令的WHERE子句中。
此函數對那些列authid內容與會話使用者相同的記錄限制了SQL命令的結果。
下列匿名代碼塊調用了ADD_POLICY預存程序。從而建立名為secure_update的政策。 通過使用函數verify_session_user,可以把政策secure_update應用於表vpemp之上,即使在參考資料表vpemp時,是否給出了一個INSERT、 UPDATE或DELETE命令。
DECLARE
v_object_schema VARCHAR2(30) := 'public';
v_object_name VARCHAR2(30) := 'vpemp';
v_policy_name VARCHAR2(30) := 'secure_update';
v_function_schema VARCHAR2(30) := 'polardb';
v_policy_function VARCHAR2(30) := 'verify_session_user';
v_statement_types VARCHAR2(30) := 'INSERT,UPDATE,DELETE';
v_update_check BOOLEAN := TRUE;
v_enable BOOLEAN := TRUE;
BEGIN
DBMS_RLS.ADD_POLICY(
v_object_schema,
v_object_name,
v_policy_name,
v_function_schema,
v_policy_function,
v_statement_types,
v_update_check,
v_enable
);
END;在成功建立政策之後,由使用者salesmgr發起了一個終結會話。下列查詢顯示了表vpemp的內容。
\c polardb salesmgr
Password for user salesmgr:
You are now connected to database "polardb" as user "salesmgr".
SELECT * FROM vpemp;
empno | ename | job | sal | comm | deptno | authid
-------+--------+-----------+---------+---------+--------+-------------
7782 | CLARK | MANAGER | 2450.00 | | 10 |
7839 | KING | PRESIDENT | 5000.00 | | 10 |
7934 | MILLER | CLERK | 1300.00 | | 10 |
7369 | SMITH | CLERK | 800.00 | | 20 | researchmgr
7566 | JONES | MANAGER | 2975.00 | | 20 | researchmgr
7788 | SCOTT | ANALYST | 3000.00 | | 20 | researchmgr
7876 | ADAMS | CLERK | 1100.00 | | 20 | researchmgr
7902 | FORD | ANALYST | 3000.00 | | 20 | researchmgr
7499 | ALLEN | SALESMAN | 1600.00 | 300.00 | 30 | salesmgr
7521 | WARD | SALESMAN | 1250.00 | 500.00 | 30 | salesmgr
7654 | MARTIN | SALESMAN | 1250.00 | 1400.00 | 30 | salesmgr
7698 | BLAKE | MANAGER | 2850.00 | | 30 | salesmgr
7844 | TURNER | SALESMAN | 1500.00 | 0.00 | 30 | salesmgr
7900 | JAMES | CLERK | 950.00 | | 30 | salesmgr
(14 rows)使用者salesmgr發起了一個非模式限定的UPDATE命令(沒有WHERE子句):
UPDATE vpemp SET comm = sal * .75;
UPDATE 6政策不會更新表中所有的記錄,而是僅對那些authid列中含有salesmgr的記錄限制更新結果。其中,salesmgr值是由政策函數謂語authid = SYS_CONTEXT('USERENV', 'SESSION_USER') 指定的。
下列查詢結果顯示了comm列僅為那些authid列中含有salesmgr的記錄而進行改變。所有其他的記錄不變 。
SELECT * FROM vpemp;
empno | ename | job | sal | comm | deptno | authid
-------+--------+-----------+---------+---------+--------+-------------
7782 | CLARK | MANAGER | 2450.00 | | 10 |
7839 | KING | PRESIDENT | 5000.00 | | 10 |
7934 | MILLER | CLERK | 1300.00 | | 10 |
7369 | SMITH | CLERK | 800.00 | | 20 | researchmgr
7566 | JONES | MANAGER | 2975.00 | | 20 | researchmgr
7788 | SCOTT | ANALYST | 3000.00 | | 20 | researchmgr
7876 | ADAMS | CLERK | 1100.00 | | 20 | researchmgr
7902 | FORD | ANALYST | 3000.00 | | 20 | researchmgr
7499 | ALLEN | SALESMAN | 1600.00 | 1200.00 | 30 | salesmgr
7521 | WARD | SALESMAN | 1250.00 | 937.50 | 30 | salesmgr
7654 | MARTIN | SALESMAN | 1250.00 | 937.50 | 30 | salesmgr
7698 | BLAKE | MANAGER | 2850.00 | 2137.50 | 30 | salesmgr
7844 | TURNER | SALESMAN | 1500.00 | 1125.00 | 30 | salesmgr
7900 | JAMES | CLERK | 950.00 | 712.50 | 30 | salesmgr
(14 rows)由於在ADD_POLICY預存程序中將update_check參數設為TRUE,所以下列INSERT命令會產生異常。 且由於給列authid的researchmgr值與會話使用者salesmgr不匹配,所以使政策失效。
INSERT INTO vpemp VALUES (9001,'SMITH','ANALYST',3200.00,NULL,20, 'researchmgr');
ERROR: policy with check option violation
DETAIL: Policy predicate was evaluated to FALSE with the updated values如果您將update_check設為FALSE,上面描述的INSERT命令就會生效。
下列樣本說明了要應用於政策的sec_relevant_cols參數僅在SQL命令中引用特定列時使用。樣本中的政策函數選擇了員工薪水少於2000的記錄。
CREATE OR REPLACE FUNCTION sal_lt_2000 (
p_schema VARCHAR2,
p_object VARCHAR2
)
RETURN VARCHAR2
IS
BEGIN
RETURN 'sal < 2000';
END;建立政策是為了在SELECT命令包括sal或comm列時,執行所建立的政策:
DECLARE
v_object_schema VARCHAR2(30) := 'public';
v_object_name VARCHAR2(30) := 'vpemp';
v_policy_name VARCHAR2(30) := 'secure_salary';
v_function_schema VARCHAR2(30) := 'polardb';
v_policy_function VARCHAR2(30) := 'sal_lt_2000';
v_statement_types VARCHAR2(30) := 'SELECT';
v_sec_relevant_cols VARCHAR2(30) := 'sal,comm';
BEGIN
DBMS_RLS.ADD_POLICY(
v_object_schema,
v_object_name,
v_policy_name,
v_function_schema,
v_policy_function,
v_statement_types,
sec_relevant_cols => v_sec_relevant_cols
);
END;如果一個查詢沒有引用列sal或comm,即沒有應用政策。下列查詢返回的是表vpemp的14行記錄:
SELECT empno, ename, job, deptno, authid FROM vpemp;
empno | ename | job | deptno | authid
-------+--------+-----------+--------+-------------
7782 | CLARK | MANAGER | 10 |
7839 | KING | PRESIDENT | 10 |
7934 | MILLER | CLERK | 10 |
7369 | SMITH | CLERK | 20 | researchmgr
7566 | JONES | MANAGER | 20 | researchmgr
7788 | SCOTT | ANALYST | 20 | researchmgr
7876 | ADAMS | CLERK | 20 | researchmgr
7902 | FORD | ANALYST | 20 | researchmgr
7499 | ALLEN | SALESMAN | 30 | salesmgr
7521 | WARD | SALESMAN | 30 | salesmgr
7654 | MARTIN | SALESMAN | 30 | salesmgr
7698 | BLAKE | MANAGER | 30 | salesmgr
7844 | TURNER | SALESMAN | 30 | salesmgr
7900 | JAMES | CLERK | 30 | salesmgr
(14 rows)如果查詢引用了列sal或comm,這個查詢則應用了政策。然後這個查詢刪除了任何sal大於或等於2000的記錄。如下所示:
SELECT empno, ename, job, sal, comm, deptno, authid FROM vpemp;
empno | ename | job | sal | comm | deptno | authid
-------+--------+----------+---------+---------+--------+-------------
7934 | MILLER | CLERK | 1300.00 | | 10 |
7369 | SMITH | CLERK | 800.00 | | 20 | researchmgr
7876 | ADAMS | CLERK | 1100.00 | | 20 | researchmgr
7499 | ALLEN | SALESMAN | 1600.00 | 1200.00 | 30 | salesmgr
7521 | WARD | SALESMAN | 1250.00 | 937.50 | 30 | salesmgr
7654 | MARTIN | SALESMAN | 1250.00 | 937.50 | 30 | salesmgr
7844 | TURNER | SALESMAN | 1500.00 | 1125.00 | 30 | salesmgr
7900 | JAMES | CLERK | 950.00 | 712.50 | 30 | salesmgr
(8 rows)DROP_POLICY
DROP_POLICY(object_schema VARCHAR2, object_name VARCHAR2,
policy_name VARCHAR2)參數
| 參數名稱 | 描述 |
| object_schema | 資料庫物件(政策應用於此資料庫物件之上)的模式名稱。 |
| object_name | 資料庫物件(政策應用於此資料庫物件之上)的名稱。 |
| policy_name | 要刪除的政策名稱。 |
樣本
下列樣本刪除了應用於表public. Vpemp的secure_update政策:
DECLARE
v_object_schema VARCHAR2(30) := 'public';
v_object_name VARCHAR2(30) := 'vpemp';
v_policy_name VARCHAR2(30) := 'secure_update';
BEGIN
DBMS_RLS.DROP_POLICY(
v_object_schema,
v_object_name,
v_policy_name
);
END;ENABLE_POLICY
ENABLE_POLICY(object_schema VARCHAR2, object_name VARCHAR2,
policy_name VARCHAR2, enable BOOLEAN)參數
| 參數名稱 | 描述 |
| object schema | 資料庫物件(政策應用於此資料庫物件之上)的模式名稱。 |
| object name | 資料庫物件(政策應用於此資料庫物件之上)的名稱。 |
| policy name | 要啟用或禁用的政策名稱。 |
| enable | 啟用或禁用政策。
|
樣本
下列樣本禁用了表public .vpemp上的secure_update政策:
DECLARE
v_object_schema VARCHAR2(30) := 'public';
v_object_name VARCHAR2(30) := 'vpemp';
v_policy_name VARCHAR2(30) := 'secure_update';
v_enable BOOLEAN := FALSE;
BEGIN
DBMS_RLS.ENABLE_POLICY(
v_object_schema,
v_object_name,
v_policy_name,
v_enable
);
END;