7 定義者権限および実行者権限のセキュリティの管理

ユーザー作成プロシージャの実行権限へのアクセス制御で実行者権限および定義者権限を使用すると、セキュリティ上のメリットが得られます。

定義者権限および実行者権限について

定義者権限および実行者権限は、ユーザー作成プロシージャまたはプログラム・ユニットの実行に必要な権限へのアクセスを制御するときに使用されます。

定義者権限プロシージャでは、プロシージャが所有者の権限で実行されます。権限は、作成されたスキーマにバインドされます。実行者の権限プロシージャは現行ユーザー(プロシージャを実行するユーザー)の権限で実行されます。

たとえば、ユーザーbixbyが表cust_recordsを変更するために設計されるプロシージャを作成し、このプロシージャのEXECUTE権限をユーザーrlaytonに付与するとします。bixbyが定義者権限でプロシージャを作成した場合、プロシージャはbixbyのスキーマの表cust_recordsを検索します。プロシージャが実行者権限で作成された場合、rlaytonが実行すると、プロシージャはrlaytonのスキーマの表cust_recordsを検索します。

デフォルトでは、すべてのプロシージャは、定義者権限とみなされます。作成時または変更時に、AUTHID CURRENT_USER句を使用してプロシージャを実行者権限プロシージャに指定するか、AUTHID DEFINER句を使用して定義者権限プロシージャに変更できます。

権限分析ポリシーを作成して、定義者権限および実行者権限プロシージャの権限の使用を取得できます。

プロシージャに対する権限が定義者権限に与える影響

定義者と呼ばれるプロシージャの所有者は、プロシージャが参照するオブジェクトに対する必要なオブジェクト権限を所有している必要があります。

プロシージャ所有者が別のユーザーにそのプロシージャを使用する権限を付与すると、(プロシージャで参照されるオブジェクトに対する)プロシージャ所有者の権限が、権限受領者のプロシージャ実行に適用されます。プロシージャの定義者の権限は、ロールを介してではなく、プロシージャ所有者に直接付与する必要があります。これらは、定義者権限と呼ばれます。

所有者以外のプロシージャのユーザーは、実行者と呼ばれます。実行者権限プロシージャの場合は、参照オブジェクトに対する追加の権限が必要ですが、 定義者権限プロシージャの場合は不要です。

定義者権限プロシージャのユーザーに必要なのは、そのプロシージャを実行する権限のみで、そのプロシージャでアクセスする基礎となるオブジェクトに対する権限は不要です。これは、定義者権限プロシージャは、その実行者に関係なく、プロシージャを所有するユーザーのセキュリティ・ドメインの下で動作するためです。プロシージャの所有者は、参照オブジェクトに対する必要なオブジェクト権限をすべて所有している必要があります。定義者権限プロシージャのユーザーに付与する権限は、できるかぎり控えめに付与してください。これによって、データベース・アクセスを厳密に制御できます。

定義者権限プロシージャを使用すると、プライベート・データベース・オブジェクトへのアクセスを制御し、データベースのセキュリティ・レベルを強化できます。定義者権限プロシージャを記述し、ユーザーにEXECUTE権限のみを付与することによって、そのプロシージャを介さない場合には、このユーザーが参照オブジェクトにアクセスできないように規定できます。

実行時には、定義者権限プロシージャの所有者の権限によってそのプロシージャの参照オブジェクトへのアクセスが許可されているかどうかが、プロシージャの実行前にチェックされます。参照オブジェクトに対して必要な権限が、定義者権限プロシージャの所有者から取り消されていると、所有者を含むユーザーは、プロシージャを実行できません。

定義者権限プロシージャを使用する場合の例は次のとおりです。表へのアクセスが制限されていないプロシージャを持つAPIを作成する必要があるとします。ただし、一般ユーザーが表のデータを直接選択し、INSERT文、UPDATE文およびDELETE文を使用して変更しないようにする必要があります。これを実行するには、個別の権限の弱いスキーマで、APIを構成する表およびプロシージャを作成します。デフォルトでは各プロシージャは定義者権限ユニットであるため、作成時にAUTHID DEFINERを指定する必要がありません。次に、EXECUTE権限をこのAPIを使用する必要があるユーザーに付与しますが、データ・アクセスを許可する権限を付与しないでください。この解決策は、API動作の完全な制御およびユーザーが基礎オブジェクトにアクセスする方法を提供します。

独自のスキーマで、定義者権限プロシージャおよびこれらのプロシージャにアクセスするビューを作成することをお薦めします。このスキーマに非常に弱い権限を付与するか、権限を付与しません。これによって、他のユーザーがこれらのプロシージャまたはビューを実行する場合、このスキーマの不要な高い権限にアクセスしません。

ノート:

トリガーの処理は、定義者権限プロシージャと同じパターンに従います。ユーザーは、実行権限があるSQL文を実行します。このSQL文の実行結果として、トリガーが起動されます。トリガーされたアクション内の文は、そのトリガーを所有するユーザーのセキュリティ・ドメインで一時的に実行されます。トリガーの概要は、『Oracle Database概要』を参照してください。

プロシージャに対する権限が実行者権限に与える影響

実行者権限プロシージャは、すべての実行者権限で実行されます。

実行者の使用可能な任意のロールを介してその実行者に付与された権限は、定義者権限プロシージャによって実行者権限プロシージャが直接または間接的にコールされないかぎり有効です。実行者権限プロシージャのユーザーには、そのプロシージャが実行者のスキーマ内で解決される外部参照を介してアクセスする、オブジェクトに対する権限(直接またはロールを介して付与されたもの)が必要です。実行者が実行者権限プロシージャを実行する場合、このユーザーは、実行者のすべての権限を一時的に保持します。

実行者には、DML文または動的SQL文に埋め込まれているプログラム参照にアクセスする権限が実行時に必要です。これは、この種のプログラム参照は実質的に実行時に再コンパイルされるためです。

PL/SQLファンクションの直接コールなど、他のすべての外部参照の場合、所有者権限はコンパイル時にチェックされ、実行時にはチェックされません。したがって、実行者権限プロシージャのユーザーには、DML文や動的SQL文の外側にある外部参照に対する権限は不要です。また、実行者権限プロシージャの開発者による権限の付与が必要なのは、プロシージャ自体に対する権限付与のみで、その実行者権限プロシージャによって直接参照されるすべてのオブジェクトに対する権限付与は必要ありません。

複数のプログラム・ユニットからなり、そのうちのいくつかは定義者権限、その他は実行者権限とするソフトウェア・バンドルを作成して、プログラム・エントリ・ポイントを制限できます(制御されたステップイン)。エントリ・ポイント・プロシージャの実行権限があるユーザーは、内部プログラム・ユニットも間接的に実行できますが、内部プログラムを直接コールすることはできません。問合せ処理を厳密に制御するには、PL/SQLパッケージ仕様を明示的なカーソルを使用して作成できます。

実行者権限プロシージャを作成する場合

特定の状況で実行者権限プロシージャを作成することをお薦めします。

