When you start seeing terms such as octal, binary, sticky bits, set UID, set GID, and ACLs, learning how UNIX file permissions work may sound confusing. Its not so bad after a bit of practice. In my opinion, it is easier than Windows permissions. You don’t need to understand octal and binary. It could possibly make things a bit more intuitive, but it isn’t necessary to understand the concepts.
Before getting started, you will sometimes see file permissions referred to as file mode. When it comes to Linux and UNIX, the terms file mode and file permissions mean the same thing.
Ownership
Every file on a UNIX like system is owned by a user and a group. The owning user and group along with 4 sets of permissions are used to determine what users can do with a file.
Every user on a UNIX like system is a member of at least one group, called their primary group. A user can be a member of additional groups, called supplementary groups.
You can view which groups you are a member of with the id -a
command.
tyler@desktop:~$ groups
tyler cdrom floppy audio dip video plugdev netdev scanner bluetooth vboxusers
tyler@desktop:~$
The first group output is the primary group. In this case, it is tyler
.
Open a terminal and run the command ls -l
. Here is the output of ls -l
on one of my machines:
tyler@desktop:~/dir$ ls -l
total 0
-rw-r--r-- 1 tyler audio 0 Sep 16 06:35 file1
-rw-r--r-- 1 root sys 0 Sep 16 06:34 file2
The highlighted portions show the owner and groups that own the listed files. The left column is the user, and the right column is the group. In the example, file1
is owned by the user tyler
and the audio
group. file2
is owned by the root
user and sys
group.
Permissions
The far left column of the output of ls -l
shows the four permission sets.
tyler@desktop:~/dir$ ls -l
total 4
drwxr-xr-x 2 tyler tyler 4096 Sep 16 06:49 dir1
-rw-r--r-- 1 tyler audio 0 Sep 16 06:35 file1
-rwxr-xr-- 1 root sys 0 Sep 16 06:34 file2
The permissions string for dir1
in the example are drwxr-xr-x
. Let’s break this down into its individual parts.
The far left character is the file type. dir1
is type d
, while file1
and file2
are type -
. A d
indicates a file is a directory. Files that have a -
are regular files. Consult your operating system’s documentation for a complete listing of all types.
There are three sets of three characters making up the rest of the permission string. These represent the four sets of permissions. They are the permissions that apply to the owner, group, and everyone else, respectively.
Permission Set | Description |
---|---|
drwxr-xr-x | The first position shows the file type. |
drwxr-xr-x | The permissions that apply to the file’s owner. |
drwxr-xr-x | The permissions that apply to the file’s group. |
drwxr-xr-x | The permissions that apply to everyone else. |
Consider file2
from the example above. It is owned by root
and sys
, and has a permission string of -rwxr-xr--
. This means file2
is a regular file, rwx
applies to root, r-x
applies to sys
, and r--
applies to everyone else.
The type is NOT one of the four sets of permissions. I will cover the fourth set later.
The Standard Permission Sets
Each permission set is made up of 3 characters. The permissions from left to right are read, write, and execute. These are represented by r
, w
, and x
, respectively. When you see the character representing a permission in a set, it is on. If you see a -
in its position, it is off. Consider the set r-x
. This means the read permission is on, write is off, and execute is on. The individual permissions will ALWAYS be listed in the order, from left to right, read, write, and then execute.
Read and write are pretty self-explanatory. If they are on, they indicate whether whomever they apply to can read or write to the file. The execute permission is more complex.
If the execute permission is set on a directory, this means that whom the set applies to will be able to set the directory as their current working directory and access files within it. In order to view files in the directory, read must be set. There may be cases where you want execute set on a directory but not read. For example, you may want a user to be able to get to a log directory, but don’t want them to see the contents of one or more directories in the path. In this case, you would give them only execute on the directories you don’t want them looking at.
If a file is a program or script, execute must be set on it to be able to run it. If the program is written in an interpreted language such as bash
, the user must also have read access. If it is compiled into machine code, execute is all they need to run it.
The Special Permission Set
The special permissions are set user id (setuid), set group id (setgid), and the sticky bit. Setuid on a regular file lets you execute a file as the owner instead of the user you are logged in as. The same applies to setgid. The sticky bit prevents users from deleting things in a directory, even if they have write access to the directory. Setgid on directories will set the group of files created in the directory to the directory’s group.
The special permission set is not displayed separately. If any of the special permissions are set, they are displayed in their respective execute position. If setuid is on, an s
or S
is displayed in the owner set’s execute position. If you see a lowercase s
, then both execute and setuid are set. An uppercase S
indicates setuid is on and execute is off.
The setgid permission is displayed in the group execute position. As with setuid, setgid is represented with an s
or S
. Setgid follows the same capitalization rules as as setuid.
The sticky bit is represented in the everyone else execute position with a t
or T
. A t
means the execute permission is also set, while a T
means it is not.
Numeric Representation
You will often see permissions represented as a number such as 755 or 0755. The numbers represent the four sets: special, owner, group, and others, respectively. E.g. 4751 means the special permission set is 4, owner is 7, group is 5, and others is 1. A 3 digit number means no special permissions are on.
Each permission is given the value shown in the table:
Permission | Number |
---|---|
Read | 4 |
Write | 2 |
Execute | 1 |
Permission | Number |
Set User ID | 4 |
Set Group ID | 2 |
Sticky Bit | 1 |
The numeric version is calculated by adding together the positions that are on for each set and concatenating them. Let’s calculate the numeric version for rw-r--r--
. No special permissions are set, so the first number is 0. The owner set has read and write on. Since read is 4 and write is 2, 4+2 = 6. We are at 06 so far. The group and others sets only have read, so they are both 4. Now we have 0644.
rwS-w-r-t
is a complicated example that you will probably never see in practice. The setuid and the sticky bit are set, which are 4 and 1. The special permissions of this file are 5. Since the S
is capital, the owner has read and write, but not execute. Read and write are 4 and 2, which add up to 6. We have 56 so far. The group only has write, so now we are at 562. Others is r-t
, meaning execute and the sticky bit are on. 4 + 1 is 5, so we finally arrive at a mode of 5625.
Changing Permissions
Three commands are commonly used to control ownership and permissions. They are chmod
, chown
, and chgrp
.
The chgrp
command is used to change a file’s group. You type chrgp
, any options you wish to use, the name of the group, followed by the filename.
chgrp newgroup filename
The chown
command can be used to change both the owner and group of a file:
chown newowner filename
chown :newgroup filename
chown newowner:newgroup filename
The chmod
command is used to change a files permissions. chmod
can either use symbols representing the changes, or the numeric version described earlier. Which one you use is entirely preference. The numeric version is self explanatory. You type chmod
, options, the number representing the permissions, and then the file name.
chmod 644 filename
With the symbolic method, you specify the changes you want to make. To do this you pass chmod
the symbol for the set(s) you want the change to apply to, +
or -
to indicate whether you want to grant or revoke the permission, then which permission(s) to change. If you omit the set, the change applies to all sets.
Here are the various symbols used with symbolic mode:
- Permission Set
-
a – all sets
u – user (owner)
g – group
o – other - Permission
r – read
w – write
x – execute
s – setuid/setgid
t – sticky bit
A few examples should clarify their usage:
root@desktop:/home/tyler/permissions# ls -l
total 0
-rwxrwxrwx 1 root root 0 Sep 18 14:36 file1
-r--r--r-- 1 root root 0 Sep 18 14:36 file2
-rw-r--r-- 1 root root 0 Sep 18 14:36 file3
root@desktop:/home/tyler/permissions# chmod -x file1
root@desktop:/home/tyler/permissions# chmod ug+w file2
root@desktop:/home/tyler/permissions# chmod u+x file3
root@desktop:/home/tyler/permissions# ls -l
root@desktop:/home/tyler/permissions# ls -l
total 0
-rw-rw-rw- 1 root root 0 Sep 18 14:36 file1
-rw-rw-r-- 1 root root 0 Sep 18 14:36 file2
-rwxr--r-- 1 root root 0 Sep 18 14:36 file3
Recursively Changing Permissions
Suppose you want to change the permissions of a directory and all files in it. If there are a lot of files or subdirectories, it would be tedious to change them one at a time. All three of the commands covered have a -R
option. The -R
will make the change to the named directory and everything in it. BE CAREFUL with this. On some systems these commands will expand .*
to ..
, meaning that the command will go up a directory and then make the changes there as well. For example if you are in /tmp
, and run the command chown -R tasha .*
, chown
will go up a level and change the owner of every file on your system to tasha
! Again, be careful with the -R
option.
root@desktop:/home/tyler/permissions# find dir1 -exec ls -ld {} \;
drwxr-xr-x 3 root root 4096 Sep 18 14:50 dir1
-rw-r--r-- 1 root root 0 Sep 18 14:50 dir1/file1
drwxr-xr-x 2 root root 4096 Sep 18 14:50 dir1/dir2
-rw-r--r-- 1 root root 0 Sep 18 14:50 dir1/dir2/file2
root@desktop:/home/tyler/permissions# chown -R tyler dir1
root@desktop:/home/tyler/permissions# find dir1 -exec ls -ld {} \;
drwxr-xr-x 3 tyler root 4096 Sep 18 14:50 dir1
-rw-r--r-- 1 tyler root 0 Sep 18 14:50 dir1/file1
drwxr-xr-x 2 tyler root 4096 Sep 18 14:50 dir1/dir2
-rw-r--r-- 1 tyler root 0 Sep 18 14:50 dir1/dir2/file2
Default Ownership and Permissions
When you create a new file, the ownership is determined by the user and group of the creating process. To see your current user and group, use the id
command. Permissions are determined by your umask
.
Default Ownership
tyler@desktop:~$ id
uid=1000(tyler) gid=1000(tyler) groups=1000(tyler),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),103(netdev),105(scanner),110(bluetooth),124(vboxusers)
Any file I create will be owned by the user tyler
and group tyler
. If you want a file to be owned by one of your supplementary groups, use the newgroup
command to change the group of your current login session.
tyler@desktop:~$ id
uid=1000(tyler) gid=1000(tyler) groups=1000(tyler),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),103(netdev),105(scanner),110(bluetooth),124(vboxusers)
tyler@desktop:~$ touch test
tyler@desktop:~$ ls -l test
-rw-r--r-- 1 tyler tyler 0 Sep 21 06:04 test
tyler@desktop:~$ newgrp cdrom
tyler@desktop:~$ id
uid=1000(tyler) gid=24(cdrom) groups=24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),103(netdev),105(scanner),110(bluetooth),124(vboxusers),1000(tyler)
tyler@desktop:~$ touch test2
tyler@desktop:~$ ls -l test2
-rw-r--r-- 1 tyler cdrom 0 Sep 21 06:05 test2
Keep in mind that setgid
on a directory will cause new files to be owned by directory’s group.
tyler@desktop:~/permissions$ ls -larth
total 24K
drwxr-xr-x 112 tyler tyler 12K Sep 21 06:06 ..
drwxrwsrwx 2 root root 4.0K Sep 21 06:19 setgid
drwxrwxrwx 2 root root 4.0K Sep 21 06:20 normal
drwxr-xr-x 4 tyler tyler 4.0K Sep 21 06:20 .
tyler@desktop:~/permissions$ touch setgid/file normal/file
tyler@desktop:~/permissions$ ls -l *
normal:
total 0
-rw-r--r-- 1 tyler cdrom 0 Sep 21 06:20 file
setgid:
total 0
-rw-r--r-- 1 tyler root 0 Sep 21 06:20 file
Default Permissions
The permissions on a newly created file depend on your umask
. A umask
is a 4 digit number that looks like the numeric version of a file’s mode. The umask
command will tell you what yours is.
tyler@desktop:~/permissions$ umask
0022
Ignore the leading 0. The umask
doesn’t apply to special permissions. My umask
is 022
. When a new file is created, all regular permissions are on except those specified by the umask
. Think of the umask
as the permissions that are off by default.
Directories and regular files are treated a little differently.
tyler@desktop:~/permissions$ umask
0022
tyler@desktop:~/umask$ mkdir dir1
tyler@desktop:~/umask$ touch file1
tyler@desktop:~/umask$ ls -l
total 4
drwxr-xr-x 2 tyler tyler 4096 Aug 25 05:02 dir1
-rw-r--r-- 1 tyler tyler 0 Aug 25 05:02 file1
Notice that the mode of dir1
is 755
and the mode of file1
is 644
. When regular files are created, the execute permissions are off. When directories are created, execute is on. If you set your umask
to turn off execute, directories will have execute turned off.
To change your umask
, pass the new one to the umask
command.
tyler@desktop:~/permissions$ umask
0022
tyler@desktop:~/permissions$ mkdir dir
tyler@desktop:~/permissions$ umask 023
tyler@desktop:~/permissions$ umask
0023
tyler@desktop:~/permissions$ mkdir dir2
tyler@desktop:~/permissions$ ls -l
total 8
drwxr-xr-x 2 tyler cdrom 4096 Sep 21 07:07 dir
drwxr-xr-- 2 tyler cdrom 4096 Sep 21 07:07 dir2
An easy way to determine what the permissions will be is to subtract the umask
from 777
. 777 - 022 = 755
. Files created when the umask
is 022
will default to a mode of 755
for directories, and 644
for regular files.
Further Reading
I recommend learning access control lists (ACLs). ACLs allow you to give a user or group their own set of permissions on top of the ones you see with ls -l. ACLs come in 2 varieties: POSIX and NFS. POSIX ACLs seem to be more common.
Your operating system may have some kind of mandatory access control (MAC) system such as Linux’s SELinux and Solaris’s trusted extensions. If your system has any kind of MAC, I would at minimum be aware of it. RHEL based Linux distributions have SELinux enabled by default. MAC settings and ACLs are a good place to look if you run into permission problems that don’t make sense.
If you use FreeBSD, be aware that file flags can affect file behavior.
References
Linux Programmer’s Manual – chmod
FreeBSD Handbook Chapter 3.4 – Permissions