Novell is now a part of Micro Focus

SCHMAP: NDS Schema Extension and LDAP-to-NDS Mapping Utility

Articles and Tips: article

KEVIN BURNETT
Software Engineer
Strategic Partner Engineering Group

CARY ANDREWS
Senior Software Engineer
Strategic Partner Engineering Group

01 Sep 1999


Examines the problem of running an application that uses LDAP APIs on a NetWare network and explores how to use SCHMAP as an interim solution.

Introduction

The LDAP specification provides a means for extending the LDAP schema via the Modify operation. Currently Novell's LDAP Services for NDS does not support this functionality. This functionality will available in the NDS 8 SP1 release. What should you do if you have an application that uses LDAP APIs and you want to run it on a NetWare network?

This article examines this problem and explores using the SCHMAP utility as an interim solution.

The Problem

Although Novell's LDAP Services for NDS does not currently support the LDAP specification, which allows you to extend the LDAP schema via the Modify operation, many developers have written applications that use the LDAP APIs. Quite a few of these applications extend the LDAP schema and interact with the resulting created objects and attributes. What should a developer do in this situation? There are a couple of solutions, most of which are quite undesirable:

First the applications could be re-written to utilize one of Novell's proprietary API sets such as our DSAPI for C/C++. Rewrite your code? Sounds like a lot of fun, huh?

Second, if the application was written using a Rapid Application Development (RAD) programming language, new, NDS specific, modules could be linked in to give proprietary NDS access.

What if you don't want to change your code? Running the LDAP application on Novell's LDAP Services for NDS will produce an error when the application tries to extend the LDAP/NDS schema. Errors will also be produced when the application tries to create objects from the non-existent class and attribute definitions. This will produce even more errors when the application tries to interact with the non-existent objects.

The Solution

SCHMAP was created to provide an interim solution to this problem. SCHMAP will run a script file containing all the information needed to extend the NDS schema with a given application's class and attribute definitions. SCHMAP will then create LDAP to NDS mappings, which allow the application to access NDS via LDAP SDK calls without changing any source code.

After SCHMAP has been run, the LDAP application will run without any problems, since the required class and attribute definitions now exist in the NDS schema.

What Is SCHMAP?

SCHMAP is a utility that reads a script file that contains all the information needed to extend the NDS schema and do the LDAP mappings. This script file is a LDAP Data Interchange Format (LDIF) type file. This file format was chosen since LDIF is somewhat of an industry standard for modifying a directory whether it be the schema or importing/exporting data. The specification was put together by Gordon Good, of Netscape Communications. The draft can be inspected at ftp://ftp.ietf.org/internet-drafts/draft-good-ldap-ldif-03.txt.

SCHMAP makes extensive use of the Novell DSAPI. It is available in both Novell NetWare NLM format and DOS command line executable (.EXE) format. SCHMAP runs on Windows 95/98/NT as well as a NetWare server. SCHMAP will also work with NDS on virtually any platform. It has been extensively tested with NDS on NetWare, Solaris and NT.

SCHMAP is being submitted to the Novell Developer Kit (NDK) and is available for download from Novell's WEB site.

Usage

SCHMAP is a command-line utility. To view the SCHMAP usage screen, go to a DOS prompt or the NetWare Server console, make sure you have the correct path, then type SCHMAP. The following information will be displayed:

Figure 1: The SCHMAP usage screen

To use SCHMAP the user types "SCHMAP," followed by the LDIF file name, the NDS tree's LDAP group object distinguished name and then an option if desired.


Example 1: schmap "sys:system"schext.ldf" "LDAP Group - GUNLOCK.NDS"

In this example, "sys:system"schext.ldf" is the complete path and name of the LDIF file. "LDAP Group - GUNLOCK.NDS" is the LDAP group object distinguished name. It is made up of the LDAP group object name followed by a dot and then the context the object is located in.

Together they form the complete distinguished name of the LDAP group object. You can verify the name of the LDAP group object by running NetWare Administrator or ConsoleOne and navigating to the container where the LDAP group object is stored.

Figure 2, which is an NWAdmin screen shot, shows the highlighted LDAP group object's name to be "LDAP Group - UNLOCK". The container it is located in is "NDS". When joined together they form the fully distinguished name of the LDAP group object: " LDAP Group - GUNLOCK.NDS".

Figure 2: NWAdmin shows the LDAP group object's name.

The LDAP group object DN argument must be entered correctly for SCHMAP to function properly. SCHMAP will check the group object to ensure it exists prior to execution of the schema extensions and mappings. If it doesn't exist, an error message will be displayed and logged in the log file.

