summaryrefslogtreecommitdiffstats
path: root/contrib/check_wins.pl
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/check_wins.pl')
-rwxr-xr-xcontrib/check_wins.pl248
1 files changed, 248 insertions, 0 deletions
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 @@
1#!/usr/bin/perl -w
2
3# $Id$
4
5# $Log$
6# Revision 1.1 2003/02/09 14:16:28 sghosh
7# more contribs
8#
9
10use strict ;
11
12use Getopt::Long ;
13use vars qw($opt_H $opt_D $opt_W $opt_T $debug @my_dcs);
14
15use lib '/usr/local/netsaint/libexec/' ;
16use utils qw($TIMEOUT %ERRORS &print_revision &support &usage);
17
18my $PROGNAME = 'check_wins' ;
19
20use constant SAMBA_DEBUG_LVL => 2 ;
21use constant MY_DCS => ('dc1','dc2') ;
22# use constant MY_DCS => qw(ipa01 ipa02 ipa03) ;
23
24my $NMBLOOKUP_PATH = '/usr/bin/nmblookup' ;
25my $NMBLOOKUP = sub { return `$NMBLOOKUP_PATH $_[2] -R -U $_[0] $_[1]` } ;
26my $NMBLOOKUP_CMD = $NMBLOOKUP_PATH . ' -R -U' ;
27
28sub print_help ();
29sub print_usage ();
30sub help ();
31sub version ();
32
33delete @ENV{'PATH', 'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
34
35$SIG{"ALRM"} = sub { die "Alarm clock restart" } ;
36
37Getopt::Long::Configure('bundling', 'no_ignore_case');
38GetOptions
39 ("V|version" => \&version,
40 "h|help" => \&help,
41 "d|debug" => \$debug,
42 "C|controllers:s" => \@my_dcs,
43 "T|timeout:i" => \$opt_T,
44 "W|wins=s" => \$opt_W,
45 "D|domain=s" => \$opt_D);
46
47
48($opt_D) || usage("MS Domain name not specified\n");
49my $domain = $1 if $opt_D =~ m#(\w+)# ; # NetBIOS names allow __any__ characters (more than \w)
50($domain) || usage("Invalid MS D name: $opt_D\n");
51
52($opt_W) || usage("WINS hostname or address not specified\n");
53my $wins = $1 if $opt_W =~ m#((?:^\w+$)|(?:\d+(?:\.\d+){3,3}$))# ;
54($wins) || usage("Invalid WINS hostname or address: $opt_W\n");
55
56usage("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")
57 unless (@my_dcs or MY_DCS) ;
58
59@my_dcs = MY_DCS unless defined $my_dcs[0] ;
60$TIMEOUT = $opt_T if defined $opt_T ;
61
62my ($netbios_name, @dcs_of_domain, @dc_addresses) ;
63my (@addr_dcs_of_domain, @found_dcs, %address2dc) ;
64my (@dc_query) ;
65
66# tsitc> /usr/local/samba/bin/nmblookup -R -U wins ipa01
67# Sending queries to 10.0.100.29
68# 10.0.100.16 ipa01<00>
69
70eval {
71 alarm($TIMEOUT) ;
72 @dc_query = $debug ? map { $NMBLOOKUP->($wins, "$_#20", '-d ' . SAMBA_DEBUG_LVL) } @my_dcs :
73 map { ( $NMBLOOKUP->($wins, "$_#20", '') )[1] } @my_dcs ;
74 alarm(0) ;
75} ;
76
77if ($@ and $@ =~ /Alarm clock restart/) {
78 print qq(Failed. Timeout while waiting for response from (one of) "$NMBLOOKUP_CMD $wins @my_dcs"\n) ;
79 exit $ERRORS{"CRITICAL"} ;
80}
81
82if ($@ and $@ !~ /Alarm clock restart/) {
83 print qq(Failed. "$@" in response to "NMBLOOKUP_CMD $wins @my_dcs"\n) ;
84 exit $ERRORS{"UNKNOWN"} ;
85}
86
87chomp @dc_query ;
88if ( scalar grep(/name_query failed/, @dc_query) ) {
89 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) ;
90 exit $ERRORS{"CRITICAL"} ;
91}
92
93# the results of looking up the DCs (by their name) in the WINS
94
95# 10.0.100.16 ipa01<20>
96# 10.0.100.1 ipa02<20>
97# 10.0.100.104 ipa03<20>
98
99@dc_addresses = () ;
100foreach (@dc_query) {
101 next unless /^(\S+)\s+(\S+?)<\S+?>$/ ;
102 $address2dc{$1} = $2 ;
103 push @dc_addresses, $1 ;
104}
105
106$netbios_name = "$domain#1C" ;
107
108eval {
109 alarm($TIMEOUT) ;
110 @dcs_of_domain = $NMBLOOKUP->($wins, $netbios_name, defined $debug ? '-d ' . SAMBA_DEBUG_LVL : '') ;
111 alarm(0) ;
112
113} ;
114
115if ($@ and $@ =~ /Alarm clock restart/) {
116 print qq(Failed. Timeout while waiting for response from "$NMBLOOKUP_CMD $wins $netbios_name"\n) ;
117 exit $ERRORS{"CRITICAL"} ;
118}
119
120if ($@ and $@ !~ /Alarm clock restart/) {
121 print qq(Failed. "$@" in response to "$NMBLOOKUP_CMD $wins $netbios_name"\n) ;
122 exit $ERRORS{"UNKNOWN"} ;
123}
124
125shift @dcs_of_domain ;
126chomp @dcs_of_domain ;
127@addr_dcs_of_domain = map /^(\S+)/, @dcs_of_domain ;
128
129# tsitc> /usr/local/samba/bin/nmblookup -R -U wins ipaustralia#1c
130# Sending queries to 10.0.100.29
131# 10.0.100.114 ipaustralia<1c>
132# 168.168.102.129 ipaustralia<1c>
133# 192.168.101.221 ipaustralia<1c>
134# 10.0.100.61 ipaustralia<1c>
135# 192.168.108.129 ipaustralia<1c>
136# 192.168.102.128 ipaustralia<1c>
137# 10.0.4.126 ipaustralia<1c>
138# 192.168.106.214 ipaustralia<1c>
139# 10.0.3.165 ipaustralia<1c>
140# 192.168.105.214 ipaustralia<1c>
141# 10.0.6.145 ipaustralia<1c>
142# 192.168.104.128 ipaustralia<1c>
143# 10.0.4.59 ipaustralia<1c>
144# 10.9.99.99 ipaustralia<1c>
145# 10.99.99.99 ipaustralia<1c>
146# 10.9.99.254 ipaustralia<1c>
147# 10.0.3.15 ipaustralia<1c>
148# 192.168.102.129 ipaustralia<1c>
149# 192.168.103.129 ipaustralia<1c>
150# 192.168.105.129 ipaustralia<1c>
151# 192.168.106.129 ipaustralia<1c>
152# 192.168.101.129 ipaustralia<1c>
153# 192.168.104.129 ipaustralia<1c>
154# 10.0.3.123 ipaustralia<1c>
155# 10.0.100.67 ipaustralia<1c>
156# tsitc>
157
158my %x ;
159@found_dcs = grep { ! $x{$_}++ } @address2dc{ grep exists $address2dc{$_}, @addr_dcs_of_domain} ;
160# @found_dcs = grep { defined $_} @address2dc{ grep exists $address2dc{$_}, @addr_dcs_of_domain} ;
161 # Gotcha.
162 # 'exists' is necessary to prevent autovivificatiton
163 # of keys in %address2dc
164
165if ( &set_eq( \@found_dcs, [ values %address2dc ] ) ) {
166 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) :
167 qq(Ok. Found controllers named "@my_dcs" in response to "$domain#1C" name query from WINS named "$wins".\n) ;
168 exit $ERRORS{"OK"} ;
169} elsif ( scalar @found_dcs == 0 ) {
170 print qq(Failed. Found __no__ controllers named "@my_dcs" in response to "$domain#1C" query from WINS named "$wins". Got "@dcs_of_domain"\n) ;
171 exit $ERRORS{"CRITICAL"} ;
172} elsif ( scalar @found_dcs < scalar keys %address2dc ) {
173 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) ;
174 exit $ERRORS{"WARNING"} ;
175}
176
177sub set_eq {
178
179 return 0 unless scalar @{$_[0]} == scalar @{$_[1]} ;
180 foreach my $a ( @{$_[0]} ) {
181 return 0 unless scalar grep { $a eq $_ } @{$_[1]} ;
182 }
183 return 1 ;
184
185}
186
187
188sub print_usage () {
189 print "Usage: $PROGNAME -W <wins> -D <domain>\n";
190}
191
192sub print_help () {
193 print_revision($PROGNAME,'$Revision$ ');
194 print "Copyright (c) 2001 Karl DeBisschop/S Hopcroft
195
196Perl Check WINS plugin for NetSaint.
197
198Returns 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'
199
200Why would you want to do this ?
201
202MS File server clients insist on connecting to file servers using NetBIOS names.
203If they __don't__ resolve NetBIOS names with a WINS (NBNS) then they'll either fail to logon and connect to shares or they will
204broadcast requsts for names.
205Both problems are eliminated by a healthy WINS.
206Also, you may have a MS domain spanning a number of WAN connected sites, with domain controllers far away from powerful local
207domain controllers.
208In this case, you want your local clients to have their logon requests validated by the local controllers.
209
210The plugin works by
211 asking the WINS to resolve the addresses of the domain controllers (supplied by -C or from the constant MY_DCS)
212 asking the WINS to return the list of addresses of the domain controllers able to validate requests for the domain
213 whose name is given by -D
214 returning Ok if all controller addresses are in that list (of addresses of domain controllers) or
215 returning WARNING if not all the controller addresses are in the list or
216 returning CRITICAL if there is no reply from the WINS or the list contains none of the contoller addresses
217
218";
219 print_usage();
220 print '
221-W, --wins=STRING
222 Hostname or address of the WINS (Either Samba/nmbd or MS product)
223-D, --domain=STRING
224 MS Domain name to find the Domain controllers of.
225-C, --controllers:STRING
226 Optional __name(s)__ of domain controller that __must__ be found in the response to a domain controller name query.
227 If not defined, then use the constant value MY_DCS. You must use either -C or make sure that MY_DCS contains the names
228 of __your__ domain controllers.
229-T, --timeout:INTEGER
230-d, --debug
231 Debugging output.
232-h, --help
233 This stuff.
234
235';
236 support();
237}
238
239sub version () {
240 print_revision($PROGNAME,'$Revision$ ');
241 exit $ERRORS{'OK'};
242}
243
244sub help () {
245 print_help();
246 exit $ERRORS{'OK'};
247}
248