OpenLDAP の利用

LDAP(Lightweight Directory Access Protocol)は、X.500ベースのディレクトリサービスをインターネット向けに軽量化したプロトコルです。OSIプロトコルを用いるDAP(Directory Access Protocol)と異なり、TCP/IP上で動作しWWWブラウザやメールソフトウェアなどから簡単に利用できるよう簡素化しています。

パッケージの入手とインストール

Solaris 8 上に、LDAP サーバーを構築するために iPlanet Directory Server が使えるかと思ったが Solaris x86 版がないので、OpenLDAP を Solaris 8 上に構築します。OpenLDAPの README で推奨しているライブラリー(OpenSSL, Berkeley DB, Cyrus SASLは面倒なのでパス)をいくつかインストールします。セキュリーティー向上のため、最新のバージョンのモジュールをダウンロードしてインストールしてください。

必要なモジュール

openssl-0.9.6g.tar.gz
( http://www.openssl.org/)

db-4.1.24.tar.gz では、 openldap-2.0.25 でうまくコンパイルできなかった。調べるのが面倒なので db-3.3.11.tar.gz を利用。
( http://www.sleepycat.com/download.html)

openldap-stable-20020618.tgz (ここでは、stable なバージョンを利用します)
( http://www.openldap.org/software/download/)

インストール手順 (スーパーユーザーで作業)

Solaris 8 の標準DB(dbm)では動作しないので Berkeley DB を利用し、後々便利なので SSL にも対応させておきます。SSLが必要なければ、OpenSSL のコンパイルと OpenLDAP を configure する時の /usr/local/ssl の指定を無視してください。(root# はプロンプトです。)

  root# gzip -dc db-3.3.11.tar.gz | tar xf -
  root# cd db-3.3.11/build_unix
  root# CC=gcc ../dist/configure
  root# make
  root# make install
  root# cd ../..
 
  root# gzip -dc openssl-0.9.6g.tar.gz | tar xf -
  root# cd openssl-0.9.6g
  root# ./config
  root# make
  root# make test
  root# make install
  root# cd ..
 
  root# gzip -dc openldap-stable-20020618.tgz | tar xf -
  root# cd openldap-2.0.25
  root# CPPFLAGS="-I/usr/local/BerkeleyDB.3.3/include -I/usr/local/ssl/include" \
  > LDFLAGS="-L/usr/local/BerkeleyDB.3.3/lib -R/usr/local/BerkeleyDB.3.3/lib \
  > -L/usr/local/ssl/lib" CC=gcc ./configure
  root# make depend
  root# make
  root# make test
  root# make install

これらのインストールで /usr/local ディレクトリーにインストールされます。

環境設定ファイル

/usr/local/etc/openldap
サーバー /usr/local/libexec
ユーティリティ /usr/local/bin
ライブラリ他 /usr/local/lib, /usr/local/include
データベース /usr/local/var

 

サーバーの設定と起動

まず、LDAP サーバー(slapd) の設定ファイルである /usr/local/etc/openldap/slapd.conf を編集します。

#
include         /usr/local/etc/openldap/schema/core.schema
include         /usr/local/etc/openldap/schema/cosine.schema
include         /usr/local/etc/openldap/schema/inetorgperson.schema
 
schemacheck off
 
pidfile /usr/local/var/slapd.pid
argsfile /usr/local/var/slapd.args
 
#######################################################################
# ldbm database definitions
#######################################################################
database ldbm
suffix "o=FOOBAR,c=JP"
rootdn "cn=root,o=FOOBAR,c=JP"
rootpw secret
directory /usr/local/var/openldap-ldbm
 
objectClass person

include ディレクティブでは、基本属性と mail, jpegPhot, posixAccount等の属性を追加しています。データーベースのルートや管理者(rootdn)およびパスワード(rootpw)を登録します。パスワードは、クリアテキストですがとりあえずテストなのでそのまま。

設定が完了したら、サーバーの起動:

  root# /usr/local/libexec/slapd

LDAP サーバーをシステム起動時に動作させるように /etc/rc.local や /etc/init.d 等に追加しておくと良いでしょう。

OpenLDAP では、マスターサーバーが停止した場合に対処できるようセカンダリサーバー(slurpd)が用意されています。セカンダリサーバーも slapd.conf を参照するので、上記の設定にいくつか追記します。マスターサーバが master.foobar.co.jp で、セカンダリサーバーが repl.foobar.co.jp の場合:

#
include         /usr/local/etc/openldap/schema/core.schema
include         /usr/local/etc/openldap/schema/cosine.schema
include         /usr/local/etc/openldap/schema/inetorgperson.schema
include         /usr/local/etc/openldap/schema/nis.schema
 
schemacheck     off
 
referral        ldap://master.foobar.co.jp
 
pidfile         /usr/local/var/slapd.pid
argsfile        /usr/local/var/slapd.args
 
#######################################################################
# ldbm database definitions
#######################################################################
database        ldbm
suffix          "o=FOOBAR,c=JP"
rootdn          "cn=root,o=FOOBAR,c=JP"
rootpw          secret
directory       /usr/local/var/openldap-ldbm
 
objectClass     person
 
replogfile      /usr/local/var/slurpd.replog
 
replica         host=repl.foobar.co.jp:389 binddn="cn=root,o=FOOBAR,c=JP"
                bindmethod=simple credentials credentials=secret

access ディレクティブを使用すればアクセス制御も行えます。機能のほんの一部を紹介。OpenLDAP コンパイルする際に TCP Wrapper を組み込むのもよいかもしれません。

# すべてのユーザーにして読み取り許可を与える
access to * by * read
 
# 自分のエントリーは更新/認証可能で、認証されたユーザーは読み取り許可を与える
access to *
    by self write
    by anonymouse auth
    by * read

 

データベースの作成と利用

OpenLDAP に付属のコマンドを使ってデータベースの作成やデータの追加削除を行います。

ldapadd

データベースの作成やデータの追加
ldapdelete データの削除
ldapmodify データの修正
ldapmodrdn 識別名(dn)の修正
ldappasswd パスワードの作成
ldapsearch データの検索
ldif2ldbm LDIF形式のデータを ldbm 形式に変換する
ldif2index LDIF形式のデータのインデックスを作成する
ldbmcat ldbm 形式のデータを LDIF形式のテキストに変換する

まず、トップオブジェクトを作ってみます。

root#
root# ldapadd -D "cn=root,o=FOOBAR,c=JP" -w secret
dn: o=FOOBAR,c=JP
o: FOOBAR
objectclass: organization
<CR> 
adding new entry "o=FOOBAR,c=JP"
^D
root# 

UNIX のアカウント登録を例にデータを登録してみましょう。これは、nis.schema に登録されている posixAccount を利用します。

root#
root# ldapadd -D "cn=root,o=FOOBAR,c=JP" -w secret
dn: ou=People, o=FOOBAR, c=JP
ou: People
objectclass: top
objectclass: organizationalUnit
<CR>
adding new entry "ou=People, o=FOOBAR, c=JP"
 
dn: uid=momo, ou=People, o=FOOBAR, c=JP
objectclass: account
objectclass: posixAccount
objectclass: top
cn: Tarou Momo
uid: momo
uidnumber: 1230
gidnumber: 100
homedirectory: /home/tarou
loginshell: /bin/bash
gecos: Tarou Momo
mail: momo@foobar.co.jp
<CR>
adding new entry "uid=momo, ou=People, o=FOOBAR, c=JP"
 
dn: uid=hana, ou=People, o=FOOBAR, c=JP
objectclass: account
objectclass: posixAccount
objectclass: top
cn: Hanako Hanazono
uid: hana
uidnumber: 1231
gidnumber: 100
homedirectory: /home/hanako
loginshell: /bin/csh
gecos: Hanako Hanazono
mail: hana@foobar.co.jp
<CR>
adding new entry "uid=hana, ou=People, o=FOOBAR, c=JP"
 
dn: uid=jack, ou=People, o=FOOBAR, c=JP
objectclass: account
objectclass: posixAccount
objectclass: top
cn: Jack Beans
uidnumber: 1232
gidnumber: 100
homedirectory: /home/jack
loginshell: /bin/bash
gecos: Jack Beans
mail: jack@foobar.co.jp
<CR>
adding new entry "uid=jack, ou=People, o=FOOBAR, c=JP"
^D
root# 

登録したのでデータ検索してみます。

root#
root# ldapsearch -b "o=FOOBAR, c=JP" "(uidnumber=1232)"
version: 2
 
#
# filter: (uidnumber=1232)
# requesting: ALL
#
 
# jack, People, FOOBAR, JP
dn: uid=jack, ou=People, o=FOOBAR, c=JP
objectClass: account
objectClass: posixAccount
objectClass: top
cn: Jack Beans
uidNumber: 1232
gidNumber: 100
homeDirectory: /home/jack
loginShell: /bin/bash
gecos: Jack Beans
mail: jack@foobar.co.jp

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1
root# 

ブラウザーでも確認

ブラウザー(mozilla)でも確認できるかテストしてみます。しかし、これまで posixAccount で登録したので、すべての情報が見れるわけではありません。

mozilla の Address Book を開き、File メニューから『New -> LDAP Directory...』を選びます。

サーバー等の情報を入力すると、Address Book に登録されます。

Tools メニューの『Search Addresses...』で検索してみると

 

SDKも使ってみよう!

OpenLDAP には SDK も含まれています。その SDKには、C言語の API が用意されているので、それらを使って DLAPサーバーにアクセスするプログラムが作成できます。

#include <stdio.h>
#include <ldap.h>

#define LDAP_SERVER     "master.foobar.co.jp"
#define BASE_DN         "o=FOOBAR,c=JP"

main()
{
    LDAP        *ld;
    LDAPMessage *result;
    int          entries;

    // Initialize
    if ((ld = ldap_init(LDAP_SERVER, LDAP_PORT )) == NULL) {
        perror("ldap_init");
        exit(1);
    }
    if (ldap_simple_bind_s(ld, NULL, NULL) != LDAP_SUCCESS) {
        ldap_perror(ld, "ldap_simple_bind_s");
        ldap_unbind(ld);
        exit(1);
    }
    // Search Entry
    if (ldap_search_s(ld, BASE_DN, LDAP_SCOPE_SUBTREE,
        NULL, NULL, 0, &result) != LDAP_SUCCESS)
    {
        ldap_perror(ld, "ldap_search_s");
        ldap_unbind(ld);
        exit(1);
    }

    entries = ldap_count_entries(ld, result);
    printf("Found %d entries\n", entries);

    ldap_msgfree(result);
    ldap_unbind(ld);
}

コンパイルと実行: OpenLDAP SDKは、/usr/local/include, /usr/local/lib にインストールされています。これらを考慮してコンパイルしなければなりません。OpenLDAP SDKのライブラリ(/usr/local/lib/libldap.so,/usr/local/lib/liblber.so) をリンクし、SSLを有効にしたのでそのライブラリ(/usr/local/ssl/lib/libssl.a, /usr/local/ssl/lib/libcrypto.a) をリンク、Solaris の Socket ライブラリー(/usr/lib/libsocket.so, /usr/lib/libresolv.so) をリンクします。

  root# gcc -I/usr/local/include ldap_sample.c -o ldap_sample \
  > -L/usr/local/lib -L/usr/local/ssl/lib -R/usr/local/lib \
  > -lldap -llber -lssl -lcrypto -lsocket -lresolv
  root# 
  root# ./ldap_sample
  Found 5 entries
  root# 

ついでだから、JNDI もやってみましょう。JNDI は、すべて理解していないのでサンプルは結構いい加減です。

import javax.naming.*;
// import javax.naming.Context;
// import javax.naming.InitialContext;
// import javax.naming.NamingException;
// import javax.naming.NameAlreadyBoundException;
// import javax.naming.NamingEnumeration;
import javax.naming.directory.*;
import java.util.*;
// import java.util.Properties;
// import java.util.Enumeration;
 
public class TestLDAP {
    final static String ldapServerName = "master.foobar.co.jp";
    final static String rootdn = "cn=root,o=FOOBAR,c=JP";
    final static String rootpass = "secret";
    final static String rootContext = "o=FOOBAR,c=JP";
 
    public static void main(String[] args) {
        // set up environment to access the server
        Properties env = new Properties();
 
        env.put(Context.INITIAL_CONTEXT_FACTORY,
                "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL,
                "ldap://" + ldapServerName + "/" + rootContext);
        env.put(Context.SECURITY_PRINCIPAL, rootdn);
        env.put(Context.SECURITY_CREDENTIALS, rootpass);
 
        try {
            int i;
 
            // obtain initial directory context using the environment
            DirContext ctx = new InitialDirContext(env);
            SearchControls constraints = new SearchControls();
            // specify search constraints to search subtree
            constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
            NamingEnumeration results = ctx.search("", "(objectclass=*)", 
                                                   constraints);
            for (i=0; results.hasMore(); i++)
                results.next();
            System.out.println("Fond " + i + " entries");
        } catch (NameAlreadyBoundException nabe) {
            System.err.println("Value has already been bound!");
        } catch (Exception e) {
            System.err.println(e);
        }
    }
}

コンパイルと実行: JDKは、JNDI 等のクラスを別途インストールする手間が要らない Version 1.3 以降を使っています。

  root# javac TestLDAP.java
  root# java -classpath . TestLDAP
  Found 5 entries
  root# 

 

スキーマの設計をして本格利用

LDAP サーバーを立ち上げることができたので、後は、目的にあったディレクトリ・スキーマを構築してディレクトリーサービスを有効利用します。スキーマの解説は、本が出版できるぐらいなのでここでは触れません。

OpenLDAPには、標準で数多くのスキーマが用意されています。これらを、うまく組み合わせるだけでもいろいろなことができます。はじめからスキーマを設計するので はなく、既存のスキーマを改良したりして目的にあったディレクトリを構築してもよいかもしれません。これまでのインストールでは、/usr/local/etc/openldap/schema/ にスキーマが用意されています。

運用にはアクセス制御をすることも忘れてはいけません。

 

Copyright (C) 2002 Shin Motomiya, All Rights Reserved.