Category: Utilitiy Scripts
Author/Contact Info Shendal
Description: Does exactly what rexec does. Communicates to an rexecd on a host and returns the results. This is a good tutorial on how to use Socket as well as extending an existing unix tool, rexec.
#!/usr/bin/perl -- # -*-Perl-*-
#
# rexec.pl
#
# a simple rexec program
#

# library for sockets
use Socket;

# constants and defaults
$|      = 1;
$user   = getlogin || (getpwuid($<))[0] || die "Unable to get username
+!";
$remote = 'machine.domain';
$port   = getservbyname('exec','tcp');
$usage  = "
Usage: rexec.pl [options] command

Options:
 -?    print this help screen and exit
 -v    verbose output mode
 -u <username>
       specify username (default: $user)
 -h <hostname>
       specify host (default: $remote)
 -p <password>
       specify a password to use
Notes:
 It is a good idea to enclose your command in single
 quotes to avoid shell interpretation.

";

# parse options
while ($_ = shift @ARGV) {
    if (/^-\?$/) { print $usage; exit; }
    if (/^-v$/)  { $verbose = 1; next; }
    if (/^-u$/)  { $user   = shift or die "Error: Missing username"; n
+ext; }
    if (/^-h$/)  { $remote = shift or die "Error: Missing hostname"; n
+ext; }
    if (/^-p$/)  { $passwd = shift or die "Error: Missing password"; n
+ext; }
    $cmd = join ' ',($_,@ARGV);
    last;
}

# if we don't have a command, we must have not gotten the right option
+s
if (! $cmd) {
    print "Error: Missing command\n";
    print $usage;
    exit;
}

# get password (without echoing it back to the screen)
if (! $passwd ) {
    print "Password:";
    system("stty -echo");
    chomp($passwd = <STDIN>);
    system("stty echo");
    print "\n";
}
die "Error: No password" unless $passwd;

# die if we don't have a port
die "Error: No port" unless $port;

# get some info
$iaddr = inet_aton($remote) or die "inet_aton: $!"; # host ip (packed)
$paddr = sockaddr_in($port, $iaddr);                # port address (pa
+cked)
$proto = getprotobyname('tcp');                     # protocol number

# open the socket
socket(SOCK, PF_INET, SOCK_STREAM, $proto) or die "socket: $!";
connect(SOCK, $paddr)                      or die "connect: $!";

# If we're verbose, print out what we're going to rexec
print "CMD: $cmd\n" if ($verbose);

# build our command and send it
$string = "$port\0$user\0$passwd\0$cmd\0";
send(SOCK,$string,0,$remote) or die "send: $!";

# get any info back
print "Listening for response...\n";
while ($line = <SOCK>) { print $line; }

# put up our toy and exit nicely
print "\nClosing connection...\n";
sleep 2;
shutdown(SOCK,2);
close(SOCK);
exit 0;