8. スキーマ指定

この章では slapd(8) が使うスキーマの拡張方法について説明します。 最初の節の配布物に含まれるスキーマファイルでは、配布物に 提供されているスキーマ定義と他の定義を入手する場所について詳説します。 その次の節のスキーマの拡張では、新しいスキーマアイテムを 定義する方法について詳説します。

8.1. 配布物に含まれるスキーマファイル

OpenLDAP の配布物には、利用できるスキーマ指定のセットが付属しています。 個々のセットは、slapd.conf(5) ファイルに(include ディレクティブを使って)取り込むのに適したファイルに定義されています。 これらのスキーマファイルは、普通 /usr/local/etc/openldap/schema ディレクトリにインストールされます。

表6.1: 提供されるスキーマ指定
ファイル 説明
core.schema OpenLDAP core (必須)
cosine.schema Cosine and Internet X.500 (有用)
inetorgperson.schema InetOrgPerson (有用)
misc.schema Assorted (実験用)
nadf.schema North American Directory Forum (参考)
nis.schema Network Information Services (参考)
openldap.schema OpenLDAP Project (実験用)

これらのスキーマファイルを使うには、 slapd.conf(5) ファイルのグローバル定義部に望むファイルを include するだけです。たとえば次のように指定します。

        # include schema
        include /usr/local/etc/openldap/schema/core.schema
        include /usr/local/etc/openldap/schema/cosine.schema
        include /usr/local/etc/openldap/schema/inetorgperson.schema

