Example of passing File Descriptors in Unix

Here's a rather complex example of the file descriptor passing mechanism in Linux and other Unix-like systems. I'm not sure what Unix dialects will run this; I've concentrated on Linux.

The example is a bit more complex than a mere example of file descriptor passing. It's meant to illustrate a specific use of the mechanism, namely to make it possible for a non-root process to use TCP sockets locally bound to low port numbers, by using a "file descriptor factory" that runs as root and does nothing but generate sockets for other, non-root processes.

This package contains two programs; a server that listens to a specific port and echoes back whatever is sent to it, and a client that forks off a non-privileged process, creates (as root) a socket bound to a specific port and sends it to the non-privileged process, which uses the socket to connect to the server.

Thus, if we instruct the client program to bind to a low port - say "8" - it will effectively be able to get a socket bound to this port without running as root, without creating the socket before forking.

The procedure for demonstrating this is as follows:

First, start the server process, to listen to port 8192:

hansl@hansl$ ./server  -p 8192 -a 127.0.0.1

Then, run the client as root and tell it to setuid() to a non-root user (here UID=1000), and to use a socket bound locally to a low port (here port 8). We also supply some test data to send to the server.

root@hansl# ./client -p 8 -A 127.0.0.1 -P 8192 -d fdehwudfhweqio -u 1000
Server: sent fd=4
Client (uid=1000): received fd=3
Sent "fdehwudfhweqio". Received "fdehwudfhweqio".

On the server side, we can verify that the connect indeed came from port 8:

Connection from 127.0.0.1 port 8 to 127.0.0.1 port 8192, received "fdehwudfhweqio".
AttachmentSize
passfd-1.1.tar.gz43.88 KB