Skip to content

User Management

Comprehensive Linux User Account Management

Section titled “Comprehensive Linux User Account Management”

User management is critical for access control, security, and compliance in any production environment:

User Management for DevOps/SRE
+------------------------------------------------------------------+
| |
| Security & Compliance: |
| +----------------------------------------------------------+ |
| | Principle of Least Privilege → Minimal access | |
| | Audit trails → Who did what, when | |
| | Password policies → Complexity, rotation | |
| | SSH keys → Key-based authentication | |
| +----------------------------------------------------------+ |
| |
| Automation & DevOps: |
| +----------------------------------------------------------+ |
| | LDAP/AD integration → Centralized auth | |
| | SSO → Single Sign-On for applications | |
| | Service accounts → App-to-app authentication | |
| | sudo policies → Delegated admin access | |
| +----------------------------------------------------------+ |
| |
| Incident Response: |
| +----------------------------------------------------------+ |
| | Quick user disable → Terminate access immediately | |
| | Password reset → Emergency access recovery | |
| | Audit logs → Investigate security incidents | |
| +----------------------------------------------------------+ |
| |
+------------------------------------------------------------------+

Practical Impact:

  • Implement least privilege access in production
  • Manage service accounts for automation (CI/CD, APIs)
  • Respond to security incidents by quickly disabling users
  • Comply with SOX, HIPAA, PCI-DSS requirements

┌────────────────────────────────────────────────────────────────────────┐
│ USER TYPES IN LINUX │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ USERS │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────┼──────────────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ ROOT │ │ SYSTEM │ │ REGULAR │ │
│ │ USER │ │ USERS │ │ USERS │ │
│ ├─────────────┤ ├─────────────┤ ├─────────────┤ │
│ │ UID: 0 │ │ UID: 1-999 │ │ UID: 1000+ │ │
│ │ │ │ │ │ │ │
│ │ Full system │ │ Services & │ │ Interactive │ │
│ │ control │ │ daemons │ │ accounts │ │
│ │ │ │ │ │ │ │
│ │ root user │ │ bin, daemon,│ │ Human users │ │
│ │ │ │ sys, mail │ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ System users (UID 1-999): │
│ - Used by system services │
│ - Usually no login shell │
│ - Limited file system access │
│ - Often use /sbin/nologin or /usr/sbin/nologin │
│ │
│ Regular users (UID 1000+): │
│ - Interactive user accounts │
│ - Home directory in /home │
│ - Login shell (/bin/bash, /bin/zsh) │
│ - Can use sudo for elevated privileges │
│ │
└────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────┐
│ USER DATABASE FILES │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┬────────────────────────────────────────────────┐ │
│ │ File │ Description │ │
│ ├─────────────┼────────────────────────────────────────────────┤ │
│ │ /etc/passwd │ User account information │ │
│ │ │ (readable by all) │ │
│ ├─────────────┼────────────────────────────────────────────────┤ │
│ │ /etc/shadow │ Encrypted passwords (root only) │ │
│ ├─────────────┼────────────────────────────────────────────────┤ │
│ │ /etc/group │ Group information │ │
│ ├─────────────┼────────────────────────────────────────────────┤ │
│ │ /etc/gshadow│ Group passwords (rarely used) │ │
│ └─────────────┴────────────────────────────────────────────────┘ │
│ │
└────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────┐
│ PASSWD FILE FORMAT │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ username:password:UID:GID:GECOS:home_directory:shell │
│ │
│ Example: │
│ ┌──────────┬────┬─────┬─────┬────────────────┬──────────┬──────────┐ │
│ │ username │pass│ UID │ GID │ GECOS │ home │ shell │ │
│ │ │wd │ │ │ │ dir │ │ │
│ ├──────────┼────┼─────┼─────┼────────────────┼──────────┼──────────┤ │
│ │ root │x │ 0 │ 0 │ root │ /root │ /bin/bash│ │
│ │ daemon │x │ 1 │ 1 │ daemon │ /usr/sbin│ /sbin/nol│ │
│ │ john │x │1000 │1000 │ John Doe │ /home/jhn│ /bin/bash│ │
│ │ mysql │x │ 999 │ 999 │ MySQL Server │ /var/lib│ /sbin/nol│ │
│ └──────────┴────┴─────┴─────┴────────────────┴──────────┴──────────┘ │
│ │
│ Field Descriptions: │
│ - username: Login name │
│ - password: 'x' means password in /etc/shadow │
│ - UID: User ID number │
│ - GID: Primary group ID │
│ - GECOS: Full name, contact info (comma-separated) │
│ - home_dir: User's home directory │
│ - shell: Login shell │
│ │
└────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────┐
│ SHADOW FILE FORMAT │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ username:password:last_change:min_age:max_age:warn:inactive:expire │
│ │
│ Example: │
│ ┌──────────┬───────────────────────────────────────────┐ │
│ │ username │password │ │
│ ├──────────┼───────────────────────────────────────────┤ │
│ │ root │$6$xyz... (locked) │ │
│ │ john │$6$abc...:19234:0:99999:7:: │ │
│ │ mysql │!! (no password set) │ │
│ └──────────┴───────────────────────────────────────────┘ │
│ │
│ Field Descriptions: │
│ - password: Encrypted password or '!' or '!!' (locked/empty) │
│ - last_change: Days since Jan 1, 1970 since last change │
│ - min_age: Days before password can be changed │
│ - max_age: Days before password must be changed │
│ - warn: Days before expiry user is warned │
│ - inactive: Days after expiry before account disabled │
│ - expire: Days since Jan 1, 1970 when account expires │
│ │
│ Password prefixes: │
│ - $1$ - MD5 │
│ - $2a$ - Blowfish │
│ - $5$ - SHA-256 │
│ - $6$ - SHA-512 (default) │
│ - ! - Account locked │
│ - !! - Password never set │
│ - * - No login allowed │
│ │
└────────────────────────────────────────────────────────────────────────┘

