Every process really has two user IDs: the effective user ID and the real user ID.
Most of the time, the kernel checks only the effective user ID. For example, if a process tries to open a file, the kernel checks the effective user ID when deciding whether to let the process access the file.
The geteuid and getegid functions described previously return the effective user ID and the effective group ID. Corresponding getuid and getgid functions return the real user ID and real group ID.
There is one very important case in which the real user ID matters. If you want to change the effective user ID of an already running process, the kernel looks at the real user ID as well as the effective user ID.
Suppose that there's a server process that might need to look at any file on the system, regardless of the user who created it.
The server process could carefully examine the permissions associated with the files in question and try to decide whether user should be allowed to access those files.
But that would mean duplicating all the processing that the kernel would normally do to check file access permissions. Reimplementing that logic would be complex, errorprone, and tedious.
A better approach is simply to temporarily change the effective user ID of the process from root to user and then try to perform the operations required.
If user is not allowed to access the data, the kernel will prevent the process from doing so and will return appropriate indications of error.
After all the operations taken on behalf of user are complete, the process can restore its original effective user ID to root.
When the user enters a username and password, the login program verifies the username and password in the system password database.
Then the login program changes both the effective user ID and the real ID to be that of the user.
Finally, the login program calls exec to start the user's shell, leaving the user running a shell whose effective user ID and real user ID are that of the user.
The function used to change the user IDs for a process is setreuid.
setreuid (geteuid(), getuid ());
If a process were allowed to change its effective user ID at will, then any user could easily impersonate any other user, simply by changing the effective user ID of one of his processes.
The kernel will let a process running with an effective user ID of 0 change its user IDs as it sees fit.
Any other process, however, can do only one of the following things:
Set its effective user ID to be the same as its real user ID.
Would be used by our accounting process when it has finished accessing files as user and wants to return to being root.
Set its real user ID to be the same as its effective user ID.
Could be used by a login program after it has set the effective user ID to that of the user who just logged in. Setting the real user ID ensures that the user will never be able go back to being root.
Swap the two user IDs.
Swapping the two user IDs is almost a historical artifact; modern programs rarely use this functionality.