[PATCH] IntermediateMessage and LDAP Content synchronisation fixes

"Mathieu Parent" <[email protected]>
Newsgroups gmane.comp.lang.perl.modules.ldap
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.