Code

check_disk_smb: Allow for specifying an IP address
[nagiosplug.git] / plugins-scripts / check_disk_smb.pl
1 #!/usr/bin/perl -w
2 #
3 #
4 # check_disk.pl <host> <share> <user> <pass> [warn] [critical] [port]
5 #
6 # Nagios host script to get the disk usage from a SMB share
7 #
8 # Changes and Modifications
9 # =========================
10 # 7-Aug-1999 - Michael Anthon
11 #  Created from check_disk.pl script provided with netsaint_statd (basically
12 #  cause I was too lazy (or is that smart?) to write it from scratch)
13 # 8-Aug-1999 - Michael Anthon
14 #  Modified [warn] and [critical] parameters to accept format of nnn[M|G] to
15 #  allow setting of limits in MBytes or GBytes.  Percentage settings for large
16 #  drives is a pain in the butt
17 # 2-May-2002 - SGhosh fix for embedded perl
18 #
19 #
21 require 5.004;
22 use POSIX;
23 use strict;
24 use Getopt::Long;
25 use vars qw($opt_P $opt_V $opt_h $opt_H $opt_s $opt_W $opt_u $opt_p $opt_w $opt_c $opt_a $verbose);
26 use vars qw($PROGNAME);
27 use lib utils.pm ;
28 use utils qw($TIMEOUT %ERRORS &print_revision &support &usage);
30 sub print_help ();
31 sub print_usage ();
33 $PROGNAME = "check_disk_smb";
35 $ENV{'PATH'}='';
36 $ENV{'BASH_ENV'}=''; 
37 $ENV{'ENV'}='';
39 Getopt::Long::Configure('bundling');
40 GetOptions
41         ("v"   => \$verbose, "verbose"    => \$verbose,
42          "P=s" => \$opt_P, "port=s"     => \$opt_P,
43          "V"   => \$opt_V, "version"    => \$opt_V,
44          "h"   => \$opt_h, "help"       => \$opt_h,
45          "w=s" => \$opt_w, "warning=s"  => \$opt_w,
46          "c=s" => \$opt_c, "critical=s" => \$opt_c,
47          "p=s" => \$opt_p, "password=s" => \$opt_p,
48          "u=s" => \$opt_u, "username=s" => \$opt_u,
49          "s=s" => \$opt_s, "share=s"    => \$opt_s,
50          "W=s" => \$opt_W, "workgroup=s" => \$opt_W,
51          "H=s" => \$opt_H, "hostname=s" => \$opt_H,
52          "a=s" => \$opt_a, "address=s" => \$opt_a);
54 if ($opt_V) {
55         print_revision($PROGNAME,'@NP_VERSION@'); #'
56         exit $ERRORS{'OK'};
57 }
59 if ($opt_h) {print_help(); exit $ERRORS{'OK'};}
61 my $smbclient= "$utils::PATH_TO_SMBCLIENT " ;
62 my $smbclientoptions= $opt_P ? "-p $opt_P " : "";
65 # Options checking
67 ($opt_H) || ($opt_H = shift) || usage("Host name not specified\n");
68 my $host = $1 if ($opt_H =~ /^([-_.A-Za-z0-9 ]+\$?)$/);
69 ($host) || usage("Invalid host: $opt_H\n");
71 ($opt_s) || ($opt_s = shift) || usage("Share volume not specified\n");
72 my $share = $1 if ($opt_s =~ /^([-_.A-Za-z0-9]+\$?)$/);
73 ($share) || usage("Invalid share: $opt_s\n");
75 ($opt_u) || ($opt_u = shift) || ($opt_u = "guest");
76 my $user = $1 if ($opt_u =~ /^([-_.A-Za-z0-9\\]+)$/);
77 ($user) || usage("Invalid user: $opt_u\n");
79 ($opt_p) || ($opt_p = shift) || ($opt_p = "");
80 my $pass = $1 if ($opt_p =~ /(.*)/);
82 ($opt_w) || ($opt_w = shift) || ($opt_w = 85);
83 my $warn = $1 if ($opt_w =~ /^([0-9]{1,2}\%?|100\%?|[0-9]+[kMG])$/);
84 ($warn) || usage("Invalid warning threshold: $opt_w\n");
86 ($opt_c) || ($opt_c = shift) || ($opt_c = 95);
87 my $crit = $1 if ($opt_c =~ /^([0-9]{1,2}\%?|100\%?|[0-9]+[kMG])$/);
88 ($crit) || usage("Invalid critical threshold: $opt_c\n");
90 # split the type from the unit value
91 #Check $warn and $crit for type (%/M/G) and set up for tests
92 #P = Percent, K = KBytes
93 my $warn_type;
94 my $crit_type;
96 if ($opt_w =~ /^([0-9]+)\%?$/) {
97         $warn = "$1";
98         $warn_type = "P";
99 } elsif ($opt_w =~ /^([0-9]+)k$/) {
100         $warn_type = "K";
101         $warn = $1;
102 } elsif ($opt_w =~ /^([0-9]+)M$/) {
103         $warn_type = "K";
104         $warn = $1 * 1024;
105 } elsif ($opt_w =~ /^([0-9]+)G$/) {
106         $warn_type = "K";
107         $warn = $1 * 1048576;
109 if ($opt_c =~ /^([0-9]+)\%?$/) {
110         $crit = "$1";
111         $crit_type = "P";
112 } elsif ($opt_c =~ /^([0-9]+)k$/) {
113         $crit_type = "K";
114         $crit = $1;
115 } elsif ($opt_c =~ /^([0-9]+)M$/) {
116         $crit_type = "K";
117         $crit = $1 * 1024;
118 } elsif ($opt_c =~ /^([0-9]+)G$/) {
119         $crit_type = "K";
120         $crit = $1 * 1048576;
123 # check if both warning and critical are percentage or size
124 unless( ( $warn_type eq "P" && $crit_type eq "P" ) || ( $warn_type ne "P" && $crit_type ne "P" ) ){
125         $opt_w =~ s/\%/\%\%/g;
126         $opt_c =~ s/\%/\%\%/g;
127         usage("Both warning and critical should be same type- warning: $opt_w critical: $opt_c \n");
130 # verify warning is less than critical
131 if ( $warn_type eq "K") {
132         unless ( $warn > $crit) {
133                 usage("Disk size: warning ($opt_w) should be greater than critical ($opt_c) \n");
134         }
135 }else{
136         unless ( $warn < $crit) {
137                 $opt_w =~ s/\%/\%\%/g;
138                 $opt_c =~ s/\%/\%\%/g;
139                 usage("Percentage: warning ($opt_w) should be less than critical ($opt_c) \n");
140         }
143 my $workgroup = $1 if (defined($opt_W) && $opt_W =~ /(.*)/);
145 my $address = $1 if (defined($opt_a) && $opt_a =~ /(.*)/);
147 # end of options checking
150 my $state = "OK";
151 my $answer = undef;
152 my $res = undef;
153 my @lines = undef;
155 # Just in case of problems, let's not hang Nagios
156 $SIG{'ALRM'} = sub { 
157         print "No Answer from Client\n";
158         exit $ERRORS{"UNKNOWN"};
159 };
160 alarm($TIMEOUT);
162 # Execute an "ls" on the share using smbclient program
163 # get the results into $res
164 if (defined($workgroup)) {
165         if (defined($address)) {
166                 print "$smbclient " . "\/\/$host\/$share" ." $pass -W $workgroup -U $user $smbclientoptions -I $address -c ls\n" if ($verbose);
167                 $res = qx/$smbclient "\/\/$host\/$share" $pass -W $workgroup -U $user $smbclientoptions -I $address -c ls/;
168         } else {
169                 print "$smbclient " . "\/\/$host\/$share" ." $pass -W $workgroup -U $user $smbclientoptions -c ls\n" if ($verbose);
170                 $res = qx/$smbclient "\/\/$host\/$share" $pass -W $workgroup -U $user $smbclientoptions -c ls/;
171         }
172 } else {
173         if (defined($address)) {
174                 print "$smbclient " . "\/\/$host\/$share" ." $pass -U $user $smbclientoptions -I $address -c ls\n" if ($verbose);
175                 $res = qx/$smbclient "\/\/$host\/$share" $pass -U $user $smbclientoptions -I $address -c ls/;
176         } else {
177                 print "$smbclient " . "\/\/$host\/$share" ." $pass -U $user $smbclientoptions -c ls\n" if ($verbose);
178                 $res = qx/$smbclient "\/\/$host\/$share" $pass -U $user $smbclientoptions -c ls/;
179         }
181 #Turn off alarm
182 alarm(0);
184 #Split $res into an array of lines
185 @lines = split /\n/, $res;
187 #Get the last line into $_
188 $_ = $lines[$#lines];
189 #print "$_\n";
191 #Process the last line to get free space.  
192 #If line does not match required regexp, return an UNKNOWN error
193 if (/\s*(\d*) blocks of size (\d*)\. (\d*) blocks available/) {
195         my ($avail) = ($3*$2)/1024;
196         my ($avail_bytes) = $avail;
197         my ($capper) = int(($3/$1)*100);
198         my ($mountpt) = "\\\\$host\\$share";
201         if (int($avail / 1024) > 0) {
202                 $avail = int($avail / 1024);
203                 if (int($avail /1024) > 0) {
204                         $avail = (int(($avail / 1024)*100))/100;
205                         $avail = $avail ."G";
206                 } else {
207                         $avail = $avail ."M";
208                 }
209         } else {
210                 $avail = $avail ."K";
211         }
213 #print ":$warn:$warn_type:\n";
214 #print ":$crit:$crit_type:\n";
215 #print ":$avail:$avail_bytes:$capper:$mountpt:\n";
217         if ((($warn_type eq "P") && (100 - $capper) < $warn) || (($warn_type eq "K") && ($avail_bytes > $warn))) { 
218                 $answer = "Disk ok - $avail ($capper%) free on $mountpt\n";
219         } elsif ((($crit_type eq "P") && (100 - $capper) < $crit) || (($crit_type eq "K") && ($avail_bytes > $crit))) {
220                 $state = "WARNING";
221                 $answer = "WARNING: Only $avail ($capper%) free on $mountpt\n";
222         } else {
223                 $state = "CRITICAL";
224                 $answer = "CRITICAL: Only $avail ($capper%) free on $mountpt\n";
225         }
226 } else {
227         $answer = "Result from smbclient not suitable\n";
228         $state = "UNKNOWN";
229         foreach (@lines) {
230                 if (/(Access denied|NT_STATUS_LOGON_FAILURE)/) {
231                         $answer = "Access Denied\n";
232                         $state = "CRITICAL";
233                         last;
234                 }
235                 if (/(Unknown host \w*|Connection.*failed)/) {
236                         $answer = "$1\n";
237                         $state = "CRITICAL";
238                         last;
239                 }
240                 if (/(You specified an invalid share name|NT_STATUS_BAD_NETWORK_NAME)/) {
241                         $answer = "Invalid share name \\\\$host\\$share\n";
242                         $state = "CRITICAL";
243                         last;
244                 }
245         }
249 print $answer;
250 print "$state\n" if ($verbose);
251 exit $ERRORS{$state};
253 sub print_usage () {
254         print "Usage: $PROGNAME -H <host> -s <share> -u <user> -p <password> 
255       -w <warn> -c <crit> [-W <workgroup>] [-P <port>] [-a <IP>]\n";
258 sub print_help () {
259         print_revision($PROGNAME,'@NP_VERSION@');
260         print "Copyright (c) 2000 Michael Anthon/Karl DeBisschop
262 Perl Check SMB Disk plugin for Nagios
264 ";
265         print_usage();
266         print "
267 -H, --hostname=HOST
268    NetBIOS name of the server
269 -s, --share=STRING
270    Share name to be tested
271 -W, --workgroup=STRING
272    Workgroup or Domain used (Defaults to \"WORKGROUP\")
273 -a, --address=IP
274    IP-address of HOST (only necessary if HOST is in another network)
275 -u, --user=STRING
276    Username to log in to server. (Defaults to \"guest\")
277 -p, --password=STRING
278    Password to log in to server. (Defaults to an empty password)
279 -w, --warning=INTEGER or INTEGER[kMG]
280    Percent of used space at which a warning will be generated (Default: 85%)
281       
282 -c, --critical=INTEGER or INTEGER[kMG]
283    Percent of used space at which a critical will be generated (Defaults: 95%)
284 -P, --port=INTEGER
285    Port to be used to connect to. Some Windows boxes use 139, others 445 (Defaults to smbclient default)
286    
287    If thresholds are followed by either a k, M, or G then check to see if that
288    much disk space is available (kilobytes, Megabytes, Gigabytes)
290    Warning percentage should be less than critical
291    Warning (remaining) disk space should be greater than critical.
293 ";
294         support();