Schema

 


Object Class Definitions

All LDAP entries in the directory are typed. That is, each entry belongs to object classes that identify the type of data represented by the entry. The object class specifies the mandatory and optional attributes that can be associated with an entry of that class.

The object classes for all objects in the directory form a class hierarchy. The classes "top" and "alias" are at the root of the hierarchy. For example, the "organizationalPerson" object class is a subclass of the "Person" object class, which in turn is a subclass of "top". When creating a new LDAP entry, always specify all of the object classes to which the new entry belongs. Because many directories do not support object class subclassing, you also should always include all of the superclasses of the entry. For example, for an "organizationalPerson" object, you should list in its object classes the "organizationalPerson", "person", and "top" classes.

Three types of object classes are possible:

  • Structural. Indicates the attributes that the entry may have and where each entry may occur in the DIT.
  • Auxiliary. Indicates the attributes that the entry may have.
  • Abstract. Indicates a "partial" specification in the object class hierarchy; only structural and auxiliary subclasses may appear as entries in the directory.

In the schema tree, the name "ClassDefinition" is bound to a flat context containing DirContext objects that represents object class definitions in the schema. For example, if a directory supports a "person" object class, then the "ClassDefinition" context will have a binding with the name "person" that is bound to a DirContext object. Each object in the "ClassDefinition" context has mandatory and optional attributes shown in the following table. Only "NUMERICOID" is mandatory.
 

Attribute Identifier Attribute Value Description
NUMERICOID (mandatory) Unique object identifier (OID)
NAME Object class's name
DESC Object class's description
OBSOLETE "true" if obsolete; "false" or absent otherwise
SUP Names of superior object classes from which this object class is derived
ABSTRACT "true" if object class is abstract; "false" or absent otherwise
STRUCTURAL "true" if object class is structural; "false" or absent otherwise
AUXILIARY "true" if object class is auxiliary; "false" or absent otherwise
MUST List of type names of attributes that must be present
MAY List of type names of attributes that may be present

These attributes correspond to the definition of "ObjectClassDescription" in RFC 2252. All of the attribute values are represented by the java.lang.String class. Some directories do not publish all of the schema data. For example, the Netscape Directory Server v4.1 does not publish whether an object class is abstract, structural, or auxiliary. In such cases, the schema objects do not completely describe the object classes definitions.

 

 

Retrieving the Schema Object of an Object Class

To retrieve the schema object of an object class, you look for it in the schema tree. For example, you can obtain the schema object that represents the "person" object class by using the following code.
// Get the schema tree root
DirContext schema = ctx.getSchema("");

// Get the schema object for "person"
DirContext personSchema = (DirContext)schema.lookup("ClassDefinition/person");
If you get the attributes of the personSchema schema object, then you will see the following.
NUMERICOID: 2.5.6.6
NAME: person 
MAY:  description, seealso, telephonenumber, userpassword
MUST: objectclass, sn, cn 
DESC: Standard ObjectClass 
SUP: top

In addition to using lookup(), you can use methods such as list() or search() to retrieve schema objects from the schema tree.

 

 

Getting an Entry's Object Classes

Given a DirContext object representing an LDAP entry, you can get that entry's object classes by invoking DirContext.getSchemaClassDefinition() on it.

Following is an example that enumerates the object class definitions for the entry "cn=Ted Geisel, ou=People". getSchemaClassDefinition() returns a context that contains the entry's object class definitions. Using this context, you can look up an individual definition, search for a definition, enumerate all definitions, or perform other DirContext operations.

// Create the initial context
DirContext ctx = new InitialDirContext(env);

// Get context containing class definitions for the "cn=Ted Geisel" entry
DirContext tedClasses = ctx.getSchemaClassDefinition("cn=Ted Geisel, ou=People");

// Enumerate the class definitions
NamingEnumeration enum = tedClasses.search("", null);
while (enum.hasMore()) {
    System.out.println(enum.next());
}

 

 

Adding a New Object Class


Before you go on: To update the schema, authenticate as the directory administrator. This is the name that you supplied to the directory administration program when you first configured the directory. For example, if you configured "cn=Directory Manager" as the administrator, then you need to do something like the following when creating the initial context.
env.put(Context.SECURITY_PRINCIPAL, "cn=Directory Manager");
env.put(Context.SECURITY_CREDENTIALS, "secret99");

