# $OpenLDAP$
-# Copyright 1999-2000, The OpenLDAP Foundation, All Rights Reserved.
+# Copyright 1999-2012 The OpenLDAP Foundation, All Rights Reserved.
# COPYING RESTRICTIONS APPLY, see COPYRIGHT.
H1: Schema Specification
-This chapter describes how to extend the user schema used by {{slapd}}(8).
+This chapter describes how to extend the user schema used by
+{{slapd}}(8). The chapter assumes the reader is familiar with the
+{{TERM:LDAP}}/{{TERM:X.500}} information model.
+
The first section, {{SECT:Distributed Schema Files}} details optional
schema definitions provided in the distribution and where to obtain
other definitions.
H2: Distributed Schema Files
-OpenLDAP is distributed with a set of schema specifications for
+OpenLDAP Software is distributed with a set of schema specifications for
your use. Each set is defined in a file suitable for inclusion
(using the {{EX:include}} directive) in your {{slapd.conf}}(5)
file. These schema files are normally installed in the
> include /usr/local/etc/openldap/schema/inetorgperson.schema
Additional files may be available. Please consult the OpenLDAP
-FAQ ({{URL:http://www.openldap.org/faq/}}).
+{{TERM:FAQ}} ({{URL:http://www.openldap.org/faq/}}).
Note: You should not modify any of the schema items defined
in provided files.
and hence is not discussed here.
There are five steps to defining new schema:
-^ obtain Object Identifer
+^ obtain Object Identifier
+ choose a name prefix
+ create local schema file
+ define custom attribute types (if necessary)
H3: Object Identifiers
-Each schema element is identified by a globally unique
-{{TERM[expand]OID}} (OID). OIDs are also used to identify
-other objects.
-They are commonly found in protocols described by {{TERM:ASN.1}}. In
+Each schema element is identified by a globally unique {{TERM[expand]OID}}
+(OID). OIDs are also used to identify other objects. They are
+commonly found in protocols described by {{TERM:ASN.1}}. In
particular, they are heavily used by the {{TERM[expand]SNMP}} (SNMP).
-As OIDs are hierarchical, your organization
-can obtain one OID and branch it as needed. For example,
-if your organization were assigned OID {{EX:1.1}}, you could branch
-the tree as follows:
+As OIDs are hierarchical, your organization can obtain one OID and
+branch it as needed. For example, if your organization were assigned
+OID {{EX:1.1}}, you could branch the tree as follows:
!block table; colaligns="LR"; coltags="EX,N"; align=Center; \
title="Table 8.2: Example OID hierarchy"
1.1.1 SNMP Elements
1.1.2 LDAP Elements
1.1.2.1 AttributeTypes
-1.1.2.1.1 myAttribute
+1.1.2.1.1 x-my-Attribute
1.1.2.2 ObjectClasses
-1.1.2.2.1 myObjectClass
+1.1.2.2.1 x-my-ObjectClass
!endblock
You are, of course, free to design a hierarchy suitable to your
-organizational needs under your organization's OID. No matter what
-hierarchy you choose, you should maintain a registry of assignments
-you make. This can be a simple flat file or something more
-sophisticated such as the {{OpenLDAP OID Registry}}
-({{URL:http://www.openldap.org/faq/index.cgi?file=197}}).
+organizational needs under your organization's OID. No matter what hierarchy you choose, you should maintain a registry of assignments you make. This can be a simple flat file or something more sophisticated such as the {{OpenLDAP OID Registry}} ({{URL:http://www.openldap.org/faq/index.cgi?file=197}}).
-For more information about Object Identifers (and a listing service)
-see {{URL:http://www.alvestrand.no/harald/objectid/}}.
+For more information about Object Identifiers (and a listing service)
+see {{URL:http://www.alvestrand.no/objectid/}}.
.{{Under no circumstances should you hijack OID namespace!}}
-To obtain a registered OID at {{no cost}}, apply for an OID under
-the {{ORG[expand]IANA}} (IANA) maintained {{Private Enterprise}}
-arc. Any private enterprise (organization) may request an OID to
-be assigned under this arc. Just fill out the {{ORG:IANA}} form
-at {{URL: http://www.iana.org/cgi-bin/enterprise.pl}} and your
-official OID will be sent to you usually within a few days. Your
-base OID will be something like {{EX:1.3.6.1.4.1.X}} where {{EX:X}}
-is an integer.
-
-Note: Don't let the "MIB/SNMP" statement on the IANA page confuse
-you. OIDs obtained using this form may be used for any purpose
+To obtain a registered OID at {{no cost}}, apply for a OID
+under the {{ORG[expand]IANA}} (ORG:IANA) maintained {{Private Enterprise}} arc.
+Any private enterprise (organization) may request a {{TERM[expand]PEN}} (PEN) to be assigned under this arc. Just fill out the IANA form at {{URL: http://pen.iana.org/pen/PenApplication.page}} and your official PEN will be sent to you usually within a few days. Your base OID will be something like {{EX:1.3.6.1.4.1.X}} where {{EX:X}} is an integer.
+
+Note: PENs obtained using this form may be used for any purpose
including identifying LDAP schema elements.
Alternatively, OID name space may be available from a national
-authority (e.g., ANSI, BSI).
+authority (e.g., {{ORG:ANSI}}, {{ORG:BSI}}).
-For private experiments, OIDs under {{EX:1.1}} may be used. The
-OID {{EX:1.1}} arc is regarded as dead name space.
-
-H3: Name Prefix
+H3: Naming Elements
In addition to assigning a unique object identifier to each schema
-element, you should provide a least one textual name for each
-element. The name should be both descriptive and not likely to
-clash with names of other schema elements. In particular, any name
-you choose should not clash with present or future Standard Track
-names.
+element, you should provide at least one textual name for each
+element. Names should be registered with the {{ORG:IANA}} or
+prefixed with "x-" to place in the "private use" name space.
+
+The name should be both descriptive and not likely to clash with
+names of other schema elements. In particular, any name you choose
+should not clash with present or future Standard Track names (this
+is assured if you registered names or use names beginning with "x-").
-To reduce (but not eliminate) the potential for name clashes, the
-convention is to prefix names of non-Standard Track with a few
-letters to localize the changes to your organization. The smaller
-the organization, the longer your prefix should be.
+It is noted that you can obtain your own registered name
+prefix so as to avoid having to register your names individually.
+See {{REF:RFC4520}} for details.
-In the examples below, we have chosen a short prefix '{{EX:my}}'
-(to save space). Such a short prefix would only be suitable for a
-very large, global organization. In general, we recommend something
-like '{{EX:deFirm}}' (German company) or '{{EX:comExample}}' (elements
-associated with organization associated with {{EX:example.com}}).
+In the examples below, we have used a short prefix '{{EX:x-my-}}'.
+Such a short prefix would only be suitable for a very large, global
+organization. In general, we recommend something like '{{EX:x-de-Firm-}}'
+(German company) or '{{EX:x-com-Example}}' (elements associated with
+organization associated with {{EX:example.com}}).
H3: Local schema file
The {{attributetype}} directive is used to define a new attribute
type. The directive uses the same Attribute Type Description
-(as defined in {{REF:RFC2252}}) used by the attributeTypes
+(as defined in {{REF:RFC4512}}) used by the attributeTypes
attribute found in the subschema subentry, e.g.:
-E: attributetype <{{REF:RFC2252}} Attribute Type Description>
+E: attributetype <{{REF:RFC4512}} Attribute Type Description>
where Attribute Type Description is defined by the following
-{{TERM:BNF}}:
+{{TERM:ABNF}}:
> AttributeTypeDescription = "(" whsp
> numericoid whsp ; AttributeType identifier
> 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' )
+> attributeType ( 2.5.4.3 NAME ( 'cn' 'commonName' )
> DESC 'common name(s) assciated with the object'
> SUP name )
{{slapd}}(8) returns the first listed name when returning results.
The first attribute, {{EX:name}}, holds values of {{EX:directoryString}}
-(UTF-8 encoded Unicode) syntax. The syntax is specified by OID
-(1.3.6.1.4.1.1466.115.121.1.15 identifies the directoryString
-syntax). A length recommendation of 32768 is specified. Servers
-should support values of this length, but may support longer values
-The field does NOT specify a size constraint, so is ignored on
-servers (such as slapd) which don't impose such size limits. In
-addition, the equality and substring matching uses case ignore
-rules. Below are tables listing commonly used syntax and
-matching rules (OpenLDAP supports these and many more).
+({{TERM:UTF-8}} encoded Unicode) syntax. The syntax is
+specified by OID (1.3.6.1.4.1.1466.115.121.1.15 identifies the
+directoryString syntax). A length recommendation of 32768 is
+specified. Servers should support values of this length, but may
+support longer values. The field does NOT specify a size constraint,
+so is ignored on servers (such as slapd) which don't impose such
+size limits. In addition, the equality and substring matching uses
+case ignore rules. Below are tables listing commonly used syntax
+and matching rules ({{slapd}}(8) supports these and many more).
!block table; align=Center; coltags="EX,EX,N"; \
title="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
+directoryString 1.3.6.1.4.1.1466.115.121.1.15 Unicode (UTF-8) string
+distinguishedName 1.3.6.1.4.1.1466.115.121.1.12 LDAP {{TERM:DN}}
+integer 1.3.6.1.4.1.1466.115.121.1.27 integer
+numericString 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
+octetString 1.3.6.1.4.1.1466.115.121.1.40 arbitrary octets
!endblock
>
!block table; align=Center; coltags="EX,N"; \
title="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
+Name Type Description
+booleanMatch equality boolean
+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
+distinguishedNameMatch equality distinguished name
+integerMatch equality integer
+integerOrderingMatch ordering integer
+numericStringMatch equality numerical
+numericStringOrderingMatch ordering numerical
+numericStringSubstringsMatch substrings numerical
+octetStringMatch equality octet string
+octetStringOrderingMatch ordering octet string
+octetStringSubstringsMatch ordering octet string
+objectIdentiferMatch equality object identifier
!endblock
The second attribute, {{EX:cn}}, is a subtype of {{EX:name}} hence
The following subsections provide a couple of examples.
-H4: myUniqueName
+H4: x-my-UniqueName
Many organizations maintain a single unique name for each user.
Though one could use {{EX:displayName}} ({{REF:RFC2798}}), this
from {{F:inetorgperson.schema}} and replace the OID, name, and
description, e.g:
-> attributetype ( 1.1.2.1.1 NAME 'myUniqueName'
+> attributetype ( 1.1.2.1.1 NAME 'x-my-UniqueName'
> DESC 'unique name with my organization'
> EQUALITY caseIgnoreMatch
> SUBSTR caseIgnoreSubstringsMatch
> SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
> SINGLE-VALUE )
-However, if we want this name to be included in
-{{EX:name}} assertions [e.g. {{EX:(name=*Jane*)}}], the attribute
-could alternatively be defined as a subtype of {{EX:name}}, e.g.:
+However, if we want this name to be used in {{EX:name}} assertions,
+e.g. {{EX:(name=*Jane*)}}, the attribute could alternatively be
+defined as a subtype of {{EX:name}}, e.g.:
-> attributetype ( 1.1.2.1.1 NAME 'myUniqueName'
+> attributetype ( 1.1.2.1.1 NAME 'x-my-UniqueName'
> DESC 'unique name with my organization'
> SUP name )
-H4: myPhoto
+H4: x-my-Photo
Many organizations maintain a photo of each each user. A
-{{EX:myPhoto}} attribute type could be defined to hold a photo.
+{{EX:x-my-Photo}} attribute type could be defined to hold a photo.
Of course, one could use just use {{EX:jpegPhoto}} ({{REF:RFC2798}})
(or a subtype) to hold the photo. However, you can only do
this if the photo is in {{JPEG File Interchange Format}}.
Alternatively, an attribute type which uses the {{Octet String}}
syntax can be defined, e.g.:
-> attributetype ( 1.1.2.1.2 NAME 'myPhoto'
+> attributetype ( 1.1.2.1.2 NAME 'x-my-Photo'
> DESC 'a photo (application defined format)'
> SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
> SINGLE-VALUE )
{{EX:labeledURI}} ({{REF:RFC2079}}) or simply create a subtype,
e.g.:
-> attributetype ( 1.1.2.1.3 NAME 'myPhotoURI'
+> attributetype ( 1.1.2.1.3 NAME 'x-my-PhotoURI'
> DESC 'URI and optional label referring to a photo'
> SUP labeledURI )
The {{objectclasses}} directive is used to define a new object
class. The directive uses the same Object Class Description
-(as defined in {{REF:RFC2252}}) used by the objectClasses
+(as defined in {{REF:RFC4512}}) used by the objectClasses
attribute found in the subschema subentry, e.g.:
-E: objectclass <{{REF:RFC2252}} Object Class Description>
+E: objectclass <{{REF:RFC4512}} Object Class Description>
where Object Class Description is defined by the following
-{{TERM:BNF}}:
+{{TERM:ABNF}}:
> ObjectClassDescription = "(" whsp
> numericoid whsp ; ObjectClass identifier
> whsp ")"
where whsp is a space ('{{EX: }}'), numericoid is a globally unique
-OID in numeric form (e.g. {{EX:1.1.0}}), qdescrs is one or more
+OID in dotted-decimal form (e.g. {{EX:1.1.0}}), qdescrs is one or more
names, and oids is one or more names and/or OIDs.
-H4: myPhotoObject
+H4: x-my-PhotoObject
To define an {{auxiliary}} object class which allows
-myPhoto to be added to any existing entry.
+x-my-Photo to be added to any existing entry.
-> objectclass ( 1.1.2.2.1 NAME 'myPhotoObject'
-> DESC 'mixin myPhoto'
+> objectclass ( 1.1.2.2.1 NAME 'x-my-PhotoObject'
+> DESC 'mixin x-my-Photo'
> AUXILIARY
-> MAY myPhoto )
+> MAY x-my-Photo )
-H4: myPerson
+H4: x-my-Person
If your organization would like have a private {{structural}}
object class to instantiate users, you can subclass one of
({{REF:RFC2798}}), and add any additional attributes which
you desire.
-> objectclass ( 1.1.2.2.2 NAME 'myPerson'
+> objectclass ( 1.1.2.2.2 NAME 'x-my-Person'
> DESC 'my person'
> SUP inetOrgPerson
-> MUST ( myUniqueName $ givenName )
-> MAY myPhoto )
+> MUST ( x-my-UniqueName $ givenName )
+> MAY x-my-Photo )
The object class inherits the required/allowed attribute
-types of {{EX:inetOrgPerson}} but requires {{EX:myUniqueName}}
-and {{EX:givenName}} and allows {{EX:myPhoto}}.
+types of {{EX:inetOrgPerson}} but requires {{EX:x-my-UniqueName}}
+and {{EX:givenName}} and allows {{EX:x-my-Photo}}.
!if 0
H2: Transferring Schema
-Since the {{slapd.conf}}(5) schema directives use {{REF:RFC2252}}
-format values, you can extract schema elements published by
-any LDAPv3 server and easily construct directives for use with
+Since the {{slapd.conf}}(5) schema directives use {{REF:RFC4512}}
+format values, you can extract schema elements published by any
+{{TERM:LDAPv3}} server and easily construct directives for use with
{{slapd}}(8).
LDAPv3 servers publish schema elements in special {{subschema}}
pairs. The following is an abbreviated example:
> dn: cn=Subschema
-> objectClasses: ( 1.1.2.2.2 NAME 'myPerson' DESC 'my person' SUP inet
-> OrgPerson MUST ( myUniqueName $ givenName ) MAY myPhoto )
-> attributeTypes: ( 1.1.2.1.1 NAME 'myUniqueName' DESC 'unique name wi
-> th my organization' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubst
-> ringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
-> attributeTypes: ( 1.1.2.1.2 NAME 'myPhoto' DESC 'a photo (applicatio
+> objectClasses: ( 1.1.2.2.2 NAME 'x-my-Person' DESC 'my person' SUP inet
+> OrgPerson MUST ( x-my-UniqueName $ givenName ) MAY x-my-Photo )
+> attributeTypes: ( 1.1.2.1.1 NAME 'x-my-UniqueName' DESC 'unique name wi
+> th my organization' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstrin
+> gsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
+> attributeTypes: ( 1.1.2.1.2 NAME 'x-my-Photo' DESC 'a photo (applicatio
> n defined format)' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
Capture the output of the search in a file and then edit the file:
For the three type/value pairs in our example, the edit should
result in a file with contains of:
-> attributetype ( 1.1.2.1.1 NAME 'myUniqueName'
+> attributetype ( 1.1.2.1.1 NAME 'x-my-UniqueName'
> DESC 'unique name with my organization'
> EQUALITY caseIgnoreMatch
> SUBSTR caseIgnoreSubstringsMatch
> SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
> SINGLE-VALUE )
-> attributeType ( 1.1.2.1.2 NAME 'myPhoto'
+> attributeType ( 1.1.2.1.2 NAME 'x-my-Photo'
> DESC 'a photo (application defined format)'
> SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
-> objectClass ( 1.1.2.2.2 NAME 'myPerson'
+> objectClass ( 1.1.2.2.2 NAME 'x-my-Person'
> DESC 'my person'
> SUP inetOrgPerson
-> MUST ( myUniqueName $ givenName )
-> MAY myPhoto )
+> MUST ( x-my-UniqueName $ givenName )
+> MAY x-my-Photo )
Save in an appropriately named file (e.g. {{F:local.schema}}).
You may now include this file in your {{slapd.conf}}(5) file.
> objectIdentifier myLDAP myOID:2
> objectIdentifier myAttributeType myLDAP:1
> objectIdentifier myObjectClass myLDAP:2
-> attributetype ( myAttributeType:3 NAME 'myPhotoURI'
+> attributetype ( myAttributeType:3 NAME 'x-my-PhotoURI'
> DESC 'URI and optional label referring to a photo'
> SUP labeledURI )
-> objectclass ( myObjectClass:1 NAME 'myPhotoObject'
-> DESC 'mixin myPhoto'
+> objectclass ( myObjectClass:1 NAME 'x-my-PhotoObject'
+> DESC 'mixin x-my-Photo'
> AUXILIARY
-> MAY myPhoto )
+> MAY x-my-Photo )