A.5 PL/SQLサーバー・プラグイン開発者リファレンス

PL/SQLのプラグイン・フレームワークを使用し、Oracle Internet DirectoryでPL/SQLサーバー・プラグインを設計、作成および使用できます。

次の各項では、これについてさらに詳しく説明しています。

A.5.1 PL/SQLサーバー・プラグインの設計、作成および使用

PL/SQLサーバー・プラグインを設計、作成および使用できます。

この項では、次の項目について説明します。

A.5.1.1 PL/SQLプラグインの注意事項

PL/SQLプラグインは、特定の操作にのみ関連付けることができます。また、プラグインが他のプラグインやストアド・プロシージャと同じデータベース・スキーマを共有する場合、そのプラグインの名前(PL/SQLパッケージ名)は一意であることが必要です。次の各項では、これについてさらに詳しく説明しています。

A.5.1.1.1 PL/SQLプラグイン操作のタイプ

PL/SQLプラグインは、ldapbindldapaddldapmodifyldapcompareldapsearchおよびldapdeleteの各操作にのみ関連付けることができます。PL/SQLプラグインをmoddnに関連付けることはできません。プラグインをmoddnに関連付ける場合には、Javaプラグインを使用する必要があります。

A.5.1.1.2 一意のPL/SQLプラグイン名

プラグインが他のプラグインやストアド・プロシージャと同じデータベース・スキーマを共有する場合、そのプラグインの名前(PL/SQLパッケージ名)は一意であることが必要です。しかし、他のデータベース・スキーマ・オブジェクト(表やビューなど)とは同じ名前を共有できます。ただし、この種の共有はお薦めしません。

A.5.1.2 PL/SQLプラグインのパッケージ名とプロシージャの仕様

PL/SQLプラグイン・モジュールの作成は、PL/SQLパッケージの作成と似ています。いずれも、仕様部分と本文に分かれています。この仕様はOracle Internet Directoryとカスタム・プラグインを接続するインタフェースの役割を果たすため、プラグインではなくディレクトリによってプラグインの仕様が決まります。

セキュリティ上およびLDAPサーバーの整合性の理由から、PL/SQLプラグインをコンパイルできるのはODSデータベース・スキーマにおいてのみです。これらを、Oracle Internet Directoryのバックエンド・データベースの役割を果すデータベースにコンパイルする必要があります。次の各項で、さらに詳しく説明します。

A.5.1.2.1 プラグイン・パッケージ名の仕様

パッケージ仕様はプラグインによって異なります。表A-19に示すように、プラグイン・パッケージには名前を指定できます。ただし、プラグイン・プロシージャの各タイプに定義されているシグネチャには従う必要があります。詳細は、「PL/SQLプラグイン・プロシージャの仕様」を参照してください。

表A-19 プラグイン・モジュール・インタフェース

プラグイン項目 ユーザー定義 Oracle Internet Directoryで定義

プラグイン・パッケージ名

X

プラグイン・プロシージャ名

X

プラグイン・プロシージャのシグネチャ

X

A.5.1.2.2 プラグイン・プロシージャの仕様

表A-20に、様々なプラグイン・プロシージャを示します。また、各プロシージャで使用されるパラメータについても説明します。

表A-20 操作ベースと属性ベースのプラグイン・プロシージャのシグネチャ

起動コンテキスト プロシージャ名 INパラメータ OUTパラメータ

ldapbind

PRE_BIND

ldapcontext、Bind DN、Password

return code、error message

ldapbind時(ただし、デフォルト・サーバーの動作を置換)

WHEN_BIND_REPLACE

ldapcontext、bind result、DN、userpassword

bind result、return code、error message

ldapbind

POST_BIND

ldapcontext、Bind result、Bind DN、Password

return code、error message

ldapmodify

PRE_MODIFY

ldapcontext、DN、Mod structure

return code、error message

ldapmodify

WHEN_MODIFY

ldapcontext、DN、Mod structure

return code、error message

ldapmodify時(ただし、デフォルト・サーバーの動作を置換)

WHEN_MODIFY_REPLACE

ldapcontext、DN、Mod structure

return code、error message

ldapmodify

POST_MODIFY

ldapcontext、Modify result、DN、Mod structure

return code、error message

ldapcompare

PRE_COMPARE

ldapcontext、DN、attribute、value

return code、error message

ldapcompare時(ただし、デフォルト・サーバーの動作を置換)

WHEN_COMPARE_REPLACE

ldapcontext、Compare result、DN、attribute、value

compare result、return code、error message

ldapcompare

POST_COMPARE

ldapcontext、Compare result、DN、attribute、value

return code、error message

ldapadd

PRE_ADD

ldapcontext、DN、Entry

return code、error message

ldapadd

WHEN_ADD

ldapcontext、DN、Entry

return code、error message

ldapadd時(ただし、デフォルト・サーバーの動作を置換)

WHEN_ADD_REPLACE

ldapcontext、DN、Entry

return code、error message

ldapadd

POST_ADD

ldapcontext、Add result、DN、Entry

return code、error message

ldapdelete

PRE_DELETE

ldapcontext、DN

return code、error message

ldapdelete

WHEN_DELETE

ldapcontext、DN

return code、error message

ldapdelete時(ただし、デフォルト・サーバーの動作を置換)

WHEN_DELETE

ldapcontext、DN

return code、error message

ldapdelete

POST_DELETE

ldapcontext、Delete result、DN

return code、error message

ldapsearch

PRE_SEARCH

ldapcontext、Base DN、scope、filter

return code、error message

ldapsearch

POST_SEARCH

Ldap context、Search result、Base DN、scope、filter

return code、error message

関連項目:

A.5.1.3 PL/SQLプラグインのコンパイル

Oracle Internet Directoryのバックエンド・データベースと同じ役割を果たすデータベースに対して、プラグイン・モジュールをコンパイルする必要があります。プラグインのコンパイルは、PL/SQLストアド・プロシージャと同じです。無名PL/SQLブロックは、メモリーにロードされるたびにコンパイルされます。

すべてのプラグイン・モジュールは、ODSデータベース・スキーマでコンパイルする必要があります。次の各項で、さらに詳しく説明します。

A.5.1.3.1 プラグイン・コンパイルの段階の概要

コンパイルは3つの段階を踏んで実行されます。これらのツールは、次のとおりです。

  • 構文チェック: PL/SQL構文がチェックされ、解析ツリーが生成されます。

  • セマンティック・チェック: 型チェックおよび解析ツリーに対する追加処理が行われます。

  • コード生成: Pコードが生成されます。

A.5.1.3.2 プラグインのコンパイル中に発生したエラーの表示

