[ Team LiB ] Previous Section Next Section

10.3 Working with Net::LDAP::LDIF

The search.pl script provided a simple introduction to retrieving data from an LDAP directory. However, the query results represented the state of the directory at a single point in time. The script has no good way to save the search results, and the way in which it prints the information is useful for humans, but not useful to any other LDAP tools. You need the ability to save the results in a format that can be parsed by other LDAP tools: in other words, you need to be able to read and write LDIF files directly from Perl code.

The Net::LDAP::LDIF module provides the ability to work with LDIF files. To introduce Net::LDAP::LDIF, we'll revisit search.pl and replace the call to dump( ) with code to produce valid LDIF output. Your first modification to the script is to add a second use pragma that imports the LDIF module:

use Net::LDAP::LDIF;

Next, the script must create a new instance of a Net::LDAP::LDIF object. Output from this object can be linked to an existing file handle such as STDOUT, as shown here:

$ldif = Net::LDAP::LDIF->new (STDOUT, "w")
     or die $!;

It is possible to pass a filename to the new( ) method, as well as inform the module how this file will be used ("r" for read, "w" for write + truncate, and "a" for write + append). This line of code creates an LDIF output stream named result.ldif in the current directory:

$ldif = Net::LDAP::LDIF->new ("./result.ldif", "w")
     or die $!;

It is best to use this code after you've run the search and confirmed that it produced some results. So, you open the file after the script has tested that $msg->count( ) > 0:

if ( $msg->count(  ) > 0 ) {
    print $msg->count(  ), " entries returned.\n";
      
    $ldif = Net::LDAP::LDIF->new (scalar<STDOUT>, "w")
          or die $!;

Finally, replace the entire foreach loop that calls dump( ) on each entry with a single call to the write_entry( ) method of Net::LDAP::LDIF:

     $ldif->write_entry($msg->all_entries(  ));

write_entry( ) accepts either a single Net::LDAP::Entry or a one-dimensional array of these objects. The new loop is:

if ( $msg->count(  ) > 0 ) {
    print $msg->count(  ), " entries returned.\n";
      
    $ldif = Net::LDAP::LDIF->new (scalar<STDOUT>, "w")
          or die $!;
      
    $ldif->write_entry($msg->all_entries(  )); 
}

Now the output of the script looks like this:

dn: cn=Gerald Carter,ou=contacts,dc=plainjoe,dc=org
cn: Gerald Carter
mail: jerry@samba.org

This doesn't look like a big change, but it's an important one. Because the data is now in LDIF format, other tools such as ldapmodify can parse your script's output.

Once the script has created the LDIF output file, you can explicitly close the file by executing the done( ) method.

$ldif->done(  );

This method is implicitly called whenever a Net::LDAP::LDIF object goes out of scope.

    [ Team LiB ] Previous Section Next Section