How it works
The explanation, with examples you can run.
Two users and a shared folder
useradd -m alice; useradd -m bob; groupadd devs; usermod -aG devs aliceid alice; id bobmkdir /tmp/shared && echo secret > /tmp/shared/plan.txtchown -R alice:devs /tmp/sharedchmod 750 /tmp/shared; chmod 640 /tmp/shared/plan.txtls -ld /tmp/shared /tmp/shared/plan.txtsu alice -c "cat /tmp/shared/plan.txt"su bob -c "cat /tmp/shared/plan.txt"uid=1001(alice) gid=1001(alice) groups=1001(alice),1003(devs)uid=1002(bob) gid=1002(bob) groups=1002(bob)drwxr-x--- 2 alice devs 4096 Oct 16 10:23 /tmp/shared-rw-r----- 1 alice devs 7 Oct 16 10:23 /tmp/shared/plan.txtsecretcat: /tmp/shared/plan.txt: Permission deniedThe octal form packs each class into one digit: read 4, write 2, execute 1. 750 is rwxr-x---, 640 is rw-r-----. Bob is neither the owner nor in devs, so he falls into "others", which has no bits at all. (UID 1000 is taken by the ubuntu user in the image, so Alice got 1001.) Names are only labels from /etc/passwd and /etc/group; the kernel stores and compares numbers, which is why files created in a container can show up with a strange owner on the host.
Directories, umask and special bits
On a directory, r lists names, w creates, deletes and renames entries (deleting a file needs write on the directory, not on the file), and x lets you enter it and reach entries by name.
New files get the mode the program asks for (usually 666 for files, 777 for directories) minus the bits in the umask. A umask of 022 gives rw-r--r--; 002, which Ubuntu gives regular users, gives group write too:
umasksu alice -c "cd /tmp/shared && umask && touch new && ls -l new"00220002-rw-rw-r-- 1 alice alice 0 Oct 16 10:23 newThree more bits appear in ls -l as s or t:
- setuid on a program runs it with the file owner's UID.
/usr/bin/passwdis-rwsr-xr-x root, so any user can update the root-owned password file through it. - setgid on a directory makes new files inherit the directory's group, handy for shared folders.
- sticky on a directory lets only a file's owner delete it.
/tmpisdrwxrwxrwt.
Least privilege
- Run services as their own user, not root. systemd's
User=orDynamicUser=yes, andUSERin a Dockerfile. - Use capabilities instead of root. Root's power is split into about 40 capabilities:
CAP_NET_BIND_SERVICEfor ports below 1024,CAP_SYS_PTRACEfor tracing others' processes. Grant just the one you need. - Keep secrets 600 or 640 and owned by the service's user.
chmod 777fixes "Permission denied" by removing all protection; find out which UID needs access instead. - ACLs and MAC.
setfacladds per-user entries beyond the nine bits, and SELinux or AppArmor can deny access even when the bits allow it.
On macOS
The same UIDs, groups and mode bits apply (regular users start at UID 501 with staff as their primary group). macOS adds ACLs (ls -le), file flags and System Integrity Protection, which stops even root from changing system files. There is no useradd; users are managed with sysadminctl or dscl.
Check yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.