プラグインのコンパイル中にエラーが発生した場合、そのプラグインは作成されません。プラグイン作成時のコンパイル・エラーを参照するには、SQL*PlusまたはEnterprise ManagerでSHOW ERRORS文を使用するか、あるいはSELECT文を使用してUSER_ERRORSビューからエラーを選択できます。

A.5.1.3.3 コンパイル済プラグインの依存性

コンパイル済プラグインには依存性があります。依存オブジェクト(プラグイン本体からコールされるストアド・プロシージャやファンクションなど)が変更された場合、プラグインは無効になります。依存性の理由から無効となったプラグインは、次回起動するまでに再コンパイルする必要があります。

A.5.1.3.4 プラグインの再コンパイル

ALTER PACKAGE文を使用してプラグインを手動で再コンパイルします。たとえば、次の文では、my_pluginプラグインを再コンパイルします。

ALTER PACKAGE my_plugin COMPILE PACKAGE;

A.5.1.4 PL/SQLプラグインの管理

次のトピックでは、プラグインの変更およびデバッグ方法について説明します。

A.5.1.4.1 プラグインの変更

ストアド・プロシージャと同様、プラグインは明示的に変更できません。これは、新しい定義で置換する必要があります。

プラグインを置換する場合は、CREATE PACKAGE文にOR REPLACEオプションを指定する必要があります。このOR REPLACEオプションによって、既存のプラグインの新規バージョンは、プラグインの元のバージョンに付与されている権限に影響を与えることなく古いバージョンを置換できます。

DROP PACKAGE文を使用してプラグインを削除してから、CREATE PACKAGE文を再実行することもできます。

プラグイン名(パッケージ名)が変更されている場合は、新規プラグインを再度登録する必要があります。

A.5.1.4.2 プラグインのデバッグ

プラグインは、PL/SQLストアド・プロシージャで使用可能な同じ機能を使用してデバッグできます。

A.5.1.5 PL/SQLプラグインの有効化と無効化

プラグインをオンまたはオフに切り替えるには、プラグイン構成オブジェクトのorclPluginEnableの値を変更します。たとえば、cn=post_mod_plugin,cn=plugins,cn=subconfigsubentryorclPluginEnableの値を1または0(ゼロ)に変更します。

A.5.1.6 PL/SQLプラグインにおける例外処理

PL/SQLプラグインの各プロシージャには、エラーを処理し、可能な場合にはリカバリを行うための例外処理ブロックが必要です。次の各項で、さらに詳しく説明します。

A.5.1.6.1 OIDのエラー・メッセージとリターン・コード

Oracle Internet Directoryでは、リターン・コード(rc)とエラー・メッセージ(errmsg)がプラグイン・プロシージャに正しく設定されている必要があります。

A.5.1.6.1.1 エラー処理のリターン・コード

表A-21にリターン・コードの有効な値を示します。

表A-21 プラグインのリターン・コードの有効な値

エラー・コード 説明
0

成功

0(ゼロ)より大きい数値

失敗

-1

警告

A.5.1.6.1.2 エラー・メッセージの表示とロギング

errmsgパラメータは、ユーザーのカスタム・エラー・メッセージをOracle Internet Directoryサーバーに戻すことができる文字列値です。errmsgのサイズ制限は、1024バイトです。Oracle Internet Directoryは、プラグイン・プログラムを実行するたびに、リターン・コードを検査し、エラー・メッセージの表示が必要かどうかを判断します。

たとえば、リターン・コードの値が0(ゼロ)の場合、エラー・メッセージの値は無視されます。リターン・コードの値が-1または0(ゼロ)よりも大きい場合は、次のメッセージがログ・ファイルに記録されるか、標準出力に表示(リクエスト元がLDAPコマンド行ツールの場合)されます。

ldap addition info: customized error 
A.5.1.6.2 プラグインの例外または失敗に応じたOracle Internet Directoryサーバーのアクション

Oracle Internet Directoryサーバーは、例外を様々な方法で処理します。次の各項で、さらに詳しく説明します。

A.5.1.6.2.1 プラグイン例外発生時のOracle Internet Directoryサーバーのアクション

表A-22に、プラグイン例外の発生場所とディレクトリによる処理方法を示します。

表A-22 プラグイン例外発生時のプログラム制御処理

プラグイン例外の発生場所 Oracle Internet Directoryサーバーによる処理

PRE_BINDPRE_MODIFYPRE_ADDPRE_SEARCHPRE_COMPAREPRE_DELETE

リターン・コードに従います。処理は次のとおりです。

  • 0(ゼロ)より大きい場合(エラー)は、LDAP操作を実行しません。

  • -1の場合(警告)は、LDAP操作を続行します。

POST_BINDPOST_MODIFYPOST_ADDPOST_SEARCHWHEN_DELETE

LDAP操作を完了します。ロールバックは実行されません。

WHEN_MODIFYWHEN_ADDWHEN_DELETE

LDAP操作をロールバックします。

A.5.1.6.2.2 LDAP操作障害時のOracle Internet Directoryサーバーのアクション

表A-23に、LDAP操作障害時のディレクトリの対応を示します。

表A-23 LDAP操作障害時のプログラム制御処理

LDAP操作障害の発生場所 Oracle Internet Directoryサーバーによる処理

PRE_BINDPRE_MODIFYPRE_ADDPRE_SEARCHWHEN_DELETE

操作前プラグインを完了します。ロールバックは実行されません。

POST_BINDPOST_MODIFYPOST_ADDPOST_SEARCHWHEN_DELETE

操作後プラグインが続行されます。LDAP操作結果はINパラメータの1つです。

WHEN_MODIFYWHEN_ADDWHEN_DELETE

操作時タイプのプラグインの変更はロールバックされます。

WHEN

プラグイン・プログラム本体への変更はロールバックされます。

A.5.1.7 PL/SQLプラグインLDAP API

APIアクセスを提供するには、次のように様々な方法があります。

  • ユーザーは標準LDAP PL/SQL APIを利用できます。ただし、プログラム・ロジックを慎重に計画しないと、プラグインの実行で無限ループが発生する可能性があることに注意してください。

  • Oracle Internet DirectoryはプラグインLDAP APIを提供します。LDAPリクエストに関連付けられている構成済のプラグインがある場合、このプラグインは、ディレクトリ・サーバー内の一連のプラグイン・アクションを実行しません。

プラグインLDAP APIでは、プラグイン・モジュールで指定されたディレクトリ・サーバーに接続するためのAPIがディレクトリにより提供されます。プラグインを実行するサーバーに接続する場合、このAPIを使用する必要があります。外部サーバーに接続する場合、DBMS_LDAP APIを使用できます。

