Linux and UNIX File Permissions Guide

By | 2016-08-25

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

Discuss