diff options
Diffstat (limited to 'devtools/bin/vmpi_chpass.pl')
| -rw-r--r-- | devtools/bin/vmpi_chpass.pl | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/devtools/bin/vmpi_chpass.pl b/devtools/bin/vmpi_chpass.pl new file mode 100644 index 0000000..12ccf8a --- /dev/null +++ b/devtools/bin/vmpi_chpass.pl @@ -0,0 +1,116 @@ +#!/usr/bin/perl -w +use IO::Socket::INET; +use Sys::Hostname; +use Data::Dumper; +use Getopt::Long; +use Pod::Usage; +use strict; + +use constant VMPI_PROTOCOL_VERSION => 5; + +use constant VMPI_MESSAGE_BASE => 71; +use constant VMPI_PING_REQUEST => VMPI_MESSAGE_BASE+2; +use constant VMPI_PING_RESPONSE => VMPI_MESSAGE_BASE+3; +use constant VMPI_FORCE_PASSWORD_CHANGE => VMPI_MESSAGE_BASE+11; + +use constant VMPI_PASSWORD_OVERRIDE => -111; + +use constant VMPI_SERVICE_PORT => 23397; +use constant VMPI_LAST_SERVICE_PORT => VMPI_SERVICE_PORT + 15; + +my $list = undef; +my $pass = ""; +my $help = 0; +my $man = 0; + +GetOptions("file=s" => \$list, + "pass=s" => \$pass, + "help|?" => \$help, + "man" => \$man) or pod2usage(1); +pod2usage(2) if $help; +pod2usage(-exitstatus=>0, -verbose=>2) if $man; + +my @machines = @ARGV; +if ($list) { + if (open(my $listfh, $list)) { + while(my $line = <$listfh>) { + chomp($line); + next unless $line =~ /\S/; + push @machines, $line; + } + } +} + +if (!@machines) { + warn "No machines specified\n"; + pod2usage(3); +} + +my $message = BuildMessage(VMPI_PROTOCOL_VERSION, VMPI_FORCE_PASSWORD_CHANGE); +$message .= pack("Z*", $pass); +my $length = length($message); + +my $socket = CreateSocket(); +# send the message 3 times to make sure it gets it +for (1..3) { + for my $host (@machines) { + SendMessage($socket, $host, $message); + } + sleep(1); +} + + +sub CreateSocket { + return IO::Socket::INET->new(Proto=>'udp'); +} + +sub BuildMessage { + my $ver = shift; + my $type = shift; + + my $message = pack("CcCC", $ver, VMPI_PASSWORD_OVERRIDE, 0, $type); + return $message; +} + +sub SendMessage { + my $socket = shift; + my $host = shift; + my $message = shift; + + my $ip = gethostbyname($host); + if (!$ip) { + warn "Can't resolve: $host\n"; + return; + } + + for my $port (VMPI_SERVICE_PORT..VMPI_LAST_SERVICE_PORT) { + my $ipaddr = sockaddr_in($port, $ip); + defined(send($socket, $message, 0, $ipaddr)) || warn("SEND: $!\n"); + } +} + +__END__ + +=head1 NAME + +vmpi_chpass.pl - Sets the VMPI password on a set of machines + +=head1 SYNOPSIS + +vmpi_chpass.pl [-pass <password>] [-help|-?] [-man] + -file <host file> | <host> ... + + Options: + -file A file that contains the names of machines to use + -pass Password to set + -help|-? Display command line usage + -man Display full documentation + +=head1 DESCRIPTION + +B<vmpi_chpass.pl> sets the password on the given list of machines. The +machines can be given as separate arguments on the command line or as +a list in a text file. If the password is not given, the password is +removed from the machines, opening them up for general use. + +=cut |