243 lines
6.4 KiB
Perl
243 lines
6.4 KiB
Perl
|
#! /usr/bin/perl -w
|
||
|
#---------------------------------------------------------------------------
|
||
|
# Check LDAP query server plugin Pandora FMS
|
||
|
#
|
||
|
# Request an LDAP server and count entries returned
|
||
|
# Artica ST
|
||
|
# Copyright (C) 2013 mario.pulido@artica.es
|
||
|
#
|
||
|
# License: GPLv2+
|
||
|
#---------------------------------------------------------------------------
|
||
|
# 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 2
|
||
|
# 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.
|
||
|
#
|
||
|
# GPL License: http://www.gnu.org/licenses/gpl.txt
|
||
|
#---------------------------------------------------------------------------
|
||
|
|
||
|
my $VERSION = 'v1r1';
|
||
|
#---------------------------------------------------------------------------
|
||
|
# Modules
|
||
|
#---------------------------------------------------------------------------
|
||
|
use strict;
|
||
|
use Getopt::Long;
|
||
|
&Getopt::Long::config('bundling');
|
||
|
use File::Basename;
|
||
|
use Net::LDAP;
|
||
|
|
||
|
#---------------------------------------------------------------------------
|
||
|
# Options
|
||
|
#---------------------------------------------------------------------------
|
||
|
my $progname = basename($0);
|
||
|
my $help;
|
||
|
my $version;
|
||
|
my $verbose = 0;
|
||
|
my $host;
|
||
|
my $authentication;
|
||
|
my $log_file;
|
||
|
my $name;
|
||
|
my $port;
|
||
|
my $regexp;
|
||
|
my $eregexp;
|
||
|
my $exclude;
|
||
|
my $minute = 60;
|
||
|
my $url;
|
||
|
|
||
|
|
||
|
# For LDAP plugins
|
||
|
my $ldap_binddn;
|
||
|
my $ldap_bindpw;
|
||
|
my $ldap_filter;
|
||
|
my $ldap_base;
|
||
|
my $ldap_scope;
|
||
|
|
||
|
GetOptions(
|
||
|
'h' => \$help,
|
||
|
'help' => \$help,
|
||
|
'v+' => \$verbose,
|
||
|
'verbose+' => \$verbose,
|
||
|
'H:s' => \$host,
|
||
|
'host:s' => \$host,
|
||
|
'p:i' => \$port,
|
||
|
'port:i' => \$port,
|
||
|
'u:s' => \$ldap_binddn,
|
||
|
'binddn:s' => \$ldap_binddn,
|
||
|
'P:s' => \$ldap_bindpw,
|
||
|
'bindpw:s' => \$ldap_bindpw,
|
||
|
'Q:s' => \$ldap_filter,
|
||
|
'filter:s' => \$ldap_filter,
|
||
|
'b:s' => \$ldap_base,
|
||
|
'base:s' => \$ldap_base,
|
||
|
's:s' => \$ldap_scope,
|
||
|
'scope:s' => \$ldap_scope,
|
||
|
);
|
||
|
|
||
|
|
||
|
#---------------------------------------------------------------------------
|
||
|
# Functions
|
||
|
#---------------------------------------------------------------------------
|
||
|
|
||
|
# DEBUG function
|
||
|
sub verbose {
|
||
|
my $output_code = shift;
|
||
|
my $text = shift;
|
||
|
if ( $verbose >= $output_code ) {
|
||
|
printf "VERBOSE $output_code ===> %s\n", $text;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# check if -H -b and -F is used
|
||
|
sub check_host_param {
|
||
|
if ( !defined($host)) {
|
||
|
|
||
|
print "-H, --host=STRING\n";
|
||
|
print "\tIP or name (FQDN) of the directory. You can use URI (ldap://, ldaps://, ldap+tls://)\n";
|
||
|
print "-p, --port=INTEGER\n";
|
||
|
print "\tDirectory port to connect to.\n";
|
||
|
print "-u, --binddn=STRING\n";
|
||
|
print "\tBind DN. Bind anonymous if not present.\n";
|
||
|
print "-P, --bindpw=STRING\n";
|
||
|
print "\tBind passwd. Need the Bind DN option to work.\n";
|
||
|
print "-Q, --filter=STRING\n";
|
||
|
print "\tLDAP search filter.\n";
|
||
|
print "-b, --base=STRING\n";
|
||
|
print "\tLDAP search base.\n";
|
||
|
print "-s, --scope=STRING\n";
|
||
|
print "\tLDAP search scope\n";
|
||
|
print "\n";
|
||
|
|
||
|
print "Version=$VERSION";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
# Bind to LDAP server
|
||
|
sub get_ldapconn {
|
||
|
&verbose( '3', "Enter &get_ldapconn" );
|
||
|
my ( $server, $binddn, $bindpw ) = @_;
|
||
|
my ( $useTls, $tlsParam );
|
||
|
|
||
|
# Manage ldap+tls:// URI
|
||
|
if ( $server =~ m{^ldap\+tls://([^/]+)/?\??(.*)$} ) {
|
||
|
$useTls = 1;
|
||
|
$server = $1;
|
||
|
$tlsParam = $2 || "";
|
||
|
}
|
||
|
else {
|
||
|
$useTls = 0;
|
||
|
}
|
||
|
|
||
|
my $ldap = Net::LDAP->new( $server );
|
||
|
|
||
|
return ('1') unless ($ldap);
|
||
|
&verbose( '2', "Connected to $server" );
|
||
|
|
||
|
if ($useTls) {
|
||
|
my %h = split( /[&=]/, $tlsParam );
|
||
|
my $message = $ldap->start_tls(%h);
|
||
|
$message->code
|
||
|
&& &verbose( '1', $message->error )
|
||
|
&& return ( $message->code, $message->error );
|
||
|
&verbose( '2', "startTLS succeed on $server" );
|
||
|
}
|
||
|
|
||
|
if ( $binddn && $bindpw ) {
|
||
|
|
||
|
# Bind witch credentials
|
||
|
my $req_bind = $ldap->bind( $binddn, password => $bindpw );
|
||
|
$req_bind->code
|
||
|
&& &verbose( '1', $req_bind->error )
|
||
|
&& return ( $req_bind->code, $req_bind->error );
|
||
|
&verbose( '2', "Bind with $binddn" );
|
||
|
}
|
||
|
else {
|
||
|
my $req_bind = $ldap->bind();
|
||
|
$req_bind->code
|
||
|
&& &verbose( '1', $req_bind->error )
|
||
|
&& return ( $req_bind->code, $req_bind->error );
|
||
|
&verbose( '2', "Bind anonym" );
|
||
|
}
|
||
|
&verbose( '3', "Leave &get_ldapconn" );
|
||
|
return ( '0', $ldap );
|
||
|
}
|
||
|
|
||
|
# Get the master URI from cn=monitor
|
||
|
sub get_entries {
|
||
|
&verbose( '3', "Enter &get_entries" );
|
||
|
my ( $ldapconn, $base, $scope, $filter ) = @_;
|
||
|
my $message;
|
||
|
my $count;
|
||
|
$message = $ldapconn->search(
|
||
|
base => $base,
|
||
|
scope => $scope,
|
||
|
filter => $filter,
|
||
|
attrs => ['1.1']
|
||
|
);
|
||
|
$message->code
|
||
|
&& &verbose( '1', $message->error )
|
||
|
&& return ( $message->code, $message->error );
|
||
|
$count = $message->count();
|
||
|
&verbose( '2', "Found $count entries" );
|
||
|
&verbose( '3', "Leave &get_entries" );
|
||
|
return ( 0, $count );
|
||
|
}
|
||
|
|
||
|
#---------------------------------------------------------------------------
|
||
|
# Main
|
||
|
#---------------------------------------------------------------------------
|
||
|
|
||
|
# Options checks
|
||
|
&check_host_param();
|
||
|
#&check_base_param();
|
||
|
|
||
|
# Default values
|
||
|
#$ldap_filter ||= "(objectClass=*)";
|
||
|
$ldap_scope ||= "sub";
|
||
|
|
||
|
my $errorcode;
|
||
|
|
||
|
# Connect to the directory
|
||
|
# If $host is an URI, use it directly
|
||
|
my $ldap_uri;
|
||
|
if ( $host =~ m#ldap(\+tls)?(s)?://.*# ) {
|
||
|
$ldap_uri = $host;
|
||
|
$ldap_uri .= ":$port" if ( $port and $host !~ m#:(\d)+# );
|
||
|
}
|
||
|
else {
|
||
|
$ldap_uri = "ldap://$host";
|
||
|
$ldap_uri .= ":$port" if $port;
|
||
|
}
|
||
|
|
||
|
my $ldap_server;
|
||
|
( $errorcode, $ldap_server ) =
|
||
|
&get_ldapconn( $ldap_uri, $ldap_binddn, $ldap_bindpw );
|
||
|
if ($errorcode) {
|
||
|
print "Can't connect to $ldap_uri.\n";
|
||
|
}
|
||
|
|
||
|
# Request LDAP
|
||
|
my $nb_entries;
|
||
|
( $errorcode, $nb_entries ) =
|
||
|
&get_entries( $ldap_server, $ldap_base, $ldap_scope, $ldap_filter );
|
||
|
if ($errorcode) {
|
||
|
print "0\n";
|
||
|
}
|
||
|
|
||
|
#---------------------------------------------------------------------------
|
||
|
# Exit
|
||
|
#---------------------------------------------------------------------------
|
||
|
|
||
|
# Print $nb_entries and exit
|
||
|
print "$nb_entries\n";
|
||
|
exit;
|
||
|
|
||
|
|
||
|
|
||
|
|