Code

3f531ac75c71a10320d8f09a0812bcc4b7226a46
[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 $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);
53 if ($opt_V) {
54         print_revision($PROGNAME,'@NP_VERSION@'); #'
55         exit $ERRORS{'OK'};
56 }
58 if ($opt_h) {print_help(); exit $ERRORS{'OK'};}
60 my $smbclient= "$utils::PATH_TO_SMBCLIENT " ;
61 my $smbclientoptions= $opt_P ? "-p $opt_P " : "";
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 = "");
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 # split the type from the unit value
90 #Check $warn and $crit for type (%/M/G) and set up for tests
91 #P = Percent, K = KBytes
92 my $warn_type;
93 my $crit_type;
95 if ($opt_w =~ /^([0-9]+)\%?$/) {
96         $warn = "$1";
97         $warn_type = "P";
98 } elsif ($opt_w =~ /^([0-9]+)k$/) {
99         $warn_type = "K";
100         $warn = $1;
101 } elsif ($opt_w =~ /^([0-9]+)M$/) {
102         $warn_type = "K";
103         $warn = $1 * 1024;
104 } elsif ($opt_w =~ /^([0-9]+)G$/) {
105         $warn_type = "K";
106         $warn = $1 * 1048576;
108 if ($opt_c =~ /^([0-9]+)\%?$/) {
109         $crit = "$1";
110         $crit_type = "P";
111 } elsif ($opt_c =~ /^([0-9]+)k$/) {
112         $crit_type = "K";
113         $crit = $1;
114 } elsif ($opt_c =~ /^([0-9]+)M$/) {
115         $crit_type = "K";
116         $crit = $1 * 1024;
117 } elsif ($opt_c =~ /^([0-9]+)G$/) {
118         $crit_type = "K";
119         $crit = $1 * 1048576;
122 # check if both warning and critical are percentage or size
123 unless( ( $warn_type eq "P" && $crit_type eq "P" ) || ( $warn_type ne "P" && $crit_type ne "P" ) ){
124         $opt_w =~ s/\%/\%\%/g;
125         $opt_c =~ s/\%/\%\%/g;
126         usage("Both warning and critical should be same type- warning: $opt_w critical: $opt_c \n");
129 # verify warning is less than critical
130 if ( $warn_type eq "K") {
131         unless ( $warn > $crit) {
132                 usage("Disk size: warning ($opt_w) should be greater than critical ($opt_c) \n");
133         }
134 }else{
135         unless ( $warn < $crit) {
136                 $opt_w =~ s/\%/\%\%/g;
137                 $opt_c =~ s/\%/\%\%/g;
138                 usage("Percentage: warning ($opt_w) should be less than critical ($opt_c) \n");
139         }
142 my $workgroup = $1 if (defined($opt_W) && $opt_W =~ /(.*)/);
144 # end of options checking
147 my $state = "OK";
148 my $answer = undef;
149 my $res = undef;
150 my @lines = undef;
152 # Just in case of problems, let's not hang Nagios
153 $SIG{'ALRM'} = sub { 
154         print "No Answer from Client\n";
155         exit $ERRORS{"UNKNOWN"};
156 };
157 alarm($TIMEOUT);
159 # Execute an "ls" on the share using smbclient program
160 # get the results into $res
161 if (defined($workgroup)) {
162         $res = qx/$smbclient \/\/$host\/$share -W $workgroup -U $user%$pass $smbclientoptions -c ls/;
163 } else {
164         print "$smbclient " . "\/\/$host\/$share" ." $pass -U $user $smbclientoptions -c ls\n" if ($verbose);
165         $res = qx/$smbclient \/\/$host\/$share -U $user%$pass $smbclientoptions -c ls/;
167 #Turn off alarm
168 alarm(0);
170 #Split $res into an array of lines
171 @lines = split /\n/, $res;
173 #Get the last line into $_
174 $_ = $lines[$#lines];
175 #print "$_\n";
177 #Process the last line to get free space.  
178 #If line does not match required regexp, return an UNKNOWN error
179 if (/\s*(\d*) blocks of size (\d*)\. (\d*) blocks available/) {
181         my ($avail) = ($3*$2)/1024;
182         my ($avail_bytes) = $avail;
183         my ($capper) = int(($3/$1)*100);
184         my ($mountpt) = "\\\\$host\\$share";
187         if (int($avail / 1024) > 0) {
188                 $avail = int($avail / 1024);
189                 if (int($avail /1024) > 0) {
190                         $avail = (int(($avail / 1024)*100))/100;
191                         $avail = $avail ."G";
192                 } else {
193                         $avail = $avail ."M";
194                 }
195         } else {
196                 $avail = $avail ."K";
197         }
199 #print ":$warn:$warn_type:\n";
200 #print ":$crit:$crit_type:\n";
201 #print ":$avail:$avail_bytes:$capper:$mountpt:\n";
203         if ((($warn_type eq "P") && (100 - $capper) < $warn) || (($warn_type eq "K") && ($avail_bytes > $warn))) { 
204                 $answer = "Disk ok - $avail ($capper%) free on $mountpt\n";
205         } elsif ((($crit_type eq "P") && (100 - $capper) < $crit) || (($crit_type eq "K") && ($avail_bytes > $crit))) {
206                 $state = "WARNING";
207                 $answer = "WARNING: Only $avail ($capper%) free on $mountpt\n";
208         } else {
209                 $state = "CRITICAL";
210                 $answer = "CRITICAL: Only $avail ($capper%) free on $mountpt\n";
211         }
212 } else {
213         $answer = "Result from smbclient not suitable\n";
214         $state = "UNKNOWN";
215         foreach (@lines) {
216                 if (/(Access denied|NT_STATUS_LOGON_FAILURE)/) {
217                         $answer = "Access Denied\n";
218                         $state = "CRITICAL";
219                         last;
220                 }
221                 if (/(Unknown host \w*|Connection.*failed)/) {
222                         $answer = "$1\n";
223                         $state = "CRITICAL";
224                         last;
225                 }
226                 if (/(You specified an invalid share name|NT_STATUS_BAD_NETWORK_NAME)/) {
227                         $answer = "Invalid share name \\\\$host\\$share\n";
228                         $state = "CRITICAL";
229                         last;
230                 }
231         }
235 print $answer;
236 print "$state\n" if ($verbose);
237 exit $ERRORS{$state};
239 sub print_usage () {
240         print "Usage: $PROGNAME -H <host> -s <share> -u <user> -p <password> 
241       -w <warn> -c <crit> [-W <workgroup>] [-P <port>]\n";
244 sub print_help () {
245         print_revision($PROGNAME,'@NP_VERSION@');
246         print "Copyright (c) 2000 Michael Anthon/Karl DeBisschop
248 Perl Check SMB Disk plugin for Nagios
250 ";
251         print_usage();
252         print "
253 -H, --hostname=HOST
254    NetBIOS name of the server
255 -s, --share=STRING
256    Share name to be tested
257 -W, --workgroup=STRING
258    Workgroup or Domain used (Defaults to \"WORKGROUP\")
259 -u, --user=STRING
260    Username to log in to server. (Defaults to \"guest\")
261 -p, --password=STRING
262    Password to log in to server. (Defaults to an empty password)
263 -w, --warning=INTEGER or INTEGER[kMG]
264    Percent of used space at which a warning will be generated (Default: 85%)
265       
266 -c, --critical=INTEGER or INTEGER[kMG]
267    Percent of used space at which a critical will be generated (Defaults: 95%)
268 -P, --port=INTEGER
269    Port to be used to connect to. Some Windows boxes use 139, others 445 (Defaults to smbclient default)
270    
271    If thresholds are followed by either a k, M, or G then check to see if that
272    much disk space is available (kilobytes, Megabytes, Gigabytes)
274    Warning percentage should be less than critical
275    Warning (remaining) disk space should be greater than critical.
277 ";
278         support();