University of Minnesota
Development of Secure Software Systems

CSci 4271 Lab 6

Today's lab will give you hands on experience with Unix file permissions, continuing the abstract discussion from lecture.

For the first part of the lab, we'd like you to spend some time trying out Unix commands related to checking and changing the permissions on files. In the description below we'll first introduce some permissions-related commands; then we'll give some suggestions of things you can try out.

Since you're doing the lab with other students, you should take advantage of being able to ask another student to test an operation for you. One of the limitations of trying out file permissions yourself is that you can only simulate one user's accesses, but someone else can check how permissions work for a non-owner.

Your CSE Labs home directories are stored on a networked file systems where some rarer aspects of permissions are unsupported or work differently. You also might not want to change the permissions on your home directory to let another student access it, even temporarily. So what we recommend you use instead is creating files and directories inside the directory named /tmp that is explicitly for temporary files. Note however that the /tmp directory is not shared between machines, so multiple people doing testing should all SSH into the same machine to run experiments in its /tmp. Also, the top-level directory /tmp has some special rules, so create a subdirectory of /tmp for testing.

There are three commands we recommend you try out for looking at the permissions on Unix files (all of these commands also have more detailed documentation in their man pages):

  • The most commonly used program is ls with the -l (lowercase ell for long) option that causes it to print a line of information about each file or directory. The permissions information is in the 2nd through 10th columns, after the very first column which gives the file type. These columns mostly correspond to the nine basic permissions bits, where they are either a hyphen to represent a bit being 0, or an r, w, or x to represent a one bit based on its position. There is an exception that an x bit will turn into an s, S, t, or T in some special circumstances we haven't covered yet. Later in the line you'll see the names of the user and group owners.

  • The stat command-line program is like a more detailed version of ls -l that prints all of the metadata returned by the stat system call, across several lines. The line of its output that has the headings Access:, Uid:, and Gid: has the permissions information. The most useful extra feature for us is that it prints the octal version of the permissions bits.

  • The command getfacl provides the most expanded version of the permissions information; as the letters ACL in its name indicates, the multiple lines of its output have the structure of a general access-control list. You may find its output the easiest to read; it also become important once you try out more general ACLs (described later).

Then there are two commands you can try out to change permissions on files:

  • The command chgrp has a limited purpose: it changes the group of a file. Only the owner of a file can change its group, and they can only change it to another group they are a member of. You can use the command groups to see what groups you're a member of. There is also an analogous program named chown to change the owner of a file, but it is useless to you on CSE Labs machines because only root can change the ownership of files. (Actually, chown can change just the group; then it's equivalent to chgrp.)

    The command chmod changes permissions. The most basic way to use it, which is convenient if you know exactly the permissions you want in octal, is to use the new permissions in octal as the first argument, and any remaining arguments are the names of files or directories you want to have that permission set. If you want to change some of the permissions and leave others the same, which is most important if your changing multiples files at once, the first argument also has a letter-based form that you can read about in the manual page. And if you want to change the permissions on a whole tree of files, the option -R causes chmod to work recursively on a directory and all of the files and directories inside it.

Take some time to try out these programs on different files, and then trying to do different operations on the files, to see whether the permissions work the way you would expect. For checking whether you can execute a file, you may want to work with a file that's a copy of a simple executable from a system directory, for instance /bin/uname. Once the basics seem to make sense, here are some further things you can try:

  • Try creating a directory where you have execute but not read permissions. For instance if you can access a file in that directory if you know its name, but ls and tab completion won't work.
  • Conversely, what happens if you try to run ls or ls -l on a directory for which you have read but not execute permission? Why?
  • If you have write permission but not execute permission on a directory, are there any operations you can do to it?
  • Suppose there is a file that you want to modify, and you don't have write permissions on the file, but you do have write permissions on the directory where the file is stored. What can you do?
  • Similar to the previous question, but what if the file is inside several levels of directories you don't have write access to, but high above it there is a directory you can modify?
  • The restriction of file ACLs having only one specified user and one specified group, which is traditional in Unix, has been lifted in many derived systems. The extension that's most reliably available for local filesystems on Linux is referred to as POSIX ACLs (though it never made it to an official part of the POSIX standard). You can set these with the command setfacl which is the modifying counterpart of the reading program getfacl mentioned above. The full mechanism has a number of wrinkles, but as something simple you might try giving read access to just one other person, something that in the traditional Unix model would require creating a new group.

Here's one question you might think about as a bit of a brainteaser; it's related to Unix permissions bits but is more of a math (or CSci 2011) question. If we put no restrictions on the different bits in a permissions set, there are a total of 512 different possible permissions sets, but most of these are not very useful. One restriction you might imagine imposing to get a more limited but useful set of permissions is to require that the permissions never go down as you go to a more specific level. In other words, require that every permission that other users have, group users have, and every permission that group users have, the owner also has. For instance 000, 700, 777, 755, and 664 all obey this restriction, but 070 and 321 do not. How many permission sets remain after imposing this restriction? The best answer would be a formula for counting the permissions that generalizes to different numbers of permission bits or different numbers of levels, and an explanation of where the formula comes from.