Kaynağa Gözat

Merge branch 'maint' into master

Bryan Heden 8 yıl önce
ebeveyn
işleme
ea5bb0c416

+ 1 - 0
.gitignore

@@ -4,6 +4,7 @@ cscope.out
 nbproject/
 nbproject/
 .kdev4/
 .kdev4/
 plugins.kdev4
 plugins.kdev4
+plugins.project
 
 
 # In all paths
 # In all paths
 NP-VERSION-FILE
 NP-VERSION-FILE

+ 31 - 0
NEWS

@@ -1,5 +1,35 @@
 This file documents the major additions and syntax changes between releases.
 This file documents the major additions and syntax changes between releases.
 
 
+2.3.0 xxxx-xx-xx
+	ENHANCEMENTS
+	Added directory plugins-python containing three Python plugins
+	check_http: New parameter `--verify-host` will check if -H hostname matches the SSL certificate
+	check_ping: plugin output will now include hostname and IP address
+	check_disk_smb: Add configfile feature
+	check_apt: Add --only-critical switch
+	check_mailq: Add support for opensmtpd
+	check_mailq: Add mailq -C option for config dir or config file
+	check_disk: Add -s option to show status for each path/partition
+	check_mailq.pl: Add option for opensmtpd (brigriffin)
+	check_procs: Add FreeBSD jail support (Mathieu Arnold)
+
+
+2.2.2 xxxx-xx-xx
+	FIXES
+	check_disk: autofs being mounted despite '-l'. Fixed, and also excluded some system "fake" mountpoints
+	check_ntp_time: Periodically returns "Socket timeout" when one of several ntp server doesn't respond
+	check_ntp_time calls `write` on a UDP socket without a successful call to `connect`
+	check_mysql_query & mysql_query: extra-opts causes crash
+	check_log does not check for "-O oldlog"
+	check_log lost ability to use regexes for query (-q) in 2.1.4
+	fix configure.ac for FreeBSD SWAPFORMAT
+	Fix --no-body
+	check_wave produces lots of errors if required arguments are not provided
+	check_disk_smb.pl added additional smb support
+	check_http Additional header/status checking
+	check_http When checking certificate, don't check content/status
+
+
 2.2.1 2017-04-19
 2.2.1 2017-04-19
 	FIXES
 	FIXES
 	check_users: not accepting zero as the threshold
 	check_users: not accepting zero as the threshold
@@ -17,6 +47,7 @@ This file documents the major additions and syntax changes between releases.
 	check_mailq: Nullmailer Regex is not working for Ubuntu 16.04
 	check_mailq: Nullmailer Regex is not working for Ubuntu 16.04
 	check_swap: Downstream Fedora patch: Prevent check_swap from returning OK, if no swap activated
 	check_swap: Downstream Fedora patch: Prevent check_swap from returning OK, if no swap activated
 	Building RPMs on Amazon Linux - Add 'install-root' on line 165 of spec file
 	Building RPMs on Amazon Linux - Add 'install-root' on line 165 of spec file
+	check_http: Memory allocation error
 
 
 
 
 2.2.0 2017-01-19
 2.2.0 2017-01-19

+ 13 - 0
THANKS.in

@@ -18,6 +18,7 @@ Andreas Ericsson
 Andreas Seemueller
 Andreas Seemueller
 Andrew Berglund
 Andrew Berglund
 Andrew Elwell
 Andrew Elwell
+Andrew Penniman
 Andrew Widdersheim
 Andrew Widdersheim
 Andy Brist
 Andy Brist
 Andy Doran
 Andy Doran
@@ -42,6 +43,7 @@ Booker C. Bense
 Bradley Baetz
 Bradley Baetz
 Brian De Wolf
 Brian De Wolf
 Brian Landers
 Brian Landers
+brigriffin
 Bryan Irvine
 Bryan Irvine
 Carlos Canau
 Carlos Canau
 Carole Verdon
 Carole Verdon
@@ -49,16 +51,19 @@ Charles-Henri Larose
 Charlie Cook
 Charlie Cook
 Chester Hosey
 Chester Hosey
 Chris Grim
 Chris Grim
+Chris Heath
 Chris Pepper
 Chris Pepper
 Chris Wilson
 Chris Wilson
 Christian G Warden
 Christian G Warden
 Christian Mies
 Christian Mies
+Christian Schmidt
 Christian Schneemann
 Christian Schneemann
 Christoph Kron
 Christoph Kron
 Christoph Schell
 Christoph Schell
 Christopher Maser
 Christopher Maser
 Christopher Schultz
 Christopher Schultz
 Cire Iriarte
 Cire Iriarte
+Claudio Kuenzler
 Cliff Rice
 Cliff Rice
 Collin Fair
 Collin Fair
 Cove Schneider
 Cove Schneider
@@ -174,6 +179,7 @@ John Rouillard
 John Sivak
 John Sivak
 John Warburton
 John Warburton
 Jon Hallett
 Jon Hallett
+Jon Stockton
 Jon Vandegrift
 Jon Vandegrift
 Jonas Genannt
 Jonas Genannt
 Jonas Genannt
 Jonas Genannt
@@ -200,6 +206,8 @@ Lars Stavholm
 Lars Vogdt
 Lars Vogdt
 Laurent Licour
 Laurent Licour
 Laurent Vaslin
 Laurent Vaslin
+Lee Clemens
+Leonid Vasiliev
 Lionel Cons
 Lionel Cons
 Lonny Selinger
 Lonny Selinger
 Luca Corti
 Luca Corti
@@ -214,6 +222,7 @@ Marco Beck
 Marcos Della
 Marcos Della
 Mario Trangoni
 Mario Trangoni
 Mario Witte
 Mario Witte
+Mark A. Ziesemer
 Mark Favas
 Mark Favas
 Mark Jewiss
 Mark Jewiss
 Mark Keisler
 Mark Keisler
@@ -221,6 +230,7 @@ Markus Baertschi
 Marlo Bell
 Marlo Bell
 Martin Foster
 Martin Foster
 Matej Vela
 Matej Vela
+Mathieu Arnold
 Mathieu Masseboeuf
 Mathieu Masseboeuf
 Matt Garrett
 Matt Garrett
 Matt Perry
 Matt Perry
@@ -244,6 +254,7 @@ Michael Tiernan
 Mikael Falkvidd
 Mikael Falkvidd
 Mike Emigh
 Mike Emigh
 Mike McHenry
 Mike McHenry
+mwennrich
 Myke Place
 Myke Place
 Nathan Shafer
 Nathan Shafer
 Neil Prockter
 Neil Prockter
@@ -344,8 +355,10 @@ StoneISStephan
 Stuart Webster
 Stuart Webster
 Stéphane Bortzmeyer
 Stéphane Bortzmeyer
 Stéphane Urbanovski
 Stéphane Urbanovski
+Subito
 Sven Meyer
 Sven Meyer
 Sven Schaffranneck
 Sven Schaffranneck
+Syl Robataille
 Thomas Nilsen
 Thomas Nilsen
 Thomas Schimpke
 Thomas Schimpke
 Tilman Koschnick
 Tilman Koschnick

+ 24 - 3
configure.ac

@@ -786,6 +786,16 @@ then
 	ac_cv_ps_cols=10
 	ac_cv_ps_cols=10
 	AC_MSG_RESULT([$ac_cv_ps_command])
 	AC_MSG_RESULT([$ac_cv_ps_command])
 
 
+dnl jails on FreeBSD:
+elif ps -axwo 'stat comm vsz rss user uid pid ppid jid args' 2>/dev/null | \
+	egrep -i "^ *STAT +COMMAND +VSZ +RSS +USER +UID +PID +PPID +JID +COMMAND" > /dev/null
+then
+	ac_cv_ps_varlist="procstat,&procuid,&procpid,&procppid,&procjid,&procvsz,&procrss,&procpcpu,procprog,&pos"
+	ac_cv_ps_command="$PATH_TO_PS -axwo 'stat uid pid ppid jid vsz rss pcpu comm args'"
+	ac_cv_ps_format="%s %d %d %d %d %d %d %f %s %n"
+	ac_cv_ps_cols=10
+	AC_MSG_RESULT([$ac_cv_ps_command])
+
 dnl Some gnu/linux systems (debian for one) don't like -axwwo and need axwwo.
 dnl Some gnu/linux systems (debian for one) don't like -axwwo and need axwwo.
 dnl so test for this first...
 dnl so test for this first...
 elif ps axwwo 'stat comm vsz rss user uid pid ppid args' 2>/dev/null | \
 elif ps axwwo 'stat comm vsz rss user uid pid ppid args' 2>/dev/null | \
@@ -1266,7 +1276,7 @@ elif test "x$PATH_TO_PING6" != "x"; then
 	then
 	then
 		with_ping6_command="$PATH_TO_PING6 -n -s 56 -c %d %s"
 		with_ping6_command="$PATH_TO_PING6 -n -s 56 -c %d %s"
 		ac_cv_ping6_packets_first=yes
 		ac_cv_ping6_packets_first=yes
-		AC_MSG_RESULT([$with_ping_command])
+		AC_MSG_RESULT([$with_ping6_command])
 
 
 	elif $PATH_TO_PING6 -n -c 1 ::1 2>/dev/null | \
 	elif $PATH_TO_PING6 -n -c 1 ::1 2>/dev/null | \
 		egrep -i "^round-trip|^rtt" >/dev/null
 		egrep -i "^round-trip|^rtt" >/dev/null
@@ -1329,7 +1339,7 @@ elif test "x$PATH_TO_PING" != "x"; then
 	then
 	then
 		with_ping6_command="$PATH_TO_PING -A inet6 -n -s 56 -c %d %s"
 		with_ping6_command="$PATH_TO_PING -A inet6 -n -s 56 -c %d %s"
 		ac_cv_ping6_packets_first=yes
 		ac_cv_ping6_packets_first=yes
-		AC_MSG_RESULT([$with_ping_command])
+		AC_MSG_RESULT([$with_ping6_command])
 
 
 	elif $PATH_TO_PING -A inet6 -n -c 1 ::1 2>/dev/null | \
 	elif $PATH_TO_PING -A inet6 -n -c 1 ::1 2>/dev/null | \
 		egrep -i "^round-trip|^rtt" >/dev/null
 		egrep -i "^round-trip|^rtt" >/dev/null
@@ -1557,6 +1567,17 @@ else
 	AC_MSG_WARN([Could not find qmail-qstat or equivalent])
 	AC_MSG_WARN([Could not find qmail-qstat or equivalent])
 fi
 fi
 
 
+AC_PATH_PROG(PATH_TO_SMTPCTL,smtpctl)
+AC_ARG_WITH(smtpctl_command,
+            ACX_HELP_STRING([--with-smtpctl-command=PATH],
+                            [sets path to smtpctl]), PATH_TO_SMTPCTL=$withval)
+if test -n "$PATH_TO_SMTPCTL"
+then
+	AC_DEFINE_UNQUOTED(PATH_TO_SMTPCTL,"$PATH_TO_SMTPCTL",[path to smtpctl])
+else
+	AC_MSG_WARN([Could not find smtpctl or equivalent])
+fi
+
 dnl SWAP info required is amount allocated/available and amount free
 dnl SWAP info required is amount allocated/available and amount free
 dnl The plugin works through all the swap devices and adds up the total swap
 dnl The plugin works through all the swap devices and adds up the total swap
 dnl available.
 dnl available.
@@ -1602,7 +1623,7 @@ then
 
 
 	if [$PATH_TO_SWAPINFO -k 2>/dev/null | egrep -i "^Device +1K-blocks +Used +Avail" >/dev/null]
 	if [$PATH_TO_SWAPINFO -k 2>/dev/null | egrep -i "^Device +1K-blocks +Used +Avail" >/dev/null]
 	then
 	then
-		ac_cv_swap_format=["%*s %f %*d %f"]
+		ac_cv_swap_format=["%*s %lf %*d %lf"]
 		ac_cv_swap_conv=1024
 		ac_cv_swap_conv=1024
 		AC_MSG_RESULT([using FreeBSD format swapinfo])
 		AC_MSG_RESULT([using FreeBSD format swapinfo])
 	fi
 	fi

+ 4 - 1
lib/parse_ini.c