これらの状況は次のとおりです。

  • 権限の高いスキーマのPL/SQLプロシージャを作成する場合。権限の弱いユーザーがプロシージャを起動する場合、それらのユーザーが実行を許可された部分のみ実行できます。つまり、実行者権限プロシージャは、実行するユーザーの権限で実行されます。

  • PL/SQLプロシージャがSQLを含まず、PL/SQLプロシージャを他のユーザーが使用できる場合。DBMS_OUTPUT PL/SQLパッケージは、SQLを含まないすべてのユーザーが使用できるPL/SQLサブプログラムの例です。この状況で実行者権限プロシージャを使用する必要がある理由は、ユニットが実行時にSQL文を発行しないので、実行時システムが権限をチェックする必要がないためです。AUTHID CURRENT_USERを指定すると、実行者権限プロシージャがコール・スタックを使用する場合にCURRENT_USERおよびCURRENT_SCHEMAの値と現在有効なロールが変更されないため、プロシージャの起動がより効率的になります。

関連項目:

プロシージャ・コールおよびビュー・アクセスの実行者権限の制御

INHERIT PRIVILEGES権限およびINHERIT ANY PRIVILEGES権限は、実行者権限プロシージャの実行時に使用される権限を規制します。

スキーマの権限が実行者権限プロシージャの使用に与える影響

権限の低いユーザーが権限の高いユーザーが所有するプロシージャを実行するような場合は、実行者権限プロシージャが便利です。

ユーザーが実行者権限プロシージャ(またはAUTHID CURRENT_USER句で作成されたPL/SQLプログラム・ユニット)を実行する場合、プロシージャの実行中に実行するユーザーのすべての権限を一時的に継承します。

その期間中に、プロシージャ所有者は、プロシージャを通じて、この実行するユーザーの権限にアクセスできます。次の使用例を考えてみます。

  1. ユーザーebrownは、check_syntax実行者権限プロシージャを作成し、ユーザーjwardにそのEXECUTE権限を付与します。

  2. 準プログラマのユーザーebrownは、仕事に必要な最低限のセットの権限のみです。check_syntaxプロシージャは、ebrownのスキーマにあります。

  3. マネージャのユーザーjwardは、ユーザーebrownよりさらに強力なセットの権限を持ちます。

  4. ユーザーjwardcheck_syntax実行者権限プロシージャを実行する場合、プロシージャは実行中にユーザーjwardより高い権限を継承します。

  5. ユーザーebrowncheck_syntaxプロシージャを所有するため、jwardcheck_syntaxプロシージャを実行するたびに、ユーザーjwardの権限にアクセスできます。

jwardがプロシージャを実行するたびに権限の弱いebrownのプロシージャがjwardの高い権限にアクセスできるこのタイプの状況の危険性は、プロシージャ所有者が実行するユーザーの高い権限を悪用できるリスクがあることです。たとえば、ユーザーebrownは、check_syntaxプロシージャをリライトしてebrownを上げるかebrownの不良なパフォーマンス評価レコードを削除して、jwardの高い権限を使用する可能性があります。また、ebrownは、元から定義者権限プロシージャとしてプロシージャを作成し、EXECUTE権限をjwardに付与して、後でjwardに通知することなく不正な可能性のある実行者権限プロシージャに変更できた可能性があります。アプリケーション・ユーザーなどのランダムなユーザーが実行者権限プロシージャを使用するデータベースにアクセスできる場合、これらのタイプのリスクが増加します。

ユーザーjwardebrownの実行者権限プロシージャを実行する場合、信頼要素が含まれます。ebrownjwardの権限にアクセスする場合に悪質な方法でcheck_syntaxプロシージャを使用しないことを確認する必要があります。INHERIT PRIVILEGESおよびINHERIT ANY PRIVILEGES権限は、ユーザーjwardに対してユーザーebrownのプロシージャがjwardの権限にアクセスできるかどうかの制御をサポートできます。ユーザーは、実行する実行者権限プロシージャのユーザーへのINHERIT PRIVILEGES権限を付与または取り消すことができます。SYSユーザーは、INHERIT ANY PRIVILEGES権限を管理します。

INHERIT [ANY] PRIVILEGES権限による権限アクセスの制御方法

INHERIT PRIVILEGESおよびINHERIT ANY PRIVILEGES権限を使用して、実行者権限プロシージャを保護します。

INHERIT PRIVILEGESおよびINHERIT ANY PRIVILEGES権限は、ユーザーが実行者権限プロシージャを実行するか、実行者権限プロシージャを参照するBEQUEATH CURRENT_USERビューに問い合せる場合に使用される権限を規制します。

ユーザーが実行者権限プロシージャを実行する場合、Oracle Databaseは、プロシージャ所有者が実行するユーザーのINHERIT PRIVILEGES権限を持っているか、所有者にINHERIT ANY PRIVILEGES権限が付与されているかを確認します。権限チェックに失敗した場合、Oracle Databaseは、 ORA-06598: INHERIT PRIVILEGES権限が不十分ですエラーを戻しません。

これらの2つの権限の利点は、実行者権限プロシージャを実行するか、BEQUEATH CURRENT_USERビューに問い合せる場合、実行するユーザーに権限にアクセスできるユーザーの制御を提供することです。

他のユーザーへのINHERIT PRIVILEGES権限の付与

デフォルトで、すべてのユーザーにINHERIT PRIVILEGES ON USER newuser TO PUBLICが付与されます。

付与が行われるのは、ユーザー・アカウントの作成時または以前に作成されたアカウントが現在のリリースにアップグレードされたときです。

実行するユーザーは、他のユーザーのINHERIT PRIVILEGE権限を取り消して、信頼するユーザーにのみ付与できます。

INHERIT PRIVILEGES権限の付与の構文は次のとおりです。

GRANT INHERIT PRIVILEGES ON USER invoking_user TO procedure_owner;

詳細は、次のとおりです。

  • invoking_userは、実行者権限プロシージャを実行するユーザーです。このユーザーは、データベース・ユーザー・アカウントである必要があります。

  • procedure_ownerは、実行者権限プロシージャを所有するユーザーです。この値は、データベース・ユーザー・アカウントである必要があります。INHERIT PRIVILEGES権限をプロシージャの所有者に付与するかわりに、プロシージャに付与されるロールに権限を付与できます。

次のユーザーまたはロールは、実行者権限プロシージャを実行するユーザーによって付与されるINHERIT PRIVILEGES権限を持つ必要があります。

  • 実行者権限プロシージャを所有するユーザーまたはロール

  • BEQUEATH CURRENT_USERビューを所有するユーザーまたはロール

例: 実行するユーザーのINHERIT PRIVILEGESの付与

GRANT文で、実行するユーザーのINHERIT PRIVILEGES権限をプロシージャ所有者に付与できます。

例7-1は、実行するユーザーjwardがユーザーebrownINHERIT PRIVILEGES権限を付与する方法を示しています。

例7-1 プロシージャ所有者への実行するユーザーのINHERIT PRIVILEGESの付与

GRANT INHERIT PRIVILEGES ON USER jward TO ebrown;

この文により、jwardが実行するとき、ebrownが書き込むまたは今後書き込む実行者権限プロシージャがjwardの権限にアクセスできます。

例: INHERIT PRIVILEGESの取消し

REVOKE文で、ユーザーのINHERIT PRIVILEGES権限を取り消すことができます。

例7-2は、ユーザーjwardebrownの権限の使用を取り消す方法を示しています。

例7-2 INHERIT PRIVILEGESの取消し