各プラグイン・モジュールでは、ldapcontextがOracleディレクトリ・サーバーから渡されます。プラグインLDAP APIがコールされると、セキュリティおよびバインドの目的でldapcontextが渡されます。このldapcontextを使用してバインドすると、Oracle Internet Directoryで、LDAPリクエストがプラグイン・モジュールからのリクエストであることが認識されます。このタイプのプラグイン・バインドの場合、ディレクトリによって後続のプラグインがトリガーされることはありません。プラグイン・バインドは、スーパーユーザー・バインドとして処理されます。このプラグイン・バインドは慎重に使用してください。

A.5.1.8 PL/SQLプラグインおよびデータベース・ツール

バルク・ツールは、サーバー・プラグインをサポートしていません。

A.5.1.9 PL/SQLプラグインのセキュリティの確保

一部のOracle Internet Directoryサーバーのプラグインでは、厳重なセキュリティを保持するコードをユーザーが用意する必要があります。たとえば、ディレクトリのldapcompareまたはldapbind操作をユーザー独自のプラグイン・モジュールで置換する場合、ユーザーは、セキュリティを維持するための機能が、この操作の実装によって除外されないことを確認する必要があります。

厳重なセキュリティを確保するには、次の処理を実行する必要があります。

  • プラグイン・パッケージを作成します。

  • LDAP管理者のみがデータベース・ユーザーを制限できるように指定します。

  • アクセス制御リスト(ACL)を使用して、LDAP管理者のみがプラグイン構成エントリにアクセスできるように設定します。

  • 異なる複数のプラグイン間におけるプログラムの関連性に注意します。

A.5.1.10 PL/SQLプラグインのデバッグ

プラグインの処理および内容を検証するには、Oracle Internet Directoryのプラグイン・デバッグ・メカニズムを使用します。次のコマンドは、サーバーのデバッグ処理の操作を制御します。

  • プラグインのデバッグを設定するには、次のコマンドを実行します。

    % sqlplus ods @$ORACLE/ldap/admin/oidspdsu.pls
    
  • プラグインのデバッグを有効にするには、次のコマンドを実行します。

    % sqlplus ods @$ORACLE/ldap/admin/oidspdon.pls
    
  • プラグインのデバッグを有効にした後は、プラグイン・モジュール・コードで次のコマンドを使用できます。

    plg_debug('debuggingmessage');
    

    生成されたデバッグ・メッセージは、プラグイン・デバッグ表に格納されます。

  • デバッグを無効にするには、次のコマンドを実行します。

    % sqlplus ods @$ORACLE/ldap/admin/oidspdof.pls
    
  • プラグイン・モジュールに設定したデバッグ・メッセージを表示するには、次のコマンドを実行します。

    % sqlplus ods @$ORACLE/ldap/admin/oidspdsh.pls
    
  • デバッグ表からすべてのデバッグ・メッセージを削除するには、次のコマンドを実行します。

    % sqlplus ods @$ORACLE/ldap/admin/oidspdde.pls

A.5.1.11 PL/SQLプラグインLDAP APIの仕様

Oracle Internet Directoryが提供するPL/SQLプラグインLDAP APIのパッケージ仕様は次のとおりです。

CREATE OR REPLACE  PACKAGE LDAP_PLUGIN AS
    SUBTYPE SESSION IS RAW(32);

    -- Initializes the LDAP library and return a session handler
    -- for use in subsequent calls.
    FUNCTION init (ldappluginctx IN ODS.plugincontext)
      RETURN SESSION;

    -- Synchronously authenticates to the directory server using
    -- a Distinguished Name and password.
    FUNCTION simple_bind_s (ldappluginctx IN ODS.plugincontext,
                            ld            IN SESSION)
      RETURN PLS_INTEGER;

    -- Get requester info from the plug-in context
    FUNCTION get_requester (ldappluginctx IN ODS.plugincontext)
      RETURN VARCHAR2;
END LDAP_PLUGIN;

A.5.2 PL/SQLプラグインの使用

例を使用してPL/SQLプラグインについて理解します。この項では、2つのサンプル・プラグインを示します。一方は、すべてのldapsearchコマンドを記録します。もう一方は、2つのディレクトリ情報ツリー(DIT)を同期化します。

この項では、次の項目について説明します。

A.5.2.1 プラグインを介したすべてのldapsearchコマンドの記録

状況: すべてのldapsearchコマンドを記録できるかどうかについて、あるユーザーが疑問を持っています。

解答: 記録できます。これには、ldapsearch操作後構成プラグインを使用できます。リクエストをすべて記録することも、検索対象のDNで発生したリクエストのみを記録することも可能です。

すべてのldapsearchコマンドを記録するには:

  1. すべてのldapsearch結果をデータベース表に記録します。このログ表には次の列があります。
    • timestamp

    • baseDN

    • search scope

    • search filter

    • required attribute

    • search result

    表を作成するには、次のSQLスクリプトを使用します。

    drop table search_log;
    create table search_log 
    (timestamp varchar2(50),
    basedn varchar2(256),
    searchscope number(1);
    searchfilter varchar2(256);
    searchresult number(1));
    drop table simple_tab;
    create table simple_tab (id NUMBER(7), dump varchar2(256));
    DROP sequence seq;
    CREATE sequence seq START WITH 10000;
    commit;
    
  2. プラグイン・パッケージ仕様を作成します。
    CREATE OR REPLACE PACKAGE LDAP_PLUGIN_EXAMPLE1 AS
    PROCEDURE post_search 
    (ldapplugincontext IN  ODS.plugincontext,
    result       IN  INTEGER,
    baseDN       IN  VARCHAR2,
    scope        IN  INTEGER,
    filterStr    IN  VARCHAR2,
    requiredAttr IN  ODS.strCollection,
    rc           OUT INTEGER,
    errormsg     OUT VARCHAR2
    );
    END LDAP_PLUGIN_EXAMPLE1;
    /
    
  3. プラグイン・パッケージ本体を作成します。
    CREATE OR REPLACE PACKAGE BODY LDAP_PLUGIN_EXAMPLE1 AS
    PROCEDURE post_search 
    (ldapplugincontext IN  ODS.plugincontext,
    result       IN  INTEGER,
    baseDN       IN  VARCHAR2,
    scope        IN  INTEGER,
    filterStr    IN  VARCHAR2,
    requiredAttr IN  ODS.strCollection,
    rc           OUT INTEGER,
    errormsg     OUT VARCHAR2
    )
          IS
    BEGIN
       INSERT INTO simple_tab VALUES 
    (to_char(sysdate, 'Month DD, YYYY HH24:MI:SS'), baseDN, scope, filterStr, result);
       -- The following code segment demonstrate how to iterate
       -- the ODS.strCollection 
       FOR l_counter1 IN 1..requiredAttr.COUNT LOOP
          INSERT INTO simple_tab
            values (seq.NEXTVAL, 'req attr ' || l_counter1 || ' = ' ||
                    requiredAttr(l_counter1));
       END LOOP;
       rc := 0;
       errormsg := 'no post_search plug-in error msg';
       COMMIT;
    EXCEPTION
       WHEN others THEN
          rc := 1;
          errormsg := 'exception: post_search plug-in';
    END;
    END LDAP_PLUGIN_EXAMPLE1;
    /
    
  4. プラグイン・エントリをOracle Internet Directoryに登録します。
    dn: cn=post_search,cn=plugin,cn=subconfigsubentry
    objectclass: orclPluginConfig
    objectclass: top
    orclPluginName: ldap_plugin_example1
    orclPluginType: configuration
    orclPluginTiming: post
    orclPluginLDAPOperation: ldapsearch
    orclPluginEnable: 1
    orclPluginVersion: 1.0.1
    cn: post_search
    orclPluginKind: PLSQL
    

    ldapaddコマンド行ツールを使用して、このエントリを追加します。

    % ldapadd –p port_number –h host_name –D bind_dn –q –v \
              –f register_post_search.ldif

