Cloud Tech by Victor
DevOpsIntermediate

Linux Users, Groups & sudo

How /etc/passwd and /etc/shadow split identity from password storage, why a UID (not a username) is what the kernel actually checks, and how a sudoers rule's who/where/as-whom/what structure grants privileges.

Updated 2026-07-243 min read

Overview

Linux identity is split across two files by design: /etc/passwd holds the world-readable account information, username, UID, primary GID, home directory, login shell, that ordinary tools need to resolve constantly, while /etc/shadow holds the actual password hash and is readable only by root. Every permission and ownership check the kernel performs operates on the numeric UID, never the username, which is why UID 0 is what "root" actually means. Elevated privilege for specific commands is granted through sudoers, whose rules follow a consistent who/where/as-whom/what structure, and whose NOPASSWD tag removes the re-authentication prompt for whichever commands it's attached to.

Quick Reference

FileReadable byHolds
/etc/passwdEveryoneUsername, UID, GID, home directory, shell
/etc/shadowRoot onlyEncrypted password hash, password aging data
/etc/groupEveryoneGroup names, GIDs, and supplementary members
/etc/sudoersRoot only (edit via visudo)Who can run what, as whom, on which hosts

Syntax

bash
useradd -m -s /bin/bash -G deploy alice   # create a user, home dir, shell, group
usermod -aG docker alice                  # add to a supplementary group
id alice                                  # show UID, GID, and group memberships

Examples

text
# /etc/sudoers - who / where = (as whom) what
# ray may run /bin/kill on host rushmore without a password prompt.
ray     rushmore = NOPASSWD: /bin/kill

Edit sudoers only with visudo

visudo validates the file's syntax before saving and locks it against concurrent edits. Editing /etc/sudoers directly with a normal editor risks a syntax error that can lock every user, including root via sudo, out of privileged commands until it's fixed from a root shell or rescue mode.

Visual Diagram

Common Mistakes

  • Assuming renaming a username changes its privileges; only the UID it maps to determines that, and two usernames can share UID 0.
  • Editing /etc/sudoers directly instead of via visudo, risking a syntax error that breaks sudo for everyone.
  • Applying NOPASSWD broadly (e.g., to ALL commands) instead of scoping it to the specific, narrow commands that genuinely need it.
  • Adding a user to a group with usermod -G (without -a) and unintentionally replacing all of their existing supplementary group memberships instead of adding to them.

Performance

  • UID/GID-based permission checks are simple integer comparisons the kernel performs on every file access; the cost is negligible next to the I/O itself.
  • Very large /etc/passwd//etc/group files (thousands of local accounts) can slow down tools that do a full linear scan; centralized directory services (LDAP, SSSD) are the standard fix at that scale, not a larger flat file.

Best Practices

  • Always edit /etc/sudoers (or files under /etc/sudoers.d/) with visudo, never a plain text editor.
  • Scope NOPASSWD and any sudo grant to the specific commands actually needed, not a blanket ALL.
  • Use usermod -aG (append), not -G alone, when adding a user to an additional group.
  • Prefer supplementary groups and sudo rules over sharing a UID or handing out root's actual password for day-to-day privileged access.

Interview questions

Why does Linux split user information across /etc/passwd and /etc/shadow instead of keeping everything, including the password hash, in one file?

/etc/passwd has to be world-readable, ordinary tools and commands need to map UIDs to usernames and look up home directories or login shells for every user on the system. If password hashes lived there too, every local user could copy them out and run an offline cracking attempt. /etc/shadow holds the actual encrypted password (and related aging data) and is readable only by root, while /etc/passwd keeps a placeholder character (commonly `x`) in the password field, preserving the UID-lookup functionality everything else depends on without exposing anything crackable.

What does the kernel actually check when deciding whether a process can access a file, the username or the UID?

The UID. A username is a human-readable label that /etc/passwd maps to a numeric UID, but every permission check, ownership comparison, and process credential the kernel deals with operates on that number, root is UID 0 specifically, not "whichever account is named root." This is why two different usernames can be given identical privileges by sharing UID 0, and why renaming an account changes nothing about what it's allowed to do, only the numeric UID does.

In a sudoers rule like "ray rushmore = NOPASSWD: /bin/kill", what does each part of the rule mean, and what does NOPASSWD change?

The rule follows sudo's who/where/as-whom/what structure: `ray` is the user the rule applies to, `rushmore` is the host it applies on (sudoers rules can be host-scoped for a shared file across many machines), and `/bin/kill` is the specific command being granted, with no explicit run-as-user meaning the default (root). NOPASSWD changes the authentication requirement, by default sudo requires the invoking user to re-enter their own password before running a privileged command, and NOPASSWD removes that prompt for the commands it's attached to, which trades a real authentication check for convenience and should be scoped to specific, narrow commands rather than applied broadly.

References

ShareXLinkedInReddit
Was this page helpful?
Suggest an improvement