The fundamental building block of all network information systems is a mechanism for performing remote procedure calls. This mechanism, usually called RPC, allows a program running on one computer to more-or-less transparently execute a function that is actually running on another computer.
RPC systems can be categorized as blocking systems, which cause the calling program to cease execution until a result is returned, or as non-blocking (asynchronous systems), which means that the calling program continues running while the remote procedure call is performed. (The results of a non-blocking RPC, if they are returned, are usually provided through some type of callback scheme.)
RPC allows programs to be distributed: a computationally intensive algorithm can be run on a high-speed computer, a remote sensing device can be run on another computer, and the results can be compiled on a third. RPC also makes it easy to create network-based client/server programs: the clients and servers communicate with each other using remote procedure calls.
One of the first UNIX remote procedure call systems was developed by Sun Microsystems for use with NIS and NFS. Sun's RPC uses a system called XDR (external data representation), to represent binary information in a uniform manner and bit order. XDR allows a program running on a computer with one byte order, such as a SPARC workstation, to communicate seamlessly with a program running on a computer with an opposite byte order, such as a workstation with an Intel x86 microprocessor. RPC messages can be sent with either the TCP or UDP IP protocols (currently, the UDP version is more common). After their creation by Sun, XDR and RPC were reimplemented by the University of California at Berkeley and are now freely available.
Sun's RPC is not unique. A different RPC system is used by the Open Software Foundation's Distributed Computing Environment (DCE). Yet another RPC system has been proposed by the Object Management Group. Called CORBA (Common Object Request Broker Architecture), this system is optimized for RPC between object-oriented programs written in C++ or SmallTalk.
In the following sections, we'll discuss the Sun RPC mechanism, as it seems to be the most widely used. The continuing popularity of NFS (described in Chapter 20) suggests that Sun RPC will be in widespread use for some time to come.
For an RPC client to communicate with an RPC server, many things must happen:
The RPC client must be running.
The RPC server must be running on the server machine (or it must be automatically started when the request is received).
The client must know on which host the RPC server is located.
The client and the server must agree to communicate on a particular TCP or UDP port.
The simplest way to satisfy this list of conditions is to have the UNIX computer start the server when the computer boots, to have the server running on a well-known host, and to have the port numbers predefined. This is the approach that UNIX takes with standard Internet services such as Telnet and SMTP.
The approach that Sun took for RPC was different. Instead of having servers run on a well-known port, Sun developed a program called portmap in SunOS 4.x, and renamed rpcbind in Solaris 2.x. We will refer to the program as the portmapper.
When an RPC server starts, it dynamically obtains a free UDP or TCP port, then registers itself with the portmapper. When a client wishes to communicate with a particular server, it contacts the portmapper process, determines the port number used by the server, and then initiates communication.
The portmapper approach has the advantage that you can have many more RPC services (in theory, 232) than there are IP port numbers (216). In practice, however, the greater availability of RPC server numbers has not been very important. Indeed, one of the most widely used RPC services, NFS, usually has a fixed UDP port of 2049.
 Of course, you can't really have 232 RPC services, because there aren't enough programmers to write them, or enough computers and RAM for them to run. The reason for having 232 different RPC service numbers available was that different vendors could pick RPC numbers without the possibility of conflict. A better way to have reached this goal would have been to allow RPC services to use names, so that companies and organizations could have registered their RPC services using their names as part of the service names - but the designers didn't ask us.
The portmapper program also complicates building Internet firewalls, because you almost never know in advance the particular IP port that will be used by RPC-based services.
Client programs contacting an RPC server need a way to authenticate themselves to the server, so that the server can determine what information the client should be able to access, and what functions should be allowed. Without authentication, any client on the network that can send packets to the RPC server could access any function.
There are several different forms of authentication available for RPC, as described in Table 19.1. Not all authentication systems are available in all versions of RPC:
No authentication. Anonymous access.
RPC client sends the UNIX UID and GIDs for the user.
Not secure. Server implicitly trusts that the user is who the user claims to be.
Authentication based on public key cryptography and DES
Reasonably secure, although not widely available from manufacturers other than Sun.
Authentication based on Kerberos
Very secure, but requires that you set up a Kerberos Server (described later in this chapter). As with AUTH_DES, AUTH_KERB is not widely available.
 AUTH_UNIX is called AUTH_SYS in at least one version of Sun Solaris.
Live fast, die young. AUTH_NONE is bare-bones RPC with no user authentication. You might use it for services that require and provide no useful information, such as time of day. On the other hand, why do you want other computers on the network to be able to find out the setting of your's system's time-of-day clock? (Furthermore, because the system's time of day is used in a variety of cryptographic protocols, even that information might be usable in an attack against your computer.)
AUTH_UNIX was the only authentication system provided by Sun through Release 4.0 of the SunOS operating systems, and it is the only form of RPC authentication offered by many UNIX vendors. It is widely used. Unfortunately, it is fundamentally unsecure.
With AUTH_UNIX, each RPC request is accompanied with a UID and a set of GIDS for authentication. The server implicitly trusts the UID and GIDS presented by the client, and uses this information to determine if the action should be allowed or not. Anyone with access to the network can craft an RPC packet with any arbitrary values for UID and GID. Obviously, AUTH_UNIX is not secure, because the client is free to claim any identity, and there is no provision for checking on the part of the server.
 Some versions of RPC present eight additional GIDs, while others present up to 16.
In recent years, Sun has changed the name AUTH_UNIX to AUTH_SYS. Nevertheless, it's still the same system.
AUTH_DES is the basis of Sun's "Secure RPC" (described later in this chapter). AUTH_DES uses a combination of secret key and public key cryptography to allow security in a networked environment. It was developed several years after AUTH_UNIX, and is not widely available on UNIX platforms other than Sun's SunOS and Solaris 2.x operating systems.
AUTH_KERB is a modification to Sun's RPC system that allows it to interoperate with MIT's Kerberos system for authentication. Although Kerberos was developed in the mid 1980s, AUTH_KERB authentication for RPC was not incorporated into Sun's RPC until the early 1990s.
NOTE: Carefully review the RPC services that are configured into your system for automatic start when the system boots, or for automatic dispatch from the inetd (see Chapter 17, TCP/IP Services). If you don't need a service, disable it.
In particular, if your version of the rexd service cannot be forced into only accepting connections authenticated with Kerberos or Secure RPC, then it should be turned off. The rexd daemon (which executes commands issued with the on command) otherwise is easily fooled into executing commands on behalf of any non-root user.