RED HAT ENTERPRISE LINUX

Managing Users, Groups, and Superuser Access

Local Account Administration and Password Policies

CIS126RH | RHEL System Administration 1
Mesa Community College

Learning Objectives

1
Obtain superuser access

Use su and sudo to run commands with elevated privileges

2
Create and manage local users

Add, modify, and delete user accounts with useradd, usermod, userdel

3
Manage local groups

Create groups and manage memberships with groupadd, groupmod, gpasswd

4
Administer password policies

Configure password aging and account expiration with chage

The Root User

root (UID 0) is the superuser account with unrestricted access to the entire system. Root can read any file, modify any setting, and execute any command.

Root Can:

  • Read/write any file on the system
  • Install and remove software
  • Manage all users and groups
  • Configure network and services
  • Mount filesystems
  • Change ownership and permissions

Dangers of Root:

  • Typos can be catastrophic
  • No confirmation for destructive actions
  • Malware runs with full privileges
  • Hard to audit who did what
  • Accidents affect entire system
  • No "undo" for many operations

Root: Best Practice

Best Practice: Never log in directly as root. Use sudo for individual commands instead.
Using sudo instead of root login provides three key benefits:
  • Accountability — logs show exactly who ran which command
  • Reduced exposure — elevated privileges only for the duration of one command
  • Limited blast radius — mistakes in a normal shell can't destroy the system
RHEL 8 and later allow installation with root login disabled entirely, forcing sudo usage from the start.

Switching Users: su

# Switch to root (prompts for root password)
[student@server ~]$ su
Password: [enter root password]
[root@server student]#

# Switch to root WITH login environment (recommended)
[student@server ~]$ su -
Password:
[root@server ~]#

