##################### # # check_ad.pl - Nagios NRPE plugin to test Active Directory functionality # # This plugin requires tools netdiag and dcdiag from Support Tools # # This program is distributed under the Artistic License. # (http://www.opensource.org/licenses/artistic-license.php) # Copyright 2007-2009, Tevfik Karagulle, ITeF!x Consulting (http://itefix.no) use strict; use warnings; use Getopt::Long; use Win32; our $VERSION = "1.4"; our $OK = 0; our $WARNING = 1; our $CRITICAL = 2; our $UNKNOWN = 3; our %status_text = ( $OK => "OK", $WARNING => "WARNING", $CRITICAL => "CRITICAL", $UNKNOWN => "UNKNOWN" ); our $is2000 = (Win32::GetOSName() eq 'Win2000'); our $member = 0; our $dc = 0; our $help = 0; our $eventlog = 1; # take kccevent/frsevent into test set our $kerbtest = 1; # take kerberos into test set GetOptions ( "member" => \$member, "dc" => \$dc, "eventlog!" => \$eventlog, "kerberos!" => \$kerbtest, "help" => \$help ) || PrintUsage(); # Form netdiag/dcdiag command arguments our $netdiagcmd = "netdiag /test:dns /test:dsgetdc /test:ldap"; our $dcdiagcmd = "dcdiag /test:services /test:replications /test:advertising /test:fsmocheck /test:ridmanager /test:machineaccount"; # add post-2000 spesific dcdiag tests $dcdiagcmd .= (not $is2000) ? " /test:frssysvol" : ""; # add eventlog tests if requested $dcdiagcmd .= ($eventlog) ? ($is2000 ? " /test:kccevent" : " /test:frsevent /test:kccevent") : ""; # add kerberos test if requested $netdiagcmd .= ($kerbtest) ? " /test:kerberos" : ""; $member && MemberTests(); $dc && DcTests(); $help && PrintUsage(); #### SUBROUTINES #### #### MemberTests #### sub MemberTests { open NETDIAG, "$netdiagcmd |" or ExitProgram ($UNKNOWN, "Could not open command pipe!"); my ($member, $netbt, $dns, $dc, $kerberos, $ldap) = (0, 0, 0, 0, 0); my $warning = ""; my $fatal = ""; my $global_result = 0; while () { chomp; $_ = lc; $global_result = 1 if /global results:/; # Only interested in warning and/or fatal messages for global results. $member = 1 if /domain membership test . . . . . . : passed/; $netbt = 1 if /netbt transports test. . . . . . . : passed/; $dns = 1 if /dns test . . . . . . . . . . . . . : passed/; $dc = 1 if /dc discovery test. . . . . . . . . : passed/; $ldap = 1 if /ldap test. . . . . . . . . . . . . : passed/; $kerberos = 1 if /kerberos test. . . . . . . . . . . . . : passed/ and $kerbtest; $warning .= "$_ " if /warning/ and $global_result; $fatal .= "$_ " if /fatal/ and $global_result; } my $status_ok = $member && $netbt && $dns && $dc && $ldap; $status_ok &&= $kerberos if $kerbtest; my $status_text = "Domain membership OK, NetBT transport OK, DNS OK, DC Discovery OK, LDAP OK"; $status_text .= ", Kerberos OK" if $kerbtest; ExitProgram ($CRITICAL, $fatal) if $fatal ne ""; ExitProgram ($WARNING, $warning) if $warning ne ""; ExitProgram ($OK, $status_text) if ($member && $netbt && $dns && $dc && $ldap); ExitProgram ($UNKNOWN, "No information is available."); } ##### DcTests ##### sub DcTests { open DCDIAG, "$dcdiagcmd |" or ExitProgram ($UNKNOWN, "Could not open command pipe!"); my ($connectivity, $services, $replications, $advertising, $fsmo, $rid, $machine, $frssysvol, $frsevent, $kccevent) = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0); my $warning = ""; my $fatal = ""; while () { chomp; $_ = lc; $connectivity = 1 if /passed test connectivity/; $services = 1 if /passed test services/; $replications = 1 if /passed test replications/; $advertising = 1 if /passed test advertising/; $fsmo = 1 if /passed test fsmocheck/; $rid = 1 if /passed test ridmanager/; $machine = 1 if /passed test machineaccount/; $frssysvol = 1 if /passed test frssysvol/ and not $is2000; $frsevent = 1 if /passed test frsevent/ and not $is2000; $kccevent = 1 if /passed test kccevent/; $warning .= "$_ " if /warning/; $fatal .= "$_ " if /failed/; } my $status_ok = $connectivity && $services && $replications && $advertising && $fsmo && $rid && $machine; $status_ok &&= $frssysvol if not $is2000; $status_ok &&= $frsevent if not $is2000 and $eventlog; $status_ok &&= $kccevent if $eventlog; my $status_text = "Connectivity OK, Services OK, Replications OK, Advertising OK, Fsmo OK, Rid Manager OK, Machine account OK"; $status_text .= ", FRS Sysvol OK" if not $is2000; $status_text .= ", FRS Event OK" if not $is2000 and $eventlog; $status_text .= ", KCC Event OK" if $eventlog; ExitProgram ($CRITICAL, $fatal) if $fatal ne ""; ExitProgram ($WARNING, $warning) if $warning ne ""; ExitProgram ($OK, $status_text) if $status_ok; ExitProgram ($UNKNOWN, "No information is available."); } ##### PrintUsage ##### sub PrintUsage { print " check_ad - Nagios NRPE Plugin for Active Directory Health Check Version 1.4, Copyright 2007-2009, http://itefix.no Usage: check_ad [--dc] [--member] [--noeventlog] [--nokerberos][--help] Options: --dc Checks domain controller functionality by using dcdiag tool from Windows Support Tools. Following dcdiag tests are performed : services, replications, advertising, fsmocheck, ridmanager, machineaccount, kccevent, frssysvol (post-Windows 2000 only), frsevent (post-Windows 2000 only), --member Checks domain member functionality by using netdiag tool from Windows Support Tools. Following netdiag tests are performed : member, netbt, dns, dsgetdc, ldap, kerberos --noeventlog Don't run the dc tests kccevent and frsevent, since their 24-hour scope may not be too relevant for Nagios. --nokerberos Don't run the member test kerberos due to netdiag bug (See Microsoft KB870692) --help Produces help message. "; } ##### ExitProgram ##### sub ExitProgram { my ($exitcode, $message) = @_; my $lcomp = "AD"; print "$lcomp $status_text{$exitcode} - $message"; exit ($exitcode); } __END__ =head1 NAME check_ad - Nagios NRPE plugin for Active Directory health check =head1 SYNOPSIS B [B<--dc>] [B<--member>] [B<--noeventlog>] [B<--nokerberos>][B<--help>] =head1 DESCRIPTION B works as a Nagios NRPE plugin for Active Directory health check. =head1 OPTIONS =over 4 =item B<--dc> Checks domain controller functionality by using I tool from Windows Support Tools. Following dcdiag tests are performed : services, replications, advertising, fsmocheck, ridmanager, machineaccount, kccevent, frssysvol (post-Windows 2000 only), frsevent (post-Windows 2000 only), =item B<--member> Checks domain member functionality by using I tool from Windows Support Tools. Following netdiag tests are performed : member, netbt, dns, dsgetdc, ldap, kerberos =item B<--noeventlog> Don't run the dc tests kccevent and frsevent, since their 24-hour scope may not be too relevant for Nagios. =item B<--nokerberos> Don't run the member test kerberos due to netdiag bug (See Microsoft KB870692) =item B<--help> Produces help message. =back =head1 EXIT VALUES 0 OK 1 WARNING 2 CRITICAL 3 UNKNOWN =head1 AUTHOR Tevfik Karagulle L =head1 SEE ALSO =over 4 =item Nagios web site L =item Nagios NRPE documentation L =item DCDIAG documentation L =item NETDIAG documentation L =back =head1 COPYRIGHT This program is distributed under the Artistic License. L =head1 VERSION Version 1.4, January 2009 =head1 CHANGELOG =over 4 =item changes from 1.3 - Windows 2008 support (checks are done in lowercase only) - Dropped member test 'trust' as it requires domain admin privileges thus introducing a security weakness. - Introducing option 'nokerberos' due to netdiag bug (see Microsoft KB870692) =item changes from 1.2 - Add command line option 'noeventlog'. =item changes from 1.1 - Support for Windows 2000 domains - Use CRITICAL instead of ERROR =item changes from 1.0 - remove sysevent test as it can be many other event producers than active directory. =back =cut