Understanding user identities within Unix-like operating systems is fundamental for anyone involved in system administration, security, or application development. The intricate interplay between the Real User ID (RUID), Effective User ID (EUID), and Saved User ID (SUID) dictates how processes access resources and manage privileges. Grasping the subtle yet critical difference between Real User ID, Effective User ID and Saved User ID is not just academic; it’s essential for preventing security vulnerabilities, managing access control effectively, and ensuring the stable operation of your systems. This article delves into each of these identifiers, elucidating their purpose, functionality, and the crucial distinctions that define their roles in the modern computing environment.
The Foundation: Real User ID (RUID)
The Real User ID (RUID) represents the true identity of the user who initially created or launched a process. This ID is assigned at the moment a user logs in or executes a program, and it generally remains constant throughout the process’s lifecycle. It acts as the primary identifier, establishing the ownership of the process and, by extension, linking it back to the actual human user or system account responsible for its initiation. Think of the RUID as the “who” behind the action.
For instance, when you log into a Linux terminal, your shell process and any subsequent commands you run will inherit your RUID. If your username is “john.doe” and your User ID (UID) is 1001, then all processes directly initiated by you will have an RUID of 1001. This persistent identification is crucial for auditing and accountability, allowing system administrators to trace actions back to their original source. It provides a foundational layer of accountability, ensuring that even when a process temporarily gains elevated privileges, its original identity is always discernible.
The RUID is primarily used by the kernel to determine which user should be billed for system resources, like CPU time and memory usage. It also plays a role in signal handling, as a process can only send signals to other processes that share the same RUID (unless it has special privileges). This mechanism helps prevent users from arbitrarily terminating or interfering with processes belonging to other users on a multi-user system. As noted by the Linux man page for getuid(2), the RUID is immutable by an unprivileged process, reinforcing its role as the unchangeable origin.
Dynamic Permissions: Effective User ID (EUID)
The Effective User ID (EUID) is perhaps the most critical of the three when it comes to determining a process’s actual permissions and access rights to system resources, such as files, directories, and other processes. While the RUID identifies who started the process, the EUID dictates what that process is currently allowed to do. This ID is dynamic and can change during a process’s execution, particularly when dealing with special programs.
The most common scenario where the EUID differs from the RUID is with “set-user-ID” (setuid) programs. These are executable files that have a special permission bit set, allowing them to run with the privileges of the file’s owner, rather than the user who executed them. A prime example is the passwd command. When a regular user executes passwd to change their password, the program needs to write to a system file (/etc/shadow) that is typically only writable by the root user. In this case, the passwd executable’s owner is root, and the setuid bit causes the process’s EUID to temporarily become 0 (root’s UID), even though the RUID remains the actual user’s UID. This temporary privilege elevation is precisely why understanding the EUID is paramount for system security and secure coding practices.
The EUID is the ID that the operating system uses for nearly all access control decisions. When a process attempts to open a file, create a directory, or send a signal, the kernel checks the EUID against the permissions of the target resource. This mechanism allows for controlled privilege escalation, enabling less-privileged users to perform specific, privileged tasks without granting them full root access. However, this power also comes with significant security implications; vulnerabilities in setuid programs are a common vector for privilege escalation attacks, making careful development and auditing of such programs essential.
The Saved User ID (SUID) acts as a crucial safety net and a mechanism for temporary privilege management. When a setuid program is executed, and its EUID is changed from the RUID (e.g., to root), the original EUID (which was the RUID) is copied and saved into the SUID. This means the SUID typically holds the value of the EUID before any privilege changes occurred due to the setuid bit.
The primary purpose of the SUID is to allow a privileged program (one running with an elevated EUID, like root) to temporarily drop its privileges to a less-privileged state (often back to the RUID) and then later regain its elevated privileges without requiring another setuid execution. This is a vital security best practice. A program should run with the minimum necessary privileges for the shortest possible time. If a root-privileged program needs to perform a non-privileged task, it can drop its EUID to the SUID (or even the RUID) to reduce the attack surface. If it then needs to perform another privileged task, it can restore its EUID from the SUID, effectively regaining its root privileges. This prevents the need to reload the program or use complex privilege management schemes.
Consider the sudo command, a complex example of UID management. While sudo itself is a setuid-root program, it carefully manages UIDs to execute commands as other users. A simpler illustration is a custom setuid-root application that needs to read a configuration file (privileged operation) but then interact with network resources (non-privileged, potentially dangerous). The program would:
- Start with RUID=user, EUID=root (due to setuid), SUID=user.
- Read configuration file (using root EUID).
- Drop privileges: set EUID back to SUID (user). Now EUID=user.
- Perform network operations (as user).
- If needed, restore privileges: set EUID to SUID (root, if SUID was initially root, or if SUID was set to root after an initial privilege drop). This step is more nuanced and often involves setting EUID to RUID, then to SUID, or carefully using setresuid to manage all three IDs.
This careful dance ensures that the program only holds root privileges when absolutely necessary, significantly reducing the window for potential exploits. The Critical Difference between Real User ID, Effective User ID and Saved User ID: Interactions and Security
The core difference between Real User ID, Effective User ID and Saved User ID lies in their roles during process execution and privilege management. The RUID is Question & Answer :
I am already aware of the real user id. It is the unique number for a user in the system.
On my system, my uid is
$ echo $UID 1014 $
What do the other two IDs stands for?
And what is the use of effective user id and saved user id and where do we use them in the system?
The distinction between a real and an effective user id is made because you may have the need to temporarily take another user’s identity (most of the time, that would be root, but it could be any user). If you only had one user id, then there would be no way of changing back to your original user id afterwards (other than taking your word for granted, and in case you are root, using root’s privileges to change to any user).
So, the real user id is who you really are (the one who owns the process), and the effective user id is what the operating system looks at to make a decision whether or not you are allowed to do something (most of the time, there are some exceptions).
When you log in, the login shell sets both the real and effective user id to the same value (your real user id) as supplied by the password file.
Now, it also happens that you execute a setuid program, and besides running as another user (e.g. root) the setuid program is also supposed to do something on your behalf. How does this work?
After executing the setuid program, it will have your real id (since you’re the process owner) and the effective user id of the file owner (for example root) since it is setuid.
The program does whatever magic it needs to do with superuser privileges and then wants to do something on your behalf. That means, attempting to do something that you shouldn’t be able to do should fail. How does it do that? Well, obviously by changing its effective user id to the real user id!
Now that setuid program has no way of switching back since all the kernel knows is your id and… your id. Bang, you’re dead.
This is what the saved set-user id is for.