Terminal window
# Basic user creation (minimal)
sudo useradd username
# Create with home directory
sudo useradd -m username
# Create with specific UID
sudo useradd -u 1500 username
# Create with specific shell
sudo useradd -s /bin/zsh username
# Create with custom home directory
sudo useradd -d /custom/home username
# Create with comment/GECOS
sudo useradd -c "John Doe" username
# Create with expiration date
sudo useradd -e 2024-12-31 username
# Create with specific primary group
sudo useradd -g developers username
# Create with supplementary groups
sudo useradd -G wheel,sudo username
# Combine all options (full example)
sudo useradd -m \
-s /bin/bash \
-c "John Doe,Systems Admin,555-1234" \
-u 1000 \
-g developers \
-G wheel,docker \
-e 2024-12-31 \
-f 30 \
john
Terminal window
# View default useradd settings
useradd -D
# Example output:
# GROUP=100
# HOME=/home
# INACTIVE=-1
# EXPIRE=
# SHELL=/bin/bash
# SKEL=/etc/skel
# CREATE_MAIL_SPOOL=yes
# Modify defaults
sudo useradd -D -s /bin/zsh
sudo useradd -D -e 2025-01-01
sudo useradd -D -f 14
# Set default password policy
sudo chage -d 0 username # Force password change on first login
Terminal window
# Using adduser (Debian/Ubuntu - interactive)
sudo adduser username
# Creates user, home dir, sets up files from /etc/skel
# Using adduser with options
sudo adduser --home /custom/home --shell /bin/bash john
# Using front-end (Fedora/RHEL)
sudo userinteractive username
# Using Arch Linux (manual steps)
sudo useradd -m john
sudo passwd john
Terminal window
# Create system user (no home, no login)
sudo useradd -r -s /sbin/nologin mysql
# System user with home (for running services)
sudo useradd -r -s /sbin/nologin \
-d /var/lib/mysql \
-c "MySQL Server" \
mysql
# Create user for application
sudo useradd -r -d /opt/myapp -s /sbin/nologin myapp
# Options for system users:
# -r : Create system account
# -s : Login shell (/sbin/nologin)
# -d : Home directory
# -M : Don't create home directory
# -N : Don't create user group
# -g : Specify primary group

