ヘッダーをスキップ
Oracle® Fusion Middleware Oracle Directory Server Enterprise Edition開発者ガイド
11g リリース1 (11.1.1.7.0)
B72440-01
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

8 エントリ・ストア・プラグインおよびエントリ・フェッチ・プラグインの作成

この章では、Directory Serverがディレクトリ・データベースに対してエントリを書き込むときとエントリを読み取るときの動作を変更するプラグインの作成方法について説明します。


注意:

エントリ・ストア・プラグインとエントリ・フェッチ・プラグインを作成するかわりに、属性の暗号化を使用できます。『Oracle Directory Server Enterprise Edition管理者ガイド』「属性値の暗号化」を参照してください。


この章の内容は、次のとおりです。

8.1 エントリ・ストア・プラグインおよびエントリ・フェッチ・プラグインのコール

この項では、エントリ・ストア・プラグインとエントリ・フェッチ・プラグインがコールされる場合について説明します。また、エントリがプラグインによってどのように処理されると予想されているのかも説明します。

サーバーは、データをディレクトリ・データベースに書き込む前に、エントリ・ストア・プラグイン関数をコールします。ディレクトリ・データベースからデータを読み取った後に、エントリ・フェッチ・プラグイン関数をコールします。そのため、エントリ・ストア・プラグインとエントリ・フェッチ・プラグインは、一般的に、ディレクトリ・エントリの暗号化および復号化、または監査作業の実行に使用されることがあります。

8.1.1 LDIF文字列パラメータの使用

他のタイプのプラグインとは異なり、エントリ・ストア・プラグイン関数とエントリ・フェッチ・プラグイン関数は、引数としてパラメータ・ブロックを取りません。かわりに、これらの関数は、エントリのLDIF文字列表現と文字列の長さの2つのパラメータを取ります。Directory Serverは、プラグインが正常に戻された後に、変更されたLDIF文字列を使用します。エントリ・ストア・プラグイン関数のプロトタイプ例は、次のとおりです。

int my_entrystore_fn(char ** entry, unsigned int * length);

プラグイン関数は、必要に応じて文字列を操作できます。エントリ・ストア・プラグインとエントリ・フェッチ・プラグインは、成功するとゼロ(0)を戻します。関数が戻されるとき、Directory Serverは、entrylengthにパラメータの変更されたバージョンが含まれることを期待します。

8.1.2 エントリ・ストアとエントリ・フェッチの検索例

この章のプラグイン関数の例は、install-path/examples/testentry.cにあります。

次の例は、この章で使用されるエントリ・ストアのスクランブル関数を示しています。この関数は、データベースにエントリを書き込む前にDirectory Serverによってコールされます。

例8-1 エントリ・フェッチのスクランブラ(testentry.c)

#include "slapi-plugin.h"

#ifdef _WIN32
typedef unsigned int uint;
__declspec(dllexport)
#endif
int
testentry_scramble(unsigned char ** entry, uint * len)
{
    uint i;

    (*len)++;
    *entry = slapi_ch_realloc(*entry, *len);
    /* Scramble using bitwise exclusive-or on each character.     */
    for (i = *len - 1; i> 0; i--) {
         (*entry)[i] = (*entry)[i - 1] ^ 0xaa;
    }
    (*entry)[0] = 0xaa;

    slapi_log_info_ex(
        SLAPI_LOG_INFO_AREA_PLUGIN,
        SLAPI_LOG_INFO_LEVEL_DEFAULT,
        SLAPI_LOG_NO_MSGID,
        SLAPI_LOG_NO_CONNID,
        SLAPI_LOG_NO_OPID,
        "testentry_scramble in test-entry plug-in",
        "Entry data scrambled.\n"
    );

    return 0;
}

次の例は、この章で使用されるエントリ・ストアのスクランブル解除関数を示しています。関数は、データベースからエントリを読み取った後にサーバーによってコールされます。

例8-2 エントリ・フェッチのアンスクランブラ(testentry.c)

#include "slapi-plugin.h"

#ifdef _WIN32
typedef unsigned int uint;
__declspec(dllexport)
#endif
int
testentry_unscramble(unsigned char ** entry, uint * len)
{
    uint i;

    /* Return now if the entry is not scrambled.                  */
    if (**entry != 0xaa) { return 0; }

    /* Unscramble using bitwise exclusive-or on each character.   */
    (*len)--;
    for (i = 0; i < *len; i++) {
        (*entry)[i] = (*entry)[i + 1] ^ 0xaa;
    }

    slapi_log_info_ex(
        SLAPI_LOG_INFO_AREA_PLUGIN,
        SLAPI_LOG_INFO_LEVEL_DEFAULT,
        SLAPI_LOG_NO_MSGID,
        SLAPI_LOG_NO_CONNID,
        SLAPI_LOG_NO_OPID,
        "testentry_unscramble in test-entry plug-in",
        "Entry data unscrambled.\n"
    );

    return 0;
}