REVOKE INHERIT PRIVILEGES ON USER jward FROM ebrown;

他のユーザーへのINHERIT ANY PRIVILEGES権限の付与

デフォルトでは、ユーザーSYSは、INHERIT ANY PRIVILEGESシステム権限を持ち、この権限を他のデータベース・ユーザーまたはロールに付与できます。

すべてのANY権限と同様に、信頼できるユーザーまたはロールにのみこの権限を付与します。ユーザーまたはロールにINHERIT ANY PRIVILEGES権限が付与されると、このユーザーの実行者権限プロシージャは、実行するユーザーの権限にアクセスできます。DBA_SYS_PRIVSデータ・ディクショナリ・ビューを問い合せて、INHERIT ANY PRIVILEGES権限を付与されたユーザーを確認できます。

例: 信頼できるプロシージャ所有者へのINHERIT ANY PRIVILEGESの付与

GRANT文で、INHERIT ANY PRIVILEGES権限を信頼できるプロシージャ所有者に付与できます。

例7-3は、ユーザーebrownへのINHERIT ANY PRIVILEGES権限の付与方法を示しています。

例7-3 信頼できるプロシージャ所有者へのINHERIT ANY PRIVILEGESの付与

GRANT INHERIT ANY PRIVILEGES TO ebrown;

強力なユーザーのINHERIT ANY PRIVILEGES権限の取消しに注意してください。たとえば、ユーザーSYSTEMが一連の実行者権限プロシージャを作成したとします。SYSTEMINHERIT ANY PRIVILEGESを取り消す場合、INHERIT PRIVILEGE権限を特に付与しないかぎり、他のユーザーはプロシージャを実行できません。

INHERIT PRIVILEGESおよびINHERIT ANY PRIVILEGESの管理

デフォルトでは、PUBLICは、新しいユーザー・アカウントおよびアップグレードされたユーザー・アカウントのINHERIT PRIVILEGE権限を持ち、SYSユーザーは、INHERIT ANY PRIVILEGES権限を持ちます。

デフォルトでは、様々なOracleで定義されているユーザーの権限の悪用に対して保護できるよう設計されている一連のINHERIT PRIVILEGESの付与を構成します。

顧客が定義するユーザーのINHERIT PRIVILEGES ON USER user_name TO PUBLICのデフォルトの付与を取り消して、その特定のユーザーに応じて詳細な付与のINHERIT PRIVILEGESを付与できます。INHERIT ANY PRIVILEGES権限を付与されたユーザーを確認するには、DBA_SYS_PRIVSデータ・ディクショナリ・ビューを問い合せます。

  1. PUBLICからINHERIT PRIVILEGES権限を取り消します。

    例:

    REVOKE INHERIT PRIVILEGES ON invoking_user FROM PUBLIC;
    

    失敗したINHERIT PRIVILEGESチェックの実行時エラーのため、この時点で実行者権限プロシージャを実行するユーザーは実行できないことに注意してください。

  2. INHERIT PRIVILEGES権限を信頼できるユーザーまたはロールに選択的に付与します。
  3. 同様に、INHERIT ANY PRIVILEGES権限を信頼できるユーザーまたはロールにのみ選択的に付与します。

監査ポリシーを作成してこれらの2つの権限の付与および取消しを監査できますが、失敗したINHERIT PRIVILEGES権限チェックによって発生する実行時エラーは監査できません。

関連項目:

ビューの定義者権限および実行者権限

CREATE VIEW SQL文でBEQEATH句を使用して、ユーザー作成ビューで定義者権限と実行者権限を制御できます。

ビューの定義者権限および実行者権限の制御について

ユーザー定義ビューを構成して、ビューで参照される実行者権限関数に対応できます。

ユーザーがIDまたは権限依存のSQL関数または実行者権限のPL/SQLまたはJava関数を起動すると、現在のスキーマ、現在のユーザーおよび操作の実行内の現在有効なロールがビューの所有者に設定することなく問い合せたユーザーの環境から継承できます。

この構成は、ビュー自体から実行者権限のオブジェクトに変更しません。ビュー内での名前解決は、引き続きビューの所有者のスキーマを使用して処理され、ビューの権限チェックは、ビューの所有者の権限で実行されます。ただし、実行時に、ビューで参照される関数は、ビュー所有者ではなく実行するユーザーの権限で実行されます。

この機能の利点は、関数をビューで参照する場合に一貫した結果を戻すために実行するユーザーに正確な情報を戻す必要がある SYS_CONTEXTUSERENVなどの関数を有効にすることです。

CREATE VIEW文のBEQUEATH句の使用

BEQUEATHは、実行ユーザーの権限を使用してどのように実行者権限関数を実行するかを制御します。

ビューを参照するSQLを発行するユーザーの権限を使用して実行者権限関数を実行するには、CREATE VIEW文で、BEQUEATH句をCURRENT_USERに設定します。

ビューに対するSQL問合せまたはDML文を発行する場合、ビュー所有者は、実行するユーザーのINHERIT PRIVILEGES権限を付与するか、INHERIT ANY PRIVILEGES権限を持つ必要があります。そうしないと、SELECT問合せまたはDML文がBEQUEATH CURRENT_USERビューを含む場合、実行時システムは、エラー「ORA-06598: INHERIT PRIVILEGES権限が不十分です」を表示します。

  • BEQUEATH CURRENT_USER句を使用して、実行者権限を使用して実行するビューの関数を設定します。

例:

CREATE VIEW MY_OBJECTS_VIEW BEQUEATH CURRENT_USER AS
 SELECT GET_OBJS_FUNCTION;

ビューの所有者の権限を使用してビュー内の関数を実行する場合、BEQUEATH句を省略するか、DEFINERに設定します。

例:

CREATE VIEW my_objects_view BEQUEATH DEFINER AS
 SELECT OBJECT_NAME FROM USER_OBJECTS;

関連項目:

実行するユーザーのユーザー名またはユーザーIDの確認

実行者権限または定義者権限を使用するかどうかに基づいて、PL/SQLファンクションを使用して、実行するユーザーを確認できます。

  • 実行者権限または定義者権限のどちらを使用するかに基づいて、ORA_INVOKING_USER関数またはORA_INVOKING_USERID関数を使用して、実行するユーザーを確認します。

    • ORA_INVOKING_USER: この関数を使用して、現在の文またはビューを実行しているユーザーの名前を戻します。この関数は、介在しているビューをBEQUEATH句で指定されたとみなします。実行するユーザーがOracle Database Real Application Securityで定義されているユーザーの場合、この関数はXS$NULLを戻します。

    • ORA_INVOKING_USERID: この関数を使用して、現在の文またはビューを実行しているユーザーの識別子(ID)を戻します。この関数は、介在しているビューをBEQUEATH句で指定されたとみなします。実行するユーザーがOracle Database Real Application Securityで定義されているユーザーである場合、この関数は、すべてのReal Application Securityセッションに共通でデータベース・ユーザーのIDとは異なるIDを戻します。

      例:

      CONNECT HR@pdb_name
      Enter password: password
      
      SELECT ORA_INVOKING_USER FROM DUAL;
      
      ORA_INVOKING_USER
      --------------------
      HR

関連項目:

Oracle Database Real Application Securityアプリケーションに使用される類似の関数の詳細は、『Oracle Database Real Application Security管理者および開発者ガイド』を参照してください。

