Sun Java logo     Previous      Contents      Index      Next     

Sun logo
Sun ONE Directory Server Resource Kit 5.2 Tools Reference 

Chapter 20
The Java-based LDIF Generator Utility

MakeLDIF is a Java-based utility that generates LDAP Data Interchange Format (LDIF ) files for importation into a Lightweight Directory Access Protocol (LDAP) directory server. This chapter provides instructions on how to use MakeLDIF. It contains the following sections:


Overview

MakeLDIF is a Java-based utility for generating LDIF files. Because the program is written in Java, it requires a Java runtime environment to function properly. The MakeLDIF program was designed to work with Java 1.2 and higher, although more recent versions typically exhibit better performance. The information needed to generate the entries is specified in a template file which can be customized to produce LDIF files for a wide variety of scenarios. The tool can be found in the DSRK_base/java/MakeLDIF directory.


Note

This chapter provides basic information required to use MakeLDIF. See the MakeLDIF Usage Guide for more specific information about MakeLDIF features and capabilities. It is located in the DSRK_base/java/MakeLDIF directory.



Command Usage

MakeLDIF is used to generate sample data for importation into an LDAP directory server. Other utilities do exist for this purpose but MakeLDIF offers features not available in those tools. The command-line options can be used to control these features and other aspects of the input and output.


Note

In order to use MakeLDIF, you should be in the same directory as the MakeLDIF.jar file. By default, the directory is DSRK_base/java/MakeLDIF.


Syntax

The syntax of the MakeLDIF program on the command-line can take either of the following forms:

java -jar MakeLDIF.jar -t example.template -o output.ldif

java -cp MakeLDIF.jar MakeLDIF -t example.template -o output.ldif

This syntax will use the template defined in the file example.template and write the output into a file titled output.ldif.


Note

If the Java executable is not currently in your path, then you may specify the absolute path to the Java executable you wish to use.


Options

The MakeLDIF program has options available to customize the way that it operates. These are detailed in Table 20-1. The MakeLDIF -H command and option when run on the command-line will display brief descriptions of the command syntax, options, and parameters.

Table 20-1  Options for MakeLDIF 

Option

Parameter

Purpose

-f

filename

Specifies the name of the file containing first names to use in the entry generation process. By default, the MakeLDIF program will use a file named first.names included in the current working directory. If a custom first name file is used, it should contain only first name information with one first name per line.

-l

filename

Specifies the name of the file containing last names to use in the entry generation process. By default, the MakeLDIF program will use a file named last.names included in the current working directory. If a custom last name file is used, it should contain only last name information with one last name per line.

-t

filename

Specifies the template file that will be used to determine how to create the LDIF file. This is a required parameter. The format of the template file is discussed in Customizing the Template File.

-o

filename

Specifies the name of the output LDIF file to generate. This is a required parameter.

-d

filename

Specifies the name of a file to which the DNs of generated entries will be written. This is useful for a number of utilities that can make use of a DN file.

-b

filename

Specifies the name of a file to which bind information for the generated entries will be written. The format will be one user per line with the DN followed by a tab and the password for the user with that DN.

-L

filename

Specifies the name of a file to which login information for the generated entries will be written. The format will be one user per line with the login ID followed by a tab and the password for that user.

-i

attribute

Specifies the name of the attribute that should be used as the login ID. By default, the uid attribute will be used as the login ID.

-F

filename

Specifies that search filters constructed from the generated entries will be written to the specified file. You will need to use the "-T" option to specify which filter types to generate.

-T

 

type

Specifies filter types that should be generated. The format of type is the name of the attribute followed by a colon and a comma-separated list of filter types to create for that attribute. Allowable filter types are "eq" and "sub". Example: "-T uid:eq -T cn:eq,sub".

-s

value

Specifies the seed to use for the random number generator. If no seed is specified, then a value will be chosen based on the current time. If a positive integer value is given, then that will be used as the seed to the random number generator. Using the same template file and the same random seed should consistently produce exactly the same LDIF file.

-m

value

Specifies the maximum number of entries that should be written to a single LDIF file. After this number of entries has been written, the current LDIF file will be closed and a new file created with a ".2" extension. This counter will increment sequentially for each new file that is created.

-x

value

Specifies the maximum number of entries that should be created for each template below each branch. This can be used to create an example of the LDIF file that would be generated from the provided template to verify that the template syntax is valid.

-w

 

Specifies that long lines should be wrapped (folded). By default, the entire value of an attribute is written on a single line, which is useful if the LDIF file needs to be processed by another application, but can be difficult to read for long values.

