dkluenter

#!/usr/bin/perl
# $Id: syncRequest-2.pl,v 1.1 2010/09/05 10:22:25 dieter Exp dieter $
# Heavily stolen from Mathieu Parent

use strict;
use 
Data::Dumper;
use 
Net::LDAP;
use 
Net::LDAP::Control::SyncRequest;
use 
Net::LDAP::Constant qw(
                            
LDAP_SYNC_REFRESH_ONLY
                            LDAP_SYNC_REFRESH_AND_PERSIST
                            LDAP_USER_CANCELED
                            LDAP_SUCCESS
);
use 
Authen::SASL qw(Perl);

$| = 
1;

my $cookie 'rid=099,csn=20100905102029.750495Z#000000#000#000000';
my $tls_cacert '/etc/openldap/certs/avciCA.pem';
my $tls_cert '/etc/openldap/certs/replicator.pem';
my $tls_key '/etc/openldap/certs/replicator-key.pem';
my $base 'o=avci,c=de';

my $ldap Net::LDAP->new'ldap://localhost',
                            
async    => 1,
                            
onerror  => 'die',
                            
# debug    => 15,
                            
);
my $tls $ldap->start_tlsverify => 'require',
                            
clientcert => $tls_cert,
                            
clientkey => $tls_key,
                            
cafile => $tls_cacert,
                            
sslversion => 'tlsv1',
                            
ciphers => 'HIGH',
                          );
 if ( 
$tls->code){
print (
"error number: " $tls->code "n");
print (
"error: " $tls->error_text "n");
print (
"is_error: " $tls->is_error "n");
 };
my $sasl Authen::SASL->new(mechanism => 'EXTERNAL',
                             
callback => { user => ''}
                            );

die $! if !
$ldap;
my $req Net::LDAP::Control::SyncRequest->newmode =>
                                                
LDAP_SYNC_REFRESH_AND_PERSIST,
                                                
critical => 'TRUE',
                                                
cookie => $cookie,
                                              );
my $msg $ldap->bindsasl => $sasl );
my $mesg2 $ldap->search(
                          
base=> $base,
                          
scope    => 'sub',
                          
control  => [ $req ],
                          
callback => &searchCallback,
                          
filter   => "(objectClass=*)",
                          
attrs    => [ '*','+'],
                            );
while(!
$mesg2->done()) {
    
$ldap->process();
    
sleep(1);
    print 
".n";
}

print 
"ENDn";

sub searchCallback {
  print 
"<<Callback startn";
   
my $message shift;
   
my $param2 shift;
   
my @controls $message->control;
  
my @sync_controls;
  if(
$param2 && $param2->isa("Net::LDAP::Entry")) {
    print 
"Received Search Entryn";
    foreach 
my $ctrl (@controls) {
      
push(@sync_controls$ctrl)
        if 
$ctrl->isa('Net::LDAP::Control::SyncState');
    }
    die 
'Got search entry with multiple Sync State controls' if
@
sync_controls>1;
    die 
'Got search entry without Sync State control' if !@sync_controls;
    die 
'Got empty entryUUID' if !$sync_controls[0]->entryUUID;
    print 
'Search Entry has Sync State Control: '.
      
'state='.$sync_controls[0]->state().
      
'; entryUUID='.unpack("H*",$sync_controls[0]->entryUUID()).
      
'; cookie='.(defined($sync_controls[0]->cookie()) ?
$sync_controls[0]->cookie() : 'UNDEF')."n";
    if(
defined($sync_controls[0]->cookie)) {
      
$cookie $sync_controls[0]->cookie;
      print 
"New cookie: ".$cookie."n";
    }
    print 
"Entry (".$param2->changetype."): ".$param2->dn()."n";
  } 
elsif($param2 && $param2->isa("Net::LDAP::Reference")) {
    print 
"Received Search Referencen";
    return;
  } 
elsif($controls[0] and $controls[0]->isa('Net::LDAP::Control::SyncDone')) {
    print 
'Received Sync Done Control: '.
      
'cookie='.(defined($controls[0]->cookie()) ?
$controls[0]->cookie() : 'UNDEF').
      
'; refreshDeletes='.$controls[0]->refreshDeletes()."n";
    if(
defined($controls[0]->cookie())
        and 
not $controls[0]->cookie() eq ''
        
and not $controls[0]->cookie() eq $cookie) {
          
$cookie $controls[0]->cookie();
          print 
"New cookie: $cookie n";
          }
  } 
elsif($param2 && $param2->isa("Net::LDAP::Intermediate::SyncInfo")) {
    print 
"Received Intermediate SyncInfo Messagen";
    
my $attrs $param2->{asn};
    if(
$attrs->{newcookie}) {
      
$cookie $attrs->{newcookie};;
      print 
"New cookie: $cookien";
    } 
elsif(my $refreshInfos = ($attrs->{refreshDelete} ||
$attrs->{refreshPresent})) {
      
$cookie $refreshInfos->{cookie} if defined($refreshInfos->{cookie});
      print (
defined($refreshInfos->{cookie}) ? 'New ' 'Empty ');
      print 
"cookie from ".
        (
$attrs->{refreshDelete} ? 'refreshDelete' 'refreshPresent').
        
" (refreshDone=".$refreshInfos->{refreshDone}."): $cookien";
    } 
elsif(my $syncIdSetInfos $attrs->{syncIdSet}) {
      
$cookie $syncIdSetInfos->{cookie} if defined($syncIdSetInfos->{cookie});
      print (
defined($syncIdSetInfos->{cookie}) ? 'Empty ' 'New ');
      print 
"cookie from syncIdSet".
        
" (refreshDeletes=".$syncIdSetInfos->{refreshDeletes}."): $cookien";
      foreach 
my $syncUUID ($syncIdSetInfos->{syncUUIDs}) {
        print 
'entryUUID='.unpack("H*",$syncUUID)."n";
      }
    }
}
 
elsif($message->code) {
    if (
$message->code == 1) {
  die 
"Communication Error: disconnecting";
 }
 
elsif ($message->code == LDAP_USER_CANCELED) {
        print 
"searchCallback() -> Exit code received, returningn";
        return;
   }
  
elsif ($message->code == 4096) {
       print 
"Refresh requiredn";
       
$cookie '';
   } else {
        die 
"searchCallback: mesg->code = `" $message->code "',
 mesg->msg = `" 
$message->error "'";
    }
  }
 else {
    die 
"Received something else.";
  }
 print 
"Callback end>>n";
  return 
0;
 } 


» dkluenter
« ohne Titel