A.5.2.2 プラグインを介した2つのDITの同期化

状況: 相互に依存する2つの製品がcn=Productscn=oraclecontextにあります。この相互依存性は、これらの製品のコンテナ内のユーザーにも適用されます。最初のDIT(製品1)のユーザーが削除された場合、もう一方のDIT(製品2)の対応するユーザーを削除する必要があります。

トリガーを設定して、最初のDITのユーザーが削除された場合に2番目のDITのユーザーを削除するトリガーをコールする、または渡すことは可能でしょうか。

解答: 可能です。ldapdelete操作後プラグインを使用して、2番目のDITで発生する2番目の削除を処理できます。

最初のDITにcn=DIT1,cn=products,cn=oraclecontextというネーミング・コンテキストがあり、2番目のDITにcn=DIT2,cn=products,cn=oraclecontextというネーミング・コンテキストがある場合、2人のユーザーは同一のID属性を共有します。ldapdelete操作後プラグイン・モジュール内で、LDAP_PLUGINDBMS_LDAPのAPIを使用して、2番目のDIT内のユーザーを削除できます。

orclPluginSubscriberDNListcn=DIT1,cn=products,cn=oraclecontextに設定する必要があります。これによって、cn=DIT1,cn=products,cn=oraclecontextのエントリを削除すると、常にプラグイン・モジュールが起動されるようになります。

ノート:

ldapmodify操作後プラグインを使用して2つのOracle Internet Directoryのノード間で変更を同期化する場合、一方のノードから他方のノードへすべての属性をプッシュすることはできません。これは、プラグイン・モジュールで取得された変更(変更構造体)に操作属性が含まれているためです。このような操作属性は各ノードで生成されるものであり、標準のLDAPメソッドを使用して変更できません。

プラグイン・プログラムを記述する際には、操作属性authPasswordcreatorsnamecreatetimestampmodifiersnamemodifytimestamporcllastlogintimepwdchangedtimepwdfailuretimepwdaccountlockedtimepwdexpirationwarnedpwdresetpwdhistorypwdgraceusetimeを同期化の対象から除外します。

同期するには:

  1. 両方のDITのエントリはディレクトリに追加されていると仮定します。たとえば、エントリid=12345,cn=DIT1,cn=products,cn=oraclecontextDIT1に、エントリid=12345,cn=DIT2,cn=products,cn=oraclecontextDIT2にあります。
  2. プラグイン・パッケージ仕様を作成します。
    CREATE OR REPLACE PACKAGE LDAP_PLUGIN_EXAMPLE2 AS
    PROCEDURE post_delete 
    (ldapplugincontext IN  ODS.plugincontext,
    result   IN  INTEGER,
    dn       IN  VARCHAR2,
    rc       OUT INTEGER,
    errormsg OUT VARCHAR2
    ); 
    END LDAP_PLUGIN_EXAMPLE2;
    /
    
  3. プラグイン・パッケージ本体を作成します。
    CREATE OR REPLACE PACKAGE BODY LDAP_PLUGIN_EXAMPLE2 AS
    PROCEDURE post_delete 
    (ldapplugincontext IN  ODS.plugincontext,
    result   IN  INTEGER,
    dn       IN  VARCHAR2,
    rc       OUT INTEGER,
    errormsg OUT VARCHAR2
    )
        IS
         retval       PLS_INTEGER;
         my_session   DBMS_LDAP.session;
         newDN        VARCHAR2(256);
    BEGIN
       retval         := -1;
       my_session := LDAP_PLUGIN.init(ldapplugincontext);
       -- bind to the directory
       retval := LDAP_PLUGIN.simple_bind_s(ldapplugincontext, my_session);
       -- if retval is not 0, then raise exception
       newDN := REPLACE(dn,'DIT1','DIT2');
       retval := DBMS_LDAP.delete_s(my_session, newDN);
       -- if retval is not 0, then raise exception
       rc := 0;
       errormsg := 'no post_delete plug-in error msg';
    EXCEPTION
       WHEN others THEN
          rc := 1;
          errormsg := 'exception: post_delete plug-in';
    END; 
    END LDAP_PLUGIN_EXAMPLE2;
    /
    (ldapplugincontext IN  ODS.plugincontext,
    result   IN  INTEGER,
    dn       IN  VARCHAR2,
    rc       OUT INTEGER,
    errormsg OUT VARCHAR2
    )
        IS
         retval       PLS_INTEGER;
         my_session   DBMS_LDAP.session;
         newDN        VARCHAR2(256);
    BEGIN
       retval         := -1;
       my_session := LDAP_PLUGIN.init(ldapplugincontext);
       -- bind to the directory
       retval := LDAP_PLUGIN.simple_bind_s(ldapplugincontext, my_session);
       -- if retval is not 0, then raise exception
       newDN := REPLACE(dn,'DIT1','DIT2');
       retval := DBMS_LDAP.delete_s(my_session, newDN);
       -- if retval is not 0, then raise exception
       rc := 0;
       errormsg := 'no post_delete plug-in error msg';
    EXCEPTION
       WHEN others THEN
          rc := 1;
          errormsg := 'exception: post_delete plug-in';
    END; 
    END LDAP_PLUGIN_EXAMPLE2;
    /
    
  4. プラグイン・エントリをOracle Internet Directoryに登録します。

    LDIFファイルregister_post_delete.ldifを構成します。

    dn: cn=post_delete,cn=plugin,cn=subconfigsubentry
    objectclass: orclPluginConfig
    objectclass: top
    orclPluginName: ldap_plugin_example2
    orclPluginType: configuration
    orclPluginTiming: post
    orclPluginLDAPOperation: ldapdelete
    orclPluginEnable: 1
    orclPluginSubscriberDNList: cn=DIT1,cn=oraclecontext,cn=products
    orclPluginVersion: 1.0.1
    cn: post_delete
    orclPluginKind: PLSQL
    

    ldapaddコマンド行ツールを使用して、このエントリを追加します。

    % ldapadd –p port_number –h host_name –D bind_dn –q –v –f register_
    post_delete.ldif

