check_ldap_repl.pl
changeset 21 172a86d4d34e
parent 20 79e0cc971747
--- 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 <http://www.gnu.org/licenses/>.
-#
-#    Matthias Förste <foerste@schlittermann.de>
-
-=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<string>
-
-Attribute of the entry that will be updated and checked for replication. (default: description)
-
-=item B<-d>|B<--dn> I<string>
-
-DN of the entry whose attribute will be updated and checked for replication.
-
-=item B<-b>|B<--binddn> I<string>
-
-DN to use when binding to provider for update. (default: same as dn)
-
-=item B<--password> I<string>
-
-Password to use when binding to provider for update. B<PASSWORD IS SHOWN IN PROCESSES, USE CONFIG FILE!>
-
-=item B<-p>|B<--provider> I<string>
-
-provider uri (default: ldapi:///)
-
-=item B<-S>|B<--consumer> I<string>
-
-consumer uri. Multiple consumers can be specified as a comma separated list (see below).
-
-=item B<--config> I<string>
-
-Path to configuration file. Use this to store the binddn and its password.
-Verify the ownership and B<permissions>, 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<integer>
-
-Wait I<n> 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<check_ldap_repl>.
-
-=head1 AUTHOR
-
-Written by Christian Arnold L<arnold@schlittermann.de>. Modified by Matthias Förste L<foerste@schlittermann.de>.
-
-=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