ヘッダーをスキップ
Oracle Fusion Middleware Oracle Internet Directory管理者ガイド
11gリリース1(11.1.1)
B55919-01
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

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

この付録では、PL/SQLにおけるプラグイン・フレームワークの使用方法を説明します。

この付録の項目は次のとおりです。

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

この項の項目は次のとおりです。

F.1.1 PL/SQLプラグインの注意事項

PL/SQLプラグインには、次の注意事項があります。

F.1.1.1 PL/SQLプラグイン操作のタイプ

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

F.1.1.2 PL/SQLプラグインの名前付け

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

F.1.2 PL/SQLプラグインの作成

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

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

F.1.2.1 プラグイン・モジュール・インタフェースのパッケージ仕様

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

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

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

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

X


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


X

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


X


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

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

起動コンテキスト プロシージャ名 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



関連項目:


F.1.3 PL/SQLプラグインのコンパイル

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

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

  2. 意味検査: 型がチェックされ、解析ツリーでさらに処理されます。

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

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

すべてのプラグイン・モジュールは、ODSデータベース・スキーマでコンパイルする必要があります。

F.1.3.1 依存性

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

F.1.3.2 プラグインの再コンパイル

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

ALTER PACKAGE my_plugin COMPILE PACKAGE;

F.1.4 PL/SQLプラグインの管理

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

F.1.4.1 プラグインの変更

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

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

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

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

F.1.4.2 プラグインのデバッグ

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

F.1.5 PL/SQLプラグインの有効化と無効化

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

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

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

F.1.6.1 エラー処理

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

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

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

エラー・コード 説明
0

成功

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

障害

-1

警告


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

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

ldap addition info: customized error

F.1.6.2 Oracle Internet Directoryとプラグインとの間のプログラム制御処理

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

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

プラグイン例外の発生場所 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操作をロールバックします。


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

表F-5 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

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


F.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リクエストがプラグイン・モジュールからのリクエストであることを認識します。このタイプのプラグイン・バインドの場合、ディレクトリは後続のプラグインをトリガーしません。ディレクトリは、プラグイン・バインドをスーパーユーザーのバインドとして処理します。このプラグイン・バインドは慎重に使用してください。

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

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

F.1.9 PL/SQLプラグインのセキュリティ

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

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

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

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

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

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

F.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
    

F.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;

F.1.12 データベースの制限事項

Oracle Internet Directoryでは、複数の異なるリリースのOracle Databaseを使用してディレクトリ・データを格納できます。これらのデータベースには、Oracle Databaseリリース2(9.2.0.6)以上、およびOracle Database 10g(10.1.0.4)以上が含まれます。

次のプラグイン機能は、Oracle Databaseリリース2を対象に実行されているディレクトリ・サーバーではサポートされません。

  • Windowsドメインの外部認証プラグイン

  • LDAP_PLUGINパッケージのsimple_bind_s()ファンクション(ディレクトリ・サーバーへの接続用のOracle Internet Directory PL/SQL PLUGIN APIとしてプラグイン定義で指定されているファンクション)

F.2 PL/SQLプラグインの例

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

F.2.1 例1: 検索問合せの記録

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

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

すべてのldapsearchコマンドを記録するには、次の手順を実行します。

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

    • タイムスタンプ

    • ベースDN

    • 検索範囲

    • 検索フィルタ

    • 必須属性

    • 検索結果

    表を作成するには、次の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;
    
  1. プラグイン・パッケージ仕様を作成します。

    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;
    /
    
  1. プラグイン・パッケージ本体を作成します。

    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;
    /
    
  1. プラグイン・エントリを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
    

F.2.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メソッドを使用して変更できません。

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

pwdchangedtimepwdfailuretimeauthpasswordpwdaccountlockedtimeは、デプロイメント環境で最もよく使用される属性です。最初に同期化の対象から除外する必要があります。


  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
    

F.3 PL/SQLプラグイン・フレームワークでのバイナリ・サポート

リリース10.1.2から、プラグインLDAP APIのオブジェクト定義によって、ldapmodifyldapaddおよびldapcompareのプラグインがディレクトリ・データベースのバイナリ属性にアクセスできるようになりました。これまではVARCHAR2型の属性にしかアクセスできませんでした。このオブジェクト定義では、リリース10.1.2より前のプラグイン・コードは無効化しないため、このコードの変更は不要です。新しい定義は、「データベース・オブジェクト・タイプの定義」に記載されています。

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

3つの例では、LOBのかわりにRAWファンクションおよび変数を使用していることに注意してください。

F.3.1 ldapmodifyでのバイナリ操作

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

このプラグインは、modobjoperationフィールドを調べて、バイナリ操作が実行されているかどうかを判断します。値DBMS_LDAP.MOD_ADDDBMS_LDAP.MOD_DELETEDBMS_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;

F.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;

F.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;

F.4 データベース・オブジェクト・タイプの定義

この項では、プラグイン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;

F.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
);