Stage 3 · Build
Users, Permissions & Processes
UID, GID & Accounts
/etc/passwd, /etc/group, shadow passwords, useradd, usermod, and account locking.
UID/GID System
Every user has a numeric UID (User ID) and at least one GID (Group ID). The kernel uses UIDs and GIDs, not names, for access control. Names are resolved by NSS (Name Service Switch).
| Range | Purpose | Examples |
|---|---|---|
| 0 | root | UID 0 = unlimited power |
| 1-999 | System accounts | daemon, nobody, systemd-network |
| 1000-59999 | Regular users | First regular user = 1000 |
| 60000-65534 | Overflow/nobody | nobody (65534) |
| 65535 | Nobody (legacy) | Sometimes used for nobody |
# Current user
id
# uid=1000(username) gid=1000(username) groups=1000(username),27(sudo)
# Specific user
id www-data
# uid=33(www-data) gid=33(www-data) groups=33(www-data)
# All UIDs in use
getent passwd | awk -F: '{print $1, $3}' | sort -k2 -n
# Check UID of a user
getent passwd username | cut -d: -f3
# 1000
# Find users with UID 0 (should be only root)
awk -F: '$3 == 0 {print $1}' /etc/passwd
# rootThe kernel only sees UIDs/GIDs. /etc/passwd and /etc/group map names to numbers. Always verify UID 0 is only root.
/etc/passwd
# Format: username:password:UID:GID:GECOS:home:shell
cat /etc/passwd | head -5
# root:x:0:0:root:/root:/bin/bash
# daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
# www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
# Fields explained:
# root — Username
# x — Password in /etc/shadow (not here)
# 0 — UID
# 0 — Primary GID
# root — GECOS (comment, full name, etc.)
# /root — Home directory
# /bin/bash — Login shell
# System accounts use nologin shell
# Interactive users use bash, zsh, fishThe password field is 'x' because passwords are stored in /etc/shadow. System accounts use nologin to prevent interactive login.
/etc/group
# Format: groupname:password:GID:members
cat /etc/group | head -5
# root:x:0:
# daemon:x:1:
# sudo:x:27:username
# docker:x:999:username,deploy
# Check group membership
groups username
# username : username sudo docker
# Supplementary groups
id username
# uid=1000(username) gid=1000(username) groups=1000(username),27(sudo),999(docker)
# List all members of a group
getent group sudo
# sudo:x:27:username,admin
# Check if user is in group
groups username | grep -q docker && echo "In docker group"Primary group is the user's GID. Supplementary groups provide additional access. A user can be in multiple groups simultaneously.
Shadow Passwords
# Shadow file (root only)
sudo cat /etc/shadow | head -3
# root:$6$abc123...:19000:0:99999:7:::
# username:$6$def456...:19000:0:99999:7:::
# Fields: username:hash:lastchange:min:max:warn:inactive:expire
# Check password aging
sudo chage -l username
# Last password change: Jan 15, 2024
# Password expires: never
# Account expires: never
# Set password aging
sudo chage -M 90 username # Password expires in 90 days
sudo chage -W 14 username # Warn 14 days before expiry
sudo chage -E 2024-12-31 username # Account expires Dec 31
# Force password change on next login
sudo chage -d 0 usernameShadow passwords store hashes in /etc/shadow (root-readable only). Password aging enforces periodic password changes.
User Management Commands
# Create a user
sudo useradd -m -s /bin/bash -G sudo,docker newuser
# Create without home directory
sudo useradd -M -s /usr/sbin/nologin serviceaccount
# Set password
sudo passwd newuser
# Modify a user
sudo usermod -aG docker username # Add to docker group (-a append)
sudo usermod -s /bin/zsh username # Change shell
sudo usermod -L username # Lock account
sudo usermod -U username # Unlock account
# Delete a user
sudo userdel username # Keep home directory
sudo userdel -r username # Remove home directory
# Add a user to a group
sudo usermod -aG groupname username
# Create a group
sudo groupadd groupname
# Delete a group
sudo groupdel groupnameAlways use -aG (append to groups) when adding groups. Without -a, the user is removed from all other groups.
Account Security
# Lock an account (disable password)
sudo passwd -l username
# or
sudo usermod -L username
# Unlock an account
sudo passwd -u username
# Check if account is locked
sudo passwd -S username
# username L 01/15/2024 0 99999 7 -1
# Disable account entirely
sudo usermod -e 1970-01-01 username
# Remove login shell
sudo usermod -s /usr/sbin/nologin username
# Find empty passwords
sudo awk -F: '($2 == "" || $2 == "!") {print $1}' /etc/shadow
# Find UID 0 accounts (should be only root)
sudo awk -F: '$3 == 0 {print $1}' /etc/passwd
# Find users with no password
sudo awk -F: '($2 == "" || $2 == "!") {print $1}' /etc/shadowLock accounts that are no longer needed. Never delete system accounts. Check for empty passwords and unauthorized UID 0 accounts regularly.
Without -a, usermod replaces all group memberships. Always use -aG to append to existing groups.
root must always be UID 0. Changing root's UID breaks the system. Verify regularly that only root has UID 0.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.