File Permissions

This article describes how to manage permissions to your files and directories in Unix/Linux.

Windows and Mac users will also have to deal with this, as the file areas are usually shared to Windows, Mac, and Linux machines.

Basic familiarity with Linux is assumed, like how to log on and run simple commands like ls, mkdir, etc.

The Basics

The Unix way of handling file permission is not very complicated, but can be confusing for the novice and sometimes also for the seasoned user.

The Unix World

(We will here use the terms Unix and Linux pretty much interchangeable.)

As a UiO user, you have access to several Linux and Windows machines where you can reach the home directory of others, or miscellaneous project directories. Conversely, others can reach your files and directories, and you must make some informed decisions on how to protect your data, and how to make shared data available for your co-workers.

Data are organized in files and directories.

  • A file is a lump of data with a name. It also has some metadata attached to it, like its owner, group, and permission modes.
  • A directory is actually a special file that simply contains a list of files "in" this directory. Also known as a folder, a directory can contain other directories in a tree-like structure, and has the same metadata as any other file.

You can inspect the contents of the current directory with the "ls" command:

$ ls
file.txt  projects  texts

To see some more details (ie. metadata), use the option "-l":

$ ls -l
-rw-r--r--  1 bill geofag    79102 Jan  8 15:16 file.txt
drwxr-xr-x  4 bill geoit      2048 Feb  5 14:19 projects
drwx------  2 bill bill       2048 Feb  5 14:19 texts

The fields you see are as follows:

  • The very first character on each line tells us what kind of file this is. A '-' (hyphen) means a regular file, while 'd' means a directory.
  • Then comes the permission string, 9 characters, the main topic for this article (sometimes this is followed by a period '.').
  • The following number (number of references) is not important to us here.
  • Then comes the user (owner) and group of the file or directory.
  • Then the size, in bytes.
  • Then the date and time of last change.
  • Finally the name of the file.

In the above example, we see that file.txt is a regular fil (-), owned by bill and group geofag; while projects is a directory ('d'), owned by bill and group geoit.

Note that the "size" of a directory in the above output is a bit misleading, it is only the size of the directory file. To find the total size of the directory and all the files (in all subdirectories), use the "du" command.

Me, you and all the others.

There are three possible permissions: read, write, and execute; or r, w, and x for short. These permissions can be assigned to the user (or u for short), the group (g), or others (o). The permissions for a given file, as seen in the output from "ls -l", is then the permissions for the user, group, and others, concatenated:

-rw-r--r--  1 bill geofag    79102 Jan  8 15:16 file.txt

In the above example, we see that the file file.txt has permissions rw-r--r--. We can break that down to

  • read- and write-permission (rw-) for the owner (bill)
  • read-permission (r--) for the group (geofag)
  • read-permission (r--) for others

chmod

When you own a file (when you are the user), you can also set access rights to the file.

Permissions are assigned with the "chmod" command. If you want to give write access to the group for the file "file.txt", you can do

$ chmod g+w file.txt
$ ls -l file.txt
-rw-rw-r--  1 bill geofag    79102 Jan  8 15:16 file.txt

Note the 'w' now added to the permission string, signifying write permissions to the group.

More generally, the "chmod" command takes an argument in the form [ugoa][+-=][rwx] to apply to one or several files. This is known as symbolic notation. Permission (zero or more of r,w,x) can be given to (+), removed from (-), or set (=) for the user, group, others, or all (a).

The "chmod" command accepts the "-R" option to run recursively, ie. to apply the changes to all files and subdirectories. We'll see some examples later on.

What does it mean?

For plain files, the permissions are pretty straight-forward.

  • When you have read-permission on a file, you can read it, e.g. view it on-screen or copy it.
  • Write-permission allows you to edit the file in-place, but note the caveat below.
  • Execute-permission means the file can be executed as a program.

A compiler will usually set execute-permission on the finished binary program when you compile and link it, but for eg. shell scripts you must see to this yourself.

For directories, the meaning of the permissions is not so obvious, but remember that a directory is just a list of filenames!

  • Read-permission on a directory allows you to read the list, i.e. see the names of the files in the directory.
  • Write-permission allows you to change the list, i.e. add files to the directory, change the name of files, or remove them.
  • Execute-permission allows you to "enter" the directory, and use its contents.

Note that when you have 'w' on a directory, you can remove a file in it, and add a new file. So even if you don't have write-permission to the file itself, you can remove the file, or replace it!

For directories, 'r' or 'x' alone is not very useful. For most practical purposes, you'll need both. Some exceptions apply, though, as the first example below will show.

Basic examples

EXAMPLEI want to protect my home directory from being read by others at UiO:

$ chmod o-r ~

Here we remove (-) the read (r) permissions for others (o).

Note that we don't remove execute-permissions (x). This means if you have a subdirectory (say, ~/projects) that you want to share with your co-workers, they will still be able to access that. They will have to know the name, though, as they can no longer read (or "navigate") your home directory.

Your co-workers will also need access to the shared directory. Right now, we will assume you have a group for this.

