Home / Learn Linux / Lesson 14
File permissions: chmod and chown
Read rwx, set permissions with letters and numbers, and change who owns a file.
- Lesson
- 14 of 30
- Time
- About 45 minutes
On this page
- Reading permissions
- chmod with letters
- chmod with numbers
- Permissions on directories
- Changing the owner: chown and chgrp
- Fixing a whole tree: find with chmod
- Common mistakes
- Practice
- Cheat sheet
Reading permissions
Every file and directory has an owner, a group, and three sets of permissions. You've seen them at the start of every ls -l line:
$ cd /srv/perm-lab $ echo "hello" > note.txt $ ls -l note.txt -rw-rw-r-- 1 ubuntu ubuntu 6 Oct 21 11:37 note.txt
The ten characters -rw-rw-r-- break down like this:
- rw- rw- r-- │ │ │ └── others: everyone else │ │ └─────── group: members of the file's group │ └──────────── user: the owner └──────────────── type: - file, d directory, l link
Each set of three is r (read), w (write) and x (execute), or - where that permission is missing. So note.txt can be read and changed by ubuntu and by members of the ubuntu group, and only read by everyone else. The ubuntu group has nobody in it but ubuntu, which is why Ubuntu is happy to let the group write (lesson 15 explains this default).
We're working in /srv/perm-lab rather than your home directory, because your home directory is closed to other users (lesson 13), and the examples need other users to be able to reach these files.
What r, w and x mean
They mean slightly different things for files and for directories, and the directory meanings trip everyone up at first:
| On a file | On a directory | |
|---|---|---|
r | Read the contents | List the names inside (ls) |
w | Change the contents | Create, delete and rename things inside |
x | Run it as a program | Enter it (cd) and reach anything inside |
Notice that deleting a file is a w on the directory, not on the file. A read-only file in a directory you can write to can still be deleted.
How Linux decides
When someone touches a file, Linux checks one set only, the first that applies:
- Are you the owner? Use the user set.
- Otherwise, are you in the file's group? Use the group set.
- Otherwise, use the others set.
Root skips all of this and can do anything.
You can test as another user with sudo -u name command, which runs one command as that user. ravi from lesson 13 is in the "others" set for this file, so he can read it but not change it:
$ sudo -u ravi cat note.txt hello $ sudo -u ravi sh -c 'echo "hacked" >> note.txt' sh: 1: cannot create note.txt: Permission denied
sh -c '...' runs the whole command line, redirection included, as Ravi.
Try it
- What can the group do with a file showing
-rwxr-x---? And others? - What are the permissions on
/etc/shadow, and who can read it?
Answer
- The group can read and run it. Others can do nothing.
2.
$ ls -l /etc/shadow
-rw-r----- 1 root shadow 952 Oct 21 11:37 /etc/shadowThe owner (root) can read and write it, and the shadow group can read it. Everyone else gets nothing, which is why ubuntu needed sudo in lesson 3.
chmod with letters
chmod (change mode) changes permissions. The letter form reads like a sentence: who, then + (add), - (remove) or = (set exactly), then which:
| Who | Means |
|---|---|
u | User (owner) |
g | Group |
o | Others |
a | All three |
$ chmod o-r note.txt $ ls -l note.txt -rw-rw---- 1 ubuntu ubuntu 6 Oct 21 11:37 note.txt $ chmod g-w note.txt $ ls -l note.txt -rw-r----- 1 ubuntu ubuntu 6 Oct 21 11:37 note.txt $ chmod a+r note.txt $ ls -l note.txt -rw-r--r-- 1 ubuntu ubuntu 6 Oct 21 11:37 note.txt $ chmod u=rw,g=r,o= note.txt $ ls -l note.txt -rw-r----- 1 ubuntu ubuntu 6 Oct 21 11:37 note.txt
o-r took read away from others. g-w took write away from the group. a+r gave read back to all three. u=rw,g=r,o= set all three exactly in one go, and o= with nothing after it means none.
Now Ravi can't even read it:
$ sudo -u ravi cat note.txt
cat: note.txt: Permission deniedMaking a script runnable
A script needs x before you can run it:
$ printf '#!/bin/bash\necho "it works"\n' > hello.sh $ ./hello.sh bash: ./hello.sh: Permission denied $ chmod u+x hello.sh $ ./hello.sh it works $ ls -l hello.sh -rwxrw-r-- 1 ubuntu ubuntu 28 Oct 21 11:37 hello.sh
./ means "the one in this directory" (lesson 27 explains why it's needed). chmod +x with no "who" adds it for everyone, which is usual for scripts.
Try it
- Make
hello.shrunnable by everyone, but writable only by you. - Remove all permissions for others from
hello.sh.
Answer
$ chmod a+x,go-w hello.sh $ ls -l hello.sh -rwxr-xr-x 1 ubuntu ubuntu 28 Oct 21 11:37 hello.sh $ chmod o= hello.sh $ ls -l hello.sh -rwxr-x--- 1 ubuntu ubuntu 28 Oct 21 11:37 hello.sh
chmod with numbers
Each permission has a value: r is 4, w is 2, x is 1. Add them up for each set and you get one digit per set:
| Digits | Letters | Typical use |
|---|---|---|
7 | rwx | 4+2+1 |
6 | rw- | 4+2 |
5 | r-x | 4+1 |
4 | r-- | 4 |
0 | --- | nothing |
Three digits make a full mode. These five cover almost everything you'll do:
| Mode | Letters | Use it for |
|---|---|---|
644 | rw-r--r-- | Normal files: you edit, everyone reads |
600 | rw------- | Private files: SSH keys, passwords |
755 | rwxr-xr-x | Programs, scripts and normal directories |
700 | rwx------ | Private directories, like ~/.ssh |
750 | rwxr-x--- | Shared with a group, closed to everyone else |
$ chmod 600 note.txt $ chmod 755 hello.sh $ ls -l total 8 -rwxr-xr-x 1 ubuntu ubuntu 28 Oct 21 11:37 hello.sh -rw------- 1 ubuntu ubuntu 6 Oct 21 11:37 note.txt $ stat -c "%a %A %n" note.txt hello.sh 600 -rw------- note.txt 755 -rwxr-xr-x hello.sh
stat -c %a prints the number form, which is handy when you want to check exactly what's set.
Numbers are quicker once you know them, and they set everything at once, so there's no doubt about the result. Letters are better for one small change, like +x, because they leave everything else alone.
Try it
- What does
chmod 640give, in letters? - Set
note.txtso you can read and write, your group can read, and others get nothing, using a number.
Answer
rw-r-----: 6 isrw-, 4 isr--, 0 is---.
2.
$ chmod 640 note.txt $ stat -c "%a %A" note.txt 640 -rw-r-----
Permissions on directories
Directories are where x and r really matter. Make one to experiment with:
$ mkdir shared $ echo "plans" > shared/plan.txt $ chmod 644 shared/plan.txt $ ls -ld shared drwxrwxr-x 2 ubuntu ubuntu 4096 Oct 21 11:37 shared
Take away x from others and Ravi can't get in at all, even though he could read plan.txt itself:
$ chmod o-x shared $ sudo -u ravi cat shared/plan.txt cat: shared/plan.txt: Permission denied $ sudo -u ravi ls shared plan.txt
With r but no x, Ravi can see the names in the directory but nothing else about them, which is a strange half-state you'll rarely want. Now give it back and take away r instead:
$ chmod o+x,o-r shared $ sudo -u ravi ls shared ls: cannot open directory 'shared': Permission denied $ sudo -u ravi cat shared/plan.txt plans
x without r lets Ravi open a file he already knows the name of, but he can't list what's there. The rule to remember: **x on every directory along the path** is what lets someone reach a file. That's why a website in /home/ubuntu/site doesn't load: the web server can't get through /home/ubuntu, which is 750.
$ chmod 755 sharedTry it
- Make
sharedso the owner can do anything, the group can list and enter it, and others can't do anything.
Answer
$ chmod 750 shared $ ls -ld shared drwxr-x--- 2 ubuntu ubuntu 4096 Oct 21 11:37 shared $ sudo -u ravi ls shared ls: cannot open directory 'shared': Permission denied
Changing the owner: chown and chgrp
Only root can give a file away, so chown (change owner) needs sudo. Give it user, user:group, or :group:
$ sudo chown ravi note.txt $ ls -l note.txt -rw-r----- 1 ravi ubuntu 6 Oct 21 11:37 note.txt $ sudo chown ravi:devs note.txt $ ls -l note.txt -rw-r----- 1 ravi devs 6 Oct 21 11:37 note.txt $ sudo chown :ubuntu note.txt $ ls -l note.txt -rw-r----- 1 ravi ubuntu 6 Oct 21 11:37 note.txt
chgrp devs file changes only the group, and is the same as chown :devs file. Add -R to change a whole directory tree:
$ sudo chown -R ravi:devs shared $ ls -la shared total 12 drwxr-xr-x 2 ravi devs 4096 Oct 21 11:37 . drwxr-xr-x 3 ubuntu ubuntu 4096 Oct 21 11:37 .. -rw-r--r-- 1 ravi devs 6 Oct 21 11:37 plan.txt
The classic use: you copied files into a website directory with sudo, so root owns them and the web server's user can't write its uploads there. sudo chown -R www-data:www-data /var/www/site/uploads hands them over.
Try it
- Give
note.txtback toubuntu:ubuntu, then check. - Make
sharedand everything in it belong toubuntuand the groupdevs.
Answer
$ sudo chown ubuntu:ubuntu note.txt $ sudo chown -R ubuntu:devs shared $ ls -l note.txt -rw-r----- 1 ubuntu ubuntu 6 Oct 21 11:37 note.txt $ ls -la shared total 12 drwxr-xr-x 2 ubuntu devs 4096 Oct 21 11:37 . drwxr-xr-x 3 ubuntu ubuntu 4096 Oct 21 11:37 .. -rw-r--r-- 1 ubuntu devs 6 Oct 21 11:37 plan.txt
Fixing a whole tree: find with chmod
chmod -R 755 dir sets the same mode on files and directories, which is wrong: it makes every file executable. Directories and files usually want different modes, so use find to treat them separately:
$ mkdir -p site/css site/img $ touch site/index.html site/css/main.css site/img/logo.png $ chmod -R 777 site $ find site -type d -exec chmod 755 {} + $ find site -type f -exec chmod 644 {} + $ find site -exec stat -c "%a %n" {} + 755 site 755 site/img 644 site/img/logo.png 644 site/index.html 755 site/css 644 site/css/main.css
There's also a shortcut: a capital X means "execute, but only for directories (and files that are already executable)", so chmod -R u=rwX,go=rX site does both jobs in one command.
Common mistakes
- **
chmod 777to make something work.** It lets anyone on the machine change or replace the file. Find out who actually needs access and give exactly that. - **
chmod -R 755on a tree of files.** Every file becomes executable. Usefind -type dandfind -type fseparately, orX. - **Forgetting
xon a parent directory.** "Permission denied" on a file that looks readable usually means a directory above it is missingx. Check every level withnamei -l /path/to/file. - SSH keys that are too open.
sshrefuses a private key that others can read. Keys are600,~/.sshis700. - **
chownwithoutsudo.** Normal users can't give files away. You'll getOperation not permitted.
Practice
- Check every directory on the way to
/etc/ssh/sshd_config, with its permissions, in one command.
Answer
$ namei -l /etc/ssh/sshd_config
f: /etc/ssh/sshd_config
drwxr-xr-x root root /
drwxr-xr-x root root etc
drwxr-xr-x root root ssh
-rw-r--r-- root root sshd_confignamei walks the path and shows the permissions and owner of each part, which makes it the fastest way to find which directory is blocking someone.
- Create
/srv/perm-lab/secret.txtthat only you can read or write, and prove Ravi can't read it.
Answer
$ echo "pin 4321" > secret.txt $ chmod 600 secret.txt $ ls -l secret.txt -rw------- 1 ubuntu ubuntu 9 Oct 21 11:37 secret.txt $ sudo -u ravi cat secret.txt cat: secret.txt: Permission denied
- Create
/srv/perm-lab/teamowned byubuntuand the groupdevs, so members ofdevscan create files in it and everyone else can't even look. Then show that Ravi (indevs) can create a file there.
Answer
$ mkdir team $ sudo chown ubuntu:devs team $ chmod 770 team $ sudo -u ravi touch team/ravi-was-here $ ls -l team total 0 -rw-r--r-- 1 ravi ravi 0 Oct 21 11:37 ravi-was-here
Lesson 15's SGID bit makes this work better: right now, Ravi's file belongs to his own group, not devs.
- Use letters to remove write permission for the group and others from every file in
site, without touching anything else.
Answer
$ find site -type f -exec chmod go-w {} + $ find site -type f -exec stat -c "%a %n" {} + 644 site/img/logo.png 644 site/index.html 644 site/css/main.css
- Find every file under
/srv/perm-labthat others can write to.
Answer
$ find /srv/perm-lab -perm -o+w -type f
/srv/perm-lab/site/index.html-perm -o+w matches files where at least the others-write bit is set.
- What's the number form of
rwxr-x--x?
Answer
751: rwx is 7, r-x is 5, --x is 1.
Cheat sheet
| Command | What it does |
|---|---|
-rwxr-xr-x | type, user, group, others |
r w x on a directory | List, create/delete inside, enter |
chmod u+x file | Add execute for the owner |
chmod go-w file | Remove write from group and others |
chmod u=rw,g=r,o= file | Set exactly |
chmod 644 / 600 / 755 / 700 / 750 | The five modes you'll use most |
stat -c "%a %A" file | Mode as a number and as letters |
sudo chown user:group file | Change owner and group |
sudo chown -R user:group dir | The whole tree |
chgrp group file | Change the group |
find dir -type d -exec chmod 755 {} + | Fix directories only |
chmod -R u=rwX,go=rX dir | Files 644, directories 755 in one go |
sudo -u user command | Test as another user |
namei -l /path | Permissions of every directory on the way |
← Users and groupsSpecial permissions: SUID, SGID, sticky bit and umask →