Netscape v4.0 Bugs: The Netscape Directory Server v4.0 and earlier releases do not support schema entries that comply with RFC 2252. Specifically, contrary to RFC 2252, the Netscape server requires that OIDs (such as those for SUP and SYNTAX) be delimited by single quotation marks and MUST/MAY lists be enclosed by parentheses. By default, the LDAP service provider produces schema entries that comply with RFC 2252 but are not acceptable to the Netscape server. To produce schema entries that are acceptable to the Netscape v4.0 server, add the following to the environment properties before creating the initial context:

env.put("com.sun.jndi.ldap.netscape.schemaBugs", "true");
Netscape v4.1 Bugs: The Netscape Directory Server v4.1 has fixed some of the schema-handling problems found in the version 4.0 server, so you should not use the "com.sun.jndi.ldap.netscape.schemaBugs" property with version 4.1. However, the version 4.1 server still requires that MUST/MAY lists be enclosed by parentheses. Sun's LDAP provider uses a quoted item instead of a parenthetical list for single-item MUST/MAY specifications. You can work around this problem by creating a single-valued "MUST"/"MAY" attribute and then adding a superfluous value, such as "objectclass", when you are modifying or creating an object class definition that has a single-itme MUST/MAY list.

Windows Active Directory: Active Directory does not support the modification of the RFC 2252 schema descriptions. Instead, update Active Directory's internal schema representation. See the Windows 2000 Planning Guide for details on how to enable and perform schema updates.


Adding a new object class to the schema is like adding a new entry to the directory. This is because the schema tree and schema objects are DirContext objects.

Following is an example that adds a new object class ("fooObjectClas") to the schema. It first declares the attributes that describe the new object class and then adds the object class definition to the schema by using DirContext.createSubcontext().

// Specify attributes for the schema object
Attributes attrs = new BasicAttributes(true); // Ignore case
attrs.put("NUMERICOID", "1.3.6.1.4.1.42.2.27.4.2.3.1.1.1");
attrs.put("NAME", "fooObjectClass");
attrs.put("DESC", "for JNDIDocs example only");
attrs.put("SUP", "top");
attrs.put("STRUCTURAL", "true");
Attribute must = new BasicAttribute("MUST", "cn");
must.add("objectclass");
attrs.put(must);

// Get the schema tree root
DirContext schema = ctx.getSchema("");

// Add the new schema object for "fooObjectClass"
DirContext newClass = schema.createSubcontext("ClassDefinition/fooObjectClass", attrs);
Some servers might modify the definition before adding it to the schema. To check the newly added definition, use a new initial context to read the definition so that any cached definition is not used.

 

 

Modifying an Object Class


Note: In versions of the LDAP provider prior to the Java 2 SDK, v1.4, you cannot modify an existing object class. In those releases, first delete the existing object class definition and then add the updated version.

Before you go on: See the Adding a New Object Class section for notes regarding updating the schema.


Modifying an existing object class in the schema is like modifying an entry in the directory. Here's an example that adds a "description" optional attribute to the object class "fooObjectClass" in the schema by using DirContext.modifyAttributes().
// Specify new MAY attribute for schema object
Attribute may = new BasicAttribute("MAY", "description");
Attributes attrs = new BasicAttributes(false);
attrs.put(may);

// Get the schema tree root
DirContext schema = ctx.getSchema("");

// Modify schema object for "fooObjectClass"
schema.modifyAttributes("ClassDefinition/fooObjectClass", 
    DirContext.ADD_ATTRIBUTE, attrs);
Some servers might modify the definition before performing the update on the schema or ignore the update. To check the newly updated definition, use a new initial context to read the definition so that any cached definition is not used.

 

 

Deleting an Object Class


Before you go on: See the Adding a New Object Class section for notes regarding updating the schema.
Deleting an existing object class from the schema is like deleting an entry from the directory. Here's an example that removes the object class "fooObjectClass" from the schema by using DirContext.destroySubcontext().
// Get the schema tree root
DirContext schema = ctx.getSchema("");

// Remove the schema object for "fooObjectClass"
schema.destroySubcontext("ClassDefinition/fooObjectClass");
Some servers might not let you delete an object class that's being used by entries in the directory. You might be able to get around this restriction by turning off schema checking.