summaryrefslogtreecommitdiffstats
path: root/plugins-scripts/check_disk_smb.pl
blob: d1b0b3d63901f2025d76ce04866a73b2fa95a9c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
#! /usr/bin/perl -wT
#
#
# check_disk.pl <host> <share> <user> <pass> [warn] [critical] [port]
#
# Nagios host script to get the disk usage from a SMB share
#
# Changes and Modifications
# =========================
# 7-Aug-1999 - Michael Anthon
#  Created from check_disk.pl script provided with netsaint_statd (basically
#  cause I was too lazy (or is that smart?) to write it from scratch)
# 8-Aug-1999 - Michael Anthon
#  Modified [warn] and [critical] parameters to accept format of nnn[M|G] to
#  allow setting of limits in MBytes or GBytes.  Percentage settings for large
#  drives is a pain in the butt

BEGIN {
	if ($0 =~ m/^(.*?)[\/\\]([^\/\\]+)$/) {
		$runtimedir = $1;
		$PROGNAME = $2;
	}
}

require 5.004;
use POSIX;
use strict;
use Getopt::Long;
use vars qw($opt_V $opt_h $opt_H $opt_s $opt_W $opt_u $opt_p $opt_w $opt_c $verbose);
use vars qw($PROGNAME);
use lib $main::runtimedir;
use utils qw($TIMEOUT %ERRORS &print_revision &support &usage);

sub print_help ();
sub print_usage ();

$ENV{'PATH'}='';
$ENV{'BASH_ENV'}=''; 
$ENV{'ENV'}='';

Getopt::Long::Configure('bundling');
GetOptions
	("v"   => \$verbose, "verbose"    => \$verbose,
	 "V"   => \$opt_V, "version"    => \$opt_V,
	 "h"   => \$opt_h, "help"       => \$opt_h,
	 "w=s" => \$opt_w, "warning=s"  => \$opt_w,
	 "c=s" => \$opt_c, "critical=s" => \$opt_c,
	 "p=s" => \$opt_p, "password=s" => \$opt_p,
	 "u=s" => \$opt_u, "username=s" => \$opt_u,
	 "s=s" => \$opt_s, "share=s"    => \$opt_s,
	 "W=s" => \$opt_W, "workgroup=s" => \$opt_W,
	 "H=s" => \$opt_H, "hostname=s" => \$opt_H);

if ($opt_V) {
	print_revision($PROGNAME,'$Revision$'); #'
	exit $ERRORS{'OK'};
}

if ($opt_h) {print_help(); exit $ERRORS{'OK'};}

my $smbclient="/usr/bin/smbclient";
my $smbclientoptions="";

($opt_H) || ($opt_H = shift) || usage("Host name not specified\n");
my $host = $1 if ($opt_H =~ /([-_.A-Za-z0-9]+)/);
($host) || usage("Invalid host: $opt_H\n");

($opt_s) || ($opt_s = shift) || usage("Share volume not specified\n");
my $share = $1 if ($opt_s =~ /([-_.A-Za-z0-9]+)/);
($share) || usage("Invalid share: $opt_s\n");

($opt_u) || ($opt_u = shift) || ($opt_u = "guest");
my $user = $1 if ($opt_u =~ /([-_.A-Za-z0-9]+)/);
($user) || usage("Invalid user: $opt_u\n");

($opt_p) || ($opt_p = shift) || ($opt_p = "guest");
my $pass = $1 if ($opt_p =~ /(.*)/);

($opt_w) || ($opt_w = shift) || ($opt_w = 85);
my $warn = $1 if ($opt_w =~ /([0-9]{1,2}\%?|100\%?|[0-9]+[kmKM])+/);
($warn) || usage("Invalid warning threshold: $opt_w\n");

($opt_c) || ($opt_c = shift) || ($opt_c = 95);
my $crit = $1 if ($opt_c =~ /([0-9]{1,2}\%?|100\%?|[0-9]+[kmKM])/);
($crit) || usage("Invalid critical threshold: $opt_c\n");

my $workgroup = $1 if (defined($opt_W) && $opt_W =~ /(.*)/);

my $state = "OK";
my $answer = undef;
my $res = undef;
my @lines = undef;

# Just in case of problems, let's not hang Nagios
$SIG{'ALRM'} = sub { 
	print "No Answer from Client\n";
	exit $ERRORS{"UNKNOWN"};
};
alarm($TIMEOUT);

