From Notes
#!/usr/bin/perl
use strict ;
use Net::LDAP ;
use Getopt::Std ;
my $debug = 0 ;
my %opts ;
getopt('Hcv', \%opts) ;
my $searchbase = "dc=example,dc=org" ;
my $userbase = "ou=People,$searchbase" ;
my $bind_dn = "uid=replicator,ou=serviceaccounts,$userbase" ;
my $bind_pw = "password" ;
unless ( ( $opts{'H'} && $opts{'c'} ) ) {
usage() ;
exit(1);
}
my @hosts = () ;
push @hosts, $opts{'H'} ;
push @hosts, $opts{'c'} ;
my %csn_list = () ;
foreach my $server (@hosts) {
# Get contextCSN and store only the first 10 digits, which is YYYYMMDDHH
$csn_list{"$server"} = substr( getContextCSN($server) , 0, 10) ;
if ( $debug ) {
printf "Current contextCSN for server %s: %s\n", $server, getContextCSN($server) ;
}
}
# Check the hash, counting unique occurences and assigning these values to %base
my %base = () ;
foreach (keys %csn_list) {
$base{$csn_list{$_}}++ ;
}
my @count = %base ;
if ( $#count > 1 ) {
printf "WARNING: LDAP Servers are NOT synchronized.\n" ;
exit(1) ;
}
printf "OK: LDAP servers are synchronized.\n" ;
exit(0) ;
## Sub-routines ##
sub usage {
printf "\n" ;
printf "$0: -H <provider> -c <consumer>\n" ;
printf "\n" ;
}
sub getContextCSN {
my $server = $_[0] ;
my $contextcsn ;
my $ldap = Net::LDAP->new("$server") or die "$@" ;
my $mesg = $ldap->start_tls(
verify => 'never',
cafile => '/usr/share/ssl/certs/cacert.crt',
sslversion => 'tlsv1',
ciphers => 'HIGH'
);
$mesg = $ldap->bind( $bind_dn, password => $bind_pw) or die "could not bind to ldap server: $server\n" ;
$mesg->code && die $mesg->error ;
my $result = $ldap->search (
base => "$searchbase",
scope => "subtree",
filter => "(objectclass=domain)",
sizelimit => 1,
attrs => ['contextCSN']
) ;
my @entries = $result->entries ;
foreach my $entry ( @entries ) {
$contextcsn = $entry->get_value('contextCSN');
}
$mesg = $ldap->unbind() ;
return $contextcsn ;
}