BEQUEATH DEFINERおよびBEQUEATH_CURRENT_USERビューの確認

ビューがBEQUEATH DEFINERまたはBEQUEATH CURRENT_USERビューであるかどうかを確認できます。

  • ビューがBEQUEATH DEFINERまたはBEQUEATH CURRENT_USERビューであるかどうかを確認するには、そのビューの*_VIEWSまたは*_VIEWS_AE静的データ・ディクショナリ・ビューのBEQUEATH列を問い合せます。

関連項目:

例:

SELECT BEQUEATH FROM USER_VIEWS WHERE VIEW_NAME = 'MY_OBJECTS';

BEQUEATH
------------
CURRENT_USER

定義者権限および実行者権限のコード・ベース・アクセス制御の使用

データベース・ロールをPL/SQLファンクション、プロシージャまたはパッケージに付与するときに使用するコード・ベース・アクセス制御は、定義者権限および実行者権限のプロシージャと一緒に使用すると効果的です。

アプリケーションのコード・ベース・アクセス制御の使用について

コード・ベース・アクセス制御(CBAC)を使用すると、実行者権限のプログラム・ユニットの管理を向上できます。

アプリケーションは、昇格した権限を必要とする一方で、コール側の環境でプログラム・ユニットを頻繁に実行する必要があります。従来PL/SQLプログラムは、定義者権限を使用してプログラムの権限を一時的に昇格します。

ただし、定義者権限ベースのプログラム・ユニットは、実行者のコンテキストではなくプログラム・ユニットの定義者または所有者のコンテキストで実行されます。また、定義者権限ベースのプログラムを使用すると、多くの場合にプログラム・ユニットが必要以上の権限を取得します。

コード・ベース・アクセス制御(CBAC)は、PL/SQLファンクション、プロシージャまたはパッケージへのデータベース・ロールのアタッチを可能にして、解決策を提供します。これらのデータベース・ロールは実行時に有効で、呼び出すユーザーの環境の必要な権限でプログラム・ユニットを実行できます。

CBACロールの使用を取得する権限分析ポリシーを作成できます。

コード・ベースのアクセス制御ロールをプログラム・ユニットに付与できる者

次のすべての条件を満たした場合、コード・ベースのアクセス制御ロールをプログラム・ユニットに付与できます。

これらの条件は次のとおりです。

  • 権限付与者は、ユーザーSYS、またはプログラム・ユニットの所有者です。

  • 権限付与者がプログラム・ユニットを所有する場合、権限付与者はGRANT ANY ROLEシステム権限を持つか、プログラム・ユニットに付与するロールに対してADMINまたはDELEGATEオプションを持つ必要があります。

  • 付与対象のロールは、所有者に対して直接付与されるロールです。

  • 付与対象のロールは、標準データベース・ロールです。

これらの3つの条件が満たされない場合、1番目の条件が満たされないときは、エラーORA-28702: プログラム・ユニットの文字列が権限付与者によって所有されていませんが生成され、2番目と3番目の条件が満たされないときは、エラーORA-1924: ロールの文字列は付与されていないか、存在していませんが生成されます。

コード・ベース・アクセス制御による実行者権限のプログラム・ユニットの処理方法

コード・ベース・アクセス制御では、実行ユーザーのコンテキストで、そのコンテキストに関連付けられたロールを使用してプログラム・ユニットを実行できます。

2つのアプリケーション・ユーザー1および2が存在するシナリオを検討します。アプリケーション・ユーザー2は、実行者権限のプログラム・ユニットを作成し、データベース・ロール2を実行者権限ユニットに付与して、実行者権限ユニットの実行権限をアプリケーション・ユーザー1に付与します。

図7-1に、アプリケーション・ユーザー1および2に付与されるデータベース・ロール1および2と実行者権限のプログラム・ユニットを示します。

図7-1 アプリケーション・ユーザーに付与されるロールおよび実行者権限のプログラム・ユニット

図7-1の説明が続きます
「図7-1 アプリケーション・ユーザーに付与されるロールおよび実行者権限のプログラム・ユニット」の説明

付与は次のとおりです。

  • アプリケーション・ユーザー1に直接データベース・ロール1および4が付与されます。

  • アプリケーション・ユーザー2に直接アプリケーション・ロール3および4を含むデータベース・ロール2が付与されます。

  • 実行者権限のプログラム・ユニットにデータベース・ロール2が付与されます。

アプリケーション・ユーザー1がログインして実行者権限のプログラム・ユニットを実行する場合、実行者権限ユニットは、ユーザー1の結合されたデータベース・ロールおよび実行者権限ユニットに付加されたデータベース・ロールで実行されます。

図7-2は、実行者権限ユニットが実行されるセキュリティ・コンテキストを示しています。アプリケーション・ユーザー1が最初にログオンする場合、アプリケーション・ユーザー1は、データベースPUBLICロール(デフォルト)およびそれに付与されたデータベース・ロール1および4を持ちます。次に、アプリケーション・ユーザー1は、アプリケーション・ユーザー2によって作成された実行者権限のプログラム・ユニットを実行します。

実行者権限のユニットは、アプリケーション・ユーザー1のコンテキストで実行され、それに付加される追加のデータベース・ロール2を持ちます。データベース・ロール2の一部であるため、データベース・ロール3および4が含まれます。実行者権限ユニットを終了した後、アプリケーション・ユーザー1のみ、それに付与されたアプリケーション・ロール、PUBLIC、ロール1およびロール4を持ちます。

図7-2 実行者権限のプログラム・ユニットIRが実行されるセキュリティ・コンテキスト

図7-2の説明が続きます
「図7-2 実行者権限のプログラム・ユニットIRが実行されるセキュリティ・コンテキスト」の説明

コード・ベース・アクセス制御による定義者権限のプログラム・ユニットの処理方法

コード・ベース・アクセス制御を使用して定義者権限を保護できます。

コード・ベース・アクセス制御は、定義するユーザーの権限で動作するプログラム・ユニットを有効にすることで定義者権限のプログラム・ユニットと連携し、このユーザーに関連付けられるデータベース・ロールを組み合せた権限で機能します。

アプリケーション・ユーザー2が定義者権限のプログラム・ユニットを作成し、定義者権限のプログラム・ユニットにロール2を付与して、定義者権限のプログラム・ユニットのEXECUTE権限をアプリケーション・ユーザー1に付与するシナリオを検討します。

図7-3に、アプリケーション・ユーザー1および2に付与されるデータベース・ロールと定義者権限のプログラム・ユニットを示します。

図7-3 アプリケーション・ユーザーに付与されるロールおよび定義者権限のプログラム・ユニット

図7-3の説明が続きます
「図7-3 アプリケーション・ユーザーに付与されるロールおよび定義者権限のプログラム・ユニット」の説明

付与は次のとおりです。

  • アプリケーション・ユーザー1に直接データベース・ロール1および4が付与されます。

  • アプリケーション・ユーザー2に直接データベース・ロール3および4を含むデータベース・ロール2が付与されます。

  • 定義者権限のプログラム・ユニットにデータベース・ロール2が付与されます。

