Unix File Permissions
Part 2

by Kurt Keller

Last time we briefly looked at commands to list and change file permissions, without explaining the details about these permissions, also called file modes. It is what we will do this time, have a thorough look at what these bits and flags do. was unable to map the groupID to a groupname.

Permissions

In Unix everything is a file and every file has not only an owner, an owning group and is of a certain filetype, every file and directory also does have a set of permissions going with it, describing who can do what to the file or directory.

permissions on files

The nine filemode positions in the first field of the long listing, positions 2-10, are three sets of three three flags each and tell us what kind of permissions three different types of users have on the file. The first set specifies the permissions the owner of the file does have, the second set is responsible for the group the file belongs to and the last set defines the permissions for all other users, also referred to as the rest of the world. Each set itself consists of three flags, the first for read access (r), the second for write access (w) and the third for execute access (x). Figure 2 tries to visualize this.

Let's have a look at an example:

When split into the three groups, we see that the owner of the file, the userID john, does have permissions rwx, members of the group projgrp have permissions r-x and the rest of the world has -x. What exactly does this mean? Well, John can read the contents of the file thanks to the read (r) permission. He can also write to the file and change it's contents, because he has write (w) permission to it. And he can execute the file due to the execute (x) permission. So he can do anything he pleases with this file, he has full permissions on it. Anything? Not necessarily. Telling from these permissions, we don't know whether he can delete or rename the file, as we will see later, when talking about permissions on directories.

The group projgrp can read the contents of the file (r) and execute it (x) if it is program. But members of this group can not change the contents of the file, because they are missing the write permission (w) which would be required for this.

What can somebody do with this file who is neither the user john, nor a member of the projgrp group? For the rest of the world, only the execute (x) permission is granted. This file is world executable, but neither world readable nor world writable.

Figure 2: filemodes and their meaning

which permissions apply

Wait a minute. Isn't there some kind of conflict here? John has the userID john on the system, but at the same time his userID is a member of the group projgrp. Which of the file permissions actually do apply to him now?

When working with file permissions, it is important to know that always the most specific set of permissions applies. In other words, for the owner of the file only the first set of permissions is effective, the one specifying the permissions for the owner, no matter what the other permissions are. If somebody does not own the file but is a member of the group the file belongs to, the group permissions apply. And for somebody neither owning the file directly, nor through group membership, the world permissions are the ones to watch. So in the above example, John does have full permissions on the file. Let's have a look at another file in John's home directory with the following, somewhat strange, permissions:

The owner of the file has no permissions at all, the group has write and execute permissions and the world has read permissions. John, the owner of the file, can not do anything with this file. He is not able to read it, neither can he write to it, nor execute it. For him, because he is the owner of the file, the first set of permissions, called the owner permissions, and this set only, defines what he can do with the file. In this special case he can do nothing at all. Even though John is a member of the group projgrp and that group does have write and execute rights to the file, John himself can not write to it or execute it. And even though the whole world can read the file, John can't.

All ohter members of the group projgrp are somewhat better off than John himself. They can execute the file and write to it. However, they will not be able to edit the file with a text editor. An editor will first read the file in order to display the contents to the user for editing. As the group does not have read permissions, the editor will not be able to read the file first and thus it will exit with an error. Writing to the file is possible for members of the group projgrp, but they must write to it directly, without reading it in first.

The only people who can read the contents of this file are users which are neither John, nor members of projgrp.

running scripts versus binary executables

