3.2.2. Account Files, UID/GID Ranges, and Profile Templates
💡 First Principle: Linux stores account data in plain text files — deliberately, so that the files can be edited with standard tools, backed up easily, and managed without a running database. The separation of /etc/passwd (world-readable names and UIDs) from /etc/shadow (root-only password hashes) was a security retrofit: originally, hashed passwords lived in /etc/passwd, readable by all users.
The Account Files:
/etc/passwd — User account records (world-readable)
/etc/shadow — Password hashes and aging (root-only)
/etc/group — Group definitions (world-readable)
/etc/gshadow — Group passwords and admins (root-only)
/etc/passwd format (:-separated, 7 fields):
alice:x:1001:1001:Alice Smith:/home/alice:/bin/bash
^ ^ ^ ^ ^ ^ ^
| | | | | | └─ Login shell
| | | | | └─ Home directory
| | | | └─ GECOS (full name/comment)
| | | └─ Primary GID
| | └─ UID
| └─ Password placeholder (x = hash in /etc/shadow)
└─ Username
/etc/shadow format (:-separated, 9 fields):
alice:$6$salt$hash:19000:0:90:14:7::
^ ^ ^ ^ ^ ^ ^
| | | | | | └─ Inactivity period after expiry (expiration + flag fields follow, both empty here)
| | | | | └─ Warning period before expiry (days)
| | | | └─ Max password age (days)
| | | └─ Min password age (days)
| | └─ Last password change (days since 1970-01-01)
| └─ Password hash ($6$ = SHA-512)
└─ Username
UID and GID Ranges:
| Range | Type | Examples |
|---|---|---|
| 0 | Root | root — absolute superuser |
| 1–99 | Static system accounts | daemon, bin, sys |
| 100–999 | Dynamic system accounts | nginx, mysql, docker |
| 1000+ | Regular user accounts | alice, bob |
System accounts (UIDs 1–999) typically use /sbin/nologin or /bin/false as their shell, preventing interactive login while still allowing services to run as those UIDs.
EUID and EGID: The Effective UID/GID is what the kernel actually checks for permissions. Normally EUID equals UID, but the setuid bit on an executable causes the process to run with the file owner's EUID instead of the launching user's UID. This is how passwd can write to /etc/shadow (which only root can modify) even when run by an ordinary user.
Profile Templates:
When useradd -m creates a home directory, it populates it from /etc/skel/:
ls -la /etc/skel/ # .bashrc, .bash_profile, .profile — defaults for new users
System-wide shell settings that apply to all users go in:
/etc/profile # Login shells (executed once at login)
/etc/profile.d/*.sh # Drop-in profile scripts (sourced by /etc/profile)
/etc/bash.bashrc # Interactive non-login shells (Debian/Ubuntu)
/etc/bashrc # Interactive non-login shells (RHEL)
⚠️ Exam Trap: The x in field 2 of /etc/passwd does NOT mean the password is x — it means the actual hash is stored in /etc/shadow. If the shadow file is missing or unreadable, authentication will fail. On systems without shadow passwords (rare), the hash would appear directly in /etc/passwd.
Reflection Question: A new system account for the backup service needs to be created so the service can run as that user but nobody can interactively log in as it. Write the useradd command, specifying an appropriate shell.