Hi, I have implemented LDAP Content Synchronization Operation (rfc4533) in perl-ldap (See the attached patch). This is used by the OpenLDAP server and provide features similar to Persistent Searches in a more consistent way.
This is my first try in this code, any feedback is welcome. I don't know how to handle the Sync Info Message which is an LDAP Intermediate Response Message (see 2.5 in RFC). perl-ldap doesn't seems to support intermediate responses in response to LDAP::Search. What is the way to correct this ? thanks Mathieu Parent
diff -urN --exclude=blib --exclude=debian --exclude '*~' libnet-ldap-perl-0.36-old/lib/Net/LDAP/ASN.pm libnet-ldap-perl-0.36/lib/Net/LDAP/ASN.pm --- libnet-ldap-perl-0.36-old/lib/Net/LDAP/ASN.pm 2008-04-21 17:11:06.000000000 +0200 +++ libnet-ldap-perl-0.36/lib/Net/LDAP/ASN.pm 2008-06-14 14:33:55.000000000 +0200 @@ -1,7 +1,7 @@ package Net::LDAP::ASN; -$VERSION = "0.06"; +$VERSION = "0.07"; use Convert::ASN1; @@ -440,6 +440,56 @@ objectName LDAPDN, attributes PartialAttributeList } + -- RFC-4533 LDAP Content Synchronization Operation + + syncUUID ::= OCTET STRING -- (SIZE(16)) + + syncCookie ::= OCTET STRING + + syncRequestValue ::= SEQUENCE { + mode ENUMERATED { + -- 0 unused + refreshOnly (1), + -- 2 reserved + refreshAndPersist (3) + } + cookie syncCookie OPTIONAL, + reloadHint BOOLEAN -- DEFAULT FALSE + } + + syncStateValue ::= SEQUENCE { + state ENUMERATED { + present (0), + add (1), + modify (2), + delete (3) + } + entryUUID syncUUID, + cookie syncCookie OPTIONAL + } + + syncDoneValue ::= SEQUENCE { + cookie syncCookie OPTIONAL, + refreshDeletes BOOLEAN -- DEFAULT FALSE + } + + syncInfoValue ::= CHOICE { + newcookie [0] syncCookie, + refreshDelete [1] SEQUENCE { + refreshDeleteCookie syncCookie OPTIONAL, + refreshDeleteDone BOOLEAN -- DEFAULT TRUE + } + refreshPresent [2] SEQUENCE { + refreshDeletecookie syncCookie OPTIONAL, + refreshDeleteDone BOOLEAN -- DEFAULT TRUE + } + syncIdSet [3] SEQUENCE { + cookie syncCookie OPTIONAL, + refreshDeletes BOOLEAN, -- DEFAULT FALSE + syncUUIDs SET OF syncUUID + } + } + LDAP_ASN 1; diff -urN --exclude=blib --exclude=debian --exclude '*~' libnet-ldap-perl-0.36-old/lib/Net/LDAP/Constant.pm libnet-ldap-perl-0.36/lib/Net/LDAP/Constant.pm --- libnet-ldap-perl-0.36-old/lib/Net/LDAP/Constant.pm 2008-04-21 17:11:06.000000000 +0200 +++ libnet-ldap-perl-0.36/lib/Net/LDAP/Constant.pm 2008-06-14 15:57:15.000000000 +0200 @@ -4,7 +4,7 @@ package Net::LDAP::Constant; -$VERSION = "0.06"; +$VERSION = "0.07"; use Carp; @@ -481,6 +481,14 @@ =item LDAP_CONTROL_ASSERTION (1.3.6.1.1.12) +=item LDAP_CONTROL_SYNC (1.3.6.1.4.1.4203.1.9.1.1) + +=item LDAP_CONTROL_SYNC_STATE (1.3.6.1.4.1.4203.1.9.1.2) + +=item LDAP_CONTROL_SYNC_DONE (1.3.6.1.4.1.4203.1.9.1.3) + +=item LDAP_SYNC_INFO (1.3.6.1.4.1.4203.1.9.1.4) + =back =head2 Control constants @@ -523,6 +531,42 @@ The new password was used too recently. +=item LDAP_SYNC_NONE (0) [LDAP_CONTROL_SYNC] + +=item LDAP_SYNC_REFRESH_ONLY (1) [LDAP_CONTROL_SYNC] + +=item LDAP_SYNC_RESERVED (2) [LDAP_CONTROL_SYNC] + +=item LDAP_SYNC_REFRESH_AND_PERSIST (3) [LDAP_CONTROL_SYNC] + +=item LDAP_SYNC_REFRESH_PRESENTS (0) [LDAP_SYNC_INFO] + +=item LDAP_SYNC_REFRESH_DELETES (1) [LDAP_SYNC_INFO] + +=item LDAP_TAG_SYNC_NEW_COOKIE (0x80) [LDAP_SYNC_INFO] + +=item LDAP_TAG_SYNC_REFRESH_DELETE (0xa1) [LDAP_SYNC_INFO] + +=item LDAP_TAG_SYNC_REFRESH_PRESENT (0xa2) [LDAP_SYNC_INFO] + +=item LDAP_TAG_SYNC_ID_SET (0xa3) [LDAP_SYNC_INFO] + +=item LDAP_TAG_SYNC_COOKIE (0x04) [LDAP_SYNC_INFO] + +=item LDAP_TAG_REFRESHDELETES (0x01) [LDAP_SYNC_INFO] + +=item LDAP_TAG_REFRESHDONE (0x01) [LDAP_SYNC_INFO] + +=item LDAP_TAG_RELOAD_HINT (0x01) [LDAP_CONTROL_SYNC] + +=item LDAP_SYNC_PRESENT (0) [LDAP_CONTROL_SYNC_STATE] + +=item LDAP_SYNC_ADD (1) [LDAP_CONTROL_SYNC_STATE] + +=item LDAP_SYNC_MODIFY (2) [LDAP_CONTROL_SYNC_STATE] + +=item LDAP_SYNC_DELETE (3) [LDAP_CONTROL_SYNC_STATE] + =back =head2 Extension OIDs diff -urN --exclude=blib --exclude=debian --exclude '*~' libnet-ldap-perl-0.36-old/lib/Net/LDAP/Control/SyncDone.pm libnet-ldap-perl-0.36/lib/Net/LDAP/Control/SyncDone.pm --- libnet-ldap-perl-0.36-old/lib/Net/LDAP/Control/SyncDone.pm 1970-01-01 01:00:00.000000000 +0100 +++ libnet-ldap-perl-0.36/lib/Net/LDAP/Control/SyncDone.pm 2008-06-14 17:50:59.000000000 +0200 @@ -0,0 +1,152 @@ +# Copyright (c) 2008 Mathieu Parent <[EMAIL PROTECTED]>. All rights reserved. +# This program is free software; you can redistribute it and/or +# modify it under the same terms as Perl itself. + +package Net::LDAP::Control::SyncDone; + +use vars qw(@ISA $VERSION); +use Net::LDAP::Control; + [EMAIL PROTECTED] = qw(Net::LDAP::Control); +$VERSION = "0.01"; + +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}) { + $self->{asn} = { + cookie => $self->{cookie} || '', + refreshDeletes => $self->{refreshDeletes} || '0', + }; + } + + $self; +} + +sub cookie { + my $self = shift; + $self->{asn} ||= $syncDoneValue->decode($self->{value}); + if (@_) { + delete $self->{value}; + return $self->{asn}{cookie} = shift || 0; + } + $self->{asn}{cookie}; +} + +sub refreshDeletes { + my $self = shift; + $self->{asn} ||= $syncDoneValue->decode($self->{value}); + if (@_) { + delete $self->{value}; + return $self->{asn}{refreshDeletes} = shift || 0; + } + $self->{asn}{refreshDeletes}; +} + +sub value { + my $self = shift; + + exists $self->{value} + ? $self->{value} + : $self->{value} = $syncDoneValue->encode($self->{asn}); +} + +1; + + +__END__ + +=head1 NAME + +Net::LDAP::Control::SyncDone - LDAPv3 Sync Done control object + +=head1 SYNOPSIS + + use Net::LDAP; + use Net::LDAP::Control::SyncRequest; + use Net::LDAP::Constant qw( + LDAP_SYNC_REFRESH_ONLY + LDAP_SYNC_REFRESH_AND_PERSIST + LDAP_SUCCESS ); + + $ldap = Net::LDAP->new( "ldap.mydomain.eg" ); + + $req = Net::LDAP::Control::SyncRequest->new( mode => LDAP_SYNC_REFRESH_ONLY ); + my $mesg = $ldap->search(base=> 'dc=mydomain,dc='eg', + scope => 'sub', + control => [ $req ], + callback => \&searchCallback, # call for each entry + filter => "(objectClass=*)", + attrs => [ '*']); + sub searchCallback { + my $message = shift; + my $entry = shift; + my @controls = $message->control; + + if($controls[0]->isa('Net::LDAP::Control::SyncState')) { + print "Received Sync State Control\n"; + print $entry->dn()."\n"; + print 'State: '.$controls[0]->state."\n".', entryUUID: '.$controls[0]->entryUUID.', cookie: '.$controls[0]->cookie; + } elsif($controls[0]->isa('Net::LDAP::Control::SyncDone')) { + print "Received Sync Done Control\n"; + print 'Cookie: '.$controls[0]->cookie.', refreshDeletes: '.$controls[0]->refreshDeletes; + } + } + +=head1 DESCRIPTION + +C<Net::LDAP::Control::SyncDone> provides an interface for the creation and +manipulation of objects that represent the C<Sync Request Control> as described +by RFC 4533. + +=head1 CONSTRUCTOR ARGUMENTS + +In addition to the constructor arguments described in +L<Net::LDAP::Control> the following are provided. + +=over 4 + +=item cookie + +=item refreshDeletes + +=back + +=head1 METHODS + +As with L<Net::LDAP::Control> each constructor argument +described above is also avaliable as a method on the object which will +return the current value for the attribute if called without an argument, +and set a new value for the attribute if called with an argument. + +=head1 SEE ALSO + +L<Net::LDAP>, +L<Net::LDAP::Control>, +L<Net::LDAP::Control::SyncRequest>, +L<Net::LDAP::Control::SyncState>, +http://www.ietf.org/rfc/rfc4533.txt + +=head1 AUTHOR + +Mathieu Parent E<lt>[EMAIL PROTECTED]<gt> + +Please report any bugs, or post any suggestions, to the perl-ldap mailing list +E<lt>[EMAIL PROTECTED]<gt> + +=head1 COPYRIGHT + +Copyright (c) 2008 Mathieu Parent. All rights reserved. This program is +free software; you can redistribute it and/or modify it under the same +terms as Perl itself. + +=cut + diff -urN --exclude=blib --exclude=debian --exclude '*~' libnet-ldap-perl-0.36-old/lib/Net/LDAP/Control/SyncRequest.pm libnet-ldap-perl-0.36/lib/Net/LDAP/Control/SyncRequest.pm --- libnet-ldap-perl-0.36-old/lib/Net/LDAP/Control/SyncRequest.pm 1970-01-01 01:00:00.000000000 +0100 +++ libnet-ldap-perl-0.36/lib/Net/LDAP/Control/SyncRequest.pm 2008-06-14 17:50:52.000000000 +0200 @@ -0,0 +1,165 @@ +# Copyright (c) 2008 Mathieu Parent <[EMAIL PROTECTED]>. All rights reserved. +# This program is free software; you can redistribute it and/or +# modify it under the same terms as Perl itself. + +package Net::LDAP::Control::SyncRequest; + +use vars qw(@ISA $VERSION); +use Net::LDAP::Control; + [EMAIL PROTECTED] = qw(Net::LDAP::Control); +$VERSION = "0.01"; + +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) = @_; + + delete $self->{asn}; + + unless (exists $self->{value}) { + $self->{asn} = { + mode => $self->{mode} || '1', + cookie => $self->{cookie} || '', + reloadHint => $self->{reloadHint} || '0', + }; + } + + $self; +} + +sub mode { + my $self = shift; + $self->{asn} ||= $syncRequestValue->decode($self->{value}); + if (@_) { + delete $self->{value}; + return $self->{asn}{mode} = shift || 0; + } + $self->{asn}{mode}; +} + +sub cookie { + my $self = shift; + $self->{asn} ||= $syncRequestValue->decode($self->{value}); + if (@_) { + delete $self->{value}; + return $self->{asn}{cookie} = shift || 0; + } + $self->{asn}{cookie}; +} + +sub reloadHint { + my $self = shift; + $self->{asn} ||= $syncRequestValue->decode($self->{value}); + if (@_) { + delete $self->{value}; + return $self->{asn}{reloadHint} = shift || 0; + } + $self->{asn}{reloadHint}; +} + +sub value { + my $self = shift; + + exists $self->{value} + ? $self->{value} + : $self->{value} = $syncRequestValue->encode($self->{asn}); +} + +1; + + +__END__ + +=head1 NAME + +Net::LDAP::Control::SyncRequest - LDAPv3 Sync Request control object + +=head1 SYNOPSIS + + use Net::LDAP; + use Net::LDAP::Control::SyncRequest; + use Net::LDAP::Constant qw( + LDAP_SYNC_REFRESH_ONLY + LDAP_SYNC_REFRESH_AND_PERSIST + LDAP_SUCCESS ); + + $ldap = Net::LDAP->new( "ldap.mydomain.eg" ); + + $req = Net::LDAP::Control::SyncRequest->new( mode => LDAP_SYNC_REFRESH_ONLY ); + my $mesg = $ldap->search(base=> 'dc=mydomain,dc='eg', + scope => 'sub', + control => [ $req ], + callback => \&searchCallback, # call for each entry + filter => "(objectClass=*)", + attrs => [ '*']); + sub searchCallback { + my $message = shift; + my $entry = shift; + my @controls = $message->control; + + if($controls[0]->isa('Net::LDAP::Control::SyncState')) { + print "Received Sync State Control\n"; + print $entry->dn()."\n"; + print 'State: '.$controls[0]->state."\n".', entryUUID: '.$controls[0]->entryUUID.', cookie: '.$controls[0]->cookie; + } elsif($controls[0]->isa('Net::LDAP::Control::SyncDone')) { + print "Received Sync Done Control\n"; + print 'Cookie: '.$controls[0]->cookie.', refreshDeletes: '.$controls[0]->refreshDeletes; + } + } + +=head1 DESCRIPTION + +C<Net::LDAP::Control::SyncRequest> provides an interface for the creation and +manipulation of objects that represent the C<Sync Request Control> as described +by RFC 4533. + +=head1 CONSTRUCTOR ARGUMENTS + +In addition to the constructor arguments described in +L<Net::LDAP::Control> the following are provided. + +=over 4 + +=item mode + +=item cookie + +=item reloadHint + +=back + +=head1 METHODS + +As with L<Net::LDAP::Control> each constructor argument +described above is also avaliable as a method on the object which will +return the current value for the attribute if called without an argument, +and set a new value for the attribute if called with an argument. + +=head1 SEE ALSO + +L<Net::LDAP>, +L<Net::LDAP::Control>, +L<Net::LDAP::Control::SyncState>, +L<Net::LDAP::Control::SyncDone>, +http://www.ietf.org/rfc/rfc4533.txt + +=head1 AUTHOR + +Mathieu Parent E<lt>[EMAIL PROTECTED]<gt> + +Please report any bugs, or post any suggestions, to the perl-ldap mailing list +E<lt>[EMAIL PROTECTED]<gt> + +=head1 COPYRIGHT + +Copyright (c) 2008 Mathieu Parent. All rights reserved. This program is +free software; you can redistribute it and/or modify it under the same +terms as Perl itself. + +=cut + diff -urN --exclude=blib --exclude=debian --exclude '*~' libnet-ldap-perl-0.36-old/lib/Net/LDAP/Control/SyncState.pm libnet-ldap-perl-0.36/lib/Net/LDAP/Control/SyncState.pm --- libnet-ldap-perl-0.36-old/lib/Net/LDAP/Control/SyncState.pm 1970-01-01 01:00:00.000000000 +0100 +++ libnet-ldap-perl-0.36/lib/Net/LDAP/Control/SyncState.pm 2008-06-14 17:50:49.000000000 +0200 @@ -0,0 +1,165 @@ +# Copyright (c) 2008 Mathieu Parent <[EMAIL PROTECTED]>. All rights reserved. +# This program is free software; you can redistribute it and/or +# modify it under the same terms as Perl itself. + +package Net::LDAP::Control::SyncState; + +use vars qw(@ISA $VERSION); +use Net::LDAP::Control; + [EMAIL PROTECTED] = qw(Net::LDAP::Control); +$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) = @_; + + delete $self->{asn}; + + unless (exists $self->{value}) { + $self->{asn} = { + state => $self->{state} || '', + entryUUID => $self->{entryUUID} || '', + cookie => $self->{cookie} || '', + }; + } + + $self; +} + +sub state { + my $self = shift; + $self->{asn} ||= $syncStateValue->decode($self->{value}); + if (@_) { + delete $self->{value}; + return $self->{asn}{state} = shift || 0; + } + $self->{asn}{state}; +} + +sub entryUUID { + my $self = shift; + $self->{asn} ||= $syncStateValue->decode($self->{value}); + if (@_) { + delete $self->{value}; + return $self->{asn}{entryUUID} = shift || 0; + } + $self->{asn}{entryUUID}; +} + +sub cookie { + my $self = shift; + $self->{asn} ||= $syncStateValue->decode($self->{value}); + if (@_) { + delete $self->{value}; + return $self->{asn}{cookie} = shift || 0; + } + $self->{asn}{cookie}; +} + +sub value { + my $self = shift; + + exists $self->{value} + ? $self->{value} + : $self->{value} = $syncStateValue->encode($self->{asn}); +} + +1; + + +__END__ + +=head1 NAME + +Net::LDAP::Control::SyncState - LDAPv3 Sync State control object + +=head1 SYNOPSIS + + use Net::LDAP; + use Net::LDAP::Control::SyncRequest; + use Net::LDAP::Constant qw( + LDAP_SYNC_REFRESH_ONLY + LDAP_SYNC_REFRESH_AND_PERSIST + LDAP_SUCCESS ); + + $ldap = Net::LDAP->new( "ldap.mydomain.eg" ); + + $req = Net::LDAP::Control::SyncRequest->new( mode => LDAP_SYNC_REFRESH_ONLY ); + my $mesg = $ldap->search(base=> 'dc=mydomain,dc='eg', + scope => 'sub', + control => [ $req ], + callback => \&searchCallback, # call for each entry + filter => "(objectClass=*)", + attrs => [ '*']); + sub searchCallback { + my $message = shift; + my $entry = shift; + my @controls = $message->control; + + if($controls[0]->isa('Net::LDAP::Control::SyncState')) { + print "Received Sync State Control\n"; + print $entry->dn()."\n"; + print 'State: '.$controls[0]->state."\n".', entryUUID: '.$controls[0]->entryUUID.', cookie: '.$controls[0]->cookie; + } elsif($controls[0]->isa('Net::LDAP::Control::SyncDone')) { + print "Received Sync Done Control\n"; + print 'Cookie: '.$controls[0]->cookie.', refreshDeletes: '.$controls[0]->refreshDeletes; + } + } + +=head1 DESCRIPTION + +C<Net::LDAP::Control::SyncState> provides an interface for the creation and +manipulation of objects that represent the C<Sync State Control> as described +by RFC 4533. + +=head1 CONSTRUCTOR ARGUMENTS + +In addition to the constructor arguments described in +L<Net::LDAP::Control> the following are provided. + +=over 4 + +=item state + +=item entryUIID + +=item cookie + +=back + +=head1 METHODS + +As with L<Net::LDAP::Control> each constructor argument +described above is also avaliable as a method on the object which will +return the current value for the attribute if called without an argument, +and set a new value for the attribute if called with an argument. + +=head1 SEE ALSO + +L<Net::LDAP>, +L<Net::LDAP::Control>, +L<Net::LDAP::Control::SyncRequest>, +L<Net::LDAP::Control::SyncDone>, +http://www.ietf.org/rfc/rfc4533.txt + +=head1 AUTHOR + +Mathieu Parent E<lt>[EMAIL PROTECTED]<gt> + +Please report any bugs, or post any suggestions, to the perl-ldap mailing list +E<lt>[EMAIL PROTECTED]<gt> + +=head1 COPYRIGHT + +Copyright (c) 2008 Mathieu Parent. All rights reserved. This program is +free software; you can redistribute it and/or modify it under the same +terms as Perl itself. + +=cut + diff -urN --exclude=blib --exclude=debian --exclude '*~' libnet-ldap-perl-0.36-old/lib/Net/LDAP/Control.pm libnet-ldap-perl-0.36/lib/Net/LDAP/Control.pm --- libnet-ldap-perl-0.36-old/lib/Net/LDAP/Control.pm 2008-04-21 17:11:06.000000000 +0200 +++ libnet-ldap-perl-0.36/lib/Net/LDAP/Control.pm 2008-06-14 17:32:30.000000000 +0200 @@ -21,9 +21,12 @@ LDAP_CONTROL_PASSWORDPOLICY LDAP_CONTROL_PREREAD LDAP_CONTROL_POSTREAD + LDAP_CONTROL_SYNC + LDAP_CONTROL_SYNC_STATE + LDAP_CONTROL_SYNC_DONE ); -$VERSION = "0.08"; +$VERSION = "0.09"; my %Pkg2Type = ( @@ -49,6 +52,10 @@ 'Net::LDAP::Control::PreRead' => LDAP_CONTROL_PREREAD, 'Net::LDAP::Control::PostRead' => LDAP_CONTROL_POSTREAD, + + 'Net::LDAP::Control::SyncRequest' => LDAP_CONTROL_SYNC, + 'Net::LDAP::Control::SyncState' => LDAP_CONTROL_SYNC_STATE, + 'Net::LDAP::Control::SyncDone' => LDAP_CONTROL_SYNC_DONE, # #LDAP_CONTROL_PWEXPIRED #LDAP_CONTROL_PWEXPIRING diff -urN --exclude=blib --exclude=debian --exclude '*~' libnet-ldap-perl-0.36-old/lib/Net/LDAP/Search.pm libnet-ldap-perl-0.36/lib/Net/LDAP/Search.pm --- libnet-ldap-perl-0.36-old/lib/Net/LDAP/Search.pm 2008-04-21 17:11:06.000000000 +0200 +++ libnet-ldap-perl-0.36/lib/Net/LDAP/Search.pm 2008-06-14 20:09:52.000000000 +0200 @@ -12,7 +12,7 @@ use Net::LDAP::Constant qw(LDAP_SUCCESS LDAP_DECODING_ERROR); @ISA = qw(Net::LDAP::Message); -$VERSION = "0.11"; +$VERSION = "0.12"; sub first_entry { # compat @@ -36,6 +36,9 @@ 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); diff -urN --exclude=blib --exclude=debian --exclude '*~' libnet-ldap-perl-0.36-old/Makefile libnet-ldap-perl-0.36/Makefile --- libnet-ldap-perl-0.36-old/Makefile 2008-06-14 14:01:18.000000000 +0200 +++ libnet-ldap-perl-0.36/Makefile 2008-06-14 20:13:27.000000000 +0200 @@ -177,6 +177,9 @@ lib/Net/LDAP/Control/ProxyAuth.pm \ lib/Net/LDAP/Control/Sort.pm \ lib/Net/LDAP/Control/SortResult.pm \ + lib/Net/LDAP/Control/SyncDone.pm \ + lib/Net/LDAP/Control/SyncRequest.pm \ + lib/Net/LDAP/Control/SyncState.pm \ lib/Net/LDAP/Control/VLV.pm \ lib/Net/LDAP/Control/VLVResponse.pm \ lib/Net/LDAP/DSML.pm \ @@ -238,6 +241,9 @@ lib/Net/LDAP/Control/ProxyAuth.pm \ lib/Net/LDAP/Control/Sort.pm \ lib/Net/LDAP/Control/SortResult.pm \ + lib/Net/LDAP/Control/SyncDone.pm \ + lib/Net/LDAP/Control/SyncRequest.pm \ + lib/Net/LDAP/Control/SyncState.pm \ lib/Net/LDAP/Control/VLV.pm \ lib/Net/LDAP/Control/VLVResponse.pm \ lib/Net/LDAP/DSML.pm \ @@ -274,6 +280,8 @@ blib/lib/Net/LDAP/Entry.pod \ lib/Net/LDAP/FilterMatch.pm \ blib/lib/Net/LDAP/FilterMatch.pm \ + lib/Net/LDAP/Control/SyncDone.pm \ + blib/lib/Net/LDAP/Control/SyncDone.pm \ lib/Net/LDAP/Message.pod \ blib/lib/Net/LDAP/Message.pod \ lib/Net/LDAP/Util.pm \ @@ -304,6 +312,8 @@ blib/lib/Net/LDAP/Control/Sort.pm \ lib/Net/LDAPS.pm \ blib/lib/Net/LDAPS.pm \ + lib/Net/LDAP/Control/SyncRequest.pm \ + blib/lib/Net/LDAP/Control/SyncRequest.pm \ lib/Net/LDAP/Message.pm \ blib/lib/Net/LDAP/Message.pm \ lib/Net/LDAP/FAQ.pod \ @@ -352,6 +362,8 @@ blib/lib/Net/LDAP/Extension/SetPassword.pm \ lib/Net/LDAP.pm \ blib/lib/Net/LDAP.pm \ + lib/Net/LDAP/Control/SyncState.pm \ + blib/lib/Net/LDAP/Control/SyncState.pm \ lib/Net/LDAP/Extension.pm \ blib/lib/Net/LDAP/Extension.pm \ lib/Net/LDAP/Reference.pod \ @@ -584,6 +596,7 @@ lib/Net/LDAP/Control/PostRead.pm \ lib/Net/LDAP/Entry.pod \ lib/Net/LDAP/FilterMatch.pm \ + lib/Net/LDAP/Control/SyncDone.pm \ lib/Net/LDAP/Message.pod \ lib/Net/LDAP/Util.pm \ lib/Net/LDAP/Extension/WhoAmI.pm \ @@ -598,6 +611,7 @@ lib/Net/LDAPI.pm \ lib/Net/LDAP/Control/Sort.pm \ lib/Net/LDAPS.pm \ + lib/Net/LDAP/Control/SyncRequest.pm \ lib/Net/LDAP/FAQ.pod \ lib/Net/LDAP/RootDSE.pm \ lib/Bundle/Net/LDAP.pm \ @@ -613,6 +627,7 @@ lib/Net/LDAP/Examples.pod \ lib/Net/LDAP/RFC.pod \ lib/Net/LDAP/Extension/SetPassword.pm \ + lib/Net/LDAP/Control/SyncState.pm \ lib/Net/LDAP/Reference.pod \ lib/Net/LDAP.pod \ lib/Net/LDAP/Constant.pm \ @@ -621,6 +636,7 @@ lib/Net/LDAP/Control/PostRead.pm $(INST_MAN3DIR)/Net::LDAP::Control::PostRead.$(MAN3EXT) \ lib/Net/LDAP/Entry.pod $(INST_MAN3DIR)/Net::LDAP::Entry.$(MAN3EXT) \ lib/Net/LDAP/FilterMatch.pm $(INST_MAN3DIR)/Net::LDAP::FilterMatch.$(MAN3EXT) \ + lib/Net/LDAP/Control/SyncDone.pm $(INST_MAN3DIR)/Net::LDAP::Control::SyncDone.$(MAN3EXT) \ lib/Net/LDAP/Message.pod $(INST_MAN3DIR)/Net::LDAP::Message.$(MAN3EXT) \ lib/Net/LDAP/Util.pm $(INST_MAN3DIR)/Net::LDAP::Util.$(MAN3EXT) \ lib/Net/LDAP/Extension/WhoAmI.pm $(INST_MAN3DIR)/Net::LDAP::Extension::WhoAmI.$(MAN3EXT) \ @@ -635,6 +651,7 @@ lib/Net/LDAPI.pm $(INST_MAN3DIR)/Net::LDAPI.$(MAN3EXT) \ lib/Net/LDAP/Control/Sort.pm $(INST_MAN3DIR)/Net::LDAP::Control::Sort.$(MAN3EXT) \ lib/Net/LDAPS.pm $(INST_MAN3DIR)/Net::LDAPS.$(MAN3EXT) \ + lib/Net/LDAP/Control/SyncRequest.pm $(INST_MAN3DIR)/Net::LDAP::Control::SyncRequest.$(MAN3EXT) \ lib/Net/LDAP/FAQ.pod $(INST_MAN3DIR)/Net::LDAP::FAQ.$(MAN3EXT) \ lib/Net/LDAP/RootDSE.pm $(INST_MAN3DIR)/Net::LDAP::RootDSE.$(MAN3EXT) \ lib/Bundle/Net/LDAP.pm $(INST_MAN3DIR)/Bundle::Net::LDAP.$(MAN3EXT) \ @@ -650,6 +667,7 @@ lib/Net/LDAP/Examples.pod $(INST_MAN3DIR)/Net::LDAP::Examples.$(MAN3EXT) \ lib/Net/LDAP/RFC.pod $(INST_MAN3DIR)/Net::LDAP::RFC.$(MAN3EXT) \ lib/Net/LDAP/Extension/SetPassword.pm $(INST_MAN3DIR)/Net::LDAP::Extension::SetPassword.$(MAN3EXT) \ + lib/Net/LDAP/Control/SyncState.pm $(INST_MAN3DIR)/Net::LDAP::Control::SyncState.$(MAN3EXT) \ lib/Net/LDAP/Reference.pod $(INST_MAN3DIR)/Net::LDAP::Reference.$(MAN3EXT) \ lib/Net/LDAP.pod $(INST_MAN3DIR)/Net::LDAP.$(MAN3EXT) \ lib/Net/LDAP/Constant.pm $(INST_MAN3DIR)/Net::LDAP::Constant.$(MAN3EXT) \ @@ -1005,6 +1023,7 @@ lib/Net/LDAP/Control/PostRead.pm blib/lib/Net/LDAP/Control/PostRead.pm \ lib/Net/LDAP/Entry.pod blib/lib/Net/LDAP/Entry.pod \ lib/Net/LDAP/FilterMatch.pm blib/lib/Net/LDAP/FilterMatch.pm \ + lib/Net/LDAP/Control/SyncDone.pm blib/lib/Net/LDAP/Control/SyncDone.pm \ lib/Net/LDAP/Message.pod blib/lib/Net/LDAP/Message.pod \ lib/Net/LDAP/Util.pm blib/lib/Net/LDAP/Util.pm \ lib/Net/LDAP/Extension/WhoAmI.pm blib/lib/Net/LDAP/Extension/WhoAmI.pm \ @@ -1020,6 +1039,7 @@ lib/Net/LDAPI.pm blib/lib/Net/LDAPI.pm \ lib/Net/LDAP/Control/Sort.pm blib/lib/Net/LDAP/Control/Sort.pm \ lib/Net/LDAPS.pm blib/lib/Net/LDAPS.pm \ + lib/Net/LDAP/Control/SyncRequest.pm blib/lib/Net/LDAP/Control/SyncRequest.pm \ lib/Net/LDAP/Message.pm blib/lib/Net/LDAP/Message.pm \ lib/Net/LDAP/FAQ.pod blib/lib/Net/LDAP/FAQ.pod \ lib/Net/LDAP/Search.pm blib/lib/Net/LDAP/Search.pm \ @@ -1044,6 +1064,7 @@ lib/Net/LDAP/RFC.pod blib/lib/Net/LDAP/RFC.pod \ lib/Net/LDAP/Extension/SetPassword.pm blib/lib/Net/LDAP/Extension/SetPassword.pm \ lib/Net/LDAP.pm blib/lib/Net/LDAP.pm \ + lib/Net/LDAP/Control/SyncState.pm blib/lib/Net/LDAP/Control/SyncState.pm \ lib/Net/LDAP/Extension.pm blib/lib/Net/LDAP/Extension.pm \ lib/Net/LDAP/Reference.pod blib/lib/Net/LDAP/Reference.pod \ lib/Net/LDAP.pod blib/lib/Net/LDAP.pod \