Users and Permissions
Linux's security model is three questions applied to every file: who owns it, what group, and what do the three classes — owner, group, other — get to do? rwxr-xr-- is a contract printed in nine bits. This chapter reads the contract fluently, then goes deeper: the special bits, umask, the password machinery, and sudo's precise delegation of root.
Reading the contract
ls -l file
# -rwxr-xr-- 1 alice devs 4096 Jan 5 file
# ^ the leading char = type: - file, d dir, l symlink, c/b devices
# rwx r-x r-- = owner rwx · group r-x · other r--
r=4, w=2, x=1 — modes as octal: 755 = rwxr-xr-x, 644 = rw-r--r--, 600 = rw-------. On directories x means enterable — a dir with rw but no x is unreadable-inside despite looking writable.
chmod 755 script.sh # octal
chmod u+x script.sh # symbolic — add exec to owner
chmod go-w file # remove write from group+other
chmod -R 644 dir/ # recursive — usually a mistake on dirs+files mixed
chown alice file # change owner
chown alice:devs file # owner + group
chgrp devs file # group only
The special bits — beyond rwx
Three extra bits change behavior fundamentally:
chmod 4755 program # SETUID — runs as the FILE's owner (passwd does this)
chmod 2755 dir # SETGID — runs as group / new files inherit group
chmod 1777 /tmp # STICKY — only owner can delete (why /tmp is shared-safe)
ls -l passwd # -rwsr-xr-x — the 's' marks setuid
setuid is how passwd lets you change your password in a file you don't own — it runs as root. It's also a security hazard — a setuid binary with a bug is privilege escalation waiting. find / -perm -4000 audits them.
umask — the default permissions
New files get 666 & ~umask, dirs 777 & ~umask:
umask # usually 022 → files 644, dirs 755
umask 077 # strict — 600/700, only for you
umask 022 # the sane shared default
Set it in ~/.profile — it's why your files arrive 644 not 777.
The account machinery
id alice # uid, gid, all groups
whoami # effective user
groups # my groups
useradd -m -s /bin/bash alice # create — -m home, -s shell
passwd alice # set her password
usermod -aG wheel alice # add to group — ALWAYS -a or you REPLACE the list
userdel -r alice # remove + home
groupadd devs # new group
gpasswd -d alice devs # remove from group
/etc/passwd — the readable roster: name:x:uid:gid:gecos:home:shell. /etc/shadow — the hashes, root-only: name:$6$hash:... with aging fields. /etc/group — group:x:gid:members. The x in passwd is the shadow split — passwords moved out of the world-readable file long ago.
su vs sudo — two kinds of becoming
su - # become root — LOGIN shell, root's env
su - alice # become alice fully
sudo command # run ONE command as root — logged, delegated
sudo -i # root login via sudo
sudo -u alice cmd # as any user
sudo !! # rerun last command as root — the muscle memory
sudo is configured in /etc/sudoers — edit only with visudo (it syntax-checks before saving; a broken sudoers locks everyone out). The delegation grammar: alice ALL=(ALL) ALL, or %wheel ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx — precise commands, precise users, optionally passwordless. su shares the root password; sudo shares nothing — it logs who ran what.
File ownership inside /proc and friends
A process carries real uid, effective uid, filesystem uid — ls -l /proc/PID/ shows the process's view. Files created follow the effective uid and the process's umask — which is why a daemon's files land with its service user's name on them.
Groups — the shared-access mechanism
A file's group is the primitive for shared access: chgrp devs repo/; chmod g+w repo/ — every devs member can write. Setgid on a directory makes new files inherit the directory's group — the shared-workspace idiom: chmod 2775 repo/ keeps devs ownership propagating downward.
ACLs — when 9 bits aren't enough
setfacl -m u:alice:rw file # alice specifically gets rw
getfacl file # the access-control list
setfacl -m d:u:devs:rwx dir # default ACL — new files inherit
ls -l file # the '+' after the mode = ACLs present
When a file needs different permissions for several specific users — beyond owner/group/other — ACLs carry it. Most systems never need them; the day you do, they're indispensable.
Capabilities — root's powers, unbundled
Traditional root is all-or-nothing; capabilities split it:
setcap 'cap_net_bind_service=+ep' server # bind :80 without root
getcap server
cap_net_bind_service, cap_setuid, cap_sys_admin — the modern way to grant a process one privilege instead of all.
Where permissions go wrong
| Symptom | Cause |
|---|---|
| "Permission denied" on a file you own | Directory missing x — can't traverse |
chmod -R 755 broke ssh keys | ~/.ssh must be 700, keys 600 |
| sudo asks for password constantly | NOPASSWD: absent, or wrong sudoers line |
| usermod wiped group membership | Forgot -a — -G REPLACES |
| New files wrong group | Missing setgid on the shared dir |
find / -perm -4000 surprises | Setuid binaries you didn't expect — audit |
| Script "can't execute" despite 755 | Filesystem mounted noexec — /tmp often is |
Exercises
stata file — read all three timestamps and the mode.umask 077; touch fthenumask 022; touch g— compare.find /usr/bin -perm -4000— inventory the setuid binaries; identify three.- Create a shared dir with setgid; prove new files inherit the group.
visudo-safe edit: grant your userNOPASSWDfor one specific command.- Explain why
passwdneeds setuid — and why it must be bug-free.
See also
- Linux · Filesystem · Processes · Shell