<?xml version="1.0" encoding="UTF-8"?>
<!--
! CCPL HEADER START
!
! This work is licensed under the Creative Commons
! Attribution-NonCommercial-NoDerivs 3.0 Unported License.
! To view a copy of this license, visit
! or send a letter to Creative Commons, 444 Castro Street,
! Suite 900, Mountain View, California, 94041, USA.
!
! You can also obtain a copy of the license at
! See the License for the specific language governing permissions
! and limitations under the License.
!
! If applicable, add the following below this CCPL HEADER, with the fields
! enclosed by brackets "[]" replaced with your own identifying information:
! Portions Copyright [yyyy] [name of copyright owner]
!
! CCPL HEADER END
!
! Copyright 2011-2014 ForgeRock AS
!
-->
<chapter xml:id='chap-schema'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:schemaLocation='http://docbook.org/ns/docbook
xmlns:xlink='http://www.w3.org/1999/xlink'>
<title>Managing Schema</title>
<indexterm><primary>Schema</primary></indexterm>
<para>Schema definitions describe the data, and especially the object classes
and attribute types that can be stored in the directory. By default OpenDJ
conforms strictly to LDAPv3 standards pertaining to schema definitions and
attribute syntax checking, ensuring that data stored is valid and properly
formed. Unless your data use only standard schema present in OpenDJ when
you install, then you must add additional schema definitions to account
the data your applications stored.</para>
<para>Out of the box, OpenDJ comes with many standard schema definitions.
In addition you can update and extend schema definitions while OpenDJ
is online. As a result you can add new applications requiring additional
data without stopping your directory service.</para>
<para>This chapter demonstrates how to change and to extend OpenDJ schema.
This chapter also identifies the standard schema definitions available when
you install OpenDJ.</para>
<section xml:id="about-schema">
<title>About Directory Schema</title>
<para>Directory schema, described in <link
the kinds of information you find in the directory, and can define how
the information are related. This chapter focuses primarily on two types
of directory schema definitions.</para>
<itemizedlist>
<listitem>
<para><firstterm>Attribute type</firstterm> definitions describe attributes
of directory entries, such as <literal>givenName</literal> or
<literal>mail</literal>.</para>
<para>Here is an example of an attribute type definition.</para>
<programlisting language="ldif">
# Attribute type definition
attributeTypes: ( 0.9.2342.19200300.100.1.3 NAME ( 'mail' 'rfc822Mailbox' )
EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} X-ORIGIN 'RFC 4524' )
</programlisting>
<para>Attribute type definitions start with an object identifier (OID),
and generally a short name or names that are easier to remember than the
OID. The attribute type definition can specify how attribute values
should be collated for sorting, and what syntax they use. The X-ORIGIN
is an extension to identify where the definition originated. When you
define your own schema, you likely want to provide an X-ORIGIN to help
you to track versions of definitions, and where the definitions came
from.</para>
</listitem>
<listitem>
<para><firstterm>Object class</firstterm> definitions identify the
attribute types that an entry must have, and may have. Examples of
object classes include <literal>person</literal> and
<literal>organizationalUnit</literal>.</para>
<para>Here is an example of an object class definition.</para>
<programlisting language="ldif">
# Object class definition
objectClasses: ( 2.5.6.6 NAME 'person' SUP top STRUCTURAL MUST ( sn $ cn )
MAY ( userPassword $ telephoneNumber $ seeAlso $ description )
X-ORIGIN 'RFC 4519' )
</programlisting>
<para>Entries all have an attribute identifying their object classes,
called <literal>objectClass</literal>.</para>
<para>Object class definitions start with an object identifier (OID), and
generally a short name that is easier to remember than the OID. The
definition here says that the person object class inherits from the top
object class, which is the top-level parent of all object classes. When
you view the objectclass attribute values on an entry, you see the list
of object classes that the entry takes. An entry can have one STRUCTURAL
object class inheritance branch, such as <literal>top</literal> -
<literal>person</literal> - <literal>organizationalPerson</literal> -
<literal>inetOrgPerson</literal>. Yet entries can have multiple
AUXILIARY object classes. The object class then defines the attribute
types that must be included, and the attribute types that may be included
on entries having the object class.</para>
</listitem>
<listitem>
<para>An <firstterm>attribute syntax</firstterm> constrains what directory
clients can store as attribute values.</para>
<para>An attribute syntax is identified in an attribute type definition by
its OID. String-based syntax OIDs are optionally followed by a number, set
between braces, that represents a minimum upper bound on the number of
characters in the attribute value. For example, in the attribute type
definition shown above, the syntax is
<literal>1.3.6.1.4.1.1466.115.121.1.26{256}</literal>. The syntax is an
IA5 string (composed of characters from the international version of the
ASCII character set) that can contain at least 256 characters.</para>
<para>You can find a table matching attribute syntax OIDs with their
human-readable names in RFC 4517, <link xlink:show="new"
xlink:href="http://tools.ietf.org/html/rfc4517#appendix-A">Appendix A.
Summary of Syntax Object Identifiers</link>. The RFC describes
attribute syntaxes in detail. Alternatively, you can see the attribute
syntaxes that OpenDJ supports by opening the OpenDJ Control Panel and
browsing to Schema > Manage Schema > Attribute Syntaxes. You can
also list them by using the <command>dsconfig</command> command.</para>
<para>Although attribute syntaxes are often specified in attribute type
definitions, directory servers do not always check that attribute values
comply with attribute syntaxes. OpenDJ directory server does tend to
enforce compliance by default, in particular for certificates, country
strings, directory strings, JPEG photos, and telephone numbers. The aim
is to avoid accumulating garbage in your directory data.</para>
<para>If you are trying unsuccessfully to import non-compliant data from a
more lenient directory server, you can either clean the data before
importing it, or if cleaning the data is not an option, read <xref
linkend="schema-legacy-support" />.</para>
<para>When creating your own attribute type definitions, use existing
attribute syntaxes where possible. If you must create your own attribute
syntax, then consider the extensions in
<xref linkend="attr-syntax-schema-definition-extensions" />.</para>
</listitem>
<listitem>
<para>Matching rules determine how the directory server compares attribute
values to assertion values for LDAP search and LDAP compare
operations.</para>
<para>For example, suppose you search with the filter
<literal>(uid=bjensen)</literal>. The assertion value in this case is
<literal>bjensen</literal>.</para>
<para>OpenDJ has the following schema definition for the user ID
attribute.</para>
<programlisting language="ldif">
attributeTypes: ( 0.9.2342.19200300.100.1.1 NAME ( 'uid' 'userid' )
EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} X-ORIGIN 'RFC 4519' )
</programlisting>
<para>When finding an equality match for your search, OpenDJ uses the
<literal>caseIgnoreMatch</literal> matching rule to check for user ID
attribute values that equal <literal>bjensen</literal> without regard
to case.</para>
<para>You can see the matching rules that OpenDJ supports by opening the
OpenDJ Control Panel and browsing to Schema > Manage Schema >
Matching Rules. Notice that many matching rules support string collation
in languages other than English. You can also list matching rules by
using the <command>dsconfig</command> command.</para>
<para>As you can read in examples like, <link xlink:show="new"
xlink:href="admin-guide#extensible-match-search"
Active Accounts</citetitle></link>, OpenDJ matching rules enable
directory clients to do more interesting searches than simply comparing
strings. That example shows how to search for users who have
authenticated in the last three months.</para>
</listitem>
</itemizedlist>
<para>OpenDJ exposes schema over protocol through the
<literal>cn=schema</literal> entry. OpenDJ stores the schema definitions
corresponding to the entry in LDIF under the
and definitions pertaining to the server configuration are included at
installation time.</para>
</section>
<section xml:id="update-schema">
<title>Updating Directory Schema</title>
<indexterm>
<primary>Replication</primary>
<secondary>Schema definitions</secondary>
</indexterm>
<para>OpenDJ directory server is designed to permit updating the list of
directory schema definitions while the server is running. As a result you can
add support for new applications that require new attributes or new kinds
of entries without interrupting the directory service. OpenDJ also replicates
schema definitions, so the schema you add on one replica is propagated to
other replicas without you having to intervene manually.</para>
<para>As it is easy to introduce typos into schema definitions, the
best way to start defining your own schema is with the OpenDJ Control
Panel. Open the Control Panel > Schema > Manage Schema window to
get started creating your custom object classes and attribute types.</para>
<mediaobject xml:id="figure-manage-schema">
<imageobject>
</imageobject>
</mediaobject>
<para>As object classes reference attribute types, you first create
custom attribute types, and then create the object class that references
the attribute types.</para>
<para>Create a custom attribute type through the New Attribute window.</para>
<mediaobject xml:id="figure-custom-attrtype">
<imageobject>
</imageobject>
</mediaobject>
<para>Using the New Object Class window, create an auxiliary object class
that allows your new custom attribute type. You set the type to Auxiliary
under Extra Options.</para>
<mediaobject xml:id="figure-custom-objclass">
<imageobject>
</imageobject>
</mediaobject>
<para>When you finish, the schema changes show up by default in the file
starts with a number, 99. This number is larger than the numbers prefixing
other schema file names. In fact, OpenDJ reads the schema files in sorted
order, reading schema definitions as they occur. If OpenDJ reads a schema
definition for an object class before it has read the definitions of the
attribute types mentioned in the object class definition, then it displays
an error. Therefore, when naming your schema file, make sure the name appears
in the sorted list of file names <emphasis>after</emphasis> all the schema
files containing definitions that your schema definitions depends on. The
that your definitions load only after all of the schema files installed by
default.</para>
<para>You can create this file in the lab using the Control Panel, and then
apply the definitions in production by adapting the content for use with the
<command>ldapmodify</command> command, for example.</para>
<screen>
<computeroutput>dn: cn=schema
objectClass: top
objectClass: ldapSubentry
objectClass: subschema
cn: schema
attributeTypes: ( temporary-fake-attr-id NAME 'myCustomAttribute' EQUALITY case
IgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstrings
Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE userApplications )
objectClasses: ( temporary-fake-oc-id NAME 'myCustomObjClass
' SUP top AUXILIARY MAY myCustomAttribute )
modifiersName: cn=Directory Manager,cn=Root DNs,cn=config
modifyTimestamp: 20110620095948Z</computeroutput>
</screen>
<para>To test your schema definition, add the object class and attribute
to an entry.</para>
<screen>
<computeroutput>dn: uid=bjensen,ou=People,dc=example,dc=com
changetype: modify
add: objectClass
objectClass: myCustomObjClass
-
add: myCustomAttribute
myCustomAttribute: Testing 1, 2, 3...</computeroutput>
$ <userinput>ldapmodify \
--port 1389 \
--bindDN "cn=Directory Manager" \
--bindPassword password \
--filename custom-attr.ldif</userinput>
<computeroutput>Processing MODIFY request for uid=bjensen,ou=People,dc=example,dc=com
MODIFY operation successful for DN uid=bjensen,ou=People,dc=example,dc=com</computeroutput>
$ <userinput>ldapsearch \
--port 1389 \
--baseDN dc=example,dc=com \
uid=bjensen \
myCustomAttribute</userinput>
<computeroutput>dn: uid=bjensen,ou=People,dc=example,dc=com
myCustomAttribute: Testing 1, 2, 3...</computeroutput>
</screen>
<para>In addition to supporting the standard schema definitions that are
>RFC 4512, section 4.1</link>, OpenDJ also supports the following extensions
that you can use when adding your own definitions.</para>
<variablelist xml:id="general-schema-definition-extensions">
<title>Extensions for All Schema Definitions</title>
<indexterm>
<primary>Schema</primary>
<secondary>Schema definition extensions</secondary>
</indexterm>
<varlistentry>
<term><literal>X-ORIGIN</literal></term>
<listitem>
<para>Used to specify the origin of a schema element. Examples include
<literal>X-ORIGIN 'RFC 4519'</literal>, <literal>X-ORIGIN
'draft-ietf-ldup-subentry'</literal>, and <literal>X-ORIGIN
'OpenDJ Directory Server'</literal>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>X-SCHEMA-FILE</literal></term>
<listitem>
<para>Used to specify the relative path to the schema file containing the
Schema definitions are located by default in
</listitem>
</varlistentry>
</variablelist>
<variablelist xml:id="attr-syntax-schema-definition-extensions">
<title>Extensions for Attribute Syntax Descriptions</title>
<indexterm>
<primary>Schema</primary>
<secondary>Schema definition extensions</secondary>
</indexterm>
<varlistentry>
<term><literal>X-ENUM</literal></term>
<listitem>
<para>Used to define a syntax that is an enumeration of values. The
following attribute syntax description defines a syntax allowing four
possible attribute values for example.</para>
<programlisting language="ldif">
ldapSyntaxes: ( security-label-syntax-oid DESC 'Security Label'
X-ENUM ( 'top-secret' 'secret' 'confidential' 'unclassified' ) )
</programlisting>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>X-PATTERN</literal></term>
<listitem>
<para>Used to define a syntax based on a regular expression pattern, where
valid regular expressions are those defined for <link xlink:show="new"
syntax description defines a simple, lenient SIP phone URI syntax
check.</para>
<programlisting language="ldif">
ldapSyntaxes: ( simple-sip-uri-syntax-oid DESC 'Lenient SIP URI Syntax'
X-PATTERN '^sip:[a-zA-Z0-9.]+@[a-zA-Z0-9.]+(:[0-9]+)?$' )
</programlisting>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>X-SUBST</literal></term>
<listitem>
<para>Used as a fallback to substitute a defined syntax for one that
OpenDJ does not implement. The following example substitutes Directory
String syntax, which has OID 1.3.6.1.4.1.1466.115.121.1.15, for a syntax
that OpenDJ does not implement.</para>
<programlisting language="ldif">
ldapSyntaxes: ( non-implemented-syntax-oid DESC 'Not Implemented in OpenDJ'
X-SUBST '1.3.6.1.4.1.1466.115.121.1.15' )
</programlisting>
</listitem>
</varlistentry>
</variablelist>
<variablelist xml:id="attr-type-schema-definition-extensions">
<title>Extension for Attribute Type Descriptions</title>
<indexterm>
<primary>Schema</primary>
<secondary>Schema definition extensions</secondary>
</indexterm>
<varlistentry>
<term><literal>X-APPROX</literal></term>
<listitem>
<para><literal>X-APPROX</literal> is used to specify the approximate
matching rule to use for a given attribute type when not using the default,
xlink:show="new">double metaphone approximate match</link>.</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section xml:id="schema-legacy-support">
<title>Relaxing Schema Checking to Import Legacy Data</title>
<indexterm>
<primary>Schema</primary>
<secondary>Legacy data</secondary>
</indexterm>
<para>By default, OpenDJ accepts data that follows the standards in terms of
what is allowed and what is rejected. You might have legacy data from a
directory service that is more lenient, allowing non-standard constructions
such as multiple structural object classes per entry, not checking attribute
value syntax, or even not respecting schema definitions.</para>
<para>For example, when importing data with multiple structural object
classes defined per entry, you can relax schema checking to warn rather
than reject entries having this issue.</para>
<screen>
$ <userinput>dsconfig \
set-global-configuration-prop \
--hostname opendj.example.com \
--port 4444 \
--bindDN "cn=Directory Manager" \
--bindPassword password \
--set single-structural-objectclass-behavior:warn \
--trustAll \
--no-prompt</userinput>
</screen>
<para>You can allow attribute values that do not respect the defined syntax
with the <command>dsconfig</command> command as well.</para>
<screen>
$ <userinput>dsconfig \
set-global-configuration-prop \
--hostname opendj.example.com \
--port 4444 \
--bindDN "cn=Directory Manager" \
--bindPassword password \
--set invalid-attribute-syntax-behavior:warn \
--trustAll \
--no-prompt</userinput>
</screen>
<para>You can even turn off schema checking altogether, although turning
off schema checking only really makes sense when you are absolutely sure
that the entries and attribute values respect the schema definitions, and
you simply want to turn off schema checking temporarily to speed up import
processing.</para>
<screen>
$ <userinput>dsconfig \
set-global-configuration-prop \
--hostname opendj.example.com \
--port 4444 \
--bindDN "cn=Directory Manager" \
--bindPassword password \
--set check-schema:false \
--trustAll \
--no-prompt</userinput>
</screen>
</section>
<section xml:id="standard-schema">
<title>Standard Schema Included With OpenDJ</title>
<indexterm>
<primary>Schema</primary>
<secondary>Bundled definitions</secondary>
</indexterm>
contain schema definitions out of the box.</para>
<variablelist>
<varlistentry>
<term>
</term>
<listitem>
<para>
This file contains a core set of
attribute type and object class definitions
from the following Internet-Drafts, RFCs, and standards:
</para>
<simplelist columns="1">
<member xlink:show="new" xlink:href="https://tools.ietf.org/html/draft-ietf-boreham-numsubordinates">draft-ietf-boreham-numsubordinates</member>
<member xlink:show="new" xlink:href="https://tools.ietf.org/html/draft-findlay-ldap-groupofentries">draft-findlay-ldap-groupofentries</member>
<member xlink:show="new" xlink:href="https://tools.ietf.org/html/draft-furuseth-ldap-untypedobject">draft-furuseth-ldap-untypedobject</member>
<member xlink:show="new" xlink:href="https://tools.ietf.org/html/draft-good-ldap-changelog">draft-good-ldap-changelog</member>
<member xlink:show="new" xlink:href="https://tools.ietf.org/html/draft-ietf-ldup-subentry">draft-ietf-ldup-subentry</member>
<member xlink:show="new" xlink:href="https://tools.ietf.org/html/draft-wahl-ldap-adminaddr">draft-wahl-ldap-adminaddr</member>
</simplelist>
</listitem>
</varlistentry>
<varlistentry>
<term>
</term>
<listitem>
<para>
This file contains schema definitions from
<link
xlink:show="new"
>draft-behera-ldap-password-policy</link> (Draft 09),
which defines a mechanism for storing password policy information
in an LDAP directory server.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
</term>
<listitem>
<para>This file contains the attribute type and objectclass definitions
for use with the directory server configuration.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
</term>
<listitem>
<para>
This file contains schema definitions from
<link
xlink:show="new"
>draft-good-ldap-changelog</link>, which defines a mechanism
for storing information about changes to directory server data.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
</term>
<listitem>
<para>
This file contains schema definitions from
<link
xlink:show="new"
xlink:href="https://tools.ietf.org/html/rfc2713"
>RFC 2713</link>, which defines a mechanism
for storing serialized Java objects in the directory server.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
</term>
<listitem>
<para>
This file contains schema definitions from
<link
xlink:show="new"
xlink:href="https://tools.ietf.org/html/rfc2714"
>RFC 2714</link>, which defines a mechanism
for storing CORBA objects in the directory server.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
</term>
<listitem>
<para>
This file contains schema definitions from
<link
xlink:show="new"
xlink:href="https://tools.ietf.org/html/rfc2739"
>RFC 2739</link>, which defines a mechanism
for storing calendar and vCard objects in the directory server.
Note that the definition in RFC 2739 contains a number of errors,
and this schema file has been altered from the standard definition
in order to fix a number of those problems.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
</term>
<listitem>
<para>
This file contains schema definitions from
<link
xlink:show="new"
xlink:href="https://tools.ietf.org/html/rfc2926"
>RFC 2926</link>, which defines a mechanism
for mapping between Service Location Protocol (SLP) advertisements and LDAP.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
</term>
<listitem>
<para>
This file contains schema definitions from
<link
xlink:show="new"
xlink:href="https://tools.ietf.org/html/rfc3112"
>RFC 3112</link>, which defines the authentication password schema.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
</term>
<listitem>
<para>
This file contains schema definitions from
<link
xlink:show="new"
xlink:href="https://tools.ietf.org/html/rfc3712"
>RFC 3712</link>, which defines a mechanism
for storing printer information in the directory server.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
</term>
<listitem>
<para>
This file contains schema definitions from
<link
xlink:show="new"
xlink:href="https://tools.ietf.org/html/rfc4403"
>RFC 4403</link>, which defines a mechanism
for storing UDDIv3 information in the directory server.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
</term>
<listitem>
<para>
This file contains schema definitions from
<link
xlink:show="new"
xlink:href="https://tools.ietf.org/html/draft-howard-rfc2307bis"
>draft-howard-rfc2307bis</link>, which defines a mechanism
for storing naming service information in the directory server.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
</term>
<listitem>
<para>
This file contains schema definitions from
<link
xlink:show="new"
xlink:href="https://tools.ietf.org/html/rfc4876"
>RFC 4876</link>, which defines a schema
for storing Directory User Agent (DUA) profiles and preferences
in the directory server.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
</term>
<listitem>
<para>This file contains schema definitions required when storing Samba
user accounts in the directory server.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
</term>
<listitem>
<para>This file contains schema definitions required for Solaris and
OpenSolaris LDAP naming services.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
</term>
<listitem>
<para>This file contains the attribute type and objectclass definitions
for use with the directory server configuration.</para>
</listitem>
</varlistentry>
</variablelist>
</section>
</chapter>