mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-22 14:16:50 +00:00
117 lines
2.6 KiB
Perl
117 lines
2.6 KiB
Perl
|
#!/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
|