Section 1: Introduction to Linux permissions

Linux is today considered the most secure operating system by many. One of key factors to system security is access permission control. All modern operating systems support this feature, which I believe first appeared in UNIX operating system. It allows file owners to restrict who can read, write, execute and otherwise change files, running processes ('tasks') and other parts of the system.

Linux, as every UNIX-like OS, has a built-in file permission control system. It assigns the following attributes to every file on its file system:

You can see what user and group you are by issuing the following command in a terminal emulator (try gnome-terminal or konsole):

id -a

uid will tell you who you are (as if you didn't already know this), gid is your primary group, and groups - all other groups your user belongs to.

Used terms:

file system - an on-disk structure holding descriptions of files (such as the attributes mentioned above, file modification date etc.) and the files' contents themselves. File systems are contained in disk partitions (also called slices). Most popular file systems today are ext3, xfs and reiserfs. If you run Debian, you probably use ext3. Worth mentioning is the fact that directories ('folders') are also considered files, simply containing other files. Therefore, permissions apply to directories, too.

user group - in UNIX-like systems, every user is assigned to some group. Users in the same group may share rights, for example a file's permissions may be set so that all users in a group can modify its contents.

Section 2: UNIX permissions explained

Having learnt the theory, it's time to pass on to practice - what do UNIX file permissions look like and how to use them? First of all, let us examine the permissions of an example file. By issuing the following command in Linux console or a terminal emulator:

stat /etc/hostname

you will see a list of file's attributes. It includes file type (it could also be a directory, a symlink, etc.), file size et cetera and a line like quoted below, which is the item of our interest:

Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)

Obviuosly, the file is owned by root user (system administrator) and belongs to root group. After the slash, numeric user ID's are shown - that's the way they are stored in the filesystem, in order to conserve disk space.

Access field contains an octal number and its human-readable representation (I personally consider the numeric one to be more readable). It is crucial to know what the permission number means. It consists of four digits, ranging from 0 to 7. For now, we shall skip the first one and focus on the last three, as they are used most commonly on every system. In our example, those are 644. Each digit may be a sum of 4, 2 and 1, but not every component has to be included, giving a possible range from 0 to 7. Below is the meaning of the sum components, with Subject being user, group or others, as discussed below.

Therefore, number 5, for example, would mean: a permission to read and execute, but not to write.

The digits define respectively: owner, group and others' permissions. Therefore, we can see that, in our example, file owner (root) may write to the file and read its contents, while group 'root' and other users (not being root nor a member of group 'root') are given the right to read the file.?BR Now, compare it to file permissions of /etc/shadow (use 'stat' again). This file has 0 as the third meaningful digit, so users not being root nor in group 'shadow' may not even read the file. You can easily confirm that by running a text editor and trying to open /etc/shadow - you, as a regular user, should not be allowed to see its contents as it contains system-wide passwords (and this is beyond the scope of this little How To).

A note on path handling To access any path in the filesystem, the user (which the particular process is running as) needs at least execute privilege for all its parent directories. Therefore, if you try to access an example file /etc/security/limits.conf, even though it has a mode of 0755 (for the sake of example), it does not necessarily mean you are free to read it. To read the file, you have to be able to 'execute' all of its parent directories, so you need execute permission on /etc and /etc/security. If either /etc or /etc/security has permissions set so that you are not allowed to execute it (1), then reading /etc/security/limits.conf will fail. This rule applies anywhere in the filesystem.

Section 3: Modifying file permissions

This section shows, using an example, the very basic usage of chmod command. Chmod is one of sysadmin's best friends and the standard tool for manipulating file permissions in various Unices (also works with *BSD and Solaris!). Let's begin... First of all, create a file for demonstration purposes. In the example, I will be using name testfile. Commands below are to be executed in a terminal emulator or Linux console. You can basically just copy, paste, and see how it works.

# first of all, create the file using touch command (see 'man touch' for details)
touch testfile
# now, let's see its permissions
stat testfile
# modify the file so that group members and other users can write to it
chmod 666 testfile
# see the new permissions
stat testfile

Have the file permissions changed? You can verify that it actually worked by starting a new session and logging on to another user account, or issuing su username. If you only have one user account, create a new one for testing:

su
(your root password here, to log on to root account and add a test user)
adduser demo
# you can remove this user when you've finished: deluser demo