アプリケーション・ユーザー1がログインして定義者権限のプログラム・ユニットを実行する場合、定義者権限ユニットは、アプリケーション・ユーザー2の結合されたデータベース・ロールおよび定義者権限ユニットに付加されたデータベース・ロール(ロール23および4)で実行されます。

図7-4は、定義者権限のプログラム・ユニットが実行されるセキュリティ・コンテキストを示しています。アプリケーション・ユーザー1が最初にログオンする場合、アプリケーション・ユーザー1は、データベースPUBLICロール(デフォルト)およびそれに付与されたデータベース・ロール1および4を持ちます。次に、アプリケーション・ユーザー1は、アプリケーション・ユーザー2によって作成された定義者権限のプログラム・ユニットを実行します。

定義者権限のプログラム・ユニットは、アプリケーション・ユーザー2のコンテキストで実行され、それに付加される追加のデータベース・ロール2を持ちます。データベース・ロール2の一部であるため、データベース・ロール3および4が含まれます。定義者権限ユニットを終了した後、アプリケーション・ユーザー1のみ、それに付与されたデータベース・ロール(PUBLIC、ロール1およびロール4)を持ちます。

図7-4 定義者権限のプログラム・ユニットDRが実行されるセキュリティ・コンテキスト

図7-4の説明が続きます
「図7-4 定義者権限のプログラム・ユニットDRが実行されるセキュリティ・コンテキスト」の説明

CBAC付与のためのユーザーへのデータベース・ロールの付与

GRANT文のDELEGATEオプションで、CBAC付与を行うユーザーによるロールへの権限付与を制限できます。

データベース・ロールをCBAC付与を行うユーザーに付与する場合、GRANT文にDELEGATEオプションを含めて、権限受領者にロールに対する追加権限が付与されないようにすることができます。

DELEGATEオプションを使用すると、ロールはプログラム・ユニットに付与されますが、他のプリンシパルまたはロール自体の管理にロールを付与することはできません。他のプリンシパルへのロールの付与を可能にするADMINオプションを付与に使用することもできます。ADMINDELEGATEオプションは共存できます。オプションごとに別のGRANT文で付与する必要はありますが、両方をユーザーに付与することができます。これらのオプション付きでユーザーにロールが付与されているかどうかを確認するには、ユーザーのUSER_ROLE_PRIVSまたはDBA_ROLE_PRIVSDELEGATE_OPTION列またはADMIN_OPTION列を問い合せます。

DELEGATEおよびADMINオプションを使用するための構文は次のとおりです。

GRANT role_list to user_list WITH DELEGATE OPTION;

GRANT role_list to user_list WITH ADMIN OPTION;

例:

GRANT cb_role1 to usr1 WITH DELEGATE OPTION;

GRANT cb_role1 to usr1 WITH ADMIN OPTION;

GRANT cb_role1, cb_role2 to usr1, usr2 with DELEGATE OPTION;

GRANT cb_role1, cb_role2 to usr1, usr2 with ADMIN OPTION;

ADMINオプションの場合と同様に、共通ユーザーへの共通ロールの付与などの共通付与のためにDELEGATEオプションを使用できます。

例:

GRANT c##cb_role1 to c##usr1 WITH DELEGATE OPTION CONTAINER = ALL;

CBAC付与自体は、PDBでローカルにのみ行えることに注意してください。

関連項目:

ADMINオプションの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

プログラム・ユニットに対するデータベース・ロールの付与と取消し

GRANTおよびREVOKE文で、プログラム・ユニットに対するデータベース・ロールの付与または取消しを行うことができます。

次の構文を使用して、PL/SQLファンクション、プロシージャまたはパッケージのデータベース・ロールを付与または取り消します。

GRANT role_list TO code_list 
REVOKE {role_list | ALL} FROM code_list
 

詳細は、次のとおりです。

role_list ::=  code-based_role_name[, role_list]
code_list ::=  {
      {FUNCTION  [schema.]function_name}
   |  {PROCEDURE [schema.]procedure_name}
   |  {PACKAGE   [schema.]package_name}
                 }[, code_list]

例:

GRANT cb_role1 TO FUNCTION func1, PACKAGE pack1;

GRANT cb_role2, cb_role3 TO FUNCTION HR.func2, PACKAGE SYS.pack2;

REVOKE cb_role1 FROM FUNCTION func1, PACKAGE pack1;

REVOKE ALL FROM FUNCTION HR.func2, PACKAGE SYS.pack2;

チュートリアル: コード・ベース・アクセス制御による機密データへのアクセス制御

このチュートリアルでは、コード・ベース・アクセス制御を使用して、HRスキーマの機密データへのアクセスを制御する方法を示します。

このチュートリアルについて

このチュートリアルでは、自分の部門のために特定の従業員情報に対するアクセス権が必要なユーザーを作成します。

ただし、HR.EMPLOYEES表には従業員給与などの機密情報が含まれており、ユーザーにはアクセスできないようにする必要があります。アクセス制御は、コード・ベース・アクセス制御を使用して実装します。従業員データは、実行者権限プロシージャを通じてユーザーに表示されます。SELECT権限をユーザーに直接付与するかわりに、データベース・ロールを通じてSELECT権限を実行者権限プロシージャに付与します。このプロシージャでは、給与のような機密情報を非表示にします。このプロシージャは実行者権限プロシージャであるため、プロシージャ内で呼出し元のコンテキストがわかります。この場合、呼出し元のコンテキストは財務部門です。ユーザーの名前は"Finance"であるため、ユーザーは財務部門に勤務する従業員のデータのみにアクセス可能です。

ステップ1: ユーザーを作成してHRにCREATE ROLE権限を付与

開始するには、"Finance"ユーザー・アカウントを作成し、このHRユーザーにCREATE ROLE権限を付与する必要があります。

  1. ユーザー・アカウントおよびロールを作成する権限がある管理者としてPDBにログインします。

    例:

    sqlplus sec_admin@pdb_name
    Enter password: password
    

    利用可能なPDBを検索するには、DBA_PDBSデータ・ディクショナリ・ビューを問い合せます。現在のPDBを確認するには、show con_nameコマンドを実行します。

  2. "Finance"ユーザー・アカウントを作成します。
    GRANT CONNECT TO "Finance" IDENTIFIED BY password;
    

    "Finance"が、大文字と小文字はこのまま、二重引用符で囲んで入力されていることを確認します。「パスワードの最低要件」のガイドラインに従って、passwordを安全なパスワードに置き換えます。

  3. CREATE ROLE権限をユーザーHRに付与します。
    GRANT CREATE ROLE TO HR;
ステップ2: print_employees実行者権限プロシージャを作成

print_employees実行者権限プロシージャは、現在のユーザーの部門内の従業員情報を表示します。

