Creating a modrdn LDIF

Following is a script to take an LDIF of existing entries and reformat it to direct the modification of the rdn. This is a companion article to Renaming LDAP entries.

Creat the input file (“ldapnow.ldif”) by searching on LDAP and asking only to return the uid value. Like this:

ldapsearch -h localhost -D "cn=directory manager" 
-w xxxxx -b "ou=people,dc=example,dc=com" -s sub 
"(o=TargetCompany)" uid >ldapnow.ldif

The basedn is focused on the “people” container to avoid capturing entries that should not be changed (like groups). The “o=TargetCompany” is used to target only the entries from the desired organization. Try to be as surgical as you can — particularly if there are a large number of entries involved. If every entry in the container needs to change you could just use “(objectclass=inetorgperson)” or another appropriate search filter. I’ve specified the return of “uid” so we can use it to capture the naming attribute value. If the “uid” and “cn” value in the existing entries are different and you really want to use the latter, substitute “cn” (on my directory they’re identical in this instance so it doesn’t matter).

#!/usr/bin/perl -w

use strict;
use Net::LDAP;
use Net::LDAP::Entry;
use Custom::Net::LDAP::LDIF;

my $HOME = $ENV{'HOME'};
my $inldif = "$HOME/data/ldapnow.ldif";
my $outldif = "$HOME/data/ldaptobe.ldif";

my $ldif = Custom::Net::LDAP::LDIF->new($inldif, 'r') or die $!;

open FH, ">$outldif" or die $!;

while (not $ldif->eof() ) {
  my $entry = $ldif->read_entry();
  if ($ldif->error() ) {
     print "tError! ",$ldif->error(),"n";
  }
  else {
	my $dn = $entry->dn;
	my $uid = $entry->get_value('uid');

	print "$dnn";

	print FH "dn: $dnn";
	print FH "changetype: modrdnn";
	print FH "newrdn: cn=$uidn";
	print FH "deleteoldrdn: 0n";
	print FH "n";
   }
}

close FH;
$ldif->done;

__END__;

Note that I’ve set deleteoldrdn to “0”, because I still want uid to exist in the modified entries.