Code

Update error message from smbclient v2.2.7 (Patch 740132 - Cove Schneider)
[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 # $Id$
20 #
22 require 5.004;
23 use POSIX;
24 use strict;
25 use Getopt::Long;
26 use vars qw($opt_V $opt_h $opt_H $opt_s $opt_W $opt_u $opt_p $opt_w $opt_c $verbose);
27 use vars qw($PROGNAME);
28 use lib utils.pm ;
29 use utils qw($TIMEOUT %ERRORS &print_revision &support &usage);
31 sub print_help ();
32 sub print_usage ();
34 $PROGNAME = "check_disk_smb";
36 $ENV{'PATH'}='';
37 $ENV{'BASH_ENV'}=''; 
38 $ENV{'ENV'}='';
40 Getopt::Long::Configure('bundling');
41 GetOptions
42         ("v"   => \$verbose, "verbose"    => \$verbose,
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);
53 if ($opt_V) {
54         print_revision($PROGNAME,'$Revision$'); #'
55         exit $ERRORS{'OK'};
56 }
58 if ($opt_h) {print_help(); exit $ERRORS{'OK'};}
60 my $smbclient= "$utils::PATH_TO_SMBCLIENT " ;
61 my $smbclientoptions="";
64 # Options checking
66 ($opt_H) || ($opt_H = shift) || usage("Host name not specified\n");
67 my $host = $1 if ($opt_H =~ /^([-_.A-Za-z0-9]+\$?)$/);
68 ($host) || usage("Invalid host: $opt_H\n");
70 ($opt_s) || ($opt_s = shift) || usage("Share volume not specified\n");
71 my $share = $1 if ($opt_s =~ /^([-_.A-Za-z0-9]+\$?)$/);
72 ($share) || usage("Invalid share: $opt_s\n");
74 ($opt_u) || ($opt_u = shift) || ($opt_u = "guest");
75 my $user = $1 if ($opt_u =~ /^([-_.A-Za-z0-9\\]+)$/);
76 ($user) || usage("Invalid user: $opt_u\n");
78 ($opt_p) || ($opt_p = shift) || ($opt_p = "guest");
79 my $pass = $1 if ($opt_p =~ /(.*)/);
81 ($opt_w) || ($opt_w = shift) || ($opt_w = 85);
82 my $warn = $1 if ($opt_w =~ /^([0-9]{1,2}\%?|100\%?|[0-9]+[kMG])$/);
83 ($warn) || usage("Invalid warning threshold: $opt_w\n");
85 ($opt_c) || ($opt_c = shift) || ($opt_c = 95);
86 my $crit = $1 if ($opt_c =~ /^([0-9]{1,2}\%?|100\%?|[0-9]+[kMG])$/);
87 ($crit) || usage("Invalid critical threshold: $opt_c\n");
89 # check if both warning and critical are percentage or size
90 unless( ( ($opt_w =~ /([0-9]){1,2}$/ ) && ($opt_c =~ /([0-9]){1,2}$/ )  )|| (( $opt_w =~ /[kMG]/ ) && ($opt_c =~ /[kMG]/) )  ){
91         usage("Both warning and critical should be same type- warning: $opt_w critical: $opt_c \n");
92 }
94 # verify warning is less than critical
95 if ( $opt_w =~ /[kMG]/) {
96         unless ( $warn > $crit) {
97                 usage("Disk size: warning ($opt_w) should be greater than critical ($opt_c) \n");
98         }
99 }else{
100         unless ( $warn < $crit) {
101                 usage("Percentage: warning ($opt_w) should be less than critical ($opt_c) \n");
102         }
105 my $workgroup = $1 if (defined($opt_W) && $opt_W =~ /(.*)/);
107 # end of options checking
110 my $state = "OK";
111 my $answer = undef;
112 my $res = undef;
113 my @lines = undef;
115 # Just in case of problems, let's not hang Nagios
116 $SIG{'ALRM'} = sub { 
117         print "No Answer from Client\n";
118         exit $ERRORS{"UNKNOWN"};
119 };
120 alarm($TIMEOUT);
122 # Execute an "ls" on the share using smbclient program
123 # get the results into $res
124 if (defined($workgroup)) {
125         $res = qx/$smbclient \/\/$host\/$share $pass -W $workgroup -U $user $smbclientoptions -c ls/;
126 } else {
127         print "$smbclient " . "\/\/$host\/$share" ." $pass -U $user $smbclientoptions -c ls\n" if ($verbose);
128         $res = qx/$smbclient \/\/$host\/$share $pass -U $user $smbclientoptions -c ls/;
130 #Turn off alarm
131 alarm(0);
133 #Split $res into an array of lines
134 @lines = split /\n/, $res;
136 #Get the last line into $_
137 $_ = $lines[$#lines];
138 #print "$_\n";
140 #Process the last line to get free space.  
141 #If line does not match required regexp, return an UNKNOWN error
142 if (/\s*(\d*) blocks of size (\d*)\. (\d*) blocks available/) {
144         my ($avail) = ($3*$2)/1024;
145         my ($avail_bytes) = $avail;
146         my ($capper) = int(($3/$1)*100);
147         my ($mountpt) = "\\\\$host\\$share";
149         #Check $warn and $crit for type (%/M/G) and set up for tests
150         #P = Percent, K = KBytes
151         my $warn_type;
152         my $crit_type;
154         if ($opt_w =~ /^([0-9]+$)/) {
155                 $warn_type = "P";
156         } elsif ($opt_w =~ /^([0-9]+)k$/) {
157                 $warn_type = "K";
158                 $warn = $1;
159         } elsif ($opt_w =~ /^([0-9]+)M$/) {
160                 $warn_type = "K";
161                 $warn = $1 * 1024;
162         } elsif ($opt_w =~ /^([0-9]+)G$/) {
163                 $warn_type = "K";
164                 $warn = $1 * 1048576;
165         }
166         if ($opt_c =~ /^([0-9]+$)/) {
167                 $crit_type = "P";
168         } elsif ($opt_c =~ /^([0-9]+)k$/) {
169                 $crit_type = "K";
170                 $crit = $1;
171         } elsif ($opt_c =~ /^([0-9]+)M$/) {
172                 $crit_type = "K";
173                 $crit = $1 * 1024;
174         } elsif ($opt_c =~ /^([0-9]+)G$/) {
175                 $crit_type = "K";
176                 $crit = $1 * 1048576;
177         }
179         if (int($avail / 1024) > 0) {
180                 $avail = int($avail / 1024);
181                 if (int($avail /1024) > 0) {
182                         $avail = (int(($avail / 1024)*100))/100;
183                         $avail = $avail ."G";
184                 } else {
185                         $avail = $avail ."M";
186                 }
187         } else {
188                 $avail = $avail ."K";
189         }
191 #print ":$warn:$warn_type:\n";
192 #print ":$crit:$crit_type:\n";
193 #print ":$avail:$avail_bytes:$capper:$mountpt:\n";
195         if ((($warn_type eq "P") && (100 - $capper) < $warn) || (($warn_type eq "K") && ($avail_bytes > $warn))) { 
196                 $answer = "Disk ok - $avail ($capper%) free on $mountpt\n";
197         } elsif ((($crit_type eq "P") && (100 - $capper) < $crit) || (($crit_type eq "K") && ($avail_bytes > $crit))) {
198                 $state = "WARNING";
199                 $answer = "WARNING: Only $avail ($capper%) free on $mountpt\n";
200         } else {
201                 $state = "CRITICAL";
202                 $answer = "CRITICAL: Only $avail ($capper%) free on $mountpt\n";
203         }
204 } else {
205         $answer = "Result from smbclient not suitable\n";
206         $state = "UNKNOWN";
207         foreach (@lines) {
208                 if (/(Access denied|NT_STATUS_LOGON_FAILURE)/) {
209                         $answer = "Access Denied\n";
210                         $state = "CRITICAL";
211                         last;
212                 }
213                 if (/(Unknown host \w*|Connection.*failed)/) {
214                         $answer = "$1\n";
215                         $state = "CRITICAL";
216                         last;
217                 }
218                 if (/(You specified an invalid share name|NT_STATUS_BAD_NETWORK_NAME)/) {
219                         $answer = "Invalid share name \\\\$host\\$share\n";
220                         $state = "CRITICAL";
221                         last;
222                 }
223         }
227 print $answer;
228 print "$state\n" if ($verbose);
229 exit $ERRORS{$state};
231 sub print_usage () {
232         print "Usage: $PROGNAME -H <host> -s <share> -u <user> -p <password> 
233       -w <warn> -c <crit> [-W <workgroup>]\n";
236 sub print_help () {
237         print_revision($PROGNAME,'$Revision$');
238         print "Copyright (c) 2000 Michael Anthon/Karl DeBisschop
240 Perl Check SMB Disk plugin for Nagios
242 ";
243         print_usage();
244         print "
245 -H, --hostname=HOST
246    NetBIOS name of the server
247 -s, --share=STRING
248    Share name to be tested
249 -W, --workgroup=STRING
250    Workgroup or Domain used (Defaults to \"WORKGROUP\")
251 -u, --user=STRING
252    Username to log in to server. (Defaults to \"guest\")
253 -p, --password=STRING
254    Password to log in to server. (Defaults to \"guest\")
255 -w, --warning=INTEGER or INTEGER[kMG]
256    Percent of used space at which a warning will be generated (Default: 85%)
257       
258 -c, --critical=INTEGER or INTEGER[kMG]
259    Percent of used space at which a critical will be generated (Defaults: 95%)
260    
261    If thresholds are followed by either a k, M, or G then check to see if that
262    much disk space is available (kilobytes, Megabytes, Gigabytes)
264    Warning percentage should be less than critical
265    Warning (remaining) disk space should be greater than critical.
267 ";
268         support();