-M

 

Specifies that a different filter file should be created for each index type for each attribute for which filter information is to be collected.

-S

 

Specifies that branch entries should be skipped when writing the LDIF information to the requested output file.

-H

 

Displays usage information for the MakeLDIF program.

-V

 

Displays version information for the MakeLDIF program.


Customizing the Template File

The MakeLDIF program uses a template file to customize the LDIF file that is generated. The use of the template file makes it possible to customize the location and kinds of entries that are generated by MakeLDIF. There are several kinds of entries that may be written into a template file: Global Replacement Definitions, Branch Entry Definitions and Template Definitions. example.template is provided with MakeLDIF in the DSRK_base/java/MakeLDIF directory. Definitions from this file are used in the following sections as examples.

Global Replacement Definitions

The first section in a template file usually defines global replacement variables. These variables are used for reference in the template file itself. Placeholders will be automatically replaced by the defined variable as each line is read into memory. Code Example 20-1 are the global replacement definitions from example.template.

Code Example 20-1  Global Replacement Entries From example.template

define suffix=dc=example,dc=com

define maildomain=example.com

define numusers=10000

As an example, the first entry (define suffix=dc=example,dc=com) will create a global replacement variable named suffix with a value of dc=example,dc=com. Now, any case in which suffix appears in square brackets (e.g., "[suffix]") will be replaced with the value that has been defined for it. Global replacement definitions must appear at the top of the file. However, it is not required that there be any; if there are none, the template file would start with the Branch Entry Definitions.

Branch Entry Definitions

Branch entry definitions define the basic structure for the directory server. They specify the entry (or entries) that should appear at the top of the hierarchy as well as the number and kinds of entries that should appear below those parent entries. Code Example 20-2 are the branch entry definitions from example.template.

Code Example 20-2  Branch Entry Definitions From example.template 

branch: [suffix]

aci: (targetattr!="userPassword")(version 3.0; acl "Anonymous access"; allow (read,search,compare) userdn="ldap:///anyone";)

aci: (targetattr != "nsroledn || aci || nsLookThroughLimit || nsSizeLimit || nsTimeLimit || nsIdleTimeout || passwordPolicySubentry ")(version 3.0; acl "Allow self entry modification except for nsroledn, aci, resource limit attributes, and passwordPolicySubentry"; allow (write)userdn ="ldap:///self";)

aci: (targetattr = "*")(version 3.0; acl "Configuration Administrator"; allow (all) userdn = "ldap:///uid=admin, ou=Administrators, ou=TopologyManagement, o=NetscapeRoot";) aci: (targetattr ="*")(version 3.0;acl "Configuration Administrators Group";allow (all) (groupdn = "ldap:///cn=Configuration Administrators, ou=Groups, ou=TopologyManagement, o=NetscapeRoot");)

aci: (targetattr ="*")(version 3.0;acl "Directory Administrators Group";allow (all) (groupdn = "ldap:///ou=Directory Administrators, [suffix]");)

branch: ou=People,[suffix]

subordinateTemplate: person:[numusers]

aci: (targetattr ="userpassword || telephonenumber || facsimiletelephonenumber")(version 3.0;acl "Allow self entry modification";allow (write)(userdn = "ldap:///self");)

aci: (targetattr !="cn || sn || uid")(targetfilter ="(ou=Accounting)")(version 3.0;acl "Accounting Managers Group Permissions";allow (write)(groupdn = "ldap:///cn=Accounting Managers,ou=groups,[suffix]");)

aci: (targetattr !="cn || sn || uid")(targetfilter ="(ou=Human Resources)")(version 3.0;acl "HR Group Permissions";allow (write)(groupdn = "ldap:///cn=HR Managers,ou=groups,[suffix]");)

aci: (targetattr !="cn ||sn || uid")(targetfilter ="(ou=Product Testing)")(version 3.0;acl "QA Group Permissions";allow (write)(groupdn = "ldap:///cn=QA Managers,ou=groups,[suffix]");)

aci: (targetattr !="cn || sn || uid")(targetfilter ="(ou=Product Development)")(version 3.0;acl "Engineering Group Permissions";allow (write)(groupdn = "ldap:///cn=PD Managers,ou=groups,[suffix]");)

Basic Structure of Branch Entry Definition

The basic structure of the branch entry definition is defined by the RDN attribute specified in the DN of the branch definition. In Code Example 20-2, the initial branch defintion is defined as:

branch: [suffix]

or:

branch: dc=example,dc=com

MakeLDIF associates the RDN with specific branch entries. The default entries created based on RDN are:

Thus, the initial branch definition specifies that an entry with the domain objectclass should be created based on the suffix global replacement variable detailed in Code Example 20-1. This means that an entry dc=example,dc=com should be created. In LDIF, the entry will look like Code Example 20-3.

Code Example 20-3  LDIF of Basic Branch Definition

dn: dc=example,dc=com

objectclass: top

objectclass: domain

dc: example

The branch defined entry will contain only the DN, its two objectclass values, and the RDN attribute. It is possible to include other attributes in the branch entry by including them in the branch definition of the template file. Code Example 20-4 adds a description attribute to the basic branch definition.

Code Example 20-4  Extended Branch Definition Entry

branch: dc=example,dc=com

description: This is the description.

Code Example 20-4 will create an entry that looks like Code Example 20-5.

Code Example 20-5  LDIF of Extended Branch Definition Entry

dn: dc=example,dc=com

objectclass: top

objectclass: domain

dc: example

description: This is the description.

This additional text is static and, unlike template definitions that may occur later in the template file, branch definitions are not dynamically parsed.

SubordinateTemplate Definition Entries

The branch entry defined thus far created only a single entry in the directory with limited control over the information contained in that entry. However, if one or more subordinateTemplate values are specified, it is possible to create additonal entries below the initial branch. For example, the first branch entry definition detailed in Code Example 20-2 will not cause any entries to be created below it. On the other hand, the second definition (further on in Code Example 20-2) will create subordinate entries because a subordinateTemplate is defined:

branch: ou=People,[suffix]

subordinateTemplate: person:[numusers]


Note

Note that suffix and numusers refer to global replacement entries also defined in the template. See Code Example 20-1.


This subordinateTemplate code will create an ou=People,dc=example,dc=com entry and 10000 sub-entries created below it, modeled after the person template entry defined later in the file. (See Template Definitions for more information.)

Branch definition entries are not limited to just one subordinateTemplate definition. Multiple subordinateTemplate definitions can be defined by including each on separate lines of the branch definition. 1000 entries based on the person template and an additional 100 entries based on the certificatePerson template will be created by this branch entry definition:

branch: ou=People,dc=example,dc=com

subordinateTemplate: person:1000

subordinateTemplate: certificatePerson: 100

Global Replacement Variables In Branch Definition Entries

It is possible to use global replacement variables in branch entry definitions. Code Example 20-6 defines both global replacement variables and branch entry definitions.

Code Example 20-6  Global Replacement Variables With Branch Entry Definitions

define suffix=dc=example,dc=com

branch: [suffix]

branch: ou=People,[suffix]

subordinateTemplate: 1000

Code Example 20-7 details the domain and the organizationlUnit that are created by Code Example 20-6. 1000 additional entries below them will also be created based on the person template.

Code Example 20-7  LDIF of Branch Definition Entries With Global Variables

dn: dc=example,dc=com

objectclass: top

objectclass: domain

dc: example

dn: ou=People,dc=example,dc=com

objectclass: top

objectclass: organizationalUnit

ou: People

Template Definitions

Branch Entry Definitions are used to specify a few key entries in the directory server hierarchy, but template definitions contain a much more useful set of information. They contain information that may be used to generate large numbers of entries below branch entries. Template definitions are parsed and may contain special tags to customize the kinds of entries that are built, so even though the same template may be used to generate thousands or millions of entries, each of those entries may still be unique. Code Example 20-8 are the template definitions from example.template provided with MakeLDIF in the DSRK_base/java/MakeLDIF directory.

Code Example 20-8  Template Definitions From example.template 

template: person

rdnAttr: uid

objectClass: top

objectClass: person

objectClass: organizationalPerson

objectClass: inetOrgPerson

givenName: <first>

sn: <last>

cn: {givenName} {sn}

initials: {givenName:1}{sn:1}

uid: {givenName}.{sn}

mail: {uid}@[maildomain]

userPassword: <random:alphanumeric:8>

telephoneNumber: <random:telephone>

homePhone: <random:telephone>

pager: <random:telephone>

mobile: <random:telephone>

employeeNumber: <sequential:100000>

street: <random:numeric:5> <file:streets> Street

l: <file:cities>

st: <file:states>

postalCode: <random:numeric:5>

postalAddress: {cn}${street}${l}, {st} {postalCode}

description: This is the description for {cn}.

template: certificatePerson

rdnAttr: uid

extends: person

userCertificate:: <random:base64:975>

template: messaging52person

rdnAttr: uid

extends: person

objectClass: inetUser

objectClass: inetMailUser

objectClass: inetLocalMailRecipient

