# $OpenLDAP$ # Copyright 1999-2000, The OpenLDAP Foundation, All Rights Reserved. # COPYING RESTRICTIONS APPLY, see COPYRIGHT. H1: Schema Specification This chapter describes how to extend the schema used by {{slapd}}(8). The first section, {{SECT:Distributed Schema Files}} details optional schema definitions provided in the distribution and where to obtain other definitions. The second section, {{SECT:Extending Schema}}, details how to define new schema items. !if 0 The third section, {{SECT:Transferring Schema}} details how you can export schema definitions from an LDAPv3 server and transform it to {{slapd.conf}}(5) format. !endif H2: Distributed Schema Files OpenLDAP 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 {{F:/usr/local/etc/openldap/schema}} directory. !block table; colaligns="LR"; coltags="F,N"; align=Center; \ title="Table 6.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) nadf.schema North American Directory Forum (FYI) nis.schema Network Information Services (FYI) openldap.schema OpenLDAP Project (experimental) !endblock To use any of these schema files, you only need to include the the desired file in the global definitions portion of your {{slapd.conf}}(5) file. For example: > # 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 Additional files may be available. Please consult the OpenLDAP FAQ ({{URL:http://www.openldap.org/faq/}}). Note: You should not modify any of the schema items defined in provided files. H2: Extending Schema Schema used by {{slapd}}(8) may be extended to support additional syntaxes, matching rules, attribute types, and object classes. This chapter details how to add attribute types and object classes using the syntaxes and matching rules already supported by slapd. slapd can also be extended to support additional syntaxes and matching rules, but this requires some programming and hence is not discussed here. There are five steps to defining new schema: ^ obtain Object Identifer + choose a name prefix + create local schema file + define custom attribute types (if necessary) + define custom object classes 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 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: !block table; colaligns="LR"; coltags="EX,N"; align=Center; \ title="Table 6.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 !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 a 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/}}. .{{Under no circumstances should you use a fictious OID!}} To obtain a fully registered OID at {{no cost}}, apply for an OID under {{ORG[expand]IANA}} (IANA) maintained {{Private Enterprise}} arch. Any private enterprise (organization) may request an OID to be assigned under this arch. 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}} were {{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 including identifying LDAP schema elements. H3: Name Prefix 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. 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. In the examples below, we have choosen a short prefix '{{EX:my}}' (to save space). Such a short prefix would only be suitable for a very large, global organization. For a small, local organization, we recommend something like '{{EX:deFirm}}' (German company) or '{{EX:comExample}}' (elements associated with organization associated with {{EX:example.com}}). H3: Local schema file The {{EX:objectclass}} and {{EX:attributeTypes}} configuration file directives can be used to define schema rules on entries in the directory. It is customary to create a file to contain definitions of your custom schema items. We recommend you create a file {{F:local.schema}} in {{F:/usr/local/etc/openldap/schema/local.schema}} and then include this file in your {{slapd.conf}}(5) file immediately after other schema {{EX:include}} directives. > # 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 H3: Attribute Type Specification 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 attribute found in the subschema subentry, e.g.: E: attributetype <{{REF:RFC2252}} Attribute Type Description> where Attribute Type Description is defined by the following {{TERM: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 ] ; see section 4.3 > [ "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 > where whsp is a space ('{{EX: }}'), numericoid is a globally unique OID in numeric form (e.g. {{EX:1.2.3}}), qdescrs is one or more names, woid is either the name or OID, and noidlen is an optional length specifier (e.g {{EX:{10}}}). For example, the attribute types {{EX:name}} and {{EX:cn}} are defined in {{F:core.schema}} as: > 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 ) Notice that each defines the attribute's OID and descriptive names. Each name is an alias for the OID. {{slapd}}(8) returns the first listed name when returning results. The first attribute, {{EX:name}}, has a syntax of {{EX:directoryString}} (a UTF-8 encoded Unicode string) with a recommend maximun length. Note that syntaxes are specified by OID. In addition, the equality and substring matching uses case ignore rules. Below are tables listing commonly used supported syntax and matching rules. !block table; align=Center; coltags="EX,EX,N"; \ title="Table 6.3: Supported Syntaxes" Name OID Description binary 1.3.6.1.4.1.1466.115.121.1.5 BER/DER data 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.15 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 !endblock > !block table; align=Center; coltags="EX,N"; \ title="Table 6.4: Supported Matching Rules" Name Type Description booleanMatch equality boolean objectIdentiferMatch equality OID distinguishedNameMatch equality DN uniqueMemberMatch equality DN 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 caseIgnoreOrderingIA5Match ordering case insensitive, space insensitive caseIgnoreSubstringsIA5Match substrings case insensitive, space insensitive caseExactIA5Match equality case sensitive, space insensitive caseExactOrderingIA5Match ordering case sensitive, space insensitive caseExactSubstringsIA5Match substrings case sensitive, space insensitive !endblock The second attribute, {{EX:cn}}, is a subtype of {{EX:name}} hence it inherits the syntax, matching rules, and usage of {{EX:name}}. {{EX:commonName}} is an alternative name. Neither attribute is restricted to a single value and both are meant for usage by user applications. You likely won't need to specify other parameters such as {{EX:OBSOLETE}}. The following subsections provide a couple of examples. H4: myUniqueName Many organizations maintain a single unique name for each user. Though one could use {{EX:displayName}} ({{REF:RFC2798}}), this attribute is really meant to be controlled by the user, not the organization. We could just copy the definition of {{EX:displayName}} from {{F:inetorgperson.schema}} and replace the OID, name, and description, e.g: > 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 ) 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.: > attributetype ( 1.1.2.1.1 NAME 'myUniqueName' > DESC 'unique name with my organization' > SUP name ) H4: myPhoto Many organizations maintain a photo of each each user. A {{EX:myPhoto}} 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' > DESC 'a photo (application defined format)' > SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 > SINGLE-VALUE ) As noted in the description, LDAP has no knowledge of the format of the photo. It's assumed that all applications accessing this attribute agree on the handling of values. If you wanted to support multiple photo formats, you could define a separate attribute type for each format, prefix the photo with some typing information, or describe the value using {{TERM:ASN.1}} and use the {{EX:;binary}} transfer option. Another alternative is for the attribute to hold a {{TERM:URI}} pointing to the photo. You can model such an attribute after {{EX:labeledURI}} ({{REF:RFC2079}}). H3: Object Class Specification 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 attribute found in the subschema subentry, e.g.: E: objectclass <{{REF:RFC2252}} Object Class Description> where Object Class Description is defined by the following {{TERM: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 ")" where whsp is a space ('{{EX: }}'), numericoid is a globally unique OID in numeric form (e.g. {{EX:1.2.3}}), qdescrs is one or more names, and oids is one or more names and/or OIDs. H4: myPhotoObject To define an {{auxiliary}} object class which allows myPhoto to be added to any existing entry. > objectclass ( 1.1.2.2.1 NAME 'myPhotoObject' > DESC 'mixin myPhoto' > AUXILIARY > MAY myPhoto ) H4: myPerson If your organization would like have a private {{structural}} object class to instantiate users, you can subclass one of the existing person classes, such as {{EX:inetOrgPerson}} ({{REF:RFC2798}}), and add any additional attributes which you desire. > objectclass ( 1.1.2.2.2 NAME 'myPerson' > DESC 'my person' > SUP inetOrgPerson > MUST ( 'myUniqueName' $ 'givenName' ) > MAY 'myPhoto' ) The object class inherits the required/allowed attribute types of {{EX:inetOrgPerson}} but requires {{EX:myUniqueName}} and {{EX:givenName}} and allows {{EX:myPhoto}}. !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 {{slapd}}(8). LDAPv3 servers publish schema elements in special {{subschema}} entries (or subentries). {{slapd}}(8) publishes a single subschema entry normally named {{EX:cn=Subschema}}. If a server which supports a single subschema subentry, the DN of the subschema subenty can usually be found by examining the value of the {{EX:subschemaSubentry}} attribute type in the {{root DSE}} Other servers may publish multiple subschema entries. These can be located by examining the {{EX:subschemaSubentry}} attribute contained in the entry at the root of each administrative context. To obtain the schema from a subschema subentry, you can use ldapsearch(1) as follows (replace the search base as needed): > ldapsearch -LLL -x -b "cn=Subschema" -s base "(objectclass=subschema)" attributeTypes objectClasses This will return {{TERM:LDIF}} output containing many type/value pairs. The following is an abbreviated example: > dn: cn=Subschema > 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 > n defined format)' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 > objectClasses: ( 1.1.2.2.2 NAME 'myPerson' DESC 'my person' SUP inet > OrgPerson MUST ( 'myUniqueName' $ 'givenName' ) MAY 'myPhoto' ) Capture the output of the search in a file and then edit the file: + to contain only desired type/value pairs ^ join LDIF continuation lines ^ replace attribute type with directive name (e.g. {{EX:s/attributeTypes:/attributeType/}} and {{EX:s/objectClasses:/objectClass/}}). ^ continue long directives over multiple lines 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' > 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' > 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' > DESC 'my person' > SUP inetOrgPerson > MUST ( 'myUniqueName' $ 'givenName' ) > MAY 'myPhoto' ) Save in an appropriately named file (e.g. {{F:my.schema}}). You may now include this file in your {{slapd.conf}}(8) file. !endif