LDAPのオープンソース実装のひとつとしてThe OpenLDAP Project <URL:http://www.openldap.org/>が開発しているOpenLDAPがあります。 OpenLDAPには、LDAPサーバslapd、LDAPレプリケーションサーバslurpd、LDAP プロトコルのライブラリ群、LDAPクライアントユーティリティなどが含まれて います。OpenLDAPにはいくつかのリリースブランチがあります。しばらく前ま ではOpenLDAP 1.2.x系列がstable版として使われていました。OpenLDAP 1.2.x はLDAPv2を実装したもので、今となってはOpenLDAP 1.2.13がHistoric releaseとして残されているだけです (コラム1)。 現在stableとしてリリースされているのはLDAPv3を実装した OpenLDAP 2.0.18(20011102)です。これが最新のリリースでもあります。
最近のLinuxディストリビューションなどではOpenLDAPのパッケージが用意さ れているのでそれをそのままインストールする方が簡単でしょう。 ただしリリースによってはOpenLDAP 1.2.x系列だけで、OpenLDAP 2.0.x系列は まだ作られていない場合もあります。
ここではOpenLDAPのソースをダウンロードして、それをビルドしてインストー ルする場合について説明します。OpenLDAPのリリース版は OpenLDAP Project のSoftware Downloadのページ <URL:http://www.openldap.org/software/download/> に書かれているところから入手することができます。日本では
<URL:ftp://ftp.dti.ad.jp/pub/net/OpenLDAP/openldap-release/openldap-2.0.18.tgz>
<URL:ftp://ftp.u-aizu.ac.jp/pub/net/openldap/openldap-release/openldap-2.0.18.tgz>
にミラーされているのでここからダウンロードするといいでしょう。
このアーカイブはtarでまとめてgzipで圧縮したものです。ダウンロードしたらgunzipしてtar xで展開できます。
% gunzip < openldap-2.0.15.tgz | tar xvf -
これでカレントディレクトリに openldap-2.0.18 というディレクトリができます。
% ls ANNOUNCEMENT LICENSE acinclude.m4 configure include CHANGES Makefile.in aclocal.m4 configure.in libraries COPYRIGHT README build contrib servers INSTALL acconfig.h clients doc tests
OpenLDAPはGNU autoconfを使っているので、後はconfigureして makeすればビルドできます。GNU autoconfを使っている configureなので./configure --helpすればわかる通りOpenLDAP には多くのビルドオプションがあります。
configureをする前に、OpenLDAPをビルドするために必要なソフトウェアがい くつかあります。それをconfigureする前にシステムにインストールしておく 必要があります。
OpenLDAPでプライマリのデータベースバックエンドとして使っているLDBM用の データベースパッケージが必要です。LDBMで利用できるデータベースパッケー ジとしては Sleepycat SoftwareのBerkeleyDBとFree Software Foundationの GNU Database Manager (GDBM)があります。これらはそれぞれ以下のところか ら入手できます。
<URL:http://www.sleepycat.com/download.html>
glibcに含まれている
<URL:ftp://ftp.gnu.org/pub/gnu/gdbm>
libgdbm1-dev
configureでどちらも見つけられないとslapdを作ることができません。 OpenLDAPをビルドする前にこれらのうちのどちらかをインストールしておく必 要があります(コラム2))。
# apt-get install libgdbmg1-dev Reading Package Lists... Done Building Dependency Tree... Done The following NEW packages will be installed: libgdbmg1-dev 0 packages upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Need to get 43.6kB of archives. After unpacking 101kB will be used. Get:1 http://localhost stable/main libgdbmg1-dev 1.7.3-26.2 [43.6kB] Fetched 43.6kB in 0s (1186kB/s) Selecting previously deselected package libgdbmg1-dev. (Reading database ... 7872 files and directories currently installed.) Unpacking libgdbmg1-dev (from .../libgdbmg1-dev_1.7.3-26.2_i386.deb) ... Setting up libgdbmg1-dev (1.7.3-26.2) ...
OpenLDAP 2.0.xではthreadを使うようになっています。そのためPOSIX pthreadsやMach CThreadsなどを必要としています。これらもあらかじめイン ストールしておかなければなりません。GNU Libc 2ではglibcにすでに含まれ ているので特にインストールする必要はありません。
OpenLDAPサーバにアクセスする際の認証方法の一つとしてSASL(Simple Authentication and Security Layer)というものがあります。SASL自体は OpenLDAP独自のものではなく汎用的な認証のためのフレームワークです。 OpenLDAPでSASLをサポートする場合はSASLライブラリを使うことができます。 configureがCyrus SASLライブラリをみつけられなかった時は、SASL機能の含 まれていないバイナリが作成されます。Debian potatoにはSASLライブラリの パッケージもないので、これもソースからインストールする必要があります。
<URL:http://asg.web.cmu.edu/cyrus/download> (libsasl-dev package; woody移行)
通信路を暗号化する仕組としてTLS(Transport Layer Security)もしくは SSL(Secure Socket Layer)と呼ばれる仕組があります。OpenLDAPでもこの TLS/SSLを使うようにすることができます。OpenLDAPにTLS/SSLを組込むには OpenSSLが必要になります。これもconfigureがOpenSSLライブラリをみつけら れなかった時は、TLS/SSL機能が含まれていないOpenLDAPが作られることにな ります。
<URL:http://www.openssl.org/source/> libssl09-dev package (libssl-dev package; woody移行)
# apt-get install libssl09-dev Reading Package Lists... Building Dependency Tree... The following extra packages will be installed: libssl09 The following NEW packages will be installed: libssl09 libssl09-dev 0 packages upgraded, 2 newly installed, 0 to remove and 0 not upgraded. Need to get 915kB of archives. After unpacking 2964kB will be used. Do you want to continue? [Y/n] y Get:1 http://http.debian.or.jp stable/non-US/main libssl09 0.9.4-5 [359kB] Get:2 http://http.debian.or.jp stable/non-US/main libssl09-dev 0.9.4-5 [556kB] Fetched 915kB in 0s (2469kB/s) Selecting previously deselected package libssl09. (Reading database ... 7739 files and directories currently installed.) Unpacking libssl09 (from .../libssl09_0.9.4-5_i386.deb) ... Selecting previously deselected package libssl09-dev. Unpacking libssl09-dev (from .../libssl09-dev_0.9.4-5_i386.deb) ... Setting up libssl09 (0.9.4-5) ... Setting up libssl09-dev (0.9.4-5) ...
TCPの接続のアクセス制限をするためのフレームワークとしてTCP Wrapperとい うソフトウェアがあります。inetd経由で利用する場合は/usr/sbin/tcpdを使っ てデーモンを起動することでTCPの接続のアクセス制限をすることができます。 OpenLDAPではTCP WrapperライブラリとリンクすることでOpenLDAPのサーバプ ログラムの中でTCP Wrapperライブラリの機能を使ってTCPの接続のアクセス制 限をおこなうようにできます。なお、OpenLDAPのサーバではTCP Wrappersがな くてもそれ自体にアクセスコントロールリストがあり、それによりTCPの接続 のアクセス制御をすることができるようになっています。
<URL:ftp://ftp.porcupine.org/pub/security/index.html> libwrap0-dev package
# apt-get install libwrap0-dev Reading Package Lists... Building Dependency Tree... The following NEW packages will be installed: libwrap0-dev 0 packages upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Need to get 27.6kB of archives. After unpacking 76.8kB will be used. Get:1 http://http.debian.or.jp stable/main libwrap0-dev 7.6-4 [27.6kB] Fetched 27.6kB in 0s (687kB/s) Selecting previously deselected package libwrap0-dev. (Reading database ... 7849 files and directories currently installed.) Unpacking libwrap0-dev (from .../libwrap0-dev_7.6-4_i386.deb) ... Setting up libwrap0-dev (7.6-4) ...
以上で説明したようなソフトウェアが標準的な場所にインストールされていれ ば、configureが見つけてくれますが、そうでない場合はそれらの場所を configureに教えてあげる必要があります。/usr/local/includeなどにインス トールしてある場合はCPPFLAGSやLDFLAGSを設定して次のようにconfigureを実 行するといいでしょう。
% CPPFLAGS='-I/usr/local/include' LDFLAGS='-L/usr/local/lib' \ ./configure [configureのオプション]
これは/bin/sh系のシェルの場合です。csh系の場合はenv(1)コマンドを使うか setenvしてからconfigureを実行することになります。
Debianの場合 libc6のdbは/usr/includeにlibgdbmg1-devはヘッダファイルを /usr/include/に、libssl09-devは/usr/include/opensslに、libwrap0-devは /usr/includeにヘッダファイルをインストールするのでCPPFLAGSには '-I/usr/include/openssl'を指定することになります。
デフォルトではBerkeley DBの方をみつけてしまうのでBerkeley DBではなく GNU DBMを使う場合には--with-ldbm-api=gdbmと指定する必要があります。
/usr/local以下にインストールする場合は、--prefixに/usr/localを指定して configureを実行します。(/usr/localはprefixのデフォルトなので--prefixに 指定しない場合と同じです)
% CPPFLAGS='-I/usr/include/openssl' ./configure --prefix=/usr/local Copyright 1998-2001 The OpenLDAP Foundation, All Rights Reserved. Restrictions apply, see COPYRIGHT and LICENSE files. Configuring OpenLDAP 2.0.18-Release ... checking host system type... i686-pc-linux-gnu checking target system type... i686-pc-linux-gnu checking build system type... i686-pc-linux-gnu checking for a BSD compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for mawk... mawk checking whether make sets ${MAKE}... yes checking for working aclocal... missing checking for working autoconf... missing checking for working automake... missing checking for working autoheader... missing checking for working makeinfo... missing checking for gnutar... no checking for gtar... no checking for tar... tar checking configure arguments... done checking for cc... cc checking for ranlib... ranlib (略) creating tests/Makefile creating tests/progs/Makefile creating contrib/Makefile creating contrib/saucer/Makefile creating include/portable.h creating include/ldap_features.h creating include/lber_types.h Please "make depend" to build dependencies
configureがおわればmake dependでビルドで必要となるMakefileでの依存関係 を生成してからmakeでビルドします。
% make depend Making depend in /usr/src/openldap/openldap-2.0.18 Entering subdirectory include make[1]: Entering directory `/usr/src/openldap/openldap-2.0.18/include' make[1]: Nothing to be done for `depend'. make[1]: Leaving directory `/usr/src/openldap/openldap-2.0.18/include' Entering subdirectory libraries (略) Entering subdirectory man8 make[3]: Entering directory `/usr/src/openldap/openldap-2.0.18/doc/man/man8' make[3]: Nothing to be done for `depend'. make[3]: Leaving directory `/usr/src/openldap/openldap-2.0.18/doc/man/man8' make[2]: Leaving directory `/usr/src/openldap/openldap-2.0.18/doc/man' make[1]: Leaving directory `/usr/src/openldap/openldap-2.0.18/doc' % make Making all in /usr/src/openldap/openldap-2.0.18 Entering subdirectory include make[1]: Entering directory `/usr/src/openldap/openldap-2.0.18/include' make[1]: Nothing to be done for `all'. make[1]: Leaving directory `/usr/src/openldap/openldap-2.0.18/include' Entering subdirectory libraries (略) make[3]: Leaving directory `/usr/src/openldap/openldap-2.0.18/doc/man/man8' make[2]: Leaving directory `/usr/src/openldap/openldap-2.0.18/doc/man' make[1]: Leaving directory `/usr/src/openldap/openldap-2.0.18/doc'
これでclients/以下にLDAPクライアントプログラムが、libraries/以下にLDAP ライブラリが、servers/以下にLDAPサーバslapdとLDAPレプリケーションサー バslurpdができています。このままインストールしてしまってもかまいません が一応正しくビルドできているかどうかテストすることができます。テストす るにはmake testを実行します。
% make test
make testを実行するとポート9009などを使って今ビルドしたslapdを立ちあげ て、サンプルデータを使っていろいろテストをおこないます。問題がなければ エラーで停止せずに終了します。
問題なくビルドできればインストールします。rootになってmake installを実行するとprefixで指定したディレクトリ以下にインストールされます。
# make install
どのディレクトリにどのようなプログラム、ファイルがインストールされるか を簡単に説明します。
ここにインストールされるのはLDAPクライアントです。LDAPプロトコルを使ってLDAPサーバにある情報を操作できます。
ldapadd LDAPサーバにデータを追加するためのクライアント ldapdelete LDAPサーバにあるデータを削除するためのクライアント ldapmodify LDAPサーバにあるデータを修正するためのクライアント ldapmodrdn LDAPサーバにあるデータを移動するためのクライアント ldappasswd LDAPサーバにあるパスワード情報を更新するためのクライアント ldapsearch LDAPサーバにあるデータを検索するためのクライアント ud LDAPサーバと接続して会話的に操作するためのクライアント
ここにはLDAPの設定ファイルなどがインストールされます。
slapd.conf, slapd.conf.default (LDAPサーバ、slapdの設定ファイル) schema/ slapd.confで参照するschemaファイル ldap.conf, ldap.conf.default ldapfilter.conf, ldapfilter.conf.default ldapsearchprefs.conf, ldapsearchprefs.conf.default ldaptempaltes.conf, ldaptemplates.conf.default LDAPクライアントなどで参照する設定
ここにはLDAP APIのためのインクルードファイルがインストールされます。
disptmpl.h lber_types.h ldap_cdefs.h ldap_schema.h lber.h ldap.h ldap_features.h srchpref.h
ここにはLDAP関係のライブラリがインストールされます。
liblber.a liblber.so.2.0.12 libldap.so.2 libldap_r.so liblber.la libldap.a libldap.so.2.0.12 libldap_r.so.2 liblber.so libldap.la libldap_r.a libldap_r.so.2.0.12 liblber.so.2 libldap.so libldap_r.la
ここにはサーバやバックエンドとして使われるプログラムがインストールされます。
slapd LDAPサーバ slurpd LDAPレプリケーションサーバ mail500 LDAP/X.500を使ったメール配送プログラム rcpt500 mail経由でLDAPを使うためのプログラム fax500 LDAP/X.500を使ったFAX配送プログラム go500,go500gw X.500によるgopherサーバ in.xfingerd LDAP/X.500を使ったfingerデーモン
ここにはslapdで使うLDBMデータベースをLDAPを使わないで直接操作するためのプログラムがインストールされます。
slapadd LDBMにデータを追加するプログラム slapcat LDBMのデータをテキストにして出力するためのプログラム slapindex LDBMのインデックスファイルを作成をするプログラム slappasswd LDAPのpassword用のエントリに使うためのデータを生成するためのプログラム
libexecにあるプログラムなどが参照するヘルプファイルなどがインストールされます。
ここはslapd, slurpdがデータを置くためのデフォルトのディレクトリです。
マニュアルページがインストールされます。
最初に、${prefix}/etc/openldap/slapd.confを各サイト用に編集する必要が あります。defaultのslapd.confはリスト1 のようになっています。#ではじまる行はコメント行です。 それ以外の行が実際の設定内容となります。
# $OpenLDAP: pkg/ldap/servers/slapd/slapd.conf,v 1.8.8.7 2001/09/27 20:00:31 kurt Exp $ # # See slapd.conf(5) for details on configuration options. # This file should NOT be world readable. # include /usr/local/etc/openldap/schema/core.schema # Define global ACLs to disable default read access. # Do not enable referrals until AFTER you have a working directory # service AND an understanding of referrals. #referral ldap://root.openldap.org pidfile /usr/local/var/slapd.pid argsfile /usr/local/var/slapd.args # Load dynamic backend modules: # modulepath /usr/local/libexec/openldap # moduleload back_ldap.la # moduleload back_ldbm.la # moduleload back_passwd.la # moduleload back_shell.la # # Sample Access Control # Allow read access of root DSE # Allow self write access # Allow authenticated users read access # Allow anonymous users to authenticate # #access to dn="" by * read #access to * # by self write # by users read # by anonymous auth # # if no access controls are present, the default is: # Allow read by all # # rootdn can always write! ####################################################################### # ldbm database definitions ####################################################################### database ldbm suffix "dc=my-domain,dc=com" #suffix "o=My Organization Name,c=US" rootdn "cn=Manager,dc=my-domain,dc=com" #rootdn "cn=Manager,o=My Organization Name,c=US" # Cleartext passwords, especially for the rootdn, should # be avoid. See slappasswd(8) and slapd.conf(5) for details. # Use of strong authentication encouraged. rootpw secret # The database directory MUST exist prior to running slapd AND # should only be accessible by the slapd/tools. Mode 700 recommended. directory /usr/local/var/openldap-ldbm # Indices to maintain index objectClass eq
サンプルのslapd.confで設定している内容を順に説明していきます。
include /usr/local/etc/openldap/schema/core.schema
このinclude行でcore.schemaというschemaファイルをインクルードしています。これによりLDAP関係のRFCなどで定義されているattributeやobjectclassが使えるようになります。
pidfile /usr/local/var/slapd.pid argsfile /usr/local/var/slapd.args
この2行はslapdのPIDおよびコマンドライン引数を書きこむためのファイルの指定です。restartする時などに参照されます。
database ldbm
このdatabaseの行からLDBMによるデータベース向けの定義です。
suffix "dc=my-domain,dc=com"
このLDBMでどういう範囲のデータを扱うかをあらわします。このdefaultの例だとdc=my-domain,dc=comの中のデータをこのslapdが持つことになります。例えばou=people,dc=my-domain,dc=comなどがそうです。dcというのはdomainComponentのことで、DNSに対応したLDAPでの表現です。つまりmy-domain.comというドメインの場合にdc=my-domain,dc=comをsuffixとして使うようにしておけば他のサイトのLDAPサーバと名前が衝突する心配がなくなるわけです。 example.jpだとdc=example,dc=jp、example.co.jpだとdc=example,dc=co,dc=jpのようにしておけばいいでしょう。ここでは例としてexample.jpを使います。よってこの行は次のように変更することになります。
suffix "dc=example,dc=jp" rootdn "cn=Manager,dc=my-domain,dc=com" rootpw secret
「rootdn "cn=Manager,dc=my-domain,dc=com"」は特権ユーザの識別名(DN)で 「rootpw secret」がそのパスワードです。LDAPではbindという操作をおこな うことで、どのユーザがLDAPのサービスを利用しているかの認証をおこないま す。その時のユーザを特定するための識別子としても識別名(DN)を使います。 OpenLDAPではLDAPサービスを利用しているユーザ(つまりbindしている識別名 (DN))がどのような操作ができるかをアクセス制御リスト(Access Control List; ACL)を使って制御することができます。rootdnで指定した識別名(DN)は 特権ユーザ扱いとなりあらゆる操作ができるようになります。rootpwも指定し てあればそれがrootdnのパスワードとなります。なお、rootdnを指定しなくて も、aclでそれと同等の設定をしておくこともできます。
OpenLDAPでは識別名(DN)ごとのパスワードはその識別名(DN)で特定されるディ レクトリエントリのuserPassword属性の値を使います。従ってrootpwを設定し ていない場合は、rootdnのパスワードはrootdnで特定されるディレクトリエン トリのuserPassword属性の値を使うことになります。もしrootpwが設定されて いれば、userPassword属性の値は無視されrootpwの方が使われます。従って、 rootdnのパスワードを忘れた時など一時的にrootpwを設定することで、rootdn のパスワードを設定しなおしたりすることが可能です。rootpwを書く場合は特 にslapd.confが他の一般ユーザから見られないようにこのファイルのパーミッ ションには気をつける必要があります。
ちなみに、パスワードはこの例のように平文でしか書けないわけではなく /etc/shadowなどに書くように暗号化した文字列でも書くことができます。こ れについては後述します。rootdnはsuffixでつくられるディレクトリツリーの 中の識別名(DN)を選びます。ここではsuffixとしてdc=example,dc=jpを使って いるので次のようにしておくといいでしょう。
rootdn "cn=Manager,dc=example,dc=jp" rootpw secret directory /usr/local/var/openldap-ldbm
directory行でどのディレクトリにLDAPの利用するデータベースをおくかを指 定します。データの中にはパスワードの情報なども含まれるのでこのディレク トリのパーミッションは700にしておくべきです。
index objectClass eq
index行はobjectClassに対してインデックスファイルを作成することを指示し ています。インデックスファイルを作成しておくことでその属性に対する検索 を高速にすることができるようになります。そのかわりディスクを余分に消費 することになります。
既に説明した通り、slapdを動かす前に少なくともslapd.confの中のsuffixと rootdn,rootpwあたりを修正する必要があります。例えば example.jpドメイン だとすると元のslapd.confのsuffix,rootdn,rootpwの行を リスト2のように 書きかえます。リスト2 ではコメント行は省いてあります。サンプルのslapd.confそのままでかまいません。
include /usr/local/etc/openldap/schema/core.schema pidfile /usr/local/var/slapd.pid argsfile /usr/local/var/slapd.args database ldbm suffix "dc=example,dc=jp" rootdn "cn=Manager,dc=example,dc=jp" rootpw パスワード文字列 directory /usr/local/var/openldap-ldbm index objectClass eq
rootpwのパスワード文字列は適当にあたえます。特別な書きかたをしない限り これはそのまま平文のパスワード文字列となるのでslapd.confのパーミッショ ンには注意してください。rootをオーナにしてオーナのみ読み書きできるよう にしておくべきでしょう。
# chown root slapd.conf # chmod 600 slapd.conf
以上のようにslapd.confのsuffix,rootdn,rootpwを変更したら、 ${prefix}/libexecにインストールされているslapdを起動します。
# /usr/local/libexec/slapd
問題がなければslapdはデーモンとなってバックグラウンドで動きはじめます。
slapdが動いているかどうかはpsコマンドなどでも調べることができますが、 正しくslapdが動いているかどうかを確認するためにはldapsearchで次のよう に検索します。
% ldapsearch -h localhost -x -b '' -s base '(objectclass=*)' namingContexts
-hオプションはLDAPサーバホストの指定です。-h localhostでlocalhostの slapdにアクセスすることを意味しています。
-xオプションはSASLを使わない単純な認証方式でLDAPサーバにアクセスするこ とを意味しています。SASLの設定をしていない場合は-xオプションをつけてお きます。
-bオプションは検索ベースの指定です。-b ''は指定したLDAPサーバのrootDSE と呼ばれるそのディレクトリサーバだけにある特殊な情報にアクセスする時に 使います。
-sオプションは検索スコープの指定です。-s baseで検索スコープとしてbase を指定することになります。つまり-bオプションで指定した識別名(DN)の属性 だけを検索することになります。
'(objectclass=*)'は検索フィルターです。(objectclass=*)という検索フィル ターはobjectclass属性が存在するディレクトリエントリを検索するという検 索フィルターです。すべてのディレクトリエントリにはobjectclass属性があ るので、この検索フィルターは検索範囲内のすべてのディレクトリエントリを 検索することになります。
最後のnamingContextsというのは検索した結果得られたディレクトリエントリ の中で欲しい属性の名前です。
-b '' -s baseにあるのはrootDSEと呼ばれるディレクトリエントリです。 (objectclass=*)という検索フィルターですべてのディレクトリエントリつま り必ずrootDSEを検索することができます。rootDSEのnamingContexts属性は、 このLDAPサーバがどの範囲のディレクトリツリーのデータを扱っているかを表 します。つまりLDAPサーバslapdに設定したsuffixの値がnamingContextsにな るわけです。
もしslapdが正しく動いていれば以下のようなレスポンスが得られます。
% ldapsearch -h localhost -x -b '' -s base '(objectclass=*)' namingContexts version: 2 # # filter: (objectclass=*) # requesting: namingContexts # # dn: namingContexts: dc=example,dc=jp # search result search: 2 result: 0 Success # numResponses: 2 # numEntries: 1
このようにnamingContextsの行にsuffixで指定したもの、つまりこの例では dc=example,dc=jpが得られれば正しくslapdは動いています。
もしLDAPサーバが動いていない時は次のようなエラーメッセージがかえってきます。
% ldapsearch -h localhost -x -b '' -s base '(objectclass=*)' namingContexts ldap_bind: Can't contact LDAP server
ちなみにrootDSEにはnamingContexts以外にも属性があります。それらをすべ て見るためには属性名として*と+を指定します。*は一般の属性全て、+はシス テム内で使われている属性全てを意味します。
% ldapsearch -h localhost -x -b '' -s base '(objectclass=*)' '*' '+' version: 2 # # filter: (objectclass=*) # requesting: * + # # dn: objectClass: top objectClass: OpenLDAProotDSE namingContexts: dc=example,dc=jp supportedControl: 2.16.840.1.113730.3.4.2 supportedExtension: 1.3.6.1.4.1.4203.1.11.1 supportedExtension: 1.3.6.1.4.1.1466.20037 supportedFeatures: 1.3.6.1.4.1.4203.1.5.1 supportedLDAPVersion: 2 supportedLDAPVersion: 3 subschemaSubentry: cn=Subschema # search result search: 2 result: 0 Success # numResponses: 2 # numEntries: 1
それでは簡単なデータを追加してみることにしましょう。LDAPのデータは LDIF(LDAP Data Interchange Format)と呼ばれる形式で記述します。最初に挿 入すべきデータはリスト3のようなものです。
dn: [suffixで指定したもの] objectclass: dcObject objectclass: organization o: [組織の名称」 dc: [トップのdcの値] dn: [rootdnで指定したもの] objectclass: organizationalRole [トップの要素]
suffix: dc=example,dc=jpでrootdn: cn=Manager, dc=example,dc=jpと設定し ている場合はリスト4のようなデータを追加することになります。
dn: dc=example,dc=jp objectclass: dcObject objectclass: organization o: Example Organization dc: example dn: cn=Manager,dc=example,dc=jp objectclass: organizationalRole cn: Manager
これはdc=example,dc=jpとcn=Manager,dc=example,dc=jpという二つ識別名 (DN)に対するディレクトリエントリを意味しています。このようにディレクト リエントリ間は空行で区切ります。ディレクトリエントリの最初はそのディレ クトリエントリの識別名(DN)をかいたdn:の行ではじめます。
dc=example,dc=jpという識別名(DN)のディレクトリエントリは、objectclass属性、o属性、dc属性をもっています。objectclass属性としてdcObject(domain component object)およびorganizationという値をもっています。o属性というのはOrganization(組織)をあわらすための属性で、ここではExample Organizationという文字列を指定しています。dc属性はドメインコンポーネント(domain component)をあわらすための属性です。これはdc=example,dc=jpという識別名(DN)をつくる最後の相対識別名(RDN)であるdc=exampleをあらわす属性です。
cn=Manager,dc=example,dc=jpという識別名(DN)のディレクトリエントリは、objectclass属性とcn属性をもっています。objectclass属性としてはorganizationalRoleという役割をもっています。cn属性は人などの一般名(common name)を表すためによく使われる属性です。これもdc=example,dc=jpからcn=Manager,dc=example,dc=jpという識別名(DN)をつくりだす相対識別名(RDN)であるcn=Managerをあらわすための属性となっています。
このリスト4の内容のファイル example.ldifをldapaddコマンドを使ってLDAPサーバに追加します。
% ldapadd -h localhost -x -D 'cn=Manager,dc=example,dc=jp' -W -f example.ldif Enter LDAP Password:
-hオプションは既に説明した通りLDAPサーバのホスト名を指定するためのオプションです。-xオプションも既に指定した通りSASLを使わないで単純認証で認証をおこなうためのオプションです。
-Dオプションで、LDAPサーバをどのユーザで使うかを指定します。LDAPではユーザは識別名(DN)で区別しているのでここで指定するのも識別名(DN)となります。まだLDAPサーバにはなんのデータも登録していないのでここで使えるのはslapd.confで指定したrootdnだけですから、ここではcn=Manager,dc=example,dc=jpという識別名(DN)でLDAPサーバを使う、つまりcn=Manager,dc=example,dc=jpでLDAPサーバにbindします。
-Wオプションはパスワードをldapaddが聞いてくるようにするためのオプションです。ここで与えるパスワードは-Dオプションで指定した識別名(DN)のパスワードです。この例ではcn=Manager,dc=example,dc=jpのパスワードですが、これはslapd.confでrootdnとして指定されていて、slapd.confではrootpwも指定しているので、パスワードとしてはrootpwで指定した文字列を使います。
-fオプションはどのファイルの内容をLDAPサーバに追加するかを指示するためのオプションです。ldapaddはこのようにファイルから追加する内容を読みとる以外にも標準入力から追加する内容を読みとることができます。標準入力から読む場合は-fオプションはなくてもかまいません。
うまくいけば次のように出力されます。
% ldapadd -h localhost -x -D 'cn=Manager,dc=example,dc=jp' -W -f example.ldif Enter LDAP Password: adding new entry "dc=example,dc=jp" adding new entry "cn=Manager,dc=example,dc=jp"
もし、LDIFの内容が間違っていると次のようなエラーになったります。 次は識別名(DN)をまちがっていた場合です。
% ldapadd -x -D 'cn=Manager,dc=example,dc=jp' -W -f example.ldif Enter LDAP Password: adding new entry "dc=examples,dc=jp" ldap_add: No such object ldif_record() = 32
次は空行にスペースやタブが入っていて空行になっておらず一つのディレクトリエントリとみなされた場合です。
adding new entry "dc=example,dc=jp" ldap_add: Undefined attribute type additional info: dn: attribute type undefined ldif_record() = 17 ldapadd: invalid format (line 6) entry: "dc=example,dc=jp" ldif_record() = 89
次はパスワードを間違えた場合です。
ldap_bind: Invalid credentials
LDAPサーバに追加したデータを確認するためにldapsearchで検索してみます。
% ldapsearch -h localhost -x -b 'dc=example,dc=jp' '(objectclass=*)' version: 2 # # filter: (objectclass=*) # requesting: ALL # # example, jp dn: dc=example,dc=jp objectClass: dcObject objectClass: organization o: Example Organization dc: example # Manager, example, jp dn: cn=Manager,dc=example,dc=jp objectClass: organizationalRole cn: Manager # search result search: 2 result: 0 Success # numResponses: 3 # numEntries: 2
-bオプションでsuffixと同じ識別名(DN)を与えることで、このLDAPサーバがもつディレクトリツリーのトップとなるディレクトリエントリを検索ベースとすることになります。-sオプションを指定していないので検索スコープはsubになります。従って検索範囲としてはこのLDAPサーバがもつディレクトリツリーすべてになります。
検索フィルターとして'(objectclass=*)'を指定しているので、すべてのディレクトリエントリを検索する意味になります。
ここで検索結果を注意してよくみると objectclass: dcObject で登録したのに検索するとobjectClass: dcObjectのようになっていることに気づくでしょう。LDAPでは属性名の大文字小文字は区別しないためobjectclass:でもobjectClass:でも同じ意味になります。
LDAPプロトコルを使わないで、直接slapdが管理しているLDBMの内容をチェックできればいい時があります。この時はldapsearchコマンドを使わないで/usr/local/sbinにインストールされたslapcatを使います。slapcatは直接データベースにアクセスするためにroot権限が必要となります。
# /usr/local/sbin/slapcat dn: dc=example,dc=jp objectClass: dcObject objectClass: organization o: Example Organization dc: example creatorsName: cn=Manager,dc=example,dc=jp createTimestamp: 20011106185435Z modifiersName: cn=Manager,dc=example,dc=jp modifyTimestamp: 20011106185435Z dn: cn=Manager,dc=example,dc=jp objectClass: organizationalRole cn: Manager creatorsName: cn=Manager,dc=example,dc=jp createTimestamp: 20011106185435Z modifiersName: cn=Manager,dc=example,dc=jp modifyTimestamp: 20011106185435Z
このようにLDAPのデータベースの中には、登録したデータ以外にcreatorsNameなどの属性も追加されて登録されています。これらはシステムで利用している属性です。
creatorsName このディレクトリエントリを追加したユーザの識別名(DN) createTimestamp このディレクトリエントリを追加した時間 modifiersName このディレクトリエントリを最後に変更したユーザの識別名(DN) modifyTimestamp このディレクトリエントリを最後に変更した時間
これらのシステムで利用している属性に関しては、ldapsearchなどで検索する時には指定しない限り結果にはあわらわないようになっています。これらもldapsearchで検索する時に取りだしたい時はその属性名を直接指定するか、+という属性名を指定します。
% ldapsearch -h localhost -x -b 'dc=example,dc=jp' '(objectclass=*)' creatorsName version: 2 # # filter: (objectclass=*) # requesting: creatorsName # # example, jp dn: dc=example,dc=jp creatorsName: cn=Manager,dc=example,dc=jp # Manager, example, jp dn: cn=Manager,dc=example,dc=jp creatorsName: cn=Manager,dc=example,dc=jp # search result search: 2 result: 0 Success # numResponses: 3 # numEntries: 2 % ldapsearch -h localhost -x -b 'dc=example,dc=jp' '(objectclass=*)' '*' '+' version: 2 # # filter: (objectclass=*) # requesting: * + # # example, jp dn: dc=example,dc=jp objectClass: dcObject objectClass: organization o: Example Organization dc: example creatorsName: cn=Manager,dc=example,dc=jp createTimestamp: 20011106185435Z modifiersName: cn=Manager,dc=example,dc=jp modifyTimestamp: 20011106185435Z subschemaSubentry: cn=Subschema # Manager, example, jp dn: cn=Manager,dc=example,dc=jp objectClass: organizationalRole cn: Manager creatorsName: cn=Manager,dc=example,dc=jp createTimestamp: 20011106185435Z modifiersName: cn=Manager,dc=example,dc=jp modifyTimestamp: 20011106185435Z subschemaSubentry: cn=Subschema # search result search: 2 result: 0 Success # numResponses: 3 # numEntries: 2
OpenLDAP 1.2.x系は長い間、OpenLDAP 1.2.12のリリースを最後にリリースされていませんでした。それ以後はほとんどOpenLDAP 2.0.xの開発に力がそそがれていたわけです。OpenLDAP 1.2.13は2001年9月9日にあったUNIX timeが10桁を越える生じるバグがslurpd関係に発見されたためにリリースされました。なお、OpenLDAP 2.0.x系ではOpenLDAP 2.0.14でこのバグが修正されています。
Berkeley DBはlibdb2-devというパッケージもありこちらの方がlibc6のものよ り新しいですが、こちらに対応するshared libraryはlibdb2.soで、これは configureでは自動的にみつけられないのでCPPFLAGS=-I/usr/include/db2で configureしてつくってもちゃんと動くものはできません。libc6のdbを使うか gdbmを使うかどちらかで作る必要があります。