objectClass: userPresenceProfile

mailAlternateAddress: {givenName}_{sn}@[maildomain]

mailDeliveryOption: mailbox

mailHost: mail.example.com

mailQuota: -1

mailMsgQuota: -1

inetUserStatus: active

mailUserStatus: active

template: ADperson

rdnAttr: cn

objectClass: top

objectClass: person

objectClass: organizationalPerson

objectClass: user

givenName: <first>

sn: <last>

cn: {givenName} {sn}

name: {cn}

displayName: {cn}

initials: {givenName:1}{sn:1}

sAMAccountName: {givenName:1}{sn}

countryCode: 0

userPrincipalName: {sAMAccountName}@[maildomain]

unicodePwd:: <base64:UnicodeLittleUnmarked:"<random:alphanumeric:8>">

telephoneNumber: <random:telephone>

userAccountControl: 512

The tags contained in these definitions will be parsed and replaced with information appropriate to the specified tag. Code Example 20-9 details an entry made from the first template definition in Code Example 20-8.

Code Example 20-9  LDIF Entry for Template Definition

dn: uid=John.Doe,ou=People,dc=example,dc=com

objectclass: top

objectclass: person

objectclass: organizationalPerson

objectclass: inetOrgPerson

givenName: John

sn: Doe

cn: John Doe

initals: JD

uid: John.Doe

mail: John.Doe@example.com

userPassword: d82fk32n

telephoneNumber: 823-630-8157

homePhone: 823-766-8231

pager: 823-766-8790

mobile: 823-766-9731

employeeNumber: 124509

street: 12345 Forsaken Street

l: San Jose

st: California

postalCode: 95127

postalAddress: John Doe 12345 Forsaken Street San Jose, California 95127

description: This is the description for John Doe.

The first line of a template definition should contain the name of the template. This name identifies the template so that the appropriate entry may be created under branch entries. Each template entry should have a unique name. The template definition should also have an rdnAttr line that specifies the attribute to be used for the RDN component of the entry's DN. This must be a single value -- multivalued RDNs are not supported by this version of the LDIF generator. If an rdnAttr definition is not present, a default RDN attribute of cn will be used.

Tokens Supported in Template Definitions

The information in a template definition (besides the template name and RDN attriubte) will be written into the entries that are generated; any recognized tokens will be evaluated and replaced with the appropriate information. The tokens detailed in Table 20-2 are supported.

Table 20-2  Supported Tokens in Template Definitions 

Token

Purpose

presence:percent

Indicates how likely the associated attribute is to be included in any given entry generated from this template. The given percentage value should be a number between 0 and 100. This should only be used with attributes that are not required by the objectClasses used in the entry, and there should be something else included in the value of that attribute that will be present in entries that are chosen to include the attribute.

first

Replaced with a first name from the first name file. If both a first and last name are included in an entry, the combination of the two is guaranteed to be unique. That is, no two entries in the LDIF file will have the same combination of first and last name values. Note that in order to guarantee uniqueness, the first and last names must be used in their entirety; that is, you cannot use the substring feature of attribute value replacements of the form givenName:5 discussed below.

last

Replaced with a last name from the last name file. If both a first and last name are included in an entry, the combination of the two is guaranteed to be unique. That is, no two entries in the LDIF file will have the same combination of first and last name values. Note that in order to guarantee uniqueness, the first and last names must be used in their entirety; that is, you cannot use the substring feature of attribute value replacements of the form givenName:5 discussed below.

parentdn

Replaced with the DN of the parent entry.

random:alpha:length

Replaced with a string of randomly-chosen alphabetic characters the length of which is defined by the length token.

random:numeric:length

Replaced with a string of randomly-chosen numeric digits the length of which is defined by the length token.

random:alphanumeric:length

Replaced with a string of randomly-chosen alphanumeric characters the length of which is defined by the length token.

random:hex:length

Replaced with a string of randomly-chosen hexadecimal digits the length of which is defined by the length token.

random:base64:length

Replaced with a string of randomly-chosen base64 characters the length of which is defined by the length token. If the specified length is not a multiple of 4, the base64 value produced will be padded with equal signs so that the total length is a multiple of 4.

random:telephone

Replaced with a string of randomly-chosen numeric digits in the form 123-456-7890. This uses a US-style telephone number, but it is possible to generate telephone numbers in the format used by other countries by combining other random tags. For example, to generate a telephone number in the UK format, you could use:

+44 random:numeric:4 random:numeric:6.

<sequential> --

