2013年7月27日土曜日

2013年7月18日木曜日

階層構造になっているセキュリティグループ内のユーザーを再帰的に検索するLDAPフィルタ

"LDAP_MATCHING_RULE_IN_CHAIN"。非常に有益な機能だと思うが、日本語の情報がほとんど無かったので記事にしておく。
普通のLDAP検索フィルタは、ネストしたセキュリティグループに対応不可

Active Directory環境では、セキュリティグループのメンバーにセキュリティグループを入れるというネスト(入れ子)構造をよく使うと思う。セキュリティグループは会社組織と対応付けされることが多いので、例えば○○部のセキュリティグループの下に●●課のセキュリティグループと▲▲課のセキュリティグループを入れるといった具合だ。
ところが、このような構造において、「○○部に所属するユーザを全員取り出す」といったLDAP検索フィルタを書こうとすると難儀することになる。
Figure.1 ネストしたセキュリティグループ

上図のような構造で、GroupAに属するユーザーを取り出すLDAPフィルタを書く場合、単純に考えると
(&(objectClass=user)(memberOf=CN=GroupA,DC=example,DC=com))
と書けばよさそうだが、これではUser1しかヒットしない。memberOf句はグループのネストに対応していないので、指定したグループ(GroupA)の直下にいるメンバーしか見つけてくれないのだ。
AD独自の演算子で、ネストしたセキュリティグループを再帰的に検索
実はADのLDAPには、この問題を解決してくれる独自の演算子が用意されている。
Search Filter Syntax (Windows)
に紹介されている"LDAP_MATCHING_RULE_IN_CHAIN"がそれだ。
具体的には下記のように記述すればよい。
(&(objectClass=user)(memberOf:1.2.840.113556.1.4.1941:=CN=GroupA,DC=example,DC=com))
このフィルタなら、GroupAの下にあるGroupBのメンバーも再帰的に検索してくれるので、User1、User2の両方がヒットする。  "1.2.840.113556.1.4.1941"がLDAP_MATCHING_RULE_IN_CHAINのOIDなのだそうな。
手っ取り早く試すなら、ldifdeコマンドで
ldifde -f export.ldf -r "(&(objectClass=user)(memberOf:1.2.840.113556.1.4.1941:=CN=GroupA,DC=example,DC=com))"
とか書いてみるとよい。