Permissions and Users · about 35 min

Users, groups and root

Why this matters

Linux is a multi-user system from the ground up: a web server, a database, a backup job and several people can share one machine without being able to read each other's secrets or break each other's work. Permission errors ("Permission denied") are among the most common things you will debug, and they always come down to one question: which user is this process running as, and what does the file allow that user to do? This lesson covers the first half: users, groups and the special user root.

Users are numbers

Every account has a user ID (UID), a small integer. The kernel works only with these numbers; names are a convenience for humans, kept in the text file /etc/passwd:

$ head -4 /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
$ tail -1 /etc/passwd
learner:x:1000:1000::/home/learner:/bin/bash

Seven fields, separated by colons:

learner : x : 1000 : 1000 : (comment) : /home/learner : /bin/bash
 name    pw   UID    GID    full name   home dir        login shell

Most entries are system accounts (daemon, bin, www-data, nobody) that no person logs into. Services run as these so that a bug in, say, the web server can damage only what the www-data user may touch. By convention on Debian, UIDs below 1000 are system accounts and people start at 1000. You are the first "person" on this machine.

Note: On real networks, accounts often come from a directory service (LDAP, Active Directory) rather than the local file. getent passwd learner asks the system's configured sources, whatever they are, and is the robust way to look a user up in scripts.

Groups

A group is a named set of users, with a group ID (GID). Groups let you give several people access to the same files without giving it to everyone. They are listed in /etc/group:

$ grep -E '^(root|sudo|learner):' /etc/group
root:x:0:
sudo:x:27:
learner:x:1000:

Fields: name, password placeholder, GID, and a comma-separated list of extra members. Each user has one primary group (from /etc/passwd; new files get this group) and may have any number of supplementary groups. Debian gives every user a personal group of the same name, which is why you are in a group called learner.

id: who am I, exactly?

Open the shell for this lesson:

$ id
uid=1000(learner) gid=1000(learner) groups=1000(learner)
$ id -u
1000
$ id -un
learner
$ id -Gn
learner
$ id root
uid=0(root) gid=0(root) groups=0(root)

whoami from module 1 is the same as id -un. On a typical desktop you would see more groups, for example sudo (allowed to use sudo), audio, video or docker.

What happens underneath: credentials belong to processes

Users do not "do" anything; processes do. Every process carries credentials in the kernel: a UID, a primary GID and a list of supplementary GIDs. When you log in, the login program checks your password, then sets its own UID and GIDs to yours and execs your shell. From then on, everything is inherited:

 login (root) ── checks password ── setuid(1000), setgid(1000) ── exec bash
                                                                   bash (uid 1000)
                                                                     ├─ fork+exec ls   (uid 1000)
                                                                     └─ fork+exec nano (uid 1000)

Every time a process opens a file, the kernel compares the process's UID and GIDs with the file's owner, group and permission bits (next lesson). It never asks "who is typing?"; only "which credentials does this process have?".

You can see process owners with ps:

$ ps -o user,uid,pid,comm
USER       UID     PID COMMAND
learner   1000       1 bash
learner   1000      27 ps

root

The user with UID 0, conventionally named root, is the superuser. For a UID 0 process the kernel skips nearly all permission checks: it can read any file, kill any process, change any file's owner, bind to network ports below 1024, load kernel modules. That is necessary for administration (installing software into /usr, editing /etc, managing users), and dangerous, because a typo or a malicious script running as root can destroy the system.

Modern Linux refines this with capabilities: root's powers split into about 40 pieces (CAP_CHOWN, CAP_KILL, CAP_NET_BIND_SERVICE...) that can be granted separately. Containers use this heavily. This sandbox drops all of them, and you are not root anyway, so you cannot change system files here. That is by design.

Becoming root: su and sudo

On a normal system you do not log in as root. Instead:

$ sudo apt install tree        # on your own machine, not in this sandbox
[sudo] password for alex:

The habit to build: work as yourself, and use sudo for the single command that needs root, never sudo your whole session out of convenience. When something fails with "Permission denied", first understand why before reaching for sudo; often the fix is to use the right directory, not more power.

sudo is not installed in this sandbox, so there is no way to become root here: you will learn permissions with your own files, which works exactly the same way.

Common mistakes

Recap

Going further: read man 5 passwd and man 5 group on a system that has them, and man 7 credentials here. Try ls -ln /etc/passwd versus ls -l /etc/passwd: -n shows the raw numbers that are really stored in the inode.

Exercises

Exercise 1 · quiz

Root's number

The kernel does not know user names at all, only numbers. What user ID (UID) number does the kernel treat as the all-powerful superuser? Type the number.

Answer

UID 0. The name root is just the entry for UID 0 in /etc/passwd. The kernel's permission checks are skipped (with a few exceptions) for processes running as UID 0, whatever that user is called. This is why a second account with UID 0 is a full administrator, and why security audits look for exactly that.

Exercise 2 · quiz

Who is asking?

Which statements are true? Select all that apply.

Answer
  • Every process carries a user ID and group IDs, and the kernel checks those on each file access.

  • A program you start runs with your user ID, because the child process inherits it from your shell.

Credentials belong to processes, and children inherit them through fork and exec. That is how everything you run acts as you. Group names have no built-in power; a group only matters where a file's group permissions or a program's configuration (like sudo's rules) mention it. And sudo does not change your shell: it is a separate program that runs as root (it is a setuid program, see lesson 3), checks its rules and your password, and then starts the requested command as a new root process.

Exercise 3 · task in a shell

Your identity, in numbers

In the shell, run id and look at the output. Then create three files in /work:

  1. uid.txt: your numeric user ID only (id -u prints it),
  2. groups.txt: the names of the groups you belong to (id -Gn prints them on one line),
  3. passwd-line.txt: your own line from /etc/passwd, the one that starts with learner:. grep '^learner:' /etc/passwd prints exactly that line (grep prints lines that match a pattern; ^ means "at the start of the line").
Hint 1

Each of the three commands in the prompt prints exactly what is needed; add > file.

Hint 2

id -u > uid.txt, id -Gn > groups.txt, grep '^learner:' /etc/passwd > passwd-line.txt

Reference solution
id -u > uid.txt
id -Gn > groups.txt
grep '^learner:' /etc/passwd > passwd-line.txt

Exercise 4 · task in a shell

Read the user database

Look at /etc/passwd with cat or less. Each line is one account, seven fields separated by colons:

name:x:UID:GID:comment:home:shell

Find the answers and write each into its own file in /work (just the value, one line):

  1. daemon-shell.txt: the login shell of the user daemon,
  2. root-home.txt: the home directory of root,
  3. uid-of-nobody.txt: the UID of the user nobody.
Hint 1

grep '^daemon:' /etc/passwd shows just daemon's line. Count the colons.

Hint 2

Fields: 1 name, 2 x, 3 UID, 4 GID, 5 comment, 6 home, 7 shell. Write the value with echo, e.g. echo /root > root-home.txt.

Reference solution
grep '^daemon:' /etc/passwd | cut -d: -f7 > daemon-shell.txt
grep '^root:' /etc/passwd | cut -d: -f6 > root-home.txt
grep '^nobody:' /etc/passwd | cut -d: -f3 > uid-of-nobody.txt