Terminal window
# Change username
sudo usermod -l newname oldname
# Change home directory (without moving)
sudo usermod -d /new/home username
# Change home directory (move contents)
sudo usermod -d /new/home -m username
# Change shell
sudo usermod -s /bin/zsh username
# Change UID
sudo usermod -u 2000 username
# Change primary group
sudo usermod -g developers username
# Set specific supplementary groups
sudo usermod -G wheel,sudo,docker username
# Add to supplementary groups (append)
sudo usermod -aG wheel,sudo username
# Remove from all supplementary groups
sudo usermod -G "" username
# Lock account
sudo usermod -L username
# Unlock account
sudo usermod -U username
# Set expiration date
sudo usermod -e 2024-12-31 username
# Remove expiration
sudo usermod -e "" username
# Set inactive days after password expires
sudo usermod -f 30 username
# Change GECOS
sudo usermod -c "New Name,New Title,555-5678" username
Terminal window
# Migrate user to new home directory
sudo usermod -d /home/newjohn -m -l johnjohn john
# Convert regular user to system user
sudo usermod -r -s /sbin/nologin username
# Add user to multiple groups
sudo usermod -aG docker,nginx,redis john
# Lock account after suspicious activity
sudo usermod -L -e 2024-01-01 john
# Change user's default group
sudo usermod -g developers john
Terminal window
# Change user's comment (GECOS)
chfn -f "John Doe" john
# Or use
sudo usermod -c "John Doe" john
# View finger info
finger john
# Change login name (username)
sudo usermod -l newname oldname
# Note: This doesn't change home directory
# Migrate user's files after rename
sudo usermod -d /home/newname -m -l newname oldname

Terminal window
# Basic user deletion
sudo userdel username
# Delete with home directory and mail spool
sudo userdel -r username
# Force deletion (even if logged in)
sudo userdel -f username
# Remove all files (even if not in usual locations)
sudo userdel -rf username
Terminal window
# Before deleting user:
# 1. Check for running processes
ps -U username
# 2. Kill any running processes
sudo pkill -u username
# 3. Backup user's files
sudo tar -czf /backup/username-home.tar.gz /home/username
# 4. Check for cron jobs
sudo crontab -u username -l
# 5. Check for print jobs
lpstat -u username
# 6. Check mail
ls /var/mail/username
ls /var/spool/mail/username
# 7. Delete user
sudo userdel -r username
# 8. Remove from sudo group
sudo deluser username sudo
# 9. Remove crontab
sudo crontab -r -u username

Terminal window
# Change own password
passwd
# Change another user's password (as root)
sudo passwd username
# Delete password (no password)
sudo passwd -d username
# Lock account
sudo passwd -l username
# Unlock account
sudo passwd -u username
# Set password expiration
sudo passwd -e username # Force change on next login
# View password status
passwd -S username
# Example output:
# username P 01/01/2024 0 99999 7 -1
# P = password set
# L = locked
# NP = no password
Terminal window
# Set password aging with chage
sudo chage -l username # View current settings
sudo chage -m 5 username # Minimum days between changes
sudo chage -M 90 username # Maximum days until expiry
sudo chage -W 7 username # Warning days before expiry
sudo chage -I 14 username # Days after expiry before lock
sudo chage -E 2024-12-31 username # Account expiry date
# Set to never expire
sudo chage -M -1 username
# Force password change on next login
sudo chage -d 0 username
Terminal window
# Install password quality checker
sudo apt-get install libpam-pwquality
# Configure password requirements
# /etc/security/pwquality.conf
# minlen = minimum password length
minlen = 12
# dcredit = digits requirement
dcredit = -1 # At least 1 digit
# ucredit = uppercase requirement
ucredit = -1 # At least 1 uppercase
# lcredit = lowercase requirement
lcredit = -1 # At least 1 lowercase
# ocredit = special character requirement
ocredit = -1 # At least 1 special
# maxclassrepeat = max same character repeats
maxclassrepeat = 3
# dictcheck = dictionary check
dictcheck = 1

