The Novell Import Conversion Export utility lets you easily import LDIF files into and export LDIF files from eDirectory. For more information, see Novell Import Conversion Export Utility.
In order for an LDIF import to work properly, you must start with an LDIF file that the Novell Import Conversion Export utility can read and process. This section describes the LDIF file format and syntax and provides examples of correct LDIF files.
LDIF is a widely used file format that describes directory information or modification operations that can be performed on a directory. LDIF is completely independent of the storage format used within any specific directory implementation, and is typically used to export directory information from and import data to LDAP servers.
LDIF is generally easy to generate. This makes it possible to use tools like awk or perl to move data from a proprietary format into an LDAP directory. You can also write scripts to generate test data in LDIF format.
Novell Import Conversion Export imports require LDIF 1 formatted files.The following are the basic rules for an LDIF 1 file:
An LDIF content record represents the contents of an entire entry. The following is an example of an LDIF file with four content records:
1 version: 1
2 dn: c=US
3 objectClass: top
4 objectClass: country
5
6 dn: l=San Francisco, c=US
7 objectClass: top
8 objectClass: locality
9 st: San Francisco
10
11 dn: ou=Artists, l=San Francisco, c=US
12 objectClass: top
13 objectClass: organizationalUnit
14 telephoneNumber: +1 415 555 0000
15
16 dn: cn=Peter Michaels, ou=Artists, l=San Francisco, c=US
17 sn: Michaels
18 givenname: Peter
19 objectClass: top
20 objectClass: person
21 objectClass: organizationalPerson
22 objectClass: iNetOrgPerson
23 telephonenumber: +1 415 555 0001
24 mail: Peter.Michaels@aaa.com
25 userpassword: Peter123
26
This LDIF file is composed of the following parts:
Table 140. LDIF File Components
LDIF change records contain modifications to be made to a directory. Any of the LDAP update operations (add, delete, modify, and modify DN) can be represented in an LDIF change record.
LDIF change records use the same format for the distinguished name specifier, attribute value specifier, and record delimiter as LDIF content records. (See LDIF Content Records for more information.) The presence of a changetype field is what distinguishes an LDIF change record from an LDIF content record. A changetype field identifies the operation specified by the change record.
A changetype field can take one of the following five forms:
Table 141. Changetype Field Forms
An add change record looks just like a content change record (see LDIF Content Records) with the addition of the changetype: add field immediately before any attribute value fields.
All records must be the same type. You can't mix content records and change records.
1 version: 1
2 dn: c=US
3 changetype: add
4 objectClass: top
5 objectClass: country
6
7 dn: l=San Francisco, c=US
8 changetype: add
9 objectClass: top
10 objectClass: locality
11 st: San Francisco
12
14 dn: ou=Artists, l=San Francisco, c=US
15 changetype: add
16 objectClass: top
17 objectClass: organizationalUnit
18 telephoneNumber: +1 415 555 0000
19
20 dn: cn=Peter Michaels, ou=Artists, l=San Francisco, c=US
21 changetype: add
22 sn: Michaels
23 givenname: Peter
24 objectClass: top
25 objectClass: person
26 objectClass: organizationalPerson
27 objectClass: iNetOrgPerson
28 telephonenumber: +1 415 555 0001
29 mail: Peter.Michaels@aaa.com
30 userpassword: Peter123
31
Because a delete change record specifies the deletion of an entry, the only fields required for a delete change record are the distinguished name specifier and a delete change type.
The following is an example of an LDIF file used to delete the four entries created by the LDIF file shown in The Add Change Type.
IMPORTANT: To delete entries you have previously added, reverse the order of the entries. If you don't do this, the delete operation will fail since the container entries would not be empty.
1 version: 1
2 dn: cn=Peter Michaels, ou=Artists, l=San Francisco, c=US
3 changetype: delete
4
5 dn: ou=Artists, l=San Francisco, c=US
8 changetype: delete
9
10 dn: l=San Francisco, c=US
11 changetype: delete
12
13 dn: c=US
14 changetype: delete
15
The modify change type lets you to specify the addition, deletion, and replacement of attribute values for an entry that already exists. Modifications take one of the following three forms:
Table 142. Modification Specifier Elements
The following is an example of a modify changetype that will add an additional telephone number to the cn=Peter Michaels entry.
1 version: 1
2 dn: cn=Peter Michaels, ou=Artists, l=San Francisco, c=US
3 changetype: modify
4 # add the telephone number to cn=Peter Michaels
4 add: telephonenumber
5 telephonenumber: +1 415 555 0002
6
Just as you can combine a mixture of modifications in a single LDAP modify request, you can specify multiple modifications in a single LDIF record. A line containing only the hyphen (-) character is used to mark the end of the attribute value specifications for each modification specifier.
The following example LDIF file contains a mixture of modifications:
1 version: 1
2
3 # An empty line to demonstrate that one or more
4 # line separators between the version identifier
5 # and the first record is legal.
6
7 dn: cn=Peter Michaels, ou=Artists, l=San Francisco, c=US
8 changetype: modify
9 # Add an additional telephone number value.
10 add: telephonenumber
11 telephonenumber: +1 415 555 0002
12 -
13 # Delete the entire fascimiletelephonenumber attribute.
14 delete: facsimileTelephoneNumber
15 -
16 # Replace the existing description (if any exists)
17 # with two new values.
18 replace: description
19 description: guitar player
20 description: solo performer
21 -
22 # Delete a specific value from the telephonenumber
23 # attribute.
24 delete: telephonenumber
25 telephonenumber: +1 415 555 0001
26 -
27 # Replace the existing title attribute with an empty
28 # set of values, thereby causing the title attribute to
29 # be removed.
30 replace: title
31 -
32
The modify DN change type lets you rename an entry, move it, or both. This change type is composed of two required fields and one optional field.
Table 143. Modify DN Change Type Fields
The following is an example of a modify DN changetype that shows how to rename an entry:
1 version: 1
2
3 # Rename ou=Artists to ou=West Coast Artists, and leave
4 # its old RDN value.
5 dn: ou=Artists,l=San Francisco,c=US
6 changetype: moddn
7 newrdn: ou=West Coast Artists
8 deleteoldrdn: 1
9
The following is an example of a modify DN changetype that shows how to move an entry:
1 version: 1
2
3 # Move cn=Peter Michaels from
4 # ou=Artists,l=San Francisco,c=US to
5 # ou=Promotion,l=New York,c=US and delete the old RDN.
5 dn: cn=Peter Michaels,ou=Artists,l=San Francisco,c=US
6 changetype: moddn
7 newrdn: cn=Peter Michaels
8 deleteoldrdn: 1
9 newsuperior: ou=Promotion,l=New York,c=US
10
The following is an example of a modify DN changetype that shows how to move an entry and rename it at the same time:
1 version: 1
2
3 # Move ou=Promotion from l=New York,c=US to
4 # l=San Francisco,c=US and rename it to
5 # ou=National Promotion.
5 dn: ou=Promotion,l=New York,c=US
6 changetype: moddn
7 newrdn: ou=National Promotion
8 deleteoldrdn: 1
9 newsuperior: l=San Francisco,c=US
10
IMPORTANT: The LDAP 2 modify RDN operation doesn't support moving entries. If you try to move an entry using the LDIF newsuperior syntax with an LDAP 2 client, the request will fail.
To fold a line in an LDIF file, simply insert a line separator (a newline or a carriage return/newline pair) followed by a space at the place where you want the line folded. When the LDIF parser encounters a space at a beginning of the line, it knows to concatenate the rest of the data on the line with the data on the previous line. The leading space is then discarded.
You should not fold lines in the middle of a multi-byte UTF-8 character.
The following is an example of an LDIF file with a folded line (see lines 13 and 14):
1 version: 1
2 dn: cn=Peter Michaels, ou=Artists, l=San Francisco, c=US
3 sn: Michaels
4 givenname: Peter
5 objectClass: top
6 objectClass: person
7 objectClass: organizationalPerson
8 objectClass: iNetOrgPerson
9 telephonenumber: +1 415 555 0001
10 mail: Peter.Michaels@aaa.com
11 userpassword: Peter123
12 description: Peter is one of the most popular music
13 ians recording on our label. He's a big concert dr
14 aw, and his fans adore him.
15
If you have problems with an LDIF file, consider the following:
You might occasionally encounter LDIF files in which a record to add one entry comes before a record to add its parents. When this happens, an error is generated because the new entry's parent does not exist when the LDAP server attempts to add the entry.
To solve this problem, simply enable the use of forward references. When you enable the creation of forward references and an entry is going to be created before its parent exists, a placeholder called a forward reference is created for the entry's parent to allow the entry to be successfully created. If a later operation creates the parent, the forward reference is changed into a normal entry.
It is possible that one or more forward references will remain once your LDIF import is complete (if, for example, the LDIF file never created the parent for an entry). In this case, the forward reference will appear as an Unknown object in ConsoleOne. Although you can search on a forward reference entry, you cannot read attributes (except objectClass) from the forward reference entry because it does not have any attributes or attribute values. However, all LDAP operations will work normally on the real object entries located below the forward reference.
Forward reference entries have an object class of Unknown and also have their internal NDS EF_REFERENCE entry flag set. In ConsoleOne, entries with an object class of Unknown are represented by a round yellow icon with a question mark in the center. You can use LDAP to search for objects with an Unknown object class, although there is currently no way to access the entry flag settings through LDAP to be sure that they are forward reference entries.
You can change a forward reference entry into an normal object by simply creating it (using, for example, an LDIF file or an LDAP client request). When you ask eDirectory to create an entry that already exists as a forward reference, eDirectory transforms the existing forward reference entry into the object you asked it to create.
To enable forward references during an LDIF import:
In ConsoleOne, select Wizard > NDS Import/Export.
Click Import LDIF File > Next.
Enter the name of the LDIF file containing the data you want to import > click Next.
Select the LDAP server where the data will be imported.
Click Advanced > Allow Forward References > Close.
Click Next > Finish to begin the LDIF import.
To enable forward references during a data to data server migration:
In ConsoleOne, select Wizard > NDS Import/Export.
Click Migrate Data between LDAP Servers > Next.
Select the LDAP server holding the entries you want to migrate > click Next.
Specify search criteria for the entries you want to migrate > click Next.
Select the LDAP server where the data will be migrated.
Click Advanced > Allow Forward References > Close.
Click Next > Finish.
To enable forward references in the command line interface, use the -F LDAP destination handler option.
For more information, see LDIF Destination Handler Options.
You can check the syntax of an LDIF file before you process the records in the file by using the Display Operations but Do Not Perform LDIF source handler option.
The LDIF source handler always checks the syntax of the records in an LDIF file as it processes them. Using this option disables the processing of the records and lets you verify the syntax.
To check your syntax during an LDIF import:
In ConsoleOne, select Wizard > NDS Import/Export.
Click Import LDIF File > Next.
Enter the name of the LDIF file containing the data you want to import > click Advanced.
Click Display Operations but Do Not Perform > Close > Next.
Select the LDAP server where the data will be imported.
Click Next > Finish to begin the LDIF import.
To check the syntax of an LDIF file in the command line interface, use the -n LDIF source handler option.
For more information, see LDIF Source Handler Options.
The Novell Import Conversion Export utility automatically creates an LDIF file listing any records that failed processing by the destination handler. You can edit the LDIF error file generated by the utility, fix the errors, then re-apply it to the server to finish an import or data migration that contained failed records.
In ConsoleOne, select Wizard > NDS Import/Export.
Click the task you want to perform.
Click Advanced.
In the Log File field, specify a filename where output messages (including error messages) will be logged.
In the LDIF Output File for Failed Records field, specify a filename where entries that fail are output in LDIF format.
You can use this file to examine or correct errors.You can also reapply a modified (corrected) version of this file to the directory.
Click Close.
Follow the online instructions to finish your selected task.
To configure error log options in the command line utility, use the -l general option.
For more information, see General Options.
To understand some LDIF problems, you might need to see how the LDAP client SDK is functioning. You can set the following debugging flags for the LDAP source handler, the LDAP destination handler, or both.
Table 144. LDAP SDK Debugging Flags
To enable this functionality, use the -e option for the LDAP source and LDAP destination handlers. The integer value you give for the -e option is a bitmask that enables various types of debugging information in the LDAP SDK.
For more information, see LDAP Source Handler Options and LDAP Destination Handler Options.
Because LDIF can represent LDAP update operations, you can use LDIF to modify the schema.
To add a class, simply add an attribute value that conforms to the specification for NDSObjectClassDescription to the objectClasses attribute of the subschemaSubentry.
NDSObjectClassDescription = "(" whsp
numericoid whsp
[ "NAME" qdescrs ]
[ "DESC" qdstring ]
[ "OBSOLETE" whsp ]
[ "SUP" oids ]
[ ( "ABSTRACT" / "STRUCTURAL" / "AUXILIARY" ) whsp ]
[ "MUST" oids ]
[ "MAY" oids ]
[ "X-NDS_NOT_CONTAINER" qdstrings ]
[ "X-NDS_NONREMOVABLE" qdstrings ]
[ "X-NDS_CONTAINMENT" qdstrings ]
[ "X-NDS_NAMING" qdstrings ]
[ "X-NDS_NAME" qdstrings ]
whsp ")"
The following example LDIF file adds the person objectClass to the schema:
1 version: 1
2 dn: cn=schema
3 changetype: add
4 objectClasses: ( 2.5.6.6 NAME 'person' DESC 'Standard
5 ObjectClass' SUP ndsLoginProperties STRUCTURAL MUST
6 (cn $ sn) MAY (description $ seeAlso $ telephoneNum
7 ber $ fullName $ givenName $ initials $ uid $ userPa
8 ssword) X-NDS_NAMING ('cn' 'uid') X-NDS_CONTAINMENT
9 ('organization' 'organizationalUnit' 'domain') X-NDS
10 _NAME 'Person' X-NDS_NOT_CONTAINER '1' X-NDS_NONREMO
11 VABLE '1')
12
Mandatory attributes are listed in the MUST section of the object class description. For the person object class, the mandatory attributes are cn and sn.
Optional attributes are listed in the MAY section of the object class description. The optional attributes in the person object class are description, seeAlso, telephoneNumber, fullName, givenName, initials, uid, and userPassword.
The object classes that can contain the object class being defined are given in the X-NDS_CONTAINMENT section of the object class description. The person object class can be contained by the organization, organizationalUnit, and domain object classes.
To add an attribute, simply add an attribute value that conforms to the specification for NDSAttributeTypeDescription to the attributes attribute of the subschemaSubentry.
NDSAttributeTypeDescription = "(" whsp
numericoid whsp ; AttributeType identifier
[ "NAME" qdescrs ] ; name used in AttributeType
[ "DESC" qdstring ] ; description
[ "OBSOLETE" whsp ]
[ "SUP" woid ] ; derived from this other AttributeType
[ "EQUALITY" woid] ; Matching Rule name
[ "ORDERING" woid] ; Matching Rule name
[ "SUBSTR" woid ] ; Matching Rule name
[ "SYNTAX" whsp noidlen whsp ] ; Syntax OID
[ "SINGLE-VALUE" whsp ] ; default multi-valued
[ "COLLECTIVE" whsp ] ; default not collective
[ "NO-USER-MODIFICATION" whsp ] ; default user modifiable
[ "USAGE" whsp AttributeUsage ] ; default userApplications
[ "X-NDS_PUBLIC_READ" qdstrings ]
; default not public read ('0')
[ "X-NDS_SERVER_READ" qdstrings ]
; default not server read ('0')
[ "X-NDS_NEVER_SYNC" qdstrings ]
; default not never sync ('0')
[ "X-NDS_NOT_SCHED_SYNC_IMMEDIATE" qdstrings ]
; default sched sync immediate ('0')
[ "X-NDS_SCHED_SYNC_NEVER" qdstrings ]
; default schedule sync ('0')
[ "X-NDS_LOWER_BOUND" qdstrings ]
; default no lower bound('0')
;(upper is specified in SYNTAX)
[ "X-NDS_NAME_VALUE_ACCESS" qdstrings ]
; default not name value access ('0')
[ "X-NDS_NAME" qdstrings ] ; legacy NDS name
whsp ")"
The following example LDIF file adds the title attribute type to the schema:
1 version: 1
2 dn: cn=schema
3 changetype: add
4 attributeTypes: ( 2.5.4.12 NAME 'title' DESC 'Standa
5 rd Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{
6 64} X-NDS_NAME 'Title' X-NDS_NOT_SCHED_SYNC_IMMEDIA
7 TE '1' X-NDS_LOWER_BOUND '1')
8
An attribute defaults to multi-valued unless it is explicitly made single-valued. The following example LDIF file makes title single-valued by adding the SINGLE-VALUE keyword after the SYNTAX section:
1 version: 1
2 dn: cn=schema
3 changetype: add
4 attributeTypes: ( 2.5.4.12 NAME 'title' DESC 'Standa
5 rd Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{
6 64} SINGLE-VALUE X-NDS_NAME 'Title' X-NDS_NOT_SCHED
7 _SYNC_IMMEDIATE '1' X-NDS_LOWER_BOUND '1')
8
Although adding new schema elements is an acceptable practice, modifying or extending existing schema elements is usually dangerous. Since every schema element is uniquely identified by an OID, when you extend a standard schema element, you effectively create a second definition for the element even though it still uses the original OID. This can cause incompatibility problems.
There are times when it is appropriate to change schema elements. For example, you might need to extend or modify new schema elements as you refine them during development. Instead of adding new attributes directly to a class, you should generally only use auxiliary classes to:
The following sample LDIF file creates two new attributes, creates an auxiliary class with these new attributes, and then adds an inetOrgPerson entry with the auxiliary class as an object class of the entry and with values for the auxiliary class attributes.
version: 1
# Add an attribute to track a bear's hair. The attribute is
# multi-valued, uses a case ignore string syntax,
# and has public read rights
# Values may include: long hair, short, curly, straight,
# none, black, and brown
# X-NDS_PUBLIC_READ '1' The 1 allows public read,
# 0 denies public read
dn: cn=schema
changetype: modify
add: attributeTypes
attributeTypes: ( 2.16.840.1.113719.1.186.4.10 NAME
'bearHair' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
X-NDS_PUBLIC_READ '1' )
# add an attribute to store a bear's picture
dn: cn=schema
changetype: modify
add: attributeTypes
attributeTypes: ( 2.16.840.1.113719.1.186.4.11 NAME
'bearPicture' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5
SINGLE-VALUE )
# create an Auxiliary class for the bearfeatures
dn: cn=schema
changetype: modify
add: objectclasses
objectclasses: (2.16.840.1.113719.1.186.6.101 NAME
'bearFeatures' MAY (bearHair $ bearPicture) AUXILIARY)
# now create a user named booboo
dn: cn=booboo,o=jellystone
changetype: add
cn: booboo
sn: bear
givenName: booboo
bearHair: Short
bearHair: Brown
bearHair: Curly
bearPicture:< file:///c:/tmp/alien.jpg
objectClass: top
objectClass: person
objectClass: inetOrgPerson
objectClass: bearFeatures
# now create a person named yogi that will later be changed
# into a bear when bearFeatures is added to its objectClass
# list
dn: cn=yogi,o=jellystone
changetype: add
cn: yogi
sn: bear
givenName: yogi
objectClass: top
objectClass: person
objectClass: inetOrgPerson
# now morph yogi into a bear by adding bearFeatures
dn: cn=yogi,o=jellystone
changetype: modify
add: objectClass
objectClass: bearFeatures
-
add: bearHair
bearHair: long
bearHair: black
#bearPicture:< file:///c:/tmp/yogi.jpg>
-
# to morph yogi back to a person, simply delete the
# objectClass bearFeatures
dn: cn=yogi,o=jellystone
changetype: modify
delete: objectClass
objectClass: bearFeatures
When removing auxiliary classes, you don't have to delete all of the values associated with the auxiliary class when you remove the auxiliary class from the objectClass list. eDirectory does this automatically.
If the auxiliary class had "MUST" attributes, they must all be specified in the same modify operation that adds the auxiliary class to the objectClass list, or the modification will fail.
Known Problems with XML Parsing
XML processing of any LDIF Record (LDIF format or records generated from LDAP server) will not succeed if the individual records will not satisfy all the XML rules specified in the XML file