Users, groups and privilege
Accounts, groups, sudo rules and the safe ways to move between identities without handing out root.
Accounts, UID and the password files
Every process runs as a numeric user id. Names are only a convenience: the kernel checks the UID and GID, and root is simply UID 0. That one fact explains most privilege questions.
| File | Holds | Notes |
|---|---|---|
/etc/passwd | name:uid:gid:comment:home:shell | World-readable; never contains a password |
/etc/shadow | Hashes and password ageing | Root only; change it with passwd or chage |
/etc/group | Group names and members | Also visible through id |
/etc/sudoers | Who may run what as whom | Edit with visudo only |
whoami # effective user name
id # uid, gid and every supplementary group
groups
getent passwd ada # resolves through NSS, so LDAP/SSSD accounts work too
getent passwd www-data # a service account: no login shell by design- UIDs below 1000 are system accounts used by daemons; human accounts normally start at 1000.
- A shell shows the groups you were given at login, so a new group appears only in a fresh session.
- A file owned by UID 1001 shows as a number when that account is deleted — a common symptom of leftover files.
Creating and modifying accounts
sudo groupadd developers
# -m creates the home directory, -s sets the shell, -G adds groups at creation
sudo useradd -m -s /bin/bash -G developers,sudo ada
sudo passwd ada # set the initial password
sudo chage -l ada # password expiry policy
sudo chage -M 90 -W 14 ada # expire after 90 days, warn 14 days ahead
sudo usermod -aG docker ada # APPEND to a group
sudo usermod -L ada # lock the account (disable password login)
sudo userdel -r ada # delete the account and its home directory
sudo passwd -S ada # is the password set, locked or expired?⚠️
usermod -G without -a replaces the whole supplementary group list, silently removing access. Always type -aG, and remember that an unlocked account with SSH keys can still log in after -L — remove the keys or lock the shell if you mean to revoke access.Delegating privilege with sudo
sudo -l # what am I allowed to run?
sudo -u postgres psql # run one command as another user
sudo -i # interactive root login shell
sudo -s # root shell that keeps your environment
sudo visudo # validates syntax before saving
sudo visudo -f /etc/sudoers.d/deploy# /etc/sudoers.d/deploy
# %group syntax applies to every member of the group
%developers ALL=(ALL) ALL
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/systemctl status nginx- Grant a specific command rather than a shell:
NOPASSWD: /usr/bin/systemctl restart nginxis narrow,NOPASSWD: ALLis root without the password. sudo -iresets the environment for a clean root session;sudo -skeeps your aliases and variables, which can surprise you.- Every privileged command is logged. Check
journalctl -t sudoor/var/log/auth.logwhen auditing.
FAQ
Why is 'sudo: command not found' shown for a command I can run myself?
Your
PATH is not inherited by the root shell (secure_path in sudoers). Use the absolute path, or add the directory to secure_path after thinking about whether you want to.How do I give a service access to a file without chmod 777?
Create a shared group,
chgrp the resource to it, chmod 640 or 750, then add both accounts to that group. Set the directory's group-sticky bit (chmod g+s) so new files inherit it.Related
Installing software across distributions Disks, filesystems and mounts
Last refreshed 2026-09-18.