# Execute an "ls" on the share using smbclient program
# get the results into $res
if (defined($workgroup)) {
	$res = qx/$smbclient \/\/$host\/$share $pass -W $workgroup -U $user $smbclientoptions -c ls/;
} else {
	$res = qx/$smbclient \/\/$host\/$share $pass -U $user $smbclientoptions -c ls/;
}
#Turn off alarm
alarm(0);

#Split $res into an array of lines
@lines = split /\n/, $res;

#Get the last line into $_
$_ = $lines[$#lines];
#print "$_\n";

#Process the last line to get free space.  
#If line does not match required regexp, return an UNKNOWN error
if (/\s*(\d*) blocks of size (\d*)\. (\d*) blocks available/) {

	my ($avail) = ($3*$2)/1024;
	my ($avail_bytes) = $avail;
	my ($capper) = int(($3/$1)*100);
	my ($mountpt) = "\\\\$host\\$share";

	#Check $warn and $crit for type (%/M/G) and set up for tests
	#P = Percent, K = KBytes
	my $warn_type;
	my $crit_type;
	if ($warn =~ /^([0-9]+$)/) {
		$warn_type = "P";
	} elsif ($warn =~ /^([0-9]+)k$/) {
		my ($warn_type) = "K";
		$warn = $1;
	} elsif ($warn =~ /^([0-9]+)M$/) {
		$warn_type = "K";
		$warn = $1 * 1024;
	} elsif ($warn =~ /^([0-9]+)G$/) {
		$warn_type = "K";
		$warn = $1 * 1048576;
	}
	if ($crit =~ /^([0-9]+$)/) {
		$crit_type = "P";
	} elsif ($crit =~ /^([0-9]+)k$/) {
		$crit_type = "K";
		$crit = $1;
	} elsif ($crit =~ /^([0-9]+)M$/) {
		$crit_type = "K";
		$crit = $1 * 1024;
	} elsif ($crit =~ /^([0-9]+)G$/) {
		$crit_type = "K";
		$crit = $1 * 1048576;
	}

	if (int($avail / 1024) > 0) {
		$avail = int($avail / 1024);
		if (int($avail /1024) > 0) {
			$avail = (int(($avail / 1024)*100))/100;
			$avail = $avail."G";
		} else {
			$avail = $avail."M";
		}
	} else {
		$avail = $avail."K";
	}

#print ":$warn:$warn_type:\n";
#print ":$crit:$crit_type:\n";
#print ":$avail:$avail_bytes:$capper:$mountpt:\n";
	if ((($warn_type eq "P") && (100 - $capper) < $warn) || (($warn_type eq "K") && ($avail_bytes > $warn))) { 
		$answer = "Disk ok - $avail ($capper%) free on $mountpt\n";
	} elsif ((($crit_type eq "P") && (100 - $capper) < $crit) || (($crit_type eq "K") && ($avail_bytes > $crit))) {
		$state = "WARNING";
		$answer = "Only $avail ($capper%) free on $mountpt\n";
	} else {
		$state = "CRITICAL";
		$answer = "Only $avail ($capper%) free on $mountpt\n";
	}
} else {
	$answer = "Result from smbclient not suitable\n";
	$state = "UNKNOWN";
	foreach (@lines) {
		if (/Access denied/) {
			$answer = "Access Denied\n";
			$state = "CRITICAL";
			last;
		}
		if (/(Unknown host \w*)/) {
			$answer = "$1\n";
			$state = "CRITICAL";
			last;
		}
		if (/(You specified an invalid share name)/) {
			$answer = "Invalid share name \\\\$host\\$share\n";
			$state = "CRITICAL";
			last;
		}
	}
}


print $answer;
print "$state\n" if ($verbose);
exit $ERRORS{$state};

sub print_usage () {
	print "Usage: $PROGNAME -H <host> -s <share> -u <user> -p <password> 
      -w <warn> -c <crit> [-W <workgroup>]\n";
}

sub print_help () {
	print_revision($PROGNAME,'$Revision$');
	print "Copyright (c) 2000 Michael Anthon/Karl DeBisschop

Perl Check SMB Disk plugin for Nagios

";
	print_usage();
	print "
-H, --hostname=HOST
   NetBIOS name of the server
-s, --share=STRING
   Share name to be tested
-W, --workgroup=STRING
   Workgroup or Domain used (Defaults to \"WORKGROUP\")
-u, --user=STRING
   Username to log in to server. (Defaults to \"guest\")
-p, --password=STRING
   Password to log in to server. (Defaults to \"guest\")
-w, --warning=INTEGER
   Percent of used space at which a warning will be generated (Default: 85%)
   
-c, --critical=INTEGER
   Percent of used space at which a critical will be generated (Defaults: 95%)
   

";
	support();
}