« NX ClientでAnthyが使えない | トップページ | 意外な副作用のその後 »

2007年5月18日 (金)

LDAPでADのグループに所属するメンバを取得する

LDAPでActiveDirectoryを操作することはよくありますが、
数千名からなるグループにユーザを登録/削除するのは初めてでした。

システム開発に携わったことがある人であれば
お分かりでしょうが、データの規模がある程度の
レベルを超えると必ずといっていいほど予想外の
ことが起きてきます。

今回はそんなお話。ちなみに使用する言語はPHPですが、
他言語でも同じことが言えます。

たとえば、exampleグループのメンバを取得しようと思えば

$result = ldap_search($ld, "cn=Users, dc=test, dc=local", "(cn=example)");
$entry = ldap_first_entry($ld, $result);
$attrs = ldap_get_attributes($ld, $entry);

で、$attrs['member']にユーザの一覧が取れます。ちなみに、
$attrs['member']['count']には自動的に件数が入ります。

(可読性向上のために「あえて」エラー処理は省いてますから、そのまま真似しないように)

これが、ある日突然全く取得できなくなってしまいました。
当然、$attrs['member']['count']に入っている値は0です。

よーく取得できた値を見てみると、いつもの['member']ではなく、
['member;Range=0-1499']というキーの中にちょうど1500件だけ
ユーザの一覧が入っています。その脇にはしっかり['member']もいます。

ちょうどこんな感じです。

$attrs = array(
    'member' => array(
        'count' => 0
    ),
    'member;Range=0-1499' => array(
        'count' => 1500,
        ....
        (ユーザの情報が1500件分)
    )
);

最初はサーバの設定を疑いましたが、どうもそうではなさそうです。
じゃあPHPかっ!とも思いましたが、PHPのソースをひっくり返しても
0-1499みたいな操作をしているところは見当たりません。

もしや……、と思ってLDAPのパケットを拾ってみると、
サーバから返ってくるデータ自体が「member;Range=0-1499」
のようになっていることが判明しました。

早速そのへんをググって見ると……、ありました。

Searching Using Range Retrieval(英語):
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ldap/ldap/searching_using_range_retrieval.asp

えーと、要は1回の問い合わせでは1500件を超えるデータは返せないと。
それ以上取得するときは、Rangeを変えながら繰り返し取得せいと。
……ざけんな、コラ。

つまりは、きちんと全件取るにはこんな処理になるということですね。

$range = 0;
$max = 1500;
$member = array('count' => $max);
while ($member['count'] == $max) {
$result = ldap_search($ld, "cn=Users, dc=test, dc=local", "(cn=example)",
        array('member;Range=' . $range . '-*'));
    if (!$result) {
        $member['count'] = 0;
        break;
    }
    $entry = ldap_first_entry($ld, $result);
    $attrs = ldap_get_attributes($ld, $entry);
    $member = array_merge($member, $attrs[$attrs[0]];
    $range += $max;
}

これで、$member に $attrs['member']相当のものが取得できます。

まー、パフォーマンスを考慮してなんでしょうけど、
そういうのは開発する側がきちんと考えればいいことで、
時間がかかっても全部返すようにしとけよ、って感じですかね。

|

« NX ClientでAnthyが使えない | トップページ | 意外な副作用のその後 »

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/161557/15104450

この記事へのトラックバック一覧です: LDAPでADのグループに所属するメンバを取得する:

« NX ClientでAnthyが使えない | トップページ | 意外な副作用のその後 »