A.5.3 PL/SQLプラグインを使用したバイナリ操作の実行

リリース10.1.2から、プラグインLDAP APIのオブジェクト定義によって、ldapmodifyldapaddおよびldapcompareのプラグインがディレクトリ・データベース内のバイナリ属性にアクセスできるようになりました。

これまでは、アクセスできるのはタイプVARCHAR2の属性のみでした。これらのオブジェクト定義では、リリース10.1.2より前のプラグイン・コードは無効化されません。このコードを変更する必要はありません。新しい定義は、「LDAP APIプラグインのオブジェクト型定義」に記載されています。

この項では、3種類のプラグインが関係するバイナリ操作について説明します。これらのプラグインの例も示します。新しいオブジェクト定義は、3つすべてについて操作前、操作後および操作時のバージョンに適用されます。

3つの例では、LOBのかわりにRAWファンクションおよび変数を使用していることに注意してください。次の各項では、これについてさらに詳しく説明しています。

A.5.3.1 ldapmodifyプラグインを使用した別のディレクトリのエントリの変更

プラグイン・フレームワークがldapmodifyのプラグインに渡すmodobjオブジェクトに、バイナリ属性の値がbinvalsとして格納されるようになりました。この変数は、binvalobjオブジェクトの表です。

このプラグインでは、modobjoperationフィールドを調べて、バイナリ操作が実行されているかどうかを判断します。これにより、値DBMS_LDAP.MOD_ADDDBMS_LDAP.MOD_DELETEおよびDBMS_LDAP.MOD_REPLACEのいずれかが、DBMS_LDAP.MOD_BVALUESと組み合されているかどうかがチェックされます。たとえば、DBMS_LDAP.MOD_ADD+DBMS_LDAP.MOD_BVALUESの組合せは、変更操作におけるバイナリの追加を示します。

次の例は、別のディレクトリのエントリを変更する、ldapmodify操作後プラグインを示しています。このプラグインは、ldapmodifyがプラグイン・ディレクトリの同じエントリに同じ変更を適用した後、起動されます。もう一方のディレクトリのエントリは、DIT cn=users,dc=us,dc=example,dc=comにあります。

create or replace package moduser as
   procedure post_modify(ldapplugincontext IN ODS.plugincontext,
                          result IN integer,
                          dn IN varchar2,
                          mods IN ODS.modlist,
                          rc OUT integer,
                          errormsg OUT varchar2);
end moduser;
/
show error
 
CREATE OR REPLACE PACKAGE BODY moduser AS
   procedure post_modify(ldapplugincontext IN ODS.plugincontext,
                          result IN integer,
                          dn IN varchar2,
                          mods IN ODS.modlist,
                          rc OUT integer,
                          errormsg OUT varchar2)
   is
      counter1 pls_integer;
      counter2 pls_integer;
      retval pls_integer := -1;
      user_session DBMS_LDAP.session;
      user_dn varchar(256);
      user_array DBMS_LDAP.mod_array;
      user_vals DBMS_LDAP.string_collection;
      user_binvals DBMS_LDAP.blob_collection;
      ldap_host varchar(256);
      ldap_port varchar(256);
      ldap_user varchar(256);
      ldap_passwd varchar(256);
   begin
      ldap_host :='backup.us.example.com';
      ldap_port :='4000';
      ldap_user :='cn=orcladmin';
      ldap_passwd :='password';
 
      plg_debug('START MODIFYING THE ENTRY');
 
      -- Get a session
         user_session := dbms_ldap.init(ldap_host, ldap_port);
 
      -- Bind to the directory
         retval := dbms_ldap.simple_bind_s(user_session, ldap_user, 
         ldap_passwd);
 
      -- Create a mod_array
         user_array := dbms_ldap.create_mod_array(mods.count);
 
      -- Create a user_dn
         user_dn := substr(dn,1,instr(dn,',',1,1))||'cn=users,dc=us,dc=example,
         dc=com';

        plg_debug('THE CREATED DN IS'||user_dn);
 
      -- Iterate through the modlist
         for counter1 in 1..mods.count loop
 
      -- Log the attribute name and operation
         if (mods(counter1).operation > DBMS_LDAP.MOD_BVALUES) then
           plg_debug('THE NAME OF THE BINARY ATTR. IS'||mods(counter1).type);
         else
           plg_debug('THE NAME OF THE NORMAL ATTR. IS'||mods(counter1).type);
         end if;
           plg_debug('THE OPERATION IS'||mods(counter1).operation);
 
      -- Add the attribute values to the collection
         for counter2 in 1..mods(counter1).vals.count loop
           user_vals(counter2) := mods(counter1).vals(counter2).val;
         end loop;
 
      -- Add the attribute values to the collection
         for counter2 in 1..mods(counter1).binvals.count loop
           plg_debug('THE NO. OF BYTES OF THE BINARY ATTR. VALUE IS'
           ||mods(counter1).binvals(counter2).length);
           user_binvals(counter2) := mods(counter1).binvals(counter2).binval;
         end loop;
 
      -- Populate the mod_array accordingly with binary/normal attributes
         if (mods(counter1).operation >= DBMS_LDAP.MOD_BVALUES) then
           dbms_ldap.populate_mod_array(user_array,mods(counter1).operation -
           DBMS_LDAP.MOD_BVALUES,mods(counter1).type,user_binvals);
           user_binvals.delete;
         else
           dbms_ldap.populate_mod_array(user_array,mods(counter1).operation,
           mods(counter1).type,user_vals);
           user_vals.delete;
         end if;
 
        end loop;
 
      -- Modify the entry
         retval := dbms_ldap.modify_s(user_session,user_dn,user_array);
         if retval = 0 then
           rc := 0;
           errormsg:='No error occurred while modifying the entry';
         else
           rc := retval;
           errormsg :='Error code'||rc||' while modifying the entry';
         end if;
 
      -- Free the mod_array
         dbms_ldap.free_mod_array(user_array);
 
       plg_debug('FINISHED MODIFYING THE ENTRY');
 
   exception
 WHEN others THEN
   plg_debug (SQLERRM);
 end;
