A Safe Environment for Multiple Users
Unix systems have multiple users – and a permissions system that lets each user share or protect their files.
This unique system has some odd twists. For example, did you know that, to rename or remove a file, you need write permission for the directory that the file is in?
Users and Groups
In Unix, every user has a username (like zoe) and a corresponding user ID number (or UID) like 1324. Every user also belongs to one or more groups, where each group also has its own name and ID number (the GID). You can run the id command to see your own user and group information:
uid=1324(zoe) gid=1324(zoe) groups=1324(zoe),111(staff)
Every file and directory has a user owner and a group owner, as well as a set of permissions that dictates what access is allowed for the file’s user, group, and others. Use pwd to check your location, and ls –dl to get information about the directory itself:
drwxr-x–x 5 zoe zoe 4096 Nov 2 10:33
A quick review of ls
The first character on each ls -l output line shows the file’s type. Here, d is a directory file. This file’s user owner is zoe, and its group owner is the group named zoe.
The next characters are the types of access allowed for the user owner (here, rwx), for members of the group (r-x), and for all others.
The meaning of the rwx permissions for files is simple: r permits reading from a file, w lets you modify it, and x lets you execute it (as a program). However, how rwx applies to directories isn’t so obvious.
Read (r) access to a directory lets you list its contents using ls or with a GUI file browser.
A directory is a special type of file that contains (among other things) the names of files that are stored “in” the directory. So, being able to read a directory file lets you see the names stored in it.
Writing to directories
In the same way, write (w) access to a directory lets you modify the directory’s contents – to change the names of the files stored in that directory.
To add, remove, or rename a file, you need write permission on the directory that contains the file’s name. If a directory is write-protected, the list of entries in that directory cannot be changed – accidentally or on purpose.
Directory x permission
Execute (x) permission on a directory lets you access entries in that directory. Even if you have read permission on a directory (which lets you see what’s in it), you can’t use any of its entries unless you also have x permission.
For example, even if an individual file’s access permissions allow you to read and write to a file, you still can’t read or write the file unless you have execute permission on its directory.
In fact, you can’t access a directory unless you also have execute permission on all of its parent directories, all the way up to the root directory! Similarly, without execute permission on a directory, you can’t browse its subdirectories.
But you don’t need read (r) permission on a directory to access an entry in it if you know the entry’s exact name.
Catch-22: Graphical Interfaces
Graphical applications may not handle Unix permissions very well. Because they usually show dialogs with icons for the files in a directory, they have to be able to read the directory. So, if users try to reach zoe’s xfotos subdirectory by clicking through /home to /home/zoe, they’ll get some sort of error on her home directory because the GUI app can’t read it.
Can’t get it write
Some applications – graphical and otherwise – also aren’t sophisticated about write permission: they assume that, if they can read a directory, they also can write to it. Writes can fail in strange ways because, although a particular file in a directory may be writable, the directory itself isn’t.
Bypassing the unreadable
GUI file-open dialogs will generally let you type (or paste) an absolute pathname (like /home/zoe/xfotos) into their “location” box.
This lets you bypass unreadable intermediate directories.
Unix permissions let groups of users share files – even modify or remove other users’ files – if they’re given permission. Directory and file access permissions are often set to allow general file sharing, so let’s see a specialized example.
Let’s say that Zoe’s home directory is on a networked filesystem shared between all computers in her office. She could tell her friends to point their photo viewers at her directory, ~zoe/xfotos.
The shell expands ~zoe to the absolute pathname of zoe’s home directory; Zoe herself can use just ~.
Just Enough Slack
Her permissions give everyone just enough access to read the photos, but not enough access to add, delete, or modify files:
ls -dl ~/ ~/xfotos
drwxr-x–x zoe zoe…/home/zoe
drwxr-xr-x zoe zoe…/home/zoe/xfotos
ls -l ~/xfotos
-rw-r–r– zoe zoe … alex.jpg
-rw-r–r– zoe zoe … boss.jpg
This example shows one of the strengths of a Unix filesystem: it’s easy to share when you want to. Zoe didn’t need to fill friends’ mailboxes with individual copies of her photos, or configure the office Web server so her friends (but no one else) could see those files. Instead, she simply “opened” her directory and her files just enough to let people read them.
An easy way to keep your private files private is to make specific directories in your home directory with owner-only access. For instance, make a directory named personal and type:
chmod 700 personal
to give yourself all (rwx) permissions, but no access to members of your group or to others. All files and subdirectories under personal – no matter what their permissions – are protected from everyone except the system superuser.
Give your private directories a less obvious name than personal or private, which could be a red flag for crackers and others who want to get into your account somehow.
Default Permissions: umask
If you’re concerned about security but also need to share files, check the permissions of every file – including “hidden” files like .bashrc – before you start sharing.
You should also set the correct umask. You’ll recall from the previous unit that the umask defines the default permissions of new files and directories. The umask is a bit mask that specifies which permissions to deny when creating a file. You can see the current umask setting by typing umask at a shell prompt. To set it, use umask nnn, where nnn is the new umask.
Recall the output of id at the start of this presentation. zoe belongs to two groups: zoe and staff. Unix groups can have many members, and each user can belong to many groups.
For instance, all system administrators and staff might belong to the staff group. They have access to private, group-only directories and files that all non-members (non-staff users) can’t access. In the same way, zoe’s manager and the office manager might be members of the zoe group – to have group-mode access to some or all of her files and directories.
Changing group ownership
If you belong to a group (and you always belong to at least one group: yours), you can change the group owner of any file or directory you own with the chgrp command.
For instance, zoe might keep confidential notes on system users in a file named users.xml. She’d use:
chgrp staff users.xml
to set the file’s group owner to staff. Then she’d use:
chmod 750 users.xml
(or chmod u=rw,g=r,o= users. xml) to give herself read and write access, give read access to members of the group staff, and no access to other users. Any staff member can open the file, but other users have no access.
But which group?
If you belong to several groups, which group owns files you create? By default, it’s your primary group – the group listed first in the id output, after gid=. That’s usually not what you want in a directory shared by all users from a particular group.
For example, the directory /projectdir/4staff might have the permissions drwxrwx— so all members of the staff group can create, remove, and rename files in that directory. But if zoe creates a file in that directory with her default group of zoe, other members of the staff group probably can’t read it (unless they’re also members of the zoe group).
Set Group ID
The answer is to set the directory’s setgid bit, like the example below. (This bit is shown by s in the permission string drwxrws—.)
Files (and subdirectories) created in a directory with its setgid bit on will have the same group owner as their directory. So, with the following settings, any file created in /projectdir/4staff will automatically have the group owner staff:
chmod g+s /projectdir/4staff/
ls -ld /projectdir/4staff/
drwxrws— 5 zoe staff /projectdir/4staff/
If you’re the only user of your Unix system, and your filesystems aren’t networked to (or from) other computers, you may wonder why you need to understand permissions. One good reason is to prevent accidents – unintended deletes or changes to your own files and directories. Mistakes happen, so protecting yourself makes sense.
If report.doc is an important file, you can make it unwritable by everyone – including yourself – with:
chmod a-w report.doc
But setting permissions on the file’s contents don’t control whether the file can be removed or replaced!
For instance, if you run gedit report.doc, gedit might rename report.doc to report.doc.bak, then create a new report.doc file. That’s perfectly legal.
To protect against all changes, the file’s directory also needs to be unwritable.
The permissions scheme we’ve seen works on Unix systems, in general, as well as on Linux. Some Unix filesystems – the widely-used ext2 and ext3 types, for instance – also have other file attributes.
The manual pages for lsattr and chattr explain how to list and change file attributes.
Here’s a quick example. The superuser can use chattr to set the a attribute, which makes a file append-only: the file can’t be modified, only added to. Running lsattr shows this attribute, but ls -l doesn’t.
# chattr +a log.txt
$ ls -l log.txt
-rw-rw-r– 1 zoe staff 1168 Oct 30 12:29 log
$ lsattr log.txt
$ cp /var/log/dmesg log.txt
cp: overwrite `log’? y
cp: cannot create regular file `log’: Operation not permitted
$ cat /var/log/dmesg >> log.txt
$ ls -l log.txt
-rw-rw-r– 1 zoe staff 3109 Oct 30 12:33 log.txt