13.1 ACCESSIBLE BY句
ACCESSIBLE BY
句は、ユニットおよびサブプログラムへのアクセスを制限します。
ACCESSIBLE BY
句は、他のユニットによるユニットおよびサブプログラムへのアクセスを制限します。accessorリスト(ホワイト・リストとしても知られます)は、アクセスできるユニットを明示的にリストします。accessorリストはパッケージ内の個々のサブプログラムで定義できます。パッケージ自体に定義されたaccessorリスト(ある場合)に加え、このリストがチェックされます。このリストは、サブプログラムへのアクセスを制限できるのみで、アクセスを広げることはできません。このコード管理機能は、内部プログラムの誤った使用を防止するために役立ちます。たとえば、1つのパッケージを再編成して、アクセス制限が必要な少数のプロシージャのパッケージと、パブリック・アクセスが必要な残りのユニットのパッケージという2つのパッケージにすることはできません。
ACCESSIBLE BY
句は、オブジェクト型、オブジェクト型本体、パッケージ、およびサブプログラムの宣言で記述できます。
ACCESSIBLE BY
句は、次のSQL文に指定できます。
構文
accessible_by_clause ::=
accessor ::=
unit_kind ::=
セマンティクス
accessible_by_clause
accessor
[schema.]unit_name
エンティティを起動できるストアドPL/SQLユニットを指定します。
各accessor
は、ACCESSIBLE BY
句が含まれるエンティティにアクセスできる別のPL/SQLエンティティを指定します。
ACCESSIBLE BY
句が出現した場合、その句が出現したエンティティにアクセスできるのは、その句で指定されたエンティティのみです。
accessor
は、ACCESSIBLE BY
句で複数回記述できます。
ACCESSIBLE BY
句は、ユニットの宣言で1回のみ記述できます。
accessor
で指定されたエンティティが存在する必要はありません。
ACCESSIBLE BY
句のあるエンティティが起動されると、すべてのチェックが実行された後、追加のアクセス・チェックが課されます。これらのチェックには、次のものがあります。
-
起動されたユニットには、unit_nameとunit_kindが起動元のユニットと同じ
accessor
が含まれている必要があります。 -
accessor
にスキーマが含まれている場合、起動元ユニットはそのスキーマに含まれている必要があります。 -
accessor
にスキーマが含まれていない場合は、起動元は起動されたエンティティと同じスキーマからのものである必要があります。
unit_kind
ユニットがFUNCTION
、PACKAGE
、PROCEDURE
、TRIGGER
またはTYPE
のいずれであるかを指定します。
使用上の注意
unit_kindはオプションですが、ユニットの名前が同じ場合のあいまいさを避けるために指定することをお薦めします。たとえば、ファンクションと同じ名前でトリガーを定義することができます。
ACCESSIBLE BY
句は、コールが直接行われた場合にのみアクセスを許可します。静的SQL、DBMS_SQLまたは動的SQLを介したアクセスの場合、チェックは失敗します。
パッケージ仕様部またはパッケージ本体の初期化プロシージャへのコールは、パッケージ仕様部のaccessorリストに対してチェックされます。
ユニットはそれ自体に常にアクセスできます。ユニット内の項目は、同じユニット内の他の項目を参照できます。
保護されたサブプログラムへのRPCコールは、コールの有効性のチェックに使用できるコンテキストがないため、コンパイル時と実行時のいずれの場合でも常に失敗します。
保護されたサブプログラムへの条件付きコンパイル・ディレクティブからのコールは失敗します。
例
例13-1 同じスキーマの最上位プロシージャへのアクセスの制限
この例は、最上位プロシージャtop_protected_procをコールできるのは現在のスキーマのプロシージャtop_trusted_procのみであることを示しています。ユーザーがtop_proctected_procを直接コールすることはできません。
Live SQL:
この例は、Oracle Live SQLの「同じスキーマの最上位プロシージャへのアクセスの制限」で表示および実行できます
PROCEDURE top_protected_proc
ACCESSIBLE BY (PROCEDURE top_trusted_proc)
AS
BEGIN
DBMS_OUTPUT.PUT_LINE('Executed top_protected_proc.');
END;
PROCEDURE top_trusted_proc AS
BEGIN
DBMS_OUTPUT.PUT_LINE('top_trusted_proc calls top_protected_proc');
top_protected_proc;
END;
EXEC top_trusted_proc;
top_trusted_proc calls top_protected_proc
Executed top_protected_proc.
EXEC top_protected_proc;
BEGIN top_protected_proc; END;
PLS-00904: insufficient privilege to access object TOP_PROTECTED_PROC
例13-2 任意のユニット名へのアクセスの制限
この例は、PL/SQLのunit_kindがACCESSIBLE BY
句で指定されていない場合、ユニット名が一致すれば、任意のunit kindからのコールが許可されることを示しています。ACCESSIBLE BY
句で指定されているunit_kindが既存のオブジェクトに一致しない場合、コンパイル・エラーは発生しません。ファンクションと同じ名前でトリガーを定義することができます。unit_kindを指定することをお薦めします。
Live SQL:
この例は、Oracle Live SQLの「任意の種類のユニット名へのアクセスの制限」で表示および実行できます
PROCEDURE protected_proc2
ACCESSIBLE BY (top_trusted_f)
AS
BEGIN
DBMS_OUTPUT.PUT_LINE('Executed protected_proc2.');
END;
FUNCTION top_protected_f RETURN NUMBER
ACCESSIBLE BY (TRIGGER top_trusted_f ) AS
BEGIN
RETURN 0.5;
END top_protected_f;
FUNCTION top_trusted_f RETURN NUMBER AUTHID DEFINER IS
FUNCTION g RETURN NUMBER DETERMINISTIC IS
BEGIN
RETURN 0.5;
END g;
BEGIN
protected_proc2;
RETURN g() - DBMS_RANDOM.VALUE();
END top_trusted_f;
SELECT top_trusted_f FROM DUAL;
.381773176
1 row selected.
Executed protected_proc2.
例13-3 ストアド・プロシージャへのアクセスの制限
この例では、top_trusted_procプロシージャからのコールのみが可能なパッケージ・プロシージャを示します。サブプログラムの仕様部と本体のACCESSIBLE BY
句が、一致している必要があります。accessorリストにこのプロシージャが含まれていないACCESSIBLE BY
句のある既存のプロシージャに対してコールが行われた場合、エラーが発生します。
Live SQL:
この例は、Oracle Live SQLの「ストアド・プロシージャへのアクセスの制限」で表示および実行できます
CREATE OR REPLACE PACKAGE protected_pkg
AS
PROCEDURE public_proc;
PROCEDURE private_proc ACCESSIBLE BY (PROCEDURE top_trusted_proc);
END;
CREATE OR REPLACE PACKAGE BODY protected_pkg
AS
PROCEDURE public_proc AS
BEGIN
DBMS_OUTPUT.PUT_LINE('Executed protected_pkg.public_proc');
END;
PROCEDURE private_proc ACCESSIBLE BY (PROCEDURE top_trusted_proc) AS
BEGIN
DBMS_OUTPUT.PUT_LINE('Executed protected_pkg.private_proc');
END;
END;
CREATE OR REPLACE PROCEDURE top_trusted_proc
AS
BEGIN
DBMS_OUTPUT.PUT_LINE('top_trusted_proc calls protected_pkg.private_proc ');
protected_pkg.private_proc;
END;
Procedure created.
EXEC top_trusted_proc;
top_trusted_proc calls protected_pkg.private_proc
Executed protected_pkg.private_proc
EXEC protected_pkg.private_proc
PLS-00904: insufficient privilege to access object PRIVATE_PROC