The ABCs of LDAP: How to Install, Run, and Administer LDAP Services

 < Day Day Up > 


From a practical point of view, the directory schema is defined in the configuration files. The problem for the beginner, however, is that the naming conventions in the configuration files may differ from those used in the RFCs. To make things even more complicated, there are not two different ways of describing the schema, but three! The description depends on which implementation you are using and which of these dialects you have installed.

Schema Descriptions

ASN.1 Schema Format

Abstract syntax notation one (ASN.1) is a framework used to describe tree-structured data. ASN.1 consists of two parts. One part describes the syntax rules, the other part the encoding of the data. The interesting part for us is part one. You will find a detailed description in Recommendation X.208 from the Consultative Committee in International Telephony and Telegraphy (CCITT). This notation is used mainly in the X.500 documentation. In the LDAP RFCs, it is used to describe some protocol elements. Look at the definition to learn more about it. For compatibility with X.500 servers, some schema files also contain the ASN.1 version of their schema in the form of comments.

slapd.conf Schema Format

This is the format used by the University of Michigan "standalone LDAP server," commonly referred to as "slapd." The slapd.conf schema format derives its name from the configuration file called "slapd.conf." It is used by other implementations too, for example by Netscape Directory Server versions 3 and 4. Thanks to its simplicity, it is very popular. It contains the whole schema in two configuration files, one containing the attribute definitions and one containing the object definitions. The OpenLDAP (v2) implementation called these configuration files "slapd.at.conf" and "slapd.oc.conf," respectively. OpenLDAP is based on the University of Michigan implementation of LDAP. Exhibit 6 shows an example the file "slapd.at.conf" defining the attributes. Note the attribute syntax notation, which provides human-readable aliases. Exhibit 7 presents an exerpt of the manual page for slapd.conf from OpenLDAP, which shows the syntax of the attributes. Exhibit 8 shows some object definitions using the slapd.conf schema format. Exhibit 9 shows an attribute definition as drawn from a page in the OpenLDAP manual.

attribute

photo

bin

 

attribute

personalsignature

bin

 

attribute

jpegphoto

bin

 

attribute

audio

bin

 

attribute

labeledurl

ces

 

attribute

ref

ces

 

attribute

userpassword

ces

 

attribute

telephonenumber

tel

 

attribute

facsimiletelephonenumber

fax

tel

attribute

pagertelephonenumber

pager

tel

attribute

homephone

tel

 

attribute

mobiletelephonenumber

mobile

tel

attribute

aliasedObjectName

dn

 

attribute

member

dn

 

attribute

owner

dn

 

attribute

seealso

dn

 

attribute

manager

dn

 

attribute

documentauthor

dn

 

attribute

secretary

dn

 

attribute

lastmodifiedby

dn

 

attribute

associatedname

dn

 

attribute

naminglink

dn

 

attribute

reciprocalnaminglink

dn

 

attribute

dn

dn

 

Exhibit 6: Attribute Definitions Using the slapd.conf Schema Format

attribute <name> [<name2>] { bin | ces | cis | tel | dn }

Associate a syntax with an attribute name. By default, an attribute is assumed to have syntax cis. An optional alternate name can be given for an attribute. The possible syntaxes and their meanings are:

Exhibit 7: Attribute Definitions Using slapd.conf Schema Format; Excerpt from OpenLDAP Manual Page

objectclass person requires objectClass, sn, cn allows description, seeAlso, telephoneNumber, userPassword objectclass organizationalPerson requires objectClass, sn, cn allows description, destinationIndicator, facsimileTelephoneNumber, internationaliSDNNumber, l, ou, physicalDeliveryOfficeName, postOfficeBox, postalAddress, postalCode, preferredDeliveryMethod, registeredAddress, seeAlso, st, streetAddress, telephoneNumber, teletexTerminalIdentifier, telexNumber, title, userPassword, x121Address

Exhibit 8: A Few Object Definitions Using the slapd.conf Schema Format

objectclass <name> requires <attrs> allows <attrs>

Define the schema rules for the object class named <name>. These are used in conjunction with the schemacheck option.

Exhibit 9: Attribute Definitions Using slapd.conf Schema Format; Excerpt from OpenLDAP Manual Page

LDAP (v3) Schema Format

This new schema format has been introduced, as the name suggests, with version 3 of the LDAP protocol. The schema format is described in RFC 2252, "LDAP (v3) Attribute Syntax Definitions." New in this schema format is that it enables the directory server to publish its schema using LDAP. This allows clients to retrieve the schema information from the directory server itself. With this knowledge, the client can tailor its actions specifically for this server. The information is held in the attribute "subschemaSubentry," which is one of the operational attributes. See the section "Information Model" in Chapter 3 to learn more about operational attributes. Exhibit 10 shows some typical definitions of attributes. Exhibit 11 shows some examples of object-class definitions.