Terminal window
# View own ID info
id
# View specific user's ID
id username
# Output example:
# uid=1000(john) gid=1000(john) groups=1000(john),10(wheel),993(docker)
# View only UID
id -u
# View only GID
id -g
# View all groups
id -G
# View username
id -un
# Numeric only
id -nu
Terminal window
# Show who is logged in
who
# Show with header
who -H
# Show all entries
who -a
# Show last login
who -b
# Show login processes
who -l
# Show users + process info
w
# Show w without header
w -h
# Show specific user
w username
Terminal window
# Show recent logins
last
# Show last 10 entries
last -10
# Show specific user
last username
# Show reboots
last reboot
# Show shutdowns
last shutdown
# Show failed logins
lastb

┌────────────────────────────────────────────────────────────────────────┐
│ USER ENVIRONMENT SETUP │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ When user is created with -m: │
│ │
│ /etc/skel/ is copied to user's home: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ /etc/skel/ │ │
│ │ ├── .bashrc - Bash configuration │ │
│ │ ├── .bash_profile - Login bash config │ │
│ │ ├── .profile - POSIX login config │ │
│ │ ├── .bash_logout - Cleanup on logout │ │
│ │ ├── .gitconfig - Git configuration │ │
│ │ └── .vimrc - Vim configuration │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ User can customize: │
│ - ~/.bashrc (non-login shell) │
│ - ~/.bash_profile or ~/.profile (login shell) │
│ - ~/.inputrc (readline) │
│ - ~/.vimrc (vim) │
│ │
└────────────────────────────────────────────────────────────────────────┘
Terminal window
# View all environment variables
env
# View user-specific variables
printenv HOME
printenv USER
printenv SHELL
printenv PATH
# Set environment variable for session
export VAR=value
# Set for all sessions
echo "export VAR=value" >> ~/.bashrc

Terminal window
# Install SSSD
sudo apt-get install sssd realmd oddjob oddjob-mkhomedir
# Join to Active Directory
sudo realm join -U admin@DOMAIN.COM domain.com
# Configure SSSD
# /etc/sssd/sssd.conf
[sssd]
services = nss, pam
config_file_version = 2
domains = DOMAIN.COM
[domain/DOMAIN.COM]
id_provider = ad
access_provider = ad
default_shell = /bin/bash
fallback_homedir = /home/%u
# Restart service
sudo systemctl restart sssd
Terminal window
# Install LDAP client
sudo apt-get install libpam-ldapd nslcd
# Configure /etc/nslcd.conf
uri ldap://ldap.example.com
base dc=example,dc=com
binddn cn=proxyuser,dc=example,dc=com
bindpw secret
# Configure PAM
sudo auth-client-config -t nss -p lac_ldap

Terminal window
# User cannot login
# Check: password set, account not locked, shell exists
sudo passwd -S username
grep username /etc/shadow
ls -l /bin/bash
# User gets "User not known to underlying authentication module"
sudo pwconv
sudo grpconv
# Home directory missing
sudo mkdir -m 755 /home/username
sudo chown username:username /home/username
sudo cp -r /etc/skel/. /home/username/
# Permission issues
sudo chown -R username:username /home/username
# Cannot create user
# Check UID range available
tail -1 /etc/passwd
# Account locked after failed attempts
sudo pam_tally2 --user username --reset
Terminal window
# Check user exists
getent passwd username
# Check password
getent shadow username
# Check groups
getent group groupname
# Check user processes
ps -U username
# Check user files
find / -user username 2>/dev/null
# Check crontabs
sudo crontab -u username -l
# Check at jobs
atq -u username
# Check print jobs
lpstat -u username

Q1: What is the difference between system users and regular users?

Section titled “Q1: What is the difference between system users and regular users?”

Answer:

  • System users (UID 1-999): Used for system services and daemons. Usually don’t have login shells (/sbin/nologin), no home directory, or minimal access. Created with useradd -r.
  • Regular users (UID 1000+): Interactive accounts for humans. Have login shells, home directories in /home, can use sudo for elevated privileges.

Q2: What is the purpose of /etc/shadow file?