end moduser;
/
show error
 
exit;

A.5.3.2 ldapaddプラグインを使用した別のディレクトリへの変更の伝播

プラグイン・フレームワークがldapaddのプラグインに渡すentryobjオブジェクトに、バイナリ属性がbinattrとして格納されるようになりました。この変数は、binattrobjオブジェクトの表です。次の例は、プラグイン・ディレクトリの変更(追加されたユーザー)を別のディレクトリに伝播する追加後プラグインを示しています。後者のディレクトリのエントリは、DIT cn=users,dc=us,dc=example,dc=comにあります。

create or replace package adduser as
   procedure post_add(ldapplugincontext IN ODS.plugincontext,
                          result IN integer,
                          dn IN varchar2,
                          entry IN ODS.entryobj,
                          rc OUT integer,
                          errormsg OUT varchar2);
end adduser;
/
show error
 
CREATE OR REPLACE PACKAGE BODY adduser AS
   procedure post_add(ldapplugincontext IN ODS.plugincontext,
                          result IN integer,
                          dn IN varchar2,
                          entry IN ODS.entryobj,
                          rc OUT integer,
                          errormsg OUT varchar2)
   is
      counter1 pls_integer;
      counter2 pls_integer;
      retval pls_integer := -1;
      s integer;
      user_session DBMS_LDAP.session;
      user_dn varchar(256);
      user_array DBMS_LDAP.mod_array;
      user_vals DBMS_LDAP.string_collection;
      user_binvals DBMS_LDAP.blob_collection;
      ldap_host varchar(256);
      ldap_port varchar(256);
      ldap_user varchar(256);
      ldap_passwd varchar(256);
   begin
      ldap_host :='backup.us.example.com';
      ldap_port :='4000';
      ldap_user :='cn=orcladmin';
      ldap_passwd :='password';
 
      plg_debug('START ADDING THE ENTRY');
 
      -- Get a session
         user_session := dbms_ldap.init(ldap_host, ldap_port);
 
      -- Bind to the directory
         retval := dbms_ldap.simple_bind_s(user_session, ldap_user, ldap_passwd);
 
      -- Create a mod_array
         user_array := dbms_ldap.create_mod_array(entry.binattr.count + 
         entry.attr.count);
 
      -- Create a user_dn
         user_dn := substr(dn,1,instr(dn,',',1,1))||'cn=users,dc=us,dc=example,
         dc=com';
         plg_debug('THE CREATED DN IS'||user_dn);
 
      -- Populate the mod_array with binary attributes
         for counter1 in 1..entry.binattr.count loop
           for counter2 in 1..entry.binattr(counter1).binattrval.count loop
             plg_debug('THE NAME OF THE BINARY ATTR. IS'||
             entry.binattr(counter1).binattrname);
             s := dbms_lob.getlength(entry.binattr(counter1).
             binattrval(counter2));
             plg_debug('THE NO. OF BYTES OF THE BINARY ATTR. VALUE IS'||s);
             user_binvals(counter2) := entry.binattr(counter1).
             binattrval(counter2);
           end loop;
         dbms_ldap.populate_mod_array(user_array,DBMS_LDAP.MOD_ADD,
         entry.binattr(counter1).binattrname,user_binvals);
         user_binvals.delete;
        end loop;
 
      -- Populate the mod_array with attributes
         for counter1 in 1..entry.attr.count loop
           for counter2 in 1..entry.attr(counter1).attrval.count loop
             plg_debug('THE NORMAL ATTRIBUTE'||entry.attr(counter1).attrname||'
             HAS THE VALUE'||entry.attr(counter1).attrval(counter2));
             user_vals(counter2) := entry.attr(counter1).attrval(counter2);
           end loop;
         dbms_ldap.populate_mod_array(user_array,DBMS_LDAP.MOD_ADD,
         entry.attr(counter1).attrname,user_vals);
         user_vals.delete;
         end loop;
 
      -- Add the entry
         retval := dbms_ldap.add_s(user_session,user_dn,user_array);
         plg_debug('THE RETURN VALUE IS'||retval);
         if retval = 0 then
           rc := 0;
           errormsg:='No error occurred while adding the entry';
         else
           rc := retval;
           errormsg :='Error code'||rc||' while adding the entry';
         end if;
 
      -- Free the mod_array
         dbms_ldap.free_mod_array(user_array);
         retval := dbms_ldap.unbind_s(user_session);
 
         plg_debug('FINISHED ADDING THE ENTRY');
 
   exception
 WHEN others THEN
   plg_debug (SQLERRM);
 end;
end adduser;
/
show error
 
exit;

A.5.3.3 ldapcompareプラグインを使用したバイナリ属性の比較

ldapcompareのプラグインは、オーバーロードされた3つの新しいモジュール・インタフェースを使用してバイナリ属性を比較できます。これらのインタフェースを使用して、バイナリと非バイナリ両方の属性を処理するプラグイン・パッケージを開発する場合、パッケージに2つの別々のプロシージャを含める必要があります。orclPluginNameはプラグイン・エントリに1つしか登録できないため、2つのプロシージャのパッケージ名は同じです。

既存のプラグイン・パッケージを更新してバイナリ属性を比較するプロシージャを含めた後、パッケージを再インストールします。そのプラグイン・パッケージに依存するパッケージを再コンパイルします。

3つの新しいインタフェースは次のようになります。

PROCEDURE pre_compare (ldapplugincontext IN ODS.plugincontext,
                       dn          IN VARCHAR2,
                       attrname    IN VARCHAR2,
                       attrval     IN BLOB,
                       rc          OUT INTEGER,
                       errormsg    OUT VARCHAR2 );

PROCEDURE when_compare_replace (ldapplugincontext IN ODS.plugincontext,
                                result      OUT INTEGER,
                                dn          IN VARCHAR2,
                                attrname    IN VARCHAR2,
                                attrval     IN BLOB,
                                rc          OUT INTEGER,
                                errormsg    OUT VARCHAR2 );

PROCEDURE post_compare (ldapplugincontext IN ODS.plugincontext,
                        result      IN INTEGER,
                        dn          IN VARCHAR2,
                        attrname    IN VARCHAR2,
                        attrval     IN BLOB,
                        rc          OUT INTEGER,
                        errormsg    OUT VARCHAR2 );

次の例では、プラグイン・ディレクトリのエントリのバイナリ属性と別のディレクトリのエントリのバイナリ属性を比較します。このパッケージは、サーバーの比較コードをプラグインの比較コードに置き換えます。また、バイナリと非バイナリ両方の属性を処理します。そのため、2つの別々のプロシージャが含まれています。

create or replace package compareattr as
   procedure when_compare_replace(ldapplugincontext IN ODS.plugincontext,
                          result OUT integer,
                          dn IN varchar2,
                          attrname IN VARCHAR2,
                          attrval IN BLOB,
                          rc OUT integer,
                          errormsg OUT varchar2);
   procedure when_compare_replace(ldapplugincontext IN ODS.plugincontext,
                          result OUT integer,
                          dn IN varchar2,
                          attrname IN VARCHAR2,
                          attrval IN varchar2,
                          rc OUT integer,
                          errormsg OUT varchar2);
end compareattr;
/
show error
 
CREATE OR REPLACE PACKAGE BODY compareattr AS
   procedure when_compare_replace(ldapplugincontext IN ODS.plugincontext,
                          result OUT integer,
                          dn IN varchar2,
                          attrname IN VARCHAR2,
                          attrval IN varchar2,
                          rc OUT integer,
                          errormsg OUT varchar2)
   is
   pos            INTEGER := 2147483647;
   begin
      plg_debug('START');
      plg_debug('THE ATTRNAME IS'||attrname||' AND THE VALUE IS'||attrval);
      plg_debug('END');
      rc := 0;
      errormsg :='No error!!!';
   exception
   WHEN others THEN
    plg_debug ('Unknown UTL_FILE Error');
   end;
 
   procedure when_compare_replace(ldapplugincontext IN ODS.plugincontext,
                          result OUT integer,
                          dn IN varchar2,
                          attrname IN VARCHAR2,
                          attrval IN BLOB,
                          rc OUT integer,
                          errormsg OUT varchar2)
   is
      counter pls_integer;
      retval pls_integer := -1;
      cmp_result integer;
      s integer;
      user_session DBMS_LDAP.session;
      user_entry DBMS_LDAP.message;
      user_message DBMS_LDAP.message;
      user_dn varchar(256);
      user_attrs DBMS_LDAP.string_collection;
      user_attr_name VARCHAR2(256);
      user_ber_elmt DBMS_LDAP.ber_element;
      user_vals DBMS_LDAP.blob_collection;
      ldap_host varchar(256);
      ldap_port varchar(256);
      ldap_user varchar(256);
      ldap_passwd varchar(256);
      ldap_base varchar(256);
   begin
      ldap_host :='backup.us.example.com';
      ldap_port :='4000';
      ldap_user :='cn=orcladmin';
      ldap_passwd :='password';
      ldap_base := dn;
 
      plg_debug('STARTING COMPARISON IN WHEN REPLACE PLUG-IN');
 
        s := dbms_lob.getlength(attrval);
        plg_debug('THE NUMBER OF BYTES OF ATTRVAL'||s);
 
      -- Get a session
         user_session := dbms_ldap.init(ldap_host, ldap_port);
 
      -- Bind to the directory
         retval := dbms_ldap.simple_bind_s(user_session, ldap_user, ldap_passwd);
 
      -- issue the search
         user_attrs(1) := attrname;
         retval := DBMS_LDAP.search_s(user_session, ldap_base,
                                     DBMS_LDAP.SCOPE_BASE,
                                    'objectclass=*',
                                     user_attrs,
                                     0,
                                     user_message);
 
      -- Get the entry in the other OID server
         user_entry := DBMS_LDAP.first_entry(user_session, user_message);
 
      -- Log the DN and the Attribute name
         user_dn := DBMS_LDAP.get_dn(user_session, user_entry);
         plg_debug('THE DN IS'||user_dn);
         user_attr_name := DBMS_LDAP.first_attribute(user_session,user_entry,
         user_ber_elmt);
 
      -- Get the values of the attribute
         user_vals := DBMS_LDAP.get_values_blob(user_session, user_entry,
         user_attr_name);
 
      -- Start the binary comparison between the ATTRVAL and the attribute
      -- values
         if user_vals.count > 0 then
          for counter in user_vals.first..user_vals.last loop
            cmp_result := dbms_lob.compare(user_vals(counter),attrval,
                             dbms_lob.getlength(user_vals(counter)),1,1);
            if  cmp_result = 0 then
                 rc := 0;
                 -- Return LDAP_COMPARE_TRUE
                 result := 6;
                 plg_debug('THE LENGTH OF THE ATTR.'||user_attr_name||' IN THE
                 ENTRY IS'||dbms_lob.getlength(user_vals(counter)));
                 errormsg :='NO ERROR. THE COMPARISON HAS SUCCEEDED.';
                 plg_debug(errormsg);
                 plg_debug('FINISHED COMPARISON');
                 return;
            end if;
          end loop;
        end if;
 
      rc := 1;
      -- Return LDAP_COMPARE_FALSE
         result := 5;
         errormsg :='ERROR. THE COMPARISON HAS FAILED.';
         plg_debug('THE LENGTH OF THE ATTR.'||user_attr_name||' IN THE ENTRY IS'
         ||dbms_lob.getlength(user_vals(user_vals.last)));
         plg_debug(errormsg);
         plg_debug('FINISHED COMPARISON');
 
      -- Free user_vals
         dbms_ldap.value_free_blob(user_vals);
         exception
         WHEN others THEN
           plg_debug (SQLERRM);
         end;
      end compareattr;
      /
      show error
 
      exit;

A.5.4 LDAP APIプラグインのオブジェクト型定義

プラグインLDAP APIに導入されたオブジェクト型について理解します。これらの定義は、すべてOracle Directory Serverのデータベース・スキーマにあります。APIにはプラグインがデータベースからバイナリ・データを抽出するためのオブジェクト型が含まれていることに注意してください。

create or replace type strCollection as TABLE of VARCHAR2(512);
/
create or replace type pluginContext as TABLE of VARCHAR2(512);
/
create or replace type attrvalType as TABLE OF VARCHAR2(4000);
/
create or replace type attrobj as object (
attrname    varchar2(2000),
attrval     attrvalType
);
/
create or replace type attrlist as table of attrobj;
/
create or replace type binattrvalType as TABLE OF BLOB;
/
create or replace type binattrobj as object (
binattrname    varchar2(2000),
binattrval     binattrvalType
);
/
create or replace type binattrlist as table of binattrobj;
/
create or replace type entryobj as object (
entryname      varchar2(2000),
attr           attrlist,
binattr        binattrlist
);
/
create or replace type entrylist as table of entryobj;
/
 
create or replace type bvalobj as object (
length         integer,
val            varchar2(4000)
);
/
create or replace type bvallist as table of bvalobj;
/
create or replace type binvalobj as object (
length         integer,
binval         blob
);
/
create or replace type binvallist as table of binvalobj;
/
create or replace type modobj as object (
operation      integer,
type           varchar2(256),
vals           bvallist,
binvals        binvallist
);
/
create or replace type modlist as table of modobj;

A.5.5 PL/SQLプラグイン・プロシージャの仕様

プラグインを使用する場合、各プラグインに定義されたシグネチャに従う必要があります。次に各シグネチャを示します。

PROCEDURE pre_add (ldapplugincontext IN  ODS.plugincontext,
dn             IN  VARCHAR2,
entry          IN  ODS.entryobj,
rc             OUT INTEGER,
errormsg       OUT VARCHAR2);
                                             
PROCEDURE when_add (ldapplugincontext IN  ODS.plugincontext,
dn             IN  VARCHAR2,
entry          IN  ODS.entryobj,
rc             OUT INTEGER,
errormsg       OUT VARCHAR2);
PROCEDURE when_add_replace (ldapplugincontext IN  ODS.plugincontext,
dn             IN  VARCHAR2,
entry          IN  ODS.entryobj,
rc             OUT INTEGER,
errormsg       OUT VARCHAR2);
PROCEDURE post_add (ldapplugincontext IN  ODS.plugincontext,
result         IN  INTEGER,
dn             IN  VARCHAR2,
entry          IN  ODS.entryobj,
rc             OUT INTEGER,
errormsg       OUT VARCHAR2);
PROCEDURE pre_modify (ldapplugincontext IN  ODS.plugincontext,
dn             IN  VARCHAR2,
mods           IN  ODS.modlist,
rc             OUT INTEGER,
errormsg       OUT VARCHAR2);
PROCEDURE when_modify (ldapplugincontext IN  ODS.plugincontext,
dn             IN  VARCHAR2,
mods           IN  ODS.modlist,
rc             OUT INTEGER,
errormsg       OUT VARCHAR2);
PROCEDURE when_modify_replace (ldapplugincontext IN  ODS.plugincontext,
dn             IN  VARCHAR2,
mods           IN  ODS.modlist,
rc             OUT INTEGER,
errormsg       OUT VARCHAR2);
PROCEDURE post_modify (ldapplugincontext IN  ODS.plugincontext,
result         IN  INTEGER,
dn             IN  VARCHAR2,
mods           IN  ODS.modlist,
rc             OUT INTEGER,
errormsg       OUT VARCHAR2);
PROCEDURE pre_compare (ldapplugincontext IN  ODS.plugincontext,
dn             IN  VARCHAR2,
attrname       IN  VARCHAR2,
attrval        IN  VARCHAR2,
rc             OUT INTEGER,
errormsg       OUT VARCHAR2
);
PROCEDURE pre_compare (ldapplugincontext IN ODS.plugincontext,
dn             IN VARCHAR2,
attrname       IN VARCHAR2,
attrval        IN BLOB,
rc             OUT INTEGER,
errormsg       OUT VARCHAR2 );

PROCEDURE when_compare_replace (ldapplugincontext IN  ODS.plugincontext,
result         OUT INTEGER,
dn             IN  VARCHAR2,
attrname       IN  VARCHAR2,
attrval        IN  VARCHAR2,
rc             OUT INTEGER,
errormsg       OUT VARCHAR2
);

PROCEDURE when_compare_replace (ldapplugincontext IN ODS.plugincontext,
result         OUT INTEGER,
dn             IN VARCHAR2,
attrname       IN VARCHAR2,
attrval        IN BLOB,
rc             OUT INTEGER,
errormsg       OUT VARCHAR2 );
PROCEDURE post_compare (ldapplugincontext IN  ODS.plugincontext,
result         IN  INTEGER,
dn             IN  VARCHAR2,
attrname       IN  VARCHAR2,
attrval        IN  VARCHAR2,
rc             OUT INTEGER,
errormsg       OUT VARCHAR2
);

PROCEDURE post_compare (ldapplugincontext IN ODS.plugincontext,
result         IN INTEGER,
dn             IN VARCHAR2,
attrname       IN VARCHAR2,
attrval        IN BLOB,
rc             OUT INTEGER,
errormsg       OUT VARCHAR2 );
PROCEDURE pre_delete (ldapplugincontext IN  ODS.plugincontext,
dn             IN  VARCHAR2,
rc             OUT INTEGER,
errormsg       OUT VARCHAR2
);
PROCEDURE when_delete (ldapplugincontext IN  ODS.plugincontext,
dn             IN  VARCHAR2,
rc             OUT INTEGER,
errormsg       OUT VARCHAR2
);
PROCEDURE when_delete_replace (ldapplugincontext IN  ODS.plugincontext,
dn             IN  VARCHAR2,
rc             OUT INTEGER,
errormsg       OUT VARCHAR2
);
PROCEDURE post_delete (ldapplugincontext IN  ODS.plugincontext,
result         IN  INTEGER,
dn             IN  VARCHAR2,
rc             OUT INTEGER,
errormsg       OUT VARCHAR2
);
PROCEDURE pre_search (ldapplugincontext IN  ODS.plugincontext,
baseDN         IN  VARCHAR2,
scope          IN  INTEGER,
filterStr      IN  VARCHAR2,
requiredAttr   IN  ODS.strCollection,
rc             OUT INTEGER,
errormsg       OUT VARCHAR2
);
PROCEDURE post_search (ldapplugincontext IN  ODS.plugincontext,
result         IN  INTEGER,
baseDN         IN  VARCHAR2,
scope          IN  INTEGER,
filterStr      IN  VARCHAR2,
requiredAttr   IN  ODS.strCollection,
rc             OUT INTEGER,
errormsg       OUT VARCHAR2
);
PROCEDURE pre_bind (ldapplugincontext IN ODS.plugincontext,
dn             IN  VARCHAR2,
passwd         IN  VARCHAR2,
rc             OUT INTEGER,
errormsg       OUT VARCHAR2
);
PROCEDURE when_bind_replace (ldapplugincontext IN ODS.plugincontext,
result         OUT INTEGER,
dn             IN  VARCHAR2,
passwd         IN  VARCHAR2,
rc             OUT INTEGER,
errormsg       OUT VARCHAR2
);
PROCEDURE post_bind (ldapplugincontext IN ODS.plugincontext,
result         IN  INTEGER,
dn             IN  VARCHAR2,
passwd         IN  VARCHAR2,
rc             OUT INTEGER,
errormsg       OUT VARCHAR2
);