Code

debian bts #268044:
[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_P $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          "P=s" => \$opt_P, "port=s"     => \$opt_P,
44          "V"   => \$opt_V, "version"    => \$opt_V,
45          "h"   => \$opt_h, "help"       => \$opt_h,
46          "w=s" => \$opt_w, "warning=s"  => \$opt_w,
47          "c=s" => \$opt_c, "critical=s" => \$opt_c,
48          "p=s" => \$opt_p, "password=s" => \$opt_p,
49          "u=s" => \$opt_u, "username=s" => \$opt_u,
50          "s=s" => \$opt_s, "share=s"    => \$opt_s,
51          "W=s" => \$opt_W, "workgroup=s" => \$opt_W,
52          "H=s" => \$opt_H, "hostname=s" => \$opt_H);
54 if ($opt_V) {
55         print_revision($PROGNAME,'$Revision$'); #'
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 # end of options checking
148 my $state = "OK";
149 my $answer = undef;
150 my $res = undef;
151 my @lines = undef;
153 # Just in case of problems, let's not hang Nagios
154 $SIG{'ALRM'} = sub { 
155         print "No Answer from Client\n";
156         exit $ERRORS{"UNKNOWN"};
157 };
158 alarm($TIMEOUT);
160 # Execute an "ls" on the share using smbclient program
161 # get the results into $res
162 if (defined($workgroup)) {
163         $res = qx/$smbclient \/\/$host\/$share -W $workgroup -U $user%$pass $smbclientoptions -c ls/;
164 } else {
165         print "$smbclient " . "\/\/$host\/$share" ." $pass -U $user $smbclientoptions -c ls\n" if ($verbose);
166         $res = qx/$smbclient \/\/$host\/$share -U $user%$pass $smbclientoptions -c ls/;
168 #Turn off alarm
169 alarm(0);
171 #Split $res into an array of lines
172 @lines = split /\n/, $res;
174 #Get the last line into $_
175 $_ = $lines[$#lines];
176 #print "$_\n";
178 #Process the last line to get free space.  
179 #If line does not match required regexp, return an UNKNOWN error
180 if (/\s*(\d*) blocks of size (\d*)\. (\d*) blocks available/) {
182         my ($avail) = ($3*$2)/1024;
183         my ($avail_bytes) = $avail;
184         my ($capper) = int(($3/$1)*100);
185         my ($mountpt) = "\\\\$host\\$share";
188         if (int($avail / 1024) > 0) {
189                 $avail = int($avail / 1024);
190                 if (int($avail /1024) > 0) {
191                         $avail = (int(($avail / 1024)*100))/100;
192                         $avail = $avail ."G";
193                 } else {
194                         $avail = $avail ."M";
195                 }
196         } else {
197                 $avail = $avail ."K";
198         }
200 #print ":$warn:$warn_type:\n";
201 #print ":$crit:$crit_type:\n";
202 #print ":$avail:$avail_bytes:$capper:$mountpt:\n";
204         if ((($warn_type eq "P") && (100 - $capper) < $warn) || (($warn_type eq "K") && ($avail_bytes > $warn))) { 
205                 $answer = "Disk ok - $avail ($capper%) free on $mountpt\n";
206         } elsif ((($crit_type eq "P") && (100 - $capper) < $crit) || (($crit_type eq "K") && ($avail_bytes > $crit))) {
207                 $state = "WARNING";
208                 $answer = "WARNING: Only $avail ($capper%) free on $mountpt\n";
209         } else {
210                 $state = "CRITICAL";
211                 $answer = "CRITICAL: Only $avail ($capper%) free on $mountpt\n";
212         }
213 } else {
214         $answer = "Result from smbclient not suitable\n";
215         $state = "UNKNOWN";
216         foreach (@lines) {
217                 if (/(Access denied|NT_STATUS_LOGON_FAILURE)/) {
218                         $answer = "Access Denied\n";
219                         $state = "CRITICAL";
220                         last;
221                 }
222                 if (/(Unknown host \w*|Connection.*failed)/) {
223                         $answer = "$1\n";
224                         $state = "CRITICAL";
225                         last;
226                 }
227                 if (/(You specified an invalid share name|NT_STATUS_BAD_NETWORK_NAME)/) {
228                         $answer = "Invalid share name \\\\$host\\$share\n";
229                         $state = "CRITICAL";
230                         last;
231                 }
232         }
236 print $answer;
237 print "$state\n" if ($verbose);
238 exit $ERRORS{$state};
240 sub print_usage () {
241         print "Usage: $PROGNAME -H <host> -s <share> -u <user> -p <password> 
242       -w <warn> -c <crit> [-W <workgroup>] [-P <port>]\n";
245 sub print_help () {
246         print_revision($PROGNAME,'$Revision$');
247         print "Copyright (c) 2000 Michael Anthon/Karl DeBisschop
249 Perl Check SMB Disk plugin for Nagios
251 ";
252         print_usage();
253         print "
254 -H, --hostname=HOST
255    NetBIOS name of the server
256 -s, --share=STRING
257    Share name to be tested
258 -W, --workgroup=STRING
259    Workgroup or Domain used (Defaults to \"WORKGROUP\")
260 -u, --user=STRING
261    Username to log in to server. (Defaults to \"guest\")
262 -p, --password=STRING
263    Password to log in to server. (Defaults to an empty password)
264 -w, --warning=INTEGER or INTEGER[kMG]
265    Percent of used space at which a warning will be generated (Default: 85%)
266       
267 -c, --critical=INTEGER or INTEGER[kMG]
268    Percent of used space at which a critical will be generated (Defaults: 95%)
269 -P, --port=INTEGER
270    Port to be used to connect to. Some Windows boxes use 139, others 445 (Defaults to smbclient default)
271    
272    If thresholds are followed by either a k, M, or G then check to see if that
273    much disk space is available (kilobytes, Megabytes, Gigabytes)
275    Warning percentage should be less than critical
276    Warning (remaining) disk space should be greater than critical.
278 ";
279         support();