diff options
author | Stanley Hopcroft <stanleyhopcroft@users.sourceforge.net> | 2005-01-27 04:46:08 +0000 |
---|---|---|
committer | Stanley Hopcroft <stanleyhopcroft@users.sourceforge.net> | 2005-01-27 04:46:08 +0000 |
commit | fce1f09f770fc5bbc6d323865af709ff515c803c (patch) | |
tree | 1e997a0bc1ace6217cc0dab87b65de52bca8be20 | |
parent | ccf789e017547e1f71b5945b2e1d85ce5b9cb8e4 (diff) | |
download | monitoring-plugins-fce1f09f770fc5bbc6d323865af709ff515c803c.tar.gz |
New /contrib plugin
git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@1112 f882894a-f735-0410-b71e-b25c423dba1c
-rw-r--r-- | contrib/check_arping.pl | 120 | ||||
-rw-r--r-- | contrib/check_cpqarray.c | 430 | ||||
-rw-r--r-- | contrib/check_frontpage | 151 | ||||
-rw-r--r-- | contrib/check_logins.c | 351 | ||||
-rw-r--r-- | contrib/check_oracle_tbs | 206 | ||||
-rw-r--r-- | contrib/check_pcpmetric.py | 106 | ||||
-rw-r--r-- | contrib/check_pfstate | 75 |
7 files changed, 1439 insertions, 0 deletions
diff --git a/contrib/check_arping.pl b/contrib/check_arping.pl new file mode 100644 index 00000000..b78ec68f --- /dev/null +++ b/contrib/check_arping.pl @@ -0,0 +1,120 @@ +#! /usr/bin/perl -w +# +# check_arping.pl - Nagios plugin to check host status via ARP ping +# +# usage: +# check_arping -H hostname -I interface -T timeout +# +# +# Copyright (C) 2003 Kenny Root +# +# 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. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# +# Report bugs to: kenny@the-b.org, nagiosplug-help@lists.sf.net + +use POSIX; +use strict; +use lib "/usr/lib/nagios/plugins" ; +use utils qw($TIMEOUT %ERRORS &print_revision &support); + +use Net::Arping; +use Getopt::Long; + +my $PROGNAME = "check_arping"; + +my($status, $state, $answer); +my($opt_V, $opt_h, $opt_t, $opt_I, $opt_H); + + +#Option checking +$status = GetOptions( + "V|version" => \$opt_V, + "help" => \$opt_h, + "I|interface=s" => \$opt_I, + "H|host=s" => \$opt_H, + "t|timeout=i" => \$opt_t); + +if ($status == 0) +{ + print_help() ; + exit $ERRORS{'OK'}; +} + + +if ($opt_V) { + print_revision($PROGNAME,'$Revision$ '); + exit $ERRORS{'OK'}; +} + +if ($opt_h) { + print_help(); + exit $ERRORS{'OK'}; +} + +if ($opt_t) { + if ($opt_t ne int($opt_t)) { + print "Timeout not in seconds!\n"; + print_help(); + exit $ERRORS{'OK'}; + } + $opt_t = int($opt_t); +} else { + $opt_t = 3; +} + +if (! utils::is_hostname($opt_H)){ + usage(); + exit $ERRORS{"UNKNOWN"}; +} + +my $ping = Net::Arping->new(); + +my $reply = $ping->arping(Host => $opt_H, Interface => $opt_I, Timeout => $opt_t); + +if ($reply eq "0") { + $state = "CRITICAL"; + print "$state: no reply from $opt_H on interface $opt_I in $opt_t seconds.\n"; + exit $ERRORS{$state}; +} else { + $state = "OK"; + $answer = "replied with MAC address $reply"; +} + +print "ARPING $state - $answer\n"; +exit $ERRORS{$state}; + + +sub usage { + print "\nMissing arguments!\n"; + print "\n"; + print "check_arping -I <interface> -H <host IP> [-t <timeout>]\n"; + print "\n\n"; + support(); + exit $ERRORS{"UNKNOWN"}; +} + +sub print_help { + print "check_arping pings hosts that normally wouldn't allow\n"; + print "ICMP packets but are still on the local network.\n"; + print "\nUsage:\n"; + print " -H (--host) IP to query - (required)\n"; + print " -I (--interface) Interface to use.\n"; + print " -t (--timeout) Timeout in seconds.\n"; + print " -V (--version) Plugin version\n"; + print " -h (--help) usage help \n\n"; + print_revision($PROGNAME, '$Revision$'); + +} diff --git a/contrib/check_cpqarray.c b/contrib/check_cpqarray.c new file mode 100644 index 00000000..badffeb4 --- /dev/null +++ b/contrib/check_cpqarray.c @@ -0,0 +1,430 @@ +/* + check_cpqarray, an extension for Netsaint / Nagios to check the + status of a Compaq SmartArray controller from the commandline. + Copyright (C) 2003 Guenther Mair + + based on the work and using main parts of + + CpqArray Deamon, a program to monitor and remotely configure a + SmartArray controller. + Copyright (C) 1999 Hugo Trippaers + + 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. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <unistd.h> +#include <sys/ioctl.h> +#include <sys/utsname.h> +#include <stdio.h> +#include <fcntl.h> +#include <string.h> +#include <errno.h> + +#include "/usr/src/linux/drivers/block/ida_ioctl.h" +#include "/usr/src/linux/drivers/block/ida_cmd.h" +#include "/usr/src/linux/drivers/block/cpqarray.h" + + +const char *controllers[] = +{ + "/dev/ida/c0d0", + "/dev/ida/c1d0", + "/dev/ida/c2d0", + "/dev/ida/c3d0", + "/dev/ida/c4d0", + "/dev/ida/c5d0", + "/dev/ida/c6d0", + "/dev/ida/c7d0" +}; + +const char *statusstr[] = { + "Logical drive /dev/ida/c%dd%d: OK\n", + "Logical drive /dev/ida/c%dd%d: FAILED\n", + "Logical drive /dev/ida/c%dd%d: not configured.\n", + "Logical drive /dev/ida/c%dd%d: using interim recovery mode, %3.2f%% done.\n", + "Logical drive /dev/ida/c%dd%d: ready for recovery operation.\n", + "Logical drive /dev/ida/c%dd%d: is currently recovering, %3.2f%% done.\n", + "Wrong physical drive was replaced.\n", + "A physical drive is not properly connected.\n", + "Hardware is overheating.\n", + "Hardware has overheated.\n", + "Logical drive /dev/ida/c%dd%d: currently expanding, %3.2f%% done.\n", + "Logical drive /dev/ida/c%dd%d: not yet available.\n", + "Logical drive /dev/ida/c%dd%d: queued for expansion.\n", +}; + +extern char *optarg; +extern int optind, opterr, optopt; + +int ctrls_found_num; +int exit_code = 0; +struct controller ctrls_found[8]; + +#define DEBUG(x) fprintf(stderr, x) + +struct opts +{ + char debug; +}; + +struct slog_disk +{ + int status; + float pvalue; +}; + +struct controller +{ + char ctrl_devicename[20]; + int num_logd_found; + struct slog_disk log_disk[16]; +}; + + + +int status_check (struct opts opts) +{ + int devicefd; + int ctrl_cntr; + int logd_cntr; + ida_ioctl_t io, io2; + int status, nr_blks, blks_tr; + float pvalue; + int counter; + + for ( ctrl_cntr=0; + ctrl_cntr < ctrls_found_num; + ctrl_cntr++) { + + devicefd = open (controllers[ctrl_cntr], O_RDONLY); + + for ( logd_cntr=0; + logd_cntr < ctrls_found[ctrl_cntr].num_logd_found; + logd_cntr++) { + + memset (&io, 0, sizeof (io)); + + io.cmd = SENSE_LOG_DRV_STAT; + io.unit = logd_cntr | UNITVALID; + + if (ioctl (devicefd, IDAPASSTHRU, &io) < 0) + { + perror ("SENSE_LOG_DRV_STAT ioctl"); + return 0; + } + + status=io.c.sense_log_drv_stat.status; + + if ((status == 3) || (status == 5) || (status == 7)) { + /* is a progress indicator required? + */ + memset (&io2, 0, sizeof (io)); + + io2.cmd = ID_LOG_DRV; + io2.unit = logd_cntr | UNITVALID; + + if (ioctl (devicefd, IDAPASSTHRU, &io2) < 0) + { + perror ("ID_LOG_DRV ioctl"); + /* return 0; no return this isn't fatal for now */ + } + else + { + nr_blks = io2.c.id_log_drv.nr_blks; + blks_tr = io.c.sense_log_drv_stat.blks_to_recover; + + pvalue = ((float)(nr_blks - blks_tr)/(float)nr_blks) * 100; + } + } + else { + pvalue = 0.0; + } + + if (opts.debug) { + fprintf(stdout, "DEBUG: Status of controller %d unit %d is %d\n", + ctrl_cntr, logd_cntr, status); + fprintf(stdout, "DEBUG: "); + fprintf(stdout, statusstr[status], + ctrl_cntr, logd_cntr, pvalue); + fprintf(stdout, "\n"); + } + + printf(statusstr[status], ctrl_cntr, logd_cntr, pvalue); + + switch(status) + { + case 1: + case 2: + case 6: + case 7: + case 9: + /* CRITICAL */ + exit_code = 2; + break; + case 3: + case 4: + case 5: + case 8: + case 10: + case 11: + case 12: + /* WARNING (only if not yet at CRITICAL LEVEL) */ + if (exit_code < 2) exit_code = 1; + break; + case 0: + default: + /* do nothing */ + break; + } + + ctrls_found[ctrl_cntr].log_disk[logd_cntr].pvalue = pvalue; + ctrls_found[ctrl_cntr].log_disk[logd_cntr].status = status; + } + close (devicefd); + } + + return 1; +} + +int discover_controllers (struct opts opts) +{ + int cntr; + int foundone = 0; + + for (cntr = 0; cntr < 8; cntr++) + { + /* does this device exist ? */ + if ((access (controllers[cntr], R_OK | F_OK)) == 0) + { + /* it does :) */ + if (interrogate_controller (opts, cntr)) + { + foundone = 1; + if (opts.debug) + fprintf (stderr, "DEBUG: %s is a existing controller\n", + controllers[cntr]); + } + } + else if (opts.debug) + { + fprintf (stderr, "DEBUG: Device %s could not be opened\n", controllers[cntr]); + perror ("DEBUG: reason"); + } + } + return foundone; +} + +void boardid2str (unsigned long board_id, char *name) +{ + switch (board_id) + { + case 0x0040110E: /* IDA */ + strcpy (name, "Compaq IDA"); + break; + case 0x0140110E: /* IDA-2 */ + strcpy (name, "Compaq IDA-2"); + break; + case 0x1040110E: /* IAES */ + strcpy (name, "Compaq IAES"); + break; + case 0x2040110E: /* SMART */ + strcpy (name, "Compaq SMART"); + break; + case 0x3040110E: /* SMART-2/E */ + strcpy (name, "Compaq SMART-2/E"); + break; + case 0x40300E11: /* SMART-2/P or SMART-2DH */ + strcpy (name, "Compaq SMART-2/P (2DH)"); + break; + case 0x40310E11: /* SMART-2SL */ + strcpy (name, "Compaq SMART-2SL"); + break; + case 0x40320E11: /* SMART-3200 */ + strcpy (name, "Compaq SMART-3200"); + break; + case 0x40330E11: /* SMART-3100ES */ + strcpy (name, "Compaq SMART-3100ES"); + break; + case 0x40340E11: /* SMART-221 */ + strcpy (name, "Compaq SMART-221"); + break; + case 0x40400E11: /* Integrated Array */ + strcpy (name, "Compaq Integrated Array"); + break; + case 0x40500E11: /* Smart Array 4200 */ + strcpy (name, "Compaq Smart Array 4200"); + break; + case 0x40510E11: /* Smart Array 4250ES */ + strcpy (name, "Compaq Smart Array 4250ES"); + break; + case 0x40580E11: /* Smart Array 431 */ + strcpy (name, "Compaq Smart Array 431"); + break; + default: + /* + * Well, its a SMART-2 or better, don't know which + * kind. + */ + strcpy (name, "Unknown Controller Type"); + } +} + +int interrogate_controller (struct opts opts, int contrnum) +{ + int devicefd; + ida_ioctl_t io; + char buffer[30]; + int foundone = 0; + int cntr; + + devicefd = open (controllers[contrnum], O_RDONLY); + /* no checks, did that before */ + + /* clear io */ + memset (&io, 0, sizeof (io)); + + io.cmd = ID_CTLR; + + if (ioctl (devicefd, IDAPASSTHRU, &io) < 0) + { + if (opts.debug) perror ("DEBUG: ioctl"); + return 0; + } + + boardid2str (io.c.id_ctlr.board_id, buffer); + + strncpy (ctrls_found[ctrls_found_num].ctrl_devicename, + buffer, 20); + + ctrls_found[ctrls_found_num].num_logd_found = 0; + + for (cntr = 0; cntr < io.c.id_ctlr.nr_drvs; cntr++) + { + if (interrogate_logical (opts, devicefd, cntr)) + { + /* logical drive found, this could be used later one */ + foundone = 1; + } + } + + switch (ctrls_found[ctrls_found_num].num_logd_found) + { + case 0: + printf("Found a %s with no logical drives.\n", buffer); + break; + case 1: + printf("Found a %s with one Logical drive.\n", buffer, + ctrls_found[ctrls_found_num].num_logd_found); + break; + default: + printf("Found a %s with %d Logical drives.\n", buffer, + ctrls_found[ctrls_found_num].num_logd_found); + break; + } + + ctrls_found_num++; + + close (devicefd); + return 1; +} + +int interrogate_logical (struct opts opts, int devicefd, int unit_nr) +{ + ida_ioctl_t io; + ida_ioctl_t io2; + int nr_blks, blks_tr; + + if (opts.debug) printf ("DEBUG: interrogating unit %d\n", unit_nr); + + memset (&io, 0, sizeof (io)); + + io.cmd = ID_LOG_DRV; + io.unit = unit_nr | UNITVALID; + + if (ioctl (devicefd, IDAPASSTHRU, &io) < 0) + { + perror ("FATAL: ID_LOG_DRV ioctl"); + return 0; + } + + memset (&io2, 0, sizeof (io2)); + + io2.cmd = SENSE_LOG_DRV_STAT; + io2.unit = unit_nr | UNITVALID; + + if (ioctl (devicefd, IDAPASSTHRU, &io2) < 0) + { + perror ("FATAL: SENSE_LOG_DRV_STAT ioctl"); + return 0; + } + + ctrls_found[ctrls_found_num].num_logd_found++; + /* ctrls_found[ctrls_found_num].log_disk[unit_nr].status = + * io2.c.sense_log_drv_stat.status; + + * nr_blks = io2.c.id_log_drv.nr_blks; + * blks_tr = io.c.sense_log_drv_stat.blks_to_recover; + * ctrls_found[ctrls_found_num].log_disk[unit_nr].pvalue = + * ((float)(nr_blks - blks_tr)/(float)nr_blks) * 100; + */ + ctrls_found[ctrls_found_num].log_disk[unit_nr].status = 0; + ctrls_found[ctrls_found_num].log_disk[unit_nr].pvalue = 0; + + return 1; +} + + +void print_usage() +{ + printf("cpqarrayd [options]\n"); + printf(" -h prints this text\n"); + printf(" -d enables debugging\n"); +} + + +int main(int argc, char *argv[]) +{ + char option; + struct opts opts; /* commandline options */ + + memset(&opts, 0, sizeof(struct opts)); + + /* check options */ + while ((option = getopt (argc, argv, "dh:")) != EOF) + { + switch (option) + { + case 'd': + opts.debug = 1; + break; + case '?': + case 'h': + default: + print_usage(); + exit(0); + break; + } + } + + /* Check for existance of array controllers */ + if (!discover_controllers(opts)) { + printf("No array controller found!\n\n"); + exit(1); + } + + status_check(opts); + + return exit_code; +} diff --git a/contrib/check_frontpage b/contrib/check_frontpage new file mode 100644 index 00000000..ee958d30 --- /dev/null +++ b/contrib/check_frontpage @@ -0,0 +1,151 @@ +#! /usr/bin/perl -w +# +# $Id$ +# +# Check that FrontPage extensions appear to be working on a specified host. +# Currently only checks that the hit counter is not returning an error. +# +# Probably not a good idea to use this on a host that someone's counting +# the hits on, so create a separate vhost for frontpage extensions testing, +# or just install the extensions on the default/root host for your server, and +# point it against that hostname, running it against all vhosts on a server is +# probably rather wasteful. +# +# Kev Green, oRe Net (http://www.orenet.co.uk/). + + +use strict; +use lib "/usr/lib/nagios/plugins"; +use utils qw($TIMEOUT %ERRORS &print_revision &support); +use vars qw($PROGNAME); +use Getopt::Long; +use LWP; +use vars qw($opt_V $opt_h $verbose $opt_w $opt_c $opt_H); +my ($tt,$url,$response,$stime, $etime,$warning,$critical,$mimetype,$failtype,$temp,$message); +my $rt = 0; + +$PROGNAME = "check_frontpage"; +sub print_help (); +sub print_usage (); + +$ENV{'PATH'}=''; +$ENV{'BASH_ENV'}=''; +$ENV{'ENV'}=''; + +Getopt::Long::Configure('bundling'); +GetOptions + ("V" => \$opt_V, "version" => \$opt_V, + "h" => \$opt_h, "help" => \$opt_h, + "v" => \$verbose, "verbose" => \$verbose, + "w=s" => \$opt_w, "warning=s" => \$opt_w, + "c=s" => \$opt_c, "critical=s" => \$opt_c, + "H=s" => \$opt_H, "hostname=s" => \$opt_H); + +if ($opt_V) { + print_revision($PROGNAME,'$Revision$'); #' + exit $ERRORS{'OK'}; +} + +if ($opt_h) { + print_help(); + exit $ERRORS{'OK'}; +} + +$opt_H = shift unless ($opt_H); +print_usage() unless $opt_H; +my $host = $1 if ($opt_H =~ m/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[a-zA-Z][-a-zA-Z0-9]+(\.[a-zA-Z0-9][-a-zA-Z0-9]+)*)$/); +print_usage() unless $host; + +($opt_c) || ($opt_c = shift) || ($opt_c = 120); +if ($opt_c =~ /([0-9]+)/) { + $critical = $1; +} else { + $critical = 10; +} + +($opt_w) || ($opt_w = shift) || ($opt_w = 60); +if ($opt_w =~ /([0-9]+)/) { + $warning = $1; +} else { + $warning = 5; +} + +# Guts go here, once we're through argument parsing and have warning and +# critical thresholds. +my $browser = LWP::UserAgent->new; + +my @urls = ( + # This is the "Hit Counter", which continues to work if frontpage extensions + # are 'uninstall'ed from the site, but not when they are 'fulluninstall'ed. + { + url => "_vti_bin/fpcount.exe?Page=_borders/right.htm|Image=4", + mimetype => "image/gif", + message => "None, or broken frontpage extensions on server, or virtual site 'fulluninstall'ed?", + failtype => "CRITICAL" + }, + # This is the "FrontPage Configuration Information" file, which is removed + # when you 'uninstall' the extensions from a site. + { + url => "_vti_inf.html", + mimetype => "text/html", + message => "Someone 'uninstall'ed extensions on virtual site?", + failtype => "WARNING" + } +); + +print "FRONTPAGE: "; + +foreach $temp (@urls) { + $url = $temp->{'url'}; + $mimetype = $temp->{'mimetype'}; + $failtype = $temp->{'failtype'}; + $message = $temp->{'message'}; + $stime = time(); + $response=$browser->get("http://".$host."/".$url); + $etime = time(); + $tt = $etime - $stime; + +# If we got a server error, or unknown output type, report back as critical. + if ($response->status_line !~ "^200") { + print $message." (".$response->status_line.")\r\n"; + exit $ERRORS{$failtype}; + } elsif ($response->content_type !~ $mimetype) { + print $message." (Wrong Content-type: ".$response->content_type.")\r\n"; + exit $ERRORS{$failtype}; + } else { + # Because we're dealing with multiple URL's + $rt += $tt; + } + +# Decide if the response time was critical or not. +# + if ($rt > $critical) { + print "Response time ".$rt." over critical threshold ".$critical."\r\n"; + exit($ERRORS{'CRITICAL'}); + } elsif ($rt > $warning) { + print "Response time ".$rt." over warning threshold ".$warning."\r\n"; + exit($ERRORS{'WARNING'}); + } +} +printf(" %s - %s second response time, ",$response->status_line, $rt); + +# If all the required URL's give the right responses quick enough, then we +# should be okay. +exit($ERRORS{'OK'}); + +sub print_usage () { + print "Usage: $PROGNAME -H <host> [-w <warn>] [-c <crit>]\n"; + exit; +} + +sub print_help () { + print_revision($PROGNAME,'$Revision$'); + print "Copyright (c) 2003 Kev Green\n"; + print "\n"; + print "FrontPage remains a copyright/trademark of Microsoft Corporation.\n"; + print_usage(); + print "\n"; + print "<warn> = Unknown.\n"; + print "<crit> = Server error from FrontPage extensions.\n\n"; + support(); +} diff --git a/contrib/check_logins.c b/contrib/check_logins.c new file mode 100644 index 00000000..fa3ed177 --- /dev/null +++ b/contrib/check_logins.c @@ -0,0 +1,351 @@ +/*================================= + * check_logins - Nagios plugin + * Copyright (C) 2003 Dag Robøle + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors email: drobole@broadpark.no + */ +//================================= +#include <sys/types.h> +#include <signal.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +#include "config.h" +#include "common.h" +#include "utils.h" +#include "popen.h" +//================================= +#define REVISION "$Revision$" +#define COPYRIGHT "2003" +#define AUTHOR "Dag Robole" +#define EMAIL "drobole@broadpark.no" +#define SUMMARY "Check for multiple user logins" + +#define check(func, errmsg) { if((func) == -1) die(STATE_UNKNOWN, errmsg); } +#define checkz(func, errmsg) { if(!(func)) die(STATE_UNKNOWN, errmsg); } +//================================= +typedef struct USERNODE_TYP { + char *name; + char *host; + struct USERNODE_TYP* next; +} USERNODE; +//================================= +char *progname = NULL; +USERNODE *userlist = NULL, *adminlist = NULL; +int warning_limit = 0, critical_limit = 0; + +void print_usage(); +void print_help(); +void process_arguments(int argc, char* *argv); +void parse_wholine(const char *line, char *name, char *host); +void node_create(USERNODE* *node, const char *name, const char *host); +void node_free(USERNODE* *node); +USERNODE* list_insert_sort_uniq(USERNODE* *list, USERNODE* *node); +void list_free(USERNODE* *list); +void cleanup(); +//================================= +int main(int argc, char* *argv) +{ + FILE *who; + USERNODE *newnode, *nptra, *nptrb; + char buffer[BUFSIZ], username[BUFSIZ], hostname[BUFSIZ], *cptra, *cptrb; + char max_login_name[BUFSIZ], currname[BUFSIZ]; + int max_login_count = 0, counter = 0, skip; + void (*old_sig_alrm)(); + + progname = argv[0]; + if(atexit(cleanup)) + die(STATE_UNKNOWN, "atexit failed\n"); + + if((old_sig_alrm = signal((int)SIGALRM, timeout_alarm_handler)) == SIG_ERR) + die(STATE_UNKNOWN, "signal failed\n"); + alarm(timeout_interval); + + process_arguments(argc, argv); + + checkz(who = spopen(PATH_TO_WHO), "spopen failed\n"); + + while(fgets(buffer, sizeof(buffer), who) != NULL) { + parse_wholine(buffer, username, hostname); + skip = 0; + nptra = adminlist; + + while(nptra != NULL) { + if(!strcmp(nptra->name, username)) { + skip = 1; + break; + } + nptra = nptra->next; + } + if(!skip) { + node_create(&newnode, username, hostname); + if(!list_insert_sort_uniq(&userlist, &newnode)) + node_free(&newnode); + } + } + + check(spclose(who), "spclose failed\n"); + + if(userlist != NULL) { + nptra = userlist; + strcpy(currname, nptra->name); + strcpy(max_login_name, nptra->name); + max_login_count = 1; + while(nptra != NULL) { + if(!strcmp(currname, nptra->name)) + ++counter; + else { + if(counter > max_login_count) { + max_login_count = counter; + strcpy(max_login_name, currname); + } + strcpy(currname, nptra->name); + counter = 1; + } + nptra = nptra->next; + } + + if(counter > max_login_count) { + max_login_count = counter; + strcpy(max_login_name, currname); + } + } + + if(signal((int)SIGALRM, old_sig_alrm) == SIG_ERR) + die(STATE_UNKNOWN, "signal failed\n"); + + if(max_login_count) { + if(critical_limit && max_login_count >= critical_limit) { + printf("CRITICAL - User %s has logged in from %d different hosts\n", max_login_name, max_login_count); + return STATE_CRITICAL; + } + else if(warning_limit && max_login_count >= warning_limit) { + printf("WARNING - User %s has logged in from %d different hosts\n", max_login_name, max_login_count); + return STATE_WARNING; + } + } + + printf("OK - No users has exceeded the login limits\n"); + return STATE_OK; +} +//================================= +void print_usage() +{ + fprintf(stderr, "Usage: %s [ -hV ] [ -w limit ] [ -c limit ] [ -u username1, ... ,usernameN ]\n", progname); +} +//================================= +void print_help() +{ + print_revision(progname, REVISION); + printf("Copyright (c) %s %s <%s>\n\n%s\n\n", COPYRIGHT, AUTHOR, EMAIL, SUMMARY); + print_usage(); + printf("\nDescription:\n" + "\tThis plugin supports the w (warning) and c (critical) options indicating the upper limits\n" + "\tof logins allowed before a warning is given.\n" + "\tThe output from %s is the username and number of login sessions for the user\n" + "\twho has the most login sessions (from different hosts) running at a given point in time.\n" + "\tThe u (users) option takes a comma separated list of usernames that will be ignored\n" + "\twhile scannig users.\n" + "\nOptions:\n" + "\t-h | --help\n\t\tShow this help message and exit\n" + "\t-V | --version\n\t\tShow version description\n" + "\t-w | --warning=INTEGER\n\t\tSet warning limit for logins (minimum value is 2)\n" + "\t-c | --critical=INTEGER\n\t\tSet critical limit for logins (minimum value is 2)\n" + "\t-u | --users=STRING\n\t\tSet usernames to be ignored\n" + "\nExamples:\n\t%s -w 3 -c 5\n" + "\t%s -w 3 -c 5 -u root,guest,jcarmack\n\n", progname, progname, progname); +} +//================================= +void process_arguments(int argc, char* *argv) +{ + USERNODE *newnode; + int optch; + char buffer[BUFSIZ], *cptra; + static struct option long_opts[] = { + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"warning", required_argument, 0, 'w'}, + {"critical", required_argument, 0, 'c'}, + {"users", required_argument, 0, 'u'}, + {0, 0, 0, 0}, + }; + + while((optch = getopt_long(argc, argv, "hVw:c:u:", long_opts, NULL)) != -1) { + switch(optch) { + case 'h': + print_help(); + exit(STATE_OK); + break; + case 'V': + print_revision(progname, REVISION); + exit(STATE_OK); + break; + case 'w': + if(!is_numeric(optarg)) { + print_usage(); + die(STATE_UNKNOWN, "invalid options\n"); + } + warning_limit = atoi(optarg) > 2 ? atoi(optarg) : 2; + break; + case 'c': + if(!is_numeric(optarg)) { + print_usage(); + die(STATE_UNKNOWN, "invalid options\n"); + } + critical_limit = atoi(optarg) > 2 ? atoi(optarg) : 2; + break; + case 'u': + strcpy(buffer, optarg); + cptra = strtok(buffer, ","); + while(cptra != NULL) { + node_create(&newnode, cptra, "(adminhost)"); + list_insert_sort_uniq(&adminlist, &newnode); + cptra = strtok(NULL, ","); + } + break; + default: + print_usage(); + exit(STATE_UNKNOWN); + break; + } + } + + if(argc > optind) { + print_usage(); + die(STATE_UNKNOWN, "invalid options\n"); + } + + if(!warning_limit && !critical_limit) { + print_usage(); + die(STATE_UNKNOWN, "you must provide a limit for this plugin\n"); + } + + if(critical_limit && warning_limit > critical_limit) { + print_usage(); + die(STATE_UNKNOWN, "warning limit must be less or equal critical limit\n"); + } +} +//================================= +void parse_wholine(const char *line, char *name, char *host) +{ + char buffer[BUFSIZ], *cptra, *cptrb, *display; + strcpy(buffer, line); + + cptra = buffer; + checkz(cptrb = (char*)strchr(buffer, ' '), "strchr failed\n"); + strncpy(name, cptra, cptrb-cptra); + name[cptrb-cptra] = '\0'; + + if((cptra = strchr(buffer, '(')) != NULL) // hostname found in source arg... + { + if(cptra[1] == ':') // local host + strcpy(host, "(localhost)"); + else // extern host + { + checkz(cptrb = strchr(cptra, ')'), "strchr failed\n"); + cptrb++; + strncpy(host, cptra, cptrb-cptra); + host[cptrb-cptra] = '\0'; + } + } + else // no hostname in source arg, look in line arg... + { + checkz(cptra = strtok(buffer, " \t\r\n"), "strtok failed\n"); + checkz(cptra = strtok(NULL, " \t\r\n"), "strtok failed\n"); + if(cptra[0] == ':') // local host + strcpy(host, "(localhost)"); + else // extern host + sprintf(host, "(%s)", cptra); + } + + if((cptra = strchr(host, ':')) != NULL) // remove display if any... + strcpy(cptra, ")"); +} +//================================= +void node_create(USERNODE* *node, const char *name, const char *host) +{ + checkz(*node = (USERNODE*)malloc(sizeof(USERNODE)), "malloc failed\n"); + checkz((*node)->name = (char*)malloc(strlen(name)+1), "malloc failed\n"); + checkz((*node)->host = (char*)malloc(strlen(host)+1), "malloc failed\n"); + (*node)->next = NULL; + strcpy((*node)->name, name); + strcpy((*node)->host, host); +} +//================================= +void node_free(USERNODE* *node) +{ + free((*node)->name); + free((*node)->host); + free(*node); + *node = NULL; +} +//================================= +USERNODE* list_insert_sort_uniq(USERNODE* *list, USERNODE* *node) +{ + char n1[BUFSIZ], n2[BUFSIZ]; + USERNODE *last_nptr = NULL, *nptr = *list; + + if(*list == NULL) + return(*list = *node); + else { + sprintf(n1, "%s %s", (*node)->name, (*node)->host); + while(nptr != NULL) { + sprintf(n2, "%s %s", nptr->name, nptr->host); + if(!strcmp(n1, n2)) + return NULL; + else if(strcmp(n1, n2) < 0) { + if(last_nptr) { + last_nptr->next = *node; + (*node)->next = nptr; + } + else { + (*node)->next = *list; + *list = *node; + } + break; + } + else { + last_nptr = nptr; + nptr = nptr->next; + } + } + if(nptr == NULL) + last_nptr->next = *node; + } + return *node; +} +//================================= +void list_free(USERNODE* *list) +{ + USERNODE *doe, *nptr = *list; + while(nptr != NULL) { + doe = nptr; + nptr = nptr->next; + node_free(&doe); + } + *list = NULL; +} +//================================= +void cleanup() +{ + list_free(&userlist); + list_free(&adminlist); +} +//================================= diff --git a/contrib/check_oracle_tbs b/contrib/check_oracle_tbs new file mode 100644 index 00000000..bcc4af87 --- /dev/null +++ b/contrib/check_oracle_tbs @@ -0,0 +1,206 @@ +#!/usr/local/bin/perl -w + +# (c)2003 John Koyle, RFP Depot, LLC. +# This is free software use it however you would like. +# Thanks to the folks at http://www.think-forward.com for the SQL query + + +use strict; +use DBI; +use Getopt::Long 2.16; +use lib "/usr/local/nagios/libexec"; +use utils qw(%ERRORS); + + +#******************************************************************************* +# Set user configureable options here. +# +# Global Oracle info set here rather than command line to avoid output in ps -ef +# Make sure this script is mode 700 and owner of the nrpe user +# +#******************************************************************************* +my $orasid = ""; +my $orauser = ""; +my $orapwd = ""; + + +if (!$ENV{ORACLE_HOME}) { + $ENV{ORACLE_HOME} = '/a01/app/oracle/product/9.2.0.1'; +} + +#*****************You shouldn't need to modify anything below here ************* +my $state = $ERRORS{'UNKNOWN'}; +my $answer = undef; + +my ($MAJOR_VERSION, $MINOR_VERSION) = q$Revision$ =~ /(\d+)\.(\d+)/; +my $VERSION = sprintf("%d.%02d", $MAJOR_VERSION - 1, $MINOR_VERSION); + +my $opt_debug; # -d|--debug +my $opt_help; # -h|--help +my $opt_version; # -V|--version +my $opt_warn_space; # -w|--warn-space +my $opt_crit_space; # -c|--crit-space + +my $help = <<MARK; # help statement + +check_oracle_tbs v$VERSION + +Checks the tablespaces in an Oracle database for available free space. +Usage: check_oracle_tbs [-w <warn>] [-c <crit>] + + -d, --debug Output debug to screen. + -h, --help Displays this help and exits. + -w, --warn-space=... Warning threshold % free (default 15) + -c, --crit-space=... Critical threshold % free (default 10) + -V, --version Output version information and exit. + +MARK + +## We want exact matches to the switches + +Getopt::Long::config('no_auto_abbrev', 'no_ignore_case'); + +my $rc = GetOptions( + "debug|d" => \$opt_debug, + "help|h" => \$opt_help, + "w|warn-space=s" => \$opt_warn_space, + "c|crit-space=s" => \$opt_crit_space, + "V|version" => \$opt_version, + ); + + +#*********************************************************************** +# Process command-line switches +#*********************************************************************** + +if (! $rc || defined $opt_help) +{ + print STDERR $help; + exit (defined $opt_help ? 0 : 1); +} + +if (defined $opt_version) +{ + print STDERR "check_oracle_tbs v$VERSION\n"; + exit 0; +} + +if (! defined $opt_warn_space) +{ + if(defined $opt_debug) { + print STDOUT "Warn space not defined, using 80%\n\n"; + } + $opt_warn_space = 15; +} + +if (! defined $opt_crit_space) +{ + if(defined $opt_debug) { + print STDOUT "Crit space not defined, using 90%\n\n"; + } + $opt_crit_space = 10; +} + +my $array_ref = executeSQL(); + +foreach my $row (@$array_ref) { + my ( $tbs_name, $tot_mb, $free_mb, $free_pct, $used_pct, $fsfi) = @$row; + if ($opt_debug) { print STDOUT "Output: $tbs_name\t$tot_mb\t$free_mb\t$free_pct\t$used_pct\t$fsfi\n\n"; } + if ($used_pct > (100 - $opt_crit_space) && $tbs_name !~ /RBS/) { + $state = $ERRORS{'CRITICAL'}; + $answer .= "$tbs_name = $used_pct\% "; + last; + } + if ($used_pct > (100 - $opt_warn_space) && $tbs_name !~ /RBS/) { + $state = $ERRORS{'WARNING'}; + $answer .= "$tbs_name = $used_pct\% "; + } +} + +if ($state != $ERRORS{'CRITICAL'} && $state != $ERRORS{'WARNING'}) { + $state = $ERRORS{'OK'}; + $answer = "All Tablespaces OK"; +} + +if ($opt_debug && $state != $ERRORS{'OK'}) { print STDOUT "The following tablespaces are in question: $answer\n\n"; } + +foreach my $key (keys %ERRORS) { + if ($state==$ERRORS{$key}) { + print ("$key: $answer"); + last; + } +} +exit $state; + +sub executeSQL +{ + my ($dbh, $sth, $results); + + $dbh = openOracle(); + + eval { + $dbh->{RaiseError} = 1; + # This query is taken from this URL and used with permission: http://www.think-forward.com/sql/tspace.htm + $sth = $dbh->prepare(q{ + select df.tablespace_name tspace, + df.bytes/(1024*1024) tot_ts_size, + sum(fs.bytes)/(1024*1024) free_ts_size, + round(sum(fs.bytes)*100/df.bytes) ts_pct, + round((df.bytes-sum(fs.bytes))*100/df.bytes) ts_pct1, + ROUND(100*SQRT(MAX(fs.bytes)/SUM(fs.bytes))* + (1/SQRT(SQRT(COUNT(fs.bytes)))) ,2) FSFI + from dba_free_space fs, (select tablespace_name, sum(bytes) bytes + from dba_data_files + group by tablespace_name ) df + where fs.tablespace_name = df.tablespace_name + group by df.tablespace_name, df.bytes + }); + + $sth->execute(); + $results = $sth->fetchall_arrayref(); + $sth->finish; + $dbh->{RaiseError} = 0; + }; + + if ($@) { + closeOracle($dbh); + if($opt_debug) { print STDOUT "DB Failed Query: $@\n"; } + CleanupAndExit($ERRORS{'UNKNOWN'}); + } + + closeOracle($dbh); + + return $results; +} + +#------ Open the connection to the database and return the handle +sub openOracle +{ + my ($dbh); + + $dbh = DBI->connect("$orasid", "$orauser", "$orapwd", "Oracle"); + + if (!$dbh) { + if ($opt_debug) { print "ERROR: Could not connect to Oracle!\n\n"; } + CleanupAndExit($ERRORS{'UNKNOWN'}); + } + if ($opt_debug) { print "Connected to Oracle SID $orasid\n\n"; } + return $dbh; +} + +#------- Close the database connection +sub closeOracle() +{ + my ($dbh) = @_; + + $dbh->disconnect; +} + +#------ Exit with the current return code +sub CleanupAndExit +{ + my ($rc) = @_; + + exit($rc); +} + diff --git a/contrib/check_pcpmetric.py b/contrib/check_pcpmetric.py new file mode 100644 index 00000000..71d816d4 --- /dev/null +++ b/contrib/check_pcpmetric.py @@ -0,0 +1,106 @@ +#! /usr/bin/env python +# +# Nagios client for checking Performance Co-Pilot metrics +# +# + +from sys import argv,exit +import popen2, getopt, string, types + +DEBUG=0 + +nagios_pcpclient_version = 0.01 +PMVAL='/usr/bin/pmval' +COMMANDLINE=PMVAL + " -s 1" +METRIC='undefined' +CRITICAL=0 +WARNING=0 + +def usage(): + print "Usage:", argv[0], "[options]" + print "Options:" + print "\t[-H host]\tHostname to contact" + print "\t[-m metric]\tPCP metric to check" + print "\t[-i instance]\tPCP metric instance" + print "\t[-w warn]\tIssue warning alert if value is larger than this" + print "\t[-c critical]\tIssue critical alert value is larger than this" + print "\t[-V]\t\tProgram version" + print "\t[-h]\t\tThis helptext" + print "" + print "F.ex. to check 5 minute loadaverage, warn if the load is above 2," + print "and give critical warning if it's above 10:" + print "\n\t%", argv[0], " -i 5 -m kernel.all.load -w 2 -c 10" + print "" + print "A list of all PCP metrics can be found with the command 'pminfo'." + print "A list of all instances within a metric can be found with 'pminfo -f metric'." + print "F.ex. to see all available instances of 'filesys.full' execute:" + print "\n\t% pminfo -f filesys.full" + print "\tfilesys.full" + print """\t\tinst [0 or "/dev/root"] value 45.35514044640914""" + print """\t\tinst [1 or "/dev/sda1"] value 46.74285959344712""" + print """\t\tinst [2 or "/dev/sdb1"] value 0.807766570678168""" + print "" + print "And the command to have nagios monitor the /dev/sda1 filesystem would be:" + print "\n\t", argv[0], " -i /dev/sda1 -m filesys.full -w 70 -c 90" + + +opts, args = getopt.getopt(argv[1:],'hH:c:w:m:i:V') +for opt in opts: + key,value = opt + if key == '-H': + COMMANDLINE = COMMANDLINE + " -h " + value + elif key == '-m': + METRIC=value + elif key == '-i': + COMMANDLINE = COMMANDLINE + " -i " + value + elif key == '-c': + CRITICAL = value + elif key == '-w': + WARNING = value + elif key == '-h': + usage() + exit(0) + elif key == '-V': + print "Nagios Performance CoPilot client v%.2f" % nagios_pcpclient_version + print "Written by Jan-Frode Myklebust <janfrode@parallab.uib.no>" + exit(0) + +if METRIC == 'undefined': + usage() + exit(3) + +COMMANDLINE = COMMANDLINE + " " + METRIC +if DEBUG: print COMMANDLINE +p=popen2.Popen4(COMMANDLINE) +exitcode=p.wait() + +# Get the last line of output from 'pmval': +buffer = p.fromchild.readline() +while (buffer != ''): + output=buffer + buffer = p.fromchild.readline() + +returndata = string.split(output)[0] + + +# Confirm that we have gotten a float, and not +# some errormessage in the returndata. If not, +# print the error, and give the UNKNOWN exit code: + +try: + retval = string.atof(returndata) +except ValueError, e: + print e + exit(3) + +if (retval < WARNING): + EXITCODE=0 +elif (retval > CRITICAL): + EXITCODE=2 +elif (retval > WARNING): + EXITCODE=1 +else: + EXITCODE=3 + +print retval +exit(EXITCODE) diff --git a/contrib/check_pfstate b/contrib/check_pfstate new file mode 100644 index 00000000..6fe0d9b0 --- /dev/null +++ b/contrib/check_pfstate @@ -0,0 +1,75 @@ +#!/usr/bin/perl + +use strict; +use Getopt::Long; +use vars qw($opt_V $opt_h $opt_P $opt_H $opt_w $opt_c $PROGNAME); +use lib "/usr/local/nagios/libexec" ; +use utils qw(%ERRORS &print_revision &support &usage); + +my $remote_user = "root"; +my $path_to_ssh = "/usr/bin/ssh"; +my $path_to_grep = "/usr/bin/grep"; +my $path_to_awk = "/usr/bin/awk"; +my $warn = 50000; +my $crit = 60000; + +$PROGNAME = "check_pfstate"; +$ENV{'PATH'}=''; +$ENV{'BASH_ENV'}=''; +$ENV{'ENV'}=''; + +Getopt::Long::Configure('bundling'); +GetOptions + ("V" => \$opt_V, "version" => \$opt_V, + "h" => \$opt_h, "help" => \$opt_h, + "H=s" => \$opt_H, "hostname=s" => \$opt_H, + "w=s" => \$opt_w, "warning=s" => \$opt_w, + "c=s" => \$opt_c, "critical=s" => \$opt_c); + +if ($opt_V) { + print_revision($PROGNAME,'$Revision$'); + exit $ERRORS{'OK'}; +} +if ($opt_h) { + print_help(); + exit $ERRORS{'OK'}; +} +if ($opt_w) { + if ($opt_w =~ /(\d+)/) { + $warn = $1; + } else { + usage("Invalid values: $opt_w\n"); + exit $ERRORS{'OK'}; + } +} +if ($opt_c) { + if ($opt_c =~ /(\d+)/) { + $crit = $1; + } else { + usage("Invalid values: $opt_c\n"); + exit $ERRORS{'OK'}; + } +} +($opt_H) || usage("Host name/address not specified\n"); +my $host = $1 if ($opt_H =~ /([-.A-Za-z0-9]+)/); +($host) || usage("Invalid host: $opt_H\n"); + +my $result = `$path_to_ssh -l $remote_user $host '/sbin/pfctl -s info' | $path_to_grep entries`; +chomp $result; +$result =~ /(\d+)/; +$result = $1; + +print "$result PF state entries\n"; + +exit $ERRORS{'CRITICAL'} if ($result >= $crit); +exit $ERRORS{'WARNING'} if ($result >= $warn); +exit $ERRORS{'OK'}; + + +sub print_help { + print_revision($PROGNAME,'$Revision$'); + print "Copyright (c) 2002 Jason Dixon\n\nThis plugin checks the number of state table entries on a PF-enabled OpenBSD system.\n\n"; + print "Usage:\t-H, --hostname=<HOST> [-w, --warning=<WARNING>] [-c, --critical=<CRITICAL>]\n\n\tDefault warning is 50000 and critical is 60000.\n\n"; + support(); +} + |