# Switch to another user
[student@server ~]$ su - jsmith
Password: [enter jsmith's password]
[jsmith@server ~]$

# Run single command as another user
[student@server ~]$ su -c "whoami" jsmith
jsmith

# Exit back to original user
[root@server ~]# exit
[student@server ~]$

su vs su -

su (without dash)

  • Switches to root user
  • Keeps your current environment
  • Keeps your PATH, variables
  • Working directory unchanged

su - (with dash)

  • Switches to root user
  • Loads root's full environment
  • Root's PATH and variables
  • Changes to root's home directory
Always use su - when becoming root to ensure you have the proper environment for administrative commands. Many admin tools are only in root's PATH.
Limitation: su requires knowing the target user's password. For root access, this means sharing the root password — problematic for auditing.

Elevated Privileges: sudo

sudo (superuser do) runs a single command with elevated privileges. Users authenticate with their own password and must be authorized in the sudoers configuration.
# Run command as root
[student@server ~]$ sudo systemctl restart httpd
[sudo] password for student: [enter YOUR password]

# Run command as specific user
[student@server ~]$ sudo -u apache cat /etc/httpd/conf/httpd.conf

# Open root shell (use sparingly)
[student@server ~]$ sudo -i
[root@server ~]#

# List your sudo privileges
[student@server ~]$ sudo -l

sudo Advantages

Security Benefits

  • No shared root password
  • Users authenticate with own password
  • Every command is logged
  • Per-command authorization
  • 5-minute password cache

Useful Options

  • sudo -u user — run as different user
  • sudo -i — interactive root shell
  • sudo -l — list allowed commands
  • sudo whoami — verify you become root
Audit trail: every sudo command is logged to /var/log/secure. This accountability is a major advantage over sharing the root password.

sudo Configuration

# ALWAYS edit sudoers safely with visudo
[root@server ~]# visudo

# sudoers syntax: who where=(as_whom) what

# Full sudo access for one user
student    ALL=(ALL)    ALL

# Allow without password
operator   ALL=(ALL)    NOPASSWD: ALL

# Limit to specific commands only
backup     ALL=(ALL)    /usr/bin/rsync, /usr/bin/tar

# Group-based access (note the %)
%wheel     ALL=(ALL)    ALL
%admins    ALL=(ALL)    NOPASSWD: /usr/bin/systemctl
⚠ Always use visudo! It validates syntax before saving. A broken sudoers file can lock you out of sudo entirely.

sudoers Drop-in Files

# Best practice: use drop-in files in /etc/sudoers.d/
[root@server ~]# cat /etc/sudoers.d/student
student    ALL=(ALL)    ALL
Rather than editing /etc/sudoers directly, create files in /etc/sudoers.d/. These are included automatically, are easier to manage, and work well with configuration management tools like Ansible.
Files in /etc/sudoers.d/ must not contain dots in the filename — a file named student.conf will be ignored.
NOPASSWD allows commands without entering a password — useful for scripts and automation, but reduces security. Use with care and limit to specific commands when possible.

The wheel Group

On RHEL, the wheel group grants sudo access to its members. This is the standard way to allow users administrative privileges.
# Add user to wheel group for sudo access
[root@server ~]# usermod -aG wheel student

# Verify membership
[student@server ~]$ groups
student wheel

# Check the sudoers configuration
[root@server ~]# grep wheel /etc/sudoers
%wheel  ALL=(ALL)       ALL

# New group membership takes effect on next login
# Or use newgrp for the current session:
[student@server ~]$ newgrp wheel

# Verify sudo works
[student@server ~]$ sudo whoami
root
RHCSA Tip: To grant a user administrative privileges on RHEL, add them to the wheel group: usermod -aG wheel username

User Account Files

FilePurposePermissions
/etc/passwdUser account information644 (world-readable)
/etc/shadowEncrypted passwords, aging000 (root only)
/etc/groupGroup definitions644 (world-readable)
/etc/gshadowGroup passwords (rarely used)000 (root only)
/etc/login.defsDefault settings for useradd644
/etc/default/useraddAdditional useradd defaults644
Never edit these files directly! Use the provided commands (useradd, usermod, passwd, etc.) to ensure consistency and proper file locking.

Understanding /etc/passwd

student:x:1000:1000:Student User:/home/student:/bin/bash
FieldNameDescription
1UsernameLogin name (max 32 characters)
2Passwordx = password in /etc/shadow
3UIDUser ID number (0 = root)
4GIDPrimary group ID
5GECOSComment / full name
6HomeHome directory path
7ShellLogin shell (/sbin/nologin = no login)
[user@host ~]$ grep student /etc/passwd
student:x:1000:1000:Student User:/home/student:/bin/bash

UID Ranges

System Accounts (0–999)

root (0), bin, daemon, apache, nobody, etc.
Run services, no interactive login.

Regular Users (1000–60000)

Normal user accounts. First user typically gets UID 1000.

# Check UID range configuration
[root@server ~]# grep -E "^UID_MIN|^UID_MAX|^SYS_UID" /etc/login.defs
UID_MIN                  1000
UID_MAX                 60000
SYS_UID_MIN               201
SYS_UID_MAX               999

# Create system user (UID below 1000)
useradd -r -s /sbin/nologin myservice

# Verify with id
[root@server ~]# id myservice
uid=987(myservice) gid=984(myservice) groups=984(myservice)

Creating Users: useradd

# Create user with defaults
[root@server ~]# useradd jsmith

# Create user with common options
[root@server ~]# useradd -c "John Smith" -s /bin/bash -m -d /home/jsmith jsmith

# Specify UID
useradd -u 1500 username

# Specify primary group
useradd -g developers username

# Add to supplementary groups at creation
useradd -G wheel,dev username

# Set no interactive login (service accounts)
useradd -s /sbin/nologin svc

useradd More Options

# Set account expiration date at creation
useradd -e 2025-12-31 temp

# Create system account (UID below 1000)
useradd -r serviceacct

# View defaults that would be applied
[root@server ~]# useradd -D
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
useradd -D shows the default values applied to new accounts — and can also be used to change those defaults. The SKEL directory (/etc/skel) contains template files copied into every new home directory.

Setting Passwords

# Set/change password interactively (as root)
[root@server ~]# passwd jsmith
Changing password for user jsmith.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.

# User changes their own password
[jsmith@server ~]$ passwd
Changing password for user jsmith.
Current password:

# Force password change at next login
[root@server ~]# passwd -e jsmith

# Lock / unlock an account
[root@server ~]# passwd -l jsmith   # Lock
[root@server ~]# passwd -u jsmith   # Unlock

passwd: Non-Interactive Use

# Set password non-interactively (for scripts)
[root@server ~]# echo "newpassword" | passwd --stdin jsmith
⚠ Security Note: The --stdin method puts the password in shell history and process listings. Use carefully — or not at all in production. Consider Ansible Vault or other secret managers for automation.
Common workflow for new accounts:
  1. Create account with useradd
  2. Set a temporary password with passwd
  3. Expire it immediately with passwd -e username
  4. User must set their own password at first login

Modifying Users: usermod

# Change user's comment (full name)
[root@server ~]# usermod -c "John A. Smith" jsmith

# Change login shell
[root@server ~]# usermod -s /bin/zsh jsmith

# Add to supplementary groups (ALWAYS use -aG together!)
[root@server ~]# usermod -aG wheel jsmith
[root@server ~]# usermod -aG wheel,developers jsmith

# Change primary group
[root@server ~]# usermod -g developers jsmith

# Lock / unlock account
[root@server ~]# usermod -L jsmith    # Lock
[root@server ~]# usermod -U jsmith    # Unlock
CRITICAL: Always use -aG together when adding groups! Using -G alone REMOVES the user from all other supplementary groups!

usermod: Rename & Relocate

# Change username
[root@server ~]# usermod -l johnsmith jsmith
# Note: does NOT rename the home directory automatically

# Move home directory to new location
[root@server ~]# usermod -d /home/johnsmith -m johnsmith
# -m moves files from old location to new
When renaming a user with -l, the home directory path is not automatically renamed. Use a separate usermod -d /new/path -m username command to also move the home directory.
For the RHCSA exam, the -aG pattern for adding users to groups is especially important. Other frequently tested options: -s (shell), -c (comment), -L/-U (lock/unlock).

Deleting Users: userdel

# Delete user (keeps home directory)
[root@server ~]# userdel jsmith

# Delete user AND home directory
[root@server ~]# userdel -r jsmith

# Force delete even if user is logged in
[root@server ~]# userdel -f jsmith

Without -r

  • Home directory remains
  • Mail spool remains
  • Files outside home become orphaned

With -r

  • Home directory removed
  • Mail spool removed
  • Files outside home still orphaned

userdel: Orphaned Files

# Before deleting: find what they own outside home
[root@server ~]# find / -user jsmith 2>/dev/null

# After deletion: find orphaned files (no matching user)
[root@server ~]# find / -nouser 2>/dev/null
Orphaned files risk: When you delete a user, files they owned outside their home directory remain owned by a numeric UID that no longer maps to a username. If a new user later receives the same UID, they'll inherit those files.
Always run find / -user username before deleting a user to audit what files exist outside the home directory. After deletion, use find / -nouser to locate any orphaned files.

Managing Groups

# Create a new group
[root@server ~]# groupadd developers

# Create group with specific GID
[root@server ~]# groupadd -g 5000 webteam

# Create system group
[root@server ~]# groupadd -r appgroup

# Modify group — change name
[root@server ~]# groupmod -n devteam developers

# Modify group — change GID
[root@server ~]# groupmod -g 6000 devteam

# Delete a group
[root@server ~]# groupdel devteam

# View group information
[root@server ~]# getent group developers
developers:x:5001:jsmith,ajones

# View a user's groups
[student@server ~]$ groups
student wheel developers

Group Membership

# Add user to group (preferred method)
[root@server ~]# usermod -aG developers jsmith

# Add user using gpasswd
[root@server ~]# gpasswd -a jsmith developers
Adding user jsmith to group developers

# Remove user from group
[root@server ~]# gpasswd -d jsmith developers
Removing user jsmith from group developers

# Designate group administrator
[root@server ~]# gpasswd -A jsmith developers

# List group members
[root@server ~]# getent group developers
developers:x:5001:jsmith,ajones,bwilson
Primary vs Supplementary: Users have ONE primary group (determines ownership of new files) and can have MULTIPLE supplementary groups (for access control).

Understanding /etc/shadow

jsmith:$6$xyz...:19500:0:99999:7:::
FieldNameDescription
1UsernameLogin name
2Password HashEncrypted password (!! = no password, ! prefix = locked)
3Last ChangeDays since Jan 1, 1970 of last password change
4Min AgeDays before password can be changed
5Max AgeDays before password must be changed
6WarningDays of warning before expiration
7InactiveGrace days after expiration before account locks
8ExpirationDays since epoch when account itself expires

/etc/shadow: Password Hash Prefixes

Algorithm Prefixes

  • $6$ — SHA-512 (current default)
  • $5$ — SHA-256
  • $y$ — yescrypt (newer systems)

Special Values

  • !! — no password set (account unusable)
  • ! prefix — account is locked
  • * — account disabled (system account)
The /etc/shadow file is readable only by root (permissions 000 with special kernel handling) to protect password hashes from offline cracking attempts.

Password Aging: chage

# View current aging settings
[root@server ~]# chage -l jsmith
Last password change                              : Dec 01, 2025
Password expires                                  : Mar 01, 2026
Password inactive                                 : never
Account expires                                   : never
Minimum number of days between password change    : 0
Maximum number of days between password change    : 90
Number of days of warning before password expires : 7
chage -l username is your go-to command for checking a user's complete password and account status in human-readable format.

chage Options

# Set maximum password age (90 days)
[root@server ~]# chage -M 90 jsmith

# Set minimum age (prevent immediate cycling)
[root@server ~]# chage -m 1 jsmith

# Set warning period (14 days before expiration)
[root@server ~]# chage -W 14 jsmith

# Set inactive period (grace period after expiration)
[root@server ~]# chage -I 30 jsmith

# Force password change at next login
[root@server ~]# chage -d 0 jsmith
chage -d 0 sets the last-change date to day 0 (before the epoch), making the password appear expired — forcing a change at next login. Use this after setting a temporary password for a new account.

Account Expiration

# Set account expiration date
[root@server ~]# chage -E 2025-12-31 contractor

# Alternative: use usermod
[root@server ~]# usermod -e 2025-12-31 contractor

# Remove account expiration (never expires)
[root@server ~]# chage -E -1 contractor

# Interactive mode — prompts for all values
[root@server ~]# chage contractor

# Verify account status
[root@server ~]# chage -l contractor | grep "Account expires"
Account expires                         : Dec 31, 2025
Use Case: Account expiration is perfect for contractors, interns, and temporary employees — set it when creating the account and it auto-disables on schedule.

Account vs Password Expiration

Password Expiration (-M)

  • Forces user to change their password
  • Login is still allowed
  • User is prompted to set a new password
  • After inactive period → account locks

Account Expiration (-E)

  • Completely prevents login
  • No password prompt shown
  • Regardless of password status
  • Admin must re-enable the account
Remember: password expiration (-M) allows login but forces a change. Account expiration (-E) completely prevents login after the date, regardless of password status.

Default Policies

# View current defaults
[root@server ~]# grep PASS /etc/login.defs
PASS_MAX_DAYS   99999
PASS_MIN_DAYS   0
PASS_MIN_LEN    5
PASS_WARN_AGE   7

# Edit to set organization policy
[root@server ~]# vim /etc/login.defs
# Change to:
PASS_MAX_DAYS   90
PASS_MIN_DAYS   1
PASS_MIN_LEN    12
PASS_WARN_AGE   14
⚠ Important: Changes to /etc/login.defs only affect newly created users. Use chage to update existing accounts.

Applying Policy to Existing Users

# Apply policy to an existing user
[root@server ~]# chage -M 90 -m 1 -W 14 existinguser

# Apply to ALL regular users (UID >= 1000)
[root@server ~]# for user in $(awk -F: '$3 >= 1000 {print $1}' /etc/passwd); do
    chage -M 90 -m 1 -W 14 "$user"
done
In enterprise environments, configuration management tools like Ansible can apply these settings consistently across all users and systems automatically.
For the RHCSA exam: know how to set defaults for new users (/etc/login.defs) AND how to modify existing users (chage). You may be asked to ensure all users meet a particular policy.

Key Takeaways

1

Superuser access: Use sudo for individual commands, avoid logging in as root. Add users to the wheel group.

2

User management: useradd, usermod, userdel, passwd — set passwords after creating users!

3

Groups: groupadd, usermod -aG (always use -aG together!), gpasswd

4

Password policy: chage -M (max age), -m (min), -W (warn), -E (account expiration)

Graded Lab

HANDS-ON EXERCISES

  • Set a default password aging policy for local users
  • Create and use a supplementary group for new users
  • Create three users with the new supplementary group
  • Set an initial password for the created users
  • Configure the supplementary group members to use sudo to run any command as any user
  • Set a user-specific password aging policy

Next: Controlling Access to Files