Linux Users, Groups, and Ownership Explained

Linux Users, Groups, and Ownership Explained

Linux was designed from the start to be used by multiple people on the same machine at the same time. The user and group system is how it keeps those users separate, controls what each can access, and allows selective sharing. Even on a single-user desktop, the model runs underneath everything: services run as dedicated users, files are owned by specific accounts, and the package manager enforces that only root can modify system files.

How Linux identifies users: UIDs

Every user account on a Linux system has a username (a human-readable string) and a UID (User ID, a 32-bit integer). The kernel works exclusively with UIDs. Usernames are a convenience layer that tools like ls, ps, and chown translate to and from UIDs using /etc/passwd.

# See your own identity
id
# uid=1000(alice) gid=1000(alice) groups=1000(alice),4(adm),27(sudo),1001(docker)

# See another user's identity
id bob

# See just your username
whoami

# See just your groups
groups

The UID ranges are conventional but important:

  • UID 0: root. The superuser. One account, total control.
  • UIDs 1-999: system accounts. Created by the OS and packages for daemons and services. Cannot log in interactively by design.
  • UIDs 1000+: regular users. Created by the administrator for human beings who log in.
# See all user accounts and their UIDs
cat /etc/passwd

# The format is:
# username:password:UID:GID:comment:home:shell
# alice:x:1000:1000:Alice Smith:/home/alice:/bin/bash
# www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

The x in the password field means the actual password hash is stored in /etc/shadow, not /etc/passwd. /etc/passwd is world-readable (services need to resolve usernames), while /etc/shadow is readable only by root.

How Linux identifies groups: GIDs

Groups work the same way. Every group has a name and a GID (Group ID). Group definitions live in /etc/group.

cat /etc/group
# Format: groupname:password:GID:member1,member2,...
# sudo:x:27:alice,bob
# docker:x:999:alice
# developers:x:1001:alice,carol,dave

Every user has one primary group (defined in /etc/passwd) and can belong to any number of supplementary groups (listed in /etc/group). The primary group is the group assigned to new files the user creates, unless a setgid directory overrides it.

# See all groups and their members
getent group

# See which groups a specific user belongs to
groups alice
id alice

# See your own current effective group
id -g    # GID
id -gn   # group name

The root account

Root has UID 0. That number is what grants the privileges, not the username. A user named toor with UID 0 would have the same power as root.

Root can read any file regardless of its permissions, write to any file, kill any process, bind to any network port, and load kernel modules. There is no permission check that applies to root.

Most Linux distributions lock the root account’s password and instead grant sudo access to the first user created during installation. Logging in directly as root is discouraged because there is no audit trail connecting actions to a specific person.

# Switch to root (requires knowing the root password, if set)
su -

# Run a single command as root via sudo
sudo apt update

# Open a root shell via sudo (use sparingly)
sudo -i
sudo -s

# See who can use sudo on the system
sudo -l          # your own sudo permissions
sudo cat /etc/sudoers

sudo: controlled privilege escalation

sudo lets an authorised user run a specific command as root (or as another user). Each use is logged to /var/log/auth.log on Debian/Ubuntu or the journal on systemd systems, creating an audit trail.

# Run a single command as root
sudo systemctl restart nginx

# Run a command as a different user (not root)
sudo -u www-data ls /var/www/html

# See recent sudo usage in the auth log
sudo grep sudo /var/log/auth.log | tail -20

# Or via journalctl
journalctl _COMM=sudo | tail -20

sudo’s behaviour is controlled by /etc/sudoers and files in /etc/sudoers.d/. Always edit the sudoers file with visudo, which validates the syntax before saving. A syntax error in sudoers can lock you out of sudo entirely.

# Safe way to edit sudoers
sudo visudo

# Add a file for a specific user or group in sudoers.d
sudo visudo -f /etc/sudoers.d/alice

# Common sudoers patterns:
# alice ALL=(ALL:ALL) ALL          # alice can run anything as any user
# %sudo ALL=(ALL:ALL) ALL          # anyone in the sudo group can run anything
# alice ALL=(ALL) NOPASSWD: /bin/systemctl restart nginx  # no password for one command

On Ubuntu and Debian, adding a user to the sudo group grants full sudo access. On RHEL-based systems, the equivalent group is wheel.

Managing users

# Create a new user with a home directory
sudo useradd -m -s /bin/bash alice

# Set a password
sudo passwd alice

# Create a user with a comment (full name) and specific shell
sudo useradd -m -c "Alice Smith" -s /bin/bash alice

# useradd defaults (what gets used when you omit options)
cat /etc/default/useradd
cat /etc/adduser.conf   # Debian/Ubuntu higher-level tool

# On Debian/Ubuntu, adduser is friendlier and interactive
sudo adduser alice

# Modify an existing user
sudo usermod -c "Alice A. Smith" alice     # change comment
sudo usermod -s /bin/zsh alice             # change shell
sudo usermod -d /home/newname alice        # change home directory
sudo usermod -l newname alice              # rename the account

