19

I always thought that "sudo" just starts another login-process, specifically using "root" as a username and asking for the Password to login. After running some program, it ends and logs out (or: keeps the open session for some time and then quits it). No idea where I heard that from, but that seemed reasonable to me.

But now I discovered this sudoers-option:

ALL    ALL = (root) NOPASSWD: /my/command

This allows me to run any program from any user as a root without asking for any password. This left me wondering:

How does that work? How does a program gain user-rights? Does sudo need a server (running as root as daemon or so) and connects to that server, sends it what should be executed and that server executes it with root-rights?

How about other users?

Is there any good and simple explanation how this works?

1
  • 4
    Hint: ls -l $(which sudo) will tell you that sudo itself is setuid root. Once you're root, you can change to any user's security context, then execute any code you like.
    – user
    Commented Apr 28, 2014 at 14:21

2 Answers 2

39

sudo is a so called "SetUID binary", as you can see in the output of ls -l:

$ ls -l /usr/bin/sudo
-rwsr-xr-x 1 root root 159016 Mar 21 20:40 /usr/bin/sudo

The s in the fourth column (where you'd normally find an x on executable files) tells you that the SetUID bit is set. This bit has one significant meaning: When a binary with the SetUID bit set is executed, it does not run with the user ID of the invoking user, but the user ID of the binary's owner (in this case root).

And that's the clue. sudo is always run with superuser privileges (as root). Thus sudo has the ability to do some privileged tasks like calling system functions only allowed for root. One of those system calls (the essential one) are setuid(2) and friends. By calling setuid() a process can change its UID to any UID it wants (thus impersonating another user).

What sudo does is:

  • read and parse /etc/sudoers, look up the invoking user and its permissions,
  • ask the invoking user for a password (this is usually the user's password, but can also be the target user's password or skipped as with NOPASSWD)
  • create a child process in which it calls setuid() to change to the target user
  • execute a shell or the command given as arguemnts in this child
2

Simple answer is the suid flag on the sudo binary:

ls -l /usr/bin/sudo
---s--x--x. 1 root root 130712 02-26 13:31 /usr/bin/sudo

The suid flag on an executable file allows for the binary to run the setuid() system call, no matter who the executor is - root, or a non-root user.

The rest is up to the individual binary's instructions, and configuration. In the case of sudo, it parses a configuration file (commonly /etc/sudoers) to determine whether to continue with the escalation.

On some files, timestamp information is restricted to only root users. The following example from a sample server demonstrates how the escalation from sudo provides timestamp information:

[artur@asus-ux21e ~]$ sudo ls -l /var/db/sudo/artur
total 12
-rw-------. 1 root artur 48 04-24 14:07 0
-rw-------. 1 root artur 48 04-24 11:27 1
-rw-------. 1 root artur 48 04-24 11:26 2

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .