DBMS_RLS
パッケージには、ファイングレイン・アクセス・コントロールの管理インタフェースが含まれ、これを使用してVirtual Private Database (VPD)を実装します。DBMS_RLS
は、Enterprise Editionでのみ使用できます。
関連項目: DBMS_RLS の使用方法については、『Oracle Databaseセキュリティ・ガイド』を参照してください。 |
この章では、次の項目について説明します。
概要
セキュリティ・モデル
使用上の注意
ファイングレイン・アクセス・コントロールをサポートする機能は、動的な述語に基づいています。セキュリティ・ルールはビューに埋め込まれていませんが、元表またはビューがDML文で参照される、文の解析時に取得されます。
表、ビューまたはシノニムに対する動的な述語はPL/SQLファンクションが生成し、PL/SQLインタフェースを介してセキュリティ・ポリシーに関連付けられます。次に例を示します。
DBMS_RLS.ADD_POLICY ( 'hr', 'employees', 'emp_policy', 'hr', 'emp_sec', 'select');
HRスキーマの下にあるEMPLOYEES
表が問合せまたは副問合せ(SELECT
)で参照されるたびに、サーバーは、EMP_SEC
ファンクション(HR
スキーマの下にある)をコールします。このファンクションは、EMP_POLICY
ポリシーについて、現行のユーザーに固有の述語を戻します。ポリシー・ファンクションは、ファンクション・コール時に使用可能なセッション環境変数に基づいて述語を生成できます。これらの変数は通常、アプリケーション・コンテキストのフォームで表示されます。ポリシーでは、セキュリティ関連の列と、INDEX
、SELECT
、INSERT、UPDATE
、DELETE
などの文を自由に組み合せて指定できます。
次に、サーバーは、テキストがある一時ビューを作成します。
SELECT * FROM hr.employees WHERE P1
ここで、P1
(SAL
> 10000や副問合せなど)は、EMP_SEC
ファンクションから戻された述語です。サーバーは、EMPLOYEES
表をビューとして処理し、ビューのテキストをデータ・ディクショナリからではなく一時ビューから取得すること以外は、通常のビューと同様にビューの展開を行います。
述語に副問合せがある場合は、ポリシー・ファンクションの所有者(定義者)を使用して副問合せ内のオブジェクトを解決し、そのオブジェクトのセキュリティをチェックします。つまり、ポリシー保護されたオブジェクトへのアクセス権限を持つユーザーには、ポリシーについての知識は不要です。このユーザーには、基礎となるセキュリティ・ポリシーに対するオブジェクト権限の付与は不要です。さらに、サーバーはファンクション定義者の権限でコールを行うため、このユーザーにはポリシー・ファンクションでのEXECUTE
権限は不要です。
注意: 一時ビューは、単一表または述語のみを持つビュー(つまり、JOIN 、ORDER BY 、GROUP BY などがない)から導出されるため、親オブジェクトの更新可能性を保持できます。 |
DBMS_RLS
は、セキュリティ・ポリシーを削除するか使用可能にするためのインタフェースも提供します。たとえば、EMP_POLICY
を削除したり、使用可能にしたりする場合は、次のPL/SQL文を使用します。
DBMS_RLS.DROP_POLICY('hr', 'employees', 'emp_policy'); DBMS_RLS.ENABLE_POLICY('hr', 'employees', 'emp_policy', TRUE);
一時ビューが副問合せを使用して作成されると、セキュリティ・チェックが実行されます。ポリシー・ファンクションを持ち、動的な述語を生成するスキーマは、セキュリティ・チェックおよびオブジェクト検索を行う一時ビューの定義者です。
DBMS_RLS
プロシージャは、現行のDMLトランザクションがある場合は、操作前にコミットします。ただし、プロシージャがDDLイベント・トリガーの内部にある場合、プロシージャは最初にコミットを実行しません。DDLトランザクションでは、DBMS_RLS
プロシージャはDDLトランザクションの一部となります。
たとえば、ユーザーはCREATE
TABLE
のトリガーを作成できます。トリガー内部で、ALTER
TABLE
を介して列を追加でき、DBMS_RLS
を介してポリシーを追加できます。これらすべての操作は、それぞれがDDL文であっても、CREATE
TABLE
と同じトランザクション内にあります。CREATE
TABLE
は、トリガーが正常終了した場合のみ成功します。
現行のカーソルおよび対応する述語のビューはv$vpd_policies
から利用できます。
シノニムが参照できるのは、ビューまたは表のみです。
表125-1 DBMS_RLSパッケージのサブプログラム
サブプログラム | 説明 |
---|---|
|
ポリシー・グループに関連付けられたポリシーを追加します。 |
|
ファイングレイン・アクセス・コントロールのポリシーを表、ビューまたはシノニムに追加します。 |
|
アクティブなアプリケーションのコンテキストを追加します。 |
|
ポリシー・グループを作成します。 |
|
ポリシー・グループを削除します。 |
|
行レベルのグループ・セキュリティ・ポリシーを使用禁止にします。 |
|
ポリシー・グループに関連付けられたポリシーを削除します。 |
|
ファイングレイン・アクセス・コントロールのポリシーを表、ビューまたはシノニムから削除します。 |
|
駆動コンテキストが1つ少なくなるように、オブジェクトから駆動コンテキストを削除します。 |
|
行レベルのグループ・セキュリティ・ポリシーを使用可能または使用禁止にします。 |
|
ファイングレイン・アクセス・コントロールのポリシーを使用可能または使用禁止にします。 |
|
リフレッシュ・ポリシーに関連付けられたSQL文を再解析します。 |
|
ポリシーに関連付けられているすべてのキャッシュ済の文を再解析します。 |
このプロシージャは、ポリシー・グループに関連付けられたポリシーを追加します。
構文
DBMS_RLS.ADD_GROUPED_POLICY( object_schema IN VARCHAR2 NULL, object_name IN VARCHAR2, policy_group IN VARCHAR2 'SYS_DEFAULT', policy_name IN VARCHAR2, function_schema IN VARCHAR2 NULL, policy_function IN VARCHAR2, statement_types IN VARCHAR2 NULL, update_check IN BOOLEAN FALSE, enable IN BOOLEAN TRUE, static_policy IN BOOLEAN FALSE, policy_type IN BINARY_INTEGER NULL, long_predicate BOOLEAN FALSE, sec_relevant_cols IN VARCHAR2, sec_relevant_cols_opt IN BINARY_INTEGER NULL);
パラメータ
表125-2 ADD_GROUPED_POLICYプロシージャのパラメータ
パラメータ | 説明 |
---|---|
表、ビューまたはシノニムを含んでいるスキーマ。デフォルトは |
|
ポリシーを追加する表、ビューまたはシノニムの名前。 |
|
ポリシーが属するポリシー・グループの名前。 |
|
ポリシーの名前。同一の表またはビューで一意である必要があります。 |
|
ポリシー・ファンクションを所有するスキーマ。デフォルトは |
|
ポリシーの述語を生成するファンクションの名前。ファンクションがパッケージ内で定義されている場合、パッケージ名は必ず存在する必要があります。 |
|
ポリシーを適用する文タイプ。 |
|
|
|
ポリシーの追加時に、そのポリシーを使用可能にするかどうかを示します。デフォルトは |
|
デフォルトは |
|
デフォルト値の |
|
デフォルト値の |
|
列レベルのVirtual Private Database (VPD)を使用可能にします(このVPDによって、機密情報を保持している列が問合せで参照されたときにセキュリティ・ポリシーが実行されます)。表およびビューに適用されますが、シノニムには適用されません。ポリシーで保護されたオブジェクトについて、カンマ区切りまたはスペース区切りの有効な列名のリストを指定します。このポリシーが実行されるのは、ユーザーのSQL文またはその基礎となるビュー定義の中で、指定した列が参照されたとき(あるいは抽象データ・タイプの列の場合は、その属性が参照されたとき)のみです。デフォルトは、オブジェクトのユーザー定義列のすべてです。 |
|
|
|
使用上の注意
このプロシージャでは、指定した表、ビューまたはシノニムにポリシーが追加され、指定したポリシー・グループにそのポリシーが関連付けられます。
ポリシー・グループは、CREATE_POLICY_GROUPプロシージャを使用して作成する必要があります。
ポリシー名は、指定したオブジェクトのポリシー・グループ内で一意である必要があります。
デフォルトのポリシー・グループ(SYS_DEFAULT
)のポリシーは、アクティブなポリシー・グループに関係なく常に実行されます。ただし、ファイングレイン・アクセス・コントロールのポリシーは、EXEMPT ACCESS POLICY
システム権限を持つユーザーには適用されません。
object_schema
が指定されていない場合は、現在のユーザーのスキーマと想定されます。
function_schema
が指定されていない場合は、現在のユーザーのスキーマと想定されます。
このプロシージャは、ファイングレイン・アクセス・コントロールのポリシーを表、ビューまたはシノニムに追加します。
トランザクションがある場合、その現行のトランザクションはプロシージャによって操作の実行前にコミットを実行します。ただし、トランザクションがDDLイベント・トリガー内にある場合は、最初にコミットを実行しません。
コミット
は、操作の最後にも実行されます。
構文
DBMS_RLS.ADD_POLICY ( object_schema IN VARCHAR2 NULL, object_name IN VARCHAR2, policy_name IN VARCHAR2, function_schema IN VARCHAR2 NULL, policy_function IN VARCHAR2, statement_types IN VARCHAR2 NULL, update_check IN BOOLEAN FALSE, enable IN BOOLEAN TRUE, static_policy IN BOOLEAN FALSE, policy_type IN BINARY_INTEGER NULL, long_predicate IN BOOLEAN FALSE, sec_relevant_cols IN VARCHAR2 NULL, sec_relevant_cols_opt IN BINARY_INTEGER NULL);
パラメータ
表125-3 ADD_POLICYプロシージャのパラメータ
パラメータ | 説明 |
---|---|
表、ビューまたはシノニムを含んでいるスキーマ。 |
|
ポリシーを追加する表、ビューまたはシノニムの名前。 |
|
追加するポリシーの名前。同じ表またはビューでは固有の名前である必要があります。 |
|
ポリシー・ファンクションのスキーマ( |
|
ポリシーの述語を生成するファンクションの名前。ファンクションがパッケージ内で定義されている場合、パッケージ名は必ず存在する必要があります。 |
|
ポリシーを適用する文タイプ。 |
|
文タイプ |
|
ポリシーの追加時に、そのポリシーを使用可能にするかどうかを示します。デフォルトは |
|
デフォルトは |
|
デフォルト値の |
|
デフォルト値の |
|
列レベルのVirtual Private Database (VPD)を使用可能にします(このVPDによって、機密情報を保持している列が問合せで参照されたときにセキュリティ・ポリシーが実行されます)。表およびビューに適用されますが、シノニムには適用されません。ポリシーで保護されたオブジェクトについて、カンマ区切りまたはスペース区切りの有効な列名のリストを指定します。このポリシーが実行されるのは、ユーザーのSQL文またはその基礎となるビュー定義の中で、指定した列が参照されたとき(あるいは抽象データ・タイプの列の場合は、その属性が参照されたとき)のみです。デフォルトは、オブジェクトのユーザー定義列のすべてです。 |
|
|
表125-4 DBMS_RLS.ADD_POLICYのポリシー・タイプ
ポリシー・タイプ | 説明 |
---|---|
ランタイム環境にかかわらず、述語は同じになります。静的ポリシーの関数は一度だけ実行されてSGAにキャッシュされます。同じオブジェクトにアクセスする文の場合、ポリシー関数が再度実行されることはありません。ただし同じカーソルの実行ごとに、 |
|
同じポリシー・タイプの同一のポリシー・ファンクションにより生成されたキャッシュ済の述語が、最初にサーバーによって検索される点を除き、 |
|
最後にカーソルが使用されてからコンテキストが変更されていることが検出された場合、サーバーは文の実行時にポリシー・ファンクションを再評価します。複数のクライアントが1つのデータベース・セッションを共有するセッション・プーリングの場合、クライアント切り替え時に中間層でコンテキストをリセットする必要があります。サーバーは、このポリシー・タイプの関数により戻された値をキャッシュしません。サーバーは文の解析時にポリシー関数を実行します。1つのオブジェクトのみに適用されます。 |
|
同じデータベース・セッション内で、同じポリシー・タイプの同一のポリシー・ファンクションによって生成されたキャッシュ済の述語がサーバーにより最初に検索される点を除いて、 |
|
デフォルトのポリシー・タイプ。サーバーでは、どのようなシステム環境やセッション環境においても常になんらかの影響が述語にはあることを想定しているため、文の解析や実行のたびに必ずポリシー・ファンクションを再実行します。1つのオブジェクトのみに適用されます。 |
使用上の注意
SYS
は、セキュリティ・ポリシーの制約を受けません。
object_schema
が指定されていない場合は、現在のユーザーのスキーマと想定されます。
function_schema
が指定されていない場合は、現在のユーザーのスキーマと想定されます。
ポリシー・ファンクションは、サーバーがコールします。次の例は、ファンクションのインタフェースを示します。
FUNCTION policy_function (object_schema IN VARCHAR2, object_name VARCHAR2) RETURN VARCHAR2 --- object_schema is the schema owning the table or view. --- object_name is the name of table, view, or synonym to which the policy applies.
ポリシー・ファンクションには、WNDS
(データベースへの書込み禁止状態)の純正レベルが必要です。
関連項目: RESTRICT_REFERENCES プラグマの詳細は、『Oracle Databaseアドバンスト・アプリケーション開発者ガイド』を参照してください。 |
同じオブジェクトにある複数のVPDポリシーから生成された述語は、全述語の論理積(AND
条件)の結合効果があります。
セキュリティ・チェックおよびオブジェクト検索は、動的な述語の副問合せで、オブジェクトのポリシー・ファンクションの所有者に対して実行されます。
ファンクションが長さ0(ゼロ)の述語を戻す場合は、ポリシーについて現行のユーザーに適用する制限はないと解釈されます。
述語で表の別名が必要な場合(たとえば、親オブジェクトが表タイプの場合)は、表またはビューの名前自体を別名として使用する必要があります。サーバーは次のような一時ビューを構成します。
"select c1, c2, ... from tab tab where <predicate>"
実行時にファンクションの妥当性チェックを行う目的は、インストールを容易にするため、およびインポート/エクスポート中に起こるその他の依存する問題を軽減するためです。
列レベルのVPD列マスクの動作(sec_relevant_cols_opt => dbms_rls.ALL_ROWS
で指定)は、行のサブセットのみを戻す他のすべてのVPDポリシーとは根本的に異なります。列マスクの動作では、ユーザーの問合せで指定されたすべての行を戻しますが、機密情報の列の値はNULL
と表示されます。このオプションには次の制約があります。
SELECT
文にのみ適用されます。
通常のVPD述語とは異なり、このポリシー・ファンクションで生成するマスク条件は、単純なブール式にする必要があります。
アプリケーションで計算処理を実行し、また、計算結果にNULL
値を想定しない場合は、列レベルのVPDのデフォルト動作を使用する必要があります。これはsec_relevant_cols
パラメータで指定します。
このオプションとともにUPDATE AS SELECT
を使用すると、表示を許可されている列の値のみが更新されます。
このオプションを使用すると表示されない行があります。次に例を示します。
select * from employees where salary = 10
列マスクのオプションが設定されているため、salary
列からNULL
値が戻された場合、この問合せでは行が戻らない可能性があります。
シノニムにVPDポリシーを追加すると、そのシノニムのすべての依存オブジェクト(シノニムを参照するポリシー・ファンクションを含む)がINVALID
とマークされます。
例
2つの例の最初のものとして、次によってhr.employee
表に適用されるポリシーが作成されます。これは列レベルのVPDポリシーで、SELECT
文またはINDEX
文が表のsalary
、birthdate
またはSSN
列を明示的に参照するか、ビューを使用して暗黙的に参照した場合にのみ実行されます。また、CONTEXT_SENSITIVE
ポリシーでもあるため、サーバーは、解析時にポリシー・ファンクションhr.hrfun
を起動します。実行中にファンクションが起動されるのは、いずれかのセッションのプライベート・コンテキストが文カーソルの最終使用時とは変わっている場合のみです。long_predicate
パラメータはコールから除外されるため、ポリシー・ファンクションによって生成された述語が4000バイト(デフォルトの長さ制限)を超えないようにしてください。
BEGIN dbms_rls.add_policy(object_schema => 'hr',
object_name => 'employee', policy_name => 'hr_policy', function_schema =>'hr', policy_function => 'hrfun', statement_types =>'select,index', policy_type => dbms_rls.CONTEXT_SENSITIVE, sec_relevant_cols=>'salary,birthdate,ssn');
END; /
2番目の例では、次のコマンドによってホスティング用の同じオブジェクトに適用される別のポリシーが作成されるため、ユーザーは各自のサブスクライバIDに基づくデータのみにアクセスできます。これはSHARED_STATIC
ポリシー・タイプとして定義されるため、サーバーはまずSGAキャッシュ内で述語の検索を試みます。検索できなかった場合、サーバーはポリシー・ファンクションsubfun
の起動のみを行います。
BEGIN dbms_rls.add_policy(object_schema => 'hr', object_name => 'employee', policy_name => 'hosting_policy', function_schema =>'hr', policy_function => 'subfun', policy_type => dbms_rls.SHARED_STATIC); END; /
このプロシージャは、アクティブなアプリケーションのコンテキストを追加します。
構文
DBMS_RLS.ADD_POLICY_CONTEXT ( object_schema IN VARCHAR2 NULL, object_name IN VARCHAR2, namespace IN VARCHAR2, attribute IN VARCHAR2);
使用上の注意
次の点に注意してください。
このプロシージャでは、ポリシーを実施するアプリケーション・コンテキストが示されます。このコンテキストは、実行するアプリケーションを決定します。
object_schema
が指定されていない場合は、現在のユーザーのスキーマと想定されます。
駆動コンテキストはセッションにもグローバルにもできます。
実行時、サーバーはこのコンテキストの値からアクティブなポリシー・グループの名前を取り出します。
ファイングレイン・アクセス・コントロールのポリシーを持つ各オブジェクトには、それぞれ少なくとも1つの駆動コンテキストを定義する必要があります。定義しない場合は、そのオブジェクトのすべてのポリシーが実行されます。
複数のコンテキストを同一のオブジェクトに追加すると、複数のポリシー・グループのポリシーが施行されます。
駆動コンテキストがNULL
の場合は、すべてのポリシー・グループのポリシーが使用されます。
ポリシーを所有するポリシー・グループが駆動コンテキストである場合、そのポリシー・グループ内の使用可能なすべてのポリシーが、SYS_DEFAULT
ポリシー・グループの全ポリシーとともに適用されます。
ポリシーをaccess_control_group
グループのhr.employees
表に追加するには、次のコマンドを発行します。
DBMS_RLS.ADD_GROUPED_POLICY('hr','employees','access_control_group','policy1','SYS', 'HR.ACCESS');
このプロシージャはポリシー・グループを作成します。
構文
DBMS_RLS.CREATE_POLICY_GROUP ( object_schema IN VARCHAR2 NULL, object_name IN VARCHAR2, policy_group IN VARCHAR2);
このプロシージャはポリシー・グループを削除します。
構文
DBMS_RLS.DELETE_POLICY_GROUP ( object_schema IN VARCHAR2 NULL, object_name IN VARCHAR2, policy_group IN VARCHAR2);
このプロシージャは、行レベルのグループ・セキュリティ・ポリシーを使用禁止にします。
構文
DBMS_RLS.DISABLE_GROUPED_POLICY ( object_schema IN VARCHAR2 NULL, object_name IN VARCHAR2, group_name IN VARCHAR2, policy_name IN VARCHAR2);
ポリシー・グループに対応付けられたポリシーを削除します。
このプロシージャは、ファイングレイン・アクセス・コントロールのポリシーを表、ビューまたはシノニムから削除します。
トランザクションがある場合、その現行のトランザクションはプロシージャによって操作の実行前にコミットを実行します。ただし、トランザクションがDDLイベント・トリガー内にある場合は、最初にコミットを実行しません。
コミットは、操作の最後にも実行されます。
構文
DBMS_RLS.DROP_POLICY ( object_schema IN VARCHAR2 NULL, object_name IN VARCHAR2, policy_name IN VARCHAR2);
このプロシージャは、駆動コンテキストが1つ少なくなるように、オブジェクトから駆動コンテキストを削除します。
このプロシージャは、行レベルのグループ・セキュリティ・ポリシーを使用可能または使用禁止にします。
構文
DBMS_RLS.ENABLE_GROUPED_POLICY ( object_schema IN VARCHAR2 NULL, object_name IN VARCHAR2, group_name IN VARCHAR2, policy_name IN VARCHAR2, enable IN BOOLEAN TRUE);
このプロシージャは、ファイングレイン・アクセス・コントロールのポリシーを使用可能または使用禁止にします。ポリシーは、その作成時に使用可能になっています。
トランザクションがある場合、その現行のトランザクションはプロシージャによって操作の実行前にコミットを実行します。ただし、トランザクションがDDLイベント・トリガー内にある場合は、最初にコミットを実行しません。
コミット
は、操作の最後にも実行されます。
このプロシージャは、リフレッシュ・ポリシーに関連付けられたSQL文を再解析します。
構文
DBMS_RLS.REFRESH_GROUPED_POLICY ( object_schema IN VARCHAR2 NULL, object_name IN VARCHAR2 NULL, group_name IN VARCHAR2 NULL, policy_name IN VARCHAR2 NULL);
このプロシージャは、ポリシーに関連付けられたすべてのキャッシュ済の文を再解析します。これにより、ポリシーへの最新の変更内容がプロシージャの実行直後に有効になります。
トランザクションがある場合、その現行のトランザクションはプロシージャによって操作の実行前にコミットを実行します。ただし、トランザクションがDDLイベント・トリガー内にある場合は、最初にコミットを実行しません。
コミットは、操作の最後にも実行されます。
構文
DBMS_RLS.REFRESH_POLICY ( object_schema IN VARCHAR2 NULL, object_name IN VARCHAR2 NULL, policy_name IN VARCHAR2 NULL);