Special care must be taken when setting permissions on shell scripts, perl scripts, python scripts etc. These are all interpreted languages; the scripts are not compiled and directly executable. Instead an interpreter is being run, which will read the commands in the script file and execute them. This is even true when you run the script directly using the hash-bang (#!) trick to include the location of the interpreter in the very first line of the script. So what permissions does a script need to have in order to be run?

Basically, there are two ways you can run a script. Most often scripts include a special first line which specifies the interpreter that must be used to run them. Such a line starts in the first column of the first line with a hash mark (#), immediately followed by an exclamation mark (!), followed by the location of the interpreter. For a perl script this could be
     #! /usr/bin/perl
When you run such a script directly, it will read the first line and execute the interpreter specified there with the script itself as input. Once again, a bit more slowly: We execute the script, which immediately will execute the specified interpreter and tell it to read the file for the commands to execute. So what permissions are required? At the very beginning we need the execute bit to be set. Then the interpreter, running under the userID of the invoking user, needs to read the file, so we also need the read bit to be set. With only the execute bit applied, the interpreter would not be able to read the instructions in the script and with only read permissions set, the first line in the script would not be able to invoke the interpreter. Don't forget, the interpreter itself is also run under a specific userID, the userID which called it or called the script. So, if you try to execute one of your own scripts, you need read and execute permissions on the file. If somebody else, who is neither you nor a member of the file's group, should be able to run the script, world needs read and execute permissions. The same, but for group permissions, if the owning group of the file must be able to run it.

Are you sure that nobody can run your script if you set read and execute permissions for yourself and read only permissions for all other people? This should allow anybody to read the file but not to execute it, right? Not quite so. On one hand, if they can read the script, they are also able to copy it, change the permissions on their own copy and run that one instead. On the other hand, scripts can also be run differently, by calling the interpreter manually and passing the script as an argument. So anybody who can read your script, can also execute it, maybe not by calling it directly, but surely by passing it to the correct interpreter.

It's a different story with compiled executables. These can be run directly and no read permission is required, the execution bit is absolutely sufficient.

permissions on directories

Now you know about permissions on files, so permissions on directories are no big deal any more, right? But what, for example, is the execute bit on directories good for? After all, directories are not executable programs or scripts.

If you do know what directories are, how they are built and how they are stored on the file system, it is not too difficult to understand what exactly the permissions do. Whithout that knowledge, though, it is not quite so obvious and can make even otherwise knowledgable unix sysadmins scratch their head. So let me first explain what kind of thing a directory is deep down in the filesystem.

what are directories

The concept of files is not foreign to practically all computer users. It is like a sheet of paper with something written on it. And a directory? For most people that is like a folder or a box into which you can put your sheets of paper, your files, and smaller boxes. This metaphor of a directory is fine for most purposes, but it does not represent what is happening deep down in the inner workings of the filesystem. And it is quite unhandy for properly comprehending Unix file permissions on directories. So what is a directory really? In fact, it is nothing more than another file. Some kind of index file. Physically, the filesystem is not a hierarchical structure. We only mantle it with a hierarchically structured logical view to mask the fact that there is just one big, flat space and each file is placed next to each other on the round, flat platters of the harddisk. Each directory is just another file, another sheet of paper. But on these directory sheets, you don't write any text or program data, you write an index of what is where on the disk. All the files and directories which are logically placed into a particular directory do have an entry on sheet of paper representing this directory; their name and a pointer to the place on the flat disk, where that file or directory is stored. So, when you create a new file in the directory /tmp, let's say /tmp/testfile.txt, the system will write the data of testfile.txt to some place on the disk, any place with enough free space in fact, then open the directory file for /tmp, write in this index file the name testfile.txt and the location where on the disk it can be found.

write permission

As we just discussed, when you save the new file /tmp/testfile.txt, you do not only write this new file, but also a new entry in the directory file for /tmp. If you do not have write permissions on the directory itself, you can not save your file in this directory. Does this sound logical? Fine. But this does have more implications, which is not so obvious at first. Say you want to delete the file /tmp/testfile.txt again. Deleting this file will not actually wipe the data in that file. All it does is to remove the pointer to it from the index, the directory file. The data itself is not touched and the file itself not accessed. The only change happens in the directory file. So, if you have write access to the directory itself, you can remove the file. If you do not have write access to the directory itself, you can not remove it, even if you have full permissions, including write permissions, to the file itself. From this the conclusion can be drawn, that you can remove or rename any file in a directory if you have write access to the directory itself. This is correct: for deleting and renaming a file, its permissions do not matter at all, as you are not doing anything to the file, but only to the directory index. You can even remove and rename files of other users to which you would not normally have access. When you want to change the contents of a file, the permissions of the file are applicable, but if you want to remove or rename it, only the permissions of the parent directory do matter.

Thinking this over properly, you will come to realize how great the impact of proper permissions on directories is to system security.

execute permission

What about the execute bit on directories, what is this used for? If you do have execute permission, this means you can access the files referenced within that directory. It is possible to cd (cange directory) into that directory or otherwise access files in it, even if you can not list the contents of the directory.

read permission

The read permission looks a little bit more complex again. Basically, with read permission you can list the contents of the directory. But read permission only is not sufficient for doing a long listing. The long listing will show more information about each file, for example its timestamp, its permissions etc. For accessing these pieces of additional information, we must be able to get to the files themselves and read the settings in their inodes; we must be able to go into the directory and access the files. Remember? We would need execute permissions on the directory as well.

By the way, if you know the name of a file in a directory and do have execute permission on the directory but no read permission on it, you can still access and list that file by specifying the file explicitly. It is not possible to list the whole contents of the directory, but you can do it for files of which you know the filename.

As we've seen, being able to list the contents of a directory does not have anything to do with the ability to access files in that directory and vice versa. Neither can restrictive file permissions on files prevent somebody from deleting or renaming the files if (s)he has write permission to the parent directory of the files. Just like files, every directory does have an owning user and an owning group, and it does have permissions for the owner, the group and the rest of the world.

next time

Now we have learnt about permissions on files and directories. About the common ones, that is. There are a few more permission flags and some other, closely related info to cover. But we'll be doing that next time, in part 3.

References

Knoppix  http://www.knoppix.org/
years of experience  not available online
PINBOARD  http://www.pinboard.com/
HighTechSamurai  http://kurt.www.pinboard.com/