2つの関数間の対称性に注意してください。スクランブル・マスク(バイナリの0xaaまたは10101010)によって、変換はわかりやすくなりますがセキュアにはなりません。セキュアな暗号化メカニズムは、かなり複雑になることがあります。

8.2 エントリを暗号化するプラグインの作成

この項では、エントリ・ストアド・エントリ・フェッチ・プラグインを登録する方法について説明します。ディレクトリ・データベースに書き込まれるディレクトリ・エントリにスクランブルをかけるプラグインを作成する方法を示します。また、ディレクトリ・データベースから読み取られるディレクトリ・エントリのスクランブルを解除する方法も説明します。


注意:

この章の例では、セキュアなエントリ・ストレージ・スキームを構成しません


次の例は、エントリ・ストア・プラグインとエントリ・フェッチ・プラグインがDirectory Serverに登録される仕組みを示しています。

8.2.1 エントリ・ストア・プラグインおよびエントリ・フェッチ・プラグインの登録

次の例は、エントリ・ストア・プラグインとエントリ・フェッチ・プラグインがDirectory Serverに登録される仕組みを示しています。

例8-3 エントリ・ストア・プラグインとエントリ・フェッチ・プラグインの登録(testentry.c)

#include "slapi-plugin.h"

Slapi_PluginDesc entrypdesc = {
  "test-entry",                      /* plug-in identifier      */
  "Oracle Corporation (test)",       /* vendor name             */
  "11.1.1.3.0",                      /* plug-in revision number */
  "Sample entry store/fetch plug-in" /* plug-in description     */
};

int
testentry_init(Slapi_PBlock *pb)
{
  int rc = 0;                        /* 0 means success         */
  rc |= slapi_pblock_set(            /* Plug-in API version     */
      pb,
      SLAPI_PLUGIN_VERSION,
      SLAPI_PLUGIN_CURRENT_VERSION
  );
  rc |= slapi_pblock_set(            /* Plug-in description     */
      pb,
      SLAPI_PLUGIN_DESCRIPTION,
      (void *) &entrypdesc    );
  rc |= slapi_pblock_set(            /* Entry store function    */
      pb,
      SLAPI_PLUGIN_ENTRY_STORE_FUNC,  
      (void *) testentry_scramble
  );
  rc |= slapi_pblock_set(            /* Entry fetch function    */
      pb,
      SLAPI_PLUGIN_ENTRY_FETCH_FUNC,  
      (void *) testentry_unscramble
  );
  return rc;
}

8.2.2 エントリ・ストアとエントリ・フェッチの試行例

データベース内のスクランブルをかけられたデータとスクランブル解除されたデータの違いを示すことによって、プラグインについて説明します。そのため、すぐにはプラグインを有効にしません。かわりに、スクランブルをかける前に新しいディレクトリ・サフィックスにエントリを追加します。その後、ディスク上のデータベースの結果を観察します。次に、エントリを削除して、スクランブル・プラグインを有効にします。その後、同じエントリを再度追加します。最後に、エントリにスクランブルがかけられた後に結果を観察します。

8.2.2.1 サンプル・サフィックスを設定するには

実行済でない場合には、サフィックスdc=example,dc=comを使用して、サンプルのLDIFファイルinstall-path/resources/ldif/Example.ldifからロードされたデータを含むディレクトリ・インスタンスを設定します。

  1. 新規Directory Serverインスタンスを作成します。

    次に例を示します。

    $ dsadm create -h localhost -p 1389 /local/ds
    Choose the Directory Manager password:
    Confirm the Directory Manager password:
    $ 
    
  2. 新規Directory Serverインスタンスを開始します。

    次に例を示します。

    $ dsadm start /local/ds
    Server started: pid=4705
    $ 
    
  3. サフィックスdc=example,dc=comを作成します。

    たとえば、長い行は印刷ページに合わせて折り返します。

    $ dsconf create-suffix -h localhost -p 1389 dc=example,dc=com
    Enter "cn=directory manager" password: 
    Certificate "CN=defaultCert, CN=hostname:1636" presented by the
     server is not trusted.
    Type "Y" to accept, "y" to accept just once,
     "n" to refuse, "d" for more details: Y
    $ 
    
  4. サンプルLDIFをロードします。

    たとえば、長い行は印刷ページに合わせて折り返します。

    $ dsconf import -h localhost -p 1389 \
     install-path/resources/ldif/Example.ldif dc=example,dc=com
    Enter "cn=directory manager" password:  
    New data will override existing data of the suffix
     "dc=example,dc=com".
    Initialization will have to be performed on replicated suffixes. 
    Do you want to continue [y/n] ? y
    
    ## Index buffering enabled with bucket size 16
    ## Beginning import job...
    ## Processing file "install-path/resources/ldif/Example.ldif"
    ## Finished scanning file "install-path/resources/ldif/Example.ldif" (160 entries)
    ## Workers finished; cleaning up...
    ## Workers cleaned up.
    ## Cleaning up producer thread...
    ## Indexing complete.
    ## Starting numsubordinates attribute generation.
     This may take a while, please wait for further activity reports.
    ## Numsubordinates attribute generation complete. Flushing caches...
    ## Closing files...
    ## Import complete. Processed 160 entries in 5 seconds.
     (32.00 entries/sec)
    
    Task completed (slapd exit code: 0).
    $ 
    

