courses

User Management

Identity is the basis of every access decision

Linux is a multi-user OS: every process runs as a user, every file is owned by one, and the kernel makes every access-control decision based on user and group identity. Managing users and groups is therefore not just an admin chore — it is where the subjects of the access-control model actually get created, and where a careless usermod -aG sudo or a forgotten UID-0 account becomes a privilege-escalation problem.

This page covers creating/modifying/deleting users (useradd, usermod, userdel, passwd), the underlying account files (/etc/passwd, /etc/shadow, /etc/group), groups and membership, POSIX ACLs for finer-grained access, sudo, and password-aging policy (chage). For the permission-bit model it builds on, see Working with Files; for authentication and password security broadly, see Identity and Access Management.

Create, Delete, and Update Users

Key files

File Contents
/etc/passwd User accounts: name, UID, GID, home, shell
/etc/shadow Hashed passwords and aging information (root-readable)
/etc/group Group definitions: name, GID, members
/etc/gshadow Group passwords and administrators
/etc/skel/ Template files copied to new home directories

useradd — create a new user

useradd alice                            # create alice with defaults
useradd -m alice                         # create with home directory
useradd -m -s /bin/bash alice            # set login shell
useradd -m -c "Alice Smith" alice        # set comment (full name)
useradd -m -u 1500 alice                 # set specific UID
useradd -m -g staff alice                # set primary group
useradd -m -G sudo,docker alice          # add to supplementary groups
useradd -m -e 2026-12-31 alice           # set account expiry date
useradd -r svcuser                       # create system account (no home, no login)
useradd -D                               # show current defaults

Note: On Debian/Ubuntu, adduser is a friendlier wrapper around useradd that creates the home directory and prompts for a password interactively.

adduser alice           # Debian/Ubuntu: interactive, creates home directory

passwd — set and manage passwords

passwd alice                # set alice's password (root)
passwd                      # change your own password
passwd -l alice             # lock account (prepends ! to hash)
passwd -u alice             # unlock account
passwd -e alice             # expire password (force change at next login)
passwd -d alice             # delete password (passwordless login, dangerous)
passwd -S alice             # show password status
chage -l alice              # show detailed password aging info

usermod — modify an existing user

usermod -l newname alice            # rename account (login name)
usermod -d /new/home alice          # change home directory
usermod -d /new/home -m alice       # change and move home directory
usermod -s /bin/zsh alice           # change login shell
usermod -aG docker alice            # append to supplementary group (use -a!)
usermod -G sudo alice               # set supplementary groups (replaces existing)
usermod -e 2026-12-31 alice         # set expiry date
usermod -L alice                    # lock account
usermod -U alice                    # unlock account
usermod -u 1501 alice               # change UID

⚠️ usermod -G without -a replaces all supplementary group memberships. Always use -aG to append a user to a group; a bare -G sudo would silently drop them from every other group they were in.

userdel — delete a user

userdel alice                # remove account but keep home directory
userdel -r alice             # remove account AND home directory and mail spool

chsh and chfn — change shell and finger info

chsh -s /bin/zsh             # change your own shell
chsh -s /bin/bash alice      # change alice's shell (root)
chfn alice                   # change full name, phone, etc.
cat /etc/shells              # list valid login shells

Worked example — create a service account:

useradd -r -s /usr/sbin/nologin -d /var/lib/myapp -c "MyApp Service" myapp
mkdir -p /var/lib/myapp
chown myapp:myapp /var/lib/myapp

Users and Groups

Understanding UIDs and GIDs

Reading /etc/passwd

alice:x:1001:1001:Alice Smith:/home/alice:/bin/bash
^     ^ ^    ^    ^           ^           ^
|     | |    |    |           |           login shell
|     | |    |    |           home directory
|     | |    |    GECOS (comment/full name)
|     | |    primary GID
|     | UID
|     password placeholder (x = hash in /etc/shadow)
username
getent passwd alice          # look up user (works with local and LDAP)
getent passwd                # all users
id alice                     # show UID, GID, groups
id                           # show your own identity

groupadd, groupmod, groupdel — manage groups