Note: SCHMAP creates a log file when the utility executes. The log file name is the same name (path and file name) as the LDIF file name entered on the command line, with a .LOG extension added in the place of the original extension. For example, if the file name MYSCHEMA.LDIF were entered on the command line, the log file would be MYSCHEMA.LOG.

Command Line Options and Function

There are five command line options provided by SCHMAP. They are as follows:

/C, /R, /S, /M, /I

/C counts the attributes and classes in the LDIF file and then exits. The LDIF parser in SCHMAP is very quick. This option will complete very quickly.

/R removes the schema extensions and mappings contained in the LDIF file from NDS. You must use the same LDIF file to remove NDS schema extensions and LDAP to NDS mappings as you used to create them. If you don't SCHMAP will produce errors.

Note: If any of the object classes or attribute definitions are currently in use, you will be unable to remove them using the /R option.

/S adds only the NDS schema extensions contained in the LDIF file. No LDAP to NDS mappings will take place.

/M adds only the LDAP to NDS mappings contained in the LDIF file. No NDS schema extensions will be added.

/I when this option is used the utility will ignore errors that may occur during schema extensions and run through the file to completion. All screen output is logged to a file for review by the user at a later time. This option may be used with any of the other options or by itself, however, it has no effect when using /C.


Example 2: schmap "sys:system"schext.ldf" "LDAP Group - GUNLOCK.NDS" /C

In this example the utility would display a count of attributes and classes in the LDIF file, and then exit.

User Interface

SCHMAP was designed to be a command line utility for simplicity. Figure 3 shows what the user interface will display during a normal execution:

Figure 3: SCHMAP user interface.

After the greeting is displayed, you will need to enter your username and password. The username may be entered in type-less or fully typed representation. (If running on a NetWare server, you may enter your username type-less, since the CLIB libraries will resolve this for you.)

