Yiling's Blog

(This site is very broken right now due to
an ill-planned domain migration. Another
version of this site built using Next.js will
be brought online later.)

Linux File Permissions


Summarising what I have recently learned about this topic and also leaving some future references for myself. The information isn’t comprehensive and may have some inaccuracies, and will probably be updated in the future if necessary.

Two factors: ownership and permissions

Access to a file depends on two factors: ownership and permissions.

A file have two ownership properties:

  • user ownership, and
  • group ownership.

Note these aren’t one of two options you choose from, but separate properties requiring their own value.

Corresponding to the above, a user trying to access a file may fall into at least one of three identity categories:

  • user owner,
  • member of group owner, and
  • others (referred to by some hosting services as world).

There are three types of permissions:

  • read,
  • write, and
  • execute.

Each permission type can be set to either allow or deny for each identity category in a Linux file system.

Reading current permissions

ls -l will show current permissions of files. For example:

drwxr-xr-- 5 username groupname ...

Of the four space-separated sections:

  • d – The first character of the first section indicates whether the current line item is a directory or a link in which case an l would be displayed.
  • rwx – The 2nd to 4th characters of the first section represent, respectively, the read, write and execute permission settings for the user owner. In the example. all three permissions are allowed.
  • r-x – The 5th to 7th characters of the first section represent permission settings for members of the group owner. In the example, read and execute are allowed, whereas write is denied.
  • r-- – The 8th to 10th characters of the first section represent permissions for all other users. In the example, only read is allowed.
  • 5 – The 2nd section shows the number of hard links within the current line item and is irrelevant to this topic.
  • username – The 3rd section is the name of the user owner.
  • groupname – The 4th section is the name of the group owner.

Managing permissions

Simply put:

  • Use chown to change user owner.
  • Use chgrp to change group owner.
  • Use chmod to change permission.

chown example:

chown -R myname yourdirectory 

This is to set myname as the user owner of yourdirectory. the -R option recursively changes the user owner of everything inside yourdirectory.

chgrp example:

chgrp thisgroup thatfile.txt

This is to set thisgroup as the group owner of thatfile.txt.

chmod examples:

chmod g+w myfile.txt

This is one of the ways to change file permissions, and it sets the write permission of group owner to allow. In it:

  • g meas group,
  • + means allow, and
  • w means write.

Instead of g, one can also do:

  • u (means user),
  • o (means others),
  • a (means all), or
  • a combination of the above such as gu, though, obviously, combining a with any other is pretty pointless.

Instead of +, one can also do:

  • - (means deny).

Instead of w, one can also do:

  • r (means read),
  • x (means execute),
  • a combination of the above such as rwx.

An alternative way to change permissions is to use the numerical representations of permissions:

chmod 721 myfile.txt

Of the three numbers, 7, 2 and 1:

  • 7 – Being the 1st number, sets user permissions; the value 7 represents allow read, allow write and allow execute.
  • 2 – Being the 2nd number, sets group permissions; the value 2 represents deny read, allow write and deny execute.
  • 1 – Being the 3rd number, sets others permissions; the value 1 represents deny read, deny write and allow execute.

Here’s a full list of numerical representations of all permission states:

  • 0 represents ---
  • 1 represents --x
  • 2 represents -w-
  • 3 represents -wx
  • 4 represents r--
  • 5 represents r-x
  • 6 represents rw-
  • 7 represents rwx

In other words, 721 represents rwx-w---x.

Mode bits?

One might wonder why the command for changing permissions is chmod instead of something like “chprm”. This is because “chmod” is an abbreviation for change mode where “mode” refers to mode bits which include:

  • permission bits,
  • sticky bit,
  • setgid bit, and
  • setuid bit.

So far, all sections except this one only talked about permission bits.

The sticky, setgid and setuid bits

The sticky bit, on modern Linux systems, is only relevant when set on a directory. When this happens, no user except for the user owner and the super user may delete, move or rename the contents of the directory.

The setgid, or set-group-ID or SGID, bit, when set on a file, would allow any user to execute the file as if they belonged to the group owner of the file. On most systems, setting this bit on a directory will cause any files or directories created within to inherit the group ownership of the directory.

The setuid, or set-user-ID or SUID, bit, when set on a file, would allow any user to execute the file as if they were the user owner of the file. On a few systems, the bit can also be set on a directory, which would make any files or directories created inside the directory to inherit the user ownership of said directory.

To set or unset these bits, one can again do it either of two ways:

chmod +t mydirectory
chmod g+s mydirectory
chmod u-s myfile.txt
chmod gu+srx myfile.txt

Respectively, the above commands:

  • set the sticky bit,
  • set the setgid bit,
  • unset the setuid bit, and
  • set both setgid and setuid bits while allowing read and execute by both user and group.

And the numeric way:

chmod 01700 mydirectory
chmod 02700 mydirectory
chmod 04700 myfile.txt
chmod 06700 myfile.txt

Respectively, the above commands:

  • sets sticky, unsets setgid and setuid, allows read, write and execute by user, and denies group and others all permissions;
  • sets setgid, unsets sticky and setuid, and sets the same permissions as the above;
  • sets setuid, unsets sticky and setgid, and sets the same permissions as the above; and
  • sets setgid and setuid, unsets sticky, and sets the same permissions as the above.

It should be obvious that the numeric representations of sticky, setgid and setuid must come before the numerals for permission, and the former have a similar schema to the latter:

  • 00 unsets all three bits
  • 01 sets sticky, unsets setgid and unsets setuid
  • 02 unsets sticky, sets setgid and unsets setuid
  • 03 sets sticky, sets setgid and unsets setuid
  • 04 unsets sticky, unsets setgid and sets setuid
  • 05 sets sticky, unsets setgid and sets setuid
  • 06 unsets sticky, sets setgid and sets setuid
  • 07 sets sticky, sets setgid and sets setuid

Though, given the different applicability of each bit to files and directories, some of the above combinations will unlikely be used.

Interestingly, almost all of the online resources I found suggest one should use four numbers instead of five (in other words omit the leading 0) to change non-permission and permission bits at the same time. The only exception is the section 2 man page for chmod.

In my own testing, four digits performed inconsistently while five worked as expected every time.

Reading current setting of sticky, setgid and setuid

Again, using ls -l, one might see:

drwsr-sr-t ...
drwSr-Sr-T ...

Notice where x‘s were previously shown now show s, S, t and T:

  • A lower case s, depending on whether it appears in the user permissions section or the group section, means execute is allowed and either setuid or setgid is set.
  • A capital S, again, depending on its position, means execute is denied and either setuid or setgid is set.
  • A lower case t, which can only appear in the others permissions section, means execute is allowed and sticky is set.
  • A capital T, which also only appears in the others permissions section, means execute is denied and sticky is set.