For Beginners

File and directory permissions in Linux / FreeBSD / MasOS

unix file permissions

According to the Unix philosophy “Everything is a file”. And it is. But sometimes it’s difficult to understand all the rules to provide this statement.

Let’s start from the most common problems that developers have when working with Unix-like file systems!

Basic commands for setting file permissions

To recursively change directories’ owner and group, use this command:

sudo chown -R user:group /home/user/path/to/directory/

Chown is a short for “change owner”, -R – means “recursively”, owner and group definition are separated by “:”. Also we need high privileges to run chown command – so we use “sudo”.

For example, this line will sets www-data user as the owner and www-data group as the group recursively for upload directory:

sudo chown -R www-data:www-data /home/user/www/site/upload/
Note: Apache and Nginx (web servers) use this user and group.

To allow all users to read this file, run the following command:

chmod a+r /var/www/index.html

Chmod is a short for “change mode”, “a+r” means “add read access for all”. Also we can use -R to set this mode recursively (makes sense for directories).

This command recursively searches files in the directory and changes the mode to 644 (the owner can write and read, others can only read):

find /var/www/html-site -type f -exec chmod 644 {} ;

The same for directories:

find /var/www/html-site -type d -exec chmod 755 {} ;

To understand why we use different mode here – read below.

Files in Unix

When we say “everything is a file”, we need many kinds of “files”. So we have 7 kinds of files:

  1. Plain file – what we call “file”.
  2. Directory – yes, it’s also a file.
  3. Symbolic link (symlink) – a reference to another file.
  4. Block device – an abstraction for HDD, SDD, etc.
  5. Char device – an abstraction for byte-by-byte devices, for example TTY terminals.
  6. Pipe (fifo) – a kind of interprocess communications (IPC).
  7. Unix-sockets – one more kind of IPC. It’s like TCP-sockets, but uses file instead

As you can see, files in Unix are not simple. For example, in Plan9 OS you can cat file /net/tcp/http… to get website’s content…

Permissions in Unix

Here we’ll talk about access rights’ matrix. It’s not the only system to organize file permissions but the most important.

Each file has an owner. Owner can define access rights (mode) by using chmod command. Also file has owning group – this is a way to define a group of users with special privileges. And other users called “others” or “all”.

Also we have the “root” – super user with permission for everything (be careful, when you are logged in as root). Only root can uses chown command to change owner / group.

Each group of users (owner, group, all) has three permissions: read file’s content, write and execute. Therefore permissions are not a list, but a 3×3 matrix.

A bitmask of access rights

To encode access rights Unix-like systems use three digits. The first digit for the owner and equals the sum of allowed actions: 4 – for read, 2 – for write and 1 – for execute.

As you can see, it’s powers of two. So, if we write it as a binary number, we get 111. Each position contains 0 or 1 – a flag means “can do it” or not.

If we want to set full permissions for the owner, the first number should be 7. 6 – for read/write and 4 – for read-only (0 – for nothing :-)).

Same rule for the group and all.

For example, 644 means read+write for the owner and read-only for the group and others.

chmod 644 /path/to/file.txt

755 – anyone can read and execute, but the owner can also write.

chmod 755 /path/to/some/

We can execute files (run as a program), but what does it mean for directories? This is a right to path through the directory. If directory has “111” permission – no one can get a list of directory’s content, no one can create any file inside, but if you know the name of file in this directory and have the right to read it – you can do it! Therefore execute right is important for directories.

Permissions as letters

We already know how to set file permission by digits, but there is another way. Let’s see output of ls command:

$ ls -l /bin
drwxr-xr-x 2 root root 4096 май 6 03:24 bin
|||||||||+- execution for "all" is allowed
||||||||+-- writing for "all" is denied
|||||||+--- reading for "all" is allowed
||||||+---- execution for group is allowed
|||||+----- writing for group is denied
||||+------ reading for group is allowed
|||+------- owner can execute
||+-------- owner can write
|+--------- owner can read
+---------- file type (directory)

Just as we wrote permissions as binary number… but with letters.

One more time:

Actions / UsersOwnerGroupOther
as lettersrwxr-xr-x
digits (splited)421401401

That’s all… For now 🙂