groupadd developers          # create group
groupadd -g 2000 developers  # create with specific GID
groupmod -n devs developers  # rename group
groupdel developers          # delete group (users not deleted, lose membership)

Managing group membership

# Add user to a group
usermod -aG groupname username
gpasswd -a alice developers   # alternative

# Remove user from a group
gpasswd -d alice developers

# Set group administrators
gpasswd -A alice developers

# List members of a group
getent group developers
grep developers /etc/group

su and login as another user

su alice                     # switch to alice (keep current environment)
su - alice                   # switch to alice with full login environment
su -                         # switch to root
exit                         # return to previous user

who and id

who                          # logged-in users
who am i                     # your login session info
id                           # your UID, GID, and groups
id alice                     # alice's UID, GID, and groups
groups                       # your group memberships
groups alice                 # alice's group memberships

Worked example — check user configuration:

getent passwd alice
id alice
groups alice
chage -l alice               # password aging policy

Managing Permissions

See the Working with Files page for full coverage of chmod, chown, and the permission bit model. This section covers additional permission-related tools.

Access Control Lists (ACLs)

Standard Unix permissions allow one owner, one group, and “other.” ACLs extend this to grant specific permissions to any user or group.

# View ACLs
getfacl file.txt

# Set ACL for a specific user
setfacl -m u:alice:rw file.txt        # give alice read/write
setfacl -m u:bob:r file.txt           # give bob read only
setfacl -m g:devs:rx directory/       # give devs group read/execute

# Default ACLs (inherited by new files in a directory)
setfacl -d -m u:alice:rw shared_dir/

# Remove an ACL entry
setfacl -x u:alice file.txt

# Remove all ACLs
setfacl -b file.txt

# Copy ACLs from one file to another
getfacl source.txt | setfacl --set-file=- dest.txt

A + at the end of the permission bits in ls -l output indicates an ACL is set:

-rw-rw-r--+ 1 alice staff  1234 May 1 12:00 file.txt

sudo — controlled privilege escalation

sudo command                    # run as root
sudo -u bob command             # run as bob
sudo -l                         # list your sudo privileges
sudo visudo                     # safely edit /etc/sudoers

/etc/sudoers syntax:

# Format: who  where=(as_whom) command
alice   ALL=(ALL:ALL) ALL           # alice can run anything as anyone
%wheel  ALL=(ALL) NOPASSWD: ALL     # wheel group: no password required
deploy  ALL=(ALL) NOPASSWD: /bin/systemctl restart nginx

chage — password aging policy

chage -l alice                  # list current aging settings
chage -M 90 alice               # maximum 90 days before password must change
chage -m 7 alice                # minimum 7 days between changes
chage -W 14 alice               # warn 14 days before expiry
chage -E 2026-12-31 alice       # account expires on date
chage -I 30 alice               # lock after 30 days of inactivity
chage -d 0 alice                # force password change on next login

Restricting access

# Prevent login (for service accounts)
usermod -s /usr/sbin/nologin alice
usermod -s /bin/false alice

# Lock an account
passwd -l alice
usermod -L alice

# Check for accounts with no password (security audit)
awk -F: '($2 == "" ) { print $1 }' /etc/shadow

# Check for UID 0 accounts other than root (security audit)
awk -F: '($3 == 0) { print $1 }' /etc/passwd

# List accounts that can log in (have valid shell)
grep -v '/nologin\|/false' /etc/passwd | cut -d: -f1

Worked example — set up a developer with appropriate access:

# Create user with home directory
useradd -m -s /bin/bash -c "Dev User" devuser

# Set password
passwd devuser

# Add to relevant groups
usermod -aG docker,sudo devuser

# Set password policy
chage -M 90 -W 14 devuser

# Verify
id devuser
chage -l devuser

Key takeaways

References


Related course pages: Access Control and Authorization · Working with Files · Shell and Other Basics · Identity and Access Management · Host Security

🛠️ Maintenance note: these tools are stable. Watch for the gradual shift from shadow-utils defaults toward systemd-homed/systemd-userdbd on newer systemd systems, and confirm the default login shell (Kali ships zsh) — verify useradd -D output on the course VM each term.