RCMD(3X) — Series 300 and 800 Only
NAME
rcmd, rresvport, ruserok − return a stream to a remote command
SYNOPSIS
#include <sys/types.h>
int rem;
rem = rcmd(ahost, inport, locuser, remuser, cmd, fd2p);
char **ahost;
u_short inport;
char *locuser, *remuser, *cmd;
int *fd2p;
int s;
s = rresvport(port);
int *port;
ruserok(rhost, superuser, ruser, luser);
char *rhost;
int superuser;
char *ruser, *luser;
DESCRIPTION
Rcmd is a routine used by the super-user to execute a command on a remote host using an authentication scheme based on reserved port numbers. The name of the remote host can be either an official host name or an alias as listed in /etc/hosts; see hosts(4). Rresvport is a routine which returns a descriptor to a socket with an address in the privileged port space. Ruserok is a routine used by servers to authenticate clients requesting service with rcmd.
Any program using rcmd or rresvport needs to have super-user privileges. Rcmd looks up the host *ahost using gethostbyname(3N), returning −1 if the host does not exist. Otherwise ∗ahost is set to the standard name of the host and a connection is established to a server residing at the internet port inport. If the connection is refused after five tries or if it was refused for a reason other than the port being in use, then rcmd returns a −1.
If the call succeeds, a socket of type SOCK_STREAM is returned to the caller, and given to the remote command as stdin and stdout. If fd2p is non-zero, then an auxiliary connection to a control process is set up, and a descriptor for it is placed in ∗fd2p. The control process returns diagnostic output from the command on this connection, and also accepts bytes on this connection as UNIX signal numbers, to be forwarded to the process group of the command. If the auxiliary port cannot be set up, then rcmd returns a −1. If fd2p is 0, then stderr of the remote command is made the same as stdout and no provision is made for sending arbitrary signals to the remote process.
The protocol is described in detail in remshd(1M).
The rresvport routine is used to obtain a socket with a privileged address bound to it. This socket is suitable for use by rcmd and several other routines. Privileged addresses consist of a port in the range 0 to 1023. Only the super-user is allowed to bind an address of this sort to a socket.
Ruserok takes a remote host’s name, as returned by a gethostent(3N) routine, two user names and a flag indicating if the local user’s name is the super-user. It then checks the files /etc/hosts.equiv and possibly .rhosts in the local user’s home directory to see if the request for service is allowed; see hosts.equiv(4). Ruserok returns a 0 if the remote hostname is listed in /etc/hosts.equiv, or if the remote host and user name are found in $HOME/.rhosts; otherwise ruserok returns −1. If the superuser flag is set, /etc/host.equiv is bypassed.
DIAGNOSTICS
Rcmd Diagnostic Messages
The diagnostic messages rcmd returns are:
<hostname>: Unknown host
Rcmd was unable to find an entry in the host database file /etc/hosts matching the address of the server; see hosts(4).
Next step: Have the system administrator of your host check whether the remote host’s entry is in /etc/hosts.
connect: <hostname>: ...
Unable to establish a connection to the reserved port. A message which specifies the reason for the failure is appended to this diagnostic message.
write: Setting up stderr
Error writing to the socket connection set up for error message transmission.
<system call>: ...
Error executing the system call. Appended to this error is a message specifying the reason for the failure.
socket: Protocol failure in circuit setup
Socket connection not established on a reserved port or socket address not of the internet family type.
read: <hostname>: ....
Error reading the information from the standard socket connection. Appended to this error is a message explaining the reason for the error.
Connection timeout
The remote host did not connect within 30 seconds to the secondary socket set up as an error connection.
Lost connection
The program attempts to read from the socket and fails. This means the socket connection with the remote host was lost.
<Message>
An error message can be transmitted through the socket connection from the daemon. That message will be sent to stderr.
primary connection shutdown
While waiting for the secondary socket to be set up, rcmd had its primary connection shut down. This may have been caused by an inetd security failure.
recv: <system error message>
While trying to set up the secondary ( stderr) socket, rcmd had an error condition on its primary connection.
accept: Interrupted system call
While trying to set up its secondary socket, rcmd ran out of some resource which caused the accept to be timed out.
Next step: Repeat the command.
Rcmd and Rresvport Diagnostic Messages
The diagnostic messages associated with rresvport can also appear in rcmd since rcmd calls rresvport. They are the following:
<system call>:...
Error in executing the system call. The error message returned by the system call is appended to the message.
socket: All ports in use
All reserved ports in use. If a timeout occurs, check whether the ARPA Services are installed and the inetd is running.
EXAMPLE
To execute the command date on the remote host “hpxzgy” using the remote account “chm”, you can use rcmd as shown below. This program needs to have super-user privileges and the remote account needs to be equivalent (see hosts.equiv(4)) to the local account that runs the program.
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <pwd.h>
struct passwd ∗getpwuid();
char *host[] = { "hpxzgy" };
char *cmd = "date";
char *ruser = "chm";
main(argv,argc)
char **argv;
int argc;
{
struct servent *sp;
struct passwd *pwd;
FILE *fp;
char ch;
int rem;
sp = getservbyname("shell","tcp");
pwd = getpwuid(getuid());
rem = rcmd(host, sp->s_port, pwd->pw_name, ruser, cmd, 0);
if (rem < 0)
exit(1); /* rcmd outputs its own error messages */
fp = fdopen(rem, "r");
while ((ch = getc(fp)) != EOF)
putchar(ch);
}
WARNINGS
There is no way to specify options to the socket call which rcmd makes. Since rcmd replaces the pointer to the hostname ( *ahost) with a pointer to the standard name of the host in a static data area, this value must be copied into the user’s data area if it is to be used later. If the user does not save this hostname, unpredictable results may occur when using this pointer with the BSD IPC network library routines.
DEPENDENCIES
Implemented on the Series 300 and 800 only.
AUTHOR
UCB (University of California at Berkeley)
SEE ALSO
rexecd(1M), rlogin(1), remsh(1), rexec(3X), rlogind(1M), remshd(1M).
Hewlett-Packard Company — May 11, 2021