summaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authorSubhendu Ghosh <sghosh@users.sourceforge.net>2003-02-09 14:16:29 +0000
committerSubhendu Ghosh <sghosh@users.sourceforge.net>2003-02-09 14:16:29 +0000
commit07fe1d77c03173f0291da02360a806260542b559 (patch)
treefdd11279ed05b38759afef2262f92b51cc091ba3 /contrib
parentd4f25e47a0b89bdbcee8172fd2c0be8bf3b7f112 (diff)
downloadmonitoring-plugins-07fe1d77c03173f0291da02360a806260542b559.tar.gz
more contribs
git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@300 f882894a-f735-0410-b71e-b25c423dba1c
Diffstat (limited to 'contrib')
-rw-r--r--contrib/check_remote_nagios_status.pl666
-rwxr-xr-xcontrib/check_wins.pl248
-rw-r--r--contrib/sched_downtime.pl47
3 files changed, 961 insertions, 0 deletions
diff --git a/contrib/check_remote_nagios_status.pl b/contrib/check_remote_nagios_status.pl
new file mode 100644
index 00000000..dc99705e
--- /dev/null
+++ b/contrib/check_remote_nagios_status.pl
@@ -0,0 +1,666 @@
1#!/usr/bin/perl -w
2
3# check_status.pl Nagios Plugin - Version 1.3
4# Last Updated: 1/9/2003
5#
6# Report any bugs/questions to Russell Scibetti at russell@quadrix.com
7#
8# check_status Change Log:
9#
10# To do for 1.4
11# - Better help and documentation (separate doc?)
12# - Take argument (patterns to match) from a separate spec file
13#
14# New Addition to 1.3
15# - Added ChangeLog information and updated --help output
16# - hostdown (hd) argument for how a service check should respond
17# when its host is Down/Unreachable
18# (--hostdown="ok|warning|critical|unknown")
19# - Changed name from check_state to check_status
20# - Set hostdown to default to OK when the argument isn't specified
21# - Number of Hosts checked is now output in OK result
22#
23# Version 1.2 additions:
24#
25# - Added ability to handle ack'd and downtimed services differently
26# depending on argument provided
27# (--ack="ok|warning|critical|unknown|down|unreachable"
28# --dt="ok|warning|critical|unknown|down|unreachable")
29#
30# Version 1.1 additions:
31#
32# - Added --host=<regex>, --servhost=<regex> to allow for specific field
33# matching (host for matching hostname in host checks, servhost for
34# matching the hostname in service checks, service for matching the
35# service name in service checks)
36# - Output the number of OK services for an OK output
37#
38# Version 1.0 features:
39#
40# - Freshness check of status.log (timestamp)
41# - Match service or host checks
42# - Can ignore acknowledged or downtimes services/hosts (--ack, --dt)
43# - Can output different levels of detail dependent on # of problems
44# - Can check for number of critical, warning, or unknowns
45#
46#############################################################
47
48use Getopt::Long;
49use File::stat;
50
51Getopt::Long::Configure('bundling');
52
53GetOptions
54 ("V" => \$version, "version" => \$version,
55 "h" => \$help, "help" => \$help,
56 "v" => \$verbose, "verbose" => \$verbose,
57 "w=s" => \$warning, "warning=s" => \$warning,
58 "c=s" => \$critical, "critical=s" => \$critical,
59 "u=s" => \$unknown, "unknown=s" => \$unknown,
60 "p=s" => \$pattern, "pattern=s" => \$pattern,
61 "S:s" => \$service, "service:s" => \$service,
62 "s=s" => \$status, "status=s" => \$status,
63 "d=s" => \$dir, "dir=s" => \$dir,
64 "D=s" => \$details, "details=s" => \$details,
65 "H:s" => \$host, "host:s" => \$host,
66 "f=s" => \$freshness, "freshness=s" => \$freshness,
67 "servhost=s" => \$servhost,
68 "a:s" => \$ack, "ack:s" => \$ack,
69 "dt:s"=> \$dt, "downtime:s" => \$dt,
70 "hd:s"=> \$hdown, "hostdown:s" => \$hdown,
71 "ok" => \$ok);
72
73#Constants:
74my $OK = 0;
75my $WARNING = 1;
76my $CRITICAL = 2;
77my $UNKNOWN = 3;
78
79my $crit="CRITICAL";
80my $warn="WARNING";
81my $unk="UNKNOWN";
82my $down="DOWN";
83my $unreach="UNREACHABLE";
84
85# Print out Help information
86if ($help) {
87 printVersion();
88 printHelp();
89 exitcheck($UNKNOWN);
90}
91
92# Print out version information
93if ($version) {
94 printVersion();
95 exitcheck($UNKNOWN);
96}
97
98# Check for status log or directory argument or print usage
99if (!$status) {
100 if (!$dir) {
101 print "Usage: $0 -s <status file> | -d <Nagios log dir>\n";
102 print "Use the --help option for full list of arguments\n";
103 exitcheck($UNKNOWN);
104 }
105 elsif ($dir =~ m#[^/]/$#) {
106 $status = $dir . "status.log";
107 }
108 else {
109 $status = $dir . "/status.log";
110 }
111}
112
113if (defined $host) {
114 if (!$host) {
115 $host="[^\\s]*";
116 }
117}
118
119if (!$host && !$servhost) {
120 $servhost="[^\\s]*";
121}
122
123if (!$host && !$service) {
124 $service="[^\\s]*";
125}
126
127if (defined $ack) {
128 if (!$ack) {
129 $ack="ok";
130 }
131 elsif (!($ack =~ "ok|critical|warning|unknown|down|unreachable")) {
132 print "Invalid value for ack\n";
133 exitcheck($UNKNOWN);
134 }
135}
136
137if (defined $dt) {
138 if (!$dt) {
139 $dt="ok";
140 }
141 elsif (!($dt =~ "ok|critical|warning|unknown|down|unreachable")) {
142 print "Invalid value for dt\n";
143 exitcheck($UNKNOWN);
144 }
145}
146
147if (defined $hdown) {
148 if (!$hdown) {
149 $hdown="ok";
150 }
151 elsif (!($hdown =~ "ok|critical|warning|unknown|down|unreachable")) {
152 print "Invalid value for hostdown\n";
153 exitcheck($UNKNOWN);
154 }
155}
156
157my $much_details = 0;
158
159my $ServiceNotOK = "CRITICAL|WARNING|UNKNOWN";
160my $HostNotOK = "DOWN|UNREACHABLE";
161
162my %numprob = ("WARNING",0,"CRITICAL",0,"UNKNOWN",0,"DOWN",0,"UNREACHABLE",0);
163
164my $CritOnly = 0;
165my $WarnOnly = 0;
166my $UnkOnly = 0;
167
168my @wlev;
169my @clev;
170my @ulev;
171my %warnlevel = ("WARNING",0,"CRITICAL",0,"UNKNOWN",0);
172my %critlevel = ("WARNING",0,"CRITICAL",0,"UNKNOWN",0);
173my %unklevel = ("WARNING",0,"CRITICAL",0,"UNKNOWN",0);
174my %hostlevel = ("DOWN",0,"UNREACHABLE",0);
175
176# Store Hosts in downtime
177my @hostdowntime;
178my $numdowntime = 0;
179
180# Store Hosts in a Down/Unreachable state
181my @hostdown;
182my $numdown = 0;
183
184# Hash for storing state-change to OK times for hosts:
185my %hostoktimes;
186
187# Number of matches in parsing
188my $nummatch = 0;
189
190if ($warning) {
191 if ($warning =~ /,/) {
192 @wlev = split /,/,$warning;
193 $warnlevel{"WARNING"} = $wlev[0];
194 $warnlevel{"CRITICAL"} = $wlev[1];
195 if ($wlev[2] ) {
196 $warnlevel{"UNKNOWN"} = $wlev[2];
197 }
198 }
199 else {
200 $WarnOnly = $warning;
201 }
202}
203else {
204 $WarnOnly = 1;
205}
206
207if ($critical) {
208 if ($critical =~ /,/) {
209 @clev = split /,/,$critical;
210 $critlevel{"WARNING"} = $clev[0];
211 $critlevel{"CRITICAL"} = $clev[1];
212 if ($clev[2] ) {
213 $critlevel{"UNKNOWN"} = $clev[2];
214 }
215 }
216 else {
217 $CritOnly = $critical;
218 }
219}
220else {
221 $CritOnly = 1;
222}
223
224if ($unknown) {
225 if ($unknown =~ /,/) {
226 @ulev = split /,/,$unknown;
227 $unklevel{"WARNING"} = $ulev[0];
228 $unklevel{"CRITICAL"} = $ulev[1];
229 if ($ulev[2] ) {
230 $unklevel{"UNKNOWN"} = $ulev[2];
231 }
232 }
233 else {
234 $UnkOnly = $unknown;
235 }
236}
237else {
238 $UnkOnly = 1;
239}
240
241
242if (!$freshness) {
243 $freshness = 30 * 60;
244}
245else {
246 $freshness = $freshness * 60;
247}
248
249my %ct = ("CRITICAL",0,"WARNING",0,"UNKNOWN",0,"DOWN",0,"UNREACHABLE",0);
250my %much_ct = ("CRITICAL",0,"WARNING",0,"UNKNOWN",0,"DOWN",0,"UNREACHABLE",0);
251
252my %output = ("CRITICAL","","WARNING","","UNKNOWN","","DOWN","","UNREACHABLE","");
253my %much_output = ("CRITICAL","","WARNING","","UNKNOWN","","DOWN","","UNREACHABLE","");
254
255if ($details) {
256 if ($details =~ /,/) {
257 my @tempv = split /,/,$details;
258 $much_details = $tempv[0];
259 $details = $tempv[1];
260 }
261}
262
263open("sta","$status") || die "Cannot open status file $status!";
264
265$curr_time = time;
266$file_time = stat($status)->mtime;
267
268if ($curr_time - $file_time > $freshness) {
269 printf "State CRITICAL - Status file is stale!!!\n";
270 exitcheck($CRITICAL);
271}
272
273while(<sta>) {
274 chomp;
275 if (/^[^\s]+[\s]+HOST;/) {
276 @hdata = split /;/,$_;
277
278# If you care about matching hosts (not services):
279 if ($host && $hdata[1] =~ /$host/) {
280 $nummatch++;
281 if ( $hdata[2] =~ /$HostNotOK/ ) {
282 addproblem($_,$hdata[2]);
283 }
284 }
285
286# If you are matching services, gather host information:
287 else {
288 if ( $hdata[2] =~ /$HostNotOK/ ) {
289 $hostdown[$numdown] = $hdata[1];
290 $numdown++;
291 }
292 else {
293 $hostoktimes{$hdata[1]} = $hdata[4];
294 }
295 if ( $hdata[17] ne "0" ) {
296 $hostdowntime[$numdowntime] = $hdata[1];
297 $numdowntime++;
298 }
299 }
300 }
301 elsif (!$host && /^[^\s]+[\s]+SERVICE;/) {
302 @servdata = split /;/,$_;
303 if ( ( $pattern && ($_ =~ /$pattern/)) ||
304 (($servdata[1] =~ /$servhost/) && ($servdata[2] =~ /$service/)) ){
305 $nummatch++;
306 if (($servdata[5] eq "HARD") && ($servdata[3] =~ /$ServiceNotOK/)) {
307 addproblem($_,$servdata[3]);
308 }
309 }
310 }
311}
312
313close("sta");
314
315if ($nummatch==0) {
316 print "Nothing Matches your criteria!\n";
317 exitcheck($UNKNOWN);
318}
319
320# Count the number of problems (for reference):
321if ($host) {
322 $total = $numprob{"DOWN"} + $numprob{"UNREACHABLE"};
323}
324else {
325 $total = $numprob{"WARNING"} + $numprob{"CRITICAL"} + $numprob{"UNKNOWN"};
326}
327
328my $numok = $nummatch - $total;
329
330# If this is a host state check:
331if ($host) {
332 if ($numprob{"DOWN"}>0 || $numprob{"UNREACHABLE"}>0 ) {
333 if ($details && ($total <= $details)) {
334 print "State CRITICAL - $total Host Problems: $output{$down} $output{$unreach}\n";
335 exitcheck($CRITICAL);
336 }
337 else {
338 print "State CRITICAL - $numprob{$down} Hosts Down, $numprob{$unreach} Hosts Unreachable\n";
339 exitcheck($CRITICAL);
340 }
341 }
342 else {
343 print "State OK - $numok Hosts Up, $total Problems\n";
344 exitcheck($OK);
345 }
346}
347
348#If you only defined a Critical level in terms of # of criticals...
349elsif ($CritOnly && ($numprob{"CRITICAL"} >= $CritOnly)) {
350 countAndPrint($crit,$numprob{$crit},0);
351 exitcheck($CRITICAL);
352}
353
354#Critical in terms on # criticals and # warnings...
355elsif (!$CritOnly && ($numprob{"WARNING"} >= $critlevel{"WARNING"} ||
356 $numprob{"CRITICAL"} >= $critlevel{"CRITICAL"} ||
357 $numprob{"UNKNOWN"} >= $critlevel{"UNKNOWN"} )) {
358 countAndPrint($crit,$total,1);
359 exitcheck($CRITICAL);
360}
361
362#Warning in terms of # warnings only...
363elsif ($WarnOnly && ($numprob{"WARNING"} >= $WarnOnly)) {
364 countAndPrint($warn,$numprob{$warn},0);
365 exitcheck($WARNING);
366}
367
368#Warning in terms of # warnings and # criticals...
369elsif (!$WarnOnly && ($numprob{"WARNING"} >= $warnlevel{"WARNING"} ||
370 $numprob{"CRITICAL"} >= $warnlevel{"CRITICAL"} ||
371 $numprob{"UNKNOWN"} >= $warnlevel{"UNKNOWN"})) {
372 countAndPrint($warn,$total,1);
373 exitcheck($WARNING);
374}
375
376#Unknown in terms on # unknown only...
377elsif ( $UnkOnly && ($numprob{"UNKNOWN"}>=$UnkOnly) ) {
378 countAndPrint($unk,$numprob{$unk},0);
379 exitcheck($UNKNOWN);
380}
381
382#Unknown in terms of # warning, critical, and unknown...
383elsif (!$UnkOnly && ($numprob{"WARNING"} >= $unklevel{"WARNING"} ||
384 $numprob{"CRITICAL"} >= $unklevel{"CRITICAL"} ||
385 $numprob{"UNKNOWN"} >= $unklevel{"UNKNOWN"})) {
386 countAndPrint($unk,$total,1);
387 exitcheck($UNKNOWN);
388}
389
390# Everything is OK!
391else {
392 print "State OK - $numok OK, $total problems\n";
393 exitcheck($OK);
394}
395
396
397
398############################
399# Subroutines
400############################
401
402# Return the proper exit code for Critical, Warning, Unknown, or OK
403sub exitcheck {
404 if ($ok) {
405 exit 0;
406 }
407 else {
408 exit $_[0];
409 }
410}
411
412# Decide what to print for services:
413sub countAndPrint {
414 my $state = $_[0];
415 my $count = $_[1];
416 my $alltypes = $_[2];
417 my $output = "State $state - ";
418
419 if ($details) {
420 if ($count<=$much_details) {
421 if ($alltypes) {
422 $output .= "$count problems: $much_output{$crit} $much_output{$warn} $much_output{$unk}";
423 }
424 else {
425 $output .= "$count \L$state\E: $much_output{$state}";
426 }
427 }
428 elsif ($count<=$details) {
429 if ($alltypes) {
430 $output .= "$count problems: $output{$crit} $output{$warn} $output{$unk}";
431 }
432 else {
433 $output .= "$count \L$state\E: $output{$state}";
434 }
435 }
436 else {
437 if ($alltypes) {
438 $output .= "$numprob{$crit} critical, $numprob{$warn} warning, $numprob{$unk} unknown";
439 }
440 else {
441 $output .= "$count \L$state\E";
442 }
443 }
444 }
445 else {
446 $output .= "$count problems";
447 }
448
449 print "$output\n";
450}
451
452
453# Add-in the problem found in the status log
454sub addproblem {
455
456 $test = 1;
457 $type = $_[1];
458 my $diffout = "";
459
460 my @values = split /;/,$_[0];
461
462 if (!$host) {
463 my $namehold = $values[1];
464 if ($ack && ($values[13] eq "1")) {
465 if ($ack =~ "ok") {
466 $test = 0;
467 }
468 else {
469 $type = "\U$ack";
470 }
471 }
472 elsif ($hdown && grep /$namehold/, @hostdown) {
473 if ($hdown =~ "ok") {
474 $test = 0;
475 }
476 else {
477 $type = "\U$hdown";
478 $diffout = "$values[1] is down";
479 }
480 }
481 elsif ($dt && (($values[27] ne "0") || (grep /$namehold/, @hostdowntime))){
482 if ($dt =~ "ok") {
483 $test = 0;
484 }
485 else {
486 $type = "\U$dt";
487 }
488 }
489 elsif (exists $hostoktimes{$namehold}) {
490 # If the state change time of the host is more recent than the last
491 # service check, must wait until the next service check runs!
492 if ($hostoktimes{$namehold} > $values[6]) {
493 $test = 0;
494 }
495 }
496 }
497 else {
498 if ($ack && $values[5]) {
499 if ($ack =~ "ok") {
500 $test = 0;
501 }
502 else {
503 $type = "\U$ack";
504 }
505 }
506 elsif ($dt && ($values[17] ne "0")) {
507 if ($dt =~ "ok") {
508 $test = 0;
509 }
510 else {
511 $type = "\U$dt";
512 }
513 }
514 }
515
516 if ($details && $test) {
517 if (!$host) {
518 if ($diffout) {
519 $much_output{$type} .= " $diffout;";
520 $output{$type} .= "$diffout;";
521 $much_ct{$type}++;
522 $ct{$type}++;
523 }
524 else {
525 if ($much_details && $much_ct{$type}<$much_details) {
526 $much_output{$type} .= " $values[2] on $values[1] $values[31];";
527 $much_ct{$type}++;
528 }
529 if ($ct{$type} < $details) {
530 $output{$type} .= " $values[2] on $values[1];";
531 $ct{$type}++;
532 }
533 }
534 }
535 else {
536 $much_output{$type} .= " $values[1] $_[1] $values[20],";
537 $much_ct{type}++;
538 $output{$type} .= " $values[1] HOST $_[1],";
539 $ct{$type}++;
540 }
541 }
542 if ($test) {
543 $numprob{$type}++;
544 }
545}
546
547################################
548#
549# Version and Help Information
550#
551################################
552
553sub printVersion {
554 printf <<EndVersion;
555$0 (nagios-plugins) 1.3
556The nagios plugins come with ABSOLUTELY NO WARRANTY. You may redistribute
557copies of the plugins under the terms of the GNU General Public License.
558For more information about these matters, see the file named COPYING.
559EndVersion
560}
561
562sub printHelp {
563 printf <<EOF;
564
565This plugin parses through the Nagios status log and will return a
566Critical, Warning, or Unknown state depending on the number of
567Critical, Warning, and/or Unknown services found in the log
568(or Down/Unreachable hosts when matching against hosts)
569
570Usage: $0 -s <Status File> | -d <Nagios Log Directory>
571 [-w #[,#][,#]] [-c #[,#][,#]] [-u #[,#][,#]]
572 [--service=<RegEx> | --servhost=<RegEx> | --pattern=<RegEx> |
573 --host | --host=<RegEx>]
574 [--ack[=string]] [--dt[=string]] [--hostdown[=string]]
575 [-D #[,#]] [--ok] [-f <Log freshness in # minutes>]
576 $0 --help
577 $0 --version
578NOTE: One of -s and -d must be specified
579
580Options:
581 -s, --status=FILE_NAME
582 Location and name of status log (e.g. /usr/local/nagios/var/status.log)
583 -d, --dir=DIRECTORY_NAME
584 Directory that contains the nagios logs (e.g. /usr/local/nagios/var/)
585 -w, --warning=INTEGER[,INTEGER][,INTEGER]
586 #: Number of warnings to result in a WARNING state
587 OR
588 #,#: Warning,Criticals to result in a WARNING state
589 OR
590 #,#,#: Warning,Critical,Unknown to result in a WARNING state
591 Default: -w=1
592 -c, --critical=INTEGER[,INTEGER][,INTEGER]
593 #: Number of criticals to result in a CRITICAL state
594 OR
595 #,#: Warning,Criticals to result in a CRITICAL state
596 OR
597 #,#,#: Warning,Critical,Unknown to result in a CRITICAL state
598 Default: -c=1
599 -u, --unknown=INTEGER[,INTEGER][,INTEGER]
600 #: Number of unknowns to result in a UNKNOWN state
601 OR
602 #,#: Warning,Criticals to result in a UNKNOWN state
603 OR
604 #,#,#: Warning,Critical,Unknown to result in a UNKNOWN state
605 Default: -u=1
606 -r, --service[=REGEX]
607 Only match services [that match the RegEx]
608 (--service is default setting if no other matching arguments provided)
609 --servhost=REGEX
610 Only match services whose host match the RegEx
611 -p, --pattern=REGEX
612 Only parse for this regular expression (services only, not hosts)
613 --host[=REGEX]
614 Report on the state of hosts (whose name matches the RegEx if provided)
615 -a, --ack[=ok|warning|critical|unknown|down|unreachable]
616 Handle Acknowledged problems [--ack defaults to ok]
617 --dt, --downtime[=ok|warning|critical|unknown|down|unreachable]
618 Handle problems in scheduled downtime [--dt defaults to ok]
619 --hd, --hostdown[=ok|warning|critical|unknown|down|unreachable]
620 Handle services whose Host is down [--hd defaults to ok]
621 -D, --details=INTEGER[,INTEGER]
622 Amount of verbosity to output
623 If # problems:
624 <= 1st integer, return full details (each plugin's output)
625 <= 2nd integer, return some details (list each service host pair)
626 > 2nd integer, return the # of problems
627 -f, --freshness=INTEGER
628 Number of minutes old the log can be to make sure Nagios is running
629 (Default = 30 minutes)
630 --ok
631 Return an OK exit code, regardless of number of problems found
632 -h, --help
633 Print detailed help screen
634 -V, --version
635 Print version information
636
637For service checking (use --service and/or --servhost):
6381. The values of warning, critical, and unknown default to 1, i.e.
639$0 will return CRITICAL if there is at least 1 critical service,
640WARNING if there is at least 1 warning service, and UNKNOWN if there is
641at least one unknown service.
642
6432. If a service's host is DOWN or UNREACHABLE, $0 will use the
644value of --hostdown to determine how to treat the service. Without that
645argument, $0 will count the service as OK.
646
6473. If a service's host is OK, but the last host-state change occurred more
648recently than the last service check, $0 will ignore that service
649(want to wait until the service has been checked after a host has recovered
650or you may get service alert for services that still need to be checked)
651
6524. If the --dt, --ack, or --hd tags are used, $0 will use the value
653of the arguments to determine how to handle services in downtime, acknowledged,
654or with down hosts (default=OK). For service checks, --dt will also check
655if the service's host is in a downtime.
656
657For host checking (use --host):
6581. Using the --host argument, $0 will look for DOWN and UNREACHABLE
659hosts. If any are found, $0 will return a CRITICAL. You can provide
660an REGEX for --host to only check hosts with matching host names.
661
6622. If the --dt or --ack tags are used, $0 will use the value of the
663--dt/--ack arguments to determine the state of the host (default is OK)
664
665EOF
666}
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
diff --git a/contrib/sched_downtime.pl b/contrib/sched_downtime.pl
new file mode 100644
index 00000000..b46b482c
--- /dev/null
+++ b/contrib/sched_downtime.pl
@@ -0,0 +1,47 @@
1#! /usr/bin/perl -w
2#
3# Marko Riedel, EDV Neue Arbeit gGmbH, mriedel@neuearbeit.de
4#
5#
6#
7#
8use POSIX qw(strtol);
9
10my $command_file = '/usr/local/nagios/var/rw/nagios.cmd';
11
12my $hour = (60*60);
13my $next_day = (24*60*60);
14
15my $downtimes =
16 [
17 {
18 host => 'somehost',
19 service => 'SERVICE',
20 times => [ ["00:00", 9], ["18:00", 6] ]
21 }
22 ];
23
24foreach my $entry (@$downtimes) {
25 my ($secstart, $secend, $cmd, $current);
26
27 $current = `/bin/date +"%s"`;
28 chomp $current;
29
30 foreach my $tperiod (@{ $entry->{times} }){
31 $secstart = strtol(`/bin/date -d "$tperiod->[0]" +"%s"`);
32 $secend = $secstart+$tperiod->[1]*$hour;
33
34 $secstart += $next_day;
35 $secend += $next_day;
36
37 $cmd = "[$current] SCHEDULE_SVC_DOWNTIME;";
38 $cmd .= "$entry->{host};$entry->{service};";
39 $cmd .= "$secstart;$secend;";
40 $cmd .= "1;0;$0;automatically scheduled;\n";
41
42 print STDERR $cmd;
43
44 system "echo \"$cmd\" >> $command_file";
45 }
46}
47