Understanding and Deploying LDAP Directory Services > 7. Schema Design > Defining New Schema Elements |
Defining New Schema ElementsIf your schema needs are not adequately met by existing, predefined schemas, you will need to define your own object classes and attributes. It is fairly easy to define your own schemas, but like all design tasks there are pitfalls and tradeoffs to be considered . In this section we describe an approach that should produce good results. We do not discuss definitions of new attribute syntaxes because in most implementations adding a new attribute syntax requires the directory software vendor or customer to write code to support it. Choosing Names for New Attribute Types and Object ClassesYou should choose a naming scheme for the new object classes and attributes you define. All names should be made as meaningful as possible but not too long or cumbersome. Attribute names and object classes are generally hidden from end users, but directory service administrators and applications developers will work with them extensively. It is also important to make some effort to avoid collisions with the names chosen by other parties (standards committees , directory vendors, other software vendors , and so on). Remember, the entire attribute namespace is flat. The same is true for the object class namespace. A good strategy is to prefix the names of all the schema elements you define with something that resembles your organization's name . If you do that, collisions with other definitions are unlikely . For example, the ACME Corporation might use the prefix acme and create attributes and object classes such as those shown in Listing 7.11. Listing 7.11 ACME attributes and object class namesobjectclass acmePerson attribute acmePrinter attribute acmeID attribute acmeHoursAllowedAccess Tip If you define schema elements that you intend to publish widely and submit to a standards body such as the Internet Engineering Task Force (IETF), there is no need to prefix the names of the attributes and object classes with a string that identifies your organization. In fact, acceptance of your schema by others will likely be hindered if the names include something specific to your organization! Obtaining and Assigning Object IdentifiersRecall that each LDAP object class or attribute type must be assigned a unique name and OID. One of the biggest stumbling blocks faced by people new to LDAP directories is how to obtain OIDs for the new attribute types and object classes they want to define. Simply put, OIDs can be obtained from anyone who has one. In fact, one OID is sufficient to meet all your schema needs; you can simply add another level of hierarchy to create new branches or OID arcs for your attributes and object classes. An OID arc is an OID that has been reserved for use as a container for defining additional OIDs. The process of assigning an arc of the OID space to another party is called delegation . As already mentioned, an OID can be obtained from anyone who has one ”they just need to delegate it to you as an arc and record this so that they do not use the OID for any other purpose. The Internet Assigned Numbers Authority (IANA) gives out OIDs to any organization that asks. IANA calls the OIDs enterprise numbers because it gives them out primarily for use with Simple Network Management Protocol (SNMP). The IANA OIDs work fine for LDAP as well because each OID is as good as another. A form for obtaining an OID from IANA can be accessed on the Web at http://www.isi.edu/cgi-bin/ iana/enterprise.pl . Other organizations known to give out OIDs are ANSI (for U.S. organizations) and BSI (for U.K. organizations). General information on OIDs maintained by a gentleman named Harald Alvestrand can be accessed using the URL http://www.alvestrand.no/objectid/ . As an example of obtaining and assigning OIDs, consider the University of Michigan directory services team, which contacted IANA to obtain an OID arc (1.3.6.1.4.1.250) for its own use. The team then created the OID arcs shown in Table 7.5 for use in defining its own directory schema. Table 7.5. University of Michigan OID schema arcs
The team assigned the OID 1.3.6.1.4.1.250.1.1 to the first attribute type it defined, 1.3.6.1.4.1.250.1.2 to the second, and so on. Tip After you obtain an OID, you should maintain a registry similar to Table 7.5 to ensure that no OID is ever used for more than one purpose. You should then publish the list of OIDs with your schemas (more on this topic later). Although it may seem unimportant to establish an OID registry when you are just getting started, you will want to have one because the number of attributes and object classes you or others in your organization create may be quite large in the end. Modifying Existing Schema ElementsIt may be tempting just to alter some predefined schema elements to meet your needs, perhaps by adding a new attribute to a predefined object class. At first glance, this seems like a reasonable thing to do. Note Do not modify existing schema elements! Changing existing schemas will break some directory servers and clients , and it will probably lead to a lot of confusion. If the person object class that everyone knows about is different within each directory service deployment, chaos will rule. You should also be careful when completely deleting object classes or attributes from any of your directory server software's pre-installed schemas. It may be okay to do this as long as you are sure the schema is not used internally by any of the directory service software. However, you may run into trouble when you upgrade your software because the upgrade process may require that all of the vendor's schemas be present. In general, there is no reason to remove schema elements even if you do not plan to use them; there is little or no penalty associated with leaving the schema elements installed. Subclassing an Existing Object ClassIt is fairly common to extend, or subclass , an existing, predefined object class in order to add new attributes to it. To do this, define a new object class that is a subclass of the existing one by indicating in the definition of the new class that the existing class is its superior . You also need to define the new attribute types When you subclass an existing object class in this way, the new class should generally be used to represent the same type of object as the class from which it was derived. For example, you might create a new subclass of a printer object class called hpPrinter that allows additional attributes specific to Hewlett-Packard printers. The hpPrinter class is still used to represent printers; it just holds more information. Also, the new object class should be the same kind as the class from which it is derived. For example, if you are subclassing a structural object class, the new class should also be a structural class. Note that in some directory service implementations such as Netscape's, little or no distinction is made between different kinds of object classes, so this may not be something you have to deal with in practice. As another example of subclassing an existing object class, suppose the ACME Corporation is deploying a directory service in which one of the directory-enabled applications being developed is a "birthday notification service" (which managers will subscribe to so they remember to take each employee out to lunch on his or her birthday). The designers of the ACME directory might define a new attribute to hold the day and month a person was born. Using the slapd.conf schema format, the attribute type definition might look like this: attribute acmeBirthday bday-OID cis Note that bday-OID would need to be replaced by a real OID assigned by the ACME directory administrators. An extension of the inetOrgPerson class that allows the new acmeBirthday attribute to be included in entries could be defined as shown in Listing 7.12. Listing 7.12 The definition of the acmePerson object classobjectclass acmePerson superior inetOrgPerson oid acmePersonOID allows acmeBirthday Note that acmePersonOID should be replaced by a real OID assigned by the directory administrators. The acmePerson class would be used whenever a user entry is created inside ACME. The following is a sample entry: dn: uid=scarter, o=acme.com objectclass: top objectclass: person objectclass: organizationalPerson objectclass: inetOrgPerson objectclass: acmePerson cn: Sally Carter sn: Carter uid: scarter userPassword: secret acmeBirthday: 29-February Now we all know why Sally claims to be so much younger than she looks ”she must be counting birthdays instead of elapsed time! Note In the LDIF just shown, values for all the superior object classes ( top, person, organizationalPerson, and inetOrgPerson ) are explicitly shown in the entry's objectClass attribute. This is always how an entry will look when you retrieve it from an LDAP server. When adding or modifying entries, it should not be necessary to explicitly provide values for all the superior classes in this way, although some implementations do require it. Because there is no harm in listing all the superior object class values, it is safest always to do so. Adding Auxiliary Information to a Directory ObjectSometimes it is preferable to create an auxiliary object class that allows attributes to be added to any type of LDAP entry regardless of what kind of real-world object it represents. A class like this is sometimes called a mix-in class because it allows additional attributes to be "mixed into" an existing class. A mix-in class may be added to a wide range of entry types ”a much simpler approach than creating a subclass for each object class you want to allow the new attributes to appear in. To create an auxiliary object class, simply define a new class that is not subclassed from any existing object class (it should have the special class top as its superior). It is best to make all the attributes in the auxiliary class optional rather than mandatory. That way, the auxiliary object class itself can be associated with an entry regardless of whether any values for its attributes are present. This reduces the burden on directory clients because they do not have to worry about removing the object class value when an attribute required by the auxiliary class is removed. An example of a useful auxiliary object class is shown in Listing 7.13 (using the ASN.1 schema description format). This class was defined by the authors while they were at the University of Michigan. Listing 7.13 The labeledURIObject object classlabeledURIObject OBJECT-CLASS ::= { SUBCLASS OF { top } KIND auxiliary MAY CONTAIN { labeledURI } ID 1.3.6.1.4.1.250.3.15 This class can be added to any LDAP entry to allow uniform resource identifiers (URIs) to be included in the entry. The labeledURI attribute itself consists of a URI and an optional text label. The most common type of URIs are URLs that are now so much a part of the computing infrastructure: User entries might contain a URL that points to a person's home page; group entries might contain a URL that points to a Web site that contains information about the group 's activities; and printer entries might contain a URL that provides access to a printer administration utility or the printer itself. The following is an example of a group entry that also contains a URL: dn: cn=UNIX Wizards, ou=Groups, dc=airius, dc=com cn: UNIX Wizards objectclass: top objectclass: groupOfNames objectclass: labeledURIObject member: uid=bjensen, ou=people, dc=airius,dc=com member: uid=bjornj, ou=people, dc=airius,dc=com labeleduri: http://www.airius.com/unixwizards/ UNIX Wizards Home Page As another example of an auxiliary object class, suppose you develop a directory-enabled application that keeps track of your organization's network- related inventory by storing information in the following custom attributes (shown here using the slapd.conf schema format): attribute inventoryID OID int attribute inventoryDatePlacedInService OID cis attribute inventoryContactPerson OID dn attribute inventoryComments OID cis Note that all the OID s would, of course, need to be replaced with real object identifiers you assign. Because you want to mix these attributes into several different types of entries (printers, hosts , and so on), you could handle your schema needs by defining an auxiliary object class such as the inventoryItem class shown in Listing 7.14. Listing 7.14 The inventoryItem auxiliary object classobjectclass inventoryItem superior top oid OID requires inventoryID allows inventoryDatePlacedInService, inventoryContactPerson, inventoryComments Here is a sample printer entry that has inventory information attached to it: dn: cn=2nd floor HP 5Si MX, ou=printers, dc=airius, dc=com objectclass: top objectclass: printer objectclass: inventoryItem cn: 2nd floor HP 5Si MX pagesPerMinute: 24 inventoryID: 1290-555-81 inventoryDatePlacedInService: 19970501000000Z inventoryContactPerson: uid=bjensen,ou=people,dc=airius,dc=com inventoryComments: on loan to the art department Accommodating New Types of ObjectsIf you cannot find a predefined object class that is similar to the type of object you need to represent in your directory service, simply define a new structural class to hold whatever attributes are appropriate. This is similar to creating a new auxiliary class except that the structural class can stand on its own as the primary object class for an entry. For example, if our friends at the ACME Corporation plan to use their directory to track company-owned and -operated telephone sets, they might reuse some predefined attributes but create a new object class such as the one shown in Listing 7.15. Listing 7.15 The acmeTelephone object classobjectclass acmeTelephone superior top oid OID allows cn, telephoneNumber, owner, l Here is a sample entry: dn: cn=Mark Smith's phone, ou=phones, o=acme.com objectclass: top objectclass: acmeTelephone cn: Mark Smith's phone telephoneNumber: 3477 owner: uid=bkady, ou=people, o=acme.com l: security office Note that when you create an object class for an entirely new kind of object, you will need to put some thought into which attribute will most likely be used to form the RDN of entries that belong to the class. For most object classes, the cn (common name) attribute is a good, generic choice. In the acmeTelephone object class we just looked at, the telephoneNumber itself might actually be a better choice for naming phone entries simply because it is more likely to be unique. The sample entry we just used might instead be defined as shown here: dn: telephoneNumber=3477, ou=phones, o=acme.com objectclass: top objectclass: acmeTelephone cn: Mark Smith's phone telephoneNumber: 3477 owner: uid=bkady, ou=people, o=acme.com l: security office The only difference is in the RDN (the first part of the DN), which uses the telephoneNumber attribute instead of cn to name the entry. See Chapter 8, "Namespace Design," for more information on entry naming. Tips for Defining New SchemasDefining a good schema is as much art as science, and the more of it you do, the easier the process becomes. The following are some tips that will help you produce better results:
|
Index terms contained in this sectionarcsOIDs University of Michigan assigning OIDs to attributes and object classes 2nd 3rd 4th auxiliary object classes inventoryItem labeledURIObject 2nd 3rd schemas 2nd 3rd 4th 5th defining object classes new schemas 2nd 3rd directories schemas assigning OIDs 2nd 3rd 4th auxiliary object classes 2nd 3rd 4th 5th defining new attributes and object classes 2nd 3rd defining new object classes 2nd 3rd 4th 5th 6th 7th 8th modifying existing elements 2nd subclassing existing objects 2nd 3rd 4th 5th 6th enterprise numbers OIDs existing objects schemas subclassing 2nd 3rd 4th 5th 6th IETF inventoryItemobject class labeledURIObject object class 2nd 3rd mandatory attributes defining new object classes modifying existing schema elements 2nd names attributes defining new 2nd 3rd new attributes schemas assigning OIDs 2nd 3rd 4th defining 2nd 3rd new object classes defining 2nd 3rd 4th 5th including smaller auxiliary classes minimizing mandatory attributes reusing existing elements schemas assigning OIDs 2nd 3rd 4th defining 2nd 3rd object classes auxiliary 2nd 3rd 4th 5th inventoryItem labeledURIObject 2nd 3rd defining new 2nd 3rd 4th 5th including smaller auxiliary classes minimizing mandatory attributes reusing existing elements OIDs assigning to 2nd 3rd 4th OIDs arcs University of Michigan assigning to attributes and object classes 2nd 3rd 4th enterprise numbers schemas attributes assigning OIDs 2nd 3rd 4th defining new 2nd 3rd modifying existing elements 2nd object classes assigning OIDs 2nd 3rd 4th defining new 2nd 3rd objects auxiliary classes 2nd 3rd 4th 5th defining new classes 2nd 3rd 4th 5th 6th 7th 8th subclassing 2nd 3rd 4th 5th 6th subclassing existing schema objects 2nd 3rd 4th 5th 6th |
2002, O'Reilly & Associates, Inc. |