OpenLDAP
OpenLDAPは、Lightweight Directory Access Protocol (LDAP) のフリーかつオープンソースの実装であり、OpenLDAP Project が開発している。独自のBSD系ライセンスである OpenLDAP Public License でリリースされている。
LDAPはプラットフォームに依存しないプロトコルである。いくつかのLinuxディストリビューションではOpenLDAPでLDAPをサポートしている。他にもBSD系、AIX、HP-UX、macOS、Solaris、Microsoft Windows(NT系の2000、XP、Vista、Windows 7など)、z/OSで動作する。
OpenLDAP Project は1998年、Kurt Zeilenga が創始した。LDAPプロトコルの開発と改良を長期プロジェクトとして行ってきたミシガン大学のLDAPリファレンス実装のクローンを出発点としてプロジェクトが始まった。
2015年5月時点で、OpenLDAP Project の中核チームは Howard Chu(チーフアーキテクト)、Quanah Gibson-Mount、Hallvard Furuseth、Kurt Zeilenga の4人で構成されている。他にも活発に活動している重要なコントリビュータとして、Luke Howard、Ryan Tandy、Gavin Henry らがいる。過去の中核チームメンバーには、Pierangelo Masarati らがいた。
OpenLDAPは次の3つのコンポーネントから成る。
slapd (Standalone LDAP Daemon) - スタンドアロン型のLDAPデーモンと対応するオーバーレイやツール
クライアントソフトウェア(ldapsearch、ldapadd、ldapdelete、その他)
さらに OpenLDAP Project ではいくつかのサブプロジェクトも運営している。
JLDAP - Java用のLDAPクラスライブラリ
JDBC-LDAP - Java JDBC - LDAP ブリッジドライバ
ldapc++ - C++用のLDAPクラスライブラリ
Fortress - Java 用のロールベースのIDアクセス管理
LMDB - メモリマップドデータベースライブラリ
OpenLDAPサーバ (slapd) は歴史的経緯から、ネットワーク処理とプロトコル処理を受け持つフロントエンドと、データストレージを扱うバックエンドに分かれている。この設計は、1996年に書かれたオリジナルのミシガン大学のコードの特徴であり、その後のすべてのOpenLDAPリリースで引き継がれている。
モジュラー構造になっており、バックエンドとしては通常のデータベースだけでなく様々なテクノロジーとのインタフェースを提供する多様なものが存在する。
なお、古いリリース (1.x) では、「バックエンド」と「データベース」はほぼ同義に使われていた。正確には、「バックエンド」はストレージインタフェースのクラスであり、「データベース」はバックエンドのインスタンスの1つである。slapdサーバは同時に複数のバックエンドを使うことができ、同種のバックエンドの複数のインスタンス(例えば多数のデータベース)を同時に扱うこともできる。
OpenLDAPディストリビューションには17種類のバックエンドが含まれており、他にもサードパーティーが独自のバックエンドを開発している。標準バックエンドは大まかに以下の3種類に分類できる。
データストレージ型バックエンド - 実際にデータを格納する。
back-bdb: OpenLDAP用の最初のトランザクション型バックエンド。Berkeley DB をベースにしている。
back-hdb: back-bdb からの派生。完全な階層型データモデルで、サブツリーの改名をサポートしている。
back-ldif: プレーンテキストファイルである LDIF (LDAP Data Interchange Format) をベースにしている。
back-mdb: メモリマップドデータベース(LMDB) 上に構築したトランザクション型バックエンド。
back-ndb: MySQLのNDBクラスタエンジン上に構築したトランザクション型バックエンド。
プロキシ型バックエンド - 他のデータストレージシステムとのゲートウェイとして機能する。
back-ldap: 他のLDAPサーバへの単純なプロキシ
back-meta: メタディレクトリ機能を持つプロキシ
back-passwd: Unix系のパスワードおよびグループデータを使用。
back-relay: 別のslapdバックエンドへ内部的にリダイレクトする。
back-sql: 任意のSQLデータベースとやり取りする。
ダイナミック型バックエンド - 要求された時にデータを生成する。
back-config: LDAP経由でslapdの設定が可能。
back-dnssrv: DNS経由でLDAPサーバの位置を把握する。
back-monitor: LDAP経由でslapdの統計情報にアクセス。
back-null: 何もしない。Unix系の/dev/nullに相当。
back-perl: LDAP要求に対して任意のPerlモジュールを呼び出す。
back-shell: LDAP要求に対して任意のシェルスクリプトを呼び出す。
back-sock: LDAP要求をプロセス間通信経由で任意のデーモンに転送する。
古いバージョンのOpenLDAPには今は使われていないバックエンドもあった。例えば、back-ldbm は元になったミシガン大学のコードを受け継いだバックエンドである。また、back-tcl は back-perl や back-shell と同様にTclスクリプトを呼び出すバックエンドである。
他のバックエンドのサポートも間もなく廃止される予定。 back-ndb は、廃止された。Oracle が MySQL を買収した後、Oracle によって MySQL とのパートナーシップが解消されたためである。 back-bdb と back-hdb は、間も無く廃止される。back-mdb の方がパフォーマンス、信頼性、および管理性の面で優れているためである。
実際、back-perl、back-shell、back-sock といったバックエンドは任意のプログラミング言語へのインタフェースとすることが可能で、拡張やカスタマイズが自由に行える。これを利用して、コンパクトでうまく定義されたAPIを持つRPCエンジンとしてslapdを使うことも可能である。
通常、LDAP要求はフロントエンドが受信し、解読し、バックエンドに処理させる。バックエンドが要求の処理を完了すると、フロントエンドに結果を返し、そこからLDAPクライアントに結果を送信する。オーバーレイはフロントエンドとバックエンドの間に挿入できるコードの断片である。したがって、そこで要求をインターセプトしてバックエンドが処理する前に別の動作を起動したり、バックエンドが返す結果をインターセプトすることもできる。オーバーレイは slapd の内部APIに完全にアクセスできるため、フロントエンドやバックエンドの関数も呼び出すことが可能である。一度に複数のオーバーレイを使うこともでき、フロントエンドとバックエンドの間にモジュールのスタックを形成できる。
オーバーレイは、データベース機能の強化に対応する単純な手段として使うことができ、新たなバックエンドを作成する必要がない。新機能をコンパクトで保守が容易なモジュール形式で追加できる。OpenLDAP 2.2 でオーバーレイが導入されて以来、多数のオーバーレイがコミュニティから集まっている。
OpenLDAPディストリビューションでは21個の中核オーバーレイが提供されている。さらに15個のユーザーコントリビューションのオーバーレイがある。他にも承認待ちのものもある。
accesslog: 別のLDAPデータベースにサーバのログを採取する。
auditlog: テキストファイルにサーバのログを採取する。
chain: クエリをインターセプトし、まとめる。back-ldap の一部。
collect: X.500風のcollective属性の実装
constraint: 特定の属性について、受容可能な値を制限する。
dds: ダイナミック・データ・サービス - その時点で自動的に生成できるエントリ。
deref: 検索結果内で参照されたエントリに関する情報を返す。
dyngroup: 単純なダイナミックグループをサポート。
dynlist: より洗練されたダイナミックグループ。
memberof: memberOf などのバックリスト属性をサポート。
pcache: 検索結果のキャッシュ(性能強化用)
ppolicy: LDAPパスワードポリシー - パスワードの品質、期限切れなど。
refint: 参照完全性
retcode: 各種操作で返す値を事前設定する(クライアントのデバッグ用)
rwm: 書き換えモジュール。LDAPデータを様々に変更。
seqmod: 個々のエントリへの書き込みのシリアライズ。
sssvlv: サーバサイドでのソートと、仮想リストビュー(未リリース)
syncprov: Syncreplプロバイダ。レプリケーションのマスター側実装
translucent: 半透過型パススルー。プロキシ型サーバでのローカルなデータ補強。
unique: ツリー内での属性値の一意性の保証。
valsort: 属性値の様々なソート。
addpartial: 追加要求を受け取り、そのエントリが既に存在していたら更新要求に置き換える。
allop: 要求の仕方を知らないクライアントに対して、指定可能な属性値全てを返す。
autogroup: 統計量グループの動的管理
cloak: 検索で指定以外の属性を隠す。
denyop: 恣意的な設定の要求を拒否する。
dupent: 複数の結果を別々のエントリとして返す。
lastbind: ユーザが最後に成功した認証のタイムスタンプを記録する。
lastmod: ツリー内の最終更新日時を管理。
nops: 冗長な更新を除去。
noopsrch: 検索によって返されるエントリの数をカウントする。
nssov: NSS要求とPAM要求にslapd内で直接応答し、nss-ldap と pam-ldap を不要にする。
proxyOld: Sunなどが使っていた古い ProxyAuthz の符号化をサポート。
smbk5pwd: SambaとKerberosのパスワードを管理。
trace: LDAP要求と応答のログ。
usn: シーケンス番号の更新(マイクロソフト AD 同様)(未リリース)
バックエンドとオーバーレイは、最も一般的に使用される2つのモジュールタイプである。バックエンドは通常 slapd バイナリに組み込まれていたが、動的にロードモジュールとして組み込み可能。オーバーレイは、通常動的モジュールとして組み込まれる。さらに、slapd は、動的モジュールをサポートしている。新しいLDAPの構文、マッチングルール、制御、そして拡張操作を実装だけでなく、カスタムアクセス制御機能やパスワードハッシュ機能を実装できる。
OpenLDAP は、サン・マイクロシステムズや Netscape/Fedora/Red Hat が使っているプラグインアーキテクチャ SLAPI もサポートしている。最新版では、SLAPI フレームワークは slapd のオーバーレイ内で実装されている。Sun/Netscape/Fedora/Red Hat 向けに書かれたプラグインの多くは OpenLDAP 互換だが、OpenLDAP コミュニティでは SLAPI はほとんど使われていない。
slapd ネイティブモジュール
acl/posixgroup –  POSIX アクセス制御をサポート
comp_match – コンポーネントベースのマッチングをサポート
kinit – slapd でのケルベロス認証 TGT のメンテナンス・更新
passwd/ – 追加のパスワードハッシングメカニズム。現在、Kerberos、Netscape、RADIUS、および SHA-2を提供。
SLAPI プラグイン
addrdnvalue – 追加要求においてRDN値が省略されている場合は、エントリにRDN値を追加する。
OpenLDAPのメジャーリリースの履歴を示す。
OpenLDAP Version 1
ミシガン大学の最終リリース(リリース3.3)に対応。
OpenLDAP Version 2.0(2000年8月)
LDAPバージョン3サポート、IPv6サポート、各種機能強化。
OpenLDAP Version 2.1(2002年6月)
Berkeley DB ベースのバックエンドなどいくつかのバックエンドを実装、Simple Authentication and Security Layer (SASL) サポート。
OpenLDAP Version 2.2(2003年12月)
レプリケーション機能サポート (syncrepl)、オーバーレイ・インタフェース、各種データベースやRFC関連の機能強化。
OpenLDAP Version 2.3(2005年6月)
back-config バックエンドなど各種強化。
OpenLDAP Version 2.4(2007年10月)
N-ウェイマルチマスター型レプリケーションサポート。スキーマ要素の動作中の削除・更新などの機能強化。
OpenLDAP は、RFC 4533 に規定されているコンテンツ同期を使用したレプリケーションをサポートしている。この仕様を以後、syncrepl と呼ぶ。基本仕様に加えて、delta-syncrepl として知られる拡張もサポートされている。複数プライマリ型(マルチマスター)レプリケーションをサポートするために追加の拡張機能が実装された。
基本的な同期操作は RFC 4533 に記述されている。このプロトコルは、変更ための無停止データベースが必要ないように定義されている。
変更内容は、各エントリに格納される変更シーケンス番号(CSN)情報により区別され、最新の削除を追跡するのに有用な任意のセッションログにより最適化されている。
レプリケーションクライアント(コンシューマ)がレプリケーションサーバー(プロバイダ)に「コンテンツ同期検索」を送信する操作モデルとなっている。
(特に以前にプロバイダと同期していた場合)コンシューマは、この検索でクッキーを提供することができる。 RFC 4533 の OpenLDAP 実装では、このクッキーには、プロバイダから受信した最新のCSN(contextCSNと呼ばれる)が含まれている。
次に、クッキーによる既知の内容に基づいてコンシューマを同期状態にするために、プロバイダは、未変更の全エントリ、および、追加・変更・削除された全エントリを検索または、同期情報の結果として返す。なお、未変更のエントリはリフレッシュステージの現在のフェーズでのみ使用される。更新フェーズではすべての現在の属性を追加する。
クッキーが存在しないか、コンシューマが完全に同期していないことを示している場合、プロバイダはリフレッシュ段階で、それが持つ各エントリの追加を送信する。
理想的な場合、応答時のリフレッシュステージには、コンシューマがプロバイダと最後に同期した時刻以降に発生したわずかな変更・削除が対象となる。
しかし、プロバイダに保持されているセッションログの状態が限られているため、現在の全エントリが必要になることがある。コンシューマがプロバイダと最後に同期した後、プロバイダが削除したものを処理するために、変更されていないすべてのエントリが必要となる。
検索は、refresh または refreshAndPersist モードで実行できる。
リフレッシュステージは常に最初に発生する。リフレッシュステージでは、present と delete の2つのフェーズが発生し、present は常に delete の前に発生する。
フェーズは、フェーズの完了を示す同期情報の応答によって区切られる。
リフレッシュおよび持続ステージもまた、同期情報の応答によって区切られる。
存在または削除されるエントリのグループをよりコンパクトに表現する最適化は、これらのエントリの entryUUID 値のリストを識別する syncIdSet を含む同期情報の応答を使用する。
present フェーズは、delete フェーズと以下のように区別される。
変更されていないエントリは、present フェーズでのみ返される。削除されるエントリは、delete フェーズでのみ返される。
追加エントリ(変更されたエントリのすべての属性を示す)は、どちらのフェーズでも返すことができる。
したがって、present フェーズの最後において、コンシューマをプロバイダと同期させるためにコンシューマは次のエントリを削除しなければならない。
プロバイダには存在ないことを示すための present フェーズ中の現在の応答のエントリ
persist ステージが始まると、プロバイダは、リフレッシュステージ完了後の追加、変更、および削除の全エントリの検索結果を送信する。
persist ステージは無期限に続き、検索には最終的な「完了」応答がない。
対照的に、リフレッシュモードでは refresh ステージのみが発生する。
refresh ステージは、persist または delete フェーズ(現在アクティブなフェーズのいずれか)も完了応答で終了する。
このプロトコルは、書き込み(変更)アクセスのデータベースを保持することで、全変更(変更された属性のみ)を厳密に表す。
標準の syncrepl 仕様に基づいている。
このプロトコルでは、変更を常に完全なエントリとして送信します。
しかし、delta-syncrepl は、送信されたエントリは実際にはログデータベースから送信され、メインデータベースの各変更は、ログエントリとして記録されます。
ログエントリは、LDAPログスキーマを使用して記録されます。