“Permission denied” is the most common Linux error. Once you can read a permission string, most cases take seconds to diagnose. This post covers the basics, how new files get their permissions, and the three special bits.
Versions in use on this date. Ubuntu 18.04.2 LTS (coreutils 8.28) and CentOS 7.6. The behaviour here is standard POSIX and identical on both.
Reading the string
flowchart TB
S[-rwxr-xr-- 1 ravi deploy] --> T[First character<br/>dash file, d directory, l link]
S --> OW[Owner bits rwx = 7]
S --> GR[Group bits r-x = 5]
S --> OT[Other bits r-- = 4]
OW --> N[Octal mode 754]
GR --> N
OT --> N
ls -l /etc/passwd /etc/shadow /usr/bin/sudo
stat -c '%A %a %U:%G %n' /etc/ssh/sshd_config
| Bit | On a file | On a directory |
|---|---|---|
r (4) |
Read contents | List names |
w (2) |
Modify contents | Create, rename, delete entries |
x (1) |
Execute | Enter (cd) and access items inside |
The directory rules explain most surprises: to read /a/b/file you need x on /a and /a/b, and deleting a file depends on the directory’s w bit, not the file’s.
chmod, chown, chgrp
chmod 640 app.conf # rw-r----- owner rw, group r, others none
chmod u+x deploy.sh # symbolic: add execute for the owner
chmod -R g+rwX /srv/shared # capital X: execute only on directories and already-executable files
sudo chown ravi:deploy app.conf
sudo chown -R www-data: /var/www/site
Common modes: 644 for ordinary files, 755 for directories and programs, 600 for private keys and secrets, 700 for private directories like ~/.ssh. Avoid chmod 777; it hides the real problem (wrong owner or group) and lets any user alter the file.
umask: default permissions for new files
New files start from 666 and directories from 777, minus the umask. With umask 022 you get 644 and 755; with 027, 640 and 750.
umask # show current
umask 027 # tighten for this shell
touch a; mkdir b; ls -ld a b
Set it for all users in /etc/profile or per service in the systemd unit (UMask=0027).
Special bits
| Bit | Mode | Effect |
|---|---|---|
| setuid | 4755 |
Runs as the file’s owner (how sudo and passwd work) |
| setgid on directory | 2775 |
New files inherit the directory’s group; good for shared folders |
| sticky on directory | 1777 |
Only the owner may delete their files (/tmp) |
sudo mkdir /srv/shared && sudo chgrp deploy /srv/shared && sudo chmod 2775 /srv/shared
sudo find / -xdev -perm -4000 -type f 2>/dev/null # audit setuid programs
An unexpected setuid file is a classic sign of compromise, so keep a baseline list.
ACLs when groups are not enough
sudo apt install acl # CentOS: yum install acl
setfacl -m u:alice:r-- report.txt
getfacl report.txt
A + at the end of the mode string in ls -l means ACLs are present.
Diagnosing “Permission denied”
namei -l /full/path/to/fileshows the permissions on every directory in the path.idshows your groups (remember to log in again after being added to one).- Check for SELinux on CentOS (
ls -Z,getenforce): correct Unix permissions can still be denied by policy. - Check mount options (
mount | grep noexec); anoexecmount stops execution regardless of mode.