8. スキーマ指定

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

この章では、slapd(8) が使うシステムスキーマのうちソースコードの更新が必要となるものについての拡張方法については扱いません。システムスキーマにはすべての運用属性型、あるいは運用属性を(直接にしろ間接にしろ)必須またはオプションとするオブジェクトクラスが含まれます。

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

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

表8.1: 提供されるスキーマ指定
ファイル 説明
core.schema OpenLDAP core (必須)
cosine.schema Cosine and Internet X.500 (有用)
inetorgperson.schema InetOrgPerson (有用)
misc.schema Assorted (実験用)
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 の割り当てをうけたとすれば、次のようにツリーをブランチできます。

表8.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)が管理している民間企業 (Private Enterprise)階層の下の 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 スキーマ要素を識別するなどの目的に使えます。

この他に、OID 名前空間は(ANSI, BSI などの)国の機関から入手できます。

内輪の実検用であれば 1.1 配下の OID を利用できます。 OID 1.1 階層は利用されなくなった名前空間として登録されています。

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.1.0)。qdescrs は一つ以上の名前です。 woid は名前あるいは OID のどちらかで、オプションで長さ指定(例:{10})を付けられます。

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

        attributeType ( 2.5.4.41 NAME 'name'
                DESC 'name(s) associated with the object'
                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' )
                DESC 'common name(s) assciated with the object'
                SUP name )

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

一番目の属性 name は、シンタックスが directoryString (UTF-8 にエンコードされた Unicode 文字列)の値を保持します。シンタックスは OID で指定します(1.3.6.1.4.1.1466.115.121.1.15 は directoryString シンタックスを示します)。推奨する最大長として 32768 が指定されています。サーバはこの長さの値をサポートすべきですが、これより長い値もサポートできます。このフィールドは長さの制約を指定するものではないので、(slapd のようなサーバは)そのようなサイズ制限を課さずに無視します。さらに等価性と部分文字列の照合は英大小文字を区別しない規則を使います。次の二つの表にサポートされているシンタックスと照合規則のうちよく使われるものを示します。

表8.3: よく利用されるシンタックス
名前 OID 説明
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 表示可能な文字列

表8.4: よく利用される照合規則
名前 種別 説明
booleanMatch equality 真偽
octetStringMatch equality octet string
objectIdentiferMatch equality OID
distinguishedNameMatch equality DN
uniqueMemberMatch equality オプションで UID の付いた名前
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 でも collective でもありません。

以降の節で二つの例を示します。

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 )

この場合、シンタックスは画像のフォーマットを特定しません。この属性にアクセスするすべてのアプリケーションが値の処理について合意していることを前提にしています(妥当ではないかもしれませんが)。

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

もう一つの代替案は、画像を指し示す URI を保有する属性を用意することです。このような属性は labeledURI (RFC2079)を手本にするか、次のように単純にサブタイプしたものを使えます。

        attributetype ( 1.1.2.1.3 NAME 'myPhotoURI'
                DESC 'URI and optional label referring to a photo'
                SUP labeledURI )

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.1.0)、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 を許可属性とします。

8.2.6. OID マクロ

OID の管理と利用を容易にするために、slapd(8) はオブジェクト識別子 マクロをサポートします。objectIdentifier ディレクティブは、マクロ(名前)を OID と結びつけるために使います。OID は、前に定義されている OID マクロから派生させることもできます。slapd.conf(5) での構文は次のようになっています。

        objectIdentifier <name> { <oid> | <name>[:<suffix>] }

次の例では、OID マクロのセットを定義し、それをスキーマ要素の定義に使っているところを示しています。

        objectIdentifier myOID  1.1
        objectIdentifier mySNMP myOID:1
        objectIdentifier myLDAP myOID:2
        objectIdentifier myAttributeType        myLDAP:1
        objectIdentifier myObjectClass  myLDAP:2
        attributetype ( myAttributeType:3 NAME 'myPhotoURI'
                DESC 'URI and optional label referring to a photo'
                SUP labeledURI )
        objectclass ( myObjectClass:1 NAME 'myPhotoObject'
                DESC 'mixin myPhoto'
                AUXILIARY
                MAY myPhoto )