From 07fe1d77c03173f0291da02360a806260542b559 Mon Sep 17 00:00:00 2001 From: Subhendu Ghosh Date: Sun, 9 Feb 2003 14:16:29 +0000 Subject: more contribs git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@300 f882894a-f735-0410-b71e-b25c423dba1c --- contrib/check_wins.pl | 248 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100755 contrib/check_wins.pl (limited to 'contrib/check_wins.pl') diff --git a/contrib/check_wins.pl b/contrib/check_wins.pl new file mode 100755 index 00000000..58a597aa --- /dev/null +++ b/contrib/check_wins.pl @@ -0,0 +1,248 @@ +#!/usr/bin/perl -w + +# $Id$ + +# $Log$ +# Revision 1.1 2003/02/09 14:16:28 sghosh +# more contribs +# + +use strict ; + +use Getopt::Long ; +use vars qw($opt_H $opt_D $opt_W $opt_T $debug @my_dcs); + +use lib '/usr/local/netsaint/libexec/' ; +use utils qw($TIMEOUT %ERRORS &print_revision &support &usage); + +my $PROGNAME = 'check_wins' ; + +use constant SAMBA_DEBUG_LVL => 2 ; +use constant MY_DCS => ('dc1','dc2') ; +# use constant MY_DCS => qw(ipa01 ipa02 ipa03) ; + +my $NMBLOOKUP_PATH = '/usr/bin/nmblookup' ; +my $NMBLOOKUP = sub { return `$NMBLOOKUP_PATH $_[2] -R -U $_[0] $_[1]` } ; +my $NMBLOOKUP_CMD = $NMBLOOKUP_PATH . ' -R -U' ; + +sub print_help (); +sub print_usage (); +sub help (); +sub version (); + +delete @ENV{'PATH', 'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; + +$SIG{"ALRM"} = sub { die "Alarm clock restart" } ; + +Getopt::Long::Configure('bundling', 'no_ignore_case'); +GetOptions + ("V|version" => \&version, + "h|help" => \&help, + "d|debug" => \$debug, + "C|controllers:s" => \@my_dcs, + "T|timeout:i" => \$opt_T, + "W|wins=s" => \$opt_W, + "D|domain=s" => \$opt_D); + + +($opt_D) || usage("MS Domain name not specified\n"); +my $domain = $1 if $opt_D =~ m#(\w+)# ; # NetBIOS names allow __any__ characters (more than \w) +($domain) || usage("Invalid MS D name: $opt_D\n"); + +($opt_W) || usage("WINS hostname or address not specified\n"); +my $wins = $1 if $opt_W =~ m#((?:^\w+$)|(?:\d+(?:\.\d+){3,3}$))# ; +($wins) || usage("Invalid WINS hostname or address: $opt_W\n"); + +usage("You must provide the names of your domain controllers by updating MY_DCS in the text or use -C dc_name1 -C dc_name2 ..\n") + unless (@my_dcs or MY_DCS) ; + +@my_dcs = MY_DCS unless defined $my_dcs[0] ; +$TIMEOUT = $opt_T if defined $opt_T ; + +my ($netbios_name, @dcs_of_domain, @dc_addresses) ; +my (@addr_dcs_of_domain, @found_dcs, %address2dc) ; +my (@dc_query) ; + +# tsitc> /usr/local/samba/bin/nmblookup -R -U wins ipa01 +# Sending queries to 10.0.100.29 +# 10.0.100.16 ipa01<00> + +eval { + alarm($TIMEOUT) ; + @dc_query = $debug ? map { $NMBLOOKUP->($wins, "$_#20", '-d ' . SAMBA_DEBUG_LVL) } @my_dcs : + map { ( $NMBLOOKUP->($wins, "$_#20", '') )[1] } @my_dcs ; + alarm(0) ; +} ; + +if ($@ and $@ =~ /Alarm clock restart/) { + print qq(Failed. Timeout while waiting for response from (one of) "$NMBLOOKUP_CMD $wins @my_dcs"\n) ; + exit $ERRORS{"CRITICAL"} ; +} + +if ($@ and $@ !~ /Alarm clock restart/) { + print qq(Failed. "$@" in response to "NMBLOOKUP_CMD $wins @my_dcs"\n) ; + exit $ERRORS{"UNKNOWN"} ; +} + +chomp @dc_query ; +if ( scalar grep(/name_query failed/, @dc_query) ) { + print qq(Failed. WINS "$wins" failed to resolve), scalar @my_dcs > 1 ? ' at least one of ' : ' ', qq("@my_dcs", the domain controller(s) of "$domain". Got "@dc_query"\n) ; + exit $ERRORS{"CRITICAL"} ; +} + +# the results of looking up the DCs (by their name) in the WINS + +# 10.0.100.16 ipa01<20> +# 10.0.100.1 ipa02<20> +# 10.0.100.104 ipa03<20> + +@dc_addresses = () ; +foreach (@dc_query) { + next unless /^(\S+)\s+(\S+?)<\S+?>$/ ; + $address2dc{$1} = $2 ; + push @dc_addresses, $1 ; +} + +$netbios_name = "$domain#1C" ; + +eval { + alarm($TIMEOUT) ; + @dcs_of_domain = $NMBLOOKUP->($wins, $netbios_name, defined $debug ? '-d ' . SAMBA_DEBUG_LVL : '') ; + alarm(0) ; + +} ; + +if ($@ and $@ =~ /Alarm clock restart/) { + print qq(Failed. Timeout while waiting for response from "$NMBLOOKUP_CMD $wins $netbios_name"\n) ; + exit $ERRORS{"CRITICAL"} ; +} + +if ($@ and $@ !~ /Alarm clock restart/) { + print qq(Failed. "$@" in response to "$NMBLOOKUP_CMD $wins $netbios_name"\n) ; + exit $ERRORS{"UNKNOWN"} ; +} + +shift @dcs_of_domain ; +chomp @dcs_of_domain ; +@addr_dcs_of_domain = map /^(\S+)/, @dcs_of_domain ; + +# tsitc> /usr/local/samba/bin/nmblookup -R -U wins ipaustralia#1c +# Sending queries to 10.0.100.29 +# 10.0.100.114 ipaustralia<1c> +# 168.168.102.129 ipaustralia<1c> +# 192.168.101.221 ipaustralia<1c> +# 10.0.100.61 ipaustralia<1c> +# 192.168.108.129 ipaustralia<1c> +# 192.168.102.128 ipaustralia<1c> +# 10.0.4.126 ipaustralia<1c> +# 192.168.106.214 ipaustralia<1c> +# 10.0.3.165 ipaustralia<1c> +# 192.168.105.214 ipaustralia<1c> +# 10.0.6.145 ipaustralia<1c> +# 192.168.104.128 ipaustralia<1c> +# 10.0.4.59 ipaustralia<1c> +# 10.9.99.99 ipaustralia<1c> +# 10.99.99.99 ipaustralia<1c> +# 10.9.99.254 ipaustralia<1c> +# 10.0.3.15 ipaustralia<1c> +# 192.168.102.129 ipaustralia<1c> +# 192.168.103.129 ipaustralia<1c> +# 192.168.105.129 ipaustralia<1c> +# 192.168.106.129 ipaustralia<1c> +# 192.168.101.129 ipaustralia<1c> +# 192.168.104.129 ipaustralia<1c> +# 10.0.3.123 ipaustralia<1c> +# 10.0.100.67 ipaustralia<1c> +# tsitc> + +my %x ; +@found_dcs = grep { ! $x{$_}++ } @address2dc{ grep exists $address2dc{$_}, @addr_dcs_of_domain} ; +# @found_dcs = grep { defined $_} @address2dc{ grep exists $address2dc{$_}, @addr_dcs_of_domain} ; + # Gotcha. + # 'exists' is necessary to prevent autovivificatiton + # of keys in %address2dc + +if ( &set_eq( \@found_dcs, [ values %address2dc ] ) ) { + print $debug ? qq(Ok. WINS named "$wins" resolved addresses of "@my_dcs" as "@dc_query" and controllers of domain "$domain" as "@dcs_of_domain"\n) : + qq(Ok. Found controllers named "@my_dcs" in response to "$domain#1C" name query from WINS named "$wins".\n) ; + exit $ERRORS{"OK"} ; +} elsif ( scalar @found_dcs == 0 ) { + print qq(Failed. Found __no__ controllers named "@my_dcs" in response to "$domain#1C" query from WINS named "$wins". Got "@dcs_of_domain"\n) ; + exit $ERRORS{"CRITICAL"} ; +} elsif ( scalar @found_dcs < scalar keys %address2dc ) { + print qq(Warning. Not all domain controllers found in response to "$domain#1C" query from WINS named "$wins". Expected "@my_dcs", got "@found_dcs"\n) ; + exit $ERRORS{"WARNING"} ; +} + +sub set_eq { + + return 0 unless scalar @{$_[0]} == scalar @{$_[1]} ; + foreach my $a ( @{$_[0]} ) { + return 0 unless scalar grep { $a eq $_ } @{$_[1]} ; + } + return 1 ; + +} + + +sub print_usage () { + print "Usage: $PROGNAME -W -D \n"; +} + +sub print_help () { + print_revision($PROGNAME,'$Revision$ '); + print "Copyright (c) 2001 Karl DeBisschop/S Hopcroft + +Perl Check WINS plugin for NetSaint. + +Returns OK if the addresses of domain controllers are found in the list of domain controllers returned in the WINS response to a 'domain controllers query' + +Why would you want to do this ? + +MS File server clients insist on connecting to file servers using NetBIOS names. +If they __don't__ resolve NetBIOS names with a WINS (NBNS) then they'll either fail to logon and connect to shares or they will +broadcast requsts for names. +Both problems are eliminated by a healthy WINS. +Also, you may have a MS domain spanning a number of WAN connected sites, with domain controllers far away from powerful local +domain controllers. +In this case, you want your local clients to have their logon requests validated by the local controllers. + +The plugin works by + asking the WINS to resolve the addresses of the domain controllers (supplied by -C or from the constant MY_DCS) + asking the WINS to return the list of addresses of the domain controllers able to validate requests for the domain + whose name is given by -D + returning Ok if all controller addresses are in that list (of addresses of domain controllers) or + returning WARNING if not all the controller addresses are in the list or + returning CRITICAL if there is no reply from the WINS or the list contains none of the contoller addresses + +"; + print_usage(); + print ' +-W, --wins=STRING + Hostname or address of the WINS (Either Samba/nmbd or MS product) +-D, --domain=STRING + MS Domain name to find the Domain controllers of. +-C, --controllers:STRING + Optional __name(s)__ of domain controller that __must__ be found in the response to a domain controller name query. + If not defined, then use the constant value MY_DCS. You must use either -C or make sure that MY_DCS contains the names + of __your__ domain controllers. +-T, --timeout:INTEGER +-d, --debug + Debugging output. +-h, --help + This stuff. + +'; + support(); +} + +sub version () { + print_revision($PROGNAME,'$Revision$ '); + exit $ERRORS{'OK'}; +} + +sub help () { + print_help(); + exit $ERRORS{'OK'}; +} + -- cgit v1.2.3