Section titled “Q2: What is the purpose of /etc/shadow file?”

Answer: The /etc/shadow file stores encrypted passwords and password aging information. It’s readable only by root for security. Each line contains: username, encrypted password, last change date, min/max age, warning period, inactivity period, and expiry date.

This separation from /etc/passwd improves security because:

  1. Regular users can’t read passwords
  2. Password aging policies can be enforced
  3. Account lockout features work properly

Q3: How do you lock and unlock a user account?

Section titled “Q3: How do you lock and unlock a user account?”

Answer:

Terminal window
# Lock account (prefix password with !)
sudo passwd -l username
# or
sudo usermod -L username
# Unlock account (remove ! prefix)
sudo passwd -u username
# or
sudo usermod -U username
# View lock status
passwd -S username

Q4: What happens when you delete a user without -r flag?

Section titled “Q4: What happens when you delete a user without -r flag?”

Answer: The user’s account is removed but:

  • Home directory remains
  • Mail spool remains
  • Files owned by user remain (become orphaned)

Use find to find and handle orphaned files:

Terminal window
find / -user UID -ls

Q5: How do you force a user to change password on next login?

Section titled “Q5: How do you force a user to change password on next login?”

Answer:

Terminal window
# Set password age to 0 (expired)
sudo chage -d 0 username
# Or
sudo passwd -e username
# Verify
sudo chage -l username

Q6: What is the difference between userdel and deluser?

Section titled “Q6: What is the difference between userdel and deluser?”

Answer:

  • userdel - Low-level command, minimal safety checks
  • deluser - Higher-level Perl script (Debian/Ubuntu), safer with more options
    • Can remove home directory
    • Can remove all files
    • Can backup before removing

Terminal window
# Create user
useradd -m -s /bin/bash -c "Name" -u 1000 -G group user
# Modify user
usermod -aG group user
usermod -L user
usermod -e 2024-12-31 user
# Delete user
userdel -r user
# Password management
passwd user
passwd -l user
passwd -e user
# User info
id user
who
finger user
# Password aging
chage -l user
FilePurpose
/etc/passwdUser account info
/etc/shadowPasswords & aging
/etc/groupGroup info
/etc/skel/Default user files
/etc/default/useraddDefault settings
RangeType
0Root
1-99System
100-999System (dynamic)
1000+Regular users

Terminal window
# ❌ WRONG: Running everything as root
sudo su - # Always root!
service myapp start # As root
# ✅ CORRECT: Use service accounts
useradd -r -s /sbin/nologin myapp # Create service account
chown myapp:myapp /opt/myapp # Set ownership
systemctl start myapp # Run as service
Terminal window
# ❌ WRONG: No password policy enforcement
# Users can set weak passwords like "password123"
# ✅ CORRECT: Configure password policies
# /etc/login.defs or PAM configuration
PASS_MIN_LEN 12
PASS_MIN_DAYS 1
PASS_MAX_DAYS 90
PASS_WARN_AGE 14
Terminal window
# ❌ WRONG: Orphaned accounts remain active
# Employee leaves but account still works!
# ✅ CORRECT: Implement lifecycle management
# Automated deprovisioning when HR system shows termination
userdel -r username # Remove user and home
# Or use identity management tools
Terminal window
# ❌ WRONG: Too much sudo access
username ALL=(ALL) NOPASSWD: ALL # Can do anything without password!
# ✅ CORRECT: Principle of least privilege
username ALL=(ALL) /usr/bin/systemctl restart myapp
username ALL=(ALL) /usr/bin/nginx, /usr/bin/systemctl nginx

In this chapter, you learned:

  • ✅ User account concepts and types
  • ✅ User database files (passwd, shadow)
  • ✅ Creating users with useradd
  • ✅ Modifying users with usermod
  • ✅ Deleting users
  • ✅ Managing passwords
  • ✅ Password aging policies
  • ✅ User information commands
  • ✅ User environment setup
  • ✅ Troubleshooting user issues
  • ✅ Interview questions and answers

Chapter 7: Group Management


Last Updated: February 2026