How Unix File Permissions Work
An introduction to the Unix file permission system
Filesystem permissions are essentially laws governing who can do what with a given file under the operating system. They aid in maintaining consistency and security across the system by facilitating separation between users’ personal environments, as well as between general users and critical system files and executables.
In this article, I will provide an overview of what permissions mean in Unix, how they are represented, and how you can go about modifying them yourself.
Basics
To begin, it would be useful to know how permissions are organised.
Under Unix, each file has an owner (a user) and a group to which it belongs.
Alongside ownership and group, each file also ships with a set of values (modes) indicating what access permissions are enabled for the owner and group, as well as one other set of users: everyone.
Classes
When talking about who permissions are granted to, we’re presented with three classes:
- User (u)— the user owning the entity
- Group (g)— the group the file belongs to
- Others (o) — every user on the system
For example, we could have the user allek
, belonging to a number of groups: users
, games
, and admin
. Along with that, we have all other users on the system.
Access Permissions
Each class can be granted three types of access:
- Read (r)— the user can see the contents of the file
- Write (w) — the user can modify the contents of the file. This includes modifying permissions of the file.
- Execute (x)— the user can run the file as an executable
The state of whether an access type is enabled is called a mode. If a file only grants read access, it is termed read-only, since only the read mode is set.
Tying Things Together
Every file (directories included) has an owner and a group, as well as a list of access permissions (read, write, and execute) for each one of three scopes: user, group, and other.
As an example, consider again our user allek
, belonging to groups games
and admin
.
- The
allek
user could be explicitly granted read, write, and execute permissions over its own files and documents (everything in its home folder). - Members of the
games
group could be granted read and execute access on gaming applications to facilitate gameplay for all members. - The
admin
group could be granted execute permissions on system utilities like fdisk, a disk formatting and partitioning utility. If anyone could run fdisk, then anyone could format the entire system, which probably isn’t desirable. - Globally, all other users could be denied write access to any file. This would prevent random users from modifying others’ files directly.
Unix doesn’t allow for multiple users or groups to own a single file. However, if you wanted to grant a few specific users access to something, you could create a new group, add them to it, and make that group an owner of the file.
Representation
Permissions are presented in different formats, depending on the context. Here, we’ll cover two common representations of a file’s permission configurations: octal, and ls
-style.
Octal
It is common to see permissions represented as a three- or four-digit octal number. For example: 0777
. In the case of four-digit numbers, we’ll ignore the first and focus on the last three here (the leftmost digit, when four are present, indicates setuid
, setgid
, and sticky bit
information, as described here).
From left to right, we have a digit representing the modes of each scope — user, group, and other — respectively. Each octal digit can be broken down into three binary digits: read, write, and execute.
If no permissions are granted to anyone, this number will be 000
:
000u g o
0 0 0user group other
r w x r w x r w x
0 0 0 0 0 0 0 0 0
If everyone has read and execute access, but only the user owner has write access, 755
:
755u g o
7 5 5user group other
r w x r w x r w x
1 1 1 1 0 1 1 0 1
LS
A quick way to check file permissions is to use the ls
command with the -l
flag (to print out some extra details):
ls -l <path>
For example:
$ ls -l pngr-rwxr-xr-x 1 allek staff 15152 1 Sep 20:08 pngr
ls
‘s longform output provides some useful information. From left to right, we just care about three of the first four for now:
-rwxr-xr-x
— the list of file permission states, as well as a special file indicator, the leftmost1
— (this is the one we don’t care about) number of contained linksallek
— owner of file (user)staff
— owner of file (group)
Let’s take a closer look at the -rwxr-xr-x
.
If it isn’t already obvious, we again have three sets of r, w, and x. For our purposes, pretend that the -
at the beginning isn’t there. It isn’t related to permissions, but it does give us some information about the file’s type (if pngr
was a directory, its would be a d
).
rwxr-xr-xuser group other
rwx r-x r-x
From left to right, we have the user, group, and other scopes respectively. A -
indicates that a permission is disabled, whereas a letter (r
, w
, or x
) indicates that access is granted in its scope.
Documentation for the ls
command can be found here.
umask
As a quick aside, one concept of mention in Unix is umask
, a command used to set a mode mask for file creation. With this, you can set default modes that a file created under the current context should inherit.
umask
uses a format much like the numeric representation we just discussed (3–4 digit octal). However, with umask
, a mode set to 1
will disable that mode on a new file created.
For example, if umask
is set to 027
, a new file created under the current context would have at most permissions of 750
.
For more information about umask
, see the documentation.
Modification
Since permissions exist, there are system utilities for modifying permissions.
Proceed with caution while playing around with these, as they will often have to be run as the root user. It can be really painful to resolve permissions conflicts that have systemwide consequences.
chmod
The most common way to modify permissions is chmod
, short for “change mode”. This allows the user to, like it sounds, change the file’s modes.
chmod
can speak both the numeric and ls-style permissions representations.
The numeric representation can be passed directly, since all modes are included. To grant the user
everything, but everything but write
to everyone else:
$ chmod 755 <file>
When using the ls-style representation, you can actually modify single modes at a time. To unset a mode, prefix the mode with -
. To set it, prefix with +
. To set modes on specific classes, you can specify the classes with u
(user), g
(group), and o
(other).
For example, to grant user
, group
, and other
write
access on a file:
$ chmod +w <file>
To deny other
users execute
access on a file:
$ chmod o-x <file>
Disabling execute permission, verified with ls
:
$ ls -l pngr-rwxr-xr-x 1 allek staff 15152 1 Sep 20:08 pngr$ chmod -x pngr$ ls -l pngr-rw-r--r-- 1 allek staff 15152 1 Sep 20:08 pngr
The chmod
documentation can be found here.
chown
You may also change the owner and group of a file. A common command to do so: chown
, short for, well, “change owner”.
To change the owner of a file to allek
:
$ chown allek <file>
This will only set the owner
of the file to allek
. The group will remain the same.
To change the owner of a file to work
and its group to coolstaff
:
$ chown work:coolstaff <file>
Changing owner and group, verified by ls
:
$ ls -l pngr-rwxr-xr-x 1 allek staff 15152 1 Sep 20:08 pngr$ chown work:admin pngr$ ls -l pngr-rwxr-xr-x 1 work admin 15152 1 Sep 20:08 pngr
The chown
documentation can be found here.
File permissions, when done right, can be an experience almost invisible to the user. However, if (when) issues occur, they can make for a hefty headache. I hope that this article will serve as a decent starting point in learning permissions, and perhaps even help relieve some headaches.
Thanks for reading!