It’s a little complicated. The operating system kernel uses a process’s effective UID and GID to determine its privileges/authorizations; they are used for
- allowing/disallowing ordinary filesystem operations (e.g., open, link/unlink) based on the user/group/other rules,
- setting the ownership of newly created files,
- determining what other processes a process can send signals to, and
- deciding whether a process can mount and unmount filesystems, change the date, shutdown the system, etc.
and probably other things. But, the catch is, when a program needs to make some sort of access/authorization decision, it usually needs to use the real UID and GID. Consider: when your with_sudo.c
program executes sudo
, the effective UID is root (0) and the real UID is you (1000), as demonstrated by your printf
. But this is exactly the same as what happens if you run sudo
from an unprivileged shell. Whenever sudo
runs, the effective UID is 0 – so sudo
can’t use that to decide how to behave. It has to use the real UID to figure out who you really, so it can determine what you’re allowed to do in sudo
. Only if the real UID is 0 does sudo
conclude that you are “really” root, or at least that it cannot reliably determine your real identity, so it doesn’t know what restrictions to apply to you, and it just executes the cat
without asking for any further authentication from you.