実行者権限および定義者権限(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セキュリティ・ガイド』を参照
ここでのトピック
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セキュリティ・ガイド』を参照してください。
IRユニットにはテンプレート・オブジェクトが必要
1人のユーザー(つまり1つのスキーマ)がIRユニットを所有し、他のユーザーは自身のスキーマ内でそのユニットを実行します。IRユニットが静的SQL文を発行する場合、これらの文が影響するスキーマ・オブジェクトはコンパイル時には所有者のスキーマ内に存在する必要があり(コンパイラが参照を解決できるように)、また実行時には起動者のスキーマ内に存在する必要があります。対応するスキーマ・オブジェクトの定義が一致する必要があります(たとえば、対応する表の名前と列が同じである必要があります)。一致していない場合は、エラーまたは予期しない結果が発生します。ただし、コンパイラで不要なため、所有者のスキーマ内のオブジェクトはデータを含む必要はありません。したがって、これらのオブジェクトはテンプレート・オブジェクトと呼ばれます。
DRユニット内の接続ユーザー・データベース・リンク
DRユニット(定義者権限ユニット)に接続ユーザー・データベース・リンクを含める場合、DRユニットを実行するユーザーにINHERIT REMOTE PRIVILEGES
権限を付与する必要があります。
この権限をユーザーに付与すると、そのユーザーはDRユニットを実行できるようになります。付与していない場合、ORA-25433: ユーザーにはINHERIT REMOTE PRIVILEGESがありません
エラーとともに実行は失敗します。定義者権限(DR)プロシージャ内から接続ユーザー・データベース・リンクを含めるには、プロシージャに@database_link
を含めます。
次の例は、DRユニットがdblink
というデータベース・リンクを使用してHR.EMPLOYEES
表のEMPLOYEE_ID
列にアクセスする方法を示しています。
例9-45 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セキュリティ・ガイドを参照してください