User Management
- 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,
adduseris a friendlier wrapper arounduseraddthat 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 -Gwithout-areplaces all supplementary group memberships. Always use-aGto append a user to a group; a bare-G sudowould 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
- UID 0: root — full system access
- UID 1–999: system accounts (daemons, services)
- UID 1000+: regular users
- Each user has a primary group (set in
/etc/passwd) and optional supplementary groups (listed in/etc/group)
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
- Accounts live in
/etc/passwd(identity) and/etc/shadow(root-only password hashes); UID 0 is root, 1–999 are system accounts, 1000+ are regular users. -
useradd/usermod/userdelmanage accounts (adduseris the friendlier Debian wrapper); always useusermod -aGto add groups without clobbering existing membership. -
POSIX ACLs (
setfacl/getfacl) extend the one-owner/one-group/other model to grant specific users or groups access — a+inls -lflags a file with ACLs. -
sudo(edited viavisudo) grants controlled, logged privilege escalation — the place to apply least privilege;sudo -lshows what’s allowed. -
chagesets password-aging policy; theawkaudits for empty-password and extra UID-0 accounts are quick wins on any host you’re securing.
References
- W. Shotts, The Linux Command Line — users and permissions chapters. https://linuxcommand.org/tlcl.php
-
useradd(8),usermod(8),passwd(1),chage(1)man pages (shadow-utils). https://man7.org/linux/man-pages/man8/useradd.8.html -
setfacl(1)/getfacl(1)— POSIX ACLs (Linuxaclpackage). https://man7.org/linux/man-pages/man1/setfacl.1.html -
passwd(5)andshadow(5)— the account file formats. https://man7.org/linux/man-pages/man5/passwd.5.html
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 -Doutput on the course VM each term.