This section addresses a critical security feature of Unix Domain Sockets: Authentication.

In a TCP/IP connection, the server knows the client’s IP address, but that doesn’t tell you which user on that machine is connecting. With Unix Domain Sockets, because the kernel manages both ends of the connection, the server can ask the kernel: “Who is on the other end of this socket?”

This capability allows a server to verify the User ID (UID) and Group ID (GID) of the client without requiring a password. This is how many system services (like the system logging daemon) verify that a command is coming from a privileged user (like root).

1. How it works (The SCM_CREDS Mechanism)

Just like passing file descriptors in Section 15.7, credentials are passed as Ancillary Data using recvmsg().

The specific implementation varies heavily between operating systems (e.g., Linux uses SCM_CREDENTIALS or SO_PEERCRED, while FreeBSD uses SCM_CREDS). The textbook focuses on the FreeBSD/BSD implementation (SCM_CREDS) as its primary example.

The Process:

  1. The Client: Sends a message and includes a cmsghdr (control message header) with the type SCM_CREDS. The client does not fill in the data. If the client filled in “I am Root,” they could lie.Instead, the client just sends the “empty container.”
  2. The Kernel: Intercepts the message, looks at the process sending it, and fills in the correct credentials (UID, GID, etc.) into the structure.
  3. The Server: Receives the message, reads the ancillary data, and trusts it because the kernel wrote it.
2. The Credential Structure (struct cmsgcred)

On the BSD systems described in the text, the credentials arrive in this structure:

struct cmsgcred {
    pid_t cmcred_pid;     /* PID of sending process */
    uid_t cmcred_uid;     /* real UID of sending process */
    uid_t cmcred_euid;    /* effective UID of sending process */
    gid_t cmcred_gid;     /* real GID of sending process */
    short cmcred_ngroups; /* number of groups */
    gid_t cmcred_groups[CMGROUP_MAX]; /* groups */ //<--- Initializer for Member 1 ONLY
};
3. Example: The Unix Stream Server (Figure 15.15)

The book modifies the earlier echo server to check these credentials.

  • Helper Function (read_cred): The text introduces a wrapper function similar to read_fd. It calls recvmsg and looks specifically fr the SCM_CREDS control message.
  • Verification:
if (user_cred.cmcred_uid == 0) {
	printf("Welcome, Root User!\n");
} else {
	printf("Client UID is %d\n", user_cred.cmcred_uid);
}
4. Why is this important?

This mechanism allows for Zero-Knowledge Authentication.

  • The user doesn’t type a password.
  • The client program doesn’t need to hold a secret key.
  • The security is guaranteed by the operating system kernel itself.