プロシージャ内で呼出し元がだれであるかを知る必要があるため、このプロシージャを実行者権限プロシージャとして作成する必要があります。
  1. ユーザーHRとしてPDBに接続します。
    CONNECT HR@pdb_name
    Enter password: password
    
  2. 次のようにprint_employeesプロシージャを作成します。
    create or replace procedure print_employees
    authid current_user
    as 
    begin
      dbms_output.put_line(rpad('ID', 10) ||
                           rpad('First Name', 15)  ||
                           rpad('Last Name', 15)   ||
                           rpad('Email', 15)       ||
                           rpad('Phone Number', 20));
      for rec in (select e.employee_id, e.first_name, e.last_name, 
                         e.email, e.phone_number
                    from hr.employees e, hr.departments d 
                   where e.department_id = d.department_id
                     and d.department_name = 
                         sys_context('userenv', 'current_user'))
      loop
        dbms_output.put_line(rpad(rec.employee_ID, 10)  ||
                             rpad(rec.first_name, 15)   || 
                             rpad(rec.last_name, 15)    ||
                             rpad(rec.email, 15)        ||
                             rpad(rec.phone_number, 20));
      end loop;
    end;
    /

    この例では、次のようになります。

    • dbms_output.put_lineは、表ヘッダーを印刷します。

    • for rec in (select ...は、呼出し元の部門の従業員情報を検索します。このチュートリアルでは、ユーザー"Finance"の財務部門となります。"Marketing"(これもHR.EMPLOYEES表のDEPARTMENT_NAME列にリストされています)という名前のユーザーを作成していた場合には、プロシージャはマーケティング部門従業員の情報を取得できました。

    • loopおよびdbms_output.put_lineは、出力に財務部門の従業員データを移入します。

ステップ3: hr_clerkロールを作成して権限を付与

次に、hr_clerkロールを作成し、print_employeesプロシージャに対するEXECUTE権限を付与する必要があります。

このロールを作成したら、これを"Finance"に付与する必要があります。
  1. hr_clerkロールを作成します。
    CREATE ROLE hr_clerk;
    
  2. print_employeesプロシージャのEXECUTE権限をhr_clerkロールに付与します。
    GRANT EXECUTE ON print_employees TO hr_clerk;
    
  3. hr_clerkロールを"Finance"に付与します。
    GRANT hr_clerk TO "Finance";
ステップ4: コード・ベース・アクセス制御HR.print_employeesプロシージャのテスト

コード・ベース・アクセス制御HR.print_employeesプロシージャをテストする準備が整いました。

コード・ベース・アクセス制御のHR.print_employeesプロシージャをテストするには、ユーザー"Finance"HR.EMPLOYEES表を問い合せて、HR.print_employeesプロシージャの実行を試みる必要があります。
  1. ユーザーFinanceとしてPDBに接続します。
    CONNECT "Finance"@pdb_name
    Enter password: password
    
  2. HR.EMPLOYEES表の直接問合せを試行します。
    SELECT EMPLOYEE_ID, FIRST_NAME, LAST_NAME, SALARY FROM HR.EMPLOYEES;
    

    ユーザーFinanceにはHR.EMPLOYEESへのSELECT権限がないため、問合せは失敗します。

    ERROR at line 1:
    ORA-00942: table or view does not exist
    
  3. HR.print_employeesプロシージャを実行します。
    EXEC HR.print_employees;
    

    ユーザー"Finance"が適切な権限を持っていないため、問合せは失敗します。

    ERROR at line 1:
    ORA-00942: table or view does not exist
    ORA-06512: at "HR.PRINT_EMPLOYEES", line 13ORA-06512: at line 1
ステップ5: view_emp_roleロールを作成して権限を付与

ここでは、ユーザーHRview_emp_roleロールを作成し、このロールに権限を付与する必要があります。

ユーザーHRSELECT権限HR.EMPLOYEESHR.DEPARTMENTSview_emp_roleロールに付与し、HR.EMPLOYEESHR.DEPARTMENTSSELECTview_emp_roleロールに付与します。
  1. ユーザーHRとしてPDBに接続します。
    CONNECT HR@pdb_name
    Enter password: password
    
  2. view_emp_roleロールを作成します。
    CREATE ROLE view_emp_role;
    
  3. view_emp_roleロールにHR.EMPLOYEESHR.DEPARTMENTSSELECT権限を付与します。
    GRANT SELECT ON HR.EMPLOYEES TO view_emp_role;
    GRANT SELECT ON HR.DEPARTMENTS TO view_emp_role;
    
  4. view_emp_roleロールをHR.print_employees実行者権限プロシージャに付与します。
    GRANT view_emp_role TO PROCEDURE HR.print_employees;
ステップ6: HR.print_employeesプロシージャの再テスト

適切な権限がある場合、ユーザー"Finance"は、HR.print_employeesプロシージャを再試行できます。

  1. ユーザーFinanceとしてPDBに接続します。
    CONNECT "Finance"@pdb_name
    Enter password: password
    
  2. サーバー出力をディスプレイに設定します。
    SET SERVEROUTPUT ON;
    
  3. HR.EMPLOYEES表の直接問合せを試行します。
    SELECT EMPLOYEE_ID, FIRST_NAME, LAST_NAME, SALARY FROM HR.EMPLOYEES;
    

    問合せが失敗します。

    ERROR at line 1:
    ORA-00942: table or view does not exist
    
  4. HR.print_employeesプロシージャを実行して、従業員情報を表示します。
    EXEC HR.print_employees;
    

    呼出しが成功します。

    ID        First Name     Last Name      Email          Phone Number
    108       Nancy          Greenberg      NGREENBE       515.124.4569
    109       Daniel         Faviet         DFAVIET        515.124.4169
    110       John           Chen           JCHEN          515.124.4269
    111       Ismael         Sciarra        ISCIARRA       515.124.4369
    112       Jose Manuel    Urman          JMURMAN        515.124.4469
    113       Luis           Popp           LPOPP          515.124.4567
    
    PL/SQL procedure successfully completed.
ステップ7: このチュートリアルのコンポーネントの削除

このチュートリアルのコンポーネントが不要になった場合、それらを削除できます。

  1. 管理権限があるユーザーとしてPDBに接続します。

    例:

    CONNECT sec_admin@pdb_name
    Enter password: password
    
  2. ユーザー"Finance"を削除します。
    DROP USER "Finance";
    
  3. hr_clerkロールを削除します。
    DROP ROLE hr_clerk;
    
  4. ユーザーHRとして接続します。
    CONNECT HR@pdb_name
    Enter password: password
    
  5. view_emp_roleロールとHR.print_employeesプロシージャを削除します。
    DROP ROLE view_emp_role;
    DROP PROCEDURE print_employees;
    
  6. 管理者権限ユーザーとして接続します。
    CONNECT sec_admin@pdb_name
    Enter password: password
    
  7. HRからCREATE ROLE権限を取り消します。
    REVOKE CREATE ROLE FROM HR;

データベース・リンクの定義者権限の制御

アプリケーションでデータベース・リンクと定義者権限プロシージャが使用されている場合は、定義者権限プロシージャの権限付与を制御できます。

データベース・リンクの定義者権限の制御について

定義者権限プロシージャがデータベース・リンクに接続する場合、データベース・リンク上の操作でプロシージャ所有者の資格証明を使用する必要があります。

INHERIT REMOTE PRIVILEGESおよびINHERIT ANY REMOTE PRIVILEGES権限は、接続ユーザー・データベース・リンクが定義者権限プロシージャで使用される場合に適用されます。これらの権限により、定義者権限プロシージャでの接続ユーザー・データベース・リンクの操作で、ログインしているユーザーの資格証明の使用が可能になります。

定義者権限プロシージャを実行するユーザーが定義者権限ブロック内で接続ユーザー・データベース・リンクを使用できるように、INHERIT REMOTE PRIVILEGESおよびINHERIT ANY REMOTE PRIVILEGES権限を付与できます。定義者権限プロシージャは、プロシージャ所有者の権限で実行されます。ただし、接続ユーザー・データベース・リンクの操作には、ログインしているユーザーの資格証明が必要です。したがって、定義者権限内でデータベース・リンクの操作を可能にするには、INHERIT REMOTE PRIVILEGESおよびINHERIT ANY REMOTE PRIVILEGES権限を付与する必要があります。

アップグレード中にINHERIT REMOTE PRIVILEGESおよびINHERIT ANY REMOTE PRIVILEGES権限はデフォルトで既存のユーザーに付与されないことに注意してください。

INHERIT REMOTE PRIVILEGESおよびINHERIT ANY REMOTE PRIVILEGES権限は、ユーザーが定義者権限プロシージャでユーザー・データベース・リンクに接続を試みる状況にのみ適用されます。また、これらの権限は、プライベート、パブリックを問わず、作成されたデータベース・リンクに適用されます。デフォルトでは、データベース・リンクはプライベート・リンクとして作成されます。さらに、デフォルトではINHERIT REMOTE PRIVILEGESPUBLICに付与されません。

これらの権限を付与する方法は次のとおりです。

  • GRANT INHERIT REMOTE PRIVILEGES ON USER dbuser_1 TO dbuser_2: このシナリオでは、dbuser_1が明示的にINHERIT REMOTE PRIVILEGE権限をdbuser_2に付与し、ユーザーdbuser_2が所有する定義者権限プロシージャを使用します。

  • GRANT INHERIT REMOTE PRIVILEGES ON USER dbuser_1 TO PUBLIC。このシナリオでは、dbuser_1INHERIT REMOTE PRIVILEGE権限をpublicに付与します。この付与により、dbuser_1は他のユーザーが所有する定義者権限プロシージャを使用できます。

  • GRANT INHERIT ANY REMOTE PRIVILEGES TO dbuser_2: このシナリオでは、いずれのユーザーもdbuser_2が所有する定義者権限プロシージャを使用できます。

INHERIT REMOTE PRIVILEGE権限のないユーザーが定義者権限を実行しようとすると、ORA-25433: ユーザーにはINHERIT REMOTE PRIVILEGESがありませんエラーが表示されます。

他のユーザーへのINHERIT REMOTE PRIVILEGES権限の付与

INHERIT REMOTE PRIVILEGES権限は、現行ユーザーがデータベースの接続ユーザーを介して明示的な権限を持つことを可能にします。

INHERIT REMOTE PRIVILEGES権限を付与する構文は次のとおりです。

GRANT INHERIT REMOTE PRIVILEGES ON USER connected_user TO current_user:

詳細は、次のとおりです。

  • connected_userは、定義者権限プロシージャを実行するユーザーです。

  • current_userは、定義者権限プロシージャを所有するユーザーです。この値は、データベース・ユーザー・アカウントである必要があります。INHERIT REMOTE PRIVILEGES権限をプロシージャの所有者に付与するかわりに、プロシージャに付与されるロールに権限を付与できます。

定義者権限プロシージャを所有するユーザーまたはロールは、定義者権限プロシージャを実行するユーザーによって付与されるINHERIT REMOTE PRIVILEGES権限を持つ必要があります。

いずれのユーザーも、自分が実行する定義者権限プロシージャを所有するユーザーに対して、自分の持つINHERIT REMOTE PRIVILEGES権限の付与または取消しを行うことができます。

例: 接続ユーザーのINHERIT REMOTE PRIVILEGESの付与

接続ユーザーのINHERIT REMOTE PRIVILEGES権限を現行ユーザーに付与することができます。

この例では、接続ユーザーjwardは、現行ユーザーebrownのリモート権限を持つ必要があります。これにより、jwardは、ebrownが作成した定義者権限プロシージャを実行できます。

例7-4に、管理者(またはユーザーjward)がユーザーjwardINHERIT REMOTE PRIVILEGESをユーザーebrownに付与する方法を示します。この権限付与により、ebrownが記述する(または今後記述する予定の)定義者権限プロシージャが、そのプロシージャの実行時にebrownの権限にアクセスできるようになります。

例7-4 現行ユーザーへの接続ユーザーのINHERIT REMOTE PRIVILEGESの付与

GRANT INHERIT REMOTE PRIVILEGES on user jward to ebrown;

他のユーザーへのINHERIT ANY REMOTE PRIVILEGES権限の付与

INHERIT ANY REMOTE PRIVILEGES権限により、権限受領ユーザーはconnected_userデータベース・リンクを任意のユーザーとしてオープンできます。

すべてのANY権限と同様に、INHERIT ANY REMOTE PRIVILEGESは、信頼できるユーザーのみに付与する必要がある強力な権限です。デフォルトでは、ユーザーSYSINHERIT ANY REMOTE PRIVILEGESシステム権限WITH GRANT OPTIONを持っています。INHERIT ANY REMOTE PRIVILEGES権限を付与されたユーザーを確認するには、DBA_SYS_PRIVSデータ・ディクショナリ・ビューを問い合せます。

セキュリティ向上のため、PDBロックダウン・プロファイルを使用してINHERIT ANY REMOTE PRIVILEGES権限を保護することをお薦めします。PDBロックダウン・プロファイルは、ローカル・プラガブル・データベース(PDB)ユーザーが持っているINHERIT REMOTE PRIVILEGEの種類に関係なく、PDBユーザーが接続ユーザー・データベース・リンクを共通ユーザーとしてオープンすることを防ぎます。PDBがPDBロックダウン・プロファイルによって保護されている場合、GRANT INHERIT REMOTE PRIVILEGESおよびGRANT INHERIT ANY REMOTE権限などの付与は成功しますが、これらの付与の影響は、PDBロックダウンが継続しているかぎり適用されません。

INHERIT ANY REMOTE PRIVILEGES権限を付与する構文は次のとおりです。

GRANT INHERIT ANY REMOTE PRIVILEGES TO current_user;

ここで、current_userは、定義者権限プロシージャを所有するユーザーです。

INHERIT [ANY] REMOTE PRIVILEGES権限の取消し

INHERIT REMOTE PRIVILEGES権限とINHERIT ANY REMOTE PRIVILEGES権限とでは取消方法が異なります。

INHERIT REMOTE PRIVILEGES権限は、ユーザーが別のユーザーから取り消すことができます。INHERIT ANY REMOTE PRIVILEGES権限は管理権限を持つユーザーが取り消す必要があります。

取消しの構文は次のとおりです

REVOKE INHERIT REMOTE PRIVILEGES ON USER connected_user FROM current_user;

詳細は、次のとおりです。

  • connected_userは、定義者権限プロシージャを実行するユーザーです。

  • current_userは、定義者権限プロシージャを所有するユーザーです。

INHERIT REMOTE PRIVILEGESまたはINHERIT ANY REMOTE PRIVILEGES権限をユーザーから取り消す場合、次のように標準の取消し構文を使用します。

REVOKE INHERIT REMOTE PRIVILEGES FROM connected_user;
REVOKE INHERIT ANY REMOTE PRIVILEGES FROM current_user;

関連項目:

REVOKE SQL文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

例: INHERIT REMOTE PRIVILEGES権限の取消し

REVOKE SQL文で、INHERIT REMOTE PRIVILEGES権限を取り消すことができます。

INHERIT REMOTE PRIVILEGES権限を取り消すと、ユーザーjwardjward所有の定義者権限プロシージャを実行する場合、jwardebrownに対して、jwardの資格証明を使用して接続ユーザー・データベース・リンクをオープンする権限を明示的に拒否しているため、定義者権限プロシージャ内での接続ユーザー・データベース・リンクの操作はすべて失敗します。

例7-5に、接続ユーザーjwardINHERIT REMOTE PRIVILEGESプロシージャをプロシージャ所有者ebrownから取り消す方法を示します。

例7-5 INHERIT REMOTE PRIVILEGES権限の取消し

REVOKE INHERIT REMOTE PRIVILEGES ON USER jward FROM ebrown;

例: PUBLICからのINHERIT REMOTE PRIVILEGES権限の取消し

REVOKE SQL文で、PUBLICおよび個々のプロシージャ所有者のINHERIT REMOTE PRIVILEGESを取り消すことができます。

例7-6に、PUBLICから権限を取り消す方法を示します。

例7-6 PUBLICからのINHERIT REMOTE PRIVILEGES権限の取消し

REVOKE INHERIT REMOTE PRIVILEGES FROM PUBLIC;

チュートリアル: 定義者権限プロシージャでのデータベース・リンクの使用

このチュートリアルでは、データベース・リンクを使用する定義者権限プロシージャでのINHERIT REMOTE PRIVILEGES権限の使用方法を示します。

このチュートリアルについて

このチュートリアルでは、INHERIT REMOTE PRIVILEGES権限の付与と取消しをテストします。

これを行うには、2人のユーザーを作成する必要があります。1人はデータベース・リンクを参照する定義者権限プロシージャを作成するユーザー、もう1人はこの定義者権限プロシージャを実行するユーザーです。いずれのユーザーも自分のスキーマで同一のルックアップ表を作成します。定義者権限プロシージャでは、定義者権限ユーザーに属するルックアップ表を2人目のユーザーが問い合せることを可能にする必要があります。

ステップ1: ユーザー・アカウントの作成

データベース・リンクを含む定義者権限プロシージャを作成するユーザーと、そのプロシージャを実行するユーザーを作成します。

  1. ユーザー作成と権限付与の権限があるユーザーとしてPDBにログインします。

    例:

    sqlplus sec_admin@pdb_name
    Enter password: password

    利用可能なPDBを検索するには、DBA_PDBSデータ・ディクショナリ・ビューを問い合せます。現在のPDBを確認するには、show con_nameコマンドを実行します。

  2. 次のようにユーザー・アカウントを作成します。
    GRANT CONNECT, RESOURCE, UNLIMITED TABLESPACE TO dbuser1 IDENTIFIED BY password;
    GRANT CONNECT, RESOURCE, UNLIMITED TABLESPACE TO dbuser2 IDENTIFIED BY password;
    「パスワードの最低要件」のガイドラインに従って、passwordを安全なパスワードに置き換えます。
ステップ2: ユーザーIDを格納する表の作成(ユーザーdbuser2として)

この表のユーザーIDは、データベース・リンクで使用するIDです。

  1. ユーザーdbuser2としてPDBのインスタンスinst1に接続します。
    connect dbuser2@inst1
    Enter password: password

    このインスタンスについての、tnsnames.oraでのSERVICE_NAME設定は、正しいPDBにマップされます。

  2. 次のように表を作成します。
    CREATE TABLE dbusertab(ID NUMBER(2));
  3. この表にID値10を移入します。
    INSERT INTO dbusertab VALUES(10);
ステップ3: データベース・リンクおよび定義者権限プロシージャの作成(ユーザーdbuser1として)

ユーザーdbuser1は、データベース・リンクに加えて、そのデータベース・リンクを参照する定義者権限プロシージャを作成できます。

  1. ユーザーdbuser1として、インスタンスinst1に接続します。
    connect dbuser1@inst1
    Enter password: password
  2. 定義者権限プロシージャで使用するデータベース・リンクを作成します。
    CREATE DATABASE LINK dblink USING 'inst1';
  3. dbusertab表を作成し、その表にID 20を移入します。
    CREATE TABLE DBUSERTAB(ID NUMBER(2));
    INSERT INTO dbusertab VALUES(20);
  4. データベース・リンクへの参照を含む定義者権限プロシージャを作成します
    CREATE OR REPLACE PROCEDURE test_remote_db_link
    AS
    v_id varchar(50);
    BEGIN   
        SELECT ID INTO v_id FROM dbusertab@dblink;
        DBMS_OUTPUT.PUT_LINE('v_id : ' || v_id);
    END ;
    /
  5. 定義者権限プロシージャをテストします。
    SET SERVEROUTPUT ON
    EXEC test_remote_db_link; 

    出力は次のようになり、ユーザーdbuser1が自分のバージョンの表dbusertabに対してプロシージャを実行したことが示されます。

    v_id : 20
    
  6. ユーザーdbuser2test_remote_db_linkプロシージャに対するEXECUTE権限を付与します。
    GRANT EXECUTE ON test_remote_db_link TO dbuser2;
ステップ4: 定義者権限プロシージャのテスト

定義者権限プロシージャをテストする前に、ユーザーdbuser2dbuser1INHERIT REMOTE PRIVILEGESを付与する必要があります。

  1. ユーザーdbuser2として、インスタンスinst1に接続します。
    connect dbuser2@inst1
    Enter password: password
  2. ユーザーdbuser2INHERIT REMOTE PRIVILEGE権限をdbuser1に付与します。
    GRANT INHERIT REMOTE PRIVILEGES ON user dbuser2 TO dbuser1;
  3. 新規セッションを開始するまで付与は有効にならないため、再ログインします。
    connect dbuser2@inst1
    Enter password: password
  4. test_remote_db_link定義者権限プロシージャを実行します。
    SET SERVEROUTPUT ON
    EXEC dbuser1.test_remote_db_link;  
    出力は次のようになり、ユーザーdbuser1がデータベース・リンクを使用してdbuser2のスキーマに接続し、dbuser2のスキーマのdbusertab表の値にアクセスできることが示されます。
    v_id : 10
    
  5. ユーザーdbuser2INHERIT REMOTE PRIVILEGE権限をdbuser1から取り消します。
    REVOKE INHERIT REMOTE PRIVILEGES ON USER dbuser2 FROM dbuser1;
  6. test_remote_db_link定義者権限プロシージャの実行を再試行します。
    EXEC dbuser1.test_remote_db_link;

    ORA-25433: ユーザーDBUSER1には接続ユーザーDBUSER2のINHERIT REMOTE PRIVILEGESがありませんエラーが表示されます。

ステップ5: このチュートリアルのコンポーネントの削除

このチュートリアルのコンポーネントが不要になった場合、それらを削除できます。

  1. ユーザー・アカウントおよびデータベース・リンクを削除する権限があるユーザーとしてPDBに接続します

    例:

    connect sec_admin@pdb_name
    Enter password: password
  2. ユーザー・アカウントを削除します。
    DROP USER dbuser1 CASCADE;
    DROP USER dbuser2 CASCADE;
  3. dblinkデータベース・リンクを削除します。
    DROP PUBLIC DATABASE LINK dblink;