I own a particular file on a Linux system. I would like to give 2 groups (accounting, shipping) read access and only read access, and 3 users(Mike, Raj and Wally) write access and only write access.
How can I accomplish this?

In a world of Windows where file permissions can be granted on a per-user basis, Linux and Unix permissions seem to be very hokey and restricted.

Well, let me tell you, they’re not. For such a seemingly basic arrangement they are an incredibly powerful tool.

Most people forget that to do anything even remotely fancy with permissions in Linux you really have to couple them with groups. And you really can do some fancy things with them!

Basic Permissions

Let’s start by looking at the basic permissions structure.

In Linux permissions are grouped into 3 main sections – Owner, Group and World. The Owner permissions define how the owner of the file can interact with the file, the Group permissions how people in the same group as the file can interact with it, and the World permissions how everyone else can interact with it.

These permissions are defined as a number between 0 and 7. They’re in Octal. That’s base 8 for the more programming literate amongst you.

An octal number is made up of 3 binary bits. In permissions the left-most bit is assigned to the Read permission, the middle bit to the Write permission, and the right-most to the Execute permission:

Read

Write

Execute

Octal

0

0

0

0

0

0

1

1

0

1

0

2

0

1

1

3

1

0

0

4

1

0

1

5

1

1

0

6

1

1

1

7

Permissions in Linux are applied using the chmod command (short for Change Mode) like this:

$ chmod <octal> <filename>

So, for example, to allow the owner read and write, the group read, and stop anyone else from accessing the file at all, the octal would be (from the table above) 640:

$ chmod 640 myfile.txt

The ls -l command can inspect the file permissions that we have just set:

The string of characters on the left is the file permissions. Any permission that is not set is depicted as a -

No, your eyes aren’t deceiving you – there really is one extra – there than you’d expect. The very first – is not a file permission, but a description of what the file is. A d in that position means the file is actually a directory. An l means it’s a symbolic link, a p for a named pipe, etc. A – means that it’s a normal, bog standard, file.

So splitting it down into groups of three we see: -/rw-/r–/— which is what we’d expect.

Immediately following the file permissions there is a 1 – this is the number of references to the file – hard links. We can ignore this for now. Next come two matt’s. The first is the username of the file’s owner, and the second is the group the file belongs to. Not the group the owner of the file belongs to as you might expect, the file itself belongs to a group.

Belong to a group?

The group ownership of the file can be changed using the chgrp command (short for Change Group):

So so far that’s fairly simple and straight forward. You can easily allow groups of people to read specific files. Now let’s get a little more fancy…

What if you want to provide a directory that members of a group can write to? You’d think that it would be a simple matter of making a directory and providing the group with write access. Well, let’s take a look, shall we?

$ ls -ld shared
drwxrwx--- 2 fred users 4096 2011-04-21 10:00 shared

(note the -d flag to ls there – it says to list the directory itself, not the contents of the directory)

You can see the d at the beginning to show it’s a directory, the read, write and execute to the owner (fred) and the group (users) and denied access to everyone else.

Directories treat the execute permission differently to files. For directories it actually means allow reading of the file list within the directory.

Yes, the user has managed to make a file in there. But you notice something? The group the file belongs to is the primary group of the user that made it. Now, the user could go back and use chgrp to change that, but that’s somewhat cumbersome, yes?

Well, actually, right at the start of this post I lied to you. I said there were three groups of permissions. That’s not strictly true. There’s a fourth, extra special, group of permissions, which are the ‘modifier’ permissions. They don’t actually define permissions themselves, but modify how the permissions of the other three sections work.

Getting sticky!

There are three special permissions: SetUID, SetGID and Stciky. They have different meanings when used on normal files compared to directories.

SetUID

SetGID

Sticky

Octal

0

0

0

0

0

0

1

1

0

1

0

2

0

1

1

3

1

0

0

4

1

0

1

5

1

1

0

6

1

1

1

7

Normal files

The SetUID is used to change who a command is executed as. Some system-level commands are SetUID to root (The owner of the file is root and the SetUID flag is set) so that when the command is run it is elevated to have root level permissions. This is both exceedingly useful for system commands, and exceptionally dangerous – it’s a prime candidate for hackers trying to obtain root permissions locally. Use with extreme care.

SetGID when applied to a file has no effect. Neither does the Sticky bit.

Dircetories

This is where the fun begins.

SetUID on a directory has no effect.

SetGID, however, is a whole different ball game. When a directory has the SetGID bit set and a file is created within that directory the group ownership of the file is automatically modified to be the group of the directory.

The Sticky bit means that only the owner of a file (or root) in this directory can delete or modify it. This is useful for shared temporary areas, like /tmp and /var/tmp.

We’re not quite there, however. The group members can’t write to that file. A simple chmod of the file (660) would cure that, but again, that seems kind of clumsy.

There’s one more command to introduce to you: umask

The umask defines the default permissions when a user creates a file. You might expect it to use the same format as chmod, but oh no, it’s not quite that simple. It defines the permissions that get removed from the system default permissions when the file is created.

Most systems have a system-default set of permissions of 0666 for files (rw-rw-rw-) and 0777 for directories (rwxrwxrwx). The values in umask get subtracted from these numbers to give the new permissions:

$ umask
0022

You see that my umask is 0022 – so this gets subtracted from the default file permissions (not mathemtaically as such, but on a per-permission basis):

0 - 0 = 0
6 - 0 = 6
6 - 2 = 4
6 - 2 = 4

If any permission equates to a number less than 0 it is rounded up to zero, so a umask of 0027 would give the last number as 0 regardless of whether the system default had a 6 or a 7 in that place.

So my umask gives us a default permission of 0644, which equates to rw-r–r–, exactly what we are seeing above.

Perfect! The file is available for anyone in the users group to edit! The umask command can be put in your .bashrc file to keep the settings as you prefer them. Also, a number of file upload systems (like FTP servers) provide a setting for the umask when files get uploaded. This means that you can create an area into which any members of a group can upload files to – for example a shared website folder that anyone in the website managers group has access to.

Being individual

One final thing to mention:

There is a second way of setting the permissions in many Linux systems (and some Unix, but not all) which is a much easier way for changing individual permissions:

$ chmod <class><direction><permission> <file>

Where <class> is one of u (user),g (group) or o (other, or world), direction is a + or a -, and permission is one of r,w,x or s. This allows you to turn on and off individual permissions. For example:

$ chmod g+s shared

would turn on the SetGID bit of the shared directory.

$ chmod o-r myfile.txt

would remove the read permission from everyone else.

So you can see, the Unix file permissions system is actually considerably more powerful than it appears at first glance. It does take a bit of practice getting your head around it properly, but it is so surprisingly flexible.

@warren – the only extra piece of knowledge you’d need for the second question is that if you want to specify multiple sets of attributes you will have to do it on separate hard-links to the file. Those can be created with the ‘ln’ command (ln myfile myfilelink). Then you can allow 1 group to have read access on “myfile” and 1 group to have write access on “myfilelink”. Both files reference the same data, so changing one file will also change the other.

Unix file permissions does seem to be a commonly asked question all over the place – hence we decided to write an article about it.

This is wrong. A hard link is a second directory entry that points to the same inode. Since all file metadata other than the name (including owner, group, mode (permissions number), and ACL) are in the inode, this means that a file and a hard link to that file cannot have different owners or groups.