diff -r 79e0cc971747 -r 172a86d4d34e check_ldap_repl.pl --- a/check_ldap_repl.pl Mon May 02 14:10:28 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,259 +0,0 @@ -#! /usr/bin/perl -w - -# Copyright (C) 2012 Christian Arnold -# Copyright (C) 2016 Matthias Förste -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# Matthias Förste - -=encoding utf8 -=cut - -use strict; -use warnings; - -# required? https://rt.cpan.org/Public/Bug/Display.html?id=95875 -use threads; - -use File::Basename; -use AppConfig; -use Net::LDAP; -use File::stat; -use Pod::Usage; -use if $ENV{DEBUG} => "Smart::Comments"; - -my %ERRORS = ( - OK => 0, - WARNING => 1, - CRITICAL => 2, - UNKNOWN => 3, - DEPENDENT => 4 -); - -my $ME = basename $0; -my $NAME = "LDAPREPL"; -my $VERSION = "0.4"; - -my $defaults = { - 'attribute|a=s' => 'description', - 'dn|d=s' => undef, - 'binddn|D=s' => undef, - 'password=s' => undef, - 'config=s' => '/etc/nagios-plugins/config/ldap_repl.cfg', - 'provider|p=s' => 'ldapi:///', - 'consumer|c=s@' => undef, - 'wait|w=i' => 1, - 'help|h!' => sub { pod2usage(-verbose => 1, -exitval => $ERRORS{OK}) }, - 'man|m!' => sub { pod2usage(-verbose => 2, -exitval => $ERRORS{OK}) }, - 'version|V!' => sub { version($ME, $VERSION); exit $ERRORS{OK}; } -}; - -sub critical { print STDERR "$NAME CRITICAL: ", @_; exit $ERRORS{CRITICAL}; } -$SIG{__DIE__} = sub { print STDERR "$NAME UNKNOWN: ", @_; exit $ERRORS{UNKNOWN}; }; - -sub stamp { - my ($u, $dn, $attr) = @_; - - my $l = ref $u eq 'Net::LDAP' ? $u : Net::LDAP->new($u, onerror => 'die') - or die "$@"; - my $r = $l->search(base => $dn, scope => 'base', filter => '(objectClass=*)'); - die "unexpected result count: ", $r->count unless $r->count == 1; - my @v = $r->entry(0)->get_value($attr); - die "unexpected value count [@v]" unless @v == 1; - return $v[0]; - -} - -sub version { - my ($progname, $version) = @_; - - print <<_VERSION; -$progname version $version -Copyright (C) 2012 by Christian Arnold and Schlittermann internet & unix support. -Copyright (C) 2016 by Matthias Förste and Schlittermann internet & unix support. - -$ME comes with ABSOLUTELY NO WARRANTY. This is free software, -and you are welcome to redistribute it under certain conditions. -See the GNU General Public Licence for details. -_VERSION -} - -MAIN: { - - my $c = AppConfig->new( - { CASE => 1 }, - map { - $_, - { ref $defaults->{$_} eq 'CODE' - ? 'ACTION' - : 'DEFAULT' => $defaults->{$_} } - } keys %{$defaults} - ) or die "Can't initialize"; - - my $cf = $c->get('config'); - - # ignore default configuration file if it does not exist - $c->file($cf) if -e $cf; - - # read configuration file if passed on command line - $c->getopt(qw(no_ignore_case)); - $c->file($cf) if $cf ne ($cf = $c->get('config')); - - # make sure that command line options override any config file options - $c->getopt; - - my %o = $c->varlist('.'); - $o{binddn} //= $o{dn}; - my $t = time(); - - my $p = Net::LDAP->new($o{provider}, onerror => 'die') or die $@; - $p->bind($o{binddn}, password => $o{password}); - $p->modify($o{dn}, replace => { $o{attribute} => $t }); - - my $tp = stamp($p, $o{dn}, $o{attribute}); - die "Provider update failed for unknown reason\n" unless $tp == $t; - sleep $o{wait}; - for (@{ $o{consumer} }) { - critical "'$_' out of sync\n" - unless $tp == stamp($_, $o{dn}, $o{attribute}); - } - - print "$NAME OK: servers are in sync\n"; - exit $ERRORS{OK}; - -} - -__END__ - -=pod - -=head1 NAME - -check_ldap_repl - nagios/icinga plugin to check ldap replication. This works by -updating an entry on the provider and checking whether the update is replicated -by querying the consumers for the updated entry after a short waiting period. - -=head1 SYNOPSIS - -check_ldap_repl [-d|--dn string] - [-D|--binddn string] - [--password string] - [--config string] - [-p|--provider string] - [-c|--consumer string] - [-w|--wait integer] - [-h|--help] - [-m|--man] - [-V|--version] - -=head1 OPTIONS - -=over - -=item B<-a>|B<--attribute> I - -Attribute of the entry that will be updated and checked for replication. (default: description) - -=item B<-d>|B<--dn> I - -DN of the entry whose attribute will be updated and checked for replication. - -=item B<-b>|B<--binddn> I - -DN to use when binding to provider for update. (default: same as dn) - -=item B<--password> I - -Password to use when binding to provider for update. B - -=item B<-p>|B<--provider> I - -provider uri (default: ldapi:///) - -=item B<-S>|B<--consumer> I - -consumer uri. Multiple consumers can be specified as a comma separated list (see below). - -=item B<--config> I - -Path to configuration file. Use this to store the binddn and its password. -Verify the ownership and B, B<(0400)> is a good choice! (default: -/etc/nagios-plugins/config/ldap_repl.cfg) - - -Example: - - # attribute = description - dn = cn=replcheck,dc=local,dc=site - # binddn = # same as dn per default - password = secret - #provider = ldapi:/// - consumer = ldap://consumer-01:389/,ldap://consumer-02:389/,... - #wait = 1 - -=item B<-w>|B<--wait> I - -Wait I seconds before checking the consumer servers. (default: 1) - -=item B<-h>|B<--help> - -Print detailed help screen. - -=item B<-m>|B<--man> - -Print manual page. - -=item B<-V>|B<--version> - -Print version information. - -=back - -=head1 DESCRIPTION - -This plugin checks if the ldap replication works correctly by updating an -attribute of an entry on the provider and checking whether the update has been -replicated to one or more consumers after some configurable time. It is -recommended to run it on the provider because the directory needs to be updated -there. The object classes for dn and binddn don't matter much, but they should -support authentication and the chosen attribute for updates. The attribute -should support numeric integer values (it will be updated with the current -unix epoch). Example: - - 430 cn=replcheck,ou=Users,dc=wiegandslide,dc=de - objectClass: simpleSecurityObject - objectClass: applicationProcess - cn: replcheck - userPassword: {SSHA}Twb/q2n4G6+PmSUfZaK09smj751ts9Rz - -The attribute does not neccessarily need to exist initially. It should be -created upon first update. You may also need to update your acl. - -=head1 VERSION - -This man page is current for version 0.4 of B. - -=head1 AUTHOR - -Written by Christian Arnold L. Modified by Matthias Förste L. - -=head1 COPYRIGHT - -Copyright (C) 2012 by Christian Arnold and Schlittermann internet & unix support. -Copyright (C) 2016 by Matthias Förste and Schlittermann internet & unix support. -This is free software, and you are welcome to redistribute it under certain conditions. -See the GNU General Public Licence for details. - -=cut