OpenLDAP 岁软 件发布了一组模式定义,您可以直接使用它们。每一组模式定义为可以被包含到您的 slapd.conf(5) 中的文件。(可以使用 include 指令)这些模式文件在正常情况下安装在 /usr/local/etc/openldap/schema 目录下。
Table 8.1: Provided Schema Specifications |
|
File |
Description |
core.schema |
OpenLDAP core (required) |
cosine.schema |
Cosine and Internet X.500 (useful) |
inetorgperson.schema |
InetOrgPerson (useful) |
misc.schema |
Assorted (experimental) |
nis.schema |
Network Information Services (FYI) |
openldap.schema |
OpenLDAP Project (experimental) |
要使用其中的任何模式文件,只需要在您的 slapd.conf(5) 文件中的全局定义 部分包含需要的文件。比如:
# 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/ )。
slapd(8) 中使 用的模式可以被扩展为支持其他的语法,匹配规则,属性类型和对象类。本章详细说明了如何使用 slapd 已经支持的语法和匹配规则来增加用户应用属性类型和对象属性类型。 slapd 也可以被扩展为支持其他的语法,匹 配规则和系统模式,但是,这需要某种程度的编程,因此,在此处不予讨论。
下面是定义一个新的模式的 5 个步骤:
¢ 获得对象标识;
¢ 选择一个名称前缀;
¢ 创建本地模式文件;
¢ 定义自定义属性类型;(如果必须)
¢ 定义自定义对象类。
每一个模式元素由一个全局唯一对象标识符( OID )标识。 OID 同时被用来标识其他的对象。他们通常可 以在 ASN.1 描 述的协议中找到。特别是,它们在简单网络管理协议( SNMP )中被广泛使用。因为 OID 是层次的,您的组织可以获得一个 OID ,并且在需要的时候对其进行分支扩展。比如,如果您的组织被赋予一个 OID1.1 ,您可以按照如下所示的方法扩展 树:
Table 8.2: Example OID hierarchy |
|
OID |
Assignment |
1.1 |
Organization's OID |
1.1.1 |
SNMP Elements |
1.1.2 |
LDAP Elements |
1.1.2.1 |
AttributeTypes |
1.1.2.1.1 |
myAttribute |
1.1.2.2 |
ObjectClasses |
1.1.2.2.1 |
myObjectClass |
您当然可以在您的组织的 OID 下面自由的根据组织的需要设计您的层次结构。无论您选择了怎样的层次,您应该保持一份分配注册表。 这可以是一个简单的平面文件或者是一个更加复杂的东西,比如, OpenLDAP OID Registry ( http://www.openldap.org/faq/index.cgi?file=197 )。
有关对象标识符(和一个服务列表)的更多信息,请参阅:
http://www.alvestrand.no/harald/objectid/ 。
任何情况 下,您都不应该使用一个伪 造的 OID!
为了免费得到一个注册过的 OID ,在 Internet Assigned Numbers Authority 维护的 Private Enterprise arch 下申请一个 OID 。任何私人企业或者组织可以申请一个在 此 arch 下的 OID 。只需要填写一个位于 http://www.iana.org/cgi-bin/enterprise.pl 的 IANA 表单就可以了。您的合法 OID 将在几天内发送给您。您的基 ID 将是类似于 1.3.6.1.4.1.X ,其中 X 是一个整数。
注意:不要让 IANA 页面上的“ MIB/SNMP ”声明混淆您的视线。从这 个表单中申请的 OID 可以用于任何用途,包括标识 LDAP 模式元素。
除了给每一个模式元素分配一个唯一的对象标识符,您应该给每一个模式元素提供 一个文本名称。该名称应该是既有描述性,又不会和其他的模式名称冲突。特别的,任何您选择的名称都不应该和已经有的或者是将要使用的标准名称冲突。
为了减少(但不是消除)潜在的名称冲突,一个简便的方法是在非标准名称前增加 几个字母的前缀,来将组织的改变本地化。组织名称越短,就应该提供越长的前缀。
在下面的示例中,我们选择了一个很短的前缀“ my ”来减少空间。在一个大型的,全球性的组 织中,使用这样短的前缀是不合适的。对于一个小的,本地的公司,我们推荐象“ deFirm ”(德国公司)或者“ comExample ”(和 example.com 关联的组织的元素)。
配置文件指令中的 objectClass 和 attibuteTypes 可以被用来定义目录中的模式规则。习惯上创建一个文件来包含对于定制的模式元素的定义。我们推荐您 在目录 /usr/local/etc/openldap/schema/local.schema 中创建一个 local.schema 文件,然后,在您的 slapd.conf(5) 文件中的其他模式包含指令之后包含该文件。
# 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
指令 attributetype 被用来定义一个新的属性类型。该指令和在子模式子树中的 attributeTypes 属性使用相同的 属性类型描述(如 RFC2252 所定义)。比如:
attributetype <RFC2252 Attribute Type Description>
其中, Attribute Type Description 按照如下 BNF 定义:
AttributeTypeDescription = "(" whsp
numericoid whsp ; AttributeType identifier
[ "NAME" qdescrs ] ; name used in AttributeType
[ "DESC" qdstring ] ; description
[ "OBSOLETE" whsp ]
[ "SUP" woid ] ; derived from this other
; AttributeType
[ "EQUALITY" woid ; Matching Rule name
[ "ORDERING" woid ; Matching Rule name
[ "SUBSTR" woid ] ; Matching Rule name
[ "SYNTAX" whsp noidlen whsp ] ; Syntax OID
[ "SINGLE-VALUE" whsp ] ; default multi-valued
[ "COLLECTIVE" whsp ] ; default not collective
[ "NO-USER-MODIFICATION" whsp ]; default user modifiable
[ "USAGE" whsp AttributeUsage ]; default userApplications
whsp ")"
AttributeUsage =
"userApplications" /
"directoryOperation" /
"distributedOperation" / ; DSA-shared
"dSAOperation" ; DSA-specific, value depends on server
其中, whsp 是一个空格, numericoid 是一个全局唯一的点分十进制格式的 OID (例如: 1.1.0 ), qdescrs 是一个或者多个名称, woid 或者是 OID 的名称,或者是 OID 后面加上可选的长度说明(比如: {10} )。
例如,属性类型 name 和 cn 在 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) 在返回结果的时候,将返回第 1 个列出的名称。
第 1 个名称, name ,保存了 directoryString ( UTF-8 编码的 Unicode )语法。该语法由 OID 说明。( 1.3.6.1.4.1.1466.115.121.1.15 标识了目录字符串语法)。还说明了一个推荐长度为 32768 的选项。服务器应该支持该长度的 值,但是,也可以支持更长的值。该域没有指明长度限制,因此,在服务器上被忽略,并且服务器不会限制其大小。另外,相等和子串匹配使用不区分大小写的规 则。下面是经常使用的语法和匹配规则( OpenLDAP 支持这些,以及更多)
Table 8.3: Commonly Used Syntaxes |
||
Name |
OID |
Description |
boolean |
1.3.6.1.4.1.1466.115.121.1.7 |
boolean value |
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 string |
IA5String |
1.3.6.1.4.1.1466.115.121.1.26 |
ASCII string |
Integer |
1.3.6.1.4.1.1466.115.121.1.27 |
integer |
Name and Optional UID |
1.3.6.1.4.1.1466.115.121.1.34 |
DN plus UID |
Numeric String |
1.3.6.1.4.1.1466.115.121.1.36 |
numeric string |
OID |
1.3.6.1.4.1.1466.115.121.1.38 |
object identifier |
Octet String |
1.3.6.1.4.1.1466.115.121.1.40 |
arbitary octets |
Printable String |
1.3.6.1.4.1.1466.115.121.1.44 |
printable string |
Table 8.4: Commonly Used Matching Rules |
||
Name |
Type |
Description |
booleanMatch |
equality |
boolean |
octetStringMatch |
equality |
octet string |
objectIdentiferMatch |
equality |
OID |
distinguishedNameMatch |
equality |
DN |
uniqueMemberMatch |
equality |
Name with optional UID |
numericStringMatch |
equality |
numerical |
numericStringOrderingMatch |
ordering |
numerical |
numericStringSubstringsMatch |
substrings |
numerical |
caseIgnoreMatch |
equality |
case insensitive, space insensitive |
caseIgnoreOrderingMatch |
ordering |
case insensitive, space insensitive |
caseIgnoreSubstringsMatch |
substrings |
case insensitive, space insensitive |
caseExactMatch |
equality |
case sensitive, space insensitive |
caseExactOrderingMatch |
ordering |
case sensitive, space insensitive |
caseExactSubstringsMatch |
substrings |
case sensitive, space insensitive |
caseIgnoreIA5Match |
equality |
case insensitive, space insensitive |
caseIgnoreIA5OrderingMatch |
ordering |
case insensitive, space insensitive |
caseIgnoreIA5SubstringsMatch |
substrings |
case insensitive, space insensitive |
caseExactIA5Match |
equality |
case sensitive, space insensitive |
caseExactIA5OrderingMatch |
ordering |
case sensitive, space insensitive |
caseExactIA5SubstringsMatch |
substrings |
case sensitive, space insensitive |
第 2 个属性, cn ,是 name 的一个子类型,因此,它继承了语法,匹配规则,并且使用 name.commonName 作为别名。
两个属性都没有限制到单一值。都可以被用户应用程序所使用,都不存在过期,都 不是集合。
下面的部分给出了几个示例。
许多组织为每个用户维护了一个单一的唯一名称。虽然可以使用 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 )
许多组织包含了每一个用户的照片。可以定义一个 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 )
objectclasses 指令用来定义一个新的对象类。该指令和在子模式子树中的 objectClasses 属性使用相同的属性类型描述(如 RFC2252 所定义)。比如:
objectclass <RFC2252 Object Class Description>
其中, Object Class Description 按照如下所示的 BNF 定义:
ObjectClassDescription = "(" whsp
numericoid whsp ; ObjectClass identifier
[ "NAME" qdescrs ]
[ "DESC" qdstring ]
[ "OBSOLETE" whsp ]
[ "SUP" oids ] ; Superior ObjectClasses
[ ( "ABSTRACT" / "STRUCTURAL" / "AUXILIARY" ) whsp ]
; default structural
[ "MUST" oids ] ; AttributeTypes
[ "MAY" oids ] ; AttributeTypes
whsp ")"
其中, whsp 是一个空格, numericoid 是一个全局唯一的点分十进制格式的 OID (例如: 1.1.0 ), qdescrs 是一个或者多个名称, oids 是一个或者多个 OID 的名称。
下面定义一个允许将 myPhoto 增加到任何已经存在的条目中的 auxiliary 对象类:
objectclass ( 1.1.2.2.1 NAME 'myPhotoObject'
DESC 'mixin myPhoto'
AUXILIARY
MAY myPhoto )
如果您的组织需要一个私有的结构化对象类来表示用户,你可以子类化任何一个已 经存在的 person 类,比如 inetOrgPerson(RFC2798 ) ,然后增加需要的属性:
objectclass ( 1.1.2.2.2 NAME 'myPerson'
DESC 'my person'
SUP inetOrgPerson
MUST ( 'myUniqueName' $ 'givenName' )
MAY 'myPhoto' )
该对象类从 inetOrgPerson 中继承允许的或者必须的属性,但是,要求 myUniqueName 和 givenName ,允许 myPhoto 。
为了简化 OID 的管理和使用, slapd(8) 支持对象描述宏。 objectIdentifier 用来将一个宏名连接到一个 OID 。 OID 可以是从一个先前已经定义的 OID 宏中派生的。 slapd.conf(5) 的语法是:
objectIdentifier <name> { <oid> | <name>[:<suffix>] }
下面显示了定义一组 OID 宏,并且在定义模式元素中使用它们:
objectIdentifier myOID 1.1
objectIdentifier mySNMP myOrgOID:1
objectIdentifier myLDAP myOrgOID:2
objectIdentifier myAttributeType myOrgLDAP:1
objectIdentifier myObjectClass myOrgLDAP: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 )