Subject: [PATCH] IntermediateMessage and LDAP Content synchronisation fixes:
- Fix ASN parsing of syncRequestValue, syncDoneValue and syncInfoValue
(attributes with default value are threated as optional values)
- Renamed syncInfoValue ASN name to match RFC
- Fixed parsing of SyncDone and SyncRequest: avoid emptying the value
- Corrected Net::LDAP::Intermediate::SyncInfo parsing
- Enable Net::LDAP::Intermediate::SyncInfo
- Moved catching of IntermediateMessage from LDAP::Search to
LDAP::Message (this is not specific to searches)
---
lib/Net/LDAP/ASN.pm | 16 ++++++++--------
lib/Net/LDAP/Control/SyncDone.pm | 15 ++++++---------
lib/Net/LDAP/Control/SyncRequest.pm | 11 +++--------
lib/Net/LDAP/Control/SyncState.pm | 3 ---
lib/Net/LDAP/Intermediate.pm | 2 +-
lib/Net/LDAP/Intermediate/SyncInfo.pm | 30 +++++++++++++++---------------
lib/Net/LDAP/Message.pm | 20 ++++++++++++++++----
lib/Net/LDAP/Search.pm | 15 +++------------
8 files changed, 52 insertions(+), 60 deletions(-)
diff --git a/lib/Net/LDAP/ASN.pm b/lib/Net/LDAP/ASN.pm
index 82b7c17..9ba0913 100644
--- a/lib/Net/LDAP/ASN.pm
+++ b/lib/Net/LDAP/ASN.pm
@@ -1,7 +1,7 @@
package Net::LDAP::ASN;
-$VERSION = "0.07";
+$VERSION = "0.08";
use Convert::ASN1;
@@ -455,7 +455,7 @@ $asn->prepare(<<LDAP_ASN) or die $asn->error;
refreshAndPersist (3)
}
cookie syncCookie OPTIONAL,
- reloadHint BOOLEAN -- DEFAULT FALSE
+ reloadHint BOOLEAN OPTIONAL -- DEFAULT FALSE
}
syncStateValue ::= SEQUENCE {
@@ -471,22 +471,22 @@ $asn->prepare(<<LDAP_ASN) or die $asn->error;
syncDoneValue ::= SEQUENCE {
cookie syncCookie OPTIONAL,
- refreshDeletes BOOLEAN -- DEFAULT FALSE
+ refreshDeletes BOOLEAN OPTIONAL -- DEFAULT FALSE
}
syncInfoValue ::= CHOICE {
newcookie [0] syncCookie,
refreshDelete [1] SEQUENCE {
- refreshDeleteCookie syncCookie OPTIONAL,
- refreshDeleteDone BOOLEAN -- DEFAULT TRUE
+ cookie syncCookie OPTIONAL,
+ refreshDone BOOLEAN OPTIONAL -- DEFAULT TRUE
}
refreshPresent [2] SEQUENCE {
- refreshDeletecookie syncCookie OPTIONAL,
- refreshDeleteDone BOOLEAN -- DEFAULT TRUE
+ cookie syncCookie OPTIONAL,
+ refreshDone BOOLEAN OPTIONAL -- DEFAULT TRUE
}
syncIdSet [3] SEQUENCE {
cookie syncCookie OPTIONAL,
- refreshDeletes BOOLEAN, -- DEFAULT FALSE
+ refreshDeletes BOOLEAN OPTIONAL, -- DEFAULT FALSE
syncUUIDs SET OF syncUUID
}
}
diff --git a/lib/Net/LDAP/Control/SyncDone.pm b/lib/Net/LDAP/Control/SyncDone.pm
index 7fcb0d9..e8bc2ae 100644
--- a/lib/Net/LDAP/Control/SyncDone.pm
+++ b/lib/Net/LDAP/Control/SyncDone.pm
@@ -8,22 +8,19 @@ use vars qw(@ISA $VERSION);
use Net::LDAP::Control;
@ISA = qw(Net::LDAP::Control);
-$VERSION = "0.01";
+$VERSION = "0.02";
use Net::LDAP::ASN qw(syncDoneValue);
use strict;
-# use some kind of hack here:
-# - calling the control without args means: response,
-# - giving an argument: means: request
sub init {
my($self) = @_;
- delete $self->{asn};
-
- unless (exists $self->{value}) {
+ if (exists $self->{value}) {
+ $self->{asn} = $syncDoneValue->decode(delete $self->{value});
+ } else {
$self->{asn} = {
- cookie => $self->{cookie} || '',
+ cookie => defined($self->{cookie}) ? $self->{cookie} : '',
refreshDeletes => $self->{refreshDeletes} || '0',
};
}
@@ -36,7 +33,7 @@ sub cookie {
$self->{asn} ||= $syncDoneValue->decode($self->{value});
if (@_) {
delete $self->{value};
- return $self->{asn}{cookie} = shift || 0;
+ return $self->{asn}{cookie} = defined($_[0]) ? $_[0] : '';
}
$self->{asn}{cookie};
}
diff --git a/lib/Net/LDAP/Control/SyncRequest.pm
b/lib/Net/LDAP/Control/SyncRequest.pm
index b33868d..95cd716 100644
--- a/lib/Net/LDAP/Control/SyncRequest.pm
+++ b/lib/Net/LDAP/Control/SyncRequest.pm
@@ -8,14 +8,11 @@ use vars qw(@ISA $VERSION);
use Net::LDAP::Control;
@ISA = qw(Net::LDAP::Control);
-$VERSION = "0.01";
+$VERSION = "0.02";
use Net::LDAP::ASN qw(syncRequestValue);
use strict;
-# use some kind of hack here:
-# - calling the control without args means: response,
-# - giving an argument: means: request
sub init {
my($self) = @_;
@@ -64,10 +61,8 @@ sub reloadHint {
sub value {
my $self = shift;
-
- exists $self->{value}
- ? $self->{value}
- : $self->{value} = $syncRequestValue->encode($self->{asn});
+ return $self->{value} if exists $self->{value};
+ $self->{value} = $syncRequestValue->encode($self->{asn});
}
1;
diff --git a/lib/Net/LDAP/Control/SyncState.pm
b/lib/Net/LDAP/Control/SyncState.pm
index b069e42..e47c78a 100644
--- a/lib/Net/LDAP/Control/SyncState.pm
+++ b/lib/Net/LDAP/Control/SyncState.pm
@@ -13,9 +13,6 @@ $VERSION = "0.01";
use Net::LDAP::ASN qw(syncStateValue);
use strict;
-# use some kind of hack here:
-# - calling the control without args means: response,
-# - giving an argument: means: request
sub init {
my($self) = @_;
diff --git a/lib/Net/LDAP/Intermediate.pm b/lib/Net/LDAP/Intermediate.pm
index b95b849..288d785 100644
--- a/lib/Net/LDAP/Intermediate.pm
+++ b/lib/Net/LDAP/Intermediate.pm
@@ -15,7 +15,7 @@ $VERSION = "0.01";
my %Class2ResponseName = (
- #'Net::LDAP::Intermediate::SyncInfo' => LDAP_SYNC_INFO, #disabled
as decoding doesn't work
+ 'Net::LDAP::Intermediate::SyncInfo' => LDAP_SYNC_INFO,
);
my %ResponseName2Class = reverse %Class2ResponseName;
diff --git a/lib/Net/LDAP/Intermediate/SyncInfo.pm
b/lib/Net/LDAP/Intermediate/SyncInfo.pm
index ed8205a..8d1814c 100644
--- a/lib/Net/LDAP/Intermediate/SyncInfo.pm
+++ b/lib/Net/LDAP/Intermediate/SyncInfo.pm
@@ -8,23 +8,26 @@ use vars qw(@ISA $VERSION);
use Net::LDAP::Intermediate;
@ISA = qw(Net::LDAP::Intermediate);
-$VERSION = "0.01";
+$VERSION = "0.02";
use Net::LDAP::ASN qw(syncInfoValue);
use strict;
-# use some kind of hack here:
-# - calling the control without args means: response,
-# - giving an argument: means: request
sub init {
my($self) = @_;
- delete $self->{asn};
-
- unless (exists $self->{responseValue}) {
- $self->{asn} = {
- newcookie => $self->{newcookie} || '',
- };
+ if (exists $self->{responseValue}) {
+ $self->{asn} = $syncInfoValue->decode(delete $self->{responseValue});
+ } else {
+ $self->{asn} = {};
+ $self->{asn}{newcookie} =
+ delete $self->{newcookie} if exists $self->{newcookie};
+ $self->{asn}{refreshDelete} =
+ delete $self->{refreshDelete} if exists $self->{refreshDelete};
+ $self->{asn}{refreshPresent} =
+ delete $self->{refreshPresent} if exists $self->{refreshPresent};
+ $self->{asn}{syncIdSet} =
+ delete $self->{syncIdSet} if exists $self->{syncIdSet};
}
$self;
@@ -32,11 +35,8 @@ sub init {
sub newcookie {
my $self = shift;
- $self->{asn} ||= $syncInfoValue->decode($self->{responseValue});
- if (@_) {
- delete $self->{responseValue};
- return $self->{asn}{newcookie} = shift || 0;
- }
+ @_ ? ($self->{asn}{newcookie}=shift)
+ : $self->{asn}{newcookie};
$self->{asn}{cookie};
}
diff --git a/lib/Net/LDAP/Message.pm b/lib/Net/LDAP/Message.pm
index 5007afb..26e5eeb 100644
--- a/lib/Net/LDAP/Message.pm
+++ b/lib/Net/LDAP/Message.pm
@@ -9,7 +9,7 @@ use Net::LDAP::ASN qw(LDAPRequest);
use strict;
use vars qw($VERSION);
-$VERSION = "1.10";
+$VERSION = "1.11";
my $MsgID = 0;
@@ -142,9 +142,21 @@ sub decode { # $self, $pdu, $control
# free up memory as we have a result so we will not need to re-send it
delete $self->{pdu};
- # tell our LDAP client to forget us as this message has now completed
- # all communications with the server
- $self->parent->_forgetmesg($self);
+ if ($data = delete $result->{protocolOp}{intermediateResponse}) {
+
+ my $intermediate = Net::LDAP::Intermediate->from_asn($data);
+
+ push(@{$self->{'intermediate'} ||= []}, $intermediate);
+
+ $self->{callback}->($self, $intermediate)
+ if (defined $self->{callback});
+
+ return $self;
+ } else {
+ # tell our LDAP client to forget us as this message has now completed
+ # all communications with the server
+ $self->parent->_forgetmesg($self);
+ }
$self->{callback}->($self)
if (defined $self->{callback});
diff --git a/lib/Net/LDAP/Search.pm b/lib/Net/LDAP/Search.pm
index d8c3568..3dd6575 100644
--- a/lib/Net/LDAP/Search.pm
+++ b/lib/Net/LDAP/Search.pm
@@ -13,7 +13,7 @@ use Net::LDAP::Filter;
use Net::LDAP::Constant qw(LDAP_SUCCESS LDAP_DECODING_ERROR);
@ISA = qw(Net::LDAP::Message);
-$VERSION = "0.12";
+$VERSION = "0.13";
sub first_entry { # compat
@@ -36,6 +36,8 @@ sub decode {
return $self->SUPER::decode($result)
if exists $result->{protocolOp}{searchResDone};
+ return $self->SUPER::decode($result)
+ if exists $result->{protocolOp}{intermediateResponse};
my $data;
@{$self}{qw(controls ctrl_hash)} = ($result->{controls}, undef);
@@ -64,17 +66,6 @@ sub decode {
return $self;
}
- elsif ($data = delete $result->{protocolOp}{intermediateResponse}) {
-
- my $intermediate = Net::LDAP::Intermediate->from_asn($data);
-
- push(@{$self->{'intermediate'} ||= []}, [$intermediate]);
-
- $self->{callback}->($self, $intermediate)
- if (defined $self->{callback});
-
- return $self;
- }
$self->set_error(LDAP_DECODING_ERROR, "LDAP decode error");
return;
--
1.5.6.5