diff options
72 files changed, 1132 insertions, 487 deletions
diff --git a/.travis.yml b/.travis.yml index 7a4c3c62..cec78786 100644 --- a/.travis.yml +++ b/.travis.yml | |||
@@ -1,19 +1,30 @@ | |||
1 | language: c | 1 | language: c |
2 | 2 | ||
3 | before_install: | 3 | before_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 | ||
7 | install: | 8 | install: |
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 | ||
11 | before_script: | 14 | before_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 | ||
15 | script: | 26 | script: |
16 | - if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then make; fi | 27 | - if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then make test; fi |
17 | 28 | ||
18 | notifications: | 29 | notifications: |
19 | irc: | 30 | irc: |
@@ -1,28 +1,54 @@ | |||
1 | This file documents the major additions and syntax changes between releases. | 1 | This file documents the major additions and syntax changes between releases. |
2 | 2 | ||
3 | 1.6 ... | 3 | 2.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 | |
7 | 2.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 ae507e4a..26f94e78 100755 --- a/NP-VERSION-GEN +++ b/NP-VERSION-GEN | |||
@@ -6,7 +6,7 @@ | |||
6 | SRC_ROOT=`dirname $0` | 6 | SRC_ROOT=`dirname $0` |
7 | 7 | ||
8 | NPVF=NP-VERSION-FILE | 8 | NPVF=NP-VERSION-FILE |
9 | DEF_VER=1.5.git | 9 | DEF_VER=2.0.git |
10 | 10 | ||
11 | LF=' | 11 | LF=' |
12 | ' | 12 | ' |
@@ -6,7 +6,7 @@ package NPTest; | |||
6 | 6 | ||
7 | require Exporter; | 7 | require 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 | ||
12 | use strict; | 12 | use strict; |
@@ -38,8 +38,8 @@ testing. | |||
38 | 38 | ||
39 | =head1 FUNCTIONS | 39 | =head1 FUNCTIONS |
40 | 40 | ||
41 | This module defines three public functions, C<getTestParameter(...)>, | 41 | This module defines four public functions, C<getTestParameter(...)>, |
42 | C<checkCmd(...)> and C<skipMissingCmd(...)>. These are exported by | 42 | C<checkCmd(...)>, C<skipMissingCmd(...)> and C<skipMsg(...)>. These are exported by |
43 | default via the C<use NPTest;> statement. | 43 | default 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 | |||
190 | If for any reason the test harness must C<Test::skip()> some | ||
191 | or all of the tests in a given test harness this function provides a | ||
192 | simple iterator to issue an appropriate message the requested number | ||
193 | of times. | ||
194 | |||
195 | =back | ||
196 | |||
188 | =head1 SEE ALSO | 197 | =head1 SEE ALSO |
189 | 198 | ||
190 | L<Test> | 199 | L<Test> |
@@ -304,6 +313,20 @@ sub skipMissingCmd | |||
304 | return $testStatus; | 313 | return $testStatus; |
305 | } | 314 | } |
306 | 315 | ||
316 | sub 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 | |||
307 | sub getTestParameter | 330 | sub 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 | ||
629 | sub testCmd { | 652 | sub 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 b2bd467b..303fd62b 100644 --- a/REQUIREMENTS +++ b/REQUIREMENTS | |||
@@ -50,14 +50,16 @@ check_dbi: | |||
50 | http://libdbi.sourceforge.net/ | 50 | http://libdbi.sourceforge.net/ |
51 | 51 | ||
52 | check_radius: | 52 | check_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 | ||
62 | check_snmp: | 64 | check_snmp: |
63 | - Requires the NET-SNMP package available from | 65 | - Requires the NET-SNMP package available from |
@@ -308,3 +308,21 @@ Luca Corti | |||
308 | Jethro Carr | 308 | Jethro Carr |
309 | Evgeni Golov | 309 | Evgeni Golov |
310 | Oskar Liljeblad | 310 | Oskar Liljeblad |
311 | Andrew Widdersheim | ||
312 | Anton Lofgren | ||
313 | Damian Myerscough | ||
314 | Davide Madrisan | ||
315 | Gunnar Beutner | ||
316 | Joseph Gooch | ||
317 | Lars Vogdt | ||
318 | Ricardo Maraschini | ||
319 | Spenser Reinhardt | ||
320 | Stephane Lapie | ||
321 | Tilmann Bubeck | ||
322 | Eric J. Mislivec | ||
323 | Jean-Claude Computing | ||
324 | Andy Brist | ||
325 | Mikael Falkvidd | ||
326 | Patric Wust | ||
327 | Julius Kriukas | ||
328 | Patrick McAndrew | ||
diff --git a/configure.ac b/configure.ac index 244df427..f6ead580 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -1,6 +1,6 @@ | |||
1 | dnl Process this file with autoconf to produce a configure script. | 1 | dnl Process this file with autoconf to produce a configure script. |
2 | AC_PREREQ(2.59) | 2 | AC_PREREQ(2.59) |
3 | AC_INIT(monitoring-plugins,1.5) | 3 | AC_INIT(monitoring-plugins,2.0) |
4 | AC_CONFIG_SRCDIR(NPTest.pm) | 4 | AC_CONFIG_SRCDIR(NPTest.pm) |
5 | AC_CONFIG_FILES([gl/Makefile | 5 | AC_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 | |||
274 | dnl Check for radius libraries | 274 | dnl Check for radius libraries |
275 | AS_IF([test "x$with_radius" != "xno"], [ | 275 | AS_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) | |||
509 | if test ! "$FOUNDOPENSSL" = "yes" && test ! "$with_gnutls" = "no"; then | 516 | if 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 4339b2c6..54abb4c7 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 | ||
26 | AUTOMAKE_OPTIONS = 1.9.6 gnits subdir-objects | 26 | AUTOMAKE_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 | |||
407 | libgnu_a_SOURCES += idpriv-droptemp.c | ||
408 | |||
409 | EXTRA_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 00000000..13d1064e --- /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 | ||
28 | static int saved_uid = -1; | ||
29 | #endif | ||
30 | #if HAVE_GETGID | ||
31 | static int saved_gid = -1; | ||
32 | #endif | ||
33 | |||
34 | int | ||
35 | idpriv_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 | |||
121 | int | ||
122 | idpriv_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 00000000..f454a2cc --- /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 | ||
21 | extern "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. */ | ||
93 | extern 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. */ | ||
102 | extern 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. */ | ||
108 | extern 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 e61a5362..d6fca2a3 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: |
33 | gl_LOCAL_DIR([]) | 33 | gl_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 b3cb4c12..67a81566 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. |
34 | AC_DEFUN([gl_EARLY], | 34 | AC_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". |
158 | AC_DEFUN([gl_INIT], | 159 | AC_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 00000000..167f5238 --- /dev/null +++ b/gl/m4/idpriv.m4 | |||
@@ -0,0 +1,14 @@ | |||
1 | # idpriv.m4 serial 1 | ||
2 | dnl Copyright (C) 2009-2013 Free Software Foundation, Inc. | ||
3 | dnl This file is free software; the Free Software Foundation | ||
4 | dnl gives unlimited permission to copy and/or distribute it, | ||
5 | dnl with or without modifications, as long as this notice is preserved. | ||
6 | |||
7 | AC_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 76953e9e..25abc89b 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 | ||
42 | static char *default_ini_file_names[] = { | ||
43 | "monitoring-plugins.ini", | ||
44 | "plugins.ini", | ||
45 | "nagios-plugins.ini", | ||
46 | NULL | ||
47 | }; | ||
48 | |||
49 | static 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 */ |
47 | static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts); | 69 | static 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 */ |
49 | static int add_option(FILE *f, np_arg_list **optlst); | 72 | static int add_option(FILE *f, np_arg_list **optlst); |
50 | /* internal function to find default file */ | ||
51 | static char* default_file(void); | ||
52 | /* internal function to test files access */ | ||
53 | static 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 */ |
75 | static char *default_file(void); | ||
76 | static 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 | */ |
59 | static void parse_locator(const char *locator, const char *def_stanza, np_ini_info *i){ | 83 | static void |
60 | size_t locator_len=0, stanza_len=0; | 84 | parse_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 | /* |
91 | np_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; | 116 | np_arg_list * |
117 | np_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 | */ |
121 | static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts){ | 157 | static int |
122 | int c, status=FALSE; | 158 | read_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 | */ |
194 | static int add_option(FILE *f, np_arg_list **optlst){ | 238 | static int |
195 | np_arg_list *opttmp=*optlst, *optnew; | 239 | add_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 | ||
298 | static char* default_file(void){ | 357 | static char * |
299 | struct stat sb; | 358 | default_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 | 371 | static char * |
350 | * existence. Returns 1 if found, 0 if not and -1 if test wasn't performed. | 372 | default_file_in_path(void) |
351 | */ | 373 | { |
352 | static 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 a3a494ef..e37601b5 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 | */ |
59 | np_arg_list* np_get_defaults(const char *locator, const char *default_section); | 19 | np_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 356887d5..f35b7e27 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 @@ | |||
29 | int | 30 | int |
30 | main (int argc, char **argv) | 31 | main (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 04c4b4f9..addf26bd 100644 --- a/lib/utils_base.c +++ b/lib/utils_base.c | |||
@@ -300,19 +300,6 @@ char *np_escaped_string (const char *string) { | |||
300 | 300 | ||
301 | int np_check_if_root(void) { return (geteuid() == 0); } | 301 | int np_check_if_root(void) { return (geteuid() == 0); } |
302 | 302 | ||
303 | int 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 d69b0da1..42ae0c09 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 */ |
77 | int np_check_if_root(void); | 77 | int 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 */ | ||
80 | int 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 4c6d0be1..9e214bd4 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 1ec5c396..b874c555 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 4b4197d8..8b563e40 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 78a950c2..794a34f8 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 \ | |||
26 | EDIT = sed \ | 26 | EDIT = 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 | ||
31 | TESTS_ENVIRONMENT=perl -I $(top_builddir) -I $(top_srcdir) | 32 | TESTS_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 12a60ee6..1a3aceba 100755 --- a/plugins-scripts/check_breeze.pl +++ b/plugins-scripts/check_breeze.pl | |||
@@ -6,6 +6,7 @@ use Getopt::Long; | |||
6 | use vars qw($opt_V $opt_h $opt_w $opt_c $opt_H $opt_C $PROGNAME); | 6 | use vars qw($opt_V $opt_h $opt_w $opt_c $opt_H $opt_C $PROGNAME); |
7 | use FindBin; | 7 | use FindBin; |
8 | use lib "$FindBin::Bin"; | 8 | use lib "$FindBin::Bin"; |
9 | use lib '@libexecdir@'; | ||
9 | use utils qw(%ERRORS &print_revision &support &usage); | 10 | use 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 99948a41..4805434f 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_ | |||
26 | use vars qw($PROGNAME); | 26 | use vars qw($PROGNAME); |
27 | use FindBin; | 27 | use FindBin; |
28 | use lib "$FindBin::Bin"; | 28 | use lib "$FindBin::Bin"; |
29 | use lib '@libexecdir@'; | ||
29 | use utils qw($TIMEOUT %ERRORS &print_revision &support &usage); | 30 | use utils qw($TIMEOUT %ERRORS &print_revision &support &usage); |
30 | 31 | ||
31 | sub print_help (); | 32 | sub print_help (); |
diff --git a/plugins-scripts/check_file_age.pl b/plugins-scripts/check_file_age.pl index 5e062deb..453e0f55 100755 --- a/plugins-scripts/check_file_age.pl +++ b/plugins-scripts/check_file_age.pl | |||
@@ -25,7 +25,9 @@ use English; | |||
25 | use Getopt::Long; | 25 | use Getopt::Long; |
26 | use File::stat; | 26 | use File::stat; |
27 | use vars qw($PROGNAME); | 27 | use vars qw($PROGNAME); |
28 | use lib "."; | 28 | use FindBin; |
29 | use lib "$FindBin::Bin"; | ||
30 | use lib '@libexecdir@'; | ||
29 | use utils qw (%ERRORS &print_revision &support); | 31 | use utils qw (%ERRORS &print_revision &support); |
30 | 32 | ||
31 | sub print_help (); | 33 | sub print_help (); |
diff --git a/plugins-scripts/check_flexlm.pl b/plugins-scripts/check_flexlm.pl index 49d674d4..5f3ed598 100755 --- a/plugins-scripts/check_flexlm.pl +++ b/plugins-scripts/check_flexlm.pl | |||
@@ -37,6 +37,7 @@ use Getopt::Long; | |||
37 | use vars qw($opt_V $opt_h $opt_F $opt_t $verbose $PROGNAME); | 37 | use vars qw($opt_V $opt_h $opt_F $opt_t $verbose $PROGNAME); |
38 | use FindBin; | 38 | use FindBin; |
39 | use lib "$FindBin::Bin"; | 39 | use lib "$FindBin::Bin"; |
40 | use lib '@libexecdir@'; | ||
40 | use utils qw(%ERRORS &print_revision &support &usage); | 41 | use 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 1a7fbba4..cf2c7b58 100755 --- a/plugins-scripts/check_ifoperstatus.pl +++ b/plugins-scripts/check_ifoperstatus.pl | |||
@@ -37,6 +37,7 @@ use POSIX; | |||
37 | use strict; | 37 | use strict; |
38 | use FindBin; | 38 | use FindBin; |
39 | use lib "$FindBin::Bin"; | 39 | use lib "$FindBin::Bin"; |
40 | use lib '@libexecdir@'; | ||
40 | use utils qw($TIMEOUT %ERRORS &print_revision &support); | 41 | use utils qw($TIMEOUT %ERRORS &print_revision &support); |
41 | 42 | ||
42 | use Net::SNMP; | 43 | use Net::SNMP; |
diff --git a/plugins-scripts/check_ifstatus.pl b/plugins-scripts/check_ifstatus.pl index e9e62149..709ad174 100755 --- a/plugins-scripts/check_ifstatus.pl +++ b/plugins-scripts/check_ifstatus.pl | |||
@@ -34,6 +34,7 @@ use POSIX; | |||
34 | use strict; | 34 | use strict; |
35 | use FindBin; | 35 | use FindBin; |
36 | use lib "$FindBin::Bin"; | 36 | use lib "$FindBin::Bin"; |
37 | use lib '@libexecdir@'; | ||
37 | use utils qw($TIMEOUT %ERRORS &print_revision &support); | 38 | use utils qw($TIMEOUT %ERRORS &print_revision &support); |
38 | 39 | ||
39 | use Net::SNMP; | 40 | use Net::SNMP; |
@@ -220,7 +221,7 @@ foreach $key (keys %ifStatus) { | |||
220 | $ifexclude, | 221 | $ifexclude, |
221 | $ifunused); | 222 | $ifunused); |
222 | } | 223 | } |
223 | my $perfdata = sprintf("up=%d,down=%d,dormant=%d,excluded=%d,unused=%d",$ifup,$ifdown,$ifdormant,$ifexclude,$ifunused); | 224 | my $perfdata = sprintf("up=%d down=%d dormant=%d excluded=%d unused=%d",$ifup,$ifdown,$ifdormant,$ifexclude,$ifunused); |
224 | print ("$state: $answer |$perfdata\n"); | 225 | print ("$state: $answer |$perfdata\n"); |
225 | exit $ERRORS{$state}; | 226 | exit $ERRORS{$state}; |
226 | 227 | ||
diff --git a/plugins-scripts/check_ircd.pl b/plugins-scripts/check_ircd.pl index afedfb95..6d40cf5a 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); | |||
51 | use vars qw($PROGNAME); | 51 | use vars qw($PROGNAME); |
52 | use FindBin; | 52 | use FindBin; |
53 | use lib "$FindBin::Bin"; | 53 | use lib "$FindBin::Bin"; |
54 | use lib '@libexecdir@'; | ||
54 | use utils qw($TIMEOUT %ERRORS &print_revision &support &usage); | 55 | use 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 df1385d2..bd78981e 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); |
34 | use FindBin; | 34 | use FindBin; |
35 | use lib "$FindBin::Bin"; | 35 | use lib "$FindBin::Bin"; |
36 | use lib '@libexecdir@'; | ||
36 | use utils qw(%ERRORS &print_revision &support &usage ); | 37 | use 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 a3f497cd..1f387884 100755 --- a/plugins-scripts/check_mssql.pl +++ b/plugins-scripts/check_mssql.pl | |||
@@ -29,7 +29,9 @@ | |||
29 | use DBI; | 29 | use DBI; |
30 | use DBD::Sybase; | 30 | use DBD::Sybase; |
31 | use Getopt::Long; | 31 | use Getopt::Long; |
32 | use lib "."; | 32 | use FindBin; |
33 | use lib "$FindBin::Bin"; | ||
34 | use lib '@libexecdir@'; | ||
33 | use utils qw($TIMEOUT %ERRORS &print_revision &support); | 35 | use utils qw($TIMEOUT %ERRORS &print_revision &support); |
34 | use strict; | 36 | use strict; |
35 | 37 | ||
diff --git a/plugins-scripts/check_netdns.pl b/plugins-scripts/check_netdns.pl index 82939bff..59c81a90 100755 --- a/plugins-scripts/check_netdns.pl +++ b/plugins-scripts/check_netdns.pl | |||
@@ -29,6 +29,7 @@ use Getopt::Long; | |||
29 | use Net::DNS; | 29 | use Net::DNS; |
30 | use FindBin; | 30 | use FindBin; |
31 | use lib "$FindBin::Bin"; | 31 | use lib "$FindBin::Bin"; |
32 | use lib '@libexecdir@'; | ||
32 | use utils ; | 33 | use utils ; |
33 | 34 | ||
34 | my $PROGNAME = "check_netdns"; | 35 | my $PROGNAME = "check_netdns"; |
diff --git a/plugins-scripts/check_rpc.pl b/plugins-scripts/check_rpc.pl index cbdeceb4..b1c61471 100755 --- a/plugins-scripts/check_rpc.pl +++ b/plugins-scripts/check_rpc.pl | |||
@@ -22,6 +22,7 @@ | |||
22 | use strict; | 22 | use strict; |
23 | use FindBin; | 23 | use FindBin; |
24 | use lib "$FindBin::Bin"; | 24 | use lib "$FindBin::Bin"; |
25 | use lib '@libexecdir@'; | ||
25 | use utils qw($TIMEOUT %ERRORS &print_revision &support); | 26 | use utils qw($TIMEOUT %ERRORS &print_revision &support); |
26 | use vars qw($PROGNAME); | 27 | use vars qw($PROGNAME); |
27 | my ($verbose,@proto,%prognum,$host,$response,$prognum,$port,$cmd,$progver,$state); | 28 | my ($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 979416e0..ee0fda4d 100755 --- a/plugins-scripts/check_wave.pl +++ b/plugins-scripts/check_wave.pl | |||
@@ -5,6 +5,7 @@ | |||
5 | use strict; | 5 | use strict; |
6 | use FindBin; | 6 | use FindBin; |
7 | use lib "$FindBin::Bin"; | 7 | use lib "$FindBin::Bin"; |
8 | use lib '@libexecdir@'; | ||
8 | use utils qw($TIMEOUT %ERRORS &print_revision &support); | 9 | use utils qw($TIMEOUT %ERRORS &print_revision &support); |
9 | use vars qw($PROGNAME); | 10 | use vars qw($PROGNAME); |
10 | use Getopt::Long; | 11 | use Getopt::Long; |
diff --git a/plugins/check_apt.c b/plugins/check_apt.c index 4c76a512..07622c2f 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 c6244fd2..a3d033f4 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 eebe72cc..31a953d7 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 1e7605ba..5fe06984 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 | ||
44 | const char *option_summary = "-H host [-C community]\n"; | 44 | const char *option_summary = "-H host [-C community]\n"; |
45 | 45 | ||
@@ -66,6 +66,7 @@ void print_usage (void); | |||
66 | 66 | ||
67 | char *community = NULL; | 67 | char *community = NULL; |
68 | char *address = NULL; | 68 | char *address = NULL; |
69 | char *port = NULL; | ||
69 | 70 | ||
70 | int | 71 | int |
71 | main (int argc, char **argv) | 72 | main (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 | |||
412 | print_usage (void) | 430 | print_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 92861d97..51679975 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 55faacce..47605e96 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 ed75f4ce..cf3fe044 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 4f09e5f8..216626bc 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 | ||
47 | char *db_user = NULL; | 48 | char *db_user = NULL; |
@@ -59,6 +60,7 @@ char *opt_file = NULL; | |||
59 | char *opt_group = NULL; | 60 | char *opt_group = NULL; |
60 | unsigned int db_port = MYSQL_PORT; | 61 | unsigned int db_port = MYSQL_PORT; |
61 | int check_slave = 0, warn_sec = 0, crit_sec = 0; | 62 | int check_slave = 0, warn_sec = 0, crit_sec = 0; |
63 | int ignore_auth = 0; | ||
62 | int verbose = 0; | 64 | int verbose = 0; |
63 | 65 | ||
64 | static double warning_time = 0; | 66 | static 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 cacf6651..fefbfb7a 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 0a7640a7..09a923eb 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){ | |||
517 | double jitter_request(const char *host, int *status){ | 517 | double 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 8dc19788..d3ae5999 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 | ||
562 | int main(int argc, char *argv[]){ | 562 | int 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 | |||
656 | void print_help(void){ | 681 | void 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 72dffbd8..e344f8b7 100644 --- a/plugins/check_ntp_time.c +++ b/plugins/check_ntp_time.c | |||
@@ -48,6 +48,7 @@ static int verbose=0; | |||
48 | static int quiet=0; | 48 | static int quiet=0; |
49 | static char *owarn="60"; | 49 | static char *owarn="60"; |
50 | static char *ocrit="120"; | 50 | static char *ocrit="120"; |
51 | static int time_offset=0; | ||
51 | 52 | ||
52 | int process_arguments (int, char **); | 53 | int process_arguments (int, char **); |
53 | thresholds *offset_thresholds = NULL; | 54 | thresholds *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 | |||
642 | print_usage(void) | 651 | print_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 3481f0cc..b2943475 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> |
41 | rc_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 **); | |||
47 | void print_help (void); | 48 | void print_help (void); |
48 | void print_usage (void); | 49 | void 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 | ||
73 | int my_rc_read_config(char *); | 77 | int my_rc_read_config(char *); |
74 | 78 | ||
79 | #if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) | ||
80 | rc_handle *rch = NULL; | ||
81 | #endif | ||
82 | |||
75 | char *server = NULL; | 83 | char *server = NULL; |
76 | char *username = NULL; | 84 | char *username = NULL; |
77 | char *password = NULL; | 85 | char *password = NULL; |
@@ -142,11 +150,10 @@ Please note that all tags must be lowercase to use the DocBook XML DTD. | |||
142 | int | 150 | int |
143 | main (int argc, char **argv) | 151 | main (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 | ||
393 | int my_rc_read_config(char * a) | 400 | int 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 47776c5b..36f64134 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 f4522e2b..b6187d61 100644 --- a/plugins/check_ssh.c +++ b/plugins/check_ssh.c | |||
@@ -46,6 +46,7 @@ const char *email = "devel@monitoring-plugins.org"; | |||
46 | int port = -1; | 46 | int port = -1; |
47 | char *server_name = NULL; | 47 | char *server_name = NULL; |
48 | char *remote_version = NULL; | 48 | char *remote_version = NULL; |
49 | char *remote_protocol = NULL; | ||
49 | int verbose = FALSE; | 50 | int verbose = FALSE; |
50 | 51 | ||
51 | int process_arguments (int, char **); | 52 | int process_arguments (int, char **); |
@@ -53,7 +54,7 @@ int validate_arguments (void); | |||
53 | void print_help (void); | 54 | void print_help (void); |
54 | void print_usage (void); | 55 | void print_usage (void); |
55 | 56 | ||
56 | int ssh_connect (char *haddr, int hport, char *remote_version); | 57 | int 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 | ||
208 | int | 213 | int |
209 | ssh_connect (char *haddr, int hport, char *remote_version) | 214 | ssh_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 0a6e2b27..f75c523c 100644 --- a/plugins/check_tcp.c +++ b/plugins/check_tcp.c | |||
@@ -32,13 +32,12 @@ char *progname; | |||
32 | const char *copyright = "1999-2008"; | 32 | const char *copyright = "1999-2008"; |
33 | const char *email = "devel@monitoring-plugins.org"; | 33 | const 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 7cced495..099881d0 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 | ||
71 | enum { NOSUCHVAR = ERROR-1 }; | 71 | enum { 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 4bd09deb..beaed1ea 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 | ||
46 | static const char **process_arguments (int, char **); | 46 | static const char **process_arguments (int, char **); |
47 | int validate_arguments (char **); | 47 | void validate_arguments (char **); |
48 | void print_help (void); | 48 | void print_help (void); |
49 | void print_usage (void); | 49 | void print_usage (void); |
50 | int subst_text = FALSE; | 50 | int 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 | ||
209 | int | 208 | void |
210 | validate_arguments (char **command_line) | 209 | validate_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 7ae97223..705aaf09 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 c5aa18fc..c6fce901 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 4352e603..1a7c904f 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 2732125d..d0ae4741 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 00000000..4ebfb90e --- /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 2c903db9..b8858807 100644 --- a/plugins/t/check_dns.t +++ b/plugins/t/check_dns.t | |||
@@ -10,7 +10,7 @@ use NPTest; | |||
10 | 10 | ||
11 | plan skip_all => "check_dns not compiled" unless (-x "check_dns"); | 11 | plan skip_all => "check_dns not compiled" unless (-x "check_dns"); |
12 | 12 | ||
13 | plan tests => 13; | 13 | plan tests => 14; |
14 | 14 | ||
15 | my $successOutput = '/DNS OK: [\.0-9]+ seconds? response time/'; | 15 | my $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"); |
56 | cmp_ok( $res->return_code, '==', 1, "Warning threshold passed"); | 56 | cmp_ok( $res->return_code, '==', 1, "Warning threshold passed"); |
57 | like( $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"); |
59 | cmp_ok( $res->return_code, '==', 2, "Invalid $hostname_invalid"); | 60 | cmp_ok( $res->return_code, '==', 2, "Invalid $hostname_invalid"); |
diff --git a/plugins/t/check_fping.t b/plugins/t/check_fping.t index 45a9be8a..08692e46 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 | ||
28 | my $t; | 28 | my $t; |
29 | 29 | ||
30 | if ( -x "./check_fping" ) | 30 | my $fping = qx(which fping 2> /dev/null); |
31 | { | 31 | chomp($fping); |
32 | if( ! -x "./check_fping") { | ||
33 | $t += skipMissingCmd( "./check_fping", $tests ); | ||
34 | } | ||
35 | elsif ( $> != 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 | } |
36 | else | ||
37 | { | ||
38 | $t += skipMissingCmd( "./check_fping", $tests ); | ||
39 | } | ||
40 | 42 | ||
41 | exit(0) if defined($Test::Harness::VERSION); | 43 | exit(0) if defined($Test::Harness::VERSION); |
42 | exit($tests - $t); | 44 | exit($tests - $t); |
diff --git a/plugins/t/check_hpjd.t b/plugins/t/check_hpjd.t index 10ded54a..4d64852a 100644 --- a/plugins/t/check_hpjd.t +++ b/plugins/t/check_hpjd.t | |||
@@ -10,7 +10,6 @@ use NPTest; | |||
10 | 10 | ||
11 | plan skip_all => "check_hpjd not compiled" unless (-x "check_hpjd"); | 11 | plan skip_all => "check_hpjd not compiled" unless (-x "check_hpjd"); |
12 | 12 | ||
13 | plan tests => 5; | ||
14 | 13 | ||
15 | my $successOutput = '/^Printer ok - /'; | 14 | my $successOutput = '/^Printer ok - /'; |
16 | my $failureOutput = '/Timeout: No [Rr]esponse from /'; | 15 | my $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 | ||
22 | my $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 | |||
28 | my $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 | |||
23 | my $host_nonresponsive = getTestParameter( | 34 | my $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 | ||
29 | my $hostname_invalid = getTestParameter( | 40 | my $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 | ||
46 | my $tests = $host_tcp_hpjd ? 9 : 5; | ||
47 | plan tests => $tests; | ||
35 | my $res; | 48 | my $res; |
36 | 49 | ||
37 | SKIP: { | 50 | SKIP: { |
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"); |
45 | cmp_ok( $res->return_code, 'eq', 2, "Host not responding"); | 66 | cmp_ok( $res->return_code, 'eq', 2, "Host not responding"); |
46 | like ( $res->output, $failureOutput, "Output OK" ); | 67 | like ( $res->output, $failureOutput, "Output OK" ); |
47 | 68 | ||
48 | $res = NPTest->testCmd("./check_hpjd $hostname_invalid"); | 69 | $res = NPTest->testCmd("./check_hpjd -H $hostname_invalid"); |
49 | cmp_ok( $res->return_code, 'eq', 3, "Hostname invalid"); | 70 | cmp_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 1aaf8125..7a708d5b 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 | ||
32 | my $jabberOK = '/JABBER OK\s-\s\d+\.\d+\ssecond response time on port 5222/'; | 32 | my $jabberOK = '/JABBER OK\s-\s\d+\.\d+\ssecond response time on '.$host_tcp_jabber.' port 5222/'; |
33 | 33 | ||
34 | my $jabberUnresponsive = '/CRITICAL\s-\sSocket timeout after\s\d+\sseconds/'; | 34 | my $jabberUnresponsive = '/CRITICAL\s-\sSocket timeout after\s\d+\sseconds/'; |
35 | 35 | ||
@@ -40,7 +40,7 @@ my $r; | |||
40 | SKIP: { | 40 | SKIP: { |
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 3eee6e17..b8fc8fdf 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 | ||
26 | my $host_nonresponsive = getTestParameter( "NP_HOST_NONRESPONSIVE", | 26 | my $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 | ||
30 | my $hostname_invalid = getTestParameter( "NP_HOSTNAME_INVALID", | 30 | my $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 | ||
34 | my $ntp_okmatch1 = '/^NTP\sOK:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs/'; | 34 | my $ntp_okmatch1 = '/^NTP\sOK:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs/'; |
35 | my $ntp_warnmatch1 = '/^NTP\sWARNING:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs/'; | 35 | my $ntp_warnmatch1 = '/^NTP\sWARNING:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs/'; |
36 | my $ntp_critmatch1 = '/^NTP\sCRITICAL:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs/'; | 36 | my $ntp_critmatch1 = '/^NTP\sCRITICAL:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs/'; |
37 | my $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]+/'; | 37 | my $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]+/'; |
38 | my $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]+/'; | 38 | my $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]+/'; |
39 | my $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]+/'; | 39 | my $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]+/'; |
40 | my $ntp_noresponse = '/^(CRITICAL - Socket timeout after 3 seconds)|(NTP CRITICAL: No response from NTP server)$/'; | 40 | my $ntp_noresponse = '/^(CRITICAL - Socket timeout after 3 seconds)|(NTP CRITICAL: No response from NTP server)$/'; |
41 | my $ntp_nosuchhost = '/^check_ntp.*: Invalid hostname/address - ' . $hostname_invalid . '/'; | 41 | my $ntp_nosuchhost = '/^check_ntp.*: Invalid hostname/address - ' . $hostname_invalid . '/'; |
42 | 42 | ||
43 | 43 | ||
44 | foreach my $plugin (@PLUGINS1) { | 44 | foreach 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 | ||
89 | foreach my $plugin (@PLUGINS2) { | 89 | foreach 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 ca4acdd7..abe7284e 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" ); | |||
26 | is( $result->return_code, 0, "Checking less than 100000 zombie processes" ); | 26 | is( $result->return_code, 0, "Checking less than 100000 zombie processes" ); |
27 | like( $result->output, '/^PROCS OK: [0-9]+ process(es)? with /', "Output correct" ); | 27 | like( $result->output, '/^PROCS OK: [0-9]+ process(es)? with /', "Output correct" ); |
28 | 28 | ||
29 | if(fork() == 0) { exec("sleep 7"); } # fork a test process | 29 | if(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'" ); |
31 | is( $result->return_code, 0, "Parent process is ignored" ); | 31 | is( $result->return_code, 0, "Parent process is ignored" ); |
32 | like( $result->output, '/^PROCS OK: 1 process?/', "Output correct" ); | 32 | like( $result->output, '/^PROCS OK: 1 process?/', "Output correct" ); |
diff --git a/plugins/t/check_snmp.t b/plugins/t/check_snmp.t index c35d7821..2d6c44a7 100644 --- a/plugins/t/check_snmp.t +++ b/plugins/t/check_snmp.t | |||
@@ -45,7 +45,7 @@ is( $res->return_code, 3, "Invalid protocol" ); | |||
45 | like( $res->output, "/check_snmp: Invalid SNMP version - 3c/" ); | 45 | like( $res->output, "/check_snmp: Invalid SNMP version - 3c/" ); |
46 | 46 | ||
47 | SKIP: { | 47 | SKIP: { |
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 619cadfb..1f6fee70 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 2c89beb0..d93a0ecf 100755 --- a/plugins/tests/check_http.t +++ b/plugins/tests/check_http.t | |||
@@ -20,8 +20,9 @@ use FindBin qw($Bin); | |||
20 | my $common_tests = 70; | 20 | my $common_tests = 70; |
21 | my $ssl_only_tests = 8; | 21 | my $ssl_only_tests = 8; |
22 | # Check that all dependent modules are available | 22 | # Check that all dependent modules are available |
23 | eval "use HTTP::Daemon 6.01;"; | ||
24 | plan skip_all => 'HTTP::Daemon >= 6.01 required' if $@; | ||
23 | eval { | 25 | eval { |
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 1ad2c2f1..54d43d9b 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" ); | 51 | SKIP: { |
52 | is( $result->return_code, 1, "Checking processes with userid=-2" ); | 52 | skip 'user with uid -2 required', 8 unless getpwuid(-2); |
53 | like( $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" ); |
56 | is( $result->return_code, 0, "Checking processes with userid=-2 past threshold" ); | 60 | is( $result->return_code, 0, "Checking processes with userid=-2 past threshold" ); |
57 | like( $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" ); |
60 | is( $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" ); |
61 | like( $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" ); |
64 | is( $result->return_code, 0, "Checking case sensitivity of args" ); | 68 | is( $result->return_code, 0, "Checking case sensitivity of args" ); |
65 | like( $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'" ); |
68 | is( $result->return_code, 0, "Checking regexp search of arguments" ); | 73 | is( $result->return_code, 0, "Checking regexp search of arguments" ); |
diff --git a/plugins/tests/check_snmp.t b/plugins/tests/check_snmp.t index d865e190..aace9bcc 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"); |
80 | cmp_ok( $res->return_code, '==', 0, "Exit OK when querying multi-line OIDs" ); | 80 | cmp_ok( $res->return_code, '==', 0, "Exit OK when querying multi-line OIDs" ); |
81 | like($res->output, '/^SNMP OK - /', "String contains SNMP OK"); | 81 | like($res->output, '/^SNMP OK - /', "String contains SNMP OK"); |
82 | like($res->output, '/'.quotemeta('SNMP OK - Cisco Internetwork Operating System Software "Alice" Kisco Outernetwork Oserating Gystem Totware | | 82 | like($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 |
85 | IOS (tm) Catalyst 4000 \"L3\" Switch Software (cat4000-I9K91S-M), Version | 85 | IOS (tm) Catalyst 4000 \"L3\" Switch Software (cat4000-I9K91S-M), Version |
@@ -1998,7 +1998,7 @@ msgstr "" | |||
1998 | 1998 | ||
1999 | #: plugins/check_mrtg.c:359 | 1999 | #: plugins/check_mrtg.c:359 |
2000 | msgid "" | 2000 | msgid "" |
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" |
2002 | msgstr "" | 2002 | msgstr "" |
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 |
5363 | msgid "ERROR - Status '%d' unkown. %d/%d tests passed\n" | 5363 | msgid "ERROR - Status '%d' unknown. %d/%d tests passed\n" |
5364 | msgstr "" | 5364 | msgstr "" |
5365 | 5365 | ||
5366 | #: plugins/check_ide_smart.c:474 | 5366 | #: plugins/check_ide_smart.c:474 |
@@ -2050,7 +2050,7 @@ msgstr "" | |||
2050 | 2050 | ||
2051 | #: plugins/check_mrtg.c:359 | 2051 | #: plugins/check_mrtg.c:359 |
2052 | msgid "" | 2052 | msgid "" |
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" |
2054 | msgstr "" | 2054 | msgstr "" |
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 |
5451 | msgid "ERROR - Status '%d' unkown. %d/%d tests passed\n" | 5451 | msgid "ERROR - Status '%d' unknown. %d/%d tests passed\n" |
5452 | msgstr "ERREUR - État '%d' inconnu. %d/%d les tests on réussi\n" | 5452 | msgstr "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 07c1b98f..8f220e98 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 |
1946 | msgid "" | 1946 | msgid "" |
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" |
1948 | msgstr "" | 1948 | msgstr "" |
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 |
5220 | msgid "ERROR - Status '%d' unkown. %d/%d tests passed\n" | 5220 | msgid "ERROR - Status '%d' unknown. %d/%d tests passed\n" |
5221 | msgstr "" | 5221 | msgstr "" |
5222 | 5222 | ||
5223 | #: plugins/check_ide_smart.c:474 | 5223 | #: plugins/check_ide_smart.c:474 |
@@ -9,6 +9,8 @@ use Getopt::Long; | |||
9 | 9 | ||
10 | use NPTest qw(DetermineTestHarnessDirectory TestsFrom); | 10 | use NPTest qw(DetermineTestHarnessDirectory TestsFrom); |
11 | 11 | ||
12 | $ENV{LC_ALL} = 'C'; | ||
13 | |||
12 | my @tstdir; | 14 | my @tstdir; |
13 | 15 | ||
14 | if ( ! GetOptions( "testdir:s" => \@tstdir ) ) | 16 | if ( ! GetOptions( "testdir:s" => \@tstdir ) ) |