Replaced with a sequentially-increasing numeric value. The first value will be zero. Sequential counters are separate on a per-attribute basis, so it is possible to use multiple sequential counters in the different attributes of the same entry without impacting each other.

guid

Replaced with a GUID value containing hexadecimal digits in the form 12345678-90ab-cdef-1234-567890abcdef. GUID values should be unique within the same LDIF file.

list:value1,value2,...,valueN

Replaced with a randomly-chosen value from the comma-delimited list. Each value will have an equal chance of being chosen.

list:value1:weight1,value2:weight2,...,valueN:weightN

Replaced with a randomly-chosen value from the comma-delimited list. The weight associated with each list item determines how likely that value is to be chosen. For example, a list item with a weight of 2 is twice as likely to be chosen as an item with a weight of 1. The weights specified must be positive integers.

file:filename

Replaced with a randomly-chosen value from the specified file. There should be one value per line of the file. It is not possible to assign weights to the values in a file, but a value can be weighted artificially by making it appear multiple times in the file.

exec:command

Replaced with the information sent to standard output when the specified command is executed on the system. Note that because this requires a separate process to be invoked for each entry created using this template, using the exec tag can make the LDIF generation process proceed much more slowly than if the exec tag is not used.

exec:command,arg1,arg2,...,argN

Replaced with the information sent to standard output when the specified command is executed on the system with the given set of arguments. Note that because this requires a separate process to be invoked for each entry created using this template, using the exec tag can make the LDIF generation process proceed much more slowly than if the exec tag is not used.

In addition to the tokens listed above, it is also possible to include the value of another attribute. For example, the string givenName.sn will be replaced with the value for the givenName attribute and the value for the sn attribute separated by a period. Note that if this feature is used, the attribute must be defined in the template before its value is referenced. If the specified attribute has multiple values, then the first value encountered for that attribute will be used. If the form givenName:5 is used, then only the first five characters of the givenName attribute will be used in the replacement. If there are fewer than the specified number of characters in the value of the target attribute, then the entire value of that attribute will be used.

Subordinate Templates in Template Definitions

It is possible to include one or more subordinateTemplate definitions (as discussed in SubordinateTemplate Definition Entries) in a template definition. This can be used to create entries generated from one template below entries generated from another template. Although not a recommended practice when designing a directory, it is an approach that some administrators have taken. Note that a template must not define itself as a subtemplate nor can there be any circular references. For example, an entry generated by one template cannot have another entry generated by the same template anywhere beneath that entry in the directory server hierarchy. If this is done, then the LDIF generation process will become stuck in an infinite loop and will eventually fail. Therefore, this feature should be used with caution.

Inheritance in Template Definitions

Template definitions also support the concept of inheritance. Therefore, it is possible to specify a template definition that builds upon a previously-defined template by using the extends definition. For example, if there are to be ten thousand entries created using the person template, and an additional one thousand entries created that should have the same structure as the person entries but should also include a value for the userCertificate attribute, you could create a second template entry as detailed in Code Example 20-10.

Code Example 20-10  extends Definition for Inheritance 

template: certificatePerson

rdnAttr: uid

extends: person

userCertificate: <random:base64:1000>

One benefit to using the extends keyword rather than redefining the entire template is that the version using extends will be smaller. Additionally, it will not be necessary to keep changes synchronized between related template entries. A change made in the initial template will automatically be reflected in any templates that extend it. Code Example 20-10 has the same effect as the template definition detailed in Code Example 20-11 without the use of the extends definition.

Code Example 20-11  Template Definition Without extends Definition

template: certificatePerson

rdnAttr: uid

objectclass: top

objectclass: person

objectclass: organizationalPerson

objectclass: inetOrgPerson

givenName: <first>

sn: <last>

cn: {givenName} {sn}

uid: {givenName}.{sn}

mail: {uid}@example.com

userPassword: <random:alphanumeric:8>

telephoneNumber: <random:telephone>

userCertificate: <random:base64:1000>

It is possible to use multiple levels of inheritance. But as with the subordinateTemplate definition, you must not define a template as its own parent or define any circular references in which a template may in some way extend itself. Also note that any template that extends another template must specify its own RDN attribute. The RDN attribute of the parent template will not automatically be used. This makes it possible to specify a different RDN attribute for one template than the one that is used for the entries created with the parent template.


Additional Information

More information on MakeLDIF can be found in the MakeLDIF LDIF Generator Usage Guide, a Portable Document Format (PDF) file located in the DSRK_base/java/MakeLDIF directory.



Previous      Contents      Index      Next     


Copyright 2004 Sun Microsystems, Inc. All rights reserved.