Every process and file on a Linux system is owned by a user and a group. Access control decisions โ who can read, write, or execute โ are made by comparing ownership and permissions. Understanding users and groups is fundamental to Linux security and administration.
This page covers the core files, concepts,
and everyday commands for managing users and groups. Part 2 covers
advanced topics like password aging and bulk operations. Part 3 covers
sudo and privilege management.
One line per user. Contains username, UID, GID, home directory, shell. World-readable.
Hashed passwords and password aging info. Root-readable only.
One line per group. Contains group name, GID, member list. World-readable.
Group passwords and administrators. Root-readable only.
Defaults for UID/GID ranges, password aging, home directory creation.
Template files copied to new user home directories on creation.
Fields: username ยท x (password in shadow) ยท
UID ยท primary GID ยท GECOS/comment ยท
home directory ยท login shell
| Range | Purpose |
|---|---|
| 0 | root โ superuser |
| 1โ199 | System accounts (distro-assigned) |
| 200โ999 | System accounts (dynamically assigned by dnf/apt) |
| 1000+ | Regular user accounts |
# Show current user whoami id # UID, GID, and all group memberships id craig # info for another user # Show all groups current user belongs to groups groups craig # Query the user database (works with LDAP/NIS too) getent passwd craig getent passwd | sort -t: -k3 -n # all users sorted by UID # Query group database getent group craig getent group | sort -t: -k3 -n # all groups sorted by GID # Who is logged in right now who w # more detail โ what they are running last | head -20 # login history lastlog # last login for every accountid output:
getent passwd
instead of cat /etc/passwd โ getent queries all configured
name service sources including LDAP, NIS, and SSSD. On systems with
central directory services, cat /etc/passwd only shows
local accounts.
# Create a basic user (home directory created automatically on RHEL) sudo useradd alice # Create with home directory explicitly (required on some Debian systems) sudo useradd -m alice # Create with full options sudo useradd \ -m \ # create home directory -d /home/alice \ # home directory path -s /bin/bash \ # login shell -c "Alice Smith" \ # GECOS comment/full name -u 1500 \ # specific UID -g staff \ # primary group -G developers,sysadmin \ # supplementary groups alice # Create a system account (no home, no login) sudo useradd -r -s /sbin/nologin appservice # Set password immediately after creation sudo passwd alice # Create user with password in one command (scripting) sudo useradd -m -p $(openssl passwd -6 'TempPass123!') alice # Verify creation getent passwd alice ls -la /home/alice
useradd creates the home directory by default
(CREATE_HOME yes in /etc/login.defs).
On Debian/Ubuntu, you must explicitly pass -m.
Always use -m to be safe and portable.
# Change login shell sudo usermod -s /bin/bash alice sudo usermod -s /sbin/nologin alice # disable login # Change home directory (and move contents) sudo usermod -d /data/alice -m alice # Change full name / comment sudo usermod -c "Alice B. Smith" alice # Change username sudo usermod -l alicesmith alice # Lock an account (prepends ! to password hash) sudo usermod -L alice sudo passwd -l alice # equivalent # Unlock an account sudo usermod -U alice sudo passwd -u alice # equivalent # Add user to supplementary groups (APPEND โ critical) sudo usermod -aG wheel alice sudo usermod -aG developers,sysadmin alice # Change primary group sudo usermod -g newgroup alice
usermod -G groupname user
without -a replaces ALL supplementary groups with just the
one specified โ removing the user from every other group they were in.
-aG appends. This is one of the most common accidental
privilege removal mistakes in Linux administration.
# Delete user account (keeps home directory) sudo userdel alice # Delete user AND home directory AND mail spool sudo userdel -r alice # Find files owned by a user before deletion sudo find / -user alice -ls 2>/dev/null # Find files by UID (useful after account is deleted) sudo find / -uid 1500 -ls 2>/dev/null # Change ownership of orphaned files before deletion sudo find / -user alice -exec chown newowner {} \;
sudo usermod -L alicesudo find / -user alice -lssudo tar -czf /archive/alice.tar.gz /home/alicesudo userdel -r alice# Create a group sudo groupadd developers sudo groupadd -g 5000 datateam # specific GID sudo groupadd -r appservice # system group # Add user to a group sudo usermod -aG developers alice sudo gpasswd -a alice developers # alternative # Remove user from a group sudo gpasswd -d alice developers # List group members getent group developers grep developers /etc/group # Change group name sudo groupmod -n devteam developers # Change group GID sudo groupmod -g 5001 developers # Delete a group sudo groupdel developers # Set group administrators (can add/remove members) sudo gpasswd -A alice developers
newgrp developersThis starts a new shell with
developers as the primary group.
Files created in this shell will be owned by the developers
group. Exit the shell to return to your original primary group.
# Set/change a user's password sudo passwd alice # Force password change on next login sudo passwd -e alice sudo chage -d 0 alice # equivalent # Lock / unlock account sudo passwd -l alice sudo passwd -u alice # Show password aging info sudo chage -l alice # Set password expiry (90 days) sudo chage -M 90 alice # Set account expiry date sudo chage -E 2026-12-31 alice # Set warning before expiry (7 days) sudo chage -W 7 alicechage -l alice output:
# Show file ownership ls -la /home/alice/ stat /home/alice/myfile.txt # Change file owner sudo chown alice myfile.txt sudo chown alice:developers myfile.txt # owner and group sudo chown :developers myfile.txt # group only # Change recursively sudo chown -R alice:developers /var/www/myapp/ # Change group only sudo chgrp developers myfile.txt sudo chgrp -R developers /var/www/myapp/ # Set permissions chmod 644 myfile.txt # rw-r--r-- chmod 755 myscript.sh # rwxr-xr-x chmod 700 ~/.ssh # rwx------ chmod 600 ~/.ssh/id_rsa # rw------- # Set group sticky bit on directory # (new files inherit the directory's group) sudo chmod g+s /var/www/myapp/ sudo chmod 2775 /var/www/myapp/
chmod g+s)
is essential for shared project directories. Without it, files created
in /var/www/myapp/ are owned by the creating user's
primary group โ which may not be developers. With setgid,
all new files inherit the directory's group automatically.
A practical script that brings together the full user creation workflow:
#!/bin/bash # new-employee.sh โ provision a new user account USERNAME=$1 FULLNAME=$2 DEPT_GROUP=$3 # e.g., developers, sysadmin, finance if [[ -z "$USERNAME" || -z "$FULLNAME" || -z "$DEPT_GROUP" ]]; then echo "Usage: $0 username 'Full Name' department_group" exit 1 fi # Create user account sudo useradd \ -m \ -s /bin/bash \ -c "$FULLNAME" \ -G "$DEPT_GROUP",users \ "$USERNAME" # Force password change on first login sudo chage -d 0 "$USERNAME" # Set a temporary password TEMP_PASS="Welcome$(date +%Y)!" echo "$USERNAME:$TEMP_PASS" | sudo chpasswd # Set up SSH directory sudo mkdir -p /home/"$USERNAME"/.ssh sudo chmod 700 /home/"$USERNAME"/.ssh sudo chown "$USERNAME":"$USERNAME" /home/"$USERNAME"/.ssh # Add to wheel/sudo if sysadmin if [[ "$DEPT_GROUP" == "sysadmin" ]]; then sudo usermod -aG wheel "$USERNAME" echo "Note: $USERNAME added to wheel group" fi echo "Account created: $USERNAME ($FULLNAME)" echo "Temp password: $TEMP_PASS" echo "Must change password on first login."
| Command | What it does |
|---|---|
| id [user] | Show UID, GID, and group memberships |
| groups [user] | List group memberships |
| whoami | Current username |
| getent passwd user | Query user from all sources (local + LDAP) |
| getent group group | Query group from all sources |
| useradd -m -s /bin/bash user | Create user with home and bash shell |
| useradd -r -s /sbin/nologin svc | Create system/service account |
| passwd user | Set or change password |
| usermod -aG group user | Add user to supplementary group |
| usermod -L user | Lock account |
| usermod -U user | Unlock account |
| usermod -s /sbin/nologin user | Disable login shell |
| userdel -r user | Delete user and home directory |
| groupadd group | Create a group |
| gpasswd -a user group | Add user to group |
| gpasswd -d user group | Remove user from group |
| groupdel group | Delete a group |
| chage -l user | Show password aging info |
| chage -M 90 user | Set 90-day password expiry |
| chown user:group file | Change file owner and group |
| chmod g+s dir | Set setgid on directory |