Now, log on to demo, open testfile (in your regular user's home directory) and type something in it. Save, and then check with your own user's account that it contains whatever you may have written. Voila! You may now want to check it with various different permissions. Try chmod with arguments like 644, 640 and so on.

Section 4: Example scenarios involving chmod

You now know how to change file permissions. However, how can they be useful in real life besides letting your buddy leave you a random message in your own text files?

Case 1: family photos

Situation: You store family photos in directory Photos on your user account. Several other family members use the computer and you want them to be able to access the photos. Question: How to set directory permissions so that other users can see your files and their content? Answer: Set the directory to 755 and all files under it to 644:

chmod 755 Photos
# Photos/* means all files in Photos directory
chmod 0644 Photos/*

Case 2: Software and data files for your department at work

Situation: In your home directory you have a program in ~/AppSoftware/program.bin . It stores your department-specific data files in ~?/OurData. The system operator has assigned you and other people in your department a user group 'mydept'. You want other people from your department to be able to run the provided software and to write the data files. At the same time, other people from outside the group should be allowed to run the software but not to modify the data. For simplicity's sake, we skip things like logging who added/removed what in terms of data (logging is a necessity in real life), focusing only on appropriate permissions. Question: How to allow execute access for a group to one file (program binary) and read-write access to other directory for the same group, while denying world (other users) access? Answer: In our example, this would be:

# below: -R flag, affects the directory and files/subdirs inside
chmod -R 0755 ~/AppSoftware
chmod -R 0770 ~/OurData

In case files have a wrong group attribute set, you can correct it by first running chrgp -R mydept files, where mydept is the group name, files is file path, and -R switch tells chgrp to run recursively (see above code example). Chgrp changes files' group to the one given.

Case 3: Classified files

Question: How to protect files that are to be kept secret?

Answer: A very basic protection can be achieved by chmodding the sensitive files/directories to 0600. However, remember that the system administrator (root) can still access them, regardless of set file permissions. Therefore, besides locking down file permissions, it is highly advisable that you encrypt the files using strong encryption software (try gpg encryption via programs like KGpg, or see ccrypt - symmetric cryptography).

UNIX permissions and their limitations

Examples above show the usefulness of UNIX file permissions. You can grant users from your group access to your files, expose them to the whole world or have them only for yourself. However, there are use cases in which this access control model is not enough. Assume that you are on a large system (perhaps a server) and, together with several dozen users you are members of group 'users'. Now, you want to make some of your files available to just one of them so that the others can not read it. How can UNIX permissions benefit you? In short: they can not. You are now dependent on some other means of exchanging files like e-mail or IM. Or, alternatively, you can make use of...

Access Control Lists in Linux

Access Control Lists (called ACL) are an extended means of defining access rights to files and objects. They allow you to specify file permissions in a more fine-grained way, assigning any user or group (besides owner and file's set group) different privileges. For instance, you may share a file with just one specific user, no matter what group they are in. How to make use of this new, powerful feature?

First, make sure your system supports ACL. Several criteria must be met before you can enable ACL for your files. Check your kernel version. If it is anything later than 2.6.18, then chances are you already have ACL support built-in. (I'm not quite certain at which version Debian kernels received the ACL patch). The next thing is acl package, required for ACL attribute manipulation. You can install it by issuing:

 # if you are not logged on as root, use 'su' first
apt-get install acl

Alternatively, you can use Synaptic package manager to get and install the package. If you are not the system administrator, ask your sysadmin to enable ACL on your machine.?BR Once you have installed acl, you can try and see if your file system supports it. Example command (I assume that file 'testfile' exists):

setfacl --modify user:demo:5 testfile

If setfacl complains about an error, you probably need to mount your filesystem with acl option. Assuming that the filesystem 'testfile' is located on is / , execute the below as root:

mount -o remount,acl /

Try setfacl again. If successful, a call to:

getfacl testfile

should show, among others, a line like this: user:demo:r-x Here, rx means 'read, execute' permission, which is equivalent to 5. To see if Access Control Lists work, set the file permissions on testfile to 700 using chmod and try to open it from 'demo' user account. If successful, ACL did override UNIX permissions indeed. Your file system is now ready for granular access control with ACL!

Note: To enable acl permanently for certain filesystems, you should include acl option in /etc/fstab. Please refer to fstab(5) manual page for instructions.

Example uses of setfacl to manage file permissions

setfacl -R -m user:josh:6 filedir   # sets read-write permissions for josh on filedir and all its contents
setfacl -m group:junior-sys-admins:4 /var/log/apache2/error.log    # let group members of junior-sys-admins read Apache2 error log file
setfacl -m user:evilcraig:0 my_notes.txt    # prevent user evilcraig from accessing my_notes.txt

Default (inherited) ACL

Default ACL are an invaluable tool when making a directory that you want to share for reading or writing among users. This hint is inspired by this thread on the Debian forums: http://forums.debian.net/viewtopic.php?f=10&t=53591

Default ACL are access control entries that get inherited by all sub-items of a directory (recursion deeper is allowed!). Thus, if you want to create a directory for bob and fred so that both can work on each other's files, the below should suffice (notice the -d flag to setfacl, it sets a default ACL):

mkdir common_workspace
setfacl -m u:bob:7 common_workspace
setfacl -d -m u:bob:7 common_workspace
setfacl -m u:fred:7 common_workspace
setfacl -d -m u:fred:7 common_workspace

Note to the above: a default ACL is inherited by all child nodes as an ACL entry and default ACL, but a default ACL on its own does not take any action permission-wise - hence the double command. The first call gives user 'bob' the right to write, read and execute the directory, and the second one sets up the default ACL which will be inherited.

Now, whenever a file gets created, it retains its original owner and group, but should automatically get assigned the above ACL. This is, for example, useful when you have users co-working on website development. You can use Apache or PHP running as www-data, write a script to change file ownership upon creation to www-data (inotify helps!), and all files are still writable by bob and fred, your Web developers.

Appendix: Some hints

  adduser me otherguy # adds user 'me' to group 'otherguy'

Then, 'otherguy' can just set their files to 0750 or whatever permissions they want you to have. However, this is the old-fashioned approach to granular file permissions and should be avoided whenever possible in favour of ACL.

That's all! Have fun and thanks for bearing with me.


CategoryCommandLineInterface