ldapsearchで複合条件検索する方法(AND/OR/NOTの書き方)

Linux

概要

LDAPの調査で ldapsearch を使う場面は多いですが、
毎回ハマるのが 検索フィルタの書き方 です。

特に次のあたりは、都度調べ直すことが多いポイントです。

  • AND / OR の書き方
  • 部分一致(ワイルドカード)
  • 括弧のネスト

本記事では、OpenLDAP環境を前提に検索条件の書き方をそのまま使える形で整理します。
ちなみに、他のLDAPでも似た感じで対応できます。


基本コマンド(最小構成)

ldapsearch -x -H ldap://ldap.example.com \  
  -D "cn=admin,dc=example,dc=com" -W xxxx \  
  -b "dc=example,dc=com" \  
  "(uid=user1)"

最低限押さえるポイントだけです。

  • -x:シンプル認証
  • -H:接続先(ldap / ldaps)
  • -D:バインドDN
  • -W:パスワード入力
  • -b:検索ベース
  • 最後の "(...)" が検索条件(フィルタ)

ldap / ldaps の使い分け

LDAP(通常接続)

-H ldap://host:389

LDAPS(SSL接続)

-H ldaps://host:636

※検証環境などで証明書エラーになる場合は、以下で回避できます。

export LDAPTLS_REQCERT=never

(SSLを無視する設定なので、本番では安易に使わない方が安全です)


フィルタ構文の基本

LDAPの検索条件は、SQLのような書き方ではなく
prefix記法(前置記法)になります。

AND(すべて一致)

(&(objectClass=person)(uid=user1))

OR(どれか一致)

(|(uid=user1)(uid=user2))

NOT(否定)

(!(uid=user1))

※LDAPのNOT条件は 「属性が存在しないエントリ」も含まれる ため、必要に応じて (uid=*) のような存在チェックを組み合わせる必要があります。


よくあるミス

SQLっぽく書いてしまう

(uid=user1 AND objectClass=person)

これはLDAPでは使えません。

括弧が足りない

&(uid=user1)(objectClass=person)

外側の括弧が必要です。

ORの範囲が分かれている

(|(uid=user1))(uid=user2)

ORは1つのまとまりとして書く必要があります。


実務で使うパターン

ユーザー検索(基本)

(&(objectClass=person)(uid=user1))

複数ユーザー検索

(|(uid=user1)(uid=user2))

部分一致

(uid=user*)

メールアドレス検索

(mail=user@example.com)

AND + OR の組み合わせ

(&(objectClass=person)(|(uid=user1)(uid=user2)))

複数条件 + 除外の組み合わせ

personオブジェクトの中でuid=uid*で、ステータスがdisabledのものを除く場合

(&(objectClass=person)
  (|(uid=user*)(uid=id*))
  (!(accountStatus=disabled))
)

実行例(LDAPS)

ldapsearch -x -H ldaps://ldap.example.com \  
  -D "cn=admin,dc=example,dc=com" -W \  
  -b "dc=example,dc=com" \  
  "(&(objectClass=person)(|(uid=user1)(uid=user2)))"

まとめ

LDAPのフィルタは一見分かりにくいですが、実務で使うパターンは限られています。

  • 外側は &(すべての条件)
  • 候補は |(ORでまとめる)
  • 除外は !(NOT)
  • 条件はすべて括弧でネストする

特に重要なのは次の形です。

(&  
  (|(条件A)(条件B))  
  (!(除外条件))  
)

この「候補を出して、除外する」形を覚えておけば、
複雑な検索でもほぼ対応できます。

また、NOT条件は「属性が存在しないエントリ」も含まれるため、
必要に応じて (uid=*) のような存在チェックを組み合わせることも重要です。

迷ったら「ANDで囲って、ORで候補、NOTで除外」に分解して考えるのがコツです。