8.14 実行者権限および定義者権限(AUTHIDプロパティ)
ストアドPL/SQLユニットのAUTHIDプロパティは、実行時にユニットによって発行されるSQL文の名前解決および権限チェックに影響します。AUTHIDプロパティはコンパイルには影響せず、コレクション型などのコードのないユニットに対しては意味を持ちません。
AUTHIDプロパティ値は、静的データ・ディクショナリ・ビュー*_PROCEDURESに公開されます。AUTHIDが意味を持つユニットの場合はビューに値CURRENT_USERまたはDEFINERが表示され、他のユニットの場合はビューにNULLが表示されます。
次の文で作成または変更するストアドPL/SQLユニットについては、オプションのAUTHID句を使用して、DEFINER(デフォルト、下位互換性用)またはCURRENT_USER(優先用途)を指定できます。
AUTHID値がCURRENT_USERのユニットは、実行者権限ユニットまたはIRユニットと呼ばれます。AUTHID値がDEFINER(デフォルト)のユニットは、定義者権限ユニットまたはDRユニットと呼ばれます。AUTHID値を指定できないPL/SQLユニットおよびスキーマ・オブジェクトは次のように動作します。
| PL/SQLユニットまたはスキーマ・オブジェクト | 動作 |
|---|---|
|
無名ブロック |
IRユニット |
|
|
IRユニットに類似(『Oracle Databaseセキュリティ・ガイド』を参照) |
|
|
DRユニット |
|
トリガー |
DRユニット |
ユニットのAUTHIDプロパティによって、そのユニットがIRであるかDRであるかが決まります。このプロパティは実行時の名前解決および権限チェックの両方に影響します。
-
名前解決のコンテキストは
CURRENT_SCHEMAです。 -
権限チェックのコンテキストは
CURRENT_USERおよび有効になっているロールです。
セッションが開始されると、CURRENT_SCHEMAの値はSESSION_USERが所有するスキーマの値となり、CURRENT_USERの値はSESSION_USERの値と同じになります。(CURRENT_SCHEMA、CURRENT_USERまたはSESSION_USERの現在の値を取得するには、『Oracle Database SQL言語リファレンス』で説明されているSYS_CONTEXTファンクションを使用します。)
CURRENT_SCHEMAは、SQL文ALTER SESSION SET CURRENT_SCHEMAを使用してセッション中に変更できます。CURRENT_USERは、プログラムでは変更できませんが、PL/SQLユニットまたはビューがコール・スタックに格納されたり、コール・スタックから取り出されると、変更される場合があります。
ノート:
ALTER SESSION SET CURRENT_SCHEMAは、ストアドPL/SQLユニット内から発行しないことをお薦めします。
サーバー・コール中にDRユニットがコール・スタックに格納されると、データベースによって、現在有効になっているロール、およびCURRENT_USERとCURRENT_SCHEMAの現在の値が格納されます。次に、CURRENT_USERとCURRENT_SCHEMAの両方がDRユニットの所有者に変更され、ロールPUBLICのみが有効にされます。(格納されたロールおよび値と新しいロールおよび値は、異なるとはかぎりません。) DRユニットがコール・スタックから取り出されると、データベースによって、格納されたロールおよび値がリストアされます。これに対し、IRユニットがコール・スタックに格納されたり、コール・スタックから取り出されても、CURRENT_USERとCURRENT_SCHEMAの値および現在有効になっているロールは変更されません(ロールがIRユニット自体に付与されていないかぎり。「PL/SQLパッケージおよびスタンドアロン・プログラムへのロールの付与」を参照)。
PL/SQLユニットによって発行される動的SQL文の場合、名前解決および権限チェックは実行時に1回行われます。静的SQL文の場合、名前解決および権限チェックは、PL/SQLユニットのコンパイル時、およびその後の実行時の2回行われます。コンパイル時に、AUTHIDプロパティは影響しません(DRユニットとIRユニットの両方がDRユニットのように処理されます)。ただし、実行時には、AUTHIDプロパティによってユニットがIRであるかDRであるかが決まり、その結果に従ってユニットは処理されます。
IRユニットの開始時に、初期化またはなんらかのコードの実行前に、ランタイム・システムにより権限がチェックされます。ユニット所有者に起動者に対するINHERIT PRIVILEGES権限またはINHERIT ANY PRIVILEGES権限のいずれもなければ、ランタイム・システムによりエラーORA-06598が発行されます。
ノート:
ユニット所有者に必要な権限がある場合、その権限は次のいずれかの文により付与されています。
GRANT INHERIT PRIVILEGES ON current_user TO PUBLIC GRANT INHERIT PRIVILEGES ON current_user TO unit_owner GRANT INHERIT ANY PRIVILEGES TO unit_owner
GRANT文の詳細は『Oracle Database SQL言語リファレンス』を参照してください。
関連項目:
-
DRおよびIRユニットのセキュリティの管理の詳細は、『Oracle Databaseセキュリティ・ガイド』を参照してください。
-
DRおよびIRプログラム・ユニットのコンパイルに必要な権限の取得の詳細は、『Oracle Databaseセキュリティ・ガイド』を参照
ここでのトピック
8.14.1 PL/SQLパッケージおよびスタンドアロン・サブプログラムへのロールの付与
SQL GRANTコマンドを使用して、PL/SQLパッケージおよびスタンドアロン・サブプログラムにロールを付与できます。PL/SQLユニットに付与されたロールはコンパイルには影響しません。ロールはユニットが実行時に発行するSQL文の権限チェックに影響します。ユニットは、自身のロールと現在有効になっているその他のロールの両方の権限で実行されます。
通常、自分より低い権限のユーザーがユニットの実行に必要な権限でのみユニットを実行できるように、IRユニットにロールを付与します。DRユニット(起動者により定義者のすべての権限で実行される)にロールを付与するのは、そのDRユニットが実行時にのみチェックされる動的SQLを発行する場合のみです。
PL/SQLユニットにロールを付与するための基本構文は次のとおりです。
GRANT role [, role ]... TO unit [, unit ]...
たとえば、このコマンドはロールreadとexecuteをファンクションscott.funcとパッケージsys.pkgに付与します。
GRANT read, execute TO FUNCTION scott.func, PACKAGE sys.pkg
GRANTコマンドの構文およびセマンティクスの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
関連項目:
-
PL/SQLユニットのロールを取り消すための
REVOKEコマンドの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。 -
アプリケーション・ユーザーおよびアプリケーション・ロールの構成の詳細は、『Oracle Databaseセキュリティ・ガイド』を参照してください。
8.14.2 IRユニットにはテンプレート・オブジェクトが必要
1人のユーザー(つまり1つのスキーマ)がIRユニットを所有し、他のユーザーは自身のスキーマ内でそのユニットを実行します。IRユニットが静的SQL文を発行する場合、これらの文が影響するスキーマ・オブジェクトはコンパイル時には所有者のスキーマ内に存在する必要があり(コンパイラが参照を解決できるように)、また実行時には起動者のスキーマ内に存在する必要があります。対応するスキーマ・オブジェクトの定義が一致する必要があります(たとえば、対応する表の名前と列が同じである必要があります)。一致していない場合は、エラーまたは予期しない結果が発生します。ただし、コンパイラで不要なため、所有者のスキーマ内のオブジェクトはデータを含む必要はありません。したがって、これらのオブジェクトはテンプレート・オブジェクトと呼ばれます。
8.14.3 DRユニット内の接続ユーザー・データベース・リンク
DRユニット(定義者権限ユニット)に接続ユーザー・データベース・リンクを含める場合、DRユニットを実行するユーザーにINHERIT REMOTE PRIVILEGES権限を付与する必要があります。
この権限をユーザーに付与すると、そのユーザーはDRユニットを実行できるようになります。付与していない場合、ORA-25433: User does not have INHERIT REMOTE PRIVILEGESエラーとともに実行は失敗します。定義者権限(DR)プロシージャ内から接続ユーザー・データベース・リンクを含めるには、プロシージャに@database_linkを含めます。
次の例は、DRユニットがdblinkというデータベース・リンクを使用してHR.EMPLOYEES表のEMPLOYEE_ID列にアクセスする方法を示しています。
例8-43 DRユニット内のデータベース・リンク
CREATE OR REPLACE PROCEDURE hr_remote_db_link
AS
v_employee_id VARCHAR(50);
BEGIN
EXECUTE IMMEDIATE 'SELECT employee_id FROM employees@dblink' into v_employee_id;
DBMS_OUTPUT.PUT_LINE('employee_id: ' || v_employee_id);
END ;
/関連項目:
INHERIT REMOTE PRIVILEGES権限の使用に関する詳細(DRユニットでデータベース・リンクを使用する方法のチュートリアルを含む)は、Oracle Databaseセキュリティ・ガイドを参照してください