関連項目

Directory Service Control Centerを使用して、このタスクを実行できます。

8.2.2.2 スクランブル前のデータベースでの文字列の検索

ここでは、エントリ・ストア・プラグインとフェッチ・プラグインをDirectory Serverに登録する前に、Quentin Cubbinsのエントリをサンプル・サフィックスに追加します。Quentinのメール・アドレスが、メール・アドレスの属性値を保持するデータベースで表示できることを確認します。Quentinのエントリquentin.ldifは、次の例のように表示されます。

例8-4 エントリのLDIF表現

dn: uid=qcubbins,ou=People,dc=example,dc=com
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
uid: qcubbins
givenName: Quentin
sn: Cubbins
cn: Quentin Cubbins
mail: qcubbins@example.com
userPassword: qcubbins
secretary: uid=bjensen,ou=People,dc=example,dc=com

Quentinのエントリをディレクトリに追加します。たとえば、エントリがquentin.ldifにある場合、次の内容を追加します。

$ ldapmodify -a -h localhost -p 1389 -f quentin.ldif \
 -D uid=kvaughan,ou=people,dc=example,dc=com -w bribery

メールの属性値について、ディレクトリ・データベース・ファイルで文字列を検索します。

例8-5 スクランブル前のデータベース・ファイルの属性値

$ cd instance-path/db/example/
$ strings example_mail.db3 | grep example.com
=qcubbins@example.com
=agodiva@example.com
=hfuddnud@example.com
=pblinn@example.com
=scooper@example.com
=bcubbins@example.com
=yyorgens@example.com

ユーザーがデータベース・ファイルにアクセスする場合、Quentinのメール・アドレスが明確に表示されることに注意してください。値がクレジット・カード番号だった場合、セキュリティが問題になります。

8.2.2.3 スクランブル後のデータベースでの文字列の検索

ここでは、エントリ・ストア・プラグインとフェッチ・プラグインをDirectory Serverに登録した後に、Quentin Cubbinsのエントリをサンプル・サフィックスに追加します。Quentinのメール・アドレスが、メール・アドレスの属性値を保持するデータベースで表示されなくなっていることを確認します。

プラグインをロードする前に、Quentinのエントリを削除します。

$ ldapdelete -D uid=kvaughan,ou=people,dc=example,dc=com -w bribery
 uid=qcubbins,ou=People,dc=example,dc=com

次に、testentry.cの最初のコメントに従って、プラグインをロードするようにDirectory Serverを構成し、サーバーを再起動します。

エントリ・ストア/フェッチ・プラグインがアクティブな状態で、Quentinのエントリをディレクトリに追加しなおします。

$ ldapmodify -a -h localhost -p 1389 -f quentin.ldif \
-D uid=kvaughan,ou=people,dc=example,dc=com -w bribery

メールの属性値について、ディレクトリ・データベース・ファイルで文字列を再度検索します。

例8-6 スクランブル後のデータベース・ファイルの属性値

$ cd instance-path/db/example/
$ strings example_mail.db3 | grep example.com
=agodiva@example.com
=hfuddnud@example.com
=pblinn@example.com
=scooper@example.com
=bcubbins@example.com
=yyorgens@example.com

Quentinのメール・アドレス値はディレクトリ・データベースに表示されないことに注意してください。適切なアクセス権を持つディレクトリ・ユーザー(この簡単な例では匿名)は、検索中に属性を表示できます。次の例では、属性とその値が強調されています。

例8-7 スクランブル解除された検索結果

$ ldapsearch -h localhost -p 1389 -b dc=example,dc=com uid=qcubbins
dn: uid=qcubbins,ou=People,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
uid: qcubbins
givenName: Quentin
sn: Cubbins
cn: Quentin Cubbins
mail: qcubbins@example.com
secretary: uid=bcubbins,ou=People,dc=example,dc=com

このように、エントリ・ストア・プラグインとエントリ・フェッチ・プラグインは、ディレクトリ・フロントエンドではなく、エントリが格納される方法にのみ影響することがわかります。