EXAMPLEI want to allow the group read access to the files in ~/projects, but no write access:

$ chmod g=rx ~/projects
$ chmod g=r ~/projects/*

First we set read and execute permissions to the directory for the group. Then we set read access to the files therein. With '=', we remove whatever other rights were in place for the group.

You would probably want to do this recursively. Keep reading!

The User and the Group

All Unix users have a unique User ID (uid) and also a primary Group ID (gid). The gid is perhaps not unique — others users can have the same gid. The id's have both a textual and numerical form, and the "id" command will show you both, and also whatever other groups you belong to:

$ id
uid=23716(bill) gid=1736(geofag) groups=1736(geofag),85444(geoit),... # (list of groups here)

When you create a new file, the file will be assigned your uid and primary gid. So for the user "bill":

$ echo hello > foobar
$ ls -l foobar
-rwxr--r--   1  bill geofag    6 Jan  8 16:37  foobar

In Unix, all files have one owner, and all files also have one (and only one) group. When we set permissions for the group, we actually mean "permissions for members of this file group".

(There are other kind of groups, but in this article we only discuss file groups.)

At UiO, group information is (usually) provided by the network. You can list the members of a given file group with the command "lsfg", and you can list the groups for a given user with the "groups" command:

$ lsfg geofag   # this will yield a rather long list of usernames
$ groups bill   # list bill's groups

Most groups are managed by the IT staff. If you want to create a new group, or if you want additional members in your group, please contact the IT staff.

You can also manage a few things yourself. Log on to brukerinfo.uio.no, select the group tab. Here, you can add other users to your personal group (or remove them). You can also request such a group here, if you haven't already got one. Note that personal file groups are not well suited for sharing data, unless you work exclusively in Linux.

You can change the group for a file with the "chgrp" command. You need to own the file, and you must be a member of the group you want to assign to. Example:

$ chgrp geoit texts/

Like "chmod", also "chgrp" accepts the "-R" option, to set the group recursively in the directory tree.

Other permissions

Apart from r, w, and x, there are a couple of other permissions.

setuid

The setuid permission is set with u+s option:

$ chmod u+s myfile
$ ls -l myfile
-rwsr-xr-x 1 bill   geofag  65340 Feb 13 14:03 myfile

If "myfile" is a binary executable, it will be executed with the runtime ID of the owner (bill, in the above example). This is rarely useful for most users, but is mentioned here for sake of completeness. It is more common for system utilities, and is a huge security risk if done carelessly.

It only makes sense to set this on executable binary files that others can execute. It will not work on interpreted scripts, ie. bash or python scripts, and makes no sense for directories.

setgid

Originally, setgid (g+s) is used similar to the setuid mode (above), ie. to execute binaries with the ID of the group. It can still be used this way, but it is rarely useful.

More interestingly, it can be set on directories. Files (and subdirectories) created in this directory will inherit the group of the parent directory, rather than the user's default file group. Subdirectories will also inherit the setgid permission itself. Consider the following :

$ mkdir pets
$ mkdir pets/dogs
$ ls -ld pets pets/dogs
drwxr-xr-x 1 bill   geofag   2048 Feb 13 14:07 pets
drwxr-xr-x 1 bill   geofag   2048 Feb 13 14:07 pets/dogs

Note that both the directories are created with bill's default file group, geofag. Now:

$ chgrp geoit pets/
$ chmod g+s pets/
$ mkdir pets/cats
$ ls -ld pets pets/*
drwxr-sr-x 1 bill   geoit    2048 Feb 13 14:07 pets
drwxr-xr-x 1 bill   geofag   2048 Feb 13 14:07 pets/dogs
drwxr-sr-x 1 bill   geoit    2048 Feb 13 14:09 pets/cats

Note that the new subdirectory ("cats") now inherits both the new group (geoit) and the setgid bit of the parent ("pets"). The old subdirectory ("dogs") is however unaffected.

As can be seen in the above examples, the 's' for setgid (and setuid) takes the same position as the execute-'x' in the ls output. If the setgid/setuid is set while the execute is unset (this would be rather pointless), this position will show as a capital 'S':

$ chmod g-x pets/cats
$ ls -ld pets/cats
drwxr-Sr-x 1 bill   geofag     0 Feb 13 14:07 pets/cats    # this is useless

Setgid permission is very useful on common project areas, where many people (possibly with different primary groups) need to create and share files.

sticky bit

The sticky bit is typically used on the system "/tmp" directory, which usually has full access for everyone. Note the "t" at the end of the permission string:

$ ls -ld /tmp
drwxrwxrwt 22 root root 4096 Feb 13 15:26 /tmp

As you recall, you can usually remove files if you have write-access to the parent directory, even if you don't have any rights to the file itself, and even if you don't own the file. The sticky bit changes this, when set on the parent directory you must own the file to be able to remove it:

$ ls -l /tmp/important
-rw-r--r-- 1 daisy daisy 6 Feb 13 15:32 /tmp/important
$ whoami
bill
$ rm /tmp/important
rm: cannot remove ‘/tmp/important’: Operation not permitted

Thus, other users can't mess with your temporary files in /tmp.

Keep in mind that "/tmp" is not a good place to put important files anyway, as they will eventually be removed by the system.

You can set the sticky bit on your own directories with the "+t" argument to "chmod".

The +X shortcut

Remember, "chmod" can be run recursively with the "-R" option.

If you run a command like "chmod -R a+rx dir", you will give read and execute permission to all files and subdirectories below "dir". Directories need execute permission to be useful, but this command will also make data files, pdf files and so on executable, even if that makes no sense. This can be confusing.

To remedy this, the +X (capital 'X') modifier will only add execute permission to directories, or to files where somebody else already have execute permissions (programs). Quite likely, this is what you want.

EXAMPLEFor example, say you own an existing directory "pets", and you are a member of the group "petshop". You can then give the group all useful rights to this directory and all subdirectories with the following commands:

$ chgrp -R petshop pets/
$ chmod -R g+rwsX pets/

Note that we also set the setgid bit (+s).

Octal modes

So far, we have used a mnemonic short-hand with u,g,o and r,w,x (and s,t,X) to set the permission bits, this is called symbolic notation. Many seasoned Unix users prefer the more compact and also more cryptic octal notation.

To understand octal notation, consider the permissions r, w, and x to have the numerical values 4,2, and 1, respectively. Add this up for whatever permission you want to set (eg. 'r-x' is 4+1=5), and concatenate this for all user categories (u,g,o). Thus, eg. "rwxr-x--x" would become "751", and you could use that to set permissions with "chmod":

$ chmod u=rwx,g=rx,o=x file.txt
$ chmod 751 file.txt    # identical result

Note that with octal notation, permissions are set, not added or subtracted. Also note that "all permissions to everyone" would be "777".

You can also set setuid, setgid and sticky bit with octal modes. The curious reader should consult the manual:

$ man chmod

In the table below, octal modes are supplied where relevant.

umask

What happens when you create a new file or directory, what permissions will it receive? This depends on the umask of the shell (or other process) creating the file. You can inspect your current umask with the "umask" command:

$ umask
0022

Its value is commonly given in octal, and should be understood as whatever should be subtracted (digit for digit) from the full set of permissions (777) to yield default permissions. For example:

$ umask
0022
$ mkdir rabbit
$ ls -ld rabbit
drwxr-xr-x 2 bill  geofag     2048 Feb 15 14:56 rabbit

Here, bill's umask is 022, so the write-permission (value 2) is subtracted from the full set of permissions for group and others, resulting in the shown permission string.

The process (shell) creating the file or directory can limit the permissions further. While execute-permissions are useful for directories, they are less so for plain files. Thus, these are commonly removed for plain files:

$ echo mammals > type.txt   # let the shell create a plain file
$ ls -l type.txt
-rw-r--r-- 1 bill  geofag        8 Feb 15 15:03 type.txt

You can change your umask with the "umask" command, so eg. to set a less permissive umask:

$ umask 027

You can use a command like this in your shell setup files (".bashrc" etc.).

The umask can also be supplied it as an argument to eg. sshfs, to take effect on the remote filesystem:

$ sshfs remote:/disk /var/sshfs/bill -o umask=002

While modern shells (like bash) can also use symbolic mode for the umask ("umask -S"), programs like sshfs typically cannot. So octal mode is useful to learn in this instance.

When a Windows machine creates a file on a Unix filesystem, there will be a umask in the server process (e.g. smbd) that the user unfortunately can't modify.

Examples

Here is a brief table with chmod arguments for setting a certain set of permission, both in symbolic and octal mode; as well as the resulting permission string (as shown by "ls").

symbolic octal resulting permission
string
Common meaning
chmod arguments
u=rw,go=r
644
rw-r--r--
File readable to all, writeable to user only.
u=rwx,go=
700
rwx------
Private directory or file, for user only.
u=rwx,go=rx
755
rwxr-xr-x
Executable file or directory, accessible for all
ug=rwx,o=x
775
rwxrwxr-x
Executable file or directory, writeable for group, readable for all. Open project directory.
ug=rwx,o=
770
rwxrwx---
Executable file or directory, for user and group only. Restricted project directory.

Project directories

If you own a project directory for shared data, you will have to decide if the directory should be readable (and executable) for others, or just for the group. Sometimes you want both, but that can not be done for a single directory.

One solution is to let the top directory be open, and create one or more restricted subdirectories within. So given a directory "project", you can do:

$ chmod 775 project
$ mkdir project/restricted
$ chmod 770 project/restricted
$ ls -ld project/ project/restricted/
drwxrwxr-x. 3 bill geofag    24 Feb 13 11:25 project/
drwxrwx---. 2 bill geofag     6 Feb 13 11:25 project/restricted/

You will probably also want to set an appropriate group and the setgid bit, as previously discussed.

Questions?

As always, you IT staff will help you if you have questions about how to share and protect your files.

By Hans Peter
Published Nov. 2, 2017 12:57 PM - Last modified Jan. 31, 2023 4:20 PM