attributetype (2.5.4.6 NAME ('c' 'countryName') DESC 'RFC2256: ISO-3166 country 2-letter code' SUP name SINGLE-VALUE) attributetype (2.5.4.7 NAME ('1' 'localityName') DESC 'RFC2256: locality which this object resides in' SUP name) attributetype (2.5.4.8 NAME ('st' 'stateOrProvinceName') DESC 'RFC2256: state or province which this object resides in' SUP name

Exhibit 10: Typical Attribute-Type Definitions Using LDAP (v3) Schema Format

objectclass (2.5.6.3 NAME 'locality' DESC 'RFC2256: a locality' SUP top STRUCTURAL MAY (street $ seeAlso $ searchGuide $ st $ 1 $ description)) objectclass (2.5.6.4 NAME 'organization' DESC 'RFC2256: an organization' SUP top STRUCTURAL MUST o MAY (userPassword $ searchGuide $ seeAlso $ businessCategory $ x121Address $ registeredAddress $ destinationIndicator $ preferredDeliveryMethod $ telexNumber $ teletexTerminalIden- tifier $ telephoneNumber $ international iSDNNumber $ facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $postalAddress $ physicalDeliveryOfficeName $ st $ 1 $ descrip- tion))

Exhibit 11: Typical Object-Class Definitions Using LDAP (v3) Schema Format

Checking the Directory Schema

We have learned that a schema defines what type of data the directory can hold. But how do you know that, in the end, only data complying with your schema will be inserted into the directory server? It is the directory server itself that verifies whether inserted or modified data on the directory is compliant with the schemas defined for the directory.

The process of checking entries takes some time. If you have to insert only a few objects or change only a few attributes, time is not a factor. Problems arise when you have to insert bulk data or modify a large number of entries. In such cases, you can simply switch off schema checking and switch it back on after you have inserted the data. This will enormously speed up the updating process. However, if the objects inserted into your directory do not conform to the schema, you will run into trouble later on.

Exploring the Directory Schema

A practical look at the schema should help resolve any remaining questions. We will use the Perl LDAP API, available on most operating systems. Perl syntax is straightforward; indeed, it even looks like a kind of pseudocode. Guided by line-by-line comments, readers who are not familiar with Perl should have no problem understanding the following examples. Some readers may even find the language attractive and decide to use it in the future.

Exhibit 12 is an example of a simple dump of the schema used by the directory server. The first line simply calls the Perl interpreter. If you have installed the interpreter at a different location, this line will be different on your system. The next line informs the interpreter that you will use the Net::LDAP library, which we will learn more about in Chapter 6 when we speak about the LDAP APIs. The Net::LDAP library offers all the functionality necessary to implement an LDAP client. Line 4 configures the variable "Host" that is used in line 6 when you open a connection to the machine where the LDAP server is running. In this example we assume that LDAP is running on the local machine. If it runs on a remote machine, put the network address or the DNS name of the computer instead of the local host. Line 6 also creates an LDAP object. In line 7, you bind to the LDAP server using a method of the LDAP object. The interesting stuff happens beginning with line 8. The method "schema" delivers the schema of the LDAP server; it delivers an object of the type "schema." In this example, we use the method "dump" on behalf the object "schema." This will fill your screen with a lot of information, most of which we will encounter in the following examples. You will have a complete listing of the attribute types, the object classes, the syntaxes, and the matching rules used by the directory. This information can be very helpful for the client, who can explore the directory schema and adapt its behavior to comply with the specific configuration. Line 13 releases the resources using the "unbind" method call.

01 #!/usr/bin/perl -w 02 use Net::LDAP ; 03 04 local $Host = "localhost" ; 05 06 $ldap = Net:: LDAP->new($Host) or die "$@" ; 07 $ldap->bind(); 08 my $schema = $ldap->schema(); 09 if ($schema) { 10 printf("Dump of Schema\n"); 11 $schema->dump(); 12 } 13 $ldap->unbind();

Exhibit 12: Perl Script Dumping out the Schema

Instead of dumping the whole schema, we could specify the particular information we need. For example, if we want a list of all object classes used in our directory, we would substitute line 13 ($schema->dump) in Exhibit 12 with the lines shown in Exhibit 13. These lines, besides dumping all object classes, instruct the server to print out another bit of interesting information, the OID of the object class. Even more interesting, using the piece of code displayed in Exhibit 14, we obtain the matching rules in the implementation of our LDAP server and the mapping between the numbers I mentioned in Chapter 3, when we discussed matching rules. Recall that every matching rule has a unique object identifier (OID) associated with it. The printout of matching rules will resemble the example depicted in Exhibit 15.

... @ObjectClasses = $schema->objectclasses(); foreach my $ObjectClass (@ObjectClasses) { printf("%s:%s\n", $ObjectClass, $schema->name2oid($ObjectClass)); } ...

Exhibit 13: Perl Script Printing the Object Classes

@MatchingRules = $schema->matchingrules(); printf("MatchingRules\n"); foreach my $MatchingRule (@MatchingRules) { printf("%s: %s\n",$MatchingRule, $schema->name2oid($MatchingRule)); }

Exhibit 14: Perl Script Printing the Matching Rules

CERTIFICATEEXACTMATCH: 2.5.13.34 CASEEXACTIA5MATCH: 1.3.6.1.4.1.1466.109.114.1 CASEIGNOREIA5MATCH: 1.3.6.1.4.1.1466.109.114.2 CASEIGNOREIA5SUBSTRINGSMATCH: 1.3.6.1.4.1.1466.109.114.3 CASEEXACTIA5SUBSTRINGSMATCH: 1.3.6.1.4.1.4203.1.2.1 INTEGERBITANDMATCH: 1.2.840.113556.1.4.803 INTEGERBITORMATCH: 1.2.840.113556.1.4.804

Exhibit 15: Example of Matching Rules

Finally, we present another piece of interesting information about the syntaxes recognized by the directory server. The code is shown in Exhibit 16, and a piece of the listing is shown in Exhibit 17. You can request this information for the whole directory or for single attributes or entries. The library, however, can do much more. For example, you can distinguish between which attributes an entry must have and which attributes it may have with the two methods calls:

@Syntaxes = $schema->syntaxes(); printf("Syntaxes\n"); foreach my $Syntax (@Syntaxes) { printf("%s:%s\n",$Syntax, $schema->name2oid($Syntax)); }

Exhibit 16: Perl Script Printing the Syntaxes

AUDIO: 1.3.6.1.4.1.1466.115.121.1.4 BINARY: 1.3.6.1.4.1.1466.115.121.1.5 BITSTRING: 1.3.6.1.4.1.1466.115.121.1.6 BOOLEAN: 1.3.6.1.4.1.1466.115.121.1.7 CERTIFICATE: 1.3.6.1.4.1.1466.115.121.1.8 CERTIFICATELIST: 1.3.6.1.4.1.1466.115.121.1.9 CERTIFICATEPAIR: 1.3.6.1.4.1.1466.115.121.1.10 COUNTRYSTRING: 1.3.6.1.4.1.1466.115.121.1.11 DISTINGUISHEDNAME: 1.3.6.1.4.1.1466.115.121.1.12

Exhibit 17: Example of Syntaxes

foreach my $Attr ($schema->must($Object)) { $Must .= sprintf("%s ",$Attr); } foreach my $Attr (@May=$schema->may($Object)) { $May .= sprintf("%s ",$Attr); } printf("Required Attributes:%s\n",$Must); printf("Allowed Attributes:%s\n",$May);

This delivers the information for the object class "person":

Required Attributes: cn sn Allowed Attributes: telephoneNumber description userPassword seeAlso

A word of warning, however: This method works only if the LDAP server supports LDAP (v3). It does not work with LDAP (v2).

If you want to learn more about the possibilities of exploring the directory schema, refer to the documentation of the software development kit (SDK) you will use. Most languages offer a number of methods or function calls allowing your client software to recognize the features offered by the LDAP server.

Extending the Directory Schema

If you look at the configuration files of your directory server implementation, you will see that you are using more than one schema file. In OpenLDAP, you must include all of these schema files. In other LDAP implementations, things may be slightly different, but you have to always include in some way the schema(s) you intend to use. Recall the example presented in Chapter 2, where we explicitly included three schema files: core.schema, 'cosine.schema, and inetorgperson.schema. Each of these files contains a number of object classes and attribute definitions. Sometimes, however, you have to store data that does not fit into any of the schemas declared in your directory implementation. The reasons for storage are manifold: Schemas do not take into account particular local requirements, and the data set of employees is very different between single enterprises. An example should make this clear. Let us assume you need a directory that holds data from a physician and that the physician's data (i.e., attributes) is not yet contained in any person object class, for example, the medical association the physician has joined, the year he subscribed to the medical association, and the subscription number to this association. These three attributes are not present in any object class defining persons. In this case, you have to extend the schema to hold the physician's object class.

If your schema files do not fit your requirements, then you have to extend your schema. This is no great problem, although you do have to consider a few things to arrive at a consistent schema. We address these immediate considerations in this chapter. The global planning phase is addressed in Chapter 9, when we discuss the design of directory services.

There are several ways to extend the schema. The following approach is a reasonable way to proceed, but there may be other approaches that are equally viable.

This was only a brief technical discussion about the possibility of extending the directory schema. We will address this issue in greater detail in Chapter 9, when we speak about the design of directory services.


 < Day Day Up > 

Категории