#!/usr/bin/perl -w # Copyright 2010, Tomas Edwardsson # check_cifs is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # check_cifs is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . use strict; use Nagios::Plugin; # Create the Nagios plugin object my $np = Nagios::Plugin->new( usage => "Usage: %s -H -u -p -s ", version => "1.0", ); # Add valid arguments $np->add_arg( spec => 'hostname|H=s', help => '-H, --hostname=', required => 1, ); $np->add_arg( spec => 'username|u=s', help => '-u, --username=', required => 1, ); $np->add_arg( spec => 'password|p=s', help => '-p, --password=', required => 1, ); $np->add_arg( spec => 'share|s=s', help => '-s, --share=', required => 1, ); $np->add_arg( spec => 'kerberos|k', help => '-k, --kerberos', required => 0, ); $np->add_arg( spec => 'writefile|w=s', help => '-w, --writefile=', required => 0, ); $np->add_arg( spec => 'writesize|W=i', help => '-W, --writesize=', required => 0, default => 10 ); my @tmpfiles = (); sub createtmpfile($) { my $size = shift; $size = 10 if (!defined $size); $np->nagios_exit(UNKNOWN, "Size for param writesize not numeric") if ($size !~ /^\d+$/); my $tmpfile = `mktemp check-cifs-XXXXXX -p /tmp`; my $rc = $? >> 8; chomp($tmpfile); push @tmpfiles, $tmpfile; if ($rc) { $np->nagios_exit(UNKNOWN, "Unable to run mktemp for temporary file"); } open TMP, ">$tmpfile" or $np->nagios_exit(UNKNOWN, "Cannot open tempfile for writing: $!"); for (1..$size) { print TMP "0"x(1024*1024); } close TMP; return $tmpfile; } sub testbin($) { my $program = shift; eval { system("$program &> /dev/null"); }; my $exit_value = $? >> 8; if ($exit_value != 127) { return 0; } else { $np->nagios_exit(UNKNOWN, "Could not execute $program"); } } # Check needed binaries testbin("smbclient"); testbin("kinit"); testbin("kdestroy"); # Parse command line operations $np->getopts; # Initialize global for kerberos credentials cache my $krb5cc = ""; # Login with kerberos if ($np->opts->kerberos) { # Cache saved to temporary file too avoid clashed with # other plugins $krb5cc = createtmpfile(0); # Execute kinit kerberised login my $kcmd = sprintf("echo '%s' | kinit -c %s '%s' 2>&1", $np->opts->password, $krb5cc, $np->opts->username); my $kinit = `$kcmd`; my $exit_value = $? >> 8; # Check return code for failures if ($exit_value != 0) { chomp $kinit; $np->nagios_exit(CRITICAL, "Unable to log in with kerberos - $kinit"); } } # Array of arguments for smbclient based on various circumstances my @smbclient_opts; my @smbclient_commands; # Set servicename push @smbclient_opts, sprintf("//%s/%s", $np->opts->hostname, $np->opts->share); # Kerberised or NTLM ? if ($np->opts->kerberos) { push @smbclient_opts, '-k' } else { push @smbclient_opts, "'" . $np->opts->password . "'", '-U', "'" . $np->opts->username . "'", } # We want to test writing a file to the remote share if ($np->opts->writefile) { my $tmpfile = createtmpfile($np->opts->writesize); my $cmd = ($krb5cc ? "KRB5CCNAME=$krb5cc " : "") . "smbclient " . join(" ", @smbclient_opts) . " -c 'put $tmpfile " . $np->opts->writefile . "' 2>&1 |"; open SMBCLIENT, $cmd or $np->nagios_exit(CRITICAL, "Unable to run CIFS connection: $!"); # Toss header ; my $return = ; chomp($return); if ($return =~ /^putting file \S+? as \S+? \((\d+\.\d*) /) { close SMBCLIENT; $np->add_perfdata( label => "file_transfer", value => $1, uom => "KBps" ); $np->nagios_exit(OK, "Connected and uploaded file at rate of $1" . ($np->opts->kerberos ? " (kerberised)" : "")); } else { close SMBCLIENT; $np->nagios_exit(CRITICAL, "Unable to upload file" . ($np->opts->kerberos ? " (kerberised)" : "") . ": $return"); } # Just a regular connection test } else { my $cmd = ($krb5cc ? "KRB5CCNAME=$krb5cc " : "") . "smbclient " . join(" ", @smbclient_opts) . " -c '' 2>&1 |"; open SMBCLIENT, $cmd or $np->nagios_exit(CRITICAL, "Unable to run CIFS connection: $!"); # Toss header ; my $nterror = ; close SMBCLIENT; chomp($nterror) if ($nterror); if ($nterror) { $np->nagios_exit(CRITICAL, "Unable to connect to share" . ($np->opts->kerberos ? " (kerberised)" : "") . ": $nterror"); } $np->nagios_exit(OK, "Connected successfully" . ($np->opts->kerberos ? " (kerberised)" : "")); } # Hack to remove the krb5 credentials file if we have exited END { if (@tmpfiles) { foreach my $f (@tmpfiles) { if (-f $f) { unlink $f; } } } };