Hi all,
I have to compare two ldif files and I use the ldifdiff.pl script to do
this. This week, I have this two entries like this :
# new.ldif
dn: cn=Tonio,ou=Washington,dc=company,dc=com
objectclass: inetOrgPerson
cn: Tonio
ou: Washington
sn: Tonio
employeenumber: 888999
# old.ldif
dn: cn=Tony,ou=Los Angeles,dc=company,dc=com
objectclass: inetOrgPerson
cn: Tony
ou: Los Angeles
sn: Tony
employeenumber: 888999
The result of ldifdiff -k employeenumber new.ldif old.ldif was :
dn: cn=Tony,ou=Los Angeles,dc=company,dc=com
changetype: modrdn
newrdn: cn=Tonio
deleteoldrdn: 1
dn: cn=Tonio,ou=Washington,dc=company,dc=com
changetype: modify
replace: ou
ou: Washington
-
replace: sn
sn: Tonio
I think that's wrong the changetype would be moddn and not modrdn.
I propose this patch to do this. The result was :
dn: cn=Tony,ou=Los Angeles,dc=company,dc=com
changetype: moddn
newrdn: cn=Tonio
deleteoldrdn: 1
newsuperior: ou=Washington,dc=company,dc=com
dn: cn=Tonio,ou=Washington,dc=company,dc=com
changetype: modify
replace: ou
ou: Washington
-
replace: sn
sn: Tonio
Hope that helps anyway.
Regards,
--
Anthony Milan
--- ldifdiff.pl.ori 2006-04-21 17:54:52.679165936 +0200
+++ ldifdiff.pl 2006-04-21 18:03:27.324927888 +0200
@@ -111,6 +111,12 @@
# Gets the relative distinguished name (RDN) value
sub rdnval { my $rv = ($_[0]->dn =~ /=(.*)/)[0]; $rv =~ s/(?<!\\),.*//; $rv }
+# Gets the relative distinguished name (RDN)
+sub rdn { ( $_[0]->dn =~ /^([^,]+),/ )[0] }
+
+# Gets the DN superior to the relative distinguished name (RDN)
+sub superior { ( $_[0]->dn =~ /^[^,]+,(.*)/ )[0] }
+
sub cmpEntries
{
my ($a, $b) = @_;
@@ -176,23 +182,48 @@
# When we get here, we're dealing with the same person in $sourceentry
# and $targetentry. Compare the data and generate the update.
- # If a modRDN is necessary, it needs to happen before other mods
if (lc(canonical_dn($sourceentry->dn))
ne lc(canonical_dn($targetentry->dn))) {
my $rdnattr = rdnattr($sourceentry);
my $rdnval = rdnval($sourceentry);
- $targetentry->{changetype} = 'modrdn';
- $targetentry->add(newrdn => "$rdnattr=$rdnval",
+ # If a modDN is necessary, it needs to happen before other mods
+ if (lc(superior($sourceentry)) ne lc(superior($targetentry))) {
+
+ $targetentry->{changetype} = 'moddn';
+ $targetentry->add(newrdn => "$rdnattr=$rdnval",
+ deleteoldrdn => '1',
+ newsuperior => superior($sourceentry),
+ );
+ $ldifout->write_entry($targetentry);
+ $targetentry->delete('newrdn');
+ $targetentry->delete('deleteoldrdn');
+ $targetentry->delete('newsuperior');
+ delete($targetentry->{changetype});
+
+ $targetentry->dn($sourceentry->dn);
+ $targetentry->replace($rdnattr,
+ $sourceentry->get_value($rdnattr))
+ if $sourceentry->exists($rdnattr);
+ }
+
+ # If a modRDN is necessary, it needs to happen before other mods
+ # but after modDN
+ if (lc(rdn($sourceentry)) ne lc(rdn($targetentry))) {
+
+ $targetentry->{changetype} = 'modrdn';
+ $targetentry->add(newrdn => "$rdnattr=$rdnval",
deleteoldrdn => '1');
- $ldifout->write_entry($targetentry);
- $targetentry->delete('newrdn');
- $targetentry->delete('deleteoldrdn');
- delete($targetentry->{changetype});
+ $ldifout->write_entry($targetentry);
+ $targetentry->delete('newrdn');
+ $targetentry->delete('deleteoldrdn');
+ delete($targetentry->{changetype});
- $targetentry->dn($sourceentry->dn);
- $targetentry->replace($rdnattr, $sourceentry->get_value($rdnattr))
- if $sourceentry->exists($rdnattr);
+ $targetentry->dn($sourceentry->dn);
+ $targetentry->replace($rdnattr,
+ $sourceentry->get_value($rdnattr))
+ if $sourceentry->exists($rdnattr);
+ }
}
# Check for differences and generate LDIF as appropriate