@@ -83,6 +83,7 @@ static char* default_file_in_path(void);
  */
  */
 static void parse_locator(const char *locator, const char *def_stanza, np_ini_info *i){
 static void parse_locator(const char *locator, const char *def_stanza, np_ini_info *i){
 	size_t locator_len=0, stanza_len=0;
 	size_t locator_len=0, stanza_len=0;
+	char *dflt = NULL;
 
 
 	/* if locator is NULL we'll use default values */
 	/* if locator is NULL we'll use default values */
 	if(locator){
 	if(locator){
@@ -102,7 +103,9 @@ static void parse_locator(const char *locator, const char *def_stanza, np_ini_in
 	}
 	}
 	/* if there is no @file part */
 	/* if there is no @file part */
 	if(stanza_len==locator_len){
 	if(stanza_len==locator_len){
-		i->file=default_file();
+		dflt=default_file();
+		if (dflt)
+			i->file=strdup(dflt);
 	} else {
 	} else {
 		i->file=strdup(&(locator[stanza_len+1]));
 		i->file=strdup(&(locator[stanza_len+1]));
 	}
 	}

+ 47 - 0
plugins-python/Makefile.am

@@ -0,0 +1,47 @@
+## Process this file with automake to produce Makefile.in
+
+if RELEASE_PRESENT
+NP_VERSION = @NP_RELEASE@
+else
+NP-VERSION-FILE: .FORCE-NP-VERSION-FILE
+	@$(SHELL_PATH) $(top_srcdir)/NP-VERSION-GEN
+.FORCE-NP-VERSION-FILE:
+-include NP-VERSION-FILE
+endif
+
+SUFFIXES = .py .in
+
+VPATH=$(top_srcdir) $(top_srcdir)/plugins-python
+
+libexec_SCRIPTS = check_heartbleed.py  check_imap_login.py check_ncpa.py
+
+EXTRA_DIST=check_heartbleed.in  check_imap_login.in  check_ncpa.in
+
+EDIT = sed \
+  -e 's|[@]NP_VERSION[@]|$(NP_VERSION)|g' \
+  -e 's|[@]TRUSTED_PATH[@]|$(with_trusted_path)|g' \
+  -e 's|[@]PYTHON[@]|$(PYTHON)|g' \
+  -e 's|[@]libexecdir[@]|$(libexecdir)|g'
+
+#TESTS_ENVIRONMENT=perl -I $(top_builddir) -I $(top_srcdir)
+
+#TESTS = @SCRIPT_TEST@
+
+#test:
+#	perl -I $(top_builddir) -I $(top_srcdir) ../test.pl
+#	perl -I $(top_builddir) -I $(top_srcdir) ../test.pl t/utils.t	# utils.t is excluded from above, so manually ask to test
+
+#test-debug:
+#	NPTEST_DEBUG=1 HARNESS_VERBOSE=1 perl -I $(top_builddir) -I $(top_srcdir) ../test.pl
+#	NPTEST_DEBUG=1 HARNESS_VERBOSE=1 perl -I $(top_builddir) -I $(top_srcdir) ../test.pl t/utils.t	# utils.t is excluded from above, so manually ask to test
+
+CLEANFILES=$(libexec_SCRIPTS)
+
+.in.py:
+	@if [ ! "$(PYTHON)" = "missing" ]; then \
+	    $(EDIT) $< > $@; \
+	    chmod +x $@; \
+	fi
+
+clean-local:
+	rm -f NP-VERSION-FILE *.pyc

+ 331 - 0
plugins-python/check_heartbleed.in

@@ -0,0 +1,331 @@
+#!/usr/bin/python2
+
+# Check_Heartbleed.py v0.6
+# 18/4/2014
+
+# Quick and dirty demonstration of CVE-2014-0160 by Jared Stafford (jspenguin@jspenguin.org)
+# The author disclaims copyright to this source code.
+
+# Modified for simplified checking by Yonathan Klijnsma
+
+# Modified to turn into a Nagios Plugin by Scott Wilkerson (swilkerson@nagios.com)
+# Modified to include TLS v1.2, v1.1, v1.0, and SSLv3.0, defaults to 1.1 (sreinhardt@nagios.com)
+# 	Corrected Hello and Heartbeat packets to match versions
+#	Added optional verbose output
+#	Reimplemented output message and added Rich's idea for looping all supported versions
+# Suggested and implemented in another plugin looping of all versions by default (rich.brown@blueberryhillsoftware.com)
+
+import sys
+import struct
+import socket
+import time
+import select
+import re
+from optparse import OptionParser
+
+options = OptionParser(usage='%prog server [options]', description='Test for SSL heartbeat vulnerability (CVE-2014-0160)')
+options.add_option('-H', '--host', type='string', default='127.0.0.1', help='Host to connect to (default: 127.0.0.1)')
+options.add_option('-p', '--port', type='int', default=443, help='TCP port to test (default: 443)')
+options.add_option('-v', '--version', type='int', default=-1, help='TLS or SSL version to test [TLSv1.0(0), TLSv1.1(1), TLSv1.2(2), or SSLv3.0(3)] (default: all)')
+options.add_option('-u', '--udp', default=False, action='store_true', help='Use TCP or UDP protocols, no arguments needed. This does not work presently, keep to TCP. (default: TCP)')
+options.add_option('-t', '--timeout', type='int', default=10, help='Plugin timeout length (default: 10)')
+options.add_option('-V', '--verbose', default=False, action='store_true', help='Print verbose output, including hexdumps of packets.')
+
+def h2bin(x):
+    return x.replace(' ', '').replace('\n', '').decode('hex')
+
+# Returns correct versioning for handshake and hb packets
+def tls_ver ():
+    global opts
+    if opts.version == 0:    #TLSv1.0
+        return '''03 01'''
+    elif opts.version == 2:    #TLSv1.2
+        return '''03 03'''
+    elif opts.version == 3:    #SSLv3.0
+        return '''03 00'''
+    else:                    #TLSv1.1
+        return '''03 02'''
+
+# Builds hello packet with correct tls version for rest of connection
+def build_hello():
+
+    hello = h2bin('''
+    16 ''' + tls_ver() + ''' 00  dc 01 00 00 d8 ''' + tls_ver() + ''' 53
+    4e d0 57 9d 9b 72 0b bc  0c bc 2b 92 a8 48 97 cf
+    bd 39 04 cc 16 0a 85 03  90 9f 77 04 33 d4 de 00
+    00 66 c0 14 c0 0a c0 22  c0 21 00 39 00 38 00 88
+    00 87 c0 0f c0 05 00 35  00 84 c0 12 c0 08 c0 1c
+    c0 1b 00 16 00 13 c0 0d  c0 03 00 0a c0 13 c0 09
+    c0 1f c0 1e 00 33 00 32  00 9a 00 99 00 45 00 44
+    c0 0e c0 04 00 2f 00 96  00 41 c0 11 c0 07 c0 0c
+    c0 02 00 05 00 04 00 15  00 12 00 09 00 14 00 11
+    00 08 00 06 00 03 00 ff  01 00 00 49 00 0b 00 04
+    03 00 01 02 00 0a 00 34  00 32 00 0e 00 0d 00 19
+    00 0b 00 0c 00 18 00 09  00 0a 00 16 00 17 00 08
+    00 06 00 07 00 14 00 15  00 04 00 05 00 12 00 13
+    00 01 00 02 00 03 00 0f  00 10 00 11 00 23 00 00
+    00 0f 00 01 01                                  
+    ''')
+
+##### Hello Packet Layout #####
+#	16													# initiate handshake
+#	+ tls_ver() +  										# version of tls to use
+#	00  dc 												# Length
+#	01 													# Handshake type (hello)
+#	00 00 d8 											# Length
+#	+ tls_ver() +  										# version of tls to use
+#	53 43 5b 90 										# timestamp (change?)
+#	9d 9b 72 0b bc  0c bc 2b 92 a8 48 97 cf				# random bytes (seriously!)
+#   bd 39 04 cc 16 0a 85 03  90 9f 77 04 33 d4 de 		# random bytes (seriously!)
+#	00													# Length of session id (start new session)
+#   00 66 												# Length of ciphers supported list
+#	c0 14 c0 0a c0 22  c0 21 00 39 00 38 00 88			# 2 byte list of supported ciphers
+#   00 87 c0 0f c0 05 00 35  00 84 c0 12 c0 08 c0 1c	# 2 byte list of supported ciphers cont
+#   c0 1b 00 16 00 13 c0 0d  c0 03 00 0a c0 13 c0 09	# 2 byte list of supported ciphers cont
+#   c0 1f c0 1e 00 33 00 32  00 9a 00 99 00 45 00 44	# 2 byte list of supported ciphers cont
+#   c0 0e c0 04 00 2f 00 96  00 41 c0 11 c0 07 c0 0c	# 2 byte list of supported ciphers cont
+#   c0 02 00 05 00 04 00 15  00 12 00 09 00 14 00 11	# 2 byte list of supported ciphers cont
+#   00 08 00 06 00 03 00 ff  							# 2 byte list of supported ciphers cont
+#	01 													# Length of compression methods
+#	00 													# Null compression (none)
+#	00 49												# Length of TLS extension list
+#	00 0b 00 04 03 00 01 02								# Elliptic curve point formats extension
+#	00 0a 00 34  00 32 00 0e 00 0d 00 19				# Elliptic curve
+#   00 0b 00 0c 00 18 00 09  00 0a 00 16 00 17 00 08	# Elliptic curve cont
+#   00 06 00 07 00 14 00 15  00 04 00 05 00 12 00 13	# Elliptic curve cont
+#   00 01 00 02 00 03 00 0f  00 10 00 11				# Elliptic curve cont
+#	00 23 00 00											# TLS sessions ticket supported
+#   00 0f 00 01 01										# Heartbeat extension
+##### End Hello Packet #####
+
+    return hello
+
+# Builds and returns heartbleed packet that matches with tls version
+def build_hb():
+
+    hb = h2bin('''
+    18 ''' + tls_ver() + ''' 00 03
+    01 40 00
+    ''')
+
+##### Heartbleed Packet Layout #####
+#   18													# TLS Record Type (heartbeat) 
+#	+ tls_ver() + 										# TLS version
+#	00 03												# Length
+#   01 													# Heartbeat request
+#	40 00												# Length (16384 bytes)
+##### End Heartbleed Packet #####
+    
+    return hb
+
+# Builds and sends hb packet with zero size
+def build_empty_hb():
+
+    hb = h2bin('''
+    18 ''' + tls_ver() + ''' 00 03
+    01 00 00
+    ''')
+
+##### Heartbleed Packet Layout #####
+#   18													# TLS Record Type (heartbeat) 
+#	+ tls_ver() + 										# TLS version
+#	00 03												# Length
+#   01 													# Heartbeat request
+#	40 00												# Length (16384 bytes)
+##### End Heartbleed Packet #####
+    
+    return hb
+
+# Receives data from socket for specified length
+def recvall(s, length):
+    global opts
+    endtime = time.time() + opts.timeout
+    rdata = ''
+    remain = length
+
+    while remain > 0:
+        rtime = endtime - time.time() 
+        if rtime < 0:
+            return None
+        r, w, e = select.select([s], [], [], 5)
+        if s in r:
+            try:
+                data = s.recv(remain)
+            except socket.error:
+                # Should this be OK, as the server has sent a rst most likely and is therefore likely patched?
+                print 'UNKNOWN: Server ' + opts.host + ' closed connection after sending heartbeat. Likely the server has been patched.'
+                sys.exit(3)
+            # EOF?
+            if not data:
+                return None
+            rdata += data
+            remain -= len(data)
+    return rdata
+        
+# Receives messages and handles accordingly
+def recvmsg(s):
+    global opts
+    hdr = recvall(s, 5)
+    if hdr is None:
+        return None, None, None
+    typ, ver, ln = struct.unpack('>BHH', hdr)
+    pay = recvall(s, ln)
+    if pay is None:
+        return None, None, None
+    if opts.verbose == True:
+        print ' ... received message: type = %d, ver = %04x, length = %d, pay = %02x' % (typ, ver, len(pay), ord(pay[0]))
+    return typ, ver, pay
+
+# Sends empty hb packet
+def hit_hb(s, hb):
+    global opts
+
+    if opts.verbose == True:
+       print 'Sending malformed heartbeat packet...'
+
+    try:
+        s.send(hb)
+    except socket.error:
+        print 'UNKNOWN: Error sending heartbeat to ' + opts.host
+        sys.exit(3)
+
+    while True:
+        typ, ver, pay = recvmsg(s)
+        if typ == None:
+            returncode = 0
+            break
+
+        if typ == 24:
+            if pay > 3:
+                returncode = 2    # vulnerable
+                break
+            else:
+                returncode = 0
+                break
+
+        if typ == 21:    # TLS mismatch, hopefully we don't find this
+            returncode = 0
+            break
+
+    #Outside of while
+    if returncode == 0: # Not vulnerable message
+        if opts.version == 3: #respond with ssl instead of tls
+            message = 'SSLv3.0 is not vulnerable. '
+        else:
+            message = 'TLSv1.' + str(opts.version) + ' is not vulnerable. '
+    else: # vulnerable message
+        if opts.version == 3: #respond with ssl instead of tls
+            message = 'SSLv3.0 is vulnerable. '
+        else:
+            message = 'TLSv1.' + str(opts.version) + ' is vulnerable. '
+
+    return returncode, message
+
+# Prints nagios style output and exit codes
+def print_output(exitcode, outputmessage):
+
+    if exitcode == 2:
+        print 'CRITICAL: Server ' + opts.host + ' ' + outputmessage
+    else:
+        print 'OK: Server ' + opts.host + ' ' + outputmessage
+
+    sys.exit(exitcode)
+
+# Outputs packets as hex, used for verbose output
+def hexdump(s):
+
+    for b in xrange(0, len(s), 16):
+        lin = [c for c in s[b : b + 16]]
+        hxdat = ' '.join('%02X' % ord(c) for c in lin)
+        pdat = ''
+        for c in lin:
+            if 32 <= ord(c) <= 126:
+                pdat += c
+            else:
+                pdat += '.'
+        print '  %04x: %-48s %s' % (b, hxdat, pdat)
+    print
+
+# Initiates connection and handles initial hello\hb sending
+def connect(hb):
+    global opts
+ 
+    if opts.udp == True:
+        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    else:
+        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    
+    s.settimeout(opts.timeout)
+
+    try: 
+        s.connect((opts.host, opts.port))
+    except socket.error:
+        print 'UNKNOWN: Connecton to server ' + opts.host + ' could not be established.'
+        sys.exit(3)
+
+    hello = build_hello()
+
+    if opts.verbose == True:
+        print 'Sending hello packet...'
+
+    try:
+        s.send(hello)
+    except socket.error:
+        print 'UNKNOWN: Error sending hello to ' + opts.host
+        sys.exit(3)
+
+    while True:
+        typ, ver, pay = recvmsg(s)
+        if typ == None:
+            print 'UNKNOWN: Server ' + opts.host + ' closed connection without sending Server Hello.'
+            sys.exit(3)
+        # Look for server hello done message.
+        if typ == 22 and ord(pay[0]) == 0x0E:
+            if opts.verbose == True:
+                hexdump(pay)
+            break
+        else:
+            if opts.verbose == True:
+                hexdump(pay)
+            continue
+
+    if opts.verbose == True:
+        print 'Sending malformed heartbeat packet...'
+
+    try:
+        s.send(hb)
+    except socket.error:
+        print 'UNKNOWN: Error sending heartbeat to ' + opts.host
+        sys.exit(3)
+
+    return s
+
+def main():
+    global opts
+    opts, args = options.parse_args()
+    exitcode = 0
+    outputmessage = ''
+
+    if opts.version == -1: # no version was specified, loop.
+
+        if opts.verbose == True:
+            print 'Checking all supported TLS and SSL versions.'
+
+        for opts.version in [0, 1, 2, 3]:
+            hb = build_hb()
+            s = connect(hb)
+            returncode, message = hit_hb(s, hb)
+
+            if returncode > exitcode:
+                exitcode = returncode
+            outputmessage += message
+            
+    else: # version was specified
+        hb = build_hb()
+        s = connect(hb)
+        exitcode, outputmessage = hit_hb(s, hb)
+
+    print_output(exitcode, outputmessage)
+
+if __name__ == '__main__':
+    main()

+ 61 - 0
plugins-python/check_imap_login.in

@@ -0,0 +1,61 @@
+#!/usr/bin/python
+# vi:si:et:sw=4:sts=4:ts=4
+# -*- coding: UTF-8 -*-
+# -*- Mode: Python -*-
+#
+# Copyright (C) 2005 Bertera Pietro <pietro@bertera.it>
+
+# This file may be distributed and/or modified under the terms of
+# the GNU General Public License version 2 as published by
+# the Free Software Foundation.
+# This file is distributed without any warranty; without even the implied
+# warranty of merchantability or fitness for a particular purpose.
+# See "LICENSE.GPL" in the source distribution for more information.
+
+import sys, os, imaplib, getopt
+
+def usage():
+    print "-u <user>"
+    print "-p <password>"
+    print "-s use SSL"
+    print "-H <host>"
+
+def main():
+	try:
+	    opts, args = getopt.getopt(sys.argv[1:], "u:p:sH:")	
+    except getopt.GetoptError:
+        usage()
+        return 3
+    
+    user = host = password = use_ssl = None
+    
+    for o, a in opts:
+        if o == "-u":
+            user = a
+        elif o == "-p":
+            password = a
+        elif o == "-s":
+            use_ssl = True
+        elif o == "-H":
+            host = a  
+    if user == None or password == None or host == None:
+        usage()
+        return 1
+    
+    if use_ssl:
+        M = imaplib.IMAP4_SSL(host=host)
+    else:
+    	M = imaplib.IMAP4(host)
+    
+    try:	
+        M.login(user, password)
+	except Exception, e:
+        print "CRITICAL: IMAP Login not Successful: %s" % e
+        sys.exit(2)
+    
+    M.logout()
+    print "OK IMAP Login Successful"
+    return 0
+
+if __name__ == "__main__":
+        sys.exit(main())

+ 300 - 0
plugins-python/check_ncpa.in

@@ -0,0 +1,300 @@
+#!@PYTHON@
+"""
+SYNOPSIS
+
+
+"""
+import sys
+import optparse
+import traceback
+import ssl
+
+# Python 2/3 Compatibility imports
+
+try:
+    import json
+except ImportError:
+    import simplejson as json
+
+try:
+    import urllib.request
+    import urllib.parse
+    import urllib.error
+except ImportError:
+    import urllib2
+    import urllib
+
+try:
+    urlencode = urllib.parse.urlencode
+except AttributeError:
+    urlencode = urllib.urlencode
+
+try:
+    urlopen = urllib.request.urlopen
+except AttributeError:
+    urlopen = urllib2.urlopen
+
+try:
+    urlquote = urllib.parse.quote
+except AttributeError:
+    urlquote = urllib.quote
+
+import shlex
+import re
+import signal
+
+__VERSION__ = '1.1.0'
+
+def pretty(d, indent=0, indenter=' ' * 4):
+    info_str = ''
+    for key, value in list(d.items()):
+        info_str += indenter * indent + str(key)
+        if isinstance(value, dict):
+            info_str += '/\n'
+            info_str += pretty(value, indent + 1, indenter)
+        else:
+            info_str += ': ' + str(value) + '\n'
+    return info_str
+
+
+def parse_args():
+    version = 'check_ncpa.py, Version %s' % __VERSION__
+
+    parser = optparse.OptionParser()
+    parser.add_option("-H", "--hostname", help="The hostname to be connected to.")
+    parser.add_option("-M", "--metric", default='',
+                      help="The metric to check, this is defined on client "
+                           "system. This would also be the plugin name in the "
+                           "plugins directory. Do not attach arguments to it, "
+                           "use the -a directive for that. DO NOT INCLUDE the api/ "
+                           "instruction.")
+    parser.add_option("-P", "--port", default=5693, type="int",
+                      help="Port to use to connect to the client.")
+    parser.add_option("-w", "--warning", default=None, type="str",
+                      help="Warning value to be passed for the check.")
+    parser.add_option("-c", "--critical", default=None, type="str",
+                      help="Critical value to be passed for the check.")
+    parser.add_option("-u", "--units", default=None,
+                      help="The unit prefix (k, Ki, M, Mi, G, Gi, T, Ti) for b and B unit "
+                           "types which calculates the value returned.")
+    parser.add_option("-n", "--unit", default=None,
+                      help="Overrides the unit with whatever unit you define. "
+                           "Does not perform calculations. This changes the unit of measurement only.")
+    parser.add_option("-a", "--arguments", default=None,
+                      help="Arguments for the plugin to be run. Not necessary "
+                           "unless you're running a custom plugin. Given in the same "
+                           "as you would call from the command line. Example: -a '-w 10 -c 20 -f /usr/local'")
+    parser.add_option("-t", "--token", default='',
+                      help="The token for connecting.")
+    parser.add_option("-T", "--timeout", default=60, type="int",
+                      help="Enforced timeout, will terminate plugins after "
+                           "this amount of seconds. [%default]")
+    parser.add_option("-d", "--delta", action='store_true',
+                      help="Signals that this check is a delta check and a "
+                           "local state will kept.")
+    parser.add_option("-l", "--list", action='store_true',
+                      help="List all values under a given node. Do not perform "
+                           "a check.")
+    parser.add_option("-v", "--verbose", action='store_true',
+                      help='Print more verbose error messages.')
+    parser.add_option("-D", "--debug", action='store_true',
+                      help='Print LOTS of error messages. Used mostly for debugging.')
+    parser.add_option("-V", "--version", action='store_true',
+                      help='Print version number of plugin.')
+    parser.add_option("-q", "--queryargs", default=None,
+                      help='Extra query arguments to pass in the NCPA URL.')
+    parser.add_option("-s", "--secure", action='store_true', default=False,
+                      help='Require successful certificate verification. Does not work on Python < 2.7.9.')
+    parser.add_option("-p", "--performance", action='store_true', default=False,
+                      help='Print performance data even when there is none. '
+                           'Will print data matching the return code of this script')
+    options, _ = parser.parse_args()
+
+    if options.version:
+        print(version)
+        sys.exit(0)
+
+    if options.arguments and options.metric and not 'plugin' in options.metric:
+        parser.print_help()
+        parser.error('You cannot specify arguments without running a custom plugin.')
+
+    if not options.hostname:
+        parser.print_help()
+        parser.error("Hostname is required for use.")
+
+    elif not options.metric and not options.list:
+        parser.print_help()
+        parser.error('No metric given, if you want to list all possible items '
+                     'use --list.')
+
+    options.metric = re.sub(r'^/?(api/)?', '', options.metric)
+
+    return options
+
+
+# ~ The following are all helper functions. I would normally split these out into
+# ~ a new module but this needs to be portable.
+
+
+def get_url_from_options(options):
+    host_part = get_host_part_from_options(options)
+    arguments = get_arguments_from_options(options)
+    return '%s?%s' % (host_part, arguments)
+
+
+def get_host_part_from_options(options):
+    """Gets the address that will be queries for the JSON.
+
+    """
+    hostname = options.hostname
+    port = options.port
+
+    if not options.metric is None:
+        metric = urlquote(options.metric)
+    else:
+        metric = ''
+
+    arguments = get_check_arguments_from_options(options)
+    if not metric and not arguments:
+        api_address = 'https://%s:%d/api' % (hostname, port)
+    else:
+        api_address = 'https://%s:%d/api/%s/%s' % (hostname, port, metric, arguments)
+
+    return api_address
+
+
+def get_check_arguments_from_options(options):
+    """Gets the escaped URL for plugin arguments to be added
+    to the end of the host URL. This is different from the get_arguments_from_options
+    in that this is meant for the syntax when the user is calling a check, whereas the below
+    is when GET arguments need to be added.
+
+    """
+    arguments = options.arguments
+    if arguments is None:
+        return ''
+    else:
+        lex = shlex.shlex(arguments)
+        lex.whitespace_split = True
+        arguments = '/'.join([urlquote(x, safe='') for x in lex])
+        return arguments
+
+
+def get_arguments_from_options(options, **kwargs):
+    """Returns the http query arguments. If there is a list variable specified,
+    it will return the arguments necessary to query for a list.
+
+    """
+
+    # Note: Changed back to units due to the units being what is passed via the
+    # API call which can confuse people if they don't match
+    arguments = { 'token': options.token,
+                  'units': options.units }
+    
+    if not options.list:
+        arguments['warning'] = options.warning
+        arguments['critical'] = options.critical
+        arguments['delta'] = options.delta
+        arguments['check'] = 1
+        arguments['unit'] = options.unit
+
+    if options.queryargs:
+        for argument in options.queryargs.split(','):
+            key, value = argument.split('=')
+            arguments[key] = value
+
+    #~ Encode the items in the dictionary that are not None
+    return urlencode(dict((k, v) for k, v in list(arguments.items()) if v is not None))
+
+
+def get_json(options):
+    """Get the page given by the options. This will call down the url and
+    encode its finding into a Python object (from JSON).
+
+    """
+    url = get_url_from_options(options)
+
+    if options.verbose:
+        print('Connecting to: ' + url)
+
+    try:
+        ctx = ssl.create_default_context()
+        if not options.secure:
+            ctx.check_hostname = False
+            ctx.verify_mode = ssl.CERT_NONE
+        ret = urlopen(url, context=ctx)
+    except AttributeError:
+        ret = urlopen(url)
+
+    ret = ''.join(ret)
+
+    if options.verbose:
+        print('File returned contained:\n' + ret)
+
+    arr = json.loads(ret)
+
+    if 'value' in arr:
+        return arr['value']
+
+    return arr
+
+
+def run_check(info_json):
+    """Run a check against the remote host.
+
+    """
+    return info_json['stdout'], info_json['returncode']
+
+
+def show_list(info_json):
+    """Show the list of available options.
+
+    """
+    return pretty(info_json), 0
+
+
+def timeout_handler(threshold):
+    def wrapped(signum, frames):
+        stdout = "UNKNOWN: Execution exceeded timeout threshold of %ds" % threshold
+        print stdout
+        sys.exit(3)
+    return wrapped
+
+
+def main():
+    options = parse_args()
+
+    # We need to ensure that we will only execute for a certain amount of
+    # seconds.
+    signal.signal(signal.SIGALRM, timeout_handler(options.timeout))
+    signal.alarm(options.timeout)
+
+    try:
+
+        if options.version:
+            stdout = 'The version of this plugin is %s' % __VERSION__
+            return stdout, 0
+
+        info_json = get_json(options)
+        if options.list:
+            return show_list(info_json)
+        else:
+            stdout, returncode = run_check(info_json)
+            if options.performance and stdout.find("|") == -1:
+                performance = " | 'status'={};1;2;".format(returncode)
+                return "{}{}".format(stdout, performance), returncode
+            else:
+                return stdout, returncode
+    except Exception, e:
+        if options.debug:
+            return 'The stack trace:' + traceback.format_exc(), 3
+        elif options.verbose:
+            return 'An error occurred:' + str(e), 3
+        else:
+            return 'UNKNOWN: Error occurred while running the plugin. Use the verbose flag for more details.', 3
+
+
+if __name__ == "__main__":
+    stdout, returncode = main()
+    print(stdout)
+    sys.exit(returncode)

+ 19 - 6
plugins-scripts/check_disk_smb.pl

@@ -22,7 +22,7 @@ require 5.004;
 use POSIX;
 use POSIX;
 use strict;
 use strict;
 use Getopt::Long;
 use Getopt::Long;
-use vars qw($opt_P $opt_V $opt_h $opt_H $opt_k $opt_s $opt_W $opt_u $opt_p $opt_w $opt_c $opt_a $verbose);
+use vars qw($opt_P $opt_V $opt_m $opt_h $opt_H $opt_k $opt_s $opt_W $opt_u $opt_p $opt_w $opt_c $opt_a $opt_C $verbose);
 use vars qw($PROGNAME);
 use vars qw($PROGNAME);
 use FindBin;
 use FindBin;
 use lib "$FindBin::Bin";
 use lib "$FindBin::Bin";
@@ -45,6 +45,7 @@ GetOptions
 	 "V"   => \$opt_V, "version"    => \$opt_V,
 	 "V"   => \$opt_V, "version"    => \$opt_V,
 	 "h"   => \$opt_h, "help"       => \$opt_h,
 	 "h"   => \$opt_h, "help"       => \$opt_h,
 	 "k"   => \$opt_k, "kerberos"   => \$opt_k,
 	 "k"   => \$opt_k, "kerberos"   => \$opt_k,
+	 "m=s" => \$opt_m, "maxprotocol=s" => \$opt_m,
 	 "w=s" => \$opt_w, "warning=s"  => \$opt_w,
 	 "w=s" => \$opt_w, "warning=s"  => \$opt_w,
 	 "c=s" => \$opt_c, "critical=s" => \$opt_c,
 	 "c=s" => \$opt_c, "critical=s" => \$opt_c,
 	 "p=s" => \$opt_p, "password=s" => \$opt_p,
 	 "p=s" => \$opt_p, "password=s" => \$opt_p,
@@ -52,7 +53,8 @@ GetOptions
 	 "s=s" => \$opt_s, "share=s"    => \$opt_s,
 	 "s=s" => \$opt_s, "share=s"    => \$opt_s,
 	 "W=s" => \$opt_W, "workgroup=s" => \$opt_W,
 	 "W=s" => \$opt_W, "workgroup=s" => \$opt_W,
 	 "H=s" => \$opt_H, "hostname=s" => \$opt_H,
 	 "H=s" => \$opt_H, "hostname=s" => \$opt_H,
-	 "a=s" => \$opt_a, "address=s" => \$opt_a);
+	 "a=s" => \$opt_a, "address=s" => \$opt_a,
+	 "C=s" => \$opt_C, "configfile=s" => \$opt_C);
 
 
 if ($opt_V) {
 if ($opt_V) {
 	print_revision($PROGNAME,'@NP_VERSION@'); #'
 	print_revision($PROGNAME,'@NP_VERSION@'); #'
@@ -82,6 +84,9 @@ defined($user) || usage("Invalid user: $opt_u\n");
 defined($opt_p) || ($opt_p = shift @ARGV) || ($opt_p = "");
 defined($opt_p) || ($opt_p = shift @ARGV) || ($opt_p = "");
 my $pass = $1 if ($opt_p =~ /(.*)/);
 my $pass = $1 if ($opt_p =~ /(.*)/);
 
 
+defined($opt_m) || ($opt_m = shift @ARGV) || ($opt_m = "");
+my $maxprotocol = $1 if ($opt_m =~ /(.*)/);
+
 ($opt_w) || ($opt_w = shift @ARGV) || ($opt_w = 85);
 ($opt_w) || ($opt_w = shift @ARGV) || ($opt_w = 85);
 my $warn = $1 if ($opt_w =~ /^([0-9]{1,2}\%?|100\%?|[0-9]+[kMG])$/);
 my $warn = $1 if ($opt_w =~ /^([0-9]{1,2}\%?|100\%?|[0-9]+[kMG])$/);
 ($warn) || usage("Invalid warning threshold: $opt_w\n");
 ($warn) || usage("Invalid warning threshold: $opt_w\n");
@@ -90,6 +95,10 @@ my $warn = $1 if ($opt_w =~ /^([0-9]{1,2}\%?|100\%?|[0-9]+[kMG])$/);
 my $crit = $1 if ($opt_c =~ /^([0-9]{1,2}\%?|100\%?|[0-9]+[kMG])$/);
 my $crit = $1 if ($opt_c =~ /^([0-9]{1,2}\%?|100\%?|[0-9]+[kMG])$/);
 ($crit) || usage("Invalid critical threshold: $opt_c\n");
 ($crit) || usage("Invalid critical threshold: $opt_c\n");
 
 
+($opt_C) || ($opt_C = shift @ARGV) || ($opt_C = "");
+my $configfile = $opt_C if ($opt_C);
+usage("Unable to read config file $configfile\n") if ($configfile) && (! -r $configfile);
+
 # Execute the given command line and return anything it writes to STDOUT and/or
 # Execute the given command line and return anything it writes to STDOUT and/or
 # STDERR.  (This might be useful for other plugins, too, so it should possibly
 # STDERR.  (This might be useful for other plugins, too, so it should possibly
 # be moved to utils.pm.)
 # be moved to utils.pm.)
@@ -187,10 +196,12 @@ my @cmd = (
 	$smbclient,
 	$smbclient,
 	"//$host/$share",
 	"//$host/$share",
 	"-U", "$user%$pass",
 	"-U", "$user%$pass",
+	defined($maxprotocol) ? ("-m", $maxprotocol) : (),
 	defined($workgroup) ? ("-W", $workgroup) : (),
 	defined($workgroup) ? ("-W", $workgroup) : (),
 	defined($address) ? ("-I", $address) : (),
 	defined($address) ? ("-I", $address) : (),
 	defined($opt_P) ? ("-p", $opt_P) : (),
 	defined($opt_P) ? ("-p", $opt_P) : (),
 	defined($opt_k) ? ("-k") : (),
 	defined($opt_k) ? ("-k") : (),
+	defined($configfile) ? ("-s, $configfile") : (),
 	"-c", "du"
 	"-c", "du"
 );
 );
 
 
@@ -289,8 +300,9 @@ print "$state\n" if ($verbose);
 exit $ERRORS{$state};
 exit $ERRORS{$state};
 
 
 sub print_usage () {
 sub print_usage () {
-	print "Usage: $PROGNAME -H <host> -s <share> -u <user> -p <password> 
-      -w <warn> -c <crit> [-W <workgroup>] [-P <port>] [-a <IP>]\n";
+	print "Usage: $PROGNAME -H <host> -s <share> -u <user> 
+      -p <password> -w <warn> -c <crit> [-W <workgroup>] [-P <port>] 
+      [-a <IP>] [-C <configfile>]\n";
 }
 }
 
 
 sub print_help () {
 sub print_help () {
@@ -316,12 +328,13 @@ Perl Check SMB Disk plugin for Nagios
    Password to log in to server. (Defaults to an empty password)
    Password to log in to server. (Defaults to an empty password)
 -w, --warning=INTEGER or INTEGER[kMG]
 -w, --warning=INTEGER or INTEGER[kMG]
    Percent of used space at which a warning will be generated (Default: 85%)
    Percent of used space at which a warning will be generated (Default: 85%)
-      
 -c, --critical=INTEGER or INTEGER[kMG]
 -c, --critical=INTEGER or INTEGER[kMG]
    Percent of used space at which a critical will be generated (Defaults: 95%)
    Percent of used space at which a critical will be generated (Defaults: 95%)
 -P, --port=INTEGER
 -P, --port=INTEGER
    Port to be used to connect to. Some Windows boxes use 139, others 445 (Defaults to smbclient default)
    Port to be used to connect to. Some Windows boxes use 139, others 445 (Defaults to smbclient default)
-   
+-C, --configfile=STRING
+   Path to configfile which should be used by smbclient (Defaults to smb.conf of your smb installation)
+
    If thresholds are followed by either a k, M, or G then check to see if that
    If thresholds are followed by either a k, M, or G then check to see if that
    much disk space is available (kilobytes, Megabytes, Gigabytes)
    much disk space is available (kilobytes, Megabytes, Gigabytes)
 
 

+ 12 - 2
plugins-scripts/check_log.sh

@@ -169,6 +169,16 @@ while test -n "$1"; do
     shift
     shift
 done
 done
 
 
+if [ "$oldlog" = "" ]; then
+	echo "Log check error: You must supply an Old Log File name using '-O'!"
+	exit "$STATE_UNKNOWN"
+fi
+rc=`echo "$oldlog" | grep -q -- "^-"; echo $?`
+if [ $rc -eq 0 ]; then
+	echo "Log check error: You must supply an Old Log File name using '-O'!"
+	exit "$STATE_UNKNOWN"
+fi
+
 # If the source log file doesn't exist, exit
 # If the source log file doesn't exist, exit
 
 
 if [ ! -e "$logfile" ]; then
 if [ ! -e "$logfile" ]; then
@@ -205,10 +215,10 @@ fi
 diff "$logfile" "$oldlog" | grep -v "^>" > "$tempdiff"
 diff "$logfile" "$oldlog" | grep -v "^>" > "$tempdiff"
 
 
 # Count the number of matching log entries we have
 # Count the number of matching log entries we have
-count=$(grep -c "$query" "$tempdiff")
+count=$(egrep -c "$query" "$tempdiff")
 
 
 # Get the last matching entry in the diff file
 # Get the last matching entry in the diff file
-lastentry=$(grep "$query" "$tempdiff" | tail -1)
+lastentry=$(egrep "$query" "$tempdiff" | tail -1)
 
 
 rm -f "$tempdiff"
 rm -f "$tempdiff"
 cat "$logfile" > "$oldlog"
 cat "$logfile" > "$oldlog"

+ 98 - 14
plugins-scripts/check_mailq.pl

@@ -28,9 +28,9 @@
 use POSIX;
 use POSIX;
 use strict;
 use strict;
 use Getopt::Long;
 use Getopt::Long;
-use vars qw($opt_V $opt_h $opt_v $verbose $PROGNAME $opt_w $opt_c $opt_t $opt_s
-					$opt_M $mailq $status $state $msg $msg_q $msg_p $opt_W $opt_C $mailq @lines
-					%srcdomains %dstdomains);
+use vars qw($opt_V $opt_h $opt_v $verbose $PROGNAME $opt_w $opt_c $opt_t $opt_s $opt_d
+					$opt_M $mailq $status $state $msg $msg_q $msg_p $opt_W $opt_C $mailq $mailq_args
+					@lines %srcdomains %dstdomains);
 use FindBin;
 use FindBin;
 use lib "$FindBin::Bin";
 use lib "$FindBin::Bin";
 use lib '@libexecdir@';
 use lib '@libexecdir@';
@@ -49,6 +49,8 @@ $PROGNAME = "check_mailq";
 $mailq = 'sendmail';	# default
 $mailq = 'sendmail';	# default
 $msg_q = 0 ;
 $msg_q = 0 ;
 $msg_p = 0 ;
 $msg_p = 0 ;
+# If appended, must start with a space
+$mailq_args = '' ;
 $state = $ERRORS{'UNKNOWN'};
 $state = $ERRORS{'UNKNOWN'};
 
 
 Getopt::Long::Configure('bundling');
 Getopt::Long::Configure('bundling');
@@ -58,6 +60,10 @@ if ($status){
 	exit $ERRORS{"UNKNOWN"};
 	exit $ERRORS{"UNKNOWN"};
 }
 }
 
 
+if ($opt_d) {
+	$mailq_args = $mailq_args . ' -C ' . $opt_d;
+}
+
 if ($opt_s) {
 if ($opt_s) {
 	if ($utils::PATH_TO_SUDO ne "") {
 	if ($utils::PATH_TO_SUDO ne "") {
 		if (-x $utils::PATH_TO_SUDO) {
 		if (-x $utils::PATH_TO_SUDO) {
@@ -313,19 +319,19 @@ elsif ( $mailq eq "postfix" ) {
      ## open mailq
      ## open mailq
 	if ( defined $utils::PATH_TO_MAILQ ) {
 	if ( defined $utils::PATH_TO_MAILQ ) {
 		if (-x $utils::PATH_TO_MAILQ) {
 		if (-x $utils::PATH_TO_MAILQ) {
-			if (! open (MAILQ, "$utils::PATH_TO_MAILQ | ")) {
-				print "ERROR: $utils::PATH_TO_MAILQ returned an error\n";
+			if (! open (MAILQ, "$utils::PATH_TO_MAILQ$mailq_args | ")) {
+				print "ERROR: $utils::PATH_TO_MAILQ$mailq_args returned an error\n";
 				exit $ERRORS{'UNKNOWN'};
 				exit $ERRORS{'UNKNOWN'};
 			}
 			}
 		}
 		}
 		else {
 		else {
 			if ( $sudo ne "" ) {
 			if ( $sudo ne "" ) {
-				if (! open (MAILQ, "$sudo $utils::PATH_TO_MAILQ | " ) ) {
-					print "ERROR: $utils::PATH_TO_MAILQ is not executable with sudo by (uid $>:gid($)))\n";
+				if (! open (MAILQ, "$sudo $utils::PATH_TO_MAILQ$mailq_args | " ) ) {
+					print "ERROR: $utils::PATH_TO_MAILQ$mailq_args is not executable with sudo by (uid $>:gid($)))\n";
 					exit $ERRORS{'UNKNOWN'};
 					exit $ERRORS{'UNKNOWN'};
 				}
 				}
 			} else {
 			} else {
-				print "ERROR: $utils::PATH_TO_MAILQ is not executable by (uid $>:gid($))) and sudo is not set in utils.pm\n";
+				print "ERROR: $utils::PATH_TO_MAILQ$mailq_args is not executable by (uid $>:gid($))) and sudo is not set in utils.pm\n";
 				exit $ERRORS{'UNKNOWN'};
 				exit $ERRORS{'UNKNOWN'};
 			}
 			}
 		}
 		}
@@ -338,7 +344,7 @@ elsif ( $mailq eq "postfix" ) {
 	@lines = reverse <MAILQ>;
 	@lines = reverse <MAILQ>;
 
 
         if ( $? ) {
         if ( $? ) {
-		print "CRITICAL: Error code ".($?>>8)." returned from $utils::PATH_TO_MAILQ",$/;
+		print "CRITICAL: Error code ".($?>>8)." returned from $utils::PATH_TO_MAILQ$mailq_args",$/;
 		exit $ERRORS{CRITICAL};
 		exit $ERRORS{CRITICAL};
         }
         }
 
 
@@ -351,7 +357,7 @@ elsif ( $mailq eq "postfix" ) {
 	}elsif ($lines[0]=~/Mail queue is empty/) {
 	}elsif ($lines[0]=~/Mail queue is empty/) {
 		$msg_q = 0;
 		$msg_q = 0;
         }else{
         }else{
-                print "Couldn't match $utils::PATH_TO_MAILQ output\n";
+                print "Couldn't match $utils::PATH_TO_MAILQ$mailq_args output\n";
                 exit   $ERRORS{'UNKNOWN'};
                 exit   $ERRORS{'UNKNOWN'};
         }
         }
 
 
@@ -520,7 +526,47 @@ elsif ( $mailq eq "exim" ) {
 		$state = $ERRORS{'CRITICAL'};
 		$state = $ERRORS{'CRITICAL'};
 	}
 	}
 } # end of ($mailq eq "exim")
 } # end of ($mailq eq "exim")
+elsif ( $mailq eq "opensmtpd" ) {
+	## open smtpctl
+	if ( defined $utils::PATH_TO_SMTPCTL && -x $utils::PATH_TO_SMTPCTL ) {
+		if (! open (MAILQ, "$sudo $utils::PATH_TO_SMTPCTL show queue | " ) ) {
+			print "ERROR: could not open $utils::PATH_TO_SMTPCTL \n";
+			exit $ERRORS{'UNKNOWN'};
+		}
+	}elsif( defined $utils::PATH_TO_SMTPCTL){
+		unless (-x $utils::PATH_TO_SMTPCTL) {
+			print "ERROR: $utils::PATH_TO_SMTPCTL is not executable by (uid $>:gid($)))\n";
+			exit $ERRORS{'UNKNOWN'};
+		}
+	} else {
+		print "ERROR: \$utils::PATH_TO_SMTPCTL is not defined\n";
+		exit $ERRORS{'UNKNOWN'};
+	}
+
+	while (<MAILQ>) {
+
+		# 34357f5b3f589feb|inet4|mta||f.someone@domaina.org|no-reply@domainb.com|no-reply@domainb.com|1498235412|1498581012|0|25|pending|17168|Network error on destination MXs
+		if (/^.*|.*|.*|.*|.*|.*|.*|.*|.*|.*|.*|.*|.*|.*$/) {
+			$msg_q++ ;
+		}
+	}
+	close(MAILQ);
 
 
+	if ( $? ) {
+		print "CRITICAL: Error code ".($?>>8)." returned from $utils::PATH_TO_SMTPCTL",$/;
+		exit $ERRORS{CRITICAL};
+	}
+	if ($msg_q < $opt_w) {
+		$msg = "OK: $mailq mailq ($msg_q) is below threshold ($opt_w/$opt_c)";
+		$state = $ERRORS{'OK'};
+	}elsif ($msg_q >= $opt_w  && $msg_q < $opt_c) {
+		$msg = "WARNING: $mailq mailq is $msg_q (threshold w = $opt_w)";
+		$state = $ERRORS{'WARNING'};
+	}else {
+		$msg = "CRITICAL: $mailq mailq is $msg_q (threshold c = $opt_c)";
+		$state = $ERRORS{'CRITICAL'};
+	}
+} # end of ($mailq eq "opensmtpd")
 elsif ( $mailq eq "nullmailer" ) {
 elsif ( $mailq eq "nullmailer" ) {
 	## open mailq
 	## open mailq
 	if ( defined $utils::PATH_TO_MAILQ && -x $utils::PATH_TO_MAILQ ) {
 	if ( defined $utils::PATH_TO_MAILQ && -x $utils::PATH_TO_MAILQ ) {
@@ -558,6 +604,39 @@ elsif ( $mailq eq "nullmailer" ) {
 	}
 	}
 } # end of ($mailq eq "nullmailer")
 } # end of ($mailq eq "nullmailer")
 
 
+elsif ( $mailq eq "opensmtp" ) {
+	## open mailq
+	if ( defined $utils::PATH_TO_MAILQ && -x $utils::PATH_TO_MAILQ ) {
+		if (! open (MAILQ, "$sudo $utils::PATH_TO_MAILQ | " ) ) {
+			print "ERROR: could not open $utils::PATH_TO_MAILQ \n";
+			exit $ERRORS{'UNKNOWN'};
+		}
+	}elsif( defined $utils::PATH_TO_MAILQ){
+		unless (-x $utils::PATH_TO_MAILQ) {
+			print "ERROR: $utils::PATH_TO_MAILQ is not executable by (uid $>:gid($)))\n";
+			exit $ERRORS{'UNKNOWN'};
+		}
+	} else {
+		print "ERROR: \$utils::PATH_TO_MAILQ is not defined\n";
+		exit $ERRORS{'UNKNOWN'};
+	}
+
+	$msg_q++ while (<MAILQ>);
+
+	close(MAILQ) ;
+	if ($msg_q < $opt_w) {
+		$msg = "OK: $mailq mailq ($msg_q) is below threshold ($opt_w/$opt_c)";
+		$state = $ERRORS{'OK'};
+	}elsif ($msg_q >= $opt_w  && $msg_q < $opt_c) {
+		$msg = "WARNING: $mailq mailq is $msg_q (threshold w = $opt_w)";
+		$state = $ERRORS{'WARNING'};
+	}else {
+		$msg = "CRITICAL: $mailq mailq is $msg_q (threshold c = $opt_c)";
+		$state = $ERRORS{'CRITICAL'};
+	}
+} # end of ($mailq eq "opensmtp")
+
+
 # Perfdata support
 # Perfdata support
 print "$msg|unsent=$msg_q;$opt_w;$opt_c;0\n";
 print "$msg|unsent=$msg_q;$opt_w;$opt_c;0\n";
 exit $state;
 exit $state;
@@ -576,7 +655,8 @@ sub process_arguments(){
 		 "w=i" => \$opt_w, "warning=i"  => \$opt_w,   # warning if above this number
 		 "w=i" => \$opt_w, "warning=i"  => \$opt_w,   # warning if above this number
 		 "c=i" => \$opt_c, "critical=i" => \$opt_c,	  # critical if above this number
 		 "c=i" => \$opt_c, "critical=i" => \$opt_c,	  # critical if above this number
 		 "t=i" => \$opt_t, "timeout=i"  => \$opt_t,
 		 "t=i" => \$opt_t, "timeout=i"  => \$opt_t,
-		 "s"   => \$opt_s, "sudo"       => \$opt_s
+		 "s"   => \$opt_s, "sudo"       => \$opt_s,
+		 "d:s" => \$opt_d, "configdir:s" => \$opt_d
 		 );
 		 );
 
 
 	if ($opt_V) {
 	if ($opt_V) {
@@ -618,7 +698,7 @@ sub process_arguments(){
 	}
 	}
 
 
 	if (defined $opt_M) {
 	if (defined $opt_M) {
-		if ($opt_M =~ /^(sendmail|qmail|postfix|exim|nullmailer)$/) {
+		if ($opt_M =~ /^(sendmail|qmail|postfix|exim|nullmailer|opensmtpd)$/) {
 			$mailq = $opt_M ;
 			$mailq = $opt_M ;
 		}elsif( $opt_M eq ''){
 		}elsif( $opt_M eq ''){
 			$mailq = 'sendmail';
 			$mailq = 'sendmail';
@@ -648,6 +728,10 @@ sub process_arguments(){
 		{
 		{
 			$mailq = 'nullmailer';
 			$mailq = 'nullmailer';
 		}
 		}
+		elsif (defined $utils::PATH_TO_SMTPCTL && -x $utils::PATH_TO_SMTPCTL)
+		{
+			$mailq = 'opensmtpd';
+		}
 		else {
 		else {
 			$mailq = 'sendmail';
 			$mailq = 'sendmail';
 		}
 		}
@@ -657,7 +741,7 @@ sub process_arguments(){
 }
 }
 
 
 sub print_usage () {
 sub print_usage () {
-	print "Usage: $PROGNAME -w <warn> -c <crit> [-W <warn>] [-C <crit>] [-M <MTA>] [-t <timeout>] [-s] [-v]\n";
+	print "Usage: $PROGNAME -w <warn> -c <crit> [-W <warn>] [-C <crit>] [-M <MTA>] [-t <timeout>] [-s] [-d <CONFIGDIR>] [-v]\n";
 }
 }
 
 
 sub print_help () {
 sub print_help () {
@@ -673,7 +757,7 @@ sub print_help () {
 	print "-W (--Warning)   = Min. number of messages for same domain in queue to generate warning\n";
 	print "-W (--Warning)   = Min. number of messages for same domain in queue to generate warning\n";
 	print "-C (--Critical)  = Min. number of messages for same domain in queue to generate critical alert ( W < C )\n";
 	print "-C (--Critical)  = Min. number of messages for same domain in queue to generate critical alert ( W < C )\n";
 	print "-t (--timeout)   = Plugin timeout in seconds (default = $utils::TIMEOUT)\n";
 	print "-t (--timeout)   = Plugin timeout in seconds (default = $utils::TIMEOUT)\n";
-	print "-M (--mailserver) = [ sendmail | qmail | postfix | exim | nullmailer ] (default = autodetect)\n";
+	print "-M (--mailserver) = [ sendmail | qmail | postfix | exim | nullmailer | opensmtpd ] (default = autodetect)\n";
 	print "-h (--help)\n";
 	print "-h (--help)\n";
 	print "-V (--version)\n";
 	print "-V (--version)\n";
 	print "-v (--verbose)   = debugging output\n";
 	print "-v (--verbose)   = debugging output\n";

+ 11 - 5
plugins-scripts/check_wave.pl

@@ -13,7 +13,8 @@ use vars qw($opt_V $opt_h $verbose $opt_w $opt_c $opt_H);
 my (@test, $low1, $med1, $high1, $snr, $low2, $med2, $high2);
 my (@test, $low1, $med1, $high1, $snr, $low2, $med2, $high2);
 my ($low, $med, $high, $lowavg, $medavg, $highavg, $tot, $ss);
 my ($low, $med, $high, $lowavg, $medavg, $highavg, $tot, $ss);
 
 
-$PROGNAME = "check_wave";
+$PROGNAME = $0;
+chomp $PROGNAME;
 sub print_help ();
 sub print_help ();
 sub print_usage ();
 sub print_usage ();
 
 
@@ -41,9 +42,9 @@ if ($opt_h) {
 }
 }
 
 
 $opt_H = shift unless ($opt_H);
 $opt_H = shift unless ($opt_H);
-print_usage() unless ($opt_H);
+unless ($opt_H) { print_usage(); exit -1; }
 my $host = $1 if ($opt_H =~ m/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[a-zA-Z][-a-zA-Z0]+(\.[a-zA-Z][-a-zA-Z0]+)*)$/);
 my $host = $1 if ($opt_H =~ m/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[a-zA-Z][-a-zA-Z0]+(\.[a-zA-Z][-a-zA-Z0]+)*)$/);
-print_usage() unless ($host);
+unless ($host) { print_usage(); exit -1; }
 
 
 ($opt_c) || ($opt_c = shift) || ($opt_c = 120);
 ($opt_c) || ($opt_c = shift) || ($opt_c = 120);
 my $critical = $1 if ($opt_c =~ /([0-9]+)/);
 my $critical = $1 if ($opt_c =~ /([0-9]+)/);
@@ -51,7 +52,12 @@ my $critical = $1 if ($opt_c =~ /([0-9]+)/);
 ($opt_w) || ($opt_w = shift) || ($opt_w = 60);
 ($opt_w) || ($opt_w = shift) || ($opt_w = 60);
 my $warning = $1 if ($opt_w =~ /([0-9]+)/);
 my $warning = $1 if ($opt_w =~ /([0-9]+)/);
 
 
-$low1 = `snmpget $host public .1.3.6.1.4.1.74.2.21.1.2.1.8.1`;
+$low1 = `snmpget $host public .1.3.6.1.4.1.74.2.21.1.2.1.8.1 2>/dev/null`;
+unless ($low1) {
+	print "UNKNOWN - Could not find the 'snmpget' command Please install\n";
+	print "the snmp commands (usually net-snmp) before using $PROGNAME\n";
+	exit $ERRORS{'UNKNOWN'};
+}
 @test = split(/ /,$low1);
 @test = split(/ /,$low1);
 $low1 = $test[2];
 $low1 = $test[2];
 
 
@@ -97,7 +103,7 @@ if ($tot==0) {
 	$ss = ($medavg*50) + ($highavg*100);
 	$ss = ($medavg*50) + ($highavg*100);
 }
 }
 
 
-printf("Signal Strength at: %3.0f%,  SNR at $snr%",$ss);
+printf("Signal Strength at: %3.0f%,  SNR at $snr%\n",$ss);
 
 
 if ($ss<$critical) {
 if ($ss<$critical) {
 	exit(2);
 	exit(2);

+ 12 - 3
plugins/check_apt.c

@@ -73,6 +73,7 @@ char* add_to_regexp(char *expr, const char *next);
 /* configuration variables */
 /* configuration variables */
 static int verbose = 0;      /* -v */
 static int verbose = 0;      /* -v */
 static int do_update = 0;    /* whether to call apt-get update */
 static int do_update = 0;    /* whether to call apt-get update */
+static int only_critical = 0;    /* whether to warn about non-critical updates */
 static upgrade_type upgrade = UPGRADE; /* which type of upgrade to do */
 static upgrade_type upgrade = UPGRADE; /* which type of upgrade to do */
 static char *upgrade_opts = NULL; /* options to override defaults for upgrade */
 static char *upgrade_opts = NULL; /* options to override defaults for upgrade */
 static char *update_opts = NULL; /* options to override defaults for update */
 static char *update_opts = NULL; /* options to override defaults for update */
@@ -110,7 +111,7 @@ int main (int argc, char **argv) {
 
 
 	if(sec_count > 0){
 	if(sec_count > 0){
 		result = max_state(result, STATE_CRITICAL);
 		result = max_state(result, STATE_CRITICAL);
-	} else if(packages_available > 0){
+	} else if(packages_available > 0 && only_critical == 0){
 		result = max_state(result, STATE_WARNING);
 		result = max_state(result, STATE_WARNING);
 	} else if(result > STATE_UNKNOWN){
 	} else if(result > STATE_UNKNOWN){
 		result = STATE_UNKNOWN;
 		result = STATE_UNKNOWN;
@@ -148,12 +149,13 @@ int process_arguments (int argc, char **argv) {
 		{"include", required_argument, 0, 'i'},
 		{"include", required_argument, 0, 'i'},
 		{"exclude", required_argument, 0, 'e'},
 		{"exclude", required_argument, 0, 'e'},
 		{"critical", required_argument, 0, 'c'},
 		{"critical", required_argument, 0, 'c'},
+		{"only-critical", no_argument, 0, 'o'},
 		{"input-file", required_argument, 0, INPUT_FILE_OPT},
 		{"input-file", required_argument, 0, INPUT_FILE_OPT},
 		{0, 0, 0, 0}
 		{0, 0, 0, 0}
 	};
 	};
 
 
 	while(1) {
 	while(1) {
-		c = getopt_long(argc, argv, "hVvt:u::U::d::ni:e:c:", longopts, NULL);
+		c = getopt_long(argc, argv, "hVvt:u::U::d::ni:e:c:o", longopts, NULL);
 
 
 		if(c == -1 || c == EOF || c == 1) break;
 		if(c == -1 || c == EOF || c == 1) break;
 
 
@@ -203,6 +205,9 @@ int process_arguments (int argc, char **argv) {
 		case 'c':
 		case 'c':
 			do_critical=add_to_regexp(do_critical, optarg);
 			do_critical=add_to_regexp(do_critical, optarg);
 			break;
 			break;
+		case 'o':
+			only_critical=1;
+			break;
 		case INPUT_FILE_OPT:
 		case INPUT_FILE_OPT:
 			input_filename = optarg;
 			input_filename = optarg;
 			break;
 			break;
@@ -463,7 +468,11 @@ print_help (void)
   printf ("    %s\n", _("upgrades for Debian and Ubuntu:"));
   printf ("    %s\n", _("upgrades for Debian and Ubuntu:"));
   printf ("    \t\%s\n", SECURITY_RE);
   printf ("    \t\%s\n", SECURITY_RE);
   printf ("    %s\n", _("Note that the package must first match the include list before its"));
   printf ("    %s\n", _("Note that the package must first match the include list before its"));
-  printf ("    %s\n\n", _("information is compared against the critical list."));
+  printf ("    %s\n", _("information is compared against the critical list."));
+  printf (" %s\n", "-o, --only-critical");
+  printf ("    %s\n", _("Only warn about upgrades matching the critical list.  The total number"));
+  printf ("    %s\n", _("of upgrades will be printed, but any non-critical upgrades will not cause"));
+  printf ("    %s\n\n", _("the plugin to return WARNING status."));
 
 
   printf ("%s\n\n", _("The following options require root privileges and should be used with care:"));
   printf ("%s\n\n", _("The following options require root privileges and should be used with care:"));
   printf (" %s\n", "-u, --update=OPTS");
   printf (" %s\n", "-u, --update=OPTS");

+ 51 - 66
plugins/check_disk.c

@@ -127,7 +127,6 @@ enum
 int process_arguments (int, char **);
 int process_arguments (int, char **);
 void print_path (const char *mypath);
 void print_path (const char *mypath);
 void set_all_thresholds (struct parameter_list *path);
 void set_all_thresholds (struct parameter_list *path);
-int validate_arguments (uintmax_t, uintmax_t, double, double, double, double, char *);
 void print_help (void);
 void print_help (void);
 void print_usage (void);
 void print_usage (void);
 double calculate_percent(uintmax_t, uintmax_t);
 double calculate_percent(uintmax_t, uintmax_t);
@@ -147,6 +146,7 @@ int erronly = FALSE;
 int display_mntp = FALSE;
 int display_mntp = FALSE;
 int exact_match = FALSE;
 int exact_match = FALSE;
 int freespace_ignore_reserved = FALSE;
 int freespace_ignore_reserved = FALSE;
+int show_status = FALSE;
 char *warn_freespace_units = NULL;
 char *warn_freespace_units = NULL;
 char *crit_freespace_units = NULL;
 char *crit_freespace_units = NULL;
 char *warn_freespace_percent = NULL;
 char *warn_freespace_percent = NULL;
@@ -171,16 +171,15 @@ main (int argc, char **argv)
   int result = STATE_UNKNOWN;
   int result = STATE_UNKNOWN;
   int disk_result = STATE_UNKNOWN;
   int disk_result = STATE_UNKNOWN;
   char *output;
   char *output;
-  char *details;
+  char status_lit[4];
   char *perf;
   char *perf;
   char *preamble;
   char *preamble;
-  char *flag_header;
   double inode_space_pct;
   double inode_space_pct;
   double warning_high_tide;
   double warning_high_tide;
   double critical_high_tide;
   double critical_high_tide;
   int temp_result;
   int temp_result;
 
 
-  struct mount_entry *me;
+  struct mount_entry *me, *last_me = NULL;
   struct fs_usage fsp, tmpfsp;
   struct fs_usage fsp, tmpfsp;
   struct parameter_list *temp_list, *path;
   struct parameter_list *temp_list, *path;
 
 
@@ -190,7 +189,6 @@ main (int argc, char **argv)
 
 
   preamble = strdup (" - free space:");
   preamble = strdup (" - free space:");
   output = strdup ("");
   output = strdup ("");
-  details = strdup ("");
   perf = strdup ("");
   perf = strdup ("");
   stat_buf = malloc(sizeof *stat_buf);
   stat_buf = malloc(sizeof *stat_buf);
 
 
@@ -206,11 +204,37 @@ main (int argc, char **argv)
   if (process_arguments (argc, argv) == ERROR)
   if (process_arguments (argc, argv) == ERROR)
     usage4 (_("Could not parse arguments"));
     usage4 (_("Could not parse arguments"));
 
 
+  if (show_status)
+    sprintf(status_lit, "x:");
+  else
+    status_lit[0] = '\0';
+
   /* If a list of paths has not been selected, find entire
   /* If a list of paths has not been selected, find entire
      mount list and create list of paths
      mount list and create list of paths
    */
    */
   if (path_selected == FALSE) {
   if (path_selected == FALSE) {
     for (me = mount_list; me; me = me->me_next) {
     for (me = mount_list; me; me = me->me_next) {
+			if (strcmp(me->me_type, "autofs") == 0 && show_local_fs) {
+				if (last_me == NULL)
+					mount_list = me;
+				else
+					last_me->me_next = me->me_next;
+				free_mount_entry (me);
+				continue;
+			}
+			if (strcmp(me->me_type, "sysfs") == 0 || strcmp(me->me_type, "proc") == 0
+			|| strcmp(me->me_type, "debugfs") == 0 || strcmp(me->me_type, "tracefs") == 0
+			|| strcmp(me->me_type, "fusectl") == 0 || strcmp(me->me_type, "fuse.gvfsd-fuse") == 0
+			|| strcmp(me->me_type, "cgroup") == 0 || strstr(me->me_type, "tmpfs") != NULL)
+			{
+				if (last_me == NULL)
+					mount_list = me->me_next;
+				else
+					last_me->me_next = me->me_next;
+				free_mount_entry (me);
+				continue;
+			}
+
       if (! (path = np_find_parameter(path_select_list, me->me_mountdir))) {
       if (! (path = np_find_parameter(path_select_list, me->me_mountdir))) {
         path = np_add_parameter(&path_select_list, me->me_mountdir);
         path = np_add_parameter(&path_select_list, me->me_mountdir);
       }
       }
@@ -321,6 +345,9 @@ main (int argc, char **argv)
       if (verbose >=3) printf("Freeinodes_percent result=%d\n", temp_result);
       if (verbose >=3) printf("Freeinodes_percent result=%d\n", temp_result);
       disk_result = max_state( disk_result, temp_result );
       disk_result = max_state( disk_result, temp_result );
 
 
+      if (show_status)
+        status_lit[0] = state_text(disk_result)[0];
+
       result = max_state(result, disk_result);
       result = max_state(result, disk_result);
 
 
       /* What a mess of units. The output shows free space, the perf data shows used space. Yikes!
       /* What a mess of units. The output shows free space, the perf data shows used space. Yikes!
@@ -357,14 +384,10 @@ main (int argc, char **argv)
       if (disk_result==STATE_OK && erronly && !verbose)
       if (disk_result==STATE_OK && erronly && !verbose)
         continue;
         continue;
 
 
-      if (disk_result && verbose) {
-	      xasprintf(&flag_header, " %s [", state_text (disk_result));
-      }
-      else {
-	      xasprintf(&flag_header, "");
-      }
-      xasprintf (&output, "%s %s %.0f %s (%.2f%%",
+      xasprintf (&output, "%s%s%s%s %.0f %s (%.2f%%",
                 output,
                 output,
+                newlines ? "" : " ",
+                status_lit,
                 (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
                 (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
                 path->dfree_units,
                 path->dfree_units,
                 units,
                 units,
@@ -384,8 +407,6 @@ main (int argc, char **argv)
         }
         }
       }
       }
 
 
-      free(flag_header);
-
       /* TODO: Need to do a similar debug line
       /* TODO: Need to do a similar debug line
       xasprintf (&details, _("%s\n\
       xasprintf (&details, _("%s\n\
 %.0f of %.0f %s (%.0f%% inode=%.0f%%) free on %s (type %s mounted on %s) warn:%lu crit:%lu warn%%:%.0f%% crit%%:%.0f%%"),
 %.0f of %.0f %s (%.0f%% inode=%.0f%%) free on %s (type %s mounted on %s) warn:%lu crit:%lu warn%%:%.0f%% crit%%:%.0f%%"),
@@ -398,9 +419,6 @@ main (int argc, char **argv)
 
 
   }
   }
 
 
-  if (verbose >= 2)
-    xasprintf (&output, "%s%s", output, details);
-
   if (newlines) {
   if (newlines) {
     printf ("DISK %s%s\n%s|%s\n", state_text (result), (erronly && result==STATE_OK) ? "" : preamble, output, perf);
     printf ("DISK %s%s\n%s|%s\n", state_text (result), (erronly && result==STATE_OK) ? "" : preamble, output, perf);
   } else {
   } else {
@@ -483,6 +501,7 @@ process_arguments (int argc, char **argv)
     {"errors-only", no_argument, 0, 'e'},
     {"errors-only", no_argument, 0, 'e'},
     {"exact-match", no_argument, 0, 'E'},
     {"exact-match", no_argument, 0, 'E'},
     {"all", no_argument, 0, 'A'},
     {"all", no_argument, 0, 'A'},
+    {"show-status", no_argument, 0, 's'},
     {"verbose", no_argument, 0, 'v'},
     {"verbose", no_argument, 0, 'v'},
     {"quiet", no_argument, 0, 'q'},
     {"quiet", no_argument, 0, 'q'},
     {"clear", no_argument, 0, 'C'},
     {"clear", no_argument, 0, 'C'},
@@ -502,7 +521,7 @@ process_arguments (int argc, char **argv)
       strcpy (argv[c], "-t");
       strcpy (argv[c], "-t");
 
 
   while (1) {
   while (1) {
-    c = getopt_long (argc, argv, "+?VqhvefCt:c:w:K:W:u:p:x:X:N:mklLg:R:r:i:I:MEAn", longopts, &option);
+    c = getopt_long (argc, argv, "+?VqhvefCt:c:w:K:W:u:p:x:X:N:mklLg:R:r:i:I:MEAns", longopts, &option);
 
 
     if (c == -1 || c == EOF)
     if (c == -1 || c == EOF)
       break;
       break;
@@ -703,6 +722,10 @@ process_arguments (int argc, char **argv)
       cflags = default_cflags;
       cflags = default_cflags;
       break;
       break;
 
 
+    case 's':
+      show_status = TRUE;
+			break;
+
     case 'A':
     case 'A':
       optarg = strdup(".*");
       optarg = strdup(".*");
     case 'R':
     case 'R':
@@ -839,50 +862,6 @@ set_all_thresholds (struct parameter_list *path)
     set_thresholds(&path->freeinodes_percent, warn_freeinodes_percent, crit_freeinodes_percent);
     set_thresholds(&path->freeinodes_percent, warn_freeinodes_percent, crit_freeinodes_percent);
 }
 }
 
 
-/* TODO: Remove?
-
-int
-validate_arguments (uintmax_t w, uintmax_t c, double wp, double cp, double iwp, double icp, char *mypath)
-{
-  if (w < 0 && c < 0 && wp < 0.0 && cp < 0.0) {
-    printf (_("INPUT ERROR: No thresholds specified"));
-    print_path (mypath);
-    return ERROR;
-  }
-  else if ((wp >= 0.0 || cp >= 0.0) &&
-           (wp < 0.0 || cp < 0.0 || wp > 100.0 || cp > 100.0 || cp > wp)) {
-    printf (_("\
-INPUT ERROR: C_DFP (%f) should be less than W_DFP (%.1f) and both should be between zero and 100 percent, inclusive"),
-            cp, wp);
-    print_path (mypath);
-    return ERROR;
-  }
-  else if ((iwp >= 0.0 || icp >= 0.0) &&
-           (iwp < 0.0 || icp < 0.0 || iwp > 100.0 || icp > 100.0 || icp > iwp)) {
-    printf (_("\
-INPUT ERROR: C_IDFP (%f) should be less than W_IDFP (%.1f) and both should be between zero and 100 percent, inclusive"),
-            icp, iwp);
-    print_path (mypath);
-    return ERROR;
-  }
-  else if ((w > 0 || c > 0) && (w == 0 || c == 0 || c > w)) {
-    printf (_("\
-INPUT ERROR: C_DF (%lu) should be less than W_DF (%lu) and both should be greater than zero"),
-            (unsigned long)c, (unsigned long)w);
-    print_path (mypath);
-    return ERROR;
-  }
-
-  return OK;
-}
-
-*/
-
-
-
-
-
-
 
 
 void
 void
 print_help (void)
 print_help (void)
@@ -949,6 +928,8 @@ print_help (void)
   printf ("    %s\n", _("Regular expression to ignore selected path/partition (case insensitive) (may be repeated)"));
   printf ("    %s\n", _("Regular expression to ignore selected path/partition (case insensitive) (may be repeated)"));
   printf (" %s\n", "-i, --ignore-ereg-path=PATH, --ignore-ereg-partition=PARTITION");
   printf (" %s\n", "-i, --ignore-ereg-path=PATH, --ignore-ereg-partition=PARTITION");
   printf ("    %s\n", _("Regular expression to ignore selected path or partition (may be repeated)"));
   printf ("    %s\n", _("Regular expression to ignore selected path or partition (may be repeated)"));
+  printf (" %s\n", "-s, --show-status");
+  printf ("    %s\n", _("Show status for each path/partition"));
   printf (UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
   printf (UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
   printf (" %s\n", "-u, --units=STRING");
   printf (" %s\n", "-u, --units=STRING");
   printf ("    %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)"));
   printf ("    %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)"));
@@ -980,16 +961,20 @@ print_usage (void)
 {
 {
   printf ("%s\n", _("Usage:"));
   printf ("%s\n", _("Usage:"));
   printf (" %s -w limit -c limit [-W limit] [-K limit] {-p path | -x device}\n", progname);
   printf (" %s -w limit -c limit [-W limit] [-K limit] {-p path | -x device}\n", progname);
-  printf ("[-C] [-E] [-e] [-f] [-g group ] [-k] [-l] [-M] [-m] [-R path ] [-r path ]\n");
-  printf ("[-t timeout] [-u unit] [-v] [-X type] [-N type] [-n]\n");
+  printf ("[-C] [-E] [-e] [-f] [-g group ] [-k] [-l] [-M] [-m] {-A | [-R path] [-r path]}\n");
+  printf ("[-s] [-t timeout] [-u unit] [-v] [-X type] [-N type] [-n]\n");
 }
 }
 
 
 void
 void
 stat_path (struct parameter_list *p)
 stat_path (struct parameter_list *p)
 {
 {
   /* Stat entry to check that dir exists and is accessible */
   /* Stat entry to check that dir exists and is accessible */
-  if (verbose >= 3)
-    printf("calling stat on %s\n", p->name);
+  if (verbose >= 3) {
+    if (p->best_match)
+      printf("calling stat on %s (%s %s)\n", p->name, p->best_match->me_devname, p->best_match->me_type);
+    else
+      printf("calling stat on %s\n", p->name);
+  }
   if (stat (p->name, &stat_buf[0])) {
   if (stat (p->name, &stat_buf[0])) {
     if (verbose >= 3)
     if (verbose >= 3)
       printf("stat failed on %s\n", p->name);
       printf("stat failed on %s\n", p->name);

Dosya farkı çok büyük olduğundan ihmal edildi
+ 1119 - 1084
plugins/check_http.c


+ 1 - 0
plugins/check_nagios.c

@@ -64,6 +64,7 @@ main (int argc, char **argv)
 	int procuid = 0;
 	int procuid = 0;
 	int procpid = 0;
 	int procpid = 0;
 	int procppid = 0;
 	int procppid = 0;
+	int procjid = 0;
 	int procvsz = 0;
 	int procvsz = 0;
 	int procrss = 0;
 	int procrss = 0;
 	char proc_cgroup_hierarchy[MAX_INPUT_BUFFER];
 	char proc_cgroup_hierarchy[MAX_INPUT_BUFFER];

+ 7 - 0
plugins/check_ntp_time.c

@@ -80,6 +80,7 @@ typedef struct {
 /* this structure holds data about results from querying offset from a peer */
 /* this structure holds data about results from querying offset from a peer */
 typedef struct {
 typedef struct {
 	time_t waiting;         /* ts set when we started waiting for a response */
 	time_t waiting;         /* ts set when we started waiting for a response */
+	int connected;          /* don't try to "write()" if "connect()" fails */
 	int num_responses;      /* number of successfully recieved responses */
 	int num_responses;      /* number of successfully recieved responses */
 	uint8_t stratum;        /* copied verbatim from the ntp_message */
 	uint8_t stratum;        /* copied verbatim from the ntp_message */
 	double rtdelay;         /* converted from the ntp_message */
 	double rtdelay;         /* converted from the ntp_message */
@@ -355,6 +356,7 @@ double offset_request(const char *host, int *status){
 			ufds[i].fd=socklist[i];
 			ufds[i].fd=socklist[i];
 			ufds[i].events=POLLIN;
 			ufds[i].events=POLLIN;
 			ufds[i].revents=0;
 			ufds[i].revents=0;
+			servers[i].connected=1;
 		}
 		}
 		ai_tmp = ai_tmp->ai_next;
 		ai_tmp = ai_tmp->ai_next;
 	}
 	}
@@ -370,6 +372,8 @@ double offset_request(const char *host, int *status){
 		now_time=time(NULL);
 		now_time=time(NULL);
 
 
 		for(i=0; i<num_hosts; i++){
 		for(i=0; i<num_hosts; i++){
+			if(servers[i].connected == 0)
+				continue;
 			if(servers[i].waiting<now_time && servers[i].num_responses<AVG_NUM){
 			if(servers[i].waiting<now_time && servers[i].num_responses<AVG_NUM){
 				if(verbose && servers[i].waiting != 0) printf("re-");
 				if(verbose && servers[i].waiting != 0) printf("re-");
 				if(verbose) printf("sending request to peer %d\n", i);
 				if(verbose) printf("sending request to peer %d\n", i);
@@ -413,6 +417,9 @@ double offset_request(const char *host, int *status){
 			}
 			}
 		}
 		}
 		/* lather, rinse, repeat. */
 		/* lather, rinse, repeat. */
+		/* break if we have one response but other ntp servers doesn't response */
+		/* greater than timeout_interval/2 */
+		if (servers_completed && now_time-start_ts > timeout_interval/2) break;
 	}
 	}
 
 
 	if (one_read == 0) {
 	if (one_read == 0) {

+ 19 - 1
plugins/check_ping.c

@@ -54,6 +54,7 @@ void print_usage (void);
 void print_help (void);
 void print_help (void);
 
 
 int display_html = FALSE;
 int display_html = FALSE;
+int show_resolution = FALSE;
 int wpl = UNKNOWN_PACKET_LOSS;
 int wpl = UNKNOWN_PACKET_LOSS;
 int cpl = UNKNOWN_PACKET_LOSS;
 int cpl = UNKNOWN_PACKET_LOSS;
 float wrta = UNKNOWN_TRIP_TIME;
 float wrta = UNKNOWN_TRIP_TIME;
@@ -67,6 +68,8 @@ int verbose = 0;
 float rta = UNKNOWN_TRIP_TIME;
 float rta = UNKNOWN_TRIP_TIME;
 int pl = UNKNOWN_PACKET_LOSS;
 int pl = UNKNOWN_PACKET_LOSS;
 
 
+char ping_name[256];
+char ping_ip_addr[64];
 char *warn_text;
 char *warn_text;
 
 
 
 
@@ -159,6 +162,12 @@ main (int argc, char **argv)
 		else
 		else
 			printf (_("PING %s - %sPacket loss = %d%%, RTA = %2.2f ms"),
 			printf (_("PING %s - %sPacket loss = %d%%, RTA = %2.2f ms"),
 							state_text (this_result), warn_text, pl, rta);
 							state_text (this_result), warn_text, pl, rta);
+		if (show_resolution) {
+			if (strcmp(ping_name, ping_ip_addr) == 0)
+				printf(" - %s", ping_name);
+			else
+				printf(" - %s (%s)", ping_name, ping_ip_addr);
+		}
 		if (display_html == TRUE)
 		if (display_html == TRUE)
 			printf ("</A>");
 			printf ("</A>");
 
 
@@ -196,6 +205,7 @@ process_arguments (int argc, char **argv)
 	static struct option longopts[] = {
 	static struct option longopts[] = {
 		STD_LONG_OPTS,
 		STD_LONG_OPTS,
 		{"packets", required_argument, 0, 'p'},
 		{"packets", required_argument, 0, 'p'},
+		{"show-resolution", no_argument, 0, 's'},
 		{"nohtml", no_argument, 0, 'n'},
 		{"nohtml", no_argument, 0, 'n'},
 		{"link", no_argument, 0, 'L'},
 		{"link", no_argument, 0, 'L'},
 		{"use-ipv4", no_argument, 0, '4'},
 		{"use-ipv4", no_argument, 0, '4'},
@@ -214,7 +224,7 @@ process_arguments (int argc, char **argv)
 	}
 	}
 
 
 	while (1) {
 	while (1) {
-		c = getopt_long (argc, argv, "VvhnL46t:c:w:H:p:", longopts, &option);
+		c = getopt_long (argc, argv, "VvhsnL46t:c:w:H:p:", longopts, &option);
 
 
 		if (c == -1 || c == EOF)
 		if (c == -1 || c == EOF)
 			break;
 			break;
@@ -271,6 +281,9 @@ process_arguments (int argc, char **argv)
 			else
 			else
 				usage2 (_("<max_packets> (%s) must be a non-negative number\n"), optarg);
 				usage2 (_("<max_packets> (%s) must be a non-negative number\n"), optarg);
 			break;
 			break;
+		case 's':
+			show_resolution = TRUE;
+			break;
 		case 'n':	/* no HTML */
 		case 'n':	/* no HTML */
 			display_html = FALSE;
 			display_html = FALSE;
 			break;
 			break;
@@ -448,6 +461,9 @@ run_ping (const char *cmd, const char *addr)
 
 
 		result = max_state (result, error_scan (buf, addr));
 		result = max_state (result, error_scan (buf, addr));
 
 
+		if(sscanf(buf, "PING %255s (%63[^)]", &ping_name, &ping_ip_addr))
+			continue;
+
 		/* get the percent loss statistics */
 		/* get the percent loss statistics */
 		match = 0;
 		match = 0;
 		if((sscanf(buf,"%*d packets transmitted, %*d packets received, +%*d errors, %d%% packet loss%n",&pl,&match) && match) ||
 		if((sscanf(buf,"%*d packets transmitted, %*d packets received, +%*d errors, %d%% packet loss%n",&pl,&match) && match) ||
@@ -585,6 +601,8 @@ print_help (void)
   printf (" %s\n", "-p, --packets=INTEGER");
   printf (" %s\n", "-p, --packets=INTEGER");
   printf ("    %s ", _("number of ICMP ECHO packets to send"));
   printf ("    %s ", _("number of ICMP ECHO packets to send"));
   printf (_("(Default: %d)\n"), DEFAULT_MAX_PACKETS);
   printf (_("(Default: %d)\n"), DEFAULT_MAX_PACKETS);
+	printf (" %s\n", "-s, --show-resolution");
+	printf ("    %s\n", _("show name resolution in the plugin output (DNS & IP)"));
   printf (" %s\n", "-L, --link");
   printf (" %s\n", "-L, --link");
   printf ("    %s\n", _("show HTML in the plugin output (obsoleted by urlize)"));
   printf ("    %s\n", _("show HTML in the plugin output (obsoleted by urlize)"));
 
 

+ 20 - 6
plugins/check_procs.c

@@ -72,6 +72,7 @@ int options = 0; /* bitmask of filter criteria to test against */
 #define EREG_ARGS 1024
 #define EREG_ARGS 1024
 #define CGROUP_HIERARCHY 2048
 #define CGROUP_HIERARCHY 2048
 #define EXCLUDE_PROGS 4096
 #define EXCLUDE_PROGS 4096
+#define JID 8192
 
 
 #define KTHREAD_PARENT "kthreadd" /* the parent process of kernel threads:
 #define KTHREAD_PARENT "kthreadd" /* the parent process of kernel threads:
 							ppid of procs are compared to pid of this proc*/
 							ppid of procs are compared to pid of this proc*/
@@ -107,6 +108,7 @@ char *fails;
 char tmp[MAX_INPUT_BUFFER];
 char tmp[MAX_INPUT_BUFFER];
 int kthread_filter = 0;
 int kthread_filter = 0;
 int usepid = 0; /* whether to test for pid or /proc/pid/exe */
 int usepid = 0; /* whether to test for pid or /proc/pid/exe */
+int jid;
 
 
 FILE *ps_input = NULL;
 FILE *ps_input = NULL;
 
 
@@ -137,6 +139,7 @@ main (int argc, char **argv)
 	int procuid = 0;
 	int procuid = 0;
 	pid_t procpid = 0;
 	pid_t procpid = 0;
 	pid_t procppid = 0;
 	pid_t procppid = 0;
+	int procjid = 0;
 	pid_t kthread_ppid = 0;
 	pid_t kthread_ppid = 0;
 	int procvsz = 0;
 	int procvsz = 0;
 	int procrss = 0;
 	int procrss = 0;
@@ -240,9 +243,9 @@ main (int argc, char **argv)
 			procseconds = convert_to_seconds(procetime);
 			procseconds = convert_to_seconds(procetime);
 
 
 			if (verbose >= 3) {
 			if (verbose >= 3) {
-				printf ("proc#=%d uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s",
++				printf ("proc#=%d uid=%d vsz=%d rss=%d pid=%d ppid=%d jid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n",
 					procs, procuid, procvsz, procrss,
 					procs, procuid, procvsz, procrss,
-					procpid, procppid, procpcpu, procstat,
+					procpid, procppid, procjid, procpcpu, procstat,
 					procetime, procprog, procargs);
 					procetime, procprog, procargs);
 				if (strstr(PS_COMMAND, "cgroup") != NULL) {
 				if (strstr(PS_COMMAND, "cgroup") != NULL) {
 					printf(" proc_cgroup_hierarchy=%s\n", proc_cgroup_hierarchy);
 					printf(" proc_cgroup_hierarchy=%s\n", proc_cgroup_hierarchy);
@@ -311,6 +314,8 @@ main (int argc, char **argv)
 				resultsum |= PROG;
 				resultsum |= PROG;
 			if ((options & PPID) && (procppid == ppid))
 			if ((options & PPID) && (procppid == ppid))
 				resultsum |= PPID;
 				resultsum |= PPID;
+			if ((options & JID) && (procjid == jid))
+				resultsum |= JID;
 			if ((options & USER) && (procuid == uid))
 			if ((options & USER) && (procuid == uid))
 				resultsum |= USER;
 				resultsum |= USER;
 			if ((options & VSZ)  && (procvsz >= vsz))
 			if ((options & VSZ)  && (procvsz >= vsz))
@@ -339,9 +344,9 @@ main (int argc, char **argv)
 
 
 			procs++;
 			procs++;
 			if (verbose >= 2) {
 			if (verbose >= 2) {
-				printf ("Matched: uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s",
++				printf ("Matched: uid=%d vsz=%d rss=%d pid=%d ppid=%d jid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n",
 					procuid, procvsz, procrss,
 					procuid, procvsz, procrss,
-					procpid, procppid, procpcpu, procstat, 
+					procpid, procppid, procjid, procpcpu, procstat,
 					procetime, procprog, procargs);
 					procetime, procprog, procargs);
 				if (strstr(PS_COMMAND, "cgroup") != NULL) {
 				if (strstr(PS_COMMAND, "cgroup") != NULL) {
 					printf(" cgroup_hierarchy=%s\n", cgroup_hierarchy);
 					printf(" cgroup_hierarchy=%s\n", cgroup_hierarchy);
@@ -463,6 +468,7 @@ process_arguments (int argc, char **argv)
 		{"traditional-filter", no_argument, 0, 'T'},
 		{"traditional-filter", no_argument, 0, 'T'},
 		{"cgroup-hierarchy", required_argument, 0, 'g'},
 		{"cgroup-hierarchy", required_argument, 0, 'g'},
 		{"exclude-process", required_argument, 0, 'X'},
 		{"exclude-process", required_argument, 0, 'X'},
+		{"jid", required_argument, 0, 'j'},
 		{0, 0, 0, 0}
 		{0, 0, 0, 0}
 	};
 	};
 
 
@@ -471,7 +477,7 @@ process_arguments (int argc, char **argv)
 			strcpy (argv[c], "-t");
 			strcpy (argv[c], "-t");
 
 
 	while (1) {
 	while (1) {
-		c = getopt_long (argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:Tg:X:",
+		c = getopt_long (argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:Tg:X:j:",
 			longopts, &option);
 			longopts, &option);
 
 
 		if (c == -1 || c == EOF)
 		if (c == -1 || c == EOF)
@@ -502,6 +508,12 @@ process_arguments (int argc, char **argv)
 				break;
 				break;
 			}
 			}
 			usage4 (_("Parent Process ID must be an integer!"));
 			usage4 (_("Parent Process ID must be an integer!"));
+		case 'j':                                   /* jail id */
+			if (sscanf (optarg, "%d%[^0-9]", &jid, tmp) == 1) {
+				xasprintf (&fmt, "%s%sJID = %d", (fmt ? fmt : "") , (options ? ", " : ""), jid);
+				options |= JID;
+				break;
+			}
 		case 's':									/* status */
 		case 's':									/* status */
 			if (statopts)
 			if (statopts)
 				break;
 				break;
@@ -808,6 +820,8 @@ print_help (void)
   printf ("   %s\n", _("RSZDT, plus others based on the output of your 'ps' command)."));
   printf ("   %s\n", _("RSZDT, plus others based on the output of your 'ps' command)."));
   printf (" %s\n", "-p, --ppid=PPID");
   printf (" %s\n", "-p, --ppid=PPID");
   printf ("   %s\n", _("Only scan for children of the parent process ID indicated."));
   printf ("   %s\n", _("Only scan for children of the parent process ID indicated."));
+  printf (" %s\n", "-j, --jid=JID");
+  printf ("   %s\n", _("Only scan for process running in jail which ID is JID."));
   printf (" %s\n", "-z, --vsz=VSZ");
   printf (" %s\n", "-z, --vsz=VSZ");
   printf ("   %s\n", _("Only scan for processes with VSZ higher than indicated."));
   printf ("   %s\n", _("Only scan for processes with VSZ higher than indicated."));
   printf (" %s\n", "-r, --rss=RSS");
   printf (" %s\n", "-r, --rss=RSS");
@@ -862,7 +876,7 @@ void
 print_usage (void)
 print_usage (void)
 {
 {
   printf ("%s\n", _("Usage:"));
   printf ("%s\n", _("Usage:"));
-	printf ("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname);
+	printf ("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid] [-j jid]\n", progname);
   printf (" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n");
   printf (" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n");
   printf (" [-C command] [-X process_to_exclude] [-k] [-t timeout] [-v]\n");
   printf (" [-C command] [-X process_to_exclude] [-k] [-t timeout] [-v]\n");
 }
 }

+ 6 - 0
plugins/common.h

@@ -146,6 +146,9 @@
 #    include <rsa.h>
 #    include <rsa.h>
 #    include <crypto.h>
 #    include <crypto.h>
 #    include <x509.h>
 #    include <x509.h>
+#    if OPENSSL_VERSION_NUMBER >= 0x10002000L
+#      include <x509v3.h>
+#    endif
 #    include <pem.h>
 #    include <pem.h>
 #    include <ssl.h>
 #    include <ssl.h>
 #    include <err.h>
 #    include <err.h>
@@ -154,6 +157,9 @@
 #      include <openssl/rsa.h>
 #      include <openssl/rsa.h>
 #      include <openssl/crypto.h>
 #      include <openssl/crypto.h>
 #      include <openssl/x509.h>
 #      include <openssl/x509.h>
+#      if OPENSSL_VERSION_NUMBER >= 0x10002000L
+#        include <openssl/x509v3.h>
+#      endif
 #      include <openssl/pem.h>
 #      include <openssl/pem.h>
 #      include <openssl/ssl.h>
 #      include <openssl/ssl.h>
 #      include <openssl/err.h>
 #      include <openssl/err.h>

+ 13 - 1
plugins/sslutils.c

@@ -35,6 +35,8 @@ static SSL_CTX *c=NULL;
 static SSL *s=NULL;
 static SSL *s=NULL;
 static int initialized=0;
 static int initialized=0;
 
 
+int check_hostname = 0;
+
 int np_net_ssl_init(int sd) {
 int np_net_ssl_init(int sd) {
 	return np_net_ssl_init_with_hostname(sd, NULL);
 	return np_net_ssl_init_with_hostname(sd, NULL);
 }
 }
@@ -157,6 +159,16 @@ int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int
 #endif
 #endif
 		SSL_set_fd(s, sd);
 		SSL_set_fd(s, sd);
 		if (SSL_connect(s) == 1) {
 		if (SSL_connect(s) == 1) {
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+			if (check_hostname && host_name && *host_name) {
+				X509 *certificate=SSL_get_peer_certificate(s);
+				int rc = X509_check_host(certificate, host_name, 0, 0, NULL);
+				if (rc != 1) {
+					printf("%s\n", _("CRITICAL - Hostname mismatch."));
+					return STATE_CRITICAL;
+				}
+			}
+#endif
 			return OK;
 			return OK;
 		} else {
 		} else {
 			printf("%s\n", _("CRITICAL - Cannot make SSL connection."));
 			printf("%s\n", _("CRITICAL - Cannot make SSL connection."));
@@ -304,7 +316,7 @@ int np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit){
 		else
 		else
 			status = STATE_CRITICAL;
 			status = STATE_CRITICAL;
 	} else {
 	} else {
-		printf(_("OK - Certificate '%s' will expire on %s. "), cn, timestamp);
+		printf(_("OK - Certificate '%s' will expire on %s.\n"), cn, timestamp);
 		status = STATE_OK;
 		status = STATE_OK;
 	}
 	}
 	X509_free(certificate);
 	X509_free(certificate);

+ 17 - 1
plugins/t/check_apt.t

@@ -23,7 +23,7 @@ sub make_result_regexp {
 }
 }
 
 
 if (-x "./check_apt") {
 if (-x "./check_apt") {
-	plan tests => 28;
+	plan tests => 36;
 } else {
 } else {
 	plan skip_all => "No check_apt compiled";
 	plan skip_all => "No check_apt compiled";
 }
 }
@@ -40,10 +40,18 @@ $result = NPTest->testCmd( sprintf($testfile_command, "", "debian2") );
 is( $result->return_code, 1, "Debian apt output, warning" );
 is( $result->return_code, 1, "Debian apt output, warning" );
 like( $result->output, make_result_regexp(13, 0), "Output correct" );
 like( $result->output, make_result_regexp(13, 0), "Output correct" );
 
 
+$result = NPTest->testCmd( sprintf($testfile_command, "-o", "debian2") );
+is( $result->return_code, 0, "Debian apt output, no critical" );
+like( $result->output, make_result_regexp(13, 0), "Output correct" );
+
 $result = NPTest->testCmd( sprintf($testfile_command, "", "debian3") );
 $result = NPTest->testCmd( sprintf($testfile_command, "", "debian3") );
 is( $result->return_code, 2, "Debian apt output, some critical" );
 is( $result->return_code, 2, "Debian apt output, some critical" );
 like( $result->output, make_result_regexp(19, 4), "Output correct" );
 like( $result->output, make_result_regexp(19, 4), "Output correct" );
 
 
+$result = NPTest->testCmd( sprintf($testfile_command, "-o", "debian3") );
+is( $result->return_code, 2, "Debian apt output, some critical" );
+like( $result->output, make_result_regexp(19, 4), "Output correct" );
+
 $result = NPTest->testCmd( sprintf($testfile_command, "-c '^[^\\(]*\\(.* (Debian-Security:|Ubuntu:[^/]*/[^-]*-security)'", "debian3") );
 $result = NPTest->testCmd( sprintf($testfile_command, "-c '^[^\\(]*\\(.* (Debian-Security:|Ubuntu:[^/]*/[^-]*-security)'", "debian3") );
 is( $result->return_code, 2, "Debian apt output - should have same result when default security regexp specified via -c" );
 is( $result->return_code, 2, "Debian apt output - should have same result when default security regexp specified via -c" );
 like( $result->output, make_result_regexp(19, 4), "Output correct" );
 like( $result->output, make_result_regexp(19, 4), "Output correct" );
@@ -52,6 +60,10 @@ $result = NPTest->testCmd( sprintf($testfile_command, "-i libc6", "debian3") );
 is( $result->return_code, 1, "Debian apt output, filter for libc6" );
 is( $result->return_code, 1, "Debian apt output, filter for libc6" );
 like( $result->output, make_result_regexp(3, 0), "Output correct" );
 like( $result->output, make_result_regexp(3, 0), "Output correct" );
 
 
+$result = NPTest->testCmd( sprintf($testfile_command, "-i libc6", "debian3") );
+is( $result->return_code, 1, "Debian apt output, filter for libc6, not critical" );
+like( $result->output, make_result_regexp(3, 0), "Output correct" );
+
 $result = NPTest->testCmd( sprintf($testfile_command, "-i libc6 -i xen", "debian3") );
 $result = NPTest->testCmd( sprintf($testfile_command, "-i libc6 -i xen", "debian3") );
 is( $result->return_code, 2, "Debian apt output, filter for libc6 and xen" );
 is( $result->return_code, 2, "Debian apt output, filter for libc6 and xen" );
 like( $result->output, make_result_regexp(9, 4), "Output correct" );
 like( $result->output, make_result_regexp(9, 4), "Output correct" );
@@ -64,6 +76,10 @@ $result = NPTest->testCmd( sprintf($testfile_command, "-e libc6", "debian3") );
 is( $result->return_code, 2, "Debian apt output, filter out libc6" );
 is( $result->return_code, 2, "Debian apt output, filter out libc6" );
 like( $result->output, make_result_regexp(16, 4), "Output correct" );
 like( $result->output, make_result_regexp(16, 4), "Output correct" );
 
 
+$result = NPTest->testCmd( sprintf($testfile_command, "-e libc6 -o", "debian3") );
+is( $result->return_code, 2, "Debian apt output, filter out libc6, critical" );
+like( $result->output, make_result_regexp(16, 4), "Output correct" );
+
 $result = NPTest->testCmd( sprintf($testfile_command, "-e libc6 -e xen", "debian3") );
 $result = NPTest->testCmd( sprintf($testfile_command, "-e libc6 -e xen", "debian3") );
 is( $result->return_code, 1, "Debian apt output, filter out libc6 and xen" );
 is( $result->return_code, 1, "Debian apt output, filter out libc6 and xen" );
 like( $result->output, make_result_regexp(10, 0), "Output correct" );
 like( $result->output, make_result_regexp(10, 0), "Output correct" );

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor