The chmod lesson explained who may read, write and execute a file. This lesson covers the other half of the model: who owns a file and how to change it, where the default permissions of new files come from, and the three special bits — setuid, setgid and sticky — that explain how passwd can edit a root-owned file and why nobody can delete your files from /tmp. These are the concepts behind most "permission denied" errors on shared servers.
ls -l shows the owning user and group in the third and fourth columns. Permissions are evaluated in order: if you are the owner, the owner bits apply; otherwise, if you are in the group, the group bits apply; otherwise the "others" bits apply. The first match wins, even if a later set would grant more.
ls -l /etc/shadow
# -rw-r----- 1 root shadow 1187 Sep 20 09:12 /etc/shadowRoot owns the file, members of the shadow group can read it, everyone else gets nothing.
Only root can change a file's owner; the owner can change the group to any group they belong to.
sudo chown alice report.txt # change owner
sudo chown alice:developers report.txt # owner and group
sudo chown :developers report.txt # group only
sudo chgrp developers report.txt # same thing
sudo chown -R www-data:www-data /var/www/app # recursively
sudo chown --reference=index.html new.html # copy ownership from another fileWhen a program creates a file it asks for 666 (directories 777), and the kernel removes the bits set in the umask. The usual mask 022 removes write for group and others, producing 644 and 755.
| umask | New file | New directory | Typical use |
|---|---|---|---|
| 022 | 644 | 755 | default on most distributions |
| 002 | 664 | 775 | collaborative group directories |
| 027 | 640 | 750 | private group, no access for others |
| 077 | 600 | 700 | strictly private (root, secrets) |
umask # show the current mask, e.g. 0022
umask 027 # set it for this shell session
touch a; mkdir d; ls -ld a d # a is -rw-r-----, d is drwxr-x---To make it permanent for a user, add umask 027 to ~/.bashrc or ~/.profile; for a service, set UMask= in its systemd unit. Note that umask subtracts permissions; it can never add execute to a new regular file.
An executable with the setuid bit runs with the privileges of its owner instead of the user who launched it. passwd is the classic example: it is owned by root so that any user can update their own entry in root-only /etc/shadow.
ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root 68208 ... /usr/bin/passwdThe s in the owner's execute position marks setuid. Set it with chmod u+s file or chmod 4755 file. Setuid programs are a security risk if they have bugs, which is why auditing them is standard practice:
sudo find / -type f -perm -4000 2>/dev/nullNever set setuid on scripts; the kernel ignores it for interpreted files on Linux, and shells would be unsafe anyway.
On an executable, setgid runs the program with the file's group. On a directory it does something far more useful: every file created inside inherits the directory's group instead of the creator's primary group. Combined with a 002 umask this is how teams share a folder without constantly running chgrp.
sudo mkdir /srv/shared
sudo chgrp developers /srv/shared
sudo chmod 2775 /srv/shared # or chmod g+s /srv/shared
ls -ld /srv/shared
# drwxrwsr-x 2 root developers 4096 Sep 27 11:00 /srv/sharedThe s in the group execute position shows setgid. New subdirectories inherit the bit as well.
On a world-writable directory, the sticky bit means a file may be deleted or renamed only by its owner, the directory owner or root. /tmp has it, which is why users share the directory safely.
ls -ld /tmp
# drwxrwxrwt 12 root root 4096 Sep 27 11:05 /tmp
sudo chmod 1777 /srv/uploads # or chmod +tThe t in the others execute position marks it.
The special bits occupy a fourth digit in front of the familiar three: setuid = 4, setgid = 2, sticky = 1.
| Command | Meaning |
|---|---|
| chmod 4755 app | setuid, rwxr-xr-x |
| chmod 2775 dir | setgid, rwxrwxr-x |
| chmod 1777 dir | sticky, rwxrwxrwx |
| chmod 6750 app | setuid and setgid |
A capital S or T in ls -l output means the special bit is set but the corresponding execute bit is not, which is almost always a mistake.
chmod -R 777 to "fix" a permission error. It removes all protection; fix ownership instead.chmod -R g+s also sets setgid on regular files. Use find dir -type d -exec chmod g+s {} +.umask 077 system-wide and then wondering why the web server cannot read uploaded files.Which command changes both the owner and group of a directory tree?
chown user:group changes ownership (root only for the owner); -R recurses.666 minus the umask; 022 gives 644/755, 027 gives 640/750.chmod 777.Next lesson: Users, Groups and sudo — create accounts, manage group membership and grant administrative rights safely.