# Lock and unlock an account
sudo usermod -L alice    # lock (prepends ! to password hash)
sudo usermod -U alice    # unlock

# Delete a user
sudo userdel alice           # remove account, keep home directory
sudo userdel -r alice        # remove account and home directory

Managing groups

# Create a group
sudo groupadd developers

# Create a group with a specific GID
sudo groupadd -g 2000 developers

# Add a user to a group (append, do not replace existing groups)
sudo usermod -aG developers alice

# Add multiple groups at once
sudo usermod -aG developers,docker,adm alice

# Remove a user from a group
sudo gpasswd -d alice developers

# Rename a group
sudo groupmod -n devs developers

# Delete a group
sudo groupdel developers

# See group membership
getent group developers
grep developers /etc/group

After adding yourself to a group, you need to log out and back in for the shell to pick up the new membership. Or use newgrp to activate a new group in the current session:

# Activate a new group without logging out
newgrp docker

# Verify your current groups
groups

System accounts and service users

Every daemon that runs on Linux should run as its own dedicated user account. nginx runs as www-data. PostgreSQL runs as postgres. systemd-resolved runs as systemd-resolve. This is called the principle of least privilege: if a service is compromised, the attacker gets the permissions of that service account, not root.

System accounts are created with flags that prevent interactive login:

# Create a system account for a service
sudo useradd -r -s /usr/sbin/nologin -d /var/lib/myapp myapp

# -r: system account (UID below 1000, no aging)
# -s /usr/sbin/nologin: prevents interactive login
# -d: home directory for the service's data

# See all system accounts
awk -F: '$3 < 1000 {print $1, $3, $7}' /etc/passwd

When you install a package that ships a service, the package maintainer’s install scripts create the service account automatically. You will rarely need to create service accounts manually unless you are packaging your own software.

Ownership and the connection to permissions

User and group accounts only matter because files have owners. Every file and directory has exactly one owning user and one owning group. The permission bits (read, write, execute) apply separately to the owner, the group, and everyone else.

# See ownership of files
ls -l /etc/ssh/
# -rw-r--r-- 1 root root       ...  sshd_config
# -rw------- 1 root root       ...  ssh_host_ed25519_key

# Change ownership
sudo chown alice file.txt
sudo chown alice:developers file.txt
sudo chown -R www-data:www-data /var/www/html

# Change group only
sudo chgrp developers project/

The ownership model answers questions like: why can a regular user not read /etc/shadow? Because it is owned by root with permissions 640 and your user is not in the shadow group. Why can the www-data user write to /var/www/html? Because that directory is owned by www-data or has group write permissions for a group www-data belongs to.

Practical reference

# Who is logged in right now?
who
w
last | head -20

# See all users with login shells
grep -v nologin /etc/passwd | grep -v false

# Check when a password expires
sudo chage -l alice

# Set password expiry
sudo chage -M 90 alice     # expire every 90 days
sudo chage -E 2027-01-01 alice  # expire on a specific date

# Find files owned by a specific user
find /home -user alice

# Find files with no valid owner (orphaned after account deletion)
find / -nouser 2>/dev/null

# See the last login time for all users
lastlog

The user and group system on Linux is simple at its core: numbers identify who you are, groups let you share access, and root has no restrictions. The tooling around it (useradd, usermod, sudo, chown) follows directly from that model. Once the underlying structure is clear, every command makes obvious sense.

Frequently Asked Questions

What is the difference between a user and a group in Linux?

A user is an individual account with a unique username and numeric UID. A group is a collection of users with a shared GID. Groups exist to grant the same permissions to multiple users at once. Every file and directory has both an owning user and an owning group. A user can belong to many groups simultaneously.

What is the root user in Linux?

Root is the superuser account with UID 0. It has unrestricted access to every file, process, and system resource on the machine. Unlike regular users, root can read any file regardless of permissions, kill any process, and modify any system configuration. Most distributions discourage logging in directly as root and instead use sudo to grant temporary elevated privileges to regular users.

What does sudo do in Linux?

sudo (superuser do) lets an authorised regular user run a single command with root privileges without switching to the root account. The user is authenticated with their own password, the command is logged, and privilege is dropped after the command completes. This is more auditable and safer than logging in as root, because each privileged action is tied to a specific user account.

How do I add a user to a group in Linux?

Use usermod -aG groupname username. The -a flag appends the group rather than replacing all existing group memberships. For example: sudo usermod -aG docker alice adds alice to the docker group without removing her from other groups. The user must log out and back in for the new group membership to take effect in their shell session.

What is the difference between a login shell and a system account?

A login shell account is a regular user account with a home directory and a valid shell (like /bin/bash). The user can log in interactively. A system account (also called a service account) is created for a daemon or service to run as, with no home directory, a shell set to /usr/sbin/nologin or /bin/false, and no password. System accounts typically have UIDs below 1000.