追加のファイルも入手できます。OpenLDAP FAQ (http://www.openldap.org/faq/) を調べてみてください。


注記:提供されるファイルに定義されているスキーマ要素を 更新するべきではありません。

8.2. スキーマの拡張

slapd(8) で使うスキーマは、追加のシンタックス、照合規則、 属性型、オブジェクトクラスをサポートするよう拡張できます。 この節では、slapd で既にサポートされているシンタックスと照合規則を 使って属性型とオブジェクトクラスを追加する方法について詳説します。 slapd は追加のシンタックスや照合規則も拡張できますが、これには プログラミングが必要なので、ここでは取り上げません。

新しいスキーマを定義することには五つのステップがあります。

  1. オブジェクト識別子の取得
  2. 名前の接頭辞の選択
  3. ローカルなスキーマファイルの作成
  4. (必要なら)カスタム属性型の定義
  5. カスタムオブジェクトクラスの定義

8.2.1. オブジェクト識別子

各スキーマ要素は、全世界的に一意な オブジェクト識別子(Object Identifier - OID)で識別されます。 OID は他のオブジェクトを識別するのにも使われます。 これは、ASN.1 で述べられているプロトコルによく見られます。 特に、Simple Network Management Protocol (SNMP) では多用されています。 OID は階層的であるので、組織で OID を一つ取得すれば、 必要に応じてブランチしていけます。たとえば、ある組織は OID 1.1 の割り当てをうけたとすれば、次のようにツリーをブランチできます。

表6.2: OID 階層の例
OID 割り当て
1.1 組織の OID
1.1.1 SNMP 要素
1.1.2 LDAP 要素
1.1.2.1 属性型群
1.1.2.1.1 とある属性
1.1.2.2 オブジェクトクラス群
1.1.2.2.1 とあるオブジェクトクラス

もちろん組織の OID の配下には、その組織のニーズに合わせて 自由に階層を設計できます。どんな階層にするにしても、OID の 割り当ての登録を管理すべきです。これは単純でフラットなファイルで もできるでしょうし、OpenLDAP OID Registry (http://www.openldap.org/faq/index.cgi?file=197) のようなより高度なシステムで行うものもあります。

オブジェクト識別子についてのさらなる情報(とサービスの一覧)は http://www.alvestrand.no/harald/objectid/ を参照してください。

コストなしで完全に登録された OID を取得するには、 Internet Assigned Numbers Authority (IANA)が管理している民間企業の登録システムに OID を申し込んでください。どんな民間企業(組織)でもこの登録システムで OID の割り当てを申し込めます。 IANA のフォーム(http://www.iana.org/cgi-bin/enterprise.pl) に必要事項を記入するだけで、たいていは数日中に OID が送られてきます。 送られてくるベース OID は 1.3.6.1.4.1.X (X は整数) のようなものでしょう。


注記:IANA のページにある "MIB/SNMP" の文に当惑することはありません。 このフォームを使って取得した OID は、LDAP スキーマ要素を識別するなどの 目的に使えます。

8.2.2. 名前の接頭辞

個々のスキーマ要素に一意なオブジェクト識別子を割り当てることに 加えて、個々のスキーマ要素に少なくとも一つの名前をつけなければ なりません。この名前は記述的で他のスキーマ要素群とぶつかりそうも ないものにすべきです。特に、現在あるいは将来に標準化される名前と ぶつからないようにしてください。

名前がぶつかる可能性を抑えるために(完全には無くせないのですが)、 数文字の標準化されていない接頭辞を名前につけて、変更を組織内に 局所化する慣習があります。小さな組織であるほど、接頭辞をより長く すべきです。

後述の例では接頭辞に短い 'my' を使っています(スペースの節約のため)。 そのような短い接頭辞は、巨大でグローバルな組織でのみふさわしいものでしょう。 小規模でローカルな組織であれば、'deFirm' (ドイツ企業)や 'comExample' (ドメインが example.com である組織に関する要素) などといったものにすることを勧めます。

8.2.3. ローカルスキーマファイル

設定ファイルのディレクティブである objectclassattributeTypes は、ディレクトリ中のエントリについての スキーマ規則を定義するのに使えます。慣例では、カスタム化した スキーマ要素の定義を記述したファイルを作成します。 お勧めは /usr/local/etc/openldap/schema/local.schema のファイル local.schema を作成して、slapd.conf(5) で 他のスキーマを include ディレクティブで取り込んでいる直後に このファイルを取り込むことです。

        # include schema
        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 local schema
        include /usr/local/etc/openldap/schema/local.schema

8.2.4. 属性型の指定

attributetype ディレクティブは、新しい属性型を定義するのに 使います。このディレクティブでは、subschema subentry にある attributeTypes 属性で使われているのと同じ属性型記述(RFC2252 に定義)を使います。このディレクティブの形式を次に示します。

        attributetype <RFC2252 属性型記述>

ここの属性型記述は BNF で次のように定義されます。

      AttributeTypeDescription = "(" whsp
            numericoid whsp              ; 属性型のオブジェクト識別子
          [ "NAME" qdescrs ]             ; 属性型で使われる名前
          [ "DESC" qdstring ]            ; 説明
          [ "OBSOLETE" whsp ]
          [ "SUP" woid ]                 ; 派生元の属性型
          [ "EQUALITY" woid              ; 照合規則の名前
          [ "ORDERING" woid              ; 照合規則の名前
          [ "SUBSTR" woid ]              ; 照合規則の名前
          [ "SYNTAX" whsp noidlen whsp ] ; シンタックスの OID および長さ指定
          [ "SINGLE-VALUE" whsp ]        ; デフォルトでは複数値が可
          [ "COLLECTIVE" whsp ]          ; デフォルトでは集合的でない
          [ "NO-USER-MODIFICATION" whsp ]; デフォルトではユーザ更新が可
          [ "USAGE" whsp AttributeUsage ]; デフォルトは userApplications
          whsp ")"

      AttributeUsage =
          "userApplications"     /
          "directoryOperation"   /
          "distributedOperation" / ; DSA 共有
          "dSAOperation"          ; DSA 固有、値はサーバによる

ここで whsp はスペース(' ')、numericoid は グローバルに一意な OID で、ドットで連結した数値の形式で表します (例:1.2.3)。qdescrs は一つ以上の名前です。 woid は名前あるいは OID のどちらかです。noidlen はオプションで長さ 指定(例:{10})を付けられる数値形式の OID を示します。

たとえば属性型 namecn は、core.schema で次のように定義されています。

        attributeType ( 2.5.4.41 NAME 'name'
                EQUALITY caseIgnoreMatch
                SUBSTR caseIgnoreSubstringsMatch
                SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
        attributeType ( 2.5.4.3 NAME
                ( 'cn' $ 'commonName' ) SUP name )

それぞれが属性の OID と記述的な名前を定義していることに注目してください。 それぞれの名前は OID の別名です。slapd(8) は結果を返すときに、 定義に並べられている名前のうち最初のものを返します。

一番目の属性 name は、シンタックスが directoryString (UTF-8 にエンコードされた Unicode 文字列)で、推奨される最大長があります。 シンタックスは OID で指定することに注意してください。 さらに等価性と部分文字列の照合は英大小文字を区別しない規則を使います。 次の二つの表にサポートされているシンタックスと照合規則のうちよく使われる ものを示します。

表6.3: サポートされているシンタックス
名前 OID 説明
binary 1.3.6.1.4.1.1466.115.121.1.5 BER/DER データ
boolean 1.3.6.1.4.1.1466.115.121.1.7 真偽値
distinguishedName 1.3.6.1.4.1.1466.115.121.1.12 DN
directoryString 1.3.6.1.4.1.1466.115.121.1.15 UTF-8 文字列
IA5String 1.3.6.1.4.1.1466.115.121.1.26 ASCII 文字列
Integer 1.3.6.1.4.1.1466.115.121.1.27 整数
Name and Optional UID 1.3.6.1.4.1.1466.115.121.1.34 DN および UID
Numeric String 1.3.6.1.4.1.1466.115.121.1.36 数値文字列
OID 1.3.6.1.4.1.1466.115.121.1.38 オブジェクト識別子
Octet String 1.3.6.1.4.1.1466.115.121.1.40 任意のオクテット文字列
Printable String 1.3.6.1.4.1.1466.115.121.1.44 表示可能な文字列

表6.4: サポートされている照合規則
名前 種別 説明
booleanMatch equality 真偽
objectIdentiferMatch equality OID
distinguishedNameMatch equality DN
uniqueMemberMatch equality UID の付いた DN
numericStringMatch equality numerical
numericStringOrderingMatch ordering numerical
numericStringSubstringsMatch substrings numerical
caseIgnoreMatch equality 英大小文字の区別なし、スペース無視
caseIgnoreOrderingMatch ordering 英大小文字の区別なし、スペース無視
caseIgnoreSubstringsMatch substrings 英大小文字の区別なし、スペース無視
caseExactMatch equality 英大小文字の区別あり、スペース無視
caseExactOrderingMatch ordering 英大小文字の区別あり、スペース無視
caseExactSubstringsMatch substrings 英大小文字の区別あり、スペース無視
caseIgnoreIA5Match equality 英大小文字の区別なし、スペース無視
caseIgnoreIA5OrderingMatch ordering 英大小文字の区別なし、スペース無視
caseIgnoreIA5SubstringsMatch substrings 英大小文字の区別なし、スペース無視
caseExactIA5Match equality 英大小文字の区別あり、スペース無視
caseExactIA5OrderingMatch ordering 英大小文字の区別あり、スペース無視
caseExactIA5SubstringsMatch substrings 英大小文字の区別あり、スペース無視

二番目の属性 cnname のサブタイプで、 name のシンタクス、照合規則、用途を継承しています。 commonName は代替名です。

どちらの属性も複数の値を持つことができ、ユーザアプリケーションで 使われることが意図されています。おそらく OBSOLETE のような その他のパラメータを指定する必要はないでしょう。

以降の節で一組の例を示します。

8.2.4.1. myUniqueName

多くの組織は各ユーザについて一つの一意な名前を管理しています。 この目的には displayName (RFC2798)を使えますが、 この属性は組織ではなくユーザが制御するように意図されているので、 そこで、inetorgperson.schema から displayName の定義をコピーしてきて、次のように OID, name, description を書き換えてみます。

        attributetype ( 1.1.2.1.1 NAME 'myUniqueName'
                DESC 'unique name with my organization'
                EQUALITY caseIgnoreMatch
                SUBSTR caseIgnoreSubstringsMatch
                SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
                SINGLE-VALUE )

しかし、属性型 name による照合に使えるように したければ[例: (name=*Jane*)]、次のように name のサブタイプとして定義することもできます。

        attributetype ( 1.1.2.1.1 NAME 'myUniqueName'
                DESC 'unique name with my organization'
                SUP name )

8.2.4.2. myPhoto

多くの組織は各ユーザについて画像を管理しています。 この画像を保持するために属性型 myPhoto を定義します。 もちろん jpegPhoto (RFC2798) (あるいはその サイブタイプ)を使ってもよいのですが、これを使えるのは 画像が JPEG ファイル交換フォーマットの場合だけです。 この代わりに次のような Octet String シンタックスを使った 属性型を定義します。

        attributetype ( 1.1.2.1.2 NAME 'myPhoto'
                DESC 'a photo (application defined format)'
                SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
                SINGLE-VALUE )

この説明で注意してほしいのですが、LDAP は画像のフォーマットが 何であるかを知りません。この属性にアクセスするすべての アプリケーションが値の処理について合意していることを前提 にしています。

複数の画像フォーマットをサポートしたければ、 各フォーマットのための属性型を個別に定義するか、画像に加えて 画像の種別を示す情報を持つようにするか、ASN.1 を使って値を記述して ;binary 転送オプションを使うと いったことができます。

もう一つの代替案は、画像を指し示す URI を保有する 属性を用意することです。このような属性は labeledURI (RFC2079)を基にして作成できます。

8.2.5. オブジェクトクラス指定

objectclasses ディレクティブは新しいオブジェクトクラスを定義するのに 使います。このディレクティブでは、subschema subentry にある objectClasses 属性で使われているのと同じオブジェクトクラス記述(RFC2252 に定義)を使います。このディレクティブの形式を次に示します。

        objectclass <RFC2252 オブジェクトクラス記述>

ここのオブジェクトクラス記述は BNF で次のように定義されます。

        ObjectClassDescription = "(" whsp
                numericoid whsp      ; オブジェクトクラスのオブジェクト識別子
                [ "NAME" qdescrs ]
                [ "DESC" qdstring ]
                [ "OBSOLETE" whsp ]
                [ "SUP" oids ]       ; 上位のオブジェクトクラス
                [ ( "ABSTRACT" / "STRUCTURAL" / "AUXILIARY" ) whsp ]
                        ; default structural
                [ "MUST" oids ]      ; 属性型
                [ "MAY" oids ]       ; 属性型
                whsp ")"

ここで whsp はスペース(' ')、numericoid はグローバルに一意な 数値形式の OID (例:1.2.3)、qdescrs は一つ以上の名前、 oids は一つ以上の名前あるいは OID です。

8.2.5.1. myPhotoObject

既存のエントリに myPhoto を追加できるように、補助型(auxiliary) のオブジェクトクラスを定義します。

        objectclass ( 1.1.2.2.1 NAME 'myPhotoObject'
                DESC 'mixin myPhoto'
                AUXILIARY
                MAY myPhoto )

8.2.5.2. myPerson

ユーザを格納する構造型オブジェクトクラスを組織に固有のものに したければ、inetOrgPerson (RFC2798)のような既存の 人のクラスのどれかのサブクラスを作り、欲しい属性を追加すれば よいです。

        objectclass ( 1.1.2.2.2 NAME 'myPerson'
                DESC 'my person'
                SUP inetOrgPerson
                MUST ( 'myUniqueName' $ 'givenName' )
                MAY 'myPhoto' )

このオブジェクトクラスは inetOrgPerson から必須/許可属性 を継承しますが、myUniqueNamegivenName を必須属性とし、myPhoto を許可属性とします。