LDAP APIプログラミング
目次
Return to Directory Page
はじめに
このドキュメントは主な内容は下記の通り。
-
ディレクトリサービスを利用する代表的なシーケンスを作成するプログラミング手順を調査する
-
ディレクトリサービス用APを構築する上での注意点を記載する
-
Netscape SDKの調査&理解
-
代表的なシーケンスの洗い出し
-
ミシガン大学のSDKを利用して、サンプルコーディング実施
-
プログラミングガイド作成
-
代表的なAPI一覧+詳細作成
-
LDAPv3の調査
対象者
尚、より正確な情報を知りたい方は、「LDAPインターネットディレクトリアプリケーションプログラミング」の書籍やRFC1823等を参考にして頂きたい。
LDAPオペレーション概要
LDAPオペレーションとは、LDAPを使ってディレクトリに対して行う操作の総称のことである。NetscapeのSDK等でも、よく書かれている言い回しなので、割に一般的な用語と言える。内容は下記の通り。
-
問合せ:検索、比較
-
更新:追加、削除、修正、RDN修正
-
認証:バインド、アンバインド、破棄
様々なLDAP APIが世の中に出ているが、その中で一般的なLDAPv2のLDAPオペレーションの処理フローは下図の通り。
図.LDAPオペレーション概要
上図からわかるように、初期化、認証、切断(接続終了)というステップは、基本的に同じであり、異なるのは、LDAPオペレーションと記述のある箱の中身だけである。この中身には、上記にあるように、LDAPオペレーション(検索、比較....)が入る形になる。
注意としては、下記の点が挙げられる。
LDAPアプリケーションプログラミング時
-
同期/非同期オペレーションのどちらを利用するのかをこの時点までに決めておく。
-
SSL上でLDAPオペレーションを実行するのかどうかを決めておく。
LDAPサーバへの接続時
-
ミシガン大学実装のLDAPサーバ(slapd 3.3.1)の場合、初期化の後に、ldap_open関数を呼び出して接続を確立する必要がある。
ldap_open関数を必要としないSDKでは、最初のLDAPオペレーションが実行されるまで、コネクションのオープンを延期しているため、ldap_open関数の呼び出しは不要である。
ミシガン大学のSDKの以前のバージョンには、ldap_init関数が存在しなかったようで、ldap_open関数でセッションを確立した後は、セッションの設定を変更することができなかったらしい。最近のバージョンで、ldap_init関数が追加されたらしい。
-
LDAP APIでメモリアロケートする関数が存在するため、必ずメモリを解放する。
ちなみに、X.509認証を行う場合は、ldap_bind関数の認証方式にあたる引数に、強い認証方式を指定する(XX_STORONG_XX
というようなマクロを指定する。)。
同期/非同期の違い
LDAP APIでは、同期関数と非同期関数というものを代表的な各々の関数に用意している。例えば、検索オペレーションに必要なldap_search関数には、同期用のldap_search_s関数と非同期用のldap_search関数とを用意している。ここでは、同期用関数と非同期用関数の違いについて簡単に説明する。
同期用関数
LDAPオペレーションでは、サーバが要求を完遂し、アプリケーションにすべてのエントリと最終結果のメッセージを返すまで、アプリケーションは処理を待たなければならない。即ち、この関数を呼び出すステップになったら、この関数が何らかの戻り値を返すまでは、次のステップに移ることができないということである。ただし、この関数を利用するとプログラムのステップが少なくなり、コーディングが簡単になる。
非同期用関数
非同期関数を使ったアプリケーションが要求した処理をディレクトリサーバが処理している間、そのアプリケーションは他の作業を行うことができる。LDAPのプロトコルに渡される各々のメッセージには、特定のセッションに対するユニークな番号である「メッセージID」を付与されている。LDAPのこの機能は、サーバに対して複数のコネクションを開かずに、同時にいくつものオペレーションを始めようとするような、複雑なアプリケーションをサポートするためのものである。非同期オペレーションが開始されると、ldap_result関数でオペレーションの状態を監視し、LDAPサーバが返す結果を取り出し、評価しなければならない。
表.同期/非同期関数の比較
|
同期用関数 |
非同期用関数 |
関数の処理待ち時 |
当該関数の処理が終了するまで待つ |
当該関数の結果をldap_result関数で監視する。その間、他の処理を行うことも可能。 |
プログラムステップ |
少ない |
多い |
検索の一般的なステップ
下図に同期/非同期の検索ステップを記述する。尚、ここでは初期化、認証、切断等の一連のステップは排除し、LDAPオペレーションの一つとしての記述をしている。簡単に言えば、下記のステップだけを実装しても、LDAPアプリケーションは動作しない。
図.同期オペレーションの場合の検索処理
上図に示した通り、同期用の検索関数を使用すると、下図にある非同期用の検索関数を使用した検索処理より少なく、単純なステップで処理フローが書かれているのがわかる。ディレクトリの概念的な構造の中で、大きな単位で抽象化されたデータの集まりをまず取得して、後に細かい単位のデータを取得して行くステップになっている。下記に図の補足説明を記す。
図.非同期オペレーションの場合の検索処理
開始点(ベースDN)
検索を開始するエントリのDNを指定する。例えば、「o=himacs,c=JP」エントリ以下を検索対象としたい場合、ベースDNは、「o=himacs,c=jp」になる。
検索スコープ
検索する範囲を指定する。検索スコープに利用可能なパラメータは下記の値の中の一つである。
表.検索スコープの一覧
スコープに利用できる値 |
意味内容 |
LDAP_SCOPE_SUBTREE |
ベースエントリとベースエントリ以下のすべてのエントリを検索範囲とする。 |
LDAP_SCOPE_ONELEVEL |
ベースエントリの一つ下のレベルにあるすべてのエントリを検索範囲とする。ベースエントリは検索範囲の対象としない。 |
LDAP_SCOPE_BASE |
ベースエントリだけを検索範囲とする。 |
検索フィルタ
UNIXでいう正規表現に近い表記法で、検索条件を設定する。SQLでのWhere句にあたる部分と考えると分かり易いかもしれない。
検索フィルタの基本的な構文は下記の通り。
(属性 オペレータ 値)
下記に検索フィルタの簡単な例を示す。
(cn=Barbara Jensen)
この例では、cnは属性であり、=はオペレータであり、Barbara Jensenは、値である。フィルタは、common
name にBarbara Jensenを持ったエントリを検索する。
検索フィルタで使用可能な属性のリストは、使用しているディレクトリサーバのslapd.at.confファイル(Netscape、ミシガン大学のサーバではこの名前が使われている)を参照。
表.検索フィルタのための基本オペレータ
オペレータ
|
詳細
|
例
|
= |
値と等しい属性を持つエントリを返す |
(cn=Barbara Jensen)
cn=Barbara Jensenエントリを見つける。 |
>= |
値以上の属性を持つエントリを返す |
(sn >=jensen)
sn=jensenからsn=z....のエントリ全てを見つける。 |
<= |
値以下の属性を持つエントリを返す |
(sn <=jensen)
sn=a....からsn=jensenのエントリすべてを見つける。 |
=* |
その属性に値が設定されているエントリを返す |
(sn =*)
sn属性を持っているすべてのエントリを見つける。 |
~= |
記入した値と大体一致している属性値を持つエントリを返す。典型的なものは、音が似ている言葉を一致しているというアルゴリズムである。 |
(sn ~=jensen)
sn=jansenエントリを見つける。 |
注意:
文字を含んでいる値を比較するとき、zよりaの方が小さい。
(booleanオペレータ(filter1)(filter2)(filter3))
表.検索フィルタのためのBooleanオペレータ
Booleanオペレータ
|
詳細
|
& |
フィルタに記述した基準のすべてにマッチしたエントリを返す。 |
| |
フィルタの基準の一つ以上にマッチしたエントリを返す。 |
! |
フィルタが真でないエントリを返す。このオペレータを一つのフィルタに適用することのみが可能である。
例えば、下記の様には使える。
(!(filter))
しかし、下記では使えない。
(!(filter1)(filter2)) |
例えば、last nameがJensenかJohnsonかであるエントリすべてを探すには、このフィルタを使うことができる。
(|(sn=Jensen)(sn=Johnson))
エントリを検索するために、検索する値の先頭、中間、末尾にワイルドカードを含めることもまた可能である。例えば、名前の先頭がFで始まるエントリすべてを検索するには、このエントリを使用することができる。
(givenName=F*)
詳細はRFC1960を参照のこと。
取得したい属性
検索範囲、条件で絞り込まれたエントリの中で必要な属性が何かを指定する。
返される書式の設定
検索によって属性の内容を返して欲しくない場合がある。ネットワーク、特にインタネット等の公共性の強いインフラ上で、本来の処理に必要のないデータを多大に流すことは好ましくない。また、性能面から見ても、不利になることが容易に理解できる。その際に、属性を返さないようにする設定を検索関数に施すことが可能である。
エントリのソート
検索関数を実行した後、ldap_sort_entries関数を使用して、ソートを行う。ただし、LDAPv2では、一つの属性値でしかソートできない。また、DNによってソートを行う場合は、注意が必要。
属性のソート
属性に対するソートは、ldap_sort_values関数を使用して行うことができる。この場合は、比較用の関数として、ldap_sort_strcasecmp関数が渡される。標準のstrcmp、strcasecmp関数では、関数の呼び出し方法が、ldap_sort_values関数からみると正しい呼び方で呼ばれないため、このような関数が存在するそうである。
追加の概要
追加したいエントリのDNとそのエントリに含まれる属性をldap_add関数に渡して実行すればよい。エントリの属性は、属性が文字列の場合は、LDAPMod構造体の各メンバに値を設定する。JPEGデータ等のイメージデータの場合は、LDAPMod構造体に値を設定し、さらに、berval構造体にも必要な値を設定する。
修正の概要
修正する処理は、追加する処理に良く似ている。修正する場合は、修正するエントリのDNとそのエントリに含まれている属性をldap_modify関数に渡して実行すれば良い。エントリの属性は、追加処理と同様に、属性が文字列の場合は、LDAPMod構造体の各メンバに値を設定する。JPEGデータ等のイメージデータの場合は、LDAPMod構造体に値を設定し、さらに、berval構造体にも必要な値を設定する。
削除の概要
削除したいエントリのDNをldap_delete関数に指定すれば、エントリの削除は、いとも簡単に終わってしまう。ただし、ディレクトリの途中のノードを削除することはできないことに注意が必要である。削除可能なエントリは、終端(リーフ)のエントリのみである。ディレクトリ途中のエントリから下のエントリすべてを削除したい場合は、終端からコツコツと一つずつエントリを削除して行くしか方法はない。
RDN修正の概要
RDNを何らかの理由で変更したい場合、ldap_modrdn2関数でRDNの変更を行うことが可能である。ただし、ディレクトリの途中にあるノードの変更は、単純にこの関数を呼んでも、うまくいかない。操作可能なのは、終端(リーフ)のエントリだけが操作可能である。ディレクトリの途中のノードを変更するには、工夫が必要である。
比較の概要
検索オペレーションとこの比較オペレーションは良く似ている。がしかし、根本的な違いが存在する。
検索(比較)要求された属性が存在しない場合、検索オペレーションは、単にそのエントリを返さない。しかし、比較オペレーションは、LDAP_NO_SUCH_ATTRIBUTEというエラーが返される。要は、検索オペレーションは下記の違いを認識することができないが、比較オペレーションはそれを認識することが可能ということである。
-
エントリは属性を持っているが、マッチする値は持っていない
-
エントリは、その属性自体をまったく持っていない
さらに、比較オペレーションは、プロトコルの面からみても、検索オペレーションより軽い。
-
比較オペレーションは、TRUE/FALSE値及びエラー識別子を含む一つのパケットになる。
-
検索オペレーションは、検索の結果が二つのパケットになり、ひとつはエントリを含み(TRUEと同等のもの)、もう一つは検索結果を含んだものになる。
これらの違いを意識しさえすれば、比較オペレーションは検索オペレーションを使ってエミュレート可能と言える。具体的には、ldap_compare関数を使えば良い。
エラー処理
エラー処理に使用すると思われる関数を下記に記す。
表.エラー用関数
関数名 |
説明 |
ldap_perror() |
最も最近発生したLDAPエラーに対応するメッセージを標準エラー出力する。 |
ldap_err2string() |
LDAPエラーコードに対応するエラーメッセージの文字列を取り出す。 |
ldap_result2error() |
LDAPオペレーションから返されたエラーコードを取り出す。 |
ldap_get_lderrno() |
最も最近発生したエラーに関する情報を取り出す(Netscape SDKのみ)。 |
非同期関数を使用したときに、ldap_result関数で、LDAPサーバからの処理結果を監視しているが、これにはエラーコードは含まれておらず、これを取得するには、ldap_result2error関数を呼ぶ。
表.LDAPエラーコード一覧
定義名 |
実際の数値 |
メッセージ |
LDAP_SUCCESS |
0x00 |
処理が成功 |
LDAP_OPERATIONS_ERROR |
0x01 |
オペレーションエラー |
LDAP_PROTOCOL_ERROR |
0x02 |
プロトコルエラー |
LDAP_TIMELIMIT_EXCEEDED |
0x03 |
時間制限超過 |
LDAP_SIZELIMIT_EXCEEDED |
0x04 |
サイズ制限超過 |
LDAP_COMPARE_FALSE |
0x05 |
比較結果が偽 |
LDAP_COMPARE_TRUE |
0x06 |
比較結果が真 |
LDAP_STRONG_AUTH_NOT_SUPPORTED |
0x07 |
強力な認証がサポートされてない |
LDAP_STRONG_AUTH_REQUIRED |
0x08 |
強力な認証が必要 |
LDAP_PARTIAL_RESULTS |
0x09 |
結果の一部と委託が受け取られた |
LDAP_NO_SUCH_ATTRIBUTE |
0x10 |
属性が存在しない |
LDAP_UNDEFINED_TYPE |
0x11 |
未定義属性タイプ |
LDAP_INAPPROPRIATE_MATCHING |
0x12 |
不適切な合致 |
LDAP_CONSTRAINT_VIOLATION |
0x13 |
制約が侵害された |
LDAP_TYPE_OR_VALUE_EXISTS |
0x14 |
タイプまたは値が存在する |
LDAP_INVALID_SYNTAX |
0x15 |
無効なシンタックス |
LDAP_NO_SUCH_OBJECT |
0x20 |
オブジェクトが存在しない |
LDAP_ALIAS_PROBLEM |
0x21 |
エイリアスに関する問題 |
LDAP_INVALID_DN_SYNTAX |
0x22 |
無効なDNシンタックス |
LDAP_IS_LEAF |
0x23 |
オブジェクトが終端(リーフ)である |
LDAP_ALIAS_DEREF_PROBLEM |
0x24 |
エイリアスの実名参照時の問題 |
LDAP_INAPPROPRIATE_AUTH |
0x30 |
認証が不適切 |
LDAP_INVALID_CREDENTIALS |
0x31 |
無効な認証証明 |
LDAP_INSUFFICIENT_ACCESS |
0x32 |
アクセス権が不十分 |
LDAP_BUSY |
0x33 |
サーバビジー |
LDAP_UNAVAILABLE |
0x34 |
サーバが利用不可能 |
LDAP_UNWILLING_TO_PERFORM |
0x35 |
サーバが実行を拒否 |
LDAP_LOOP_DETECT |
0x36 |
ループを検出 |
LDAP_NAMING_VIOLATION |
0x40 |
ネーミング侵害 |
LDAP_OBJECT_CLASS_VIOLATION |
0x41 |
オブジェクトクラス侵害 |
LDAP_NOT_ALLOWED_ON_NONLEAF |
0x42 |
終端以外に対するオペレーションは認められない |
LDAP_NOT_ALLOWED_ON_RDN |
0x43 |
RDNに対するオペレーションは認められない |
LDAP_ALREADY_EXISTS |
0x44 |
既に存在する |
LDAP_NO_OBJECT_CLASS_MODS |
0x45 |
オブジェクトクラスを変更不可能 |
LDAP_RESULTS_TOO_LARGE |
0x46 |
結果が大きすぎる |
LDAP_OTHER |
0x50 |
未知のエラー |
LDAP_SERVER_DOWN |
0x51 |
LDAPサーバとコンタクト不可能 |
LDAP_LOCAL_ERROR |
0x52 |
ローカルエラー |
LDAP_ENCODING_ERROR |
0x53 |
符号化時のエラー |
LDAP_DECODING_ERROR |
0x54 |
復号化時のエラー |
LDAP_TIMEOUT |
0x55 |
時間切れ |
LDAP_AUTH_UNKNOWN |
0x56 |
未知の認証方式 |
LDAP_FILTER_ERROR |
0x57 |
検索フィルタが正しくない |
LDAP_USER_CANCELLED |
0x58 |
ユーザがオペレーションを中断した |
LDAP_PARAM_ERROR |
0x59 |
ldapルーチンに誤ったパラメータが渡された |
LDAP_NO_MEMORY |
0x5a |
メモリ不足 |
LDAP_CONNECT_ERROR |
0x5b |
LDAPサーバに接続不可能 |
LDAP URLの表記法
LDAP URLは、ldap://のプロトコル接頭辞で始まり、LDAPサーバへ送る検索要求を付与しているURLである(もしくは、サーバがSSLコネクション上で会話を行う場合は、プロトコル接頭辞はldaps://である)。
LDAP URLのコンポーネント
ldap[s]://<hostname>:<port>/<base_dn>?<attributes>?<scope>?<filter>
(ldap://プロトコルは、セキュアでないコネクション上でLDAPサーバに接続するのに使用している。そして、ldaps://プロトコルは、SSLコネクション上でLDAPサーバに接続するために使用されている)
表.LDAP URLのコンポーネントリスト
コンポーネント
|
詳細
|
<hostname> |
LDAPサーバ(例えば、ldap.netscape.comか192.202.185.90)の名前(もしくはドット表記のIPアドレス)。 |
<port> |
LDAPサーバのポート番号(例えば696)。ポート番号が記述されていなければ、標準LDAPポート(389)が使用される。 |
<base_dn>
|
ディレクトリにあるエントリのDN。このDNは検索開始点のエントリを示す。このコンポーネントが無記入ならば、ルートDNから検索を開始する。 |
<attributes> |
返される属性。一つ以上の属性を記述するには、属性との境に、カンマを使用する(例えば、"cn,mail,telephoneNumber")。URLに属性が記述されていなければ、すべての属性が返される。 |
<scope> |
下記の値の内の一つの検索範囲。
baseは、URLに記入したDN(<base_dn>)についての情報だけを検索する。
oneは、URLに記入したDN(<base_dn>)の下の一つのレベルのエントリについての情報を検索する。ベースエントリは、範囲に含まれていない。
subは、URLに記入したDN(<base_dn>)の下のすべてのレベルのエントリについての情報を検索する。ベースエントリはこの範囲に含まれている。
スコープを何も記入しない場合、サーバはbase検索を実行する。 |
<filter>
|
記入した検索範囲の中のエントリに適用する検索フィルタ。フィルタを記入しない場合、サーバはフィルタ(objectClass=*)を使用する。 |
URLの中にあるいくつかのunsafe characterは、特別な番号の文字として表現される(これはしばしば、escaping
unsafe charactersと呼ばれている)。例えば、スペースは、%20として表現されなければならない。このようにDN"o=Ace
Industry"は、"o=Ace%20Industry"にエンコードされる。
"unsafe characters"上の詳細は、RFC 1738 Uniform Resource Locators(URLs)を参照。
<attributes>と、<scope>と、<filter>は、URLの中でそれらの位置によって識別される。いくつかの属性を記入しない場合、分別しているフィールドにクエスチョンマークを含める必要があることに注意する。
例えば、"(sn=Jensen)"にマッチするすべての属性を返し、サブツリー検索を"o=Ace
Industry,c=US"から開始するというLDAP URLを記述するには、下記のURLを使用する。
ldap://ldap.netscape.com/o=Ace%20Industry,c=US??sub?(sn=Jensen)
二つの連続したクエスチョンマーク--??--が、その間に記述されている属性は何もないことを示している。特定な属性が、URLの中に識別されていなければ、検索ですべての属性が返される。
LDAP URLの例
下記のLDAP URLは、DN "o=Ace Industry, c=US" であるエントリに対してbase検索を行うように記述している。
ldap://ldap.netscape.com/o=Ace%20Industry,c=US
-
ポート番号が記入されていないので、標準LDAPポート番号(389)が使われる。
-
属性が記入されていないので、検索ではすべての属性が返ってくる。
-
検索範囲が記入されていないので、検索は"o=Ace Industry,c=US"エントリをベースに限定される。
-
フィルタが記入されていないの、デフォルトフィルタ"(objectclass=*)"が使用される。
下記のLDAP URLは、Ace Industryエントリの postalAddress属性を検索する。
ldap://ldap.netscape.com/o=Ace%20Industry,c=US?postalAddress
-
検索範囲が記入されていないので、検索は"o=Ace Industry,c=US"エントリをベースに限定される。
-
フィルタが記入されていないの、デフォルトフィルタ"(objectclass=*)"が使用される。
下記のLDAP URLは、Barbara Jensenエントリのcn、mail、telephoneNumber属性を検索する。
ldap://ldap.netscape.com/cn=Barbara%20Jensen,o=Ace%20Industry,c=US?cn,mail,telephoneNumber
-
検索範囲が記入されていないので、検索は"cn=Barbara Jensen,o=Ace Industry,c=US"エントリをベースに限定される。
-
フィルタが記入されていないの、デフォルトフィルタ"(objectclass=*)"が使用される。
下記のLDAP URLは、ラストネーム Jensenを持っているエントリの検索と"o=Ace
Industry,c=US"の以下の検索範囲を記述している。
ldap://ldap.netscape.com/o=Ace%20Industry,c=US??sub?(sn=Jensen)
-
属性が記入されていないので、検索ではすべての属性が返ってくる。
-
検索範囲はsubであるので、検索は"o=Ace Industry,c=US"エントリをベースにするのと、ベースエントリ下のすべてのレベルのエントリとを取り囲む。
下記のLDAP URLは、"o=Ace Industry,c=US"の下の一つのレベルのすべてのエントリのobject
classの検索を記述している。
ldap://ldap.netscape.com/o=Ace%20Industry,c=US?objectClass?one
-
検索範囲がoneなので、検索は"o=Ace Industry,c=US"エントリをベースにするのと、ベースエントリ下のすべてのレベルのエントリとを取り囲む。検索範囲は、ベースエントリを含んでいない。
-
フィルタが記入されていないの、デフォルトフィルタ"(objectclass=*)"が使用される。
重要
LDAP URLの構文は、証明書やパスワードのための処理を含んでいない。検索要求は、認証
されていないLDAP URLを渡して、開始されている。
トピックス
-
ldap_bind(ldap_bind_s)関数とldap_simple_bind(ldap_simple_bind_s)関数の違いは、認証方式を設定できるか否かである。ldap_bind(ldap_bind_s)関数は認証方式を設定することが可能であり、ldap_simple_bind(ldap_simple_bind_s)関数は認証方式が、LDAP_AUTH_SIMPLE(パスワードによる簡易認証)であるldap_bind(ldap_bind_s)関数のことである。
-
ldap_open関数とldap_init関数は異なる。
ldap_init関数は、LDAPセッションハンドルを割り当て、それに対するポインタを返す。実際にサーバへのネットワークコネクションのオープンはしない。ldap_open関数は、LDAPセッションハンドルを割り当て、それに対するポインタを返す。さらに、サーバへのネットワークコネクションのオープンも行う。
ディレクトリサーバへのコネクションを確立する前には、ldap_open関数を使ってLDAPセッションの設定変更をすることはできない。一方、ldap_init関数を使用すると、これが可能になる。これは、最初のLDAPオペレーションが実行されるまで、この呼び出しがコネクションのオープンを延期しているためである(委託やSSLに必要)。
-
Netscape社のsampleには、ber_free関数が使用されているが、Netscape社のAPIリファレンスには載っていない。多分、ldap_ber_free関数の間違いと思われる。
-
Netscape、ミシガン大学のサーバでは、bind呼び出しを行なわなくても接続できるが、LDAPv2では、匿名アクセスの場合でも常にbindのステップが必要である。ちなみに、ミシガン大学のサーバはbindがなくても処理は可能である。
-
エイリアスの機能が必要なければ、プリファレンスのderefにはLDAP_DEREF_NEVERを設定しておいたほうがよい。理由としては、検索オペレーション中にエイリアスの実名参照することが非常にコストの高いものになるためである。
-
プリファレンスのtimelimit(LDAP_OPT_TIMELIMIT)を設定するとサーバ側の検索に費やす時間を設定することができる。ただし、この場合にネットワーク障害が発生すると、サーバの時間制限を待つため、設定した時間以上に待たされることがある。これを避けるために、クライアント自身で、制限時間を設定しその時間だけ検索に費やす時間を設定するにはldap_search_st関数を使用する。
-
ldap_first_attribute、ldap_next_attribute関数を使用して属性のタイプ、一つ一つを見て行く以外に、「属性が存在しない」ことと「属性が値を持たない」ことを区別することができない。
-
ldap_get_values関数は、NULLターミネートされたC言語の文字列を想定しているため、バイナリデータの属性値取得には使用できない。その場合は、ldap_get_values_len関数を使用する。
-
ldap_count_entries関数は、基本的に検索結果中のエントリ数を返すか、エラー発生時には-1を返すが、0を返した場合は、エントリが存在しないというわけではない。エントリがアクセス制御されて保護されていたり、検索完了前に、検索制限を越えてしまった結果が検索から返されたということも有り得る。
-
エントリ数が必要な場合、ldap_count_entries関数を呼び出すが、検索結果である属性値は必要ない。だが、検索のデフォルトの設定であると、属性値を返し、ネットワークのトラフィックを増やしてしまう。これをさけるために、attrsonly引数に0以外の値を代入し、返されるエントリに含まれていないと思われるタイプをattr引数に設定するとよい。
-
ldap_search関数とldap_search_s関数の違いは、同期/非同期関数というちがいになるが、その内容は、下記の通りである。
ldap_search関数:戻り値は、メッセージIDである。それはLDAPセッションで未処理となっている他のメッセージIDとはユニークである。
ldap_search関数の検索の状態を知るには、このメッセージIDをldap_result関数に渡して、取得する。
ldap_search関数は、要求を開始できないとき、ネットワークダウン時、メモリを割り当てられないときに-1を返す。
ldap_search_s関数:戻り値は、検索の正否を返す。
-
Netscape SDKでは、LDAPMessage構造体は非公開なものである。
-
ミシガン大学 SDKでは、対象エントリの下にエントリを持っているエントリは、削除オペレーションを実行しても削除されなかった。サブディレクトリを持たないエントリ、つまり階層化された葉の部分から削除を行う必要が有ると思われる。
-
検索条件に指定した値をDNの構成要素には保持しているが、属性には保持していないエントリはldap_search関数の検索条件に指定されても検索されない。属性にdnを指定すると検索できる可能性があるが未調査。
-
LDAPオペレーションの同期/非同期の違いは、同期の場合は、オペレーション後の後処理は不要、非同期の場合は、ldap_result関数を使用して、ループで状態監視を行い終了する。
-
ldap_memfree関数は、Netscape SDKには存在するが、ミシガン大学 SDKには存在しない。
-
ldap_set_option及びldap_get_option関数は、Netscape SDKには存在するが、ミシガン大学
SDKには存在しない。ミシガン大学 SDKで同様の設定を行うには、LDAPセッションハンドルで示される構造体のメンバを直接操作する。Netscape
SDKではLDAPセッションハンドルは非公開のデータ型のため当該関数を必ず使用してプリファレンスの設定、読出を行う。
Return to Top