Next, the message "Adding Schema Extensions And LDAP To NDS Mappings" is displayed followed by the two possible states of SCHMAP:

  • Parsing the schema file indicates that the LDIF file is being parsed.

  • Adding schema extensions and mappings indicates that the class and attribute definitions, parsed from the LDIF file, are being created in the NDS schema. Because this operation can take quite a while due to the speed of the DSAPIs, SCHMAP provides a `whirly-gig' that spins indicating that SCHMAP has not suspended operation. During this step the LDAP to NDS mappings, also parsed from the LDIF file, are being added to the LDAP Services for NDS mapping tables.

SCHMAP Ended indicates that the utility has completed execution.

Note: The spinning whirly-gig mentioned above is implemented for all states. You just might not see it with the parsing state due to the speed of the operation.

Any errors that occur during these operations will be displayed on the screen and logged into the log file. Should an error occur, a message will appear suggesting to the user that they should review the log file.

If you start the utility and then decide to exit without performing the operations, just press Enter at the user name prompt without entering a user name.

Sample LDIF File

The LDIF file format used in SCHMAP follows the LDIF RFC 2251 specification very closely, but a few exceptions have been made to accommodate NDS. With the current release of SCHMAP, the format of the LDIF file has been modified to make entries more logical and easier to add. Traditional LDIF files put all the information for one schema entry on one line of the file. SCHMAP's parser, on the other hand, uses the following format:

# Sample LDIF File



    # Attributes

    dn: cn=schema

    changetype: modify

    add: newattribute

    name: aTestAttribute

    syntax: SYN_INTEGER

    oid: 1.3.114.7.4.2.0.1

    flag: DS_SINGLE_VALUED_ATTR

    lowerbound: 0

    upperbound: 20

    map: aTestAttribute

    -



    # Classes

    dn: cn=schema

    changetype: modify

    add: newclass

    name: aTestClass

    oid: 1.3.114.7.3.2.0.2

    flag: DS_EFFECTIVE_CLASS

    superior: top

    containedby: organization

    containedby: organizational unit

    namedby: cn

    requires: cn

    allows: full name

    allows: telephone number

    map: aTestClass

    -

File Format Explanation

The first four lines of each block are mandatory for each class or attribute. The single dash at the end of each block must also be present. All lines must contain a label and a value. If a line has a label and no value, the utility will display an error and exit. Comments are preceded by a pound sign (#).

Lets look at each of these lines that comprise this sample LDIF file. For each line we will state whether the line is mandatory or optional. We'll start with the attribute definition first.

Note: For a complete description of the syntax, flags, and other aspects of the NDS schema you can go to the following web site: http://developer.novell.com/ndk/doc/ndslib/index5.htm

dn: cn=schema

Mandatory. This is part of the LDIF Specification. This indicates the distinguished name as defined in RFC 2253. In this case the DN will be schema. It signifies that this will be a change in the directory's schema, not objects.

changetype: modify

Mandatory. This indicates the operation we are going to execute. In this case, it will be a modification to the NDS schema.

add: newattribute

Mandatory. This indicates what is going to be added to the NDS schema. In this case it is a new attribute definition.

name: aTestAttribute

Mandatory. This is the name of the new attribute definition.

syntax: SYN_INTEGER

Mandatory. This is required by NDS. It indicates what type of data the attribute will hold. Possible syntax values for attributes include:

SYN_UNKNOWN SN_DIST_NAME SYN_CE_STRING SYN_CI_STRING SYN_PR_STRING SYN_NU_STING SYN_CI_LIST * SYN_BOOLEAN SYN_INTEGER SYN_OCTET_STRING SYN_TEL_NUMBER SYN_FAX_NUMBER SYN_NET_ADDRESS SYN_OCTET_LIST * SYN_EMAIL_ADDRESS * SYN_PATH SYN_REPLICA_POINTER * SYN_OBJECT_ACL * SYN_PO_ADDRESS SYN_TIMESTAMP * SYN_CLASS_NAME SYN_STREAM SYN_COUNTER SYN_BACK_LINK * SYN_TIME SYN_TYPED_NAME SYN_HOLD * SYN_INTERVAL SYNTAX_COUNT *

Note: The syntax types above followed by an asterisk (*) are currently not supported in LDAP, but are supported in NDS.

oid: 1.3.114.7.4.2.0.1

Optional. This value is used by NDS (NetWare 5 and later). It is used as a unique identifier for the attribute definition. It is also LDAP compliant. The value shown may or may not be a valid OID.

Note: The OID value must be entered in the standard format as shown. This value will be compressed into a special format when stored in NDS. SCHMAP takes care of this conversion.

flag: DS_SINGLE_VALUED_ATTR flag: DS_SYNC_IMMEDIATE

Optional. This is NDS specific. The flags indicate things that define the attribute such as whether it can have multiple values or not. Numeric values are not allowed with this release. The flag: value can comprise multiple entries (as shown). Possible flag values for attributes include:

DS_SINGLE_VALUED_ATTR DS_SIZED_ATTR DS_NONREMOVABLE_ATTR DS_READ_ONLY_ATTR DS_HIDDEN_ATTR DS_STRING_ATTR DS_SYNC_IMMEDIATE DS_PUBLIC_READ DS_SERVER_READ DS_WRITE_MANAGED DS_PER_REPLICA DS_SCHEDULE_SYNC_NEVER DS_OPERATIONAL

lowerbound: 0

Optional. This is NDS specific and defines the lower bound of the value stored in this attribute.

upperbound: 20

Optional. This is NDS specific and defines the upper bound of the value stored in this attribute.

map: aTestAttribute

Optional. For this version of SCHMAP this value is not used.

Now lets look at the LDIF entry for a class:

dn: cn=schema

Mandatory. This is part of the LDIF Specification. This indicates the distinguished name as defined in RFC 2253. In this case the DN will be schema. It signifies that this will be a change in the directory's schema, not objects.

changetype: modify

Mandatory. This indicates the operation we are going to execute. In this case, it will be a modification to the NDS schema.

add: newclass

Mandatory. This indicates what is going to be added to the NDS schema. In this case it is a new class definition.

name: aTestClass

Mandatory. This is the name of the new class.

oid: 1.3.114.7.3.2.0.2

Optional. This is used by NDS (NetWare 5 and later). It is used as a unique identifier for the attribute definition. It is also LDAP compliant. The value shown may or may not be a valid OID.

flag: DS_EFFECTIVE_CLASS

Optional. This is NDS specific. The flags indicate things that define the class such as whether you can create objects from it or not. The flag: value can comprise multiple entries. Possible flag values include:

DS_CONTAINER_CLASS DS_EFFECTIVE_CLASS DS_NONREMOVABLE_CLASS DS_AMBIGUOUS_NAMING DS_AMBIGUOUS_CONTAINMENT DS_AUXILIARY_CLASS DS_OPERATIONAL_CLASS

superior: top

Optional. Every class has a list of super classes. These are classes that contribute to the definition of the new class. A class inherits all the definition information of its super classes. Inheritance forms a hierarchy of classes, each contributing to an object's final characteristics. This is where you inherit characteristics from. All classes must inherit from a superclass except auxiliary classes (flag: DS_AUXILIARY_CLASS). The superior: value can comprise multiple entries.

containedby: organization containedby: organizational unit

Optional. This specifies the classes to which an object can be immediately subordinate. By limiting the possible locations for an object, containment ensures that objects are added in a consistent and logical fashion. Effective classes (those that can be instantiated into objects) must specify at least one containment class. Any NDS container class, including those created by extending the schema, may be included here. The containedby: value can comprise multiple entries.

namedby: cn

Optional. A class must define one or more naming attributes if it is an effective class. These are the only attributes that can serve as part of the attribute's name. When you create an object from this class, you must assign a value to the object's naming attribute, otherwise there is no way to interact with the object. The naming: value can comprise multiple entries.

requires: cn

Optional. These are attributes that require a value when you create an object from this class. The requires: value can comprise multiple entries.

allows: full name allows: telephone number

Optional. These are attributes that are not required to have values assigned to them when the object is created from the class. The value can be added at a later time. The allows: value can comprise multiple entries.

map: aTestClass

Optional. For this version of SCHMAP this value is not used.

Additional LDIF File Format Conditions

  • For attributes, only flag: can comprise multiple entries.

  • For classes, all entries (below the first four required lines) except oid: and map: can comprise multiple entries.

  • It is important to note that order is important in this file. All attributes must be added before classes, and all classes that use other classes (such as containment or superior) must follow those classes they use. Errors will be generated should these restrictions be violated.

Note: When running SCHMAP (.EXE) from a Novell/NT client when you are logged into multiple trees, ensure that the tree you are extending is the "current" tree. This can be done by opening up Network Neighborhood, selecting the desired tree, and then selecting "Set Current Tree" with the right mouse button.

Experimentation with SCHMAP

To see for yourself how SCHMAP works, perform the following exercises:

We will use the sample LDIF file above. Copy the contents into a text file to get it ready for use. Name the file TEST.LDIF. Remove the oid: lines from each section, as these are not valid values.

  1. Load NetWare Administrator.

    1. Double-click on `LDAP Group' object.

    2. Look at the last entry in `Attribute Map' and Class Map.' Note the last entry in each. (This will prove that there is no hocus pocus going on with SCHMAP).

    Figure 4: NWADMIN showing the LDAP Group object.

    Figure 5: NWADMIN shows the new LDAP class mappings.

  2. Load NDS Manager.

    1. Open the `Object' menu and select `Schema Manager.'

    2. Note that the new class is not in the class window and that the new attribute is not in the attribute window.

    Figure 6: NDS Manager Screen.

  3. Run SCHMAP.

    1. Login as admin. Use NWAdmin to find your LDAP group object name and context.

    2. At the command line type SCHMAP "test.ldif" "ldap group - "server_name.context"", substituting your server name and context for the "server_name.context".

      Figure 7: SCHMAP running at the command line.

    3. Look in NetWare Administrator at the LDAP Group object to see the new mappings (attribute and class).

      Figure 8: NWAdmin shows the new LDAP attribute mappings.

      Figure 9: NWAdmin shows the LDAP class mappings.

    4. Look in NDS Manager/Schema Manager to see the new attribute and class (F5 will update the screen).

      Figure 10: NDS Schema Manager shows new classes and attributes.

  4. Run SCHMAP with the /R "remove" option.

    1. At the command line type SCHMAP "test.ldif" "ldap group -"server_name.context""/R, substituting your server name and context for the "server_name.context".

      Figure 11: SCHMAP running with the /R option.

    2. Look in NetWare Administrator at the LDAP Group object to see that the new class and attribute mappings are removed.

    3. Look in NDS Manager/Schema Manager to see that the new class and attribute are removed.

Summary

SCHMAP was created to provide an interim solution for allowing LDAP applications that extend the schema to run correctly on NDS. SCHMAP accomplishes this by parsing an LDIF text file containing class and attribute information, extending the NDS schema with this information and then providing LDAP to NDS mappings to Novell's LDAP Services for NDS. SCHMAP is available as an EXE or NLM. SCHMAP will run and access any current implementation of NDS such as NDS for NT, Solaris and NetWare.

* Originally published in Novell AppNotes


Disclaimer

The origin of this information may be internal or external to Novell. While Novell makes all reasonable efforts to verify this information, Novell does not make explicit or implied claims to its validity.

© Copyright Micro Focus or one of its affiliates