There are several ways to set the owner of a network service: (1) the service can be configured to run as a pseudo user (e.g., apache) with enough privileges to satisfy any request. (2) the service may need user authentication to ensure that it is a valid user (e.g., for mail relay), but all users are treated identically. This service too can be owned by a pseudo user. (3) the service provided depends on the user, who therefore must be authenticated--it is usually appropriate that the service process be owned by its user (i.e., UBNS).
A UBNS service (a process run under the user's ID) performs the following steps: (a) it accepts a connection, (b) performs user authentication to identify the user requesting the service, (c) creates a new process, and (d) changes the ownership of the process to the authenticated user. Once the ownership of the process is changed to the user, it cannot be used by anyone else.
We next examine how this general paradigm is performed in Unix and then in netAuth.
Figure 3 shows the call sequence for implementing a user authenticated service using UNIX socket APIs. The client creates a socket (socket), connects to the server (connect), and then does a series of sends and receives (send/recv), and when its done closes the socket.
The server creates a socket (socket), associates it with a network address on the server (bind), allocates a pending queue of connection requests (listen), waits for a new connection request to arrive (accept). To perform UBNS, it spawns a process (fork), and after determining the user via network messages (not shown) it then changes the owner of the process (setuid). At this point the newly created service process is operating as the user. It communicates back and forth with the client and then closes the connection. Since there is typically no way to reuse the process after it closes the socket, it exits.
Figure 4 shows the equivalent sequencing for netAuth. On the client side, the only programming change needed to adapt to netAuth is to replace connect with connect_by_user (of course, the application-level authentication must be removed).
On the server side, netAuth basically splits the accept for a new connection into two phases:
The change of ownership of the process is performed by set_net_user. The set_net_user changes the owner of the process to the authenticated user and consumes the netAuthenticate privilege for that process. Thus, set_net_user serves as a highly restricted version of setuid, and is far safer to use.
Manigandan Radhakrishnan 2008-05-13