Hi, I always found it quite annoying that one needs two different objects/methods when writing a Net:LLDAP:Entry to either a directory server or an LDIF file. With directory servers you can do $entry->update($ldap) while with LDIF you need $ldif->write_entry($entry)
This always requires a distinction in the code path in the perl scripts although LDIF makes a nice output when doing a "dry run", and Perl should be able to do the RightThing(tm). I have attached a patch that extends Net::LDAP::Entry->update by accepting an Net::LDAP::LDIF object as a parameter too. It would be great if this patch would make it into the next release of perl-ldap. Best regards Peter -- Peter Marschall pe...@adpm.de
From bce3842056339ebdbbaaebd46857b13eadc68759 Mon Sep 17 00:00:00 2001 From: Peter Marschall <pe...@adpm.de> Date: Sun, 9 Jan 2011 19:47:55 +0100 Subject: [PATCH] extend Net::LDAP::Entry->update() to take LDIF objects Extend Net::LDAP::Entry.pm's update() method so that it can take Net::LDAP::LDIF objects as handles too, and append the entry's data to the LDIF. For LDIF arguments also return a Net::LDAP::Message argument: on success return LDAP_SUCCESS, on error return LDAP_OTHER. One might argue that tis is against the standards, but Net::LDAP::Entry->update() is not covered in any standard. The big plus is, it allows clients to have one common code path for directory servers and LDIF files (except for startup/shutdown) which makes using LDIF as "dry-run" output for servers really simple. Especially for the result value, it s a lot more convenient than any other combination of Net::LDAP::entry->update() and Net::LDAP::Entry->ldif(). Signed-off-by: Peter Marschall <pe...@adpm.de> --- lib/Net/LDAP/Entry.pm | 50 +++++++++++++++++++++++++++------------------- lib/Net/LDAP/Message.pm | 4 +- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/lib/Net/LDAP/Entry.pm b/lib/Net/LDAP/Entry.pm index 118428e..f7c8df8 100644 --- a/lib/Net/LDAP/Entry.pm +++ b/lib/Net/LDAP/Entry.pm @@ -6,7 +6,7 @@ package Net::LDAP::Entry; use strict; use Net::LDAP::ASN qw(LDAPEntry); -use Net::LDAP::Constant qw(LDAP_LOCAL_ERROR); +use Net::LDAP::Constant qw(LDAP_LOCAL_ERROR LDAP_OTHER); use vars qw($VERSION); use constant CHECK_UTF8 => $] > 5.007; @@ -258,33 +258,41 @@ sub delete { sub update { my $self = shift; - my $ldap = shift; + my $target = shift; # a Net::LDAP or a Net::LDAP::LDIF object my %opt = @_; my $mesg; my $user_cb = delete $opt{callback}; my $cb = sub { $self->changetype('modify') unless $_[0]->code; $user_cb->(@_) if $user_cb }; - if ($self->{'changetype'} eq 'add') { - $mesg = $ldap->add($self, 'callback' => $cb, %opt); - } - elsif ($self->{'changetype'} eq 'delete') { - $mesg = $ldap->delete($self, 'callback' => $cb, %opt); - } - elsif ($self->{'changetype'} =~ /modr?dn/o) { - my @args = (newrdn => $self->get_value('newrdn') || undef, - deleteoldrdn => $self->get_value('deleteoldrdn') || undef); - my $newsuperior = $self->get_value('newsuperior'); - push(@args, newsuperior => $newsuperior) if $newsuperior; - $mesg = $ldap->moddn($self, @args, 'callback' => $cb, %opt); - } - elsif (@{$self->{'changes'}}) { - $mesg = $ldap->modify($self, 'changes' => $self->{'changes'}, 'callback' => $cb, %opt); + if (ref($target) && UNIVERSAL::isa($target, 'Net::LDAP')) { + if ($self->{'changetype'} eq 'add') { + $mesg = $target->add($self, 'callback' => $cb, %opt); + } + elsif ($self->{'changetype'} eq 'delete') { + $mesg = $target->delete($self, 'callback' => $cb, %opt); + } + elsif ($self->{'changetype'} =~ /modr?dn/o) { + my @args = (newrdn => $self->get_value('newrdn') || undef, + deleteoldrdn => $self->get_value('deleteoldrdn') || undef); + my $newsuperior = $self->get_value('newsuperior'); + push(@args, newsuperior => $newsuperior) if $newsuperior; + $mesg = $target->moddn($self, @args, 'callback' => $cb, %opt); + } + elsif (@{$self->{'changes'}}) { + $mesg = $target->modify($self, 'changes' => $self->{'changes'}, 'callback' => $cb, %opt); + } + else { + require Net::LDAP::Message; + $mesg = Net::LDAP::Message->new( $target ); + $mesg->set_error(LDAP_LOCAL_ERROR,"No attributes to update"); + } } - else { - require Net::LDAP::Message; - $mesg = Net::LDAP::Message->new( $ldap ); - $mesg->set_error(LDAP_LOCAL_ERROR,"No attributes to update"); + elsif (ref($target) && UNIVERSAL::isa($target, 'Net::LDAP::LDIF')) { + $target->write_entry($self); + $mesg = Net::LDAP::Message::Dummy->new(); + $mesg->set_error(LDAP_OTHER, $target->error()) + if ($target->error()); } return $mesg; diff --git a/lib/Net/LDAP/Message.pm b/lib/Net/LDAP/Message.pm index 7df478d..569a376 100644 --- a/lib/Net/LDAP/Message.pm +++ b/lib/Net/LDAP/Message.pm @@ -254,8 +254,8 @@ sub Net::LDAP::Compare::is_error { sub sync { shift } sub decode { shift } sub abandon { shift } - sub code { 0 } - sub error { "" } + sub code { $self->{resultcode} || LDAP_SUCCESS } + sub error { $self->{errorMessage} || "" } sub dn { "" } sub done { 1 } } -- 1.7.2.3