summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml15
-rw-r--r--NEWS40
-rwxr-xr-xNP-VERSION-GEN2
-rw-r--r--NPTest.pm34
-rw-r--r--REQUIREMENTS12
-rw-r--r--THANKS.in18
-rw-r--r--configure.ac23
-rw-r--r--gl/Makefile.am10
-rw-r--r--gl/idpriv-droptemp.c204
-rw-r--r--gl/idpriv.h116
-rw-r--r--gl/m4/gnulib-cache.m43
-rw-r--r--gl/m4/gnulib-comp.m49
-rw-r--r--gl/m4/idpriv.m414
-rw-r--r--lib/parse_ini.c492
-rw-r--r--lib/parse_ini.h42
-rw-r--r--lib/tests/test_utils.c8
-rw-r--r--lib/utils_base.c17
-rw-r--r--lib/utils_base.h3
-rw-r--r--lib/utils_cmd.c3
-rw-r--r--plugins-root/check_dhcp.c5
-rw-r--r--plugins-root/check_icmp.c3
-rw-r--r--plugins-scripts/Makefile.am3
-rwxr-xr-xplugins-scripts/check_breeze.pl1
-rwxr-xr-xplugins-scripts/check_disk_smb.pl1
-rwxr-xr-xplugins-scripts/check_file_age.pl4
-rwxr-xr-xplugins-scripts/check_flexlm.pl1
-rwxr-xr-xplugins-scripts/check_ifoperstatus.pl1
-rwxr-xr-xplugins-scripts/check_ifstatus.pl3
-rwxr-xr-xplugins-scripts/check_ircd.pl1
-rwxr-xr-xplugins-scripts/check_mailq.pl1
-rwxr-xr-xplugins-scripts/check_mssql.pl4
-rwxr-xr-xplugins-scripts/check_netdns.pl1
-rwxr-xr-xplugins-scripts/check_rpc.pl1
-rwxr-xr-xplugins-scripts/check_wave.pl1
-rw-r--r--plugins/check_apt.c3
-rw-r--r--plugins/check_dbi.c6
-rw-r--r--plugins/check_dns.c18
-rw-r--r--plugins/check_hpjd.c30
-rw-r--r--plugins/check_http.c10
-rw-r--r--plugins/check_ide_smart.c2
-rw-r--r--plugins/check_mrtg.c2
-rw-r--r--plugins/check_mysql.c22
-rw-r--r--plugins/check_nt.c4
-rw-r--r--plugins/check_ntp.c13
-rw-r--r--plugins/check_ntp_peer.c49
-rw-r--r--plugins/check_ntp_time.c15
-rw-r--r--plugins/check_radius.c49
-rw-r--r--plugins/check_real.c1
-rw-r--r--plugins/check_ssh.c24
-rw-r--r--plugins/check_tcp.c12
-rw-r--r--plugins/check_ups.c6
-rw-r--r--plugins/negate.c11
-rw-r--r--plugins/netutils.c15
-rw-r--r--plugins/netutils.h4
-rw-r--r--plugins/runcmd.c2
-rw-r--r--plugins/sslutils.c11
-rw-r--r--plugins/t/NPTest.cache.travis56
-rw-r--r--plugins/t/check_dns.t3
-rw-r--r--plugins/t/check_fping.t14
-rw-r--r--plugins/t/check_hpjd.t35
-rw-r--r--plugins/t/check_jabber.t6
-rw-r--r--plugins/t/check_ntp.t14
-rw-r--r--plugins/t/check_procs.t2
-rw-r--r--plugins/t/check_snmp.t2
-rw-r--r--plugins/t/check_udp.t2
-rwxr-xr-xplugins/tests/check_http.t35
-rwxr-xr-xplugins/tests/check_procs.t29
-rwxr-xr-xplugins/tests/check_snmp.t2
-rw-r--r--po/de.po4
-rw-r--r--po/fr.po4
-rw-r--r--po/monitoring-plugins.pot4
-rwxr-xr-xtest.pl.in2
72 files changed, 1132 insertions, 487 deletions
diff --git a/.travis.yml b/.travis.yml
index 7a4c3c6..cec7878 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,19 +1,30 @@
1language: c 1language: c
2 2
3before_install: 3before_install:
4 - sudo add-apt-repository -y ppa:waja/precise-backports
4 - sudo apt-get update -qq 5 - sudo apt-get update -qq
5 - sudo apt-get purge -qq gawk 6 - sudo apt-get purge -qq gawk
6 7
7install: 8install:
8 - sudo apt-get install -qq --no-install-recommends perl autotools-dev libdbi-dev libldap2-dev libpq-dev libmysqlclient-dev libradiusclient-ng-dev libkrb5-dev libnet-snmp-perl procps 9 - sudo apt-get install -qq --no-install-recommends perl autotools-dev libdbi-dev libldap2-dev libpq-dev libmysqlclient-dev libfreeradius-client-dev libkrb5-dev libnet-snmp-perl procps
10 - sudo apt-get install -qq --no-install-recommends libdbi0-dev libdbd-sqlite3 libssl-dev dnsutils snmp-mibs-downloader
11 - sudo apt-get install -qq --no-install-recommends fping snmp netcat smbclient fping pure-ftpd apache2 postfix libhttp-daemon-ssl-perl
9 - sudo apt-get install -qq --no-install-recommends autoconf automake 12 - sudo apt-get install -qq --no-install-recommends autoconf automake
10 13
11before_script: 14before_script:
12 - tools/setup 15 - tools/setup
13 - ./configure 16 - ./configure
17 - make
18 - export NPTEST_CACHE="$(pwd)/plugins/t/NPTest.cache.travis"
19 - ssh-keygen -t dsa -N "" -f ~/.ssh/id_dsa
20 - cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
21 - ssh-keyscan localhost >> ~/.ssh/known_hosts
22 - touch ~/.ssh/config
23 - sudo rm -f /usr/share/mibs/ietf/SNMPv2-PDU /usr/share/mibs/ietf/IPSEC-SPD-MIB /usr/share/mibs/ietf/IPATM-IPMC-MIB /usr/share/mibs/iana/IANA-IPPM-METRICS-REGISTRY-MIB
24 - sudo mkdir -p /var/lib/snmp/mib_indexes
14 25
15script: 26script:
16 - if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then make; fi 27 - if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then make test; fi
17 28
18notifications: 29notifications:
19 irc: 30 irc:
diff --git a/NEWS b/NEWS
index c0c9d11..d48e1d8 100644
--- a/NEWS
+++ b/NEWS
@@ -1,28 +1,54 @@
1This file documents the major additions and syntax changes between releases. 1This file documents the major additions and syntax changes between releases.
2 2
31.6 ... 32.1
4 ENHANCEMENTS 4 ENHANCEMENTS
5 check_mailq now supports auto detection of qmail, postfix, exim and nullmailer with 5 New check_hpjd -p option for port specification (abrist)
6 fallback to sendmail 6
72.0 11th July 2014
8 ENHANCEMENTS
9 check_mailq now supports auto detection of qmail, postfix, exim and nullmailer with
10 fallback to sendmail
7 check_ide_smart now defaults to plugin output, original output appended with -v 11 check_ide_smart now defaults to plugin output, original output appended with -v
8 Extra-Opts are now enabled by default 12 Extra-Opts are now enabled by default, see:
13 https://www.monitoring-plugins.org/doc/extra-opts.html
9 check_swap now supports a configurable state when there is no swap 14 check_swap now supports a configurable state when there is no swap
15 check_radius now supports the FreeRADIUS Client library
16 New check_mysql_query -f option to specify a client options file
17 New check_mysql_query -g option to specify a client options group
18 Add performance data to check_mysql_query
19 New check_file_age -i/--ignore-missing option to return OK on nonexistent files
20 Make check_ping, check_users, and check_disk work on Windows
21 New check_ssh -P option to specify the expected SSH protocol version
22 check_dns now emits the warning and critical thresholds with the performance data
10 23
11 FIXES 24 FIXES
12 Don't let e.g. check_http's -C option reset SSL version if e.g. -S 1 -C 5 is specified 25 Don't let e.g. check_http's -C option reset SSL version if e.g. -S 1 -C 5 is specified
26 Don't have check_http's -N option expect an argument
13 check_ide_smart could disable offline auto tests but could not re-enable them. 27 check_ide_smart could disable offline auto tests but could not re-enable them.
14 For this reason all SMART command modes have been disabled. 28 For this reason all SMART command modes have been disabled.
15 check_dig: fix wrong IPv6 arguments order (Stéphane Bortzmeyer) 29 check_dig: fix wrong IPv6 arguments order (Stéphane Bortzmeyer)
30 check_dig: make sure not to give up too early when a timeout is specified with -t
31 check_log: don't stumble over log lines that include a "%" character
32 check_nt: add UPTIME to perfdata
33 Handle SNMPv3 noAuthNoPriv properly with check_snmp
34 Fix compilation with GnuTLS
16 35
17 WARNINGS 36 WARNINGS
18 check_procs now ignores its parent process to avoid unexpected results when invoked via certain shells 37 New default installation prefix: /usr/local instead of /usr/local/nagios
38 check_snmp now evaluates negative values properly, which means it might return CRITICAL
39 in cases where it used to return OK. If this is undesired, the warning/critical
40 threshold(s) must be fixed by specifying e.g. ~:100 instead of 100
41 check_procs now ignores its parent process to avoid unexpected results when invoked via
42 certain shells
19 utils.sh no longer defines ECH 43 utils.sh no longer defines ECH
20 check_ide_smart -q/--quiet and -n/--nagios (Nagios-compatile output) are now deprecated 44 check_ide_smart -q/--quiet and -n/--nagios (Nagios-compatible output) are now deprecated
21 but accepted for backward-compatibility 45 but accepted for backward-compatibility
22 check_ide_smart -0/--auto-off, -1/--auto-on and -i/--immediate: options have 46 check_ide_smart -0/--auto-off, -1/--auto-on and -i/--immediate: options have
23 been disabled because they were broken 47 been disabled because they were broken
24 State retention: the NAGIOS_PLUGIN_STATE_DIRECTORY environment variable has been 48 State retention: the NAGIOS_PLUGIN_STATE_DIRECTORY environment variable has been
25 renamed MP_STATE_DIRECTORY. The old variable will continue to work in v1.6.x 49 renamed MP_STATE_PATH. The old variable will continue to work in v2.0.x
50 Add the UID of the invoking user to the state retention file path. This helps solving
51 permission issues when different users run the same plugin
26 check_swap used to allow returning OK on a system without swap when only percent thresholds 52 check_swap used to allow returning OK on a system without swap when only percent thresholds
27 were used. This is no longer the case and one must now use -n/--no-swap=<state> 53 were used. This is no longer the case and one must now use -n/--no-swap=<state>
28 The Perl and Shell plugins now use the PATH specified via ./configure's --trusted-path 54 The Perl and Shell plugins now use the PATH specified via ./configure's --trusted-path
diff --git a/NP-VERSION-GEN b/NP-VERSION-GEN
index ae507e4..26f94e7 100755
--- a/NP-VERSION-GEN
+++ b/NP-VERSION-GEN
@@ -6,7 +6,7 @@
6SRC_ROOT=`dirname $0` 6SRC_ROOT=`dirname $0`
7 7
8NPVF=NP-VERSION-FILE 8NPVF=NP-VERSION-FILE
9DEF_VER=1.5.git 9DEF_VER=2.0.git
10 10
11LF=' 11LF='
12' 12'
diff --git a/NPTest.pm b/NPTest.pm
index 2baed0b..f72ed2d 100644
--- a/NPTest.pm
+++ b/NPTest.pm
@@ -6,7 +6,7 @@ package NPTest;
6 6
7require Exporter; 7require Exporter;
8@ISA = qw(Exporter); 8@ISA = qw(Exporter);
9@EXPORT = qw(getTestParameter checkCmd skipMissingCmd); 9@EXPORT = qw(getTestParameter checkCmd skipMissingCmd skipMsg);
10@EXPORT_OK = qw(DetermineTestHarnessDirectory TestsFrom SetCacheFilename); 10@EXPORT_OK = qw(DetermineTestHarnessDirectory TestsFrom SetCacheFilename);
11 11
12use strict; 12use strict;
@@ -38,8 +38,8 @@ testing.
38 38
39=head1 FUNCTIONS 39=head1 FUNCTIONS
40 40
41This module defines three public functions, C<getTestParameter(...)>, 41This module defines four public functions, C<getTestParameter(...)>,
42C<checkCmd(...)> and C<skipMissingCmd(...)>. These are exported by 42C<checkCmd(...)>, C<skipMissingCmd(...)> and C<skipMsg(...)>. These are exported by
43default via the C<use NPTest;> statement. 43default via the C<use NPTest;> statement.
44 44
45=over 45=over
@@ -185,6 +185,15 @@ of times.
185 185
186=back 186=back
187 187
188=item C<skipMsg(...)>
189
190If for any reason the test harness must C<Test::skip()> some
191or all of the tests in a given test harness this function provides a
192simple iterator to issue an appropriate message the requested number
193of times.
194
195=back
196
188=head1 SEE ALSO 197=head1 SEE ALSO
189 198
190L<Test> 199L<Test>
@@ -304,6 +313,20 @@ sub skipMissingCmd
304 return $testStatus; 313 return $testStatus;
305} 314}
306 315
316sub skipMsg
317{
318 my( $msg, $count ) = @_;
319
320 my $testStatus;
321
322 for ( 1 .. $count )
323 {
324 $testStatus += skip( $msg, 1 );
325 }
326
327 return $testStatus;
328}
329
307sub getTestParameter 330sub getTestParameter
308{ 331{
309 my( $param, $envvar, $default, $brief, $scoped ); 332 my( $param, $envvar, $default, $brief, $scoped );
@@ -627,12 +650,13 @@ sub only_output {
627} 650}
628 651
629sub testCmd { 652sub testCmd {
630 my $class = shift; 653 my $class = shift;
631 my $command = shift or die "No command passed to testCmd"; 654 my $command = shift or die "No command passed to testCmd";
655 my $timeout = shift || 120;
632 my $object = $class->new; 656 my $object = $class->new;
633 657
634 local $SIG{'ALRM'} = sub { die("timeout in command: $command"); }; 658 local $SIG{'ALRM'} = sub { die("timeout in command: $command"); };
635 alarm(120); # no test should take longer than 120 seconds 659 alarm($timeout); # no test should take longer than 120 seconds
636 660
637 my $output = `$command`; 661 my $output = `$command`;
638 $object->return_code($? >> 8); 662 $object->return_code($? >> 8);
diff --git a/REQUIREMENTS b/REQUIREMENTS
index b2bd467..303fd62 100644
--- a/REQUIREMENTS
+++ b/REQUIREMENTS
@@ -50,14 +50,16 @@ check_dbi:
50 http://libdbi.sourceforge.net/ 50 http://libdbi.sourceforge.net/
51 51
52check_radius: 52check_radius:
53 - Requires the radiusclient-ng library available from: 53 - Requires the FreeRADIUS Client library available from:
54 http://developer.berlios.de/projects/radiusclient-ng/ 54 http://freeradius.org/freeradius-client/
55 - As an alternative, the radiusclient-ng library may be used:
56 http://sourceforge.net/projects/radiusclient-ng.berlios/
55 - This plugin also works with the original radiusclient library from 57 - This plugin also works with the original radiusclient library from
56 ftp://ftp.cityline.net/pub/radiusclient/ 58 ftp://ftp.cityline.net/pub/radiusclient/
57 RPM (rpmfind): radiusclient 0.3.2, radiusclient-devel-0.3.2 59 RPM (rpmfind): radiusclient 0.3.2, radiusclient-devel-0.3.2
58 Unless you're using a distro-maintained version of this library you 60 However, you probably want to use the FreeRADIUS Client library, as
59 probably want to use radiusclient-ng. The original radiusclient library is 61 both radiusclient and radiusclient-ng are unmaintained and have known
60 unmaintained and has many known issues, particularly with 64bit systems. 62 issues.
61 63
62check_snmp: 64check_snmp:
63 - Requires the NET-SNMP package available from 65 - Requires the NET-SNMP package available from
diff --git a/THANKS.in b/THANKS.in
index 0600051..b6dc294 100644
--- a/THANKS.in
+++ b/THANKS.in
@@ -308,3 +308,21 @@ Luca Corti
308Jethro Carr 308Jethro Carr
309Evgeni Golov 309Evgeni Golov
310Oskar Liljeblad 310Oskar Liljeblad
311Andrew Widdersheim
312Anton Lofgren
313Damian Myerscough
314Davide Madrisan
315Gunnar Beutner
316Joseph Gooch
317Lars Vogdt
318Ricardo Maraschini
319Spenser Reinhardt
320Stephane Lapie
321Tilmann Bubeck
322Eric J. Mislivec
323Jean-Claude Computing
324Andy Brist
325Mikael Falkvidd
326Patric Wust
327Julius Kriukas
328Patrick McAndrew
diff --git a/configure.ac b/configure.ac
index 244df42..f6ead58 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
1dnl Process this file with autoconf to produce a configure script. 1dnl Process this file with autoconf to produce a configure script.
2AC_PREREQ(2.59) 2AC_PREREQ(2.59)
3AC_INIT(monitoring-plugins,1.5) 3AC_INIT(monitoring-plugins,2.0)
4AC_CONFIG_SRCDIR(NPTest.pm) 4AC_CONFIG_SRCDIR(NPTest.pm)
5AC_CONFIG_FILES([gl/Makefile 5AC_CONFIG_FILES([gl/Makefile
6 monitoring-plugins.spec]) 6 monitoring-plugins.spec])
@@ -274,20 +274,27 @@ AC_ARG_WITH([radius], [AS_HELP_STRING([--without-radius], [Skips the radius plug
274dnl Check for radius libraries 274dnl Check for radius libraries
275AS_IF([test "x$with_radius" != "xno"], [ 275AS_IF([test "x$with_radius" != "xno"], [
276 _SAVEDLIBS="$LIBS" 276 _SAVEDLIBS="$LIBS"
277 AC_CHECK_LIB(radiusclient,rc_read_config) 277 AC_CHECK_LIB(freeradius-client,rc_read_config)
278 if test "$ac_cv_lib_radiusclient_rc_read_config" = "yes"; then 278 if test "$ac_cv_lib_freeradius_client_rc_read_config" = "yes"; then
279 EXTRAS="$EXTRAS check_radius\$(EXEEXT)" 279 EXTRAS="$EXTRAS check_radius\$(EXEEXT)"
280 RADIUSLIBS="-lradiusclient" 280 RADIUSLIBS="-lfreeradius-client"
281 AC_SUBST(RADIUSLIBS) 281 AC_SUBST(RADIUSLIBS)
282 else 282 else
283 AC_CHECK_LIB(radiusclient-ng,rc_read_config) 283 AC_CHECK_LIB(radiusclient-ng,rc_read_config)
284 if test "$ac_cv_lib_radiusclient_ng_rc_read_config" = "yes"; then 284 if test "$ac_cv_lib_radiusclient_ng_rc_read_config" = "yes"; then
285 EXTRAS="$EXTRAS check_radius\$(EXEEXT)" 285 EXTRAS="$EXTRAS check_radius\$(EXEEXT)"
286 RADIUSLIBS="-lradiusclient-ng" 286 RADIUSLIBS="-lradiusclient-ng"
287 AC_SUBST(RADIUSLIBS) 287 AC_SUBST(RADIUSLIBS)
288 else 288 else
289 AC_MSG_WARN([Skipping radius plugin]) 289 AC_CHECK_LIB(radiusclient,rc_read_config)
290 AC_MSG_WARN([install radius libs to compile this plugin (see REQUIREMENTS).]) 290 if test "$ac_cv_lib_radiusclient_rc_read_config" = "yes"; then
291 EXTRAS="$EXTRAS check_radius\$(EXEEXT)"
292 RADIUSLIBS="-lradiusclient"
293 AC_SUBST(RADIUSLIBS)
294 else
295 AC_MSG_WARN([Skipping radius plugin])
296 AC_MSG_WARN([install radius libs to compile this plugin (see REQUIREMENTS).])
297 fi
291 fi 298 fi
292 fi 299 fi
293 LIBS="$_SAVEDLIBS" 300 LIBS="$_SAVEDLIBS"
@@ -509,8 +516,6 @@ dnl check for gnutls if openssl isn't found (or is disabled)
509if test ! "$FOUNDOPENSSL" = "yes" && test ! "$with_gnutls" = "no"; then 516if test ! "$FOUNDOPENSSL" = "yes" && test ! "$with_gnutls" = "no"; then
510 if test ! "$with_gnutls" = ""; then 517 if test ! "$with_gnutls" = ""; then
511 CPPFLAGS="$CPPFLAGS -I${with_gnutls}/include" 518 CPPFLAGS="$CPPFLAGS -I${with_gnutls}/include"
512 elif test ! "$LIBGNUTLS_CONFIG" = ""; then
513 CPPFLAGS="$CPPFLAGS -I`$LIBGNUTLS_CONFIG --prefix`"
514 fi 519 fi
515 AC_CHECK_HEADERS([gnutls/openssl.h],FOUNDGNUTLS="yes",) 520 AC_CHECK_HEADERS([gnutls/openssl.h],FOUNDGNUTLS="yes",)
516 if test "$FOUNDGNUTLS" = "yes"; then 521 if test "$FOUNDGNUTLS" = "yes"; then
diff --git a/gl/Makefile.am b/gl/Makefile.am
index 4339b2c..54abb4c 100644
--- a/gl/Makefile.am
+++ b/gl/Makefile.am
@@ -21,7 +21,7 @@
21# the same distribution terms as the rest of that program. 21# the same distribution terms as the rest of that program.
22# 22#
23# Generated by gnulib-tool. 23# Generated by gnulib-tool.
24# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files base64 crypto/sha1 dirname environ floorf fsusage getaddrinfo gethostname getloadavg getopt-gnu gettext mountlist regex setenv strcase strsep timegm unsetenv vasprintf vsnprintf 24# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files base64 crypto/sha1 dirname environ floorf fsusage getaddrinfo gethostname getloadavg getopt-gnu gettext idpriv-droptemp mountlist regex setenv strcase strsep timegm unsetenv vasprintf vsnprintf
25 25
26AUTOMAKE_OPTIONS = 1.9.6 gnits subdir-objects 26AUTOMAKE_OPTIONS = 1.9.6 gnits subdir-objects
27 27
@@ -402,6 +402,14 @@ EXTRA_DIST += $(top_srcdir)/build-aux/config.rpath
402 402
403## end gnulib module havelib 403## end gnulib module havelib
404 404
405## begin gnulib module idpriv-droptemp
406
407libgnu_a_SOURCES += idpriv-droptemp.c
408
409EXTRA_DIST += idpriv.h
410
411## end gnulib module idpriv-droptemp
412
405## begin gnulib module inet_ntop 413## begin gnulib module inet_ntop
406 414
407 415
diff --git a/gl/idpriv-droptemp.c b/gl/idpriv-droptemp.c
new file mode 100644
index 0000000..13d1064
--- /dev/null
+++ b/gl/idpriv-droptemp.c
@@ -0,0 +1,204 @@
1/* Dropping uid/gid privileges of the current process temporarily.
2 Copyright (C) 2009-2013 Free Software Foundation, Inc.
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
16
17#include <config.h>
18
19#include "idpriv.h"
20
21#include <errno.h>
22#include <stdlib.h>
23#include <sys/types.h>
24#include <unistd.h>
25
26/* The privileged uid and gid that the process had earlier. */
27#if HAVE_GETUID
28static int saved_uid = -1;
29#endif
30#if HAVE_GETGID
31static int saved_gid = -1;
32#endif
33
34int
35idpriv_temp_drop (void)
36{
37#if HAVE_GETEUID && HAVE_GETEGID && (HAVE_SETRESUID || HAVE_SETREUID) && (HAVE_SETRESGID || HAVE_SETREGID)
38 int uid = getuid ();
39 int gid = getgid ();
40
41 /* Find out about the privileged uid and gid at the first call. */
42 if (saved_uid == -1)
43 saved_uid = geteuid ();
44 if (saved_gid == -1)
45 saved_gid = getegid ();
46
47 /* Drop the gid privilege first, because in some cases the gid privilege
48 cannot be dropped after the uid privilege has been dropped. */
49
50 /* This is for executables that have the setgid bit set. */
51# if HAVE_SETRESGID /* glibc, FreeBSD, OpenBSD, HP-UX */
52 if (setresgid (-1, gid, saved_gid) < 0)
53 return -1;
54# else /* Mac OS X, NetBSD, AIX, IRIX, Solaris >= 2.5, OSF/1, Cygwin */
55 if (setregid (-1, gid) < 0)
56 return -1;
57# endif
58
59 /* This is for executables that have the setuid bit set. */
60# if HAVE_SETRESUID /* glibc, FreeBSD, OpenBSD, HP-UX */
61 /* See <http://www.usenix.org/events/sec02/full_papers/chen/chen.pdf>
62 figure 14. */
63 if (setresuid (-1, uid, saved_uid) < 0)
64 return -1;
65# else /* Mac OS X, NetBSD, AIX, IRIX, Solaris >= 2.5, OSF/1, Cygwin */
66 if (setreuid (-1, uid) < 0)
67 return -1;
68# endif
69
70 /* Verify that the privileges have really been dropped.
71 This verification is here for security reasons. Doesn't matter if it
72 takes a couple of system calls.
73 When the verification fails, it indicates that we need to use different
74 API in the code above. Therefore 'abort ()', not 'return -1'. */
75# if HAVE_GETRESUID /* glibc, FreeBSD, OpenBSD, HP-UX */
76 {
77 uid_t real;
78 uid_t effective;
79 uid_t saved;
80 if (getresuid (&real, &effective, &saved) < 0
81 || real != uid
82 || effective != uid
83 || saved != saved_uid)
84 abort ();
85 }
86# else
87# if HAVE_GETEUID
88 if (geteuid () != uid)
89 abort ();
90# endif
91 if (getuid () != uid)
92 abort ();
93# endif
94# if HAVE_GETRESGID /* glibc, FreeBSD, OpenBSD, HP-UX */
95 {
96 uid_t real;
97 uid_t effective;
98 uid_t saved;
99 if (getresgid (&real, &effective, &saved) < 0
100 || real != gid
101 || effective != gid
102 || saved != saved_gid)
103 abort ();
104 }
105# else
106# if HAVE_GETEGID
107 if (getegid () != gid)
108 abort ();
109# endif
110 if (getgid () != gid)
111 abort ();
112# endif
113
114 return 0;
115#else
116 errno = ENOSYS;
117 return -1;
118#endif
119}
120
121int
122idpriv_temp_restore (void)
123{
124#if HAVE_GETEUID && HAVE_GETEGID && (HAVE_SETRESUID || HAVE_SETREUID) && (HAVE_SETRESGID || HAVE_SETREGID)
125 int uid = getuid ();
126 int gid = getgid ();
127
128 if (saved_uid == -1 || saved_gid == -1)
129 /* Caller error: idpriv_temp_drop was never invoked. */
130 abort ();
131
132 /* Acquire the gid privilege last, because in some cases the gid privilege
133 cannot be acquired before the uid privilege has been acquired. */
134
135 /* This is for executables that have the setuid bit set. */
136# if HAVE_SETRESUID /* glibc, FreeBSD, OpenBSD, HP-UX */
137 /* See <http://www.usenix.org/events/sec02/full_papers/chen/chen.pdf>
138 figure 14. */
139 if (setresuid (-1, saved_uid, -1) < 0)
140 return -1;
141# else /* Mac OS X, NetBSD, AIX, IRIX, Solaris >= 2.5, OSF/1, Cygwin */
142 if (setreuid (-1, saved_uid) < 0)
143 return -1;
144# endif
145
146 /* This is for executables that have the setgid bit set. */
147# if HAVE_SETRESGID /* glibc, FreeBSD, OpenBSD, HP-UX */
148 if (setresgid (-1, saved_gid, -1) < 0)
149 return -1;
150# else /* Mac OS X, NetBSD, AIX, IRIX, Solaris >= 2.5, OSF/1, Cygwin */
151 if (setregid (-1, saved_gid) < 0)
152 return -1;
153# endif
154
155 /* Verify that the privileges have really been acquired.
156 This verification is here for security reasons. Doesn't matter if it
157 takes a couple of system calls.
158 When the verification fails, it indicates that we need to use different
159 API in the code above. Therefore 'abort ()', not 'return -1'. */
160# if HAVE_GETRESUID /* glibc, FreeBSD, OpenBSD, HP-UX */
161 {
162 uid_t real;
163 uid_t effective;
164 uid_t saved;
165 if (getresuid (&real, &effective, &saved) < 0
166 || real != uid
167 || effective != saved_uid
168 || saved != saved_uid)
169 abort ();
170 }
171# else
172# if HAVE_GETEUID
173 if (geteuid () != saved_uid)
174 abort ();
175# endif
176 if (getuid () != uid)
177 abort ();
178# endif
179# if HAVE_GETRESGID /* glibc, FreeBSD, OpenBSD, HP-UX */
180 {
181 uid_t real;
182 uid_t effective;
183 uid_t saved;
184 if (getresgid (&real, &effective, &saved) < 0
185 || real != gid
186 || effective != saved_gid
187 || saved != saved_gid)
188 abort ();
189 }
190# else
191# if HAVE_GETEGID
192 if (getegid () != saved_gid)
193 abort ();
194# endif
195 if (getgid () != gid)
196 abort ();
197# endif
198
199 return 0;
200#else
201 errno = ENOSYS;
202 return -1;
203#endif
204}
diff --git a/gl/idpriv.h b/gl/idpriv.h
new file mode 100644
index 0000000..f454a2c
--- /dev/null
+++ b/gl/idpriv.h
@@ -0,0 +1,116 @@
1/* Dropping uid/gid privileges of the current process.
2 Copyright (C) 2009-2013 Free Software Foundation, Inc.
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
16
17#ifndef _IDPRIV_H
18#define _IDPRIV_H
19
20#ifdef __cplusplus
21extern "C" {
22#endif
23
24/* This module allows programs which are installed with setuid or setgid bit
25 (and which therefore initially run with an effective user id or group id
26 different from the one of the current user) to drop their uid or gid
27 privilege, either permanently or temporarily.
28
29 It is absolutely necessary to minimize the amount of code that is running
30 with escalated privileges (e.g. with effective uid = root). The reason is
31 that any bug or exploit in a part of a program that is running with
32 escalated privileges is a security vulnerability that - upon discovery -
33 puts the users in danger and requires immediate fixing. Then consider that
34 there's a bug every 10 or 20 lines of code on average...
35
36 For programs that temporarily drop privileges but have the ability to
37 restore them later, there are additionally the dangers that
38 - Any bug in the non-privileged part of the program may be used to
39 create invalid data structures that will trigger security
40 vulnerabilities in the privileged part of the program.
41 - Code execution exploits in the non-privileged part of the program may
42 be used to invoke the function that restores high privileges and then
43 execute additional arbitrary code.
44
45 1) The usual, and reasonably safe, way to minimize the amount of code
46 running with privileges is to create a separate executable, with setuid
47 or setgid bit, that contains only code for the tasks that require
48 privileges (and,of course, strict checking of the arguments, so that the
49 program cannot be abused). The main program is installed without setuid
50 or setgid bit.
51
52 2) A less safe way is to do some privileged tasks at the beginning of the
53 program's run, and drop privileges permanently as soon as possible.
54
55 Note: There may still be security issues if the privileged task puts
56 sensitive data into the process memory or opens communication channels
57 to restricted facilities.
58
59 3) The most unsafe way is to drop privileges temporarily for most of the
60 main program but to re-enable them for the duration of privileged tasks.
61
62 As explained above, this approach has uncontrollable dangers for
63 security.
64
65 This approach is normally not usable in multithreaded programs, because
66 you cannot know what kind of system calls the other threads could be
67 doing during the time the privileges are enabled.
68
69 With approach 1, you don't need gnulib modules.
70 With approach 2, you need the gnulib module 'idpriv-drop'.
71 With approach 3, you need the gnulib module 'idpriv-droptemp'. But really,
72 you should better stay away from this approach.
73 */
74
75/* For more in-depth discussion of these topics, see the papers/articles
76 * Hao Chen, David Wagner, Drew Dean: Setuid Demystified
77 <http://www.usenix.org/events/sec02/full_papers/chen/chen.pdf>
78 * Dan Tsafrir, Dilma da Silva, David Wagner: The Murky Issue of Changing
79 Process Identity: Revising "Setuid Demystified"
80 <http://www.eecs.berkeley.edu/~daw/papers/setuid-login08b.pdf>
81 <http://code.google.com/p/change-process-identity/>
82 * Dhruv Mohindra: Observe correct revocation order while relinquishing
83 privileges
84 <https://www.securecoding.cert.org/confluence/display/seccode/POS36-C.+Observe+correct+revocation+order+while+relinquishing+privileges>
85 */
86
87
88/* For approach 2. */
89
90/* Drop the uid and gid privileges of the current process.
91 Return 0 if successful, or -1 with errno set upon failure. The recommended
92 handling of failure is to terminate the process. */
93extern int idpriv_drop (void);
94
95
96/* For approach 3. */
97
98/* Drop the uid and gid privileges of the current process in a way that allows
99 them to be restored later.
100 Return 0 if successful, or -1 with errno set upon failure. The recommended
101 handling of failure is to terminate the process. */
102extern int idpriv_temp_drop (void);
103
104/* Restore the uid and gid privileges of the current process.
105 Return 0 if successful, or -1 with errno set upon failure. The recommended
106 handling of failure is to not perform the actions that require the escalated
107 privileges. */
108extern int idpriv_temp_restore (void);
109
110
111#ifdef __cplusplus
112}
113#endif
114
115
116#endif /* _IDPRIV_H */
diff --git a/gl/m4/gnulib-cache.m4 b/gl/m4/gnulib-cache.m4
index e61a536..d6fca2a 100644
--- a/gl/m4/gnulib-cache.m4
+++ b/gl/m4/gnulib-cache.m4
@@ -27,7 +27,7 @@
27 27
28 28
29# Specification in the form of a command-line invocation: 29# Specification in the form of a command-line invocation:
30# gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files base64 crypto/sha1 dirname environ floorf fsusage getaddrinfo gethostname getloadavg getopt-gnu gettext mountlist regex setenv strcase strsep timegm unsetenv vasprintf vsnprintf 30# gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files base64 crypto/sha1 dirname environ floorf fsusage getaddrinfo gethostname getloadavg getopt-gnu gettext idpriv-droptemp mountlist regex setenv strcase strsep timegm unsetenv vasprintf vsnprintf
31 31
32# Specification in the form of a few gnulib-tool.m4 macro invocations: 32# Specification in the form of a few gnulib-tool.m4 macro invocations:
33gl_LOCAL_DIR([]) 33gl_LOCAL_DIR([])
@@ -43,6 +43,7 @@ gl_MODULES([
43 getloadavg 43 getloadavg
44 getopt-gnu 44 getopt-gnu
45 gettext 45 gettext
46 idpriv-droptemp
46 mountlist 47 mountlist
47 regex 48 regex
48 setenv 49 setenv
diff --git a/gl/m4/gnulib-comp.m4 b/gl/m4/gnulib-comp.m4
index b3cb4c1..67a8156 100644
--- a/gl/m4/gnulib-comp.m4
+++ b/gl/m4/gnulib-comp.m4
@@ -28,7 +28,7 @@
28# other built files. 28# other built files.
29 29
30 30
31# This macro should be invoked from ./configure.in, in the section 31# This macro should be invoked from ./configure.ac, in the section
32# "Checks for programs", right after AC_PROG_CC, and certainly before 32# "Checks for programs", right after AC_PROG_CC, and certainly before
33# any checks for libraries, header files, types and library functions. 33# any checks for libraries, header files, types and library functions.
34AC_DEFUN([gl_EARLY], 34AC_DEFUN([gl_EARLY],
@@ -70,6 +70,7 @@ AC_DEFUN([gl_EARLY],
70 # Code from module gettext-h: 70 # Code from module gettext-h:
71 # Code from module havelib: 71 # Code from module havelib:
72 # Code from module hostent: 72 # Code from module hostent:
73 # Code from module idpriv-droptemp:
73 # Code from module include_next: 74 # Code from module include_next:
74 # Code from module inet_ntop: 75 # Code from module inet_ntop:
75 # Code from module intprops: 76 # Code from module intprops:
@@ -153,7 +154,7 @@ AC_DEFUN([gl_EARLY],
153 # Code from module xstrndup: 154 # Code from module xstrndup:
154]) 155])
155 156
156# This macro should be invoked from ./configure.in, in the section 157# This macro should be invoked from ./configure.ac, in the section
157# "Check for header files, types and library functions". 158# "Check for header files, types and library functions".
158AC_DEFUN([gl_INIT], 159AC_DEFUN([gl_INIT],
159[ 160[
@@ -258,6 +259,7 @@ AC_DEFUN([gl_INIT],
258 AC_SUBST([LIBINTL]) 259 AC_SUBST([LIBINTL])
259 AC_SUBST([LTLIBINTL]) 260 AC_SUBST([LTLIBINTL])
260 gl_HOSTENT 261 gl_HOSTENT
262 gl_IDPRIV
261 gl_FUNC_INET_NTOP 263 gl_FUNC_INET_NTOP
262 if test $HAVE_INET_NTOP = 0 || test $REPLACE_INET_NTOP = 1; then 264 if test $HAVE_INET_NTOP = 0 || test $REPLACE_INET_NTOP = 1; then
263 AC_LIBOBJ([inet_ntop]) 265 AC_LIBOBJ([inet_ntop])
@@ -658,6 +660,8 @@ AC_DEFUN([gl_FILE_LIST], [
658 lib/glthread/lock.c 660 lib/glthread/lock.c
659 lib/glthread/lock.h 661 lib/glthread/lock.h
660 lib/glthread/threadlib.c 662 lib/glthread/threadlib.c
663 lib/idpriv-droptemp.c
664 lib/idpriv.h
661 lib/inet_ntop.c 665 lib/inet_ntop.c
662 lib/intprops.h 666 lib/intprops.h
663 lib/itold.c 667 lib/itold.c
@@ -790,6 +794,7 @@ AC_DEFUN([gl_FILE_LIST], [
790 m4/gnulib-common.m4 794 m4/gnulib-common.m4
791 m4/hostent.m4 795 m4/hostent.m4
792 m4/iconv.m4 796 m4/iconv.m4
797 m4/idpriv.m4
793 m4/include_next.m4 798 m4/include_next.m4
794 m4/inet_ntop.m4 799 m4/inet_ntop.m4
795 m4/intdiv0.m4 800 m4/intdiv0.m4
diff --git a/gl/m4/idpriv.m4 b/gl/m4/idpriv.m4
new file mode 100644
index 0000000..167f523
--- /dev/null
+++ b/gl/m4/idpriv.m4
@@ -0,0 +1,14 @@
1# idpriv.m4 serial 1
2dnl Copyright (C) 2009-2013 Free Software Foundation, Inc.
3dnl This file is free software; the Free Software Foundation
4dnl gives unlimited permission to copy and/or distribute it,
5dnl with or without modifications, as long as this notice is preserved.
6
7AC_DEFUN([gl_IDPRIV],
8[
9 dnl Persuade glibc <unistd.h> to declare {get,set}res{uid,gid}.
10 AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
11
12 AC_CHECK_FUNCS_ONCE([getuid geteuid getresuid getgid getegid getresgid])
13 AC_CHECK_FUNCS_ONCE([setresuid setreuid seteuid setresgid setregid setegid])
14])
diff --git a/lib/parse_ini.c b/lib/parse_ini.c
index 76953e9..25abc89 100644
--- a/lib/parse_ini.c
+++ b/lib/parse_ini.c
@@ -22,16 +22,15 @@
22*****************************************************************************/ 22*****************************************************************************/
23 23
24#include "common.h" 24#include "common.h"
25#include "idpriv.h"
25#include "utils_base.h" 26#include "utils_base.h"
26#include "parse_ini.h" 27#include "parse_ini.h"
27#include <ctype.h>
28 28
29#include <ctype.h>
29#include <sys/types.h> 30#include <sys/types.h>
30#include <sys/stat.h> 31#include <sys/stat.h>
31#include <unistd.h> 32#include <unistd.h>
32 33
33/* TODO: die like N::P if config file is not found */
34
35/* np_ini_info contains the result of parsing a "locator" in the format 34/* np_ini_info contains the result of parsing a "locator" in the format
36 * [stanza_name][@config_filename] (check_foo@/etc/foo.ini, for example) 35 * [stanza_name][@config_filename] (check_foo@/etc/foo.ini, for example)
37 */ 36 */
@@ -40,254 +39,314 @@ typedef struct {
40 char *stanza; 39 char *stanza;
41} np_ini_info; 40} np_ini_info;
42 41
42static char *default_ini_file_names[] = {
43 "monitoring-plugins.ini",
44 "plugins.ini",
45 "nagios-plugins.ini",
46 NULL
47};
48
49static char *default_ini_path_names[] = {
50 "/usr/local/etc/monitoring-plugins/monitoring-plugins.ini",
51 "/usr/local/etc/monitoring-plugins.ini",
52 "/etc/monitoring-plugins/monitoring-plugins.ini",
53 "/etc/monitoring-plugins.ini",
54 /* deprecated path names (for backward compatibility): */
55 "/etc/nagios/plugins.ini",
56 "/usr/local/nagios/etc/plugins.ini",
57 "/usr/local/etc/nagios/plugins.ini",
58 "/etc/opt/nagios/plugins.ini",
59 "/etc/nagios-plugins.ini",
60 "/usr/local/etc/nagios-plugins.ini",
61 "/etc/opt/nagios-plugins.ini",
62 NULL
63};
64
43/* eat all characters from a FILE pointer until n is encountered */ 65/* eat all characters from a FILE pointer until n is encountered */
44#define GOBBLE_TO(f, c, n) do { (c)=fgetc((f)); } while((c)!=EOF && (c)!=(n)) 66#define GOBBLE_TO(f, c, n) do { (c)=fgetc((f)); } while((c)!=EOF && (c)!=(n))
45 67
46/* internal function that returns the constructed defaults options */ 68/* internal function that returns the constructed defaults options */
47static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts); 69static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts);
70
48/* internal function that converts a single line into options format */ 71/* internal function that converts a single line into options format */
49static int add_option(FILE *f, np_arg_list **optlst); 72static int add_option(FILE *f, np_arg_list **optlst);
50/* internal function to find default file */
51static char* default_file(void);
52/* internal function to test files access */
53static int test_file(const char* env, int len, const char* file, char* temp_file);
54 73
55/* parse_locator decomposes a string of the form 74/* internal functions to find default file */
75static char *default_file(void);
76static char *default_file_in_path(void);
77
78/*
79 * Parse_locator decomposes a string of the form
56 * [stanza][@filename] 80 * [stanza][@filename]
57 * into its seperate parts 81 * into its seperate parts.
58 */ 82 */
59static void parse_locator(const char *locator, const char *def_stanza, np_ini_info *i){ 83static void
60 size_t locator_len=0, stanza_len=0; 84parse_locator(const char *locator, const char *def_stanza, np_ini_info *i)
85{
86 size_t locator_len = 0, stanza_len = 0;
61 87
62 /* if locator is NULL we'll use default values */ 88 /* if locator is NULL we'll use default values */
63 if(locator){ 89 if (locator != NULL) {
64 locator_len=strlen(locator); 90 locator_len = strlen(locator);
65 stanza_len=strcspn(locator, "@"); 91 stanza_len = strcspn(locator, "@");
66 } 92 }
67 /* if a non-default stanza is provided */ 93 /* if a non-default stanza is provided */
68 if(stanza_len>0){ 94 if (stanza_len > 0) {
69 i->stanza=(char*)malloc(sizeof(char)*(stanza_len+1)); 95 i->stanza = malloc(sizeof(char) * (stanza_len + 1));
70 strncpy(i->stanza, locator, stanza_len); 96 strncpy(i->stanza, locator, stanza_len);
71 i->stanza[stanza_len]='\0'; 97 i->stanza[stanza_len] = '\0';
72 } else { /* otherwise we use the default stanza */ 98 } else /* otherwise we use the default stanza */
73 i->stanza=strdup(def_stanza); 99 i->stanza = strdup(def_stanza);
74 }
75 /* if there is no @file part */
76 if(stanza_len==locator_len){
77 i->file=default_file();
78 if(strcmp(i->file, "") == 0){
79 die(STATE_UNKNOWN, _("Cannot find '%s' or '%s' in any standard location.\n"), NP_DEFAULT_INI_FILENAME1, NP_DEFAULT_INI_FILENAME2);
80 }
81 } else {
82 i->file=strdup(&(locator[stanza_len+1]));
83 }
84 100
85 if(i->file==NULL || i->stanza==NULL){ 101 if (i->stanza == NULL)
86 die(STATE_UNKNOWN, _("malloc() failed!\n")); 102 die(STATE_UNKNOWN, _("malloc() failed!\n"));
87 } 103
104 /* check whether there's an @file part */
105 i->file = stanza_len == locator_len
106 ? default_file()
107 : strdup(&(locator[stanza_len + 1]));
108 if (i->file == NULL || i->file[0] == '\0')
109 die(STATE_UNKNOWN,
110 _("Cannot find config file in any standard location.\n"));
88} 111}
89 112
90/* this is the externally visible function used by extra_opts */ 113/*
91np_arg_list* np_get_defaults(const char *locator, const char *default_section){ 114 * This is the externally visible function used by extra_opts.
92 FILE *inifile=NULL; 115 */
93 np_arg_list *defaults=NULL; 116np_arg_list *
117np_get_defaults(const char *locator, const char *default_section)
118{
119 FILE *inifile = NULL;
120 np_arg_list *defaults = NULL;
94 np_ini_info i; 121 np_ini_info i;
122 int is_suid_plugin = mp_suid();
95 123
96 parse_locator(locator, default_section, &i); 124 if (is_suid_plugin && idpriv_temp_drop() == -1)
97 /* if a file was specified or if we're using the default file */ 125 die(STATE_UNKNOWN, _("Cannot drop privileges: %s\n"),
98 if(i.file != NULL && strlen(i.file) > 0){ 126 strerror(errno));
99 if(strcmp(i.file, "-")==0){
100 inifile=stdin;
101 } else {
102 inifile=fopen(i.file, "r");
103 }
104 if(inifile==NULL) die(STATE_UNKNOWN, "%s\n", _("Can't read config file"));
105 if(read_defaults(inifile, i.stanza, &defaults)==FALSE)
106 die(STATE_UNKNOWN, _("Invalid section '%s' in config file '%s'\n"), i.stanza, i.file);
107 127
108 free(i.file); 128 parse_locator(locator, default_section, &i);
109 if(inifile!=stdin) fclose(inifile); 129 inifile = strcmp(i.file, "-") == 0 ? stdin : fopen(i.file, "r");
110 } 130
131 if (inifile == NULL)
132 die(STATE_UNKNOWN, _("Can't read config file: %s\n"),
133 strerror(errno));
134 if (read_defaults(inifile, i.stanza, &defaults) == FALSE)
135 die(STATE_UNKNOWN,
136 _("Invalid section '%s' in config file '%s'\n"), i.stanza,
137 i.file);
138
139 free(i.file);
140 if (inifile != stdin)
141 fclose(inifile);
111 free(i.stanza); 142 free(i.stanza);
143 if (is_suid_plugin && idpriv_temp_restore() == -1)
144 die(STATE_UNKNOWN, _("Cannot restore privileges: %s\n"),
145 strerror(errno));
146
112 return defaults; 147 return defaults;
113} 148}
114 149
115/* read_defaults is where the meat of the parsing takes place. 150/*
151 * The read_defaults() function is where the meat of the parsing takes place.
116 * 152 *
117 * note that this may be called by a setuid binary, so we need to 153 * Note that this may be called by a setuid binary, so we need to
118 * be extra careful about user-supplied input (i.e. avoiding possible 154 * be extra careful about user-supplied input (i.e. avoiding possible
119 * format string vulnerabilities, etc) 155 * format string vulnerabilities, etc).
120 */ 156 */
121static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts){ 157static int
122 int c, status=FALSE; 158read_defaults(FILE *f, const char *stanza, np_arg_list **opts)
159{
160 int c, status = FALSE;
123 size_t i, stanza_len; 161 size_t i, stanza_len;
124 enum { NOSTANZA, WRONGSTANZA, RIGHTSTANZA } stanzastate=NOSTANZA; 162 enum { NOSTANZA, WRONGSTANZA, RIGHTSTANZA } stanzastate = NOSTANZA;
125 163
126 stanza_len=strlen(stanza); 164 stanza_len = strlen(stanza);
127 165
128 /* our little stanza-parsing state machine. */ 166 /* our little stanza-parsing state machine */
129 while((c=fgetc(f))!=EOF){ 167 while ((c = fgetc(f)) != EOF) {
130 /* gobble up leading whitespace */ 168 /* gobble up leading whitespace */
131 if(isspace(c)) continue; 169 if (isspace(c))
132 switch(c){ 170 continue;
171 switch (c) {
133 /* globble up coment lines */ 172 /* globble up coment lines */
134 case ';': 173 case ';':
135 case '#': 174 case '#':
136 GOBBLE_TO(f, c, '\n'); 175 GOBBLE_TO(f, c, '\n');
137 break; 176 break;
138 /* start of a stanza. check to see if it matches */ 177 /* start of a stanza, check to see if it matches */
139 case '[': 178 case '[':
140 stanzastate=WRONGSTANZA; 179 stanzastate = WRONGSTANZA;
141 for(i=0; i<stanza_len; i++){ 180 for (i = 0; i < stanza_len; i++) {
142 c=fgetc(f); 181 c = fgetc(f);
143 /* Strip leading whitespace */ 182 /* strip leading whitespace */
144 if(i==0) for(c; isspace(c); c=fgetc(f)); 183 if (i == 0)
145 /* nope, read to the end of the line */ 184 for (; isspace(c); c = fgetc(f))
146 if(c!=stanza[i]) { 185 continue;
147 GOBBLE_TO(f, c, '\n'); 186 /* nope, read to the end of the line */
148 break; 187 if (c != stanza[i]) {
149 } 188 GOBBLE_TO(f, c, '\n');
150 } 189 break;
151 /* if it matched up to here and the next char is ']'... */
152 if(i==stanza_len){
153 c=fgetc(f);
154 /* Strip trailing whitespace */
155 for(c; isspace(c); c=fgetc(f));
156 if(c==']') stanzastate=RIGHTSTANZA;
157 } 190 }
158 break; 191 }
192 /* if it matched up to here and the next char is ']'... */
193 if (i == stanza_len) {
194 c = fgetc(f);
195 /* strip trailing whitespace */
196 for (; isspace(c); c = fgetc(f))
197 continue;
198 if (c == ']')
199 stanzastate = RIGHTSTANZA;
200 }
201 break;
159 /* otherwise, we're in the body of a stanza or a parse error */ 202 /* otherwise, we're in the body of a stanza or a parse error */
160 default: 203 default:
161 switch(stanzastate){ 204 switch (stanzastate) {
162 /* we never found the start of the first stanza, so 205 /* we never found the start of the first stanza, so
163 * we're dealing with a config error 206 * we're dealing with a config error
164 */ 207 */
165 case NOSTANZA: 208 case NOSTANZA:
166 die(STATE_UNKNOWN, "%s\n", _("Config file error")); 209 die(STATE_UNKNOWN, "%s\n",
167 break; 210 _("Config file error"));
168 /* we're in a stanza, but for a different plugin */ 211 /* we're in a stanza, but for a different plugin */
169 case WRONGSTANZA: 212 case WRONGSTANZA:
170 GOBBLE_TO(f, c, '\n'); 213 GOBBLE_TO(f, c, '\n');
171 break; 214 break;
172 /* okay, this is where we start taking the config */ 215 /* okay, this is where we start taking the config */
173 case RIGHTSTANZA: 216 case RIGHTSTANZA:
174 ungetc(c, f); 217 ungetc(c, f);
175 if(add_option(f, opts)){ 218 if (add_option(f, opts)) {
176 die(STATE_UNKNOWN, "%s\n", _("Config file error")); 219 die(STATE_UNKNOWN, "%s\n",
177 } 220 _("Config file error"));
178 status=TRUE;
179 break;
180 } 221 }
222 status = TRUE;
181 break; 223 break;
224 }
225 break;
182 } 226 }
183 } 227 }
184 return status; 228 return status;
185} 229}
186 230
187/* 231/*
188 * read one line of input in the format 232 * Read one line of input in the format
189 * ^option[[:space:]]*(=[[:space:]]*value)? 233 * ^option[[:space:]]*(=[[:space:]]*value)?
190 * and creates it as a cmdline argument 234 * and create it as a cmdline argument
191 * --option[=value] 235 * --option[=value]
192 * appending it to the linked list optbuf. 236 * appending it to the linked list optbuf.
193 */ 237 */
194static int add_option(FILE *f, np_arg_list **optlst){ 238static int
195 np_arg_list *opttmp=*optlst, *optnew; 239add_option(FILE *f, np_arg_list **optlst)
196 char *linebuf=NULL, *lineend=NULL, *optptr=NULL, *optend=NULL; 240{
197 char *eqptr=NULL, *valptr=NULL, *spaceptr=NULL, *valend=NULL; 241 np_arg_list *opttmp = *optlst, *optnew;
198 short done_reading=0, equals=0, value=0; 242 char *linebuf = NULL, *lineend = NULL, *optptr = NULL, *optend = NULL;
199 size_t cfg_len=0, read_sz=8, linebuf_sz=0, read_pos=0; 243 char *eqptr = NULL, *valptr = NULL, *valend = NULL;
200 size_t opt_len=0, val_len=0; 244 short done_reading = 0, equals = 0, value = 0;
245 size_t cfg_len = 0, read_sz = 8, linebuf_sz = 0, read_pos = 0;
246 size_t opt_len = 0, val_len = 0;
201 247
202 /* read one line from the file */ 248 /* read one line from the file */
203 while(!done_reading){ 249 while (!done_reading) {
204 /* grow if necessary */ 250 /* grow if necessary */
205 if(linebuf==NULL || read_pos+read_sz >= linebuf_sz){ 251 if (linebuf == NULL || read_pos + read_sz >= linebuf_sz) {
206 linebuf_sz=(linebuf_sz>0)?linebuf_sz<<1:read_sz; 252 linebuf_sz = linebuf_sz > 0 ? linebuf_sz << 1 : read_sz;
207 linebuf=realloc(linebuf, linebuf_sz); 253 linebuf = realloc(linebuf, linebuf_sz);
208 if(linebuf==NULL) die(STATE_UNKNOWN, _("malloc() failed!\n")); 254 if (linebuf == NULL)
255 die(STATE_UNKNOWN, _("malloc() failed!\n"));
209 } 256 }
210 if(fgets(&linebuf[read_pos], read_sz, f)==NULL) done_reading=1; 257 if (fgets(&linebuf[read_pos], (int)read_sz, f) == NULL)
258 done_reading = 1;
211 else { 259 else {
212 read_pos=strlen(linebuf); 260 read_pos = strlen(linebuf);
213 if(linebuf[read_pos-1]=='\n') { 261 if (linebuf[read_pos - 1] == '\n') {
214 linebuf[--read_pos]='\0'; 262 linebuf[--read_pos] = '\0';
215 done_reading=1; 263 done_reading = 1;
216 } 264 }
217 } 265 }
218 } 266 }
219 lineend=&linebuf[read_pos]; 267 lineend = &linebuf[read_pos];
220 /* all that to read one line. isn't C fun? :) now comes the parsing :/ */ 268 /* all that to read one line, isn't C fun? :) now comes the parsing :/ */
221 269
222 /* skip leading whitespace */ 270 /* skip leading whitespace */
223 for(optptr=linebuf; optptr<lineend && isspace(*optptr); optptr++); 271 for (optptr = linebuf; optptr < lineend && isspace(*optptr); optptr++)
272 continue;
224 /* continue to '=' or EOL, watching for spaces that might precede it */ 273 /* continue to '=' or EOL, watching for spaces that might precede it */
225 for(eqptr=optptr; eqptr<lineend && *eqptr!='='; eqptr++){ 274 for (eqptr = optptr; eqptr < lineend && *eqptr != '='; eqptr++) {
226 if(isspace(*eqptr) && optend==NULL) optend=eqptr; 275 if (isspace(*eqptr) && optend == NULL)
227 else optend=NULL; 276 optend = eqptr;
277 else
278 optend = NULL;
228 } 279 }
229 if(optend==NULL) optend=eqptr; 280 if (optend == NULL)
281 optend = eqptr;
230 --optend; 282 --optend;
231 /* ^[[:space:]]*=foo is a syntax error */ 283 /* ^[[:space:]]*=foo is a syntax error */
232 if(optptr==eqptr) die(STATE_UNKNOWN, "%s\n", _("Config file error")); 284 if (optptr == eqptr)
285 die(STATE_UNKNOWN, "%s\n", _("Config file error"));
233 /* continue from '=' to start of value or EOL */ 286 /* continue from '=' to start of value or EOL */
234 for(valptr=eqptr+1; valptr<lineend && isspace(*valptr); valptr++); 287 for (valptr = eqptr + 1; valptr < lineend && isspace(*valptr);
288 valptr++)
289 continue;
235 /* continue to the end of value */ 290 /* continue to the end of value */
236 for(valend=valptr; valend<lineend; valend++); 291 for (valend = valptr; valend < lineend; valend++)
292 continue;
237 --valend; 293 --valend;
238 /* Finally trim off trailing spaces */ 294 /* finally trim off trailing spaces */
239 for(valend; isspace(*valend); valend--); 295 for (; isspace(*valend); valend--)
296 continue;
240 /* calculate the length of "--foo" */ 297 /* calculate the length of "--foo" */
241 opt_len=1+optend-optptr; 298 opt_len = (size_t)(1 + optend - optptr);
242 /* 1-character params needs only one dash */ 299 /* 1-character params needs only one dash */
243 if(opt_len==1) 300 if (opt_len == 1)
244 cfg_len=1+(opt_len); 301 cfg_len = 1 + (opt_len);
245 else 302 else
246 cfg_len=2+(opt_len); 303 cfg_len = 2 + (opt_len);
247 /* if valptr<lineend then we have to also allocate space for "=bar" */ 304 /* if valptr<lineend then we have to also allocate space for "=bar" */
248 if(valptr<lineend) { 305 if (valptr < lineend) {
249 equals=value=1; 306 equals = value = 1;
250 val_len=1+valend-valptr; 307 val_len = (size_t)(1 + valend - valptr);
251 cfg_len+=1+val_len; 308 cfg_len += 1 + val_len;
252 } 309 }
253 /* if valptr==valend then we have "=" but no "bar" */ 310 /* if valptr==valend then we have "=" but no "bar" */
254 else if(valptr==lineend) { 311 else if (valptr == lineend) {
255 equals=1; 312 equals = 1;
256 cfg_len+=1; 313 cfg_len += 1;
257 } 314 }
258 /* A line with no equal sign isn't valid */ 315 /* a line with no equal sign isn't valid */
259 if(equals==0) die(STATE_UNKNOWN, "%s\n", _("Config file error")); 316 if (equals == 0)
317 die(STATE_UNKNOWN, "%s\n", _("Config file error"));
260 318
261 /* okay, now we have all the info we need, so we create a new np_arg_list 319 /* okay, now we have all the info we need, so we create a new np_arg_list
262 * element and set the argument... 320 * element and set the argument...
263 */ 321 */
264 optnew=(np_arg_list *)malloc(sizeof(np_arg_list)); 322 optnew = malloc(sizeof(np_arg_list));
265 optnew->next=NULL; 323 optnew->next = NULL;
266 324
267 read_pos=0; 325 read_pos = 0;
268 optnew->arg=(char *)malloc(cfg_len+1); 326 optnew->arg = malloc(cfg_len + 1);
269 /* 1-character params needs only one dash */ 327 /* 1-character params needs only one dash */
270 if(opt_len==1) { 328 if (opt_len == 1) {
271 strncpy(&optnew->arg[read_pos], "-", 1); 329 strncpy(&optnew->arg[read_pos], "-", 1);
272 read_pos+=1; 330 read_pos += 1;
273 } else { 331 } else {
274 strncpy(&optnew->arg[read_pos], "--", 2); 332 strncpy(&optnew->arg[read_pos], "--", 2);
275 read_pos+=2; 333 read_pos += 2;
276 } 334 }
277 strncpy(&optnew->arg[read_pos], optptr, opt_len); read_pos+=opt_len; 335 strncpy(&optnew->arg[read_pos], optptr, opt_len);
278 if(value) { 336 read_pos += opt_len;
279 optnew->arg[read_pos++]='='; 337 if (value) {
280 strncpy(&optnew->arg[read_pos], valptr, val_len); read_pos+=val_len; 338 optnew->arg[read_pos++] = '=';
339 strncpy(&optnew->arg[read_pos], valptr, val_len);
340 read_pos += val_len;
281 } 341 }
282 optnew->arg[read_pos]='\0'; 342 optnew->arg[read_pos] = '\0';
283 343
284 /* ...and put that to the end of the list */ 344 /* ...and put that to the end of the list */
285 if(*optlst==NULL) { 345 if (*optlst == NULL)
286 *optlst=optnew; 346 *optlst = optnew;
287 } else { 347 else {
288 while(opttmp->next!=NULL) { 348 while (opttmp->next != NULL)
289 opttmp=opttmp->next; 349 opttmp = opttmp->next;
290 }
291 opttmp->next = optnew; 350 opttmp->next = optnew;
292 } 351 }
293 352
@@ -295,71 +354,42 @@ static int add_option(FILE *f, np_arg_list **optlst){
295 return 0; 354 return 0;
296} 355}
297 356
298static char* default_file(void){ 357static char *
299 struct stat sb; 358default_file(void)
300 char *np_env=NULL, *default_file=NULL; 359{
301 char temp_file[MAX_INPUT_BUFFER]; 360 char **p, *ini_file;
302 size_t len; 361
303 362 if ((ini_file = getenv("MP_CONFIG_FILE")) != NULL ||
304 if((np_env=getenv("NAGIOS_CONFIG_PATH"))!=NULL) { 363 (ini_file = default_file_in_path()) != NULL)
305 /* skip any starting colon... */ 364 return ini_file;
306 while(*np_env==':') np_env++; 365 for (p = default_ini_path_names; *p != NULL; p++)
307 /* Look for NP_DEFAULT_INI_FILENAME1 and NP_DEFAULT_INI_FILENAME2 in 366 if (access(*p, F_OK) == 0)
308 * every PATHs defined (colon-separated). 367 return *p;
309 */ 368 return NULL;
310 while((len=strcspn(np_env,":"))>0){
311 /* Test NP_DEFAULT_INI_FILENAME[1-2] in current np_env token */
312 if(test_file(np_env,len,NP_DEFAULT_INI_FILENAME1,temp_file)==1 ||
313 test_file(np_env,len,NP_DEFAULT_INI_FILENAME2,temp_file)==1){
314 default_file=strdup(temp_file);
315 break;
316 }
317
318 /* Move on to the next token */
319 np_env+=len;
320 while(*np_env==':') np_env++;
321 } /* while(...) */
322 } /* if(getenv("NAGIOS_CONFIG_PATH")) */
323
324 /* Look for NP_DEFAULT_INI_FILENAME1 in NP_DEFAULT_INI_NAGIOS_PATH[1-4] */
325 if(!default_file){
326 if(test_file(NP_DEFAULT_INI_NAGIOS_PATH1,strlen(NP_DEFAULT_INI_NAGIOS_PATH1),NP_DEFAULT_INI_FILENAME1,temp_file)==1 ||
327 test_file(NP_DEFAULT_INI_NAGIOS_PATH2,strlen(NP_DEFAULT_INI_NAGIOS_PATH2),NP_DEFAULT_INI_FILENAME1,temp_file)==1 ||
328 test_file(NP_DEFAULT_INI_NAGIOS_PATH3,strlen(NP_DEFAULT_INI_NAGIOS_PATH3),NP_DEFAULT_INI_FILENAME1,temp_file)==1 ||
329 test_file(NP_DEFAULT_INI_NAGIOS_PATH4,strlen(NP_DEFAULT_INI_NAGIOS_PATH4),NP_DEFAULT_INI_FILENAME1,temp_file)==1)
330 default_file=strdup(temp_file);
331 }
332
333 /* Look for NP_DEFAULT_INI_FILENAME2 in NP_DEFAULT_INI_PATH[1-3] */
334 if(!default_file){
335 if(test_file(NP_DEFAULT_INI_PATH1,strlen(NP_DEFAULT_INI_PATH1),NP_DEFAULT_INI_FILENAME2,temp_file)==1 ||
336 test_file(NP_DEFAULT_INI_PATH2,strlen(NP_DEFAULT_INI_PATH2),NP_DEFAULT_INI_FILENAME2,temp_file)==1 ||
337 test_file(NP_DEFAULT_INI_PATH3,strlen(NP_DEFAULT_INI_PATH3),NP_DEFAULT_INI_FILENAME2,temp_file)==1)
338 default_file=strdup(temp_file);
339 }
340
341 /* Return default_file or empty string (should return NULL if we want plugins
342 * to die there)...
343 */
344 if(default_file)
345 return default_file;
346 return "";
347} 369}
348 370
349/* put together len bytes from env and the filename and test for its 371static char *
350 * existence. Returns 1 if found, 0 if not and -1 if test wasn't performed. 372default_file_in_path(void)
351 */ 373{
352static int test_file(const char* env, int len, const char* file, char* temp_file){ 374 char *config_path, **file;
353 375 char *dir, *ini_file, *tokens;
354 /* test if len + filelen + '/' + '\0' fits in temp_file */ 376
355 if((len+strlen(file)+2)>MAX_INPUT_BUFFER) return -1; 377 if ((config_path = getenv("NAGIOS_CONFIG_PATH")) == NULL)
356 378 return NULL;
357 strncpy(temp_file,env,len); 379 /* shall we spit out a warning that NAGIOS_CONFIG_PATH is deprecated? */
358 temp_file[len]='\0'; 380
359 strncat(temp_file,"/",len+1); 381 if ((tokens = strdup(config_path)) == NULL)
360 strncat(temp_file,file,len+strlen(file)+1); 382 die(STATE_UNKNOWN, "%s\n", _("Insufficient Memory"));
361 383 for (dir = strtok(tokens, ":"); dir != NULL; dir = strtok(NULL, ":")) {
362 if(access(temp_file, F_OK) == 0) return 1; 384 for (file = default_ini_file_names; *file != NULL; file++) {
363 return 0; 385 if ((asprintf(&ini_file, "%s/%s", dir, *file)) < 0)
386 die(STATE_UNKNOWN, "%s\n", _("Insufficient Memory"));
387 if (access(ini_file, F_OK) == 0) {
388 free(tokens);
389 return ini_file;
390 }
391 }
392 }
393 free(tokens);
394 return NULL;
364} 395}
365
diff --git a/lib/parse_ini.h b/lib/parse_ini.h
index a3a494e..e37601b 100644
--- a/lib/parse_ini.h
+++ b/lib/parse_ini.h
@@ -13,50 +13,10 @@ typedef struct np_arg_el {
13 struct np_arg_el *next; 13 struct np_arg_el *next;
14} np_arg_list; 14} np_arg_list;
15 15
16/* FIXME: This is in plugins/common.c. Should be eventually moved to lib/
17 * (although for this particular one a configure settings should be ideal)
18 */
19#ifndef MAX_INPUT_BUFFER
20# define MAX_INPUT_BUFFER 8192
21#endif /* MAX_INPUT_BUFFER */
22
23/* Filenames (see below) */
24#ifndef NP_DEFAULT_INI_FILENAME1
25# define NP_DEFAULT_INI_FILENAME1 "plugins.ini"
26#endif /* NP_DEFAULT_INI_FILENAME1 */
27#ifndef NP_DEFAULT_INI_FILENAME2
28# define NP_DEFAULT_INI_FILENAME2 "nagios-plugins.ini"
29#endif /* NP_DEFAULT_INI_FILENAME2 */
30
31/* Config paths ending in nagios (search for NP_DEFAULT_INI_FILENAME1) */
32#ifndef NP_DEFAULT_INI_NAGIOS_PATH1
33# define NP_DEFAULT_INI_NAGIOS_PATH1 "/etc/nagios"
34#endif /* NP_DEFAULT_INI_NAGIOS_PATH1 */
35#ifndef NP_DEFAULT_INI_NAGIOS_PATH2
36# define NP_DEFAULT_INI_NAGIOS_PATH2 "/usr/local/nagios/etc"
37#endif /* NP_DEFAULT_INI_NAGIOS_PATH2 */
38#ifndef NP_DEFAULT_INI_NAGIOS_PATH3
39# define NP_DEFAULT_INI_NAGIOS_PATH3 "/usr/local/etc/nagios"
40#endif /* NP_DEFAULT_INI_NAGIOS_PATH3 */
41#ifndef NP_DEFAULT_INI_NAGIOS_PATH4
42# define NP_DEFAULT_INI_NAGIOS_PATH4 "/etc/opt/nagios"
43#endif /* NP_DEFAULT_INI_NAGIOS_PATH4 */
44
45/* Config paths not ending in nagios (search for NP_DEFAULT_INI_FILENAME2) */
46#ifndef NP_DEFAULT_INI_PATH1
47# define NP_DEFAULT_INI_PATH1 "/etc"
48#endif /* NP_DEFAULT_INI_PATH1 */
49#ifndef NP_DEFAULT_INI_PATH2
50# define NP_DEFAULT_INI_PATH2 "/usr/local/etc"
51#endif /* NP_DEFAULT_INI_PATH2 */
52#ifndef NP_DEFAULT_INI_PATH3
53# define NP_DEFAULT_INI_PATH3 "/etc/opt"
54#endif /* NP_DEFAULT_INI_PATH3 */
55
56/* np_load_defaults: load the default configuration (if present) for 16/* np_load_defaults: load the default configuration (if present) for
57 * a plugin from the ini file 17 * a plugin from the ini file
58 */ 18 */
59np_arg_list* np_get_defaults(const char *locator, const char *default_section); 19np_arg_list *np_get_defaults(const char *locator, const char *default_section);
60 20
61#endif /* _PARSE_INI_H_ */ 21#endif /* _PARSE_INI_H_ */
62 22
diff --git a/lib/tests/test_utils.c b/lib/tests/test_utils.c
index 356887d..f35b7e2 100644
--- a/lib/tests/test_utils.c
+++ b/lib/tests/test_utils.c
@@ -21,6 +21,7 @@
21 21
22#include "tap.h" 22#include "tap.h"
23 23
24#include <unistd.h>
24#include <sys/types.h> 25#include <sys/types.h>
25#include <sys/stat.h> 26#include <sys/stat.h>
26 27
@@ -29,6 +30,7 @@
29int 30int
30main (int argc, char **argv) 31main (int argc, char **argv)
31{ 32{
33 char state_path[1024];
32 range *range; 34 range *range;
33 double temp; 35 double temp;
34 thresholds *thresholds = NULL; 36 thresholds *thresholds = NULL;
@@ -345,9 +347,10 @@ main (int argc, char **argv)
345 347
346 np_enable_state("allowedchars_in_keyname", 77); 348 np_enable_state("allowedchars_in_keyname", 77);
347 temp_state_key = this_monitoring_plugin->state; 349 temp_state_key = this_monitoring_plugin->state;
350 sprintf(state_path, "/usr/local/nagios/var/%lu/check_test/allowedchars_in_keyname", (unsigned long)geteuid());
348 ok( !strcmp(temp_state_key->plugin_name, "check_test"), "Got plugin name" ); 351 ok( !strcmp(temp_state_key->plugin_name, "check_test"), "Got plugin name" );
349 ok( !strcmp(temp_state_key->name, "allowedchars_in_keyname"), "Got key name with valid chars" ); 352 ok( !strcmp(temp_state_key->name, "allowedchars_in_keyname"), "Got key name with valid chars" );
350 ok( !strcmp(temp_state_key->_filename, "/usr/local/nagios/var/check_test/allowedchars_in_keyname"), "Got internal filename" ); 353 ok( !strcmp(temp_state_key->_filename, state_path), "Got internal filename" );
351 354
352 355
353 /* Don't do this test just yet. Will die */ 356 /* Don't do this test just yet. Will die */
@@ -359,12 +362,13 @@ main (int argc, char **argv)
359 362
360 np_enable_state("funnykeyname", 54); 363 np_enable_state("funnykeyname", 54);
361 temp_state_key = this_monitoring_plugin->state; 364 temp_state_key = this_monitoring_plugin->state;
365 sprintf(state_path, "/usr/local/nagios/var/%lu/check_test/funnykeyname", (unsigned long)geteuid());
362 ok( !strcmp(temp_state_key->plugin_name, "check_test"), "Got plugin name" ); 366 ok( !strcmp(temp_state_key->plugin_name, "check_test"), "Got plugin name" );
363 ok( !strcmp(temp_state_key->name, "funnykeyname"), "Got key name" ); 367 ok( !strcmp(temp_state_key->name, "funnykeyname"), "Got key name" );
364 368
365 369
366 370
367 ok( !strcmp(temp_state_key->_filename, "/usr/local/nagios/var/check_test/funnykeyname"), "Got internal filename" ); 371 ok( !strcmp(temp_state_key->_filename, state_path), "Got internal filename" );
368 ok( temp_state_key->data_version==54, "Version set" ); 372 ok( temp_state_key->data_version==54, "Version set" );
369 373
370 temp_state_data = np_state_read(); 374 temp_state_data = np_state_read();
diff --git a/lib/utils_base.c b/lib/utils_base.c
index 04c4b4f..addf26b 100644
--- a/lib/utils_base.c
+++ b/lib/utils_base.c
@@ -300,19 +300,6 @@ char *np_escaped_string (const char *string) {
300 300
301int np_check_if_root(void) { return (geteuid() == 0); } 301int np_check_if_root(void) { return (geteuid() == 0); }
302 302
303int np_warn_if_not_root(void) {
304 int status = np_check_if_root();
305 if(!status) {
306 printf(_("Warning: "));
307 printf(_("This plugin must be either run as root or setuid root.\n"));
308 printf(_("To run as root, you can use a tool like sudo.\n"));
309 printf(_("To set the setuid permissions, use the command:\n"));
310 /* XXX could we use something like progname? */
311 printf("\tchmod u+s yourpluginfile\n");
312 }
313 return status;
314}
315
316/* 303/*
317 * Extract the value from key/value pairs, or return NULL. The value returned 304 * Extract the value from key/value pairs, or return NULL. The value returned
318 * can be free()ed. 305 * can be free()ed.
@@ -489,7 +476,9 @@ void np_enable_state(char *keyname, int expected_data_version) {
489 this_state->state_data=NULL; 476 this_state->state_data=NULL;
490 477
491 /* Calculate filename */ 478 /* Calculate filename */
492 asprintf(&temp_filename, "%s/%s/%s", _np_state_calculate_location_prefix(), this_monitoring_plugin->plugin_name, this_state->name); 479 asprintf(&temp_filename, "%s/%lu/%s/%s",
480 _np_state_calculate_location_prefix(), (unsigned long)geteuid(),
481 this_monitoring_plugin->plugin_name, this_state->name);
493 this_state->_filename=temp_filename; 482 this_state->_filename=temp_filename;
494 483
495 this_monitoring_plugin->state = this_state; 484 this_monitoring_plugin->state = this_state;
diff --git a/lib/utils_base.h b/lib/utils_base.h
index d69b0da..42ae0c0 100644
--- a/lib/utils_base.h
+++ b/lib/utils_base.h
@@ -75,9 +75,6 @@ void die (int, const char *, ...) __attribute__((noreturn,format(printf, 2, 3)))
75/* a simple check to see if we're running as root. 75/* a simple check to see if we're running as root.
76 * returns zero on failure, nonzero on success */ 76 * returns zero on failure, nonzero on success */
77int np_check_if_root(void); 77int np_check_if_root(void);
78/* and a helpful wrapper around that. it returns the same status
79 * code from the above function, in case it's helpful for testing */
80int np_warn_if_not_root(void);
81 78
82/* mp_suid() returns true if the real and effective uids differs, such as when 79/* mp_suid() returns true if the real and effective uids differs, such as when
83 * running a suid plugin */ 80 * running a suid plugin */
diff --git a/lib/utils_cmd.c b/lib/utils_cmd.c
index 4c6d0be..9e214bd 100644
--- a/lib/utils_cmd.c
+++ b/lib/utils_cmd.c
@@ -390,6 +390,9 @@ cmd_file_read ( char *filename, output *out, int flags)
390 390
391 if(out) 391 if(out)
392 out->lines = _cmd_fetch_output (fd, out, flags); 392 out->lines = _cmd_fetch_output (fd, out, flags);
393
394 if (close(fd) == -1)
395 die( STATE_UNKNOWN, _("Error closing %s: %s"), filename, strerror(errno) );
393 396
394 return 0; 397 return 0;
395} 398}
diff --git a/plugins-root/check_dhcp.c b/plugins-root/check_dhcp.c
index 1ec5c39..b874c55 100644
--- a/plugins-root/check_dhcp.c
+++ b/plugins-root/check_dhcp.c
@@ -270,9 +270,6 @@ int main(int argc, char **argv){
270 usage4 (_("Could not parse arguments")); 270 usage4 (_("Could not parse arguments"));
271 } 271 }
272 272
273 /* this plugin almost certainly needs root permissions. */
274 np_warn_if_not_root();
275
276 /* create socket for DHCP communications */ 273 /* create socket for DHCP communications */
277 dhcp_socket=create_dhcp_socket(); 274 dhcp_socket=create_dhcp_socket();
278 275
@@ -837,7 +834,7 @@ int add_dhcp_offer(struct in_addr source,dhcp_packet *offer_packet){
837 return ERROR; 834 return ERROR;
838 835
839 /* process all DHCP options present in the packet */ 836 /* process all DHCP options present in the packet */
840 for(x=4;x<MAX_DHCP_OPTIONS_LENGTH;){ 837 for(x=4;x<MAX_DHCP_OPTIONS_LENGTH-1;){
841 838
842 if((int)offer_packet->options[x]==-1) 839 if((int)offer_packet->options[x]==-1)
843 break; 840 break;
diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c
index 4b4197d..8b563e4 100644
--- a/plugins-root/check_icmp.c
+++ b/plugins-root/check_icmp.c
@@ -383,9 +383,6 @@ main(int argc, char **argv)
383 bindtextdomain (PACKAGE, LOCALEDIR); 383 bindtextdomain (PACKAGE, LOCALEDIR);
384 textdomain (PACKAGE); 384 textdomain (PACKAGE);
385 385
386 /* print a helpful error message if geteuid != 0 */
387 np_warn_if_not_root();
388
389 /* we only need to be setsuid when we get the sockets, so do 386 /* we only need to be setsuid when we get the sockets, so do
390 * that before pointer magic (esp. on network data) */ 387 * that before pointer magic (esp. on network data) */
391 icmp_sockerrno = udp_sockerrno = tcp_sockerrno = sockets = 0; 388 icmp_sockerrno = udp_sockerrno = tcp_sockerrno = sockets = 0;
diff --git a/plugins-scripts/Makefile.am b/plugins-scripts/Makefile.am
index 78a950c..794a34f 100644
--- a/plugins-scripts/Makefile.am
+++ b/plugins-scripts/Makefile.am
@@ -26,7 +26,8 @@ EXTRA_DIST=check_breeze.pl check_disk_smb.pl check_flexlm.pl check_ircd.pl \
26EDIT = sed \ 26EDIT = sed \
27 -e 's|[@]NP_VERSION[@]|$(NP_VERSION)|g' \ 27 -e 's|[@]NP_VERSION[@]|$(NP_VERSION)|g' \
28 -e 's|[@]TRUSTED_PATH[@]|$(with_trusted_path)|g' \ 28 -e 's|[@]TRUSTED_PATH[@]|$(with_trusted_path)|g' \
29 -e 's|[@]PERL[@]|$(PERL)|g' 29 -e 's|[@]PERL[@]|$(PERL)|g' \
30 -e 's|[@]libexecdir[@]|$(libexecdir)|g'
30 31
31TESTS_ENVIRONMENT=perl -I $(top_builddir) -I $(top_srcdir) 32TESTS_ENVIRONMENT=perl -I $(top_builddir) -I $(top_srcdir)
32 33
diff --git a/plugins-scripts/check_breeze.pl b/plugins-scripts/check_breeze.pl
index 12a60ee..1a3aceb 100755
--- a/plugins-scripts/check_breeze.pl
+++ b/plugins-scripts/check_breeze.pl
@@ -6,6 +6,7 @@ use Getopt::Long;
6use vars qw($opt_V $opt_h $opt_w $opt_c $opt_H $opt_C $PROGNAME); 6use vars qw($opt_V $opt_h $opt_w $opt_c $opt_H $opt_C $PROGNAME);
7use FindBin; 7use FindBin;
8use lib "$FindBin::Bin"; 8use lib "$FindBin::Bin";
9use lib '@libexecdir@';
9use utils qw(%ERRORS &print_revision &support &usage); 10use utils qw(%ERRORS &print_revision &support &usage);
10 11
11$PROGNAME = "check_breeze"; 12$PROGNAME = "check_breeze";
diff --git a/plugins-scripts/check_disk_smb.pl b/plugins-scripts/check_disk_smb.pl
index 99948a4..4805434 100755
--- a/plugins-scripts/check_disk_smb.pl
+++ b/plugins-scripts/check_disk_smb.pl
@@ -26,6 +26,7 @@ use vars qw($opt_P $opt_V $opt_h $opt_H $opt_s $opt_W $opt_u $opt_p $opt_w $opt_
26use vars qw($PROGNAME); 26use vars qw($PROGNAME);
27use FindBin; 27use FindBin;
28use lib "$FindBin::Bin"; 28use lib "$FindBin::Bin";
29use lib '@libexecdir@';
29use utils qw($TIMEOUT %ERRORS &print_revision &support &usage); 30use utils qw($TIMEOUT %ERRORS &print_revision &support &usage);
30 31
31sub print_help (); 32sub print_help ();
diff --git a/plugins-scripts/check_file_age.pl b/plugins-scripts/check_file_age.pl
index 5e062de..453e0f5 100755
--- a/plugins-scripts/check_file_age.pl
+++ b/plugins-scripts/check_file_age.pl
@@ -25,7 +25,9 @@ use English;
25use Getopt::Long; 25use Getopt::Long;
26use File::stat; 26use File::stat;
27use vars qw($PROGNAME); 27use vars qw($PROGNAME);
28use lib "."; 28use FindBin;
29use lib "$FindBin::Bin";
30use lib '@libexecdir@';
29use utils qw (%ERRORS &print_revision &support); 31use utils qw (%ERRORS &print_revision &support);
30 32
31sub print_help (); 33sub print_help ();
diff --git a/plugins-scripts/check_flexlm.pl b/plugins-scripts/check_flexlm.pl
index 49d674d..5f3ed59 100755
--- a/plugins-scripts/check_flexlm.pl
+++ b/plugins-scripts/check_flexlm.pl
@@ -37,6 +37,7 @@ use Getopt::Long;
37use vars qw($opt_V $opt_h $opt_F $opt_t $verbose $PROGNAME); 37use vars qw($opt_V $opt_h $opt_F $opt_t $verbose $PROGNAME);
38use FindBin; 38use FindBin;
39use lib "$FindBin::Bin"; 39use lib "$FindBin::Bin";
40use lib '@libexecdir@';
40use utils qw(%ERRORS &print_revision &support &usage); 41use utils qw(%ERRORS &print_revision &support &usage);
41 42
42$PROGNAME="check_flexlm"; 43$PROGNAME="check_flexlm";
diff --git a/plugins-scripts/check_ifoperstatus.pl b/plugins-scripts/check_ifoperstatus.pl
index 1a7fbba..cf2c7b5 100755
--- a/plugins-scripts/check_ifoperstatus.pl
+++ b/plugins-scripts/check_ifoperstatus.pl
@@ -37,6 +37,7 @@ use POSIX;
37use strict; 37use strict;
38use FindBin; 38use FindBin;
39use lib "$FindBin::Bin"; 39use lib "$FindBin::Bin";
40use lib '@libexecdir@';
40use utils qw($TIMEOUT %ERRORS &print_revision &support); 41use utils qw($TIMEOUT %ERRORS &print_revision &support);
41 42
42use Net::SNMP; 43use Net::SNMP;
diff --git a/plugins-scripts/check_ifstatus.pl b/plugins-scripts/check_ifstatus.pl
index e9e6214..709ad17 100755
--- a/plugins-scripts/check_ifstatus.pl
+++ b/plugins-scripts/check_ifstatus.pl
@@ -34,6 +34,7 @@ use POSIX;
34use strict; 34use strict;
35use FindBin; 35use FindBin;
36use lib "$FindBin::Bin"; 36use lib "$FindBin::Bin";
37use lib '@libexecdir@';
37use utils qw($TIMEOUT %ERRORS &print_revision &support); 38use utils qw($TIMEOUT %ERRORS &print_revision &support);
38 39
39use Net::SNMP; 40use Net::SNMP;
@@ -220,7 +221,7 @@ foreach $key (keys %ifStatus) {
220 $ifexclude, 221 $ifexclude,
221 $ifunused); 222 $ifunused);
222 } 223 }
223my $perfdata = sprintf("up=%d,down=%d,dormant=%d,excluded=%d,unused=%d",$ifup,$ifdown,$ifdormant,$ifexclude,$ifunused); 224my $perfdata = sprintf("up=%d down=%d dormant=%d excluded=%d unused=%d",$ifup,$ifdown,$ifdormant,$ifexclude,$ifunused);
224print ("$state: $answer |$perfdata\n"); 225print ("$state: $answer |$perfdata\n");
225exit $ERRORS{$state}; 226exit $ERRORS{$state};
226 227
diff --git a/plugins-scripts/check_ircd.pl b/plugins-scripts/check_ircd.pl
index afedfb9..6d40cf5 100755
--- a/plugins-scripts/check_ircd.pl
+++ b/plugins-scripts/check_ircd.pl
@@ -51,6 +51,7 @@ use vars qw($opt_V $opt_h $opt_t $opt_p $opt_H $opt_w $opt_c $verbose);
51use vars qw($PROGNAME); 51use vars qw($PROGNAME);
52use FindBin; 52use FindBin;
53use lib "$FindBin::Bin"; 53use lib "$FindBin::Bin";
54use lib '@libexecdir@';
54use utils qw($TIMEOUT %ERRORS &print_revision &support &usage); 55use utils qw($TIMEOUT %ERRORS &print_revision &support &usage);
55 56
56# ----------------------------------------------------[ Function Prototypes ]-- 57# ----------------------------------------------------[ Function Prototypes ]--
diff --git a/plugins-scripts/check_mailq.pl b/plugins-scripts/check_mailq.pl
index df1385d..bd78981 100755
--- a/plugins-scripts/check_mailq.pl
+++ b/plugins-scripts/check_mailq.pl
@@ -33,6 +33,7 @@ use vars qw($opt_V $opt_h $opt_v $verbose $PROGNAME $opt_w $opt_c $opt_t
33 %srcdomains %dstdomains); 33 %srcdomains %dstdomains);
34use FindBin; 34use FindBin;
35use lib "$FindBin::Bin"; 35use lib "$FindBin::Bin";
36use lib '@libexecdir@';
36use utils qw(%ERRORS &print_revision &support &usage ); 37use utils qw(%ERRORS &print_revision &support &usage );
37 38
38 39
diff --git a/plugins-scripts/check_mssql.pl b/plugins-scripts/check_mssql.pl
index a3f497c..1f38788 100755
--- a/plugins-scripts/check_mssql.pl
+++ b/plugins-scripts/check_mssql.pl
@@ -29,7 +29,9 @@
29use DBI; 29use DBI;
30use DBD::Sybase; 30use DBD::Sybase;
31use Getopt::Long; 31use Getopt::Long;
32use lib "."; 32use FindBin;
33use lib "$FindBin::Bin";
34use lib '@libexecdir@';
33use utils qw($TIMEOUT %ERRORS &print_revision &support); 35use utils qw($TIMEOUT %ERRORS &print_revision &support);
34use strict; 36use strict;
35 37
diff --git a/plugins-scripts/check_netdns.pl b/plugins-scripts/check_netdns.pl
index 82939bf..59c81a9 100755
--- a/plugins-scripts/check_netdns.pl
+++ b/plugins-scripts/check_netdns.pl
@@ -29,6 +29,7 @@ use Getopt::Long;
29use Net::DNS; 29use Net::DNS;
30use FindBin; 30use FindBin;
31use lib "$FindBin::Bin"; 31use lib "$FindBin::Bin";
32use lib '@libexecdir@';
32use utils ; 33use utils ;
33 34
34my $PROGNAME = "check_netdns"; 35my $PROGNAME = "check_netdns";
diff --git a/plugins-scripts/check_rpc.pl b/plugins-scripts/check_rpc.pl
index cbdeceb..b1c6147 100755
--- a/plugins-scripts/check_rpc.pl
+++ b/plugins-scripts/check_rpc.pl
@@ -22,6 +22,7 @@
22use strict; 22use strict;
23use FindBin; 23use FindBin;
24use lib "$FindBin::Bin"; 24use lib "$FindBin::Bin";
25use lib '@libexecdir@';
25use utils qw($TIMEOUT %ERRORS &print_revision &support); 26use utils qw($TIMEOUT %ERRORS &print_revision &support);
26use vars qw($PROGNAME); 27use vars qw($PROGNAME);
27my ($verbose,@proto,%prognum,$host,$response,$prognum,$port,$cmd,$progver,$state); 28my ($verbose,@proto,%prognum,$host,$response,$prognum,$port,$cmd,$progver,$state);
diff --git a/plugins-scripts/check_wave.pl b/plugins-scripts/check_wave.pl
index 979416e..ee0fda4 100755
--- a/plugins-scripts/check_wave.pl
+++ b/plugins-scripts/check_wave.pl
@@ -5,6 +5,7 @@
5use strict; 5use strict;
6use FindBin; 6use FindBin;
7use lib "$FindBin::Bin"; 7use lib "$FindBin::Bin";
8use lib '@libexecdir@';
8use utils qw($TIMEOUT %ERRORS &print_revision &support); 9use utils qw($TIMEOUT %ERRORS &print_revision &support);
9use vars qw($PROGNAME); 10use vars qw($PROGNAME);
10use Getopt::Long; 11use Getopt::Long;
diff --git a/plugins/check_apt.c b/plugins/check_apt.c
index 4c76a51..07622c2 100644
--- a/plugins/check_apt.c
+++ b/plugins/check_apt.c
@@ -223,6 +223,9 @@ int run_upgrade(int *pkgcount, int *secpkgcount){
223 regex_t ireg, ereg, sreg; 223 regex_t ireg, ereg, sreg;
224 char *cmdline=NULL, rerrbuf[64]; 224 char *cmdline=NULL, rerrbuf[64];
225 225
226 /* initialize ereg as it is possible it is printed while uninitialized */
227 memset(&ereg, "\0", sizeof(ereg.buffer));
228
226 if(upgrade==NO_UPGRADE) return STATE_OK; 229 if(upgrade==NO_UPGRADE) return STATE_OK;
227 230
228 /* compile the regexps */ 231 /* compile the regexps */
diff --git a/plugins/check_dbi.c b/plugins/check_dbi.c
index c6244fd..a3d033f 100644
--- a/plugins/check_dbi.c
+++ b/plugins/check_dbi.c
@@ -215,7 +215,7 @@ main (int argc, char **argv)
215 } 215 }
216 216
217 if (dbi_conn_connect (conn) < 0) { 217 if (dbi_conn_connect (conn) < 0) {
218 np_dbi_print_error (conn, "UNKOWN - failed to connect to database"); 218 np_dbi_print_error (conn, "UNKNOWN - failed to connect to database");
219 return STATE_UNKNOWN; 219 return STATE_UNKNOWN;
220 } 220 }
221 221
@@ -241,7 +241,7 @@ main (int argc, char **argv)
241 printf ("Selecting database '%s'\n", np_dbi_database); 241 printf ("Selecting database '%s'\n", np_dbi_database);
242 242
243 if (dbi_conn_select_db (conn, np_dbi_database)) { 243 if (dbi_conn_select_db (conn, np_dbi_database)) {
244 np_dbi_print_error (conn, "UNKOWN - failed to select database '%s'", 244 np_dbi_print_error (conn, "UNKNOWN - failed to select database '%s'",
245 np_dbi_database); 245 np_dbi_database);
246 return STATE_UNKNOWN; 246 return STATE_UNKNOWN;
247 } 247 }
@@ -456,7 +456,7 @@ process_arguments (int argc, char **argv)
456 new = realloc (np_dbi_options, 456 new = realloc (np_dbi_options,
457 (np_dbi_options_num + 1) * sizeof (*new)); 457 (np_dbi_options_num + 1) * sizeof (*new));
458 if (! new) { 458 if (! new) {
459 printf ("UNKOWN - failed to reallocate memory\n"); 459 printf ("UNKNOWN - failed to reallocate memory\n");
460 exit (STATE_UNKNOWN); 460 exit (STATE_UNKNOWN);
461 } 461 }
462 462
diff --git a/plugins/check_dns.c b/plugins/check_dns.c
index eebe72c..31a953d 100644
--- a/plugins/check_dns.c
+++ b/plugins/check_dns.c
@@ -242,7 +242,23 @@ main (int argc, char **argv)
242 } 242 }
243 printf (ngettext("%.3f second response time", "%.3f seconds response time", elapsed_time), elapsed_time); 243 printf (ngettext("%.3f second response time", "%.3f seconds response time", elapsed_time), elapsed_time);
244 printf (_(". %s returns %s"), query_address, address); 244 printf (_(". %s returns %s"), query_address, address);
245 printf ("|%s\n", fperfdata ("time", elapsed_time, "s", FALSE, 0, FALSE, 0, TRUE, 0, FALSE, 0)); 245 if ((time_thresholds->warning != NULL) && (time_thresholds->critical != NULL)) {
246 printf ("|%s\n", fperfdata ("time", elapsed_time, "s",
247 TRUE, time_thresholds->warning->end,
248 TRUE, time_thresholds->critical->end,
249 TRUE, 0, FALSE, 0));
250 } else if ((time_thresholds->warning == NULL) && (time_thresholds->critical != NULL)) {
251 printf ("|%s\n", fperfdata ("time", elapsed_time, "s",
252 FALSE, 0,
253 TRUE, time_thresholds->critical->end,
254 TRUE, 0, FALSE, 0));
255 } else if ((time_thresholds->warning != NULL) && (time_thresholds->critical == NULL)) {
256 printf ("|%s\n", fperfdata ("time", elapsed_time, "s",
257 TRUE, time_thresholds->warning->end,
258 FALSE, 0,
259 TRUE, 0, FALSE, 0));
260 } else
261 printf ("|%s\n", fperfdata ("time", elapsed_time, "s", FALSE, 0, FALSE, 0, TRUE, 0, FALSE, 0));
246 } 262 }
247 else if (result == STATE_WARNING) 263 else if (result == STATE_WARNING)
248 printf (_("DNS WARNING - %s\n"), 264 printf (_("DNS WARNING - %s\n"),
diff --git a/plugins/check_hpjd.c b/plugins/check_hpjd.c
index 1e7605b..5fe0698 100644
--- a/plugins/check_hpjd.c
+++ b/plugins/check_hpjd.c
@@ -39,7 +39,7 @@ const char *email = "devel@monitoring-plugins.org";
39#include "netutils.h" 39#include "netutils.h"
40 40
41#define DEFAULT_COMMUNITY "public" 41#define DEFAULT_COMMUNITY "public"
42 42#define DEFAULT_PORT "161"
43 43
44const char *option_summary = "-H host [-C community]\n"; 44const char *option_summary = "-H host [-C community]\n";
45 45
@@ -66,6 +66,7 @@ void print_usage (void);
66 66
67char *community = NULL; 67char *community = NULL;
68char *address = NULL; 68char *address = NULL;
69char *port = NULL;
69 70
70int 71int
71main (int argc, char **argv) 72main (int argc, char **argv)
@@ -119,8 +120,8 @@ main (int argc, char **argv)
119 HPJD_GD_DOOR_OPEN, HPJD_GD_PAPER_OUTPUT, HPJD_GD_STATUS_DISPLAY); 120 HPJD_GD_DOOR_OPEN, HPJD_GD_PAPER_OUTPUT, HPJD_GD_STATUS_DISPLAY);
120 121
121 /* get the command to run */ 122 /* get the command to run */
122 sprintf (command_line, "%s -OQa -m : -v 1 -c %s %s %s", PATH_TO_SNMPGET, community, 123 sprintf (command_line, "%s -OQa -m : -v 1 -c %s %s:%hd %s", PATH_TO_SNMPGET, community,
123 address, query_string); 124 address, port, query_string);
124 125
125 /* run the command */ 126 /* run the command */
126 child_process = spopen (command_line); 127 child_process = spopen (command_line);
@@ -313,7 +314,7 @@ process_arguments (int argc, char **argv)
313 {"community", required_argument, 0, 'C'}, 314 {"community", required_argument, 0, 'C'},
314/* {"critical", required_argument,0,'c'}, */ 315/* {"critical", required_argument,0,'c'}, */
315/* {"warning", required_argument,0,'w'}, */ 316/* {"warning", required_argument,0,'w'}, */
316/* {"port", required_argument,0,'P'}, */ 317 {"port", required_argument,0,'p'},
317 {"version", no_argument, 0, 'V'}, 318 {"version", no_argument, 0, 'V'},
318 {"help", no_argument, 0, 'h'}, 319 {"help", no_argument, 0, 'h'},
319 {0, 0, 0, 0} 320 {0, 0, 0, 0}
@@ -324,7 +325,7 @@ process_arguments (int argc, char **argv)
324 325
325 326
326 while (1) { 327 while (1) {
327 c = getopt_long (argc, argv, "+hVH:C:", longopts, &option); 328 c = getopt_long (argc, argv, "+hVH:C:p:", longopts, &option);
328 329
329 if (c == -1 || c == EOF || c == 1) 330 if (c == -1 || c == EOF || c == 1)
330 break; 331 break;
@@ -341,6 +342,12 @@ process_arguments (int argc, char **argv)
341 case 'C': /* community */ 342 case 'C': /* community */
342 community = strscpy (community, optarg); 343 community = strscpy (community, optarg);
343 break; 344 break;
345 case 'p':
346 if (!is_intpos(optarg))
347 usage2 (_("Port must be a positive short integer"), optarg);
348 else
349 port = atoi(optarg);
350 break;
344 case 'V': /* version */ 351 case 'V': /* version */
345 print_revision (progname, NP_VERSION); 352 print_revision (progname, NP_VERSION);
346 exit (STATE_OK); 353 exit (STATE_OK);
@@ -369,6 +376,13 @@ process_arguments (int argc, char **argv)
369 community = strdup (DEFAULT_COMMUNITY); 376 community = strdup (DEFAULT_COMMUNITY);
370 } 377 }
371 378
379 if (port == NULL) {
380 if (argv[c] != NULL )
381 port = argv[c];
382 else
383 port = atoi (DEFAULT_PORT);
384 }
385
372 return validate_arguments (); 386 return validate_arguments ();
373} 387}
374 388
@@ -402,6 +416,10 @@ print_help (void)
402 printf (" %s", _("The SNMP community name ")); 416 printf (" %s", _("The SNMP community name "));
403 printf (_("(default=%s)"), DEFAULT_COMMUNITY); 417 printf (_("(default=%s)"), DEFAULT_COMMUNITY);
404 printf ("\n"); 418 printf ("\n");
419 printf (" %s\n", "-p, --port=STRING");
420 printf (" %s", _("Specify the port to check "));
421 printf (_("(default=%s)"), DEFAULT_PORT);
422 printf ("\n");
405 423
406 printf (UT_SUPPORT); 424 printf (UT_SUPPORT);
407} 425}
@@ -412,5 +430,5 @@ void
412print_usage (void) 430print_usage (void)
413{ 431{
414 printf ("%s\n", _("Usage:")); 432 printf ("%s\n", _("Usage:"));
415 printf ("%s -H host [-C community]\n", progname); 433 printf ("%s -H host [-C community] [-p port]\n", progname);
416} 434}
diff --git a/plugins/check_http.c b/plugins/check_http.c
index 92861d9..5167997 100644
--- a/plugins/check_http.c
+++ b/plugins/check_http.c
@@ -1243,6 +1243,7 @@ redir (char *pos, char *status_line)
1243 if (addr == NULL) 1243 if (addr == NULL)
1244 die (STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate addr\n")); 1244 die (STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate addr\n"));
1245 1245
1246 memset(addr, 0, MAX_IPV4_HOSTLENGTH);
1246 url = malloc (strcspn (pos, "\r\n")); 1247 url = malloc (strcspn (pos, "\r\n"));
1247 if (url == NULL) 1248 if (url == NULL)
1248 die (STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate URL\n")); 1249 die (STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate URL\n"));
@@ -1333,8 +1334,8 @@ redir (char *pos, char *status_line)
1333 max_depth, type, addr, i, url, (display_html ? "</A>" : "")); 1334 max_depth, type, addr, i, url, (display_html ? "</A>" : ""));
1334 1335
1335 if (server_port==i && 1336 if (server_port==i &&
1336 !strcmp(server_address, addr) && 1337 !strncmp(server_address, addr, MAX_IPV4_HOSTLENGTH) &&
1337 (host_name && !strcmp(host_name, addr)) && 1338 (host_name && !strncmp(host_name, addr, MAX_IPV4_HOSTLENGTH)) &&
1338 !strcmp(server_url, url)) 1339 !strcmp(server_url, url))
1339 die (STATE_WARNING, 1340 die (STATE_WARNING,
1340 _("HTTP WARNING - redirection creates an infinite loop - %s://%s:%d%s%s\n"), 1341 _("HTTP WARNING - redirection creates an infinite loop - %s://%s:%d%s%s\n"),
@@ -1343,11 +1344,11 @@ redir (char *pos, char *status_line)
1343 strcpy (server_type, type); 1344 strcpy (server_type, type);
1344 1345
1345 free (host_name); 1346 free (host_name);
1346 host_name = strdup (addr); 1347 host_name = strndup (addr, MAX_IPV4_HOSTLENGTH);
1347 1348
1348 if (!(followsticky & STICKY_HOST)) { 1349 if (!(followsticky & STICKY_HOST)) {
1349 free (server_address); 1350 free (server_address);
1350 server_address = strdup (addr); 1351 server_address = strndup (addr, MAX_IPV4_HOSTLENGTH);
1351 } 1352 }
1352 if (!(followsticky & STICKY_PORT)) { 1353 if (!(followsticky & STICKY_PORT)) {
1353 server_port = i; 1354 server_port = i;
@@ -1366,6 +1367,7 @@ redir (char *pos, char *status_line)
1366 printf (_("Redirection to %s://%s:%d%s\n"), server_type, 1367 printf (_("Redirection to %s://%s:%d%s\n"), server_type,
1367 host_name ? host_name : server_address, server_port, server_url); 1368 host_name ? host_name : server_address, server_port, server_url);
1368 1369
1370 free(addr);
1369 check_http (); 1371 check_http ();
1370} 1372}
1371 1373
diff --git a/plugins/check_ide_smart.c b/plugins/check_ide_smart.c
index 55faacc..47605e9 100644
--- a/plugins/check_ide_smart.c
+++ b/plugins/check_ide_smart.c
@@ -419,7 +419,7 @@ nagios (values_t * p, thresholds_t * t)
419 status=STATE_OK; 419 status=STATE_OK;
420 break; 420 break;
421 default: 421 default:
422 printf (_("ERROR - Status '%d' unkown. %d/%d tests passed\n"), status, 422 printf (_("ERROR - Status '%d' unknown. %d/%d tests passed\n"), status,
423 passed, total); 423 passed, total);
424 status = STATE_UNKNOWN; 424 status = STATE_UNKNOWN;
425 break; 425 break;
diff --git a/plugins/check_mrtg.c b/plugins/check_mrtg.c
index ed75f4c..cf3fe04 100644
--- a/plugins/check_mrtg.c
+++ b/plugins/check_mrtg.c
@@ -356,7 +356,7 @@ print_help (void)
356 printf (" %s\n", _("This plugin is useful for monitoring MRTG data that does not correspond to")); 356 printf (" %s\n", _("This plugin is useful for monitoring MRTG data that does not correspond to"));
357 printf (" %s\n", _("bandwidth usage. (Use the check_mrtgtraf plugin for monitoring bandwidth).")); 357 printf (" %s\n", _("bandwidth usage. (Use the check_mrtgtraf plugin for monitoring bandwidth)."));
358 printf (" %s\n", _("It can be used to monitor any kind of data that MRTG is monitoring - errors,")); 358 printf (" %s\n", _("It can be used to monitor any kind of data that MRTG is monitoring - errors,"));
359 printf (" %s\n", _("packets/sec, etc. I use MRTG in conjuction with the Novell NLM that allows")); 359 printf (" %s\n", _("packets/sec, etc. I use MRTG in conjunction with the Novell NLM that allows"));
360 printf (" %s\n", _("me to track processor utilization, user connections, drive space, etc and")); 360 printf (" %s\n", _("me to track processor utilization, user connections, drive space, etc and"));
361 printf (" %s\n\n", _("this plugin works well for monitoring that kind of data as well.")); 361 printf (" %s\n\n", _("this plugin works well for monitoring that kind of data as well."));
362 362
diff --git a/plugins/check_mysql.c b/plugins/check_mysql.c
index 4f09e5f..216626b 100644
--- a/plugins/check_mysql.c
+++ b/plugins/check_mysql.c
@@ -42,6 +42,7 @@ const char *email = "devel@monitoring-plugins.org";
42#include "netutils.h" 42#include "netutils.h"
43 43
44#include <mysql.h> 44#include <mysql.h>
45#include <mysqld_error.h>
45#include <errmsg.h> 46#include <errmsg.h>
46 47
47char *db_user = NULL; 48char *db_user = NULL;
@@ -59,6 +60,7 @@ char *opt_file = NULL;
59char *opt_group = NULL; 60char *opt_group = NULL;
60unsigned int db_port = MYSQL_PORT; 61unsigned int db_port = MYSQL_PORT;
61int check_slave = 0, warn_sec = 0, crit_sec = 0; 62int check_slave = 0, warn_sec = 0, crit_sec = 0;
63int ignore_auth = 0;
62int verbose = 0; 64int verbose = 0;
63 65
64static double warning_time = 0; 66static double warning_time = 0;
@@ -136,7 +138,16 @@ main (int argc, char **argv)
136 mysql_ssl_set(&mysql,key,cert,ca_cert,ca_dir,ciphers); 138 mysql_ssl_set(&mysql,key,cert,ca_cert,ca_dir,ciphers);
137 /* establish a connection to the server and error checking */ 139 /* establish a connection to the server and error checking */
138 if (!mysql_real_connect(&mysql,db_host,db_user,db_pass,db,db_port,db_socket,0)) { 140 if (!mysql_real_connect(&mysql,db_host,db_user,db_pass,db,db_port,db_socket,0)) {
139 if (mysql_errno (&mysql) == CR_UNKNOWN_HOST) 141 if (ignore_auth && mysql_errno (&mysql) == ER_ACCESS_DENIED_ERROR)
142 {
143 printf("MySQL OK - Version: %s (protocol %d)\n",
144 mysql_get_server_info(&mysql),
145 mysql_get_proto_info(&mysql)
146 );
147 mysql_close (&mysql);
148 return STATE_OK;
149 }
150 else if (mysql_errno (&mysql) == CR_UNKNOWN_HOST)
140 die (STATE_WARNING, "%s\n", mysql_error (&mysql)); 151 die (STATE_WARNING, "%s\n", mysql_error (&mysql));
141 else if (mysql_errno (&mysql) == CR_VERSION_ERROR) 152 else if (mysql_errno (&mysql) == CR_VERSION_ERROR)
142 die (STATE_WARNING, "%s\n", mysql_error (&mysql)); 153 die (STATE_WARNING, "%s\n", mysql_error (&mysql));
@@ -341,6 +352,7 @@ process_arguments (int argc, char **argv)
341 {"critical", required_argument, 0, 'c'}, 352 {"critical", required_argument, 0, 'c'},
342 {"warning", required_argument, 0, 'w'}, 353 {"warning", required_argument, 0, 'w'},
343 {"check-slave", no_argument, 0, 'S'}, 354 {"check-slave", no_argument, 0, 'S'},
355 {"ignore-auth", no_argument, 0, 'n'},
344 {"verbose", no_argument, 0, 'v'}, 356 {"verbose", no_argument, 0, 'v'},
345 {"version", no_argument, 0, 'V'}, 357 {"version", no_argument, 0, 'V'},
346 {"help", no_argument, 0, 'h'}, 358 {"help", no_argument, 0, 'h'},
@@ -357,7 +369,7 @@ process_arguments (int argc, char **argv)
357 return ERROR; 369 return ERROR;
358 370
359 while (1) { 371 while (1) {
360 c = getopt_long (argc, argv, "hlvVSP:p:u:d:H:s:c:w:a:k:C:D:L:f:g:", longopts, &option); 372 c = getopt_long (argc, argv, "hlvVnSP:p:u:d:H:s:c:w:a:k:C:D:L:f:g:", longopts, &option);
361 373
362 if (c == -1 || c == EOF) 374 if (c == -1 || c == EOF)
363 break; 375 break;
@@ -419,6 +431,9 @@ process_arguments (int argc, char **argv)
419 case 'S': 431 case 'S':
420 check_slave = 1; /* check-slave */ 432 check_slave = 1; /* check-slave */
421 break; 433 break;
434 case 'n':
435 ignore_auth = 1; /* ignore-auth */
436 break;
422 case 'w': 437 case 'w':
423 warning = optarg; 438 warning = optarg;
424 warning_time = strtod (warning, NULL); 439 warning_time = strtod (warning, NULL);
@@ -506,6 +521,9 @@ print_help (void)
506 printf (UT_EXTRA_OPTS); 521 printf (UT_EXTRA_OPTS);
507 522
508 printf (UT_HOST_PORT, 'P', myport); 523 printf (UT_HOST_PORT, 'P', myport);
524 printf (" %s\n", "-n, --ignore-auth");
525 printf (" %s\n", _("Ignore authentication failure and check for mysql connectivity only"));
526
509 printf (" %s\n", "-s, --socket=STRING"); 527 printf (" %s\n", "-s, --socket=STRING");
510 printf (" %s\n", _("Use the specified socket (has no effect if -H is used)")); 528 printf (" %s\n", _("Use the specified socket (has no effect if -H is used)"));
511 529
diff --git a/plugins/check_nt.c b/plugins/check_nt.c
index cacf665..fefbfb7 100644
--- a/plugins/check_nt.c
+++ b/plugins/check_nt.c
@@ -293,10 +293,10 @@ int main(int argc, char **argv){
293 293
294 /* Divisor should be 1048567, not 3044515, as we are measuring "Commit Charge" here, 294 /* Divisor should be 1048567, not 3044515, as we are measuring "Commit Charge" here,
295 which equals RAM + Pagefiles. */ 295 which equals RAM + Pagefiles. */
296 xasprintf(&output_message,_("Memory usage: total:%.2f Mb - used: %.2f Mb (%.0f%%) - free: %.2f Mb (%.0f%%)"), 296 xasprintf(&output_message,_("Memory usage: total:%.2f MB - used: %.2f MB (%.0f%%) - free: %.2f MB (%.0f%%)"),
297 mem_commitLimit / 1048567, mem_commitByte / 1048567, percent_used_space, 297 mem_commitLimit / 1048567, mem_commitByte / 1048567, percent_used_space,
298 (mem_commitLimit - mem_commitByte) / 1048567, (mem_commitLimit - mem_commitByte) / mem_commitLimit * 100); 298 (mem_commitLimit - mem_commitByte) / 1048567, (mem_commitLimit - mem_commitByte) / mem_commitLimit * 100);
299 xasprintf(&perfdata,_("'Memory usage'=%.2fMb;%.2f;%.2f;0.00;%.2f"), mem_commitByte / 1048567, 299 xasprintf(&perfdata,_("'Memory usage'=%.2fMB;%.2f;%.2f;0.00;%.2f"), mem_commitByte / 1048567,
300 warning_used_space / 1048567, critical_used_space / 1048567, mem_commitLimit / 1048567); 300 warning_used_space / 1048567, critical_used_space / 1048567, mem_commitLimit / 1048567);
301 301
302 return_code=STATE_OK; 302 return_code=STATE_OK;
diff --git a/plugins/check_ntp.c b/plugins/check_ntp.c
index 0a7640a..09a923e 100644
--- a/plugins/check_ntp.c
+++ b/plugins/check_ntp.c
@@ -517,13 +517,14 @@ setup_control_request(ntp_control_message *p, uint8_t opcode, uint16_t seq){
517double jitter_request(const char *host, int *status){ 517double jitter_request(const char *host, int *status){
518 int conn=-1, i, npeers=0, num_candidates=0, syncsource_found=0; 518 int conn=-1, i, npeers=0, num_candidates=0, syncsource_found=0;
519 int run=0, min_peer_sel=PEER_INCLUDED, num_selected=0, num_valid=0; 519 int run=0, min_peer_sel=PEER_INCLUDED, num_selected=0, num_valid=0;
520 int peers_size=0, peer_offset=0; 520 int peers_size=0, peer_offset=0, bytes_read=0;
521 ntp_assoc_status_pair *peers=NULL; 521 ntp_assoc_status_pair *peers=NULL;
522 ntp_control_message req; 522 ntp_control_message req;
523 const char *getvar = "jitter"; 523 const char *getvar = "jitter";
524 double rval = 0.0, jitter = -1.0; 524 double rval = 0.0, jitter = -1.0;
525 char *startofvalue=NULL, *nptr=NULL; 525 char *startofvalue=NULL, *nptr=NULL;
526 void *tmp; 526 void *tmp;
527 int ntp_cm_ints = sizeof(uint16_t) * 5 + sizeof(uint8_t) * 2;
527 528
528 /* Long-winded explanation: 529 /* Long-winded explanation:
529 * Getting the jitter requires a number of steps: 530 * Getting the jitter requires a number of steps:
@@ -608,7 +609,15 @@ double jitter_request(const char *host, int *status){
608 609
609 req.count = htons(MAX_CM_SIZE); 610 req.count = htons(MAX_CM_SIZE);
610 DBG(printf("recieving READVAR response...\n")); 611 DBG(printf("recieving READVAR response...\n"));
611 read(conn, &req, SIZEOF_NTPCM(req)); 612
613 /* cov-66524 - req.data not null terminated before usage. Also covers verifying struct was returned correctly*/
614 if ((bytes_read = read(conn, &req, SIZEOF_NTPCM(req))) == -1)
615 die(STATE_UNKNOWN, _("Cannot read from socket: %s"), strerror(errno));
616 if (bytes_read != ntp_cm_ints + req.count)
617 die(STATE_UNKNOWN, _("Invalid NTP response: %d bytes read does not equal %d plus %d data segment"), bytes_read, ntp_cm_ints, req.count);
618 /* else null terminate */
619 strncpy(req.data[req.count], "\0", 1);
620
612 DBG(print_ntp_control_message(&req)); 621 DBG(print_ntp_control_message(&req));
613 622
614 if(req.op&REM_ERROR && strstr(getvar, "jitter")) { 623 if(req.op&REM_ERROR && strstr(getvar, "jitter")) {
diff --git a/plugins/check_ntp_peer.c b/plugins/check_ntp_peer.c
index 8dc1978..d3ae599 100644
--- a/plugins/check_ntp_peer.c
+++ b/plugins/check_ntp_peer.c
@@ -560,7 +560,7 @@ char *perfd_truechimers (int num_truechimers)
560} 560}
561 561
562int main(int argc, char *argv[]){ 562int main(int argc, char *argv[]){
563 int result, offset_result, stratum, num_truechimers; 563 int result, offset_result, stratum, num_truechimers, oresult, jresult, sresult, tresult;
564 double offset=0, jitter=0; 564 double offset=0, jitter=0;
565 char *result_line, *perfdata_line; 565 char *result_line, *perfdata_line;
566 566
@@ -597,15 +597,19 @@ int main(int argc, char *argv[]){
597 result = STATE_UNKNOWN; 597 result = STATE_UNKNOWN;
598 result = max_state_alt(result, get_status(fabs(offset), offset_thresholds)); 598 result = max_state_alt(result, get_status(fabs(offset), offset_thresholds));
599 } 599 }
600 600 oresult = result;
601
601 if(do_truechimers) 602 if(do_truechimers)
602 result = max_state_alt(result, get_status(num_truechimers, truechimer_thresholds)); 603 tresult = get_status(num_truechimers, truechimer_thresholds);
604 result = max_state_alt(result, tresult);
603 605
604 if(do_stratum) 606 if(do_stratum)
605 result = max_state_alt(result, get_status(stratum, stratum_thresholds)); 607 sresult = get_status(stratum, stratum_thresholds);
608 result = max_state_alt(result, sresult);
606 609
607 if(do_jitter) 610 if(do_jitter)
608 result = max_state_alt(result, get_status(jitter, jitter_thresholds)); 611 jresult = get_status(jitter, jitter_thresholds);
612 result = max_state_alt(result, jresult);
609 613
610 switch (result) { 614 switch (result) {
611 case STATE_CRITICAL : 615 case STATE_CRITICAL :
@@ -629,20 +633,43 @@ int main(int argc, char *argv[]){
629 if(offset_result == STATE_UNKNOWN){ 633 if(offset_result == STATE_UNKNOWN){
630 xasprintf(&result_line, "%s %s", result_line, _("Offset unknown")); 634 xasprintf(&result_line, "%s %s", result_line, _("Offset unknown"));
631 xasprintf(&perfdata_line, ""); 635 xasprintf(&perfdata_line, "");
636 } else if (oresult == STATE_WARNING) {
637 xasprintf(&result_line, "%s %s %.10g secs (WARNING)", result_line, _("Offset"), offset);
638 } else if (oresult == STATE_CRITICAL) {
639 xasprintf(&result_line, "%s %s %.10g secs (CRITICAL)", result_line, _("Offset"), offset);
632 } else { 640 } else {
633 xasprintf(&result_line, "%s %s %.10g secs", result_line, _("Offset"), offset); 641 xasprintf(&result_line, "%s %s %.10g secs", result_line, _("Offset"), offset);
634 xasprintf(&perfdata_line, "%s", perfd_offset(offset)); 642 }
635 } 643 xasprintf(&perfdata_line, "%s", perfd_offset(offset));
644
636 if (do_jitter) { 645 if (do_jitter) {
637 xasprintf(&result_line, "%s, jitter=%f", result_line, jitter); 646 if (jresult == STATE_WARNING) {
647 xasprintf(&result_line, "%s, jitter=%f (WARNING)", result_line, jitter);
648 } else if (jresult == STATE_CRITICAL) {
649 xasprintf(&result_line, "%s, jitter=%f (CRITICAL)", result_line, jitter);
650 } else {
651 xasprintf(&result_line, "%s, jitter=%f", result_line, jitter);
652 }
638 xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_jitter(jitter)); 653 xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_jitter(jitter));
639 } 654 }
640 if (do_stratum) { 655 if (do_stratum) {
641 xasprintf(&result_line, "%s, stratum=%i", result_line, stratum); 656 if (sresult == STATE_WARNING) {
657 xasprintf(&result_line, "%s, stratum=%i (WARNING)", result_line, stratum);
658 } else if (sresult == STATE_CRITICAL) {
659 xasprintf(&result_line, "%s, stratum=%i (CRITICAL)", result_line, stratum);
660 } else {
661 xasprintf(&result_line, "%s, stratum=%i", result_line, stratum);
662 }
642 xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_stratum(stratum)); 663 xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_stratum(stratum));
643 } 664 }
644 if (do_truechimers) { 665 if (do_truechimers) {
645 xasprintf(&result_line, "%s, truechimers=%i", result_line, num_truechimers); 666 if (tresult == STATE_WARNING) {
667 xasprintf(&result_line, "%s, truechimers=%i (WARNING)", result_line, num_truechimers);
668 } else if (tresult == STATE_CRITICAL) {
669 xasprintf(&result_line, "%s, truechimers=%i (CRITICAL)", result_line, num_truechimers);
670 } else {
671 xasprintf(&result_line, "%s, truechimers=%i", result_line, num_truechimers);
672 }
646 xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_truechimers(num_truechimers)); 673 xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_truechimers(num_truechimers));
647 } 674 }
648 printf("%s|%s\n", result_line, perfdata_line); 675 printf("%s|%s\n", result_line, perfdata_line);
@@ -651,8 +678,6 @@ int main(int argc, char *argv[]){
651 return result; 678 return result;
652} 679}
653 680
654
655
656void print_help(void){ 681void print_help(void){
657 print_revision(progname, NP_VERSION); 682 print_revision(progname, NP_VERSION);
658 683
diff --git a/plugins/check_ntp_time.c b/plugins/check_ntp_time.c
index 72dffbd..e344f8b 100644
--- a/plugins/check_ntp_time.c
+++ b/plugins/check_ntp_time.c
@@ -48,6 +48,7 @@ static int verbose=0;
48static int quiet=0; 48static int quiet=0;
49static char *owarn="60"; 49static char *owarn="60";
50static char *ocrit="120"; 50static char *ocrit="120";
51static int time_offset=0;
51 52
52int process_arguments (int, char **); 53int process_arguments (int, char **);
53thresholds *offset_thresholds = NULL; 54thresholds *offset_thresholds = NULL;
@@ -400,7 +401,7 @@ double offset_request(const char *host, int *status){
400 gettimeofday(&recv_time, NULL); 401 gettimeofday(&recv_time, NULL);
401 DBG(print_ntp_message(&req[i])); 402 DBG(print_ntp_message(&req[i]));
402 respnum=servers[i].num_responses++; 403 respnum=servers[i].num_responses++;
403 servers[i].offset[respnum]=calc_offset(&req[i], &recv_time); 404 servers[i].offset[respnum]=calc_offset(&req[i], &recv_time)+time_offset;
404 if(verbose) { 405 if(verbose) {
405 printf("offset %.10g\n", servers[i].offset[respnum]); 406 printf("offset %.10g\n", servers[i].offset[respnum]);
406 } 407 }
@@ -455,6 +456,7 @@ int process_arguments(int argc, char **argv){
455 {"use-ipv4", no_argument, 0, '4'}, 456 {"use-ipv4", no_argument, 0, '4'},
456 {"use-ipv6", no_argument, 0, '6'}, 457 {"use-ipv6", no_argument, 0, '6'},
457 {"quiet", no_argument, 0, 'q'}, 458 {"quiet", no_argument, 0, 'q'},
459 {"time-offset", optional_argument, 0, 'o'},
458 {"warning", required_argument, 0, 'w'}, 460 {"warning", required_argument, 0, 'w'},
459 {"critical", required_argument, 0, 'c'}, 461 {"critical", required_argument, 0, 'c'},
460 {"timeout", required_argument, 0, 't'}, 462 {"timeout", required_argument, 0, 't'},
@@ -468,7 +470,7 @@ int process_arguments(int argc, char **argv){
468 usage ("\n"); 470 usage ("\n");
469 471
470 while (1) { 472 while (1) {
471 c = getopt_long (argc, argv, "Vhv46qw:c:t:H:p:", longopts, &option); 473 c = getopt_long (argc, argv, "Vhv46qw:c:t:H:p:o:", longopts, &option);
472 if (c == -1 || c == EOF || c == 1) 474 if (c == -1 || c == EOF || c == 1)
473 break; 475 break;
474 476
@@ -504,6 +506,9 @@ int process_arguments(int argc, char **argv){
504 case 't': 506 case 't':
505 socket_timeout=atoi(optarg); 507 socket_timeout=atoi(optarg);
506 break; 508 break;
509 case 'o':
510 time_offset=atoi(optarg);
511 break;
507 case '4': 512 case '4':
508 address_family = AF_INET; 513 address_family = AF_INET;
509 break; 514 break;
@@ -616,6 +621,8 @@ void print_help(void){
616 printf (" %s\n", _("Offset to result in warning status (seconds)")); 621 printf (" %s\n", _("Offset to result in warning status (seconds)"));
617 printf (" %s\n", "-c, --critical=THRESHOLD"); 622 printf (" %s\n", "-c, --critical=THRESHOLD");
618 printf (" %s\n", _("Offset to result in critical status (seconds)")); 623 printf (" %s\n", _("Offset to result in critical status (seconds)"));
624 printf (" %s\n", "-o, --time_offset=INTEGER");
625 printf (" %s\n", _("Expected offset of the ntp server relative to local server (seconds)"));
619 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 626 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
620 printf (UT_VERBOSE); 627 printf (UT_VERBOSE);
621 628
@@ -628,6 +635,8 @@ void print_help(void){
628 printf("%s\n", _("Notes:")); 635 printf("%s\n", _("Notes:"));
629 printf(" %s\n", _("If you'd rather want to monitor an NTP server, please use")); 636 printf(" %s\n", _("If you'd rather want to monitor an NTP server, please use"));
630 printf(" %s\n", _("check_ntp_peer.")); 637 printf(" %s\n", _("check_ntp_peer."));
638 printf(" %s\n", _("--time-offset is usefull for compensating for servers with known"));
639 printf(" %s\n", _("and expected clock skew."));
631 printf("\n"); 640 printf("\n");
632 printf(UT_THRESHOLDS_NOTES); 641 printf(UT_THRESHOLDS_NOTES);
633 642
@@ -642,6 +651,6 @@ void
642print_usage(void) 651print_usage(void)
643{ 652{
644 printf ("%s\n", _("Usage:")); 653 printf ("%s\n", _("Usage:"));
645 printf(" %s -H <host> [-4|-6] [-w <warn>] [-c <crit>] [-v verbose]\n", progname); 654 printf(" %s -H <host> [-4|-6] [-w <warn>] [-c <crit>] [-v verbose] [-o <time offset>]\n", progname);
646} 655}
647 656
diff --git a/plugins/check_radius.c b/plugins/check_radius.c
index 3481f0c..b294347 100644
--- a/plugins/check_radius.c
+++ b/plugins/check_radius.c
@@ -36,9 +36,10 @@ const char *email = "devel@monitoring-plugins.org";
36#include "utils.h" 36#include "utils.h"
37#include "netutils.h" 37#include "netutils.h"
38 38
39#ifdef HAVE_LIBRADIUSCLIENT_NG 39#if defined(HAVE_LIBFREERADIUS_CLIENT)
40#include <freeradius-client.h>
41#elif defined(HAVE_LIBRADIUSCLIENT_NG)
40#include <radiusclient-ng.h> 42#include <radiusclient-ng.h>
41rc_handle *rch = NULL;
42#else 43#else
43#include <radiusclient.h> 44#include <radiusclient.h>
44#endif 45#endif
@@ -47,11 +48,14 @@ int process_arguments (int, char **);
47void print_help (void); 48void print_help (void);
48void print_usage (void); 49void print_usage (void);
49 50
50/* libradiusclient(-ng) wrapper functions */ 51#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG)
51#ifdef HAVE_LIBRADIUSCLIENT_NG
52#define my_rc_conf_str(a) rc_conf_str(rch,a) 52#define my_rc_conf_str(a) rc_conf_str(rch,a)
53#define my_rc_send_server(a,b) rc_send_server(rch,a,b) 53#define my_rc_send_server(a,b) rc_send_server(rch,a,b)
54#ifdef HAVE_LIBFREERADIUS_CLIENT
55#define my_rc_buildreq(a,b,c,d,e,f) rc_buildreq(rch,a,b,c,d,(a)->secret,e,f)
56#else
54#define my_rc_buildreq(a,b,c,d,e,f) rc_buildreq(rch,a,b,c,d,e,f) 57#define my_rc_buildreq(a,b,c,d,e,f) rc_buildreq(rch,a,b,c,d,e,f)
58#endif
55#define my_rc_own_ipaddress() rc_own_ipaddress(rch) 59#define my_rc_own_ipaddress() rc_own_ipaddress(rch)
56#define my_rc_avpair_add(a,b,c,d) rc_avpair_add(rch,a,b,c,-1,d) 60#define my_rc_avpair_add(a,b,c,d) rc_avpair_add(rch,a,b,c,-1,d)
57#define my_rc_read_dictionary(a) rc_read_dictionary(rch, a) 61#define my_rc_read_dictionary(a) rc_read_dictionary(rch, a)
@@ -72,6 +76,10 @@ void print_usage (void);
72 76
73int my_rc_read_config(char *); 77int my_rc_read_config(char *);
74 78
79#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG)
80rc_handle *rch = NULL;
81#endif
82
75char *server = NULL; 83char *server = NULL;
76char *username = NULL; 84char *username = NULL;
77char *password = NULL; 85char *password = NULL;
@@ -142,11 +150,10 @@ Please note that all tags must be lowercase to use the DocBook XML DTD.
142int 150int
143main (int argc, char **argv) 151main (int argc, char **argv)
144{ 152{
145 UINT4 service;
146 char msg[BUFFER_LEN]; 153 char msg[BUFFER_LEN];
147 SEND_DATA data; 154 SEND_DATA data;
148 int result = STATE_UNKNOWN; 155 int result = STATE_UNKNOWN;
149 UINT4 client_id; 156 uint32_t client_id, service;
150 char *str; 157 char *str;
151 158
152 setlocale (LC_ALL, ""); 159 setlocale (LC_ALL, "");
@@ -162,7 +169,7 @@ main (int argc, char **argv)
162 str = strdup ("dictionary"); 169 str = strdup ("dictionary");
163 if ((config_file && my_rc_read_config (config_file)) || 170 if ((config_file && my_rc_read_config (config_file)) ||
164 my_rc_read_dictionary (my_rc_conf_str (str))) 171 my_rc_read_dictionary (my_rc_conf_str (str)))
165 die (STATE_UNKNOWN, _("Config file error")); 172 die (STATE_UNKNOWN, _("Config file error\n"));
166 173
167 service = PW_AUTHENTICATE_ONLY; 174 service = PW_AUTHENTICATE_ONLY;
168 175
@@ -171,24 +178,24 @@ main (int argc, char **argv)
171 my_rc_avpair_add (&data.send_pairs, PW_USER_NAME, username, 0) && 178 my_rc_avpair_add (&data.send_pairs, PW_USER_NAME, username, 0) &&
172 my_rc_avpair_add (&data.send_pairs, PW_USER_PASSWORD, password, 0) 179 my_rc_avpair_add (&data.send_pairs, PW_USER_PASSWORD, password, 0)
173 )) 180 ))
174 die (STATE_UNKNOWN, _("Out of Memory?")); 181 die (STATE_UNKNOWN, _("Out of Memory?\n"));
175 182
176 if (nasid != NULL) { 183 if (nasid != NULL) {
177 if (!(my_rc_avpair_add (&data.send_pairs, PW_NAS_IDENTIFIER, nasid, 0))) 184 if (!(my_rc_avpair_add (&data.send_pairs, PW_NAS_IDENTIFIER, nasid, 0)))
178 die (STATE_UNKNOWN, _("Invalid NAS-Identifier")); 185 die (STATE_UNKNOWN, _("Invalid NAS-Identifier\n"));
179 } 186 }
180 187
181 if (nasipaddress != NULL) { 188 if (nasipaddress != NULL) {
182 if (rc_good_ipaddr (nasipaddress)) 189 if (rc_good_ipaddr (nasipaddress))
183 die (STATE_UNKNOWN, _("Invalid NAS-IP-Address")); 190 die (STATE_UNKNOWN, _("Invalid NAS-IP-Address\n"));
184 if ((client_id = rc_get_ipaddr(nasipaddress)) == 0) 191 if ((client_id = rc_get_ipaddr(nasipaddress)) == 0)
185 die (STATE_UNKNOWN, _("Invalid NAS-IP-Address")); 192 die (STATE_UNKNOWN, _("Invalid NAS-IP-Address\n"));
186 } else { 193 } else {
187 if ((client_id = my_rc_own_ipaddress ()) == 0) 194 if ((client_id = my_rc_own_ipaddress ()) == 0)
188 die (STATE_UNKNOWN, _("Can't find local IP for NAS-IP-Address")); 195 die (STATE_UNKNOWN, _("Can't find local IP for NAS-IP-Address\n"));
189 } 196 }
190 if (my_rc_avpair_add (&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) == NULL) 197 if (my_rc_avpair_add (&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) == NULL)
191 die (STATE_UNKNOWN, _("Invalid NAS-IP-Address")); 198 die (STATE_UNKNOWN, _("Invalid NAS-IP-Address\n"));
192 199
193 my_rc_buildreq (&data, PW_ACCESS_REQUEST, server, port, (int)timeout_interval, 200 my_rc_buildreq (&data, PW_ACCESS_REQUEST, server, port, (int)timeout_interval,
194 retries); 201 retries);
@@ -199,19 +206,19 @@ main (int argc, char **argv)
199 rc_avpair_free (data.receive_pairs); 206 rc_avpair_free (data.receive_pairs);
200 207
201 if (result == TIMEOUT_RC) 208 if (result == TIMEOUT_RC)
202 die (STATE_CRITICAL, _("Timeout")); 209 die (STATE_CRITICAL, _("Timeout\n"));
203 if (result == ERROR_RC) 210 if (result == ERROR_RC)
204 die (STATE_CRITICAL, _("Auth Error")); 211 die (STATE_CRITICAL, _("Auth Error\n"));
205 if (result == REJECT_RC) 212 if (result == REJECT_RC)
206 die (STATE_WARNING, _("Auth Failed")); 213 die (STATE_WARNING, _("Auth Failed\n"));
207 if (result == BADRESP_RC) 214 if (result == BADRESP_RC)
208 die (STATE_WARNING, _("Bad Response")); 215 die (STATE_WARNING, _("Bad Response\n"));
209 if (expect && !strstr (msg, expect)) 216 if (expect && !strstr (msg, expect))
210 die (STATE_WARNING, "%s", msg); 217 die (STATE_WARNING, "%s\n", msg);
211 if (result == OK_RC) 218 if (result == OK_RC)
212 die (STATE_OK, _("Auth OK")); 219 die (STATE_OK, _("Auth OK\n"));
213 (void)snprintf(msg, sizeof(msg), _("Unexpected result code %d"), result); 220 (void)snprintf(msg, sizeof(msg), _("Unexpected result code %d"), result);
214 die (STATE_UNKNOWN, "%s", msg); 221 die (STATE_UNKNOWN, "%s\n", msg);
215} 222}
216 223
217 224
@@ -392,7 +399,7 @@ print_usage (void)
392 399
393int my_rc_read_config(char * a) 400int my_rc_read_config(char * a)
394{ 401{
395#ifdef HAVE_LIBRADIUSCLIENT_NG 402#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG)
396 rch = rc_read_config(a); 403 rch = rc_read_config(a);
397 return (rch == NULL) ? 1 : 0; 404 return (rch == NULL) ? 1 : 0;
398#else 405#else
diff --git a/plugins/check_real.c b/plugins/check_real.c
index 47776c5..36f6413 100644
--- a/plugins/check_real.c
+++ b/plugins/check_real.c
@@ -178,6 +178,7 @@ main (int argc, char **argv)
178 178
179 /* watch for the REAL connection string */ 179 /* watch for the REAL connection string */
180 result = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0); 180 result = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0);
181 buffer[result] = "\0"; /* null terminate recieved buffer */
181 182
182 /* return a CRITICAL status if we couldn't read any data */ 183 /* return a CRITICAL status if we couldn't read any data */
183 if (result == -1) { 184 if (result == -1) {
diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c
index f4522e2..b6187d6 100644
--- a/plugins/check_ssh.c
+++ b/plugins/check_ssh.c
@@ -46,6 +46,7 @@ const char *email = "devel@monitoring-plugins.org";
46int port = -1; 46int port = -1;
47char *server_name = NULL; 47char *server_name = NULL;
48char *remote_version = NULL; 48char *remote_version = NULL;
49char *remote_protocol = NULL;
49int verbose = FALSE; 50int verbose = FALSE;
50 51
51int process_arguments (int, char **); 52int process_arguments (int, char **);
@@ -53,7 +54,7 @@ int validate_arguments (void);
53void print_help (void); 54void print_help (void);
54void print_usage (void); 55void print_usage (void);
55 56
56int ssh_connect (char *haddr, int hport, char *remote_version); 57int ssh_connect (char *haddr, int hport, char *remote_version, char *remote_protocol);
57 58
58 59
59 60
@@ -78,7 +79,7 @@ main (int argc, char **argv)
78 alarm (socket_timeout); 79 alarm (socket_timeout);
79 80
80 /* ssh_connect exits if error is found */ 81 /* ssh_connect exits if error is found */
81 result = ssh_connect (server_name, port, remote_version); 82 result = ssh_connect (server_name, port, remote_version, remote_protocol);
82 83
83 alarm (0); 84 alarm (0);
84 85
@@ -105,6 +106,7 @@ process_arguments (int argc, char **argv)
105 {"timeout", required_argument, 0, 't'}, 106 {"timeout", required_argument, 0, 't'},
106 {"verbose", no_argument, 0, 'v'}, 107 {"verbose", no_argument, 0, 'v'},
107 {"remote-version", required_argument, 0, 'r'}, 108 {"remote-version", required_argument, 0, 'r'},
109 {"remote-protcol", required_argument, 0, 'P'},
108 {0, 0, 0, 0} 110 {0, 0, 0, 0}
109 }; 111 };
110 112
@@ -116,7 +118,7 @@ process_arguments (int argc, char **argv)
116 strcpy (argv[c], "-t"); 118 strcpy (argv[c], "-t");
117 119
118 while (1) { 120 while (1) {
119 c = getopt_long (argc, argv, "+Vhv46t:r:H:p:", longopts, &option); 121 c = getopt_long (argc, argv, "+Vhv46t:r:H:p:P:", longopts, &option);
120 122
121 if (c == -1 || c == EOF) 123 if (c == -1 || c == EOF)
122 break; 124 break;
@@ -152,6 +154,9 @@ process_arguments (int argc, char **argv)
152 case 'r': /* remote version */ 154 case 'r': /* remote version */
153 remote_version = optarg; 155 remote_version = optarg;
154 break; 156 break;
157 case 'P': /* remote version */
158 remote_protocol = optarg;
159 break;
155 case 'H': /* host */ 160 case 'H': /* host */
156 if (is_host (optarg) == FALSE) 161 if (is_host (optarg) == FALSE)
157 usage2 (_("Invalid hostname/address"), optarg); 162 usage2 (_("Invalid hostname/address"), optarg);
@@ -206,7 +211,7 @@ validate_arguments (void)
206 211
207 212
208int 213int
209ssh_connect (char *haddr, int hport, char *remote_version) 214ssh_connect (char *haddr, int hport, char *remote_version, char *remote_protocol)
210{ 215{
211 int sd; 216 int sd;
212 int result; 217 int result;
@@ -254,6 +259,14 @@ ssh_connect (char *haddr, int hport, char *remote_version)
254 exit (STATE_WARNING); 259 exit (STATE_WARNING);
255 } 260 }
256 261
262 if (remote_protocol && strcmp(remote_protocol, ssh_proto)) {
263 printf
264 (_("SSH WARNING - %s (protocol %s) protocol version mismatch, expected '%s'\n"),
265 ssh_server, ssh_proto, remote_protocol);
266 close(sd);
267 exit (STATE_WARNING);
268 }
269
257 elapsed_time = (double)deltime(tv) / 1.0e6; 270 elapsed_time = (double)deltime(tv) / 1.0e6;
258 271
259 printf 272 printf
@@ -296,6 +309,9 @@ print_help (void)
296 printf (" %s\n", "-r, --remote-version=STRING"); 309 printf (" %s\n", "-r, --remote-version=STRING");
297 printf (" %s\n", _("Warn if string doesn't match expected server version (ex: OpenSSH_3.9p1)")); 310 printf (" %s\n", _("Warn if string doesn't match expected server version (ex: OpenSSH_3.9p1)"));
298 311
312 printf (" %s\n", "-P, --remote-protocol=STRING");
313 printf (" %s\n", _("Warn if protocol doesn't match expected protocol version (ex: 2.0)"));
314
299 printf (UT_VERBOSE); 315 printf (UT_VERBOSE);
300 316
301 printf (UT_SUPPORT); 317 printf (UT_SUPPORT);
diff --git a/plugins/check_tcp.c b/plugins/check_tcp.c
index 0a6e2b2..f75c523 100644
--- a/plugins/check_tcp.c
+++ b/plugins/check_tcp.c
@@ -32,13 +32,12 @@ char *progname;
32const char *copyright = "1999-2008"; 32const char *copyright = "1999-2008";
33const char *email = "devel@monitoring-plugins.org"; 33const char *email = "devel@monitoring-plugins.org";
34 34
35#include <ctype.h>
36
37#include "common.h" 35#include "common.h"
38#include "netutils.h" 36#include "netutils.h"
39#include "utils.h" 37#include "utils.h"
40#include "utils_tcp.h" 38#include "utils_tcp.h"
41 39
40#include <ctype.h>
42#include <sys/select.h> 41#include <sys/select.h>
43 42
44#ifdef HAVE_SSL 43#ifdef HAVE_SSL
@@ -354,8 +353,13 @@ main (int argc, char **argv)
354 printf("Unexpected response from host/socket on "); 353 printf("Unexpected response from host/socket on ");
355 else 354 else
356 printf("%.3f second response time on ", elapsed_time); 355 printf("%.3f second response time on ", elapsed_time);
357 if(server_address[0] != '/') 356 if(server_address[0] != '/') {
358 printf("port %d", server_port); 357 if (host_specified)
358 printf("%s port %d",
359 server_address, server_port);
360 else
361 printf("port %d", server_port);
362 }
359 else 363 else
360 printf("socket %s", server_address); 364 printf("socket %s", server_address);
361 } 365 }
diff --git a/plugins/check_ups.c b/plugins/check_ups.c
index 7cced49..099881d 100644
--- a/plugins/check_ups.c
+++ b/plugins/check_ups.c
@@ -66,7 +66,7 @@ enum {
66#define UPSSTATUS_BOOST 512 66#define UPSSTATUS_BOOST 512
67#define UPSSTATUS_CHRG 1024 67#define UPSSTATUS_CHRG 1024
68#define UPSSTATUS_DISCHRG 2048 68#define UPSSTATUS_DISCHRG 2048
69#define UPSSTATUS_UNKOWN 4096 69#define UPSSTATUS_UNKNOWN 4096
70 70
71enum { NOSUCHVAR = ERROR-1 }; 71enum { NOSUCHVAR = ERROR-1 };
72 72
@@ -181,7 +181,7 @@ main (int argc, char **argv)
181 if (status & UPSSTATUS_DISCHRG) { 181 if (status & UPSSTATUS_DISCHRG) {
182 xasprintf (&ups_status, "%s%s", ups_status, _(", Discharging")); 182 xasprintf (&ups_status, "%s%s", ups_status, _(", Discharging"));
183 } 183 }
184 if (status & UPSSTATUS_UNKOWN) { 184 if (status & UPSSTATUS_UNKNOWN) {
185 xasprintf (&ups_status, "%s%s", ups_status, _(", Unknown")); 185 xasprintf (&ups_status, "%s%s", ups_status, _(", Unknown"));
186 } 186 }
187 } 187 }
@@ -379,7 +379,7 @@ determine_status (void)
379 else if (!strcmp (ptr, "DISCHRG")) 379 else if (!strcmp (ptr, "DISCHRG"))
380 status |= UPSSTATUS_DISCHRG; 380 status |= UPSSTATUS_DISCHRG;
381 else 381 else
382 status |= UPSSTATUS_UNKOWN; 382 status |= UPSSTATUS_UNKNOWN;
383 } 383 }
384 384
385 return OK; 385 return OK;
diff --git a/plugins/negate.c b/plugins/negate.c
index 4bd09de..beaed1e 100644
--- a/plugins/negate.c
+++ b/plugins/negate.c
@@ -35,16 +35,16 @@ const char *email = "devel@monitoring-plugins.org";
35 35
36#define DEFAULT_TIMEOUT 11 36#define DEFAULT_TIMEOUT 11
37 37
38#include <ctype.h>
39
40#include "common.h" 38#include "common.h"
41#include "utils.h" 39#include "utils.h"
42#include "utils_cmd.h" 40#include "utils_cmd.h"
43 41
42#include <ctype.h>
43
44/* char *command_line; */ 44/* char *command_line; */
45 45
46static const char **process_arguments (int, char **); 46static const char **process_arguments (int, char **);
47int validate_arguments (char **); 47void validate_arguments (char **);
48void print_help (void); 48void print_help (void);
49void print_usage (void); 49void print_usage (void);
50int subst_text = FALSE; 50int subst_text = FALSE;
@@ -98,8 +98,7 @@ main (int argc, char **argv)
98 die (max_state_alt (result, STATE_UNKNOWN), _("No data returned from command\n")); 98 die (max_state_alt (result, STATE_UNKNOWN), _("No data returned from command\n"));
99 99
100 for (i = 0; i < chld_out.lines; i++) { 100 for (i = 0; i < chld_out.lines; i++) {
101 if (subst_text && result != state[result] && 101 if (subst_text && result >= 0 && result <= 4 && result != state[result]) {
102 result >= 0 && result <= 4) {
103 /* Loop over each match found */ 102 /* Loop over each match found */
104 while ((sub = strstr (chld_out.line[i], state_text (result)))) { 103 while ((sub = strstr (chld_out.line[i], state_text (result)))) {
105 /* Terminate the first part and skip over the string we'll substitute */ 104 /* Terminate the first part and skip over the string we'll substitute */
@@ -206,7 +205,7 @@ process_arguments (int argc, char **argv)
206} 205}
207 206
208 207
209int 208void
210validate_arguments (char **command_line) 209validate_arguments (char **command_line)
211{ 210{
212 if (command_line[0] == NULL) 211 if (command_line[0] == NULL)
diff --git a/plugins/netutils.c b/plugins/netutils.c
index 7ae9722..705aaf0 100644
--- a/plugins/netutils.c
+++ b/plugins/netutils.c
@@ -171,11 +171,12 @@ np_net_connect (const char *host_name, int port, int *sd, int proto)
171 char port_str[6], host[MAX_HOST_ADDRESS_LENGTH]; 171 char port_str[6], host[MAX_HOST_ADDRESS_LENGTH];
172 size_t len; 172 size_t len;
173 int socktype, result; 173 int socktype, result;
174 short is_socket = (host_name[0] == '/');
174 175
175 socktype = (proto == IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM; 176 socktype = (proto == IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM;
176 177
177 /* as long as it doesn't start with a '/', it's assumed a host or ip */ 178 /* as long as it doesn't start with a '/', it's assumed a host or ip */
178 if(host_name[0] != '/'){ 179 if (!is_socket){
179 memset (&hints, 0, sizeof (hints)); 180 memset (&hints, 0, sizeof (hints));
180 hints.ai_family = address_family; 181 hints.ai_family = address_family;
181 hints.ai_protocol = proto; 182 hints.ai_protocol = proto;
@@ -255,7 +256,11 @@ np_net_connect (const char *host_name, int port, int *sd, int proto)
255 case STATE_OK: 256 case STATE_OK:
256 case STATE_WARNING: /* user wants WARN or OK on refusal, or... */ 257 case STATE_WARNING: /* user wants WARN or OK on refusal, or... */
257 case STATE_CRITICAL: /* user did not set econn_refuse_state, or wanted critical */ 258 case STATE_CRITICAL: /* user did not set econn_refuse_state, or wanted critical */
258 printf ("%s\n", strerror(errno)); 259 if (is_socket)
260 printf("connect to file socket %s: %s\n", host_name, strerror(errno));
261 else
262 printf("connect to address %s and port %d: %s\n",
263 host_name, port, strerror(errno));
259 return STATE_CRITICAL; 264 return STATE_CRITICAL;
260 break; 265 break;
261 default: /* it's a logic error if we do not end up in STATE_(OK|WARNING|CRITICAL) */ 266 default: /* it's a logic error if we do not end up in STATE_(OK|WARNING|CRITICAL) */
@@ -264,7 +269,11 @@ np_net_connect (const char *host_name, int port, int *sd, int proto)
264 } 269 }
265 } 270 }
266 else { 271 else {
267 printf ("%s\n", strerror(errno)); 272 if (is_socket)
273 printf("connect to file socket %s: %s\n", host_name, strerror(errno));
274 else
275 printf("connect to address %s and port %d: %s\n",
276 host_name, port, strerror(errno));
268 return STATE_CRITICAL; 277 return STATE_CRITICAL;
269 } 278 }
270} 279}
diff --git a/plugins/netutils.h b/plugins/netutils.h
index c5aa18f..c6fce90 100644
--- a/plugins/netutils.h
+++ b/plugins/netutils.h
@@ -40,8 +40,8 @@
40#ifdef HAVE_SYS_UN_H 40#ifdef HAVE_SYS_UN_H
41# include <sys/un.h> 41# include <sys/un.h>
42# ifndef UNIX_PATH_MAX 42# ifndef UNIX_PATH_MAX
43 /* linux uses this, on sun it's hard-coded at 108 without a define */ 43 /* linux uses this, on sun it's hard-coded at 108 without a define, on BSD at 104 */
44# define UNIX_PATH_MAX 108 44# define UNIX_PATH_MAX 104
45# endif /* UNIX_PATH_MAX */ 45# endif /* UNIX_PATH_MAX */
46#endif /* HAVE_SYS_UN_H */ 46#endif /* HAVE_SYS_UN_H */
47 47
diff --git a/plugins/runcmd.c b/plugins/runcmd.c
index 4352e60..1a7c904 100644
--- a/plugins/runcmd.c
+++ b/plugins/runcmd.c
@@ -261,7 +261,7 @@ runcmd_timeout_alarm_handler (int signo)
261 size_t i; 261 size_t i;
262 262
263 if (signo == SIGALRM) 263 if (signo == SIGALRM)
264 puts(_("CRITICAL - Plugin timed out while executing system call\n")); 264 puts(_("CRITICAL - Plugin timed out while executing system call"));
265 265
266 if(np_pids) for(i = 0; i < maxfd; i++) { 266 if(np_pids) for(i = 0; i < maxfd; i++) {
267 if(np_pids[i] != 0) kill(np_pids[i], SIGKILL); 267 if(np_pids[i] != 0) kill(np_pids[i], SIGKILL);
diff --git a/plugins/sslutils.c b/plugins/sslutils.c
index 2732125..d0ae474 100644
--- a/plugins/sslutils.c
+++ b/plugins/sslutils.c
@@ -86,10 +86,12 @@ int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int
86 if (cert && privkey) { 86 if (cert && privkey) {
87 SSL_CTX_use_certificate_file(c, cert, SSL_FILETYPE_PEM); 87 SSL_CTX_use_certificate_file(c, cert, SSL_FILETYPE_PEM);
88 SSL_CTX_use_PrivateKey_file(c, privkey, SSL_FILETYPE_PEM); 88 SSL_CTX_use_PrivateKey_file(c, privkey, SSL_FILETYPE_PEM);
89#ifdef USE_OPENSSL
89 if (!SSL_CTX_check_private_key(c)) { 90 if (!SSL_CTX_check_private_key(c)) {
90 printf ("%s\n", _("CRITICAL - Private key does not seem to match certificate!\n")); 91 printf ("%s\n", _("CRITICAL - Private key does not seem to match certificate!\n"));
91 return STATE_CRITICAL; 92 return STATE_CRITICAL;
92 } 93 }
94#endif
93 } 95 }
94#ifdef SSL_OP_NO_TICKET 96#ifdef SSL_OP_NO_TICKET
95 SSL_CTX_set_options(c, SSL_OP_NO_TICKET); 97 SSL_CTX_set_options(c, SSL_OP_NO_TICKET);
@@ -151,7 +153,8 @@ int np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit){
151 struct tm stamp; 153 struct tm stamp;
152 float time_left; 154 float time_left;
153 int days_left; 155 int days_left;
154 char timestamp[17] = ""; 156 char timestamp[50] = "";
157 time_t tm_t;
155 158
156 certificate=SSL_get_peer_certificate(s); 159 certificate=SSL_get_peer_certificate(s);
157 if (!certificate) { 160 if (!certificate) {
@@ -209,10 +212,8 @@ int np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit){
209 212
210 time_left = difftime(timegm(&stamp), time(NULL)); 213 time_left = difftime(timegm(&stamp), time(NULL));
211 days_left = time_left / 86400; 214 days_left = time_left / 86400;
212 snprintf 215 tm_t = mktime (&stamp);
213 (timestamp, 17, "%02d/%02d/%04d %02d:%02d", 216 strftime(timestamp, 50, "%c", localtime(&tm_t));
214 stamp.tm_mon + 1,
215 stamp.tm_mday, stamp.tm_year + 1900, stamp.tm_hour, stamp.tm_min);
216 217
217 if (days_left > 0 && days_left <= days_till_exp_warn) { 218 if (days_left > 0 && days_left <= days_till_exp_warn) {
218 printf (_("%s - Certificate '%s' expires in %d day(s) (%s).\n"), (days_left>days_till_exp_crit)?"WARNING":"CRITICAL", cn, days_left, timestamp); 219 printf (_("%s - Certificate '%s' expires in %d day(s) (%s).\n"), (days_left>days_till_exp_crit)?"WARNING":"CRITICAL", cn, days_left, timestamp);
diff --git a/plugins/t/NPTest.cache.travis b/plugins/t/NPTest.cache.travis
new file mode 100644
index 0000000..4ebfb90
--- /dev/null
+++ b/plugins/t/NPTest.cache.travis
@@ -0,0 +1,56 @@
1{
2 'MYSQL_LOGIN_DETAILS' => '-u root -d test',
3 'NP_ALLOW_SUDO' => 'yes',
4 'NP_DNS_SERVER' => '8.8.8.8',
5 'NP_GOOD_NTP_SERVICE' => '',
6 'NP_HOSTNAME_INVALID' => 'nosuchhost',
7 'NP_HOSTNAME_VALID' => 'monitoringplugins.org',
8 'NP_HOSTNAME_VALID_IP' => '130.133.8.40',
9 'NP_HOSTNAME_VALID_REVERSE' => 'orwell.monitoring-plugins.org.',
10 'NP_HOST_DHCP_RESPONSIVE' => '',
11 'NP_HOST_NONRESPONSIVE' => '10.0.0.1',
12 'NP_HOST_RESPONSIVE' => 'localhost',
13 'NP_HOST_SMB' => '',
14 'NP_HOST_SNMP' => '',
15 'NP_HOST_TCP_FTP' => '',
16 'NP_HOST_TCP_HPJD' => '',
17 'NP_HOST_HPJD_PORT_INVALID' => '161',
18 'NP_HOST_HPJD_PORT_VALID' => '',
19 'NP_HOST_TCP_HTTP' => 'localhost',
20 'NP_HOST_TCP_HTTP2' => 'labs.consol.de',
21 'NP_HOST_TCP_IMAP' => 'imap.web.de',
22 'NP_HOST_TCP_POP' => 'pop.web.de',
23 'NP_HOST_TCP_SMTP' => 'localhost',
24 'NP_HOST_TCP_SMTP_NOTLS' => '',
25 'NP_HOST_TCP_SMTP_TLS' => '',
26 'NP_INTERNET_ACCESS' => 'yes',
27 'NP_MOUNTPOINT2_VALID' => '',
28 'NP_MOUNTPOINT_VALID' => '/',
29 'NP_MYSQL_SERVER' => 'localhost',
30 'NP_HOST_UDP_TIME' => 'localhost',
31 'NP_MYSQL_SOCKET' => '/var/run/mysqld/mysqld.sock',
32 'NP_MYSQL_WITH_SLAVE' => '',
33 'NP_MYSQL_WITH_SLAVE_LOGIN' => '',
34 'NP_NO_NTP_SERVICE' => 'localhost',
35 'NP_SMB_SHARE' => '',
36 'NP_SMB_SHARE_DENY' => '',
37 'NP_SMB_SHARE_SPC' => '',
38 'NP_SMB_VALID_USER' => '',
39 'NP_SMB_VALID_USER_PASS' => '',
40 'NP_SNMP_COMMUNITY' => '',
41 'NP_SSH_CONFIGFILE' => '~/.ssh/config',
42 'NP_SSH_HOST' => 'localhost',
43 'NP_SSH_IDENTITY' => '~/.ssh/id_dsa',
44 'NP_HOST_TCP_JABBER' => 'jabber.org',
45 'host_nonresponsive' => '10.0.0.1',
46 'host_responsive' => 'localhost',
47 'host_snmp' => '',
48 'host_tcp_ftp' => '',
49 'host_tcp_http' => 'localhost',
50 'host_tcp_imap' => 'imap.nierlein.de',
51 'host_tcp_smtp' => 'localhost',
52 'hostname_invalid' => 'nosuchhost',
53 'snmp_community' => '',
54 'user_snmp' => '',
55 'host_udp_time' => 'none',
56}
diff --git a/plugins/t/check_dns.t b/plugins/t/check_dns.t
index 2c903db..b885880 100644
--- a/plugins/t/check_dns.t
+++ b/plugins/t/check_dns.t
@@ -10,7 +10,7 @@ use NPTest;
10 10
11plan skip_all => "check_dns not compiled" unless (-x "check_dns"); 11plan skip_all => "check_dns not compiled" unless (-x "check_dns");
12 12
13plan tests => 13; 13plan tests => 14;
14 14
15my $successOutput = '/DNS OK: [\.0-9]+ seconds? response time/'; 15my $successOutput = '/DNS OK: [\.0-9]+ seconds? response time/';
16 16
@@ -54,6 +54,7 @@ cmp_ok( $res->return_code, '==', 2, "Critical threshold passed");
54 54
55$res = NPTest->testCmd("./check_dns -H $hostname_valid -t 5 -w 0 -c 5"); 55$res = NPTest->testCmd("./check_dns -H $hostname_valid -t 5 -w 0 -c 5");
56cmp_ok( $res->return_code, '==', 1, "Warning threshold passed"); 56cmp_ok( $res->return_code, '==', 1, "Warning threshold passed");
57like( $res->output, '/\|time=[\d\.]+s;0.0*;5\.0*;0\.0*/', "Output performance data OK" );
57 58
58$res = NPTest->testCmd("./check_dns -H $hostname_invalid -t 1"); 59$res = NPTest->testCmd("./check_dns -H $hostname_invalid -t 1");
59cmp_ok( $res->return_code, '==', 2, "Invalid $hostname_invalid"); 60cmp_ok( $res->return_code, '==', 2, "Invalid $hostname_invalid");
diff --git a/plugins/t/check_fping.t b/plugins/t/check_fping.t
index 45a9be8..08692e4 100644
--- a/plugins/t/check_fping.t
+++ b/plugins/t/check_fping.t
@@ -27,16 +27,18 @@ my $hostname_invalid = getTestParameter( "hostname_invalid", "NP_HOSTNAME_IN
27 27
28my $t; 28my $t;
29 29
30if ( -x "./check_fping" ) 30my $fping = qx(which fping 2> /dev/null);
31{ 31chomp($fping);
32if( ! -x "./check_fping") {
33 $t += skipMissingCmd( "./check_fping", $tests );
34}
35elsif ( $> != 0 && (!$fping || ! -u $fping)) {
36 $t += skipMsg( "./check_fping", $tests );
37} else {
32 $t += checkCmd( "./check_fping $host_responsive", 0, $successOutput ); 38 $t += checkCmd( "./check_fping $host_responsive", 0, $successOutput );
33 $t += checkCmd( "./check_fping $host_nonresponsive", [ 1, 2 ] ); 39 $t += checkCmd( "./check_fping $host_nonresponsive", [ 1, 2 ] );
34 $t += checkCmd( "./check_fping $hostname_invalid", [ 1, 2 ] ); 40 $t += checkCmd( "./check_fping $hostname_invalid", [ 1, 2 ] );
35} 41}
36else
37{
38 $t += skipMissingCmd( "./check_fping", $tests );
39}
40 42
41exit(0) if defined($Test::Harness::VERSION); 43exit(0) if defined($Test::Harness::VERSION);
42exit($tests - $t); 44exit($tests - $t);
diff --git a/plugins/t/check_hpjd.t b/plugins/t/check_hpjd.t
index 10ded54..4d64852 100644
--- a/plugins/t/check_hpjd.t
+++ b/plugins/t/check_hpjd.t
@@ -10,7 +10,6 @@ use NPTest;
10 10
11plan skip_all => "check_hpjd not compiled" unless (-x "check_hpjd"); 11plan skip_all => "check_hpjd not compiled" unless (-x "check_hpjd");
12 12
13plan tests => 5;
14 13
15my $successOutput = '/^Printer ok - /'; 14my $successOutput = '/^Printer ok - /';
16my $failureOutput = '/Timeout: No [Rr]esponse from /'; 15my $failureOutput = '/Timeout: No [Rr]esponse from /';
@@ -20,31 +19,53 @@ my $host_tcp_hpjd = getTestParameter(
20 "A host (usually a printer) providing the HP-JetDirect Services" 19 "A host (usually a printer) providing the HP-JetDirect Services"
21 ); 20 );
22 21
22my $host_hpjd_port_invalid = getTestParameter(
23 "NP_HOST_HPJD_PORT_INVALID",
24 "A port that HP-JetDirect Services is not listening on",
25 "162"
26 );
27
28my $host_hpjd_port_valid = getTestParameter(
29 "NP_HOST_HPJD_PORT_VALID",
30 "The port that HP-JetDirect Services is currently listening on",
31 "161"
32 );
33
23my $host_nonresponsive = getTestParameter( 34my $host_nonresponsive = getTestParameter(
24 "NP_HOST_NONRESPONSIVE", 35 "NP_HOST_NONRESPONSIVE",
25 "The hostname of system not responsive to network requests", 36 "The hostname of system not responsive to network requests",
26 "10.0.0.1", 37 "10.0.0.1"
27 ); 38 );
28 39
29my $hostname_invalid = getTestParameter( 40my $hostname_invalid = getTestParameter(
30 "NP_HOSTNAME_INVALID", 41 "NP_HOSTNAME_INVALID",
31 "An invalid (not known to DNS) hostname", 42 "An invalid (not known to DNS) hostname",
32 "nosuchhost", 43 "nosuchhost"
33 ); 44 );
34 45
46my $tests = $host_tcp_hpjd ? 9 : 5;
47plan tests => $tests;
35my $res; 48my $res;
36 49
37SKIP: { 50SKIP: {
38 skip "No HP JetDirect defined", 2 unless $host_tcp_hpjd; 51 skip "No HP JetDirect defined", 2 unless $host_tcp_hpjd;
39 $res = NPTest->testCmd("./check_hpjd $host_tcp_hpjd"); 52 $res = NPTest->testCmd("./check_hpjd -H $host_tcp_hpjd");
40 cmp_ok( $res->return_code, '==', 0, "Jetdirect responding" ); 53 cmp_ok( $res->return_code, 'eq', 0, "Jetdirect responding" );
41 like ( $res->output, $successOutput, "Output correct" ); 54 like ( $res->output, $successOutput, "Output correct" );
55
56 $res = NPTest->testCmd("./check_hpjd -H $host_tcp_hpjd -p $host_hpjd_port_valid");
57 cmp_ok( $res->return_code, 'eq', 0, "Jetdirect responding on port $host_hpjd_port_valid" );
58 like ( $res->output, $successOutput, "Output correct" );
59
60 $res = NPTest->testCmd("./check_hpjd -H $host_tcp_hpjd -p $host_hpjd_port_invalid");
61 cmp_ok( $res->return_code, 'eq', 2, "Jetdirect not responding on port $host_hpjd_port_invalid" );
62 like ( $res->output, $failureOutput, "Output correct" );
42} 63}
43 64
44$res = NPTest->testCmd("./check_hpjd $host_nonresponsive"); 65$res = NPTest->testCmd("./check_hpjd -H $host_nonresponsive");
45cmp_ok( $res->return_code, 'eq', 2, "Host not responding"); 66cmp_ok( $res->return_code, 'eq', 2, "Host not responding");
46like ( $res->output, $failureOutput, "Output OK" ); 67like ( $res->output, $failureOutput, "Output OK" );
47 68
48$res = NPTest->testCmd("./check_hpjd $hostname_invalid"); 69$res = NPTest->testCmd("./check_hpjd -H $hostname_invalid");
49cmp_ok( $res->return_code, 'eq', 3, "Hostname invalid"); 70cmp_ok( $res->return_code, 'eq', 3, "Hostname invalid");
50 71
diff --git a/plugins/t/check_jabber.t b/plugins/t/check_jabber.t
index 1aaf812..7a708d5 100644
--- a/plugins/t/check_jabber.t
+++ b/plugins/t/check_jabber.t
@@ -29,7 +29,7 @@ my $hostname_invalid = getTestParameter(
29 ); 29 );
30 30
31 31
32my $jabberOK = '/JABBER OK\s-\s\d+\.\d+\ssecond response time on port 5222/'; 32my $jabberOK = '/JABBER OK\s-\s\d+\.\d+\ssecond response time on '.$host_tcp_jabber.' port 5222/';
33 33
34my $jabberUnresponsive = '/CRITICAL\s-\sSocket timeout after\s\d+\sseconds/'; 34my $jabberUnresponsive = '/CRITICAL\s-\sSocket timeout after\s\d+\sseconds/';
35 35
@@ -40,7 +40,7 @@ my $r;
40SKIP: { 40SKIP: {
41 skip "No jabber server defined", 6 unless $host_tcp_jabber; 41 skip "No jabber server defined", 6 unless $host_tcp_jabber;
42 42
43 $r = NPTest->testCmd( "./check_jabber $host_tcp_jabber" ); 43 $r = NPTest->testCmd( "./check_jabber -H $host_tcp_jabber" );
44 is( $r->return_code, 0, "Connected okay"); 44 is( $r->return_code, 0, "Connected okay");
45 like( $r->output, $jabberOK, "Output as expected" ); 45 like( $r->output, $jabberOK, "Output as expected" );
46 46
@@ -48,7 +48,7 @@ SKIP: {
48 is( $r->return_code, 0, "Connected okay, within limits" ); 48 is( $r->return_code, 0, "Connected okay, within limits" );
49 like( $r->output, $jabberOK, "Output as expected" ); 49 like( $r->output, $jabberOK, "Output as expected" );
50 50
51 $r = NPTest->testCmd( "./check_jabber $host_tcp_jabber -wt 9 -ct 9 -to 10" ); 51 $r = NPTest->testCmd( "./check_jabber -H $host_tcp_jabber -wt 9 -ct 9 -to 10" );
52 is( $r->return_code, 0, "Old syntax okay" ); 52 is( $r->return_code, 0, "Old syntax okay" );
53 like( $r->output, $jabberOK, "Output as expected" ); 53 like( $r->output, $jabberOK, "Output as expected" );
54 54
diff --git a/plugins/t/check_ntp.t b/plugins/t/check_ntp.t
index 3eee6e1..b8fc8fd 100644
--- a/plugins/t/check_ntp.t
+++ b/plugins/t/check_ntp.t
@@ -23,27 +23,27 @@ my $no_ntp_service = getTestParameter( "NP_NO_NTP_SERVICE",
23 "A host NOT providing the NTP service", 23 "A host NOT providing the NTP service",
24 "localhost" ); 24 "localhost" );
25 25
26my $host_nonresponsive = getTestParameter( "NP_HOST_NONRESPONSIVE", 26my $host_nonresponsive = getTestParameter( "NP_HOST_NONRESPONSIVE",
27 "The hostname of system not responsive to network requests", 27 "The hostname of system not responsive to network requests",
28 "10.0.0.1" ); 28 "10.0.0.1" );
29 29
30my $hostname_invalid = getTestParameter( "NP_HOSTNAME_INVALID", 30my $hostname_invalid = getTestParameter( "NP_HOSTNAME_INVALID",
31 "An invalid (not known to DNS) hostname", 31 "An invalid (not known to DNS) hostname",
32 "nosuchhost"); 32 "nosuchhost");
33 33
34my $ntp_okmatch1 = '/^NTP\sOK:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs/'; 34my $ntp_okmatch1 = '/^NTP\sOK:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs/';
35my $ntp_warnmatch1 = '/^NTP\sWARNING:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs/'; 35my $ntp_warnmatch1 = '/^NTP\sWARNING:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs/';
36my $ntp_critmatch1 = '/^NTP\sCRITICAL:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs/'; 36my $ntp_critmatch1 = '/^NTP\sCRITICAL:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs/';
37my $ntp_okmatch2 = '/^NTP\sOK:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs,\sjitter=[0-9]+\.[0-9]+,\sstratum=[0-9]{1,2},\struechimers=[0-9]+/'; 37my $ntp_okmatch2 = '/^NTP\sOK:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs,\sjitter=[0-9]+\.[0-9]+,\sstratum=[0-9]{1,2},\struechimers=[0-9]+/';
38my $ntp_warnmatch2 = '/^NTP\sWARNING:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs,\sjitter=[0-9]+\.[0-9]+,\sstratum=[0-9]{1,2},\struechimers=[0-9]+/'; 38my $ntp_warnmatch2 = '/^NTP\sWARNING:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs,\sjitter=[0-9]+\.[0-9]+,\sstratum=[0-9]{1,2}\s\(WARNING\),\struechimers=[0-9]+/';
39my $ntp_critmatch2 = '/^NTP\sCRITICAL:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs,\sjitter=[0-9]+\.[0-9]+,\sstratum=[0-9]{1,2},\struechimers=[0-9]+/'; 39my $ntp_critmatch2 = '/^NTP\sCRITICAL:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs,\sjitter=[0-9]+\.[0-9]+\s\(CRITICAL\),\sstratum=[0-9]{1,2},\struechimers=[0-9]+/';
40my $ntp_noresponse = '/^(CRITICAL - Socket timeout after 3 seconds)|(NTP CRITICAL: No response from NTP server)$/'; 40my $ntp_noresponse = '/^(CRITICAL - Socket timeout after 3 seconds)|(NTP CRITICAL: No response from NTP server)$/';
41my $ntp_nosuchhost = '/^check_ntp.*: Invalid hostname/address - ' . $hostname_invalid . '/'; 41my $ntp_nosuchhost = '/^check_ntp.*: Invalid hostname/address - ' . $hostname_invalid . '/';
42 42
43 43
44foreach my $plugin (@PLUGINS1) { 44foreach my $plugin (@PLUGINS1) {
45 SKIP: { 45 SKIP: {
46 skip "No NTP server defined", 1 unless $ntp_service; 46 skip "No NTP server defined", 6 unless $ntp_service;
47 $res = NPTest->testCmd( 47 $res = NPTest->testCmd(
48 "./$plugin -H $ntp_service -w 1000 -c 2000" 48 "./$plugin -H $ntp_service -w 1000 -c 2000"
49 ); 49 );
@@ -88,7 +88,7 @@ foreach my $plugin (@PLUGINS1) {
88 88
89foreach my $plugin (@PLUGINS2) { 89foreach my $plugin (@PLUGINS2) {
90 SKIP: { 90 SKIP: {
91 skip "No NTP server defined", 1 unless $ntp_service; 91 skip "No NTP server defined", 6 unless $ntp_service;
92 $res = NPTest->testCmd( 92 $res = NPTest->testCmd(
93 "./$plugin -H $ntp_service -w 1000 -c 2000 -W 20 -C 21 -j 100000 -k 200000 -m 1: -n 0:" 93 "./$plugin -H $ntp_service -w 1000 -c 2000 -W 20 -C 21 -j 100000 -k 200000 -m 1: -n 0:"
94 ); 94 );
diff --git a/plugins/t/check_procs.t b/plugins/t/check_procs.t
index ca4acdd..abe7284 100644
--- a/plugins/t/check_procs.t
+++ b/plugins/t/check_procs.t
@@ -26,7 +26,7 @@ $result = NPTest->testCmd( "./check_procs -w 100000 -c 100000 -s Z" );
26is( $result->return_code, 0, "Checking less than 100000 zombie processes" ); 26is( $result->return_code, 0, "Checking less than 100000 zombie processes" );
27like( $result->output, '/^PROCS OK: [0-9]+ process(es)? with /', "Output correct" ); 27like( $result->output, '/^PROCS OK: [0-9]+ process(es)? with /', "Output correct" );
28 28
29if(fork() == 0) { exec("sleep 7"); } # fork a test process 29if(fork() == 0) { exec("sleep 7"); } else { sleep(1) } # fork a test process in child and give child time to fork in parent
30$result = NPTest->testCmd( "./check_procs -a 'sleep 7'" ); 30$result = NPTest->testCmd( "./check_procs -a 'sleep 7'" );
31is( $result->return_code, 0, "Parent process is ignored" ); 31is( $result->return_code, 0, "Parent process is ignored" );
32like( $result->output, '/^PROCS OK: 1 process?/', "Output correct" ); 32like( $result->output, '/^PROCS OK: 1 process?/', "Output correct" );
diff --git a/plugins/t/check_snmp.t b/plugins/t/check_snmp.t
index c35d782..2d6c44a 100644
--- a/plugins/t/check_snmp.t
+++ b/plugins/t/check_snmp.t
@@ -45,7 +45,7 @@ is( $res->return_code, 3, "Invalid protocol" );
45like( $res->output, "/check_snmp: Invalid SNMP version - 3c/" ); 45like( $res->output, "/check_snmp: Invalid SNMP version - 3c/" );
46 46
47SKIP: { 47SKIP: {
48 skip "no snmp host defined", 38 if ( ! $host_snmp ); 48 skip "no snmp host defined", 48 if ( ! $host_snmp );
49 49
50 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0 -w 1: -c 1:"); 50 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0 -w 1: -c 1:");
51 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying uptime" ); 51 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying uptime" );
diff --git a/plugins/t/check_udp.t b/plugins/t/check_udp.t
index 619cadf..1f6fee7 100644
--- a/plugins/t/check_udp.t
+++ b/plugins/t/check_udp.t
@@ -62,7 +62,7 @@ SKIP: {
62 cmp_ok( $res->return_code, '==', '2', "Hung waiting for response"); 62 cmp_ok( $res->return_code, '==', '2', "Hung waiting for response");
63 like ( $res->output, '/Socket timeout after 5 seconds/', "Timeout message"); 63 like ( $res->output, '/Socket timeout after 5 seconds/', "Timeout message");
64 like ( $duration, '/^[56]$/', "Timeout after 5 (possibly 6) seconds"); 64 like ( $duration, '/^[56]$/', "Timeout after 5 (possibly 6) seconds");
65 my $read_nc = <NC>; 65 my $read_nc = <NC> || '';
66 close NC; 66 close NC;
67 cmp_ok( $read_nc, 'eq', "foofoo", "Data received correctly" ); 67 cmp_ok( $read_nc, 'eq', "foofoo", "Data received correctly" );
68} 68}
diff --git a/plugins/tests/check_http.t b/plugins/tests/check_http.t
index 2c89beb..d93a0ec 100755
--- a/plugins/tests/check_http.t
+++ b/plugins/tests/check_http.t
@@ -20,8 +20,9 @@ use FindBin qw($Bin);
20my $common_tests = 70; 20my $common_tests = 70;
21my $ssl_only_tests = 8; 21my $ssl_only_tests = 8;
22# Check that all dependent modules are available 22# Check that all dependent modules are available
23eval "use HTTP::Daemon 6.01;";
24plan skip_all => 'HTTP::Daemon >= 6.01 required' if $@;
23eval { 25eval {
24 require HTTP::Daemon;
25 require HTTP::Status; 26 require HTTP::Status;
26 require HTTP::Response; 27 require HTTP::Response;
27}; 28};
@@ -185,21 +186,21 @@ SKIP: {
185 186
186 $result = NPTest->testCmd( "$command -p $port_https -S -C 14" ); 187 $result = NPTest->testCmd( "$command -p $port_https -S -C 14" );
187 is( $result->return_code, 0, "$command -p $port_https -S -C 14" ); 188 is( $result->return_code, 0, "$command -p $port_https -S -C 14" );
188 is( $result->output, 'OK - Certificate \'Ton Voon\' will expire on 03/03/2019 21:41.', "output ok" ); 189 is( $result->output, 'OK - Certificate \'Ton Voon\' will expire on Sun Mar 3 21:41:00 2019.', "output ok" );
189 190
190 $result = NPTest->testCmd( "$command -p $port_https -S -C 14000" ); 191 $result = NPTest->testCmd( "$command -p $port_https -S -C 14000" );
191 is( $result->return_code, 1, "$command -p $port_https -S -C 14000" ); 192 is( $result->return_code, 1, "$command -p $port_https -S -C 14000" );
192 like( $result->output, '/WARNING - Certificate \'Ton Voon\' expires in \d+ day\(s\) \(03/03/2019 21:41\)./', "output ok" ); 193 like( $result->output, '/WARNING - Certificate \'Ton Voon\' expires in \d+ day\(s\) \(Sun Mar 3 21:41:00 2019\)./', "output ok" );
193 194
194 # Expired cert tests 195 # Expired cert tests
195 $result = NPTest->testCmd( "$command -p $port_https -S -C 13960,14000" ); 196 $result = NPTest->testCmd( "$command -p $port_https -S -C 13960,14000" );
196 is( $result->return_code, 2, "$command -p $port_https -S -C 13960,14000" ); 197 is( $result->return_code, 2, "$command -p $port_https -S -C 13960,14000" );
197 like( $result->output, '/CRITICAL - Certificate \'Ton Voon\' expires in \d+ day\(s\) \(03/03/2019 21:41\)./', "output ok" ); 198 like( $result->output, '/CRITICAL - Certificate \'Ton Voon\' expires in \d+ day\(s\) \(Sun Mar 3 21:41:00 2019\)./', "output ok" );
198 199
199 $result = NPTest->testCmd( "$command -p $port_https_expired -S -C 7" ); 200 $result = NPTest->testCmd( "$command -p $port_https_expired -S -C 7" );
200 is( $result->return_code, 2, "$command -p $port_https_expired -S -C 7" ); 201 is( $result->return_code, 2, "$command -p $port_https_expired -S -C 7" );
201 is( $result->output, 202 is( $result->output,
202 'CRITICAL - Certificate \'Ton Voon\' expired on 03/05/2009 00:13.', 203 'CRITICAL - Certificate \'Ton Voon\' expired on Thu Mar 5 00:13:00 2009.',
203 "output ok" ); 204 "output ok" );
204 205
205} 206}
@@ -392,27 +393,21 @@ sub run_common_tests {
392 skip "This doesn't seems to work all the time", 1 unless ($ENV{HTTP_EXTERNAL}); 393 skip "This doesn't seems to work all the time", 1 unless ($ENV{HTTP_EXTERNAL});
393 $cmd = "$command -f follow -u /redir_external -t 5"; 394 $cmd = "$command -f follow -u /redir_external -t 5";
394 eval { 395 eval {
395 local $SIG{ALRM} = sub { die "alarm\n" }; 396 $result = NPTest->testCmd( $cmd, 2 );
396 alarm(2); 397 };
397 $result = NPTest->testCmd( $cmd ); 398 like( $@, "/timeout in command: $cmd/", $cmd );
398 alarm(0); };
399 is( $@, "alarm\n", $cmd );
400 } 399 }
401 400
402 $cmd = "$command -u /timeout -t 5"; 401 $cmd = "$command -u /timeout -t 5";
403 eval { 402 eval {
404 local $SIG{ALRM} = sub { die "alarm\n" }; 403 $result = NPTest->testCmd( $cmd, 2 );
405 alarm(2); 404 };
406 $result = NPTest->testCmd( $cmd ); 405 like( $@, "/timeout in command: $cmd/", $cmd );
407 alarm(0); };
408 is( $@, "alarm\n", $cmd );
409 406
410 $cmd = "$command -f follow -u /redir_timeout -t 2"; 407 $cmd = "$command -f follow -u /redir_timeout -t 2";
411 eval { 408 eval {
412 local $SIG{ALRM} = sub { die "alarm\n" }; 409 $result = NPTest->testCmd( $cmd, 5 );
413 alarm(5); 410 };
414 $result = NPTest->testCmd( $cmd ); 411 is( $@, "", $cmd );
415 alarm(0); };
416 isnt( $@, "alarm\n", $cmd );
417 412
418} 413}
diff --git a/plugins/tests/check_procs.t b/plugins/tests/check_procs.t
index 1ad2c2f..54d43d9 100755
--- a/plugins/tests/check_procs.t
+++ b/plugins/tests/check_procs.t
@@ -48,21 +48,26 @@ SKIP: {
48 like( $result->output, '/^PROCS OK: 1 process with command name \'launchd\', UID = 501 (.*)$/', "Output correct" ); 48 like( $result->output, '/^PROCS OK: 1 process with command name \'launchd\', UID = 501 (.*)$/', "Output correct" );
49} 49}
50 50
51$result = NPTest->testCmd( "$command -u -2 -w 2:2" ); 51SKIP: {
52is( $result->return_code, 1, "Checking processes with userid=-2" ); 52 skip 'user with uid -2 required', 8 unless getpwuid(-2);
53like( $result->output, '/^PROCS WARNING: 3 processes with UID = -2 \(nobody\)$/', "Output correct" ); 53 skip 'uid -2 must have name "nobody"', 8 unless getpwuid(-2) eq 'nobody';
54
55 $result = NPTest->testCmd( "$command -u -2 -w 2:2" );
56 is( $result->return_code, 1, "Checking processes with userid=-2" );
57 like( $result->output, '/^PROCS WARNING: 3 processes with UID = -2 \(nobody\)$/', "Output correct" );
54 58
55$result = NPTest->testCmd( "$command -u -2 -w 3:3" ); 59 $result = NPTest->testCmd( "$command -u -2 -w 3:3" );
56is( $result->return_code, 0, "Checking processes with userid=-2 past threshold" ); 60 is( $result->return_code, 0, "Checking processes with userid=-2 past threshold" );
57like( $result->output, '/^PROCS OK: 3 processes with UID = -2 \(nobody\)$/', "Output correct" ); 61 like( $result->output, '/^PROCS OK: 3 processes with UID = -2 \(nobody\)$/', "Output correct" );
58 62
59$result = NPTest->testCmd( "$command -u -2 -a usb" ); 63 $result = NPTest->testCmd( "$command -u -2 -a usb" );
60is( $result->return_code, 0, "Checking processes with userid=-2 and usb in arguments" ); 64 is( $result->return_code, 0, "Checking processes with userid=-2 and usb in arguments" );
61like( $result->output, '/^PROCS OK: 1 process with UID = -2 \(nobody\), args \'usb\'/', "Output correct" ); 65 like( $result->output, '/^PROCS OK: 1 process with UID = -2 \(nobody\), args \'usb\'/', "Output correct" );
62 66
63$result = NPTest->testCmd( "$command -u -2 -a UsB" ); 67 $result = NPTest->testCmd( "$command -u -2 -a UsB" );
64is( $result->return_code, 0, "Checking case sensitivity of args" ); 68 is( $result->return_code, 0, "Checking case sensitivity of args" );
65like( $result->output, '/^PROCS OK: 0 processes with UID = -2 \(nobody\), args \'UsB\'/', "Output correct" ); 69 like( $result->output, '/^PROCS OK: 0 processes with UID = -2 \(nobody\), args \'UsB\'/', "Output correct" );
70};
66 71
67$result = NPTest->testCmd( "$command --ereg-argument-array='mdworker.*501'" ); 72$result = NPTest->testCmd( "$command --ereg-argument-array='mdworker.*501'" );
68is( $result->return_code, 0, "Checking regexp search of arguments" ); 73is( $result->return_code, 0, "Checking regexp search of arguments" );
diff --git a/plugins/tests/check_snmp.t b/plugins/tests/check_snmp.t
index d865e19..aace9bc 100755
--- a/plugins/tests/check_snmp.t
+++ b/plugins/tests/check_snmp.t
@@ -79,7 +79,7 @@ Copyright (c) 1986-2004 by cisco Systems, Inc.
79$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.0 -o sysContact.0 -o .1.3.6.1.4.1.8072.3.2.67.1"); 79$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.0 -o sysContact.0 -o .1.3.6.1.4.1.8072.3.2.67.1");
80cmp_ok( $res->return_code, '==', 0, "Exit OK when querying multi-line OIDs" ); 80cmp_ok( $res->return_code, '==', 0, "Exit OK when querying multi-line OIDs" );
81like($res->output, '/^SNMP OK - /', "String contains SNMP OK"); 81like($res->output, '/^SNMP OK - /', "String contains SNMP OK");
82like($res->output, '/'.quotemeta('SNMP OK - Cisco Internetwork Operating System Software "Alice" Kisco Outernetwork Oserating Gystem Totware | 82like($res->output, '/'.quotemeta('SNMP OK - Cisco Internetwork Operating System Software ').'"?Alice"?'.quotemeta(' Kisco Outernetwork Oserating Gystem Totware |
83.1.3.6.1.4.1.8072.3.2.67.0: 83.1.3.6.1.4.1.8072.3.2.67.0:
84"Cisco Internetwork Operating System Software 84"Cisco Internetwork Operating System Software
85IOS (tm) Catalyst 4000 \"L3\" Switch Software (cat4000-I9K91S-M), Version 85IOS (tm) Catalyst 4000 \"L3\" Switch Software (cat4000-I9K91S-M), Version
diff --git a/po/de.po b/po/de.po
index b9dd8f2..51551ae 100644
--- a/po/de.po
+++ b/po/de.po
@@ -1998,7 +1998,7 @@ msgstr ""
1998 1998
1999#: plugins/check_mrtg.c:359 1999#: plugins/check_mrtg.c:359
2000msgid "" 2000msgid ""
2001"packets/sec, etc. I use MRTG in conjuction with the Novell NLM that allows" 2001"packets/sec, etc. I use MRTG in conjunction with the Novell NLM that allows"
2002msgstr "" 2002msgstr ""
2003 2003
2004#: plugins/check_mrtg.c:360 2004#: plugins/check_mrtg.c:360
@@ -5360,7 +5360,7 @@ msgstr ""
5360 5360
5361#: plugins/check_ide_smart.c:441 5361#: plugins/check_ide_smart.c:441
5362#, c-format 5362#, c-format
5363msgid "ERROR - Status '%d' unkown. %d/%d tests passed\n" 5363msgid "ERROR - Status '%d' unknown. %d/%d tests passed\n"
5364msgstr "" 5364msgstr ""
5365 5365
5366#: plugins/check_ide_smart.c:474 5366#: plugins/check_ide_smart.c:474
diff --git a/po/fr.po b/po/fr.po
index 0537949..d88dfe2 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -2050,7 +2050,7 @@ msgstr ""
2050 2050
2051#: plugins/check_mrtg.c:359 2051#: plugins/check_mrtg.c:359
2052msgid "" 2052msgid ""
2053"packets/sec, etc. I use MRTG in conjuction with the Novell NLM that allows" 2053"packets/sec, etc. I use MRTG in conjunction with the Novell NLM that allows"
2054msgstr "" 2054msgstr ""
2055 2055
2056#: plugins/check_mrtg.c:360 2056#: plugins/check_mrtg.c:360
@@ -5448,7 +5448,7 @@ msgstr "OK - En fonctionnement (%d/%d les tests on été réussi)\n"
5448 5448
5449#: plugins/check_ide_smart.c:441 5449#: plugins/check_ide_smart.c:441
5450#, c-format 5450#, c-format
5451msgid "ERROR - Status '%d' unkown. %d/%d tests passed\n" 5451msgid "ERROR - Status '%d' unknown. %d/%d tests passed\n"
5452msgstr "ERREUR - État '%d' inconnu. %d/%d les tests on réussi\n" 5452msgstr "ERREUR - État '%d' inconnu. %d/%d les tests on réussi\n"
5453 5453
5454#: plugins/check_ide_smart.c:474 5454#: plugins/check_ide_smart.c:474
diff --git a/po/monitoring-plugins.pot b/po/monitoring-plugins.pot
index 07c1b98..8f220e9 100644
--- a/po/monitoring-plugins.pot
+++ b/po/monitoring-plugins.pot
@@ -1944,7 +1944,7 @@ msgstr ""
1944 1944
1945#: plugins/check_mrtg.c:359 1945#: plugins/check_mrtg.c:359
1946msgid "" 1946msgid ""
1947"packets/sec, etc. I use MRTG in conjuction with the Novell NLM that allows" 1947"packets/sec, etc. I use MRTG in conjunction with the Novell NLM that allows"
1948msgstr "" 1948msgstr ""
1949 1949
1950#: plugins/check_mrtg.c:360 1950#: plugins/check_mrtg.c:360
@@ -5217,7 +5217,7 @@ msgstr ""
5217 5217
5218#: plugins/check_ide_smart.c:441 5218#: plugins/check_ide_smart.c:441
5219#, c-format 5219#, c-format
5220msgid "ERROR - Status '%d' unkown. %d/%d tests passed\n" 5220msgid "ERROR - Status '%d' unknown. %d/%d tests passed\n"
5221msgstr "" 5221msgstr ""
5222 5222
5223#: plugins/check_ide_smart.c:474 5223#: plugins/check_ide_smart.c:474
diff --git a/test.pl.in b/test.pl.in
index 01a97ec..2f2c44f 100755
--- a/test.pl.in
+++ b/test.pl.in
@@ -9,6 +9,8 @@ use Getopt::Long;
9 9
10use NPTest qw(DetermineTestHarnessDirectory TestsFrom); 10use NPTest qw(DetermineTestHarnessDirectory TestsFrom);
11 11
12$ENV{LC_ALL} = 'C';
13
12my @tstdir; 14my @tstdir;
13 15
14if ( ! GetOptions( "testdir:s" => \@tstdir ) ) 16if ( ! GetOptions( "testdir:s" => \@tstdir ) )