Control Access to Files

All Linux and Unix systems use file permissions or modes to control access to files. Fedora extends this with the user-private-group scheme, which simplifies the configuration of permissions for collaboration.

Tip

There are two other mechanisms available for file access control: see Lab 8.2, “Using SELinux” and Lab 8.3, “Using Access Control Lists.”

How Do I Do That?

There are three basic file permissions:

read (r)

Grants permission to access the contents of a file. There are no restrictions on what can be done with the file contents, so read permission includes permission to view or process the contents of the file, as well as permission to copy the file. On a directory, read permission enables the display of the list of files in the directory; without read permission, you can access a file contained in the directory only if you know the exact name of the file.

write (w)

Grants permission to write to a file; this includes overwriting existing information, append to the end of the file, and truncate (shorten) the file. On a directory, write permission enables the creation and deletion of files within that directory.

execute (x)

Grants permission to execute the file. If the file is a binary, it can be executed by the kernel; if it is a text file, it is treated as a script. On a directory, execute permission grants access to the contents of the directory (some people refer to execute permission on a directory as search, or passthrough, permission).

Remember the order: r w x.

Each of these three permissions is granted or denied to users in three different communities:

user (u)

The user who owns the file. Initially, this is the user who created the file; it may be changed by the superuser ( root).

group (g)

All members of the group that owns the file. Normally, this starts off as the group of the user who created the file. A file’s owner may change the group ownership to any group to which she belongs; e.g., if Jane owns the file foo and is a member of the audit and toronto groups, she can make either group own the file.

other (o)

Everyone else.

The order is significant here, too; you’ll want to memorize it: u g o.

This gives a total of nine permissions for each file and directory:

  • read, write, and execute for the user

  • read, write, and execute for the group

  • read, write, and execute for other

There are also three special file permissions, as outlined in Table 4-13.

Table 4-13. Special file permissions

NameAbbreviationAppearance in ls -l outputMeaning when applied to a fileMeaning when applied to a directory
Set-User-ID SUID s in the x column for the user if execute permission is enabled, or S if execute permission is disabled.When executed, the program takes on the user identity of the file’s owner.(No meaning)
Set-Group-ID SGID s in the x column for the group if execute permission is enabled, or S if execute permission is disabled.When executed, the program takes on the group identity of the file’s group.All files and subdirectories created in the directory will be owned by the same group that owns the directory. Subdirectories will automatically have their SGID permission enabled.
Sticky bitSticky t in the x column for other if execute permission is enabled, or T if execute permission is disabled.(No meaning)Files in the directory can be deleted or removed only by their owner (otherwise, anyone with write permission on the directory can delete or rename files in that directory).

The SUID and SGID permissions provide critical abilities. For example, /etc/passwd and /etc/shadow are only writable by root, but normal users need to be able to change their passwords. The program /usr/bin/passwd is owned by root and has the SUID permission enabled, so it runs with root privilege—regardless of who executes it—and is therefore able to change /etc/shadow.

Viewing the current user, group, and mode from the command line

When ls is executed with the -l option, a long and detailed listing of file information is displayed. Here is an example:

$ ls -l /etc/aliases.db
-rw-r-----   1 root    smmsp    12288 Oct  6 19:31 aliases.db

The first field displayed is -rw-r-----. The first character is reserved for file type information, and the rest of that field contains the file’s mode: rw-r-----.

This mode breaks down into three sets of three characters, representing the permissions granted to each of the three communities:

  • user: rw-

  • group: r--

  • other: ---

Notice that these communities are displayed in the u g o order mentioned earlier.

The three characters displayed for each of these communities represent read, write, and execute permission; if the permission is denied, a dash is shown, but if the permission is granted, the letter r, w, or x is shown, in that order (r w x).

In the preceding example, the permissions granted to the user are read and write (rw-); the permission granted to the group is read (r--); and no permission is granted to other users (---).

In order to correctly interpret the permission, we need to know who the user and group are. The ls -l output shows this information in fields 3 and 4; in this case, the user is root and the group is smmsp.

Putting this all together, we know that:

  • root can read and write the file.

  • All users in the smmsp group can read the file.

  • No one else on the system can read, write, or execute the file.

Warning

The permissions on the directories that contain the file also come into play when determining what a user can do with a file. If he does not have execute permission on all of the directories in the path from the root (/) to the file, then he will not be able to access the file, regardless of the permissions on the file itself. Likewise, if he has execute permission on all of those directories, plus write permission on the directory containing the file, then he can delete the file (destroying all the data), even if he can’t write to it—and then create a new file with the same name.

Viewing the current user, group, and mode graphically

GNOME’s Nautilus file manager normally displays files and directories as icons. To change the display to a list resembling the output of ls -l, select the menu option View→View as List. The default display shows the file name, size, type, and date modified.

You can add the permissions, owner, and group to the display by selecting Edit→Preferences, which presents the File Management Preferences window shown in Figure 4-11. Click on the List Columns tab, and then click on the checkboxes for permissions, owner, and group to include them on the display. You can also use the Move Up and Move Down buttons to change the displayed order of the fields. Click Close when the display is configured to your liking.

Nautilus File Management Preferences window

Figure 4-11. Nautilus File Management Preferences window

KDE’s Konqueror application provides a similar display when you select View→View Mode→Detailed List View.

Changing permissions graphically

Right-clicking on a file in Nautilus or Konqueror will bring up the file Properties window shown in Figure 4-12. The Permissions tab within that window contains checkboxes for each of the three permissions in each of the three communities—nine checkboxes total, plus three for the special permissions (to view the checkboxes in Konqueror, use the Advanced Permissions button).

Nautilus File Properties window

Figure 4-12. Nautilus File Properties window

To change the permissions, simply toggle checkmarks in the appropriate boxes using your mouse. When you’re done, click Close.

Changing permissions from the command line

The chmod (change-mode) command is used to change permissions from a shell prompt. The permissions can be specified using either of two different syntaxes: relative symbolic notation or octal notation.

Relative symbolic notation uses any combination of the three community letters (u, g, or o) or the letter a to indicate all three communities; an operation symbol, which is + to add a permission and - to remove it, or = to exactly set a permission; and finally, one or more permission letters (r, w, or x). Table 4-14 shows some examples of relative symbolic notation; note that multiple operations can be specified using commas as separators (no spaces).

Table 4-14. Relative symbolic notation used by chmod

NotationDescription
u+w
Adds write permission for the user.
o-rwx
Removes read, write, and execute permission for others.
ug+r,o-r
Adds read permission for the user and the group; removes read permission for others.
a-x
ugo-x
Removes execute permission for all users.
u=rw,go=r
Sets exactly read and write permission for the user, and only read permission for group and others. The difference between = and + is that = will disable other permissions (such as execute for the user in this example), while + will leave other permissions at their previous value.

Special permissions are specified based on their appearance in ls -l output:

  • SUID is specified as u+s.

  • SGUID is specified as g+s.

  • Sticky is specified as o+t.

Octal notation uses a multidigit number, where each digit represents one community (in u g o order). The digit is the sum of values representing each enabled permission:

  • 4 for read permission

  • 2 for write permission

  • 1 for execute permission

Therefore, the octal permission 764 represents read/write/execute for the user (4+2+1=7), read/write for the group (4+2=6), and read for others (4): rwxrw-r--.

When using octal notation, special permissions are given as a fourth digit placed in front of the others; the value of this fourth digit is the sum of 4 for SUID, 2 for SGID, and 1 for Sticky. Octal permission 2770 represents rwxrws---.

To change a permission with chmod, specify the permission as the first argument and one or more filenames as the remaining arguments:

$ ls -l 
                  
                     oreilly
                  
-rw-rw-r--  1 chris chris 40 Oct 12 17:18 oreilly
$ chmod 
                  
                     g-w,o= oreilly
                  
$ ls -l 
                  
                     oreilly
                  
-rw-r-----  1 chris chris 40 Oct 12 17:18 oreilly
$ chmod 
                  
                     764 oreilly
                  
$ ls -l 
                  
                     oreilly
                  
-rwxrw-r--  1 chris chris 40 Oct 12 17:18 oreilly

The -R option causes chmod to recursively process subdirectories. To remove write permission for others on all files and subdirectories within your home directory, execute:

$ chmod -R o-w ~

Using group permissions

Users can belong to more than one group, which enables documents to be shared according to group roles.

Previously, we used Richard in group examples; he’s a member of the groups richard, it, toronto, acmeproposal, christmas, soccer, and audit. Richard’s primary group is richard, as that is the group listed in his entry in /etc/passwd. When Richard logs in, the shell starts with its group identity set to the primary group, so any new files or directories created have richard as the group owner.

The group identity can be changed at any time using the newgrp command, and verified with the id command:

richard$ id
uid=503(richard) gid=503(richard) groups=503(richard),504(audit),505(soccer), 506(toronto),511(acmeproposal),512(christmas),608(it)
richard$ newgrp 
                  
                     audit
                  
richard$ id
uid=503(richard) gid=504(audit) groups=503(richard),504(audit),505(soccer), 506(toronto),511(acmeproposal),512(christmas),608(it)

The current group identity (also called real group ID) affects only the creation of files and directories; existing files and directories keep their existing group, and a user can access files accessible to any group to which she belongs.

In this case, Richard can access any file that is readable by, say, the acmeproposal group, even when his current real group ID is audit. However, any files he creates will be owned by the group audit and won’t be accessible to the acmeproposal group.

chgrp modifies the group ownership of an existing file. The group name is given as the first argument, and all other arguments are filenames:

$ ls -l 
                  
                     report.txt
                  
-rw-r--r--  1 richard richard 3078 Oct 12 19:35 report.txt
$ chgrp 
                  
                     audit report.txt
                  
$ ls -l 
                  
                     report.txt
                  
-rw-r--r--  1 richard audit 3078 Oct 12 19:35 report.txt

A normal user can set the group ownership only to one of the groups to which he belongs, and can change the group ownership only of files that he owns. The root user can set the group ownership of any file to any group. Like chmod, chgrp accepts the -R (recursive) option.

Using chgrp and newgrp is cumbersome. A much better solution is to use the SGID permission on directories, which automatically sets the group ownership.

Richard could create a directory named game_scores in his home directory, change the group ownership to soccer, and change the permission to rwxrws---:

richard$ mkdir 
                  
                     game_scores
                  
richard$ chgrp 
                  
                     soccer game_scores
                  
richard$ chmod 
                  
                     u=rwx,g=rwxs,o= game_scores
                  
richard$ ls -ld 
                  
                     game_scores
                  
drwxrws---  2 richard soccer 4096 Oct 12 19:46 game_scores

Everyone in the soccer group can access that directory. Because the SGID permission is set, any file created in that directory is automatically owned by the group soccer and can be accessed by other group members—exactly what is needed for collaboration within a group. The SGID permission is automatically applied to any directory created within games_scores, too.

Default permissions

When a Fedora program asks the Linux kernel to create a new file or directory, that program requests a default set of permissions. OpenOffice.org, for example, requests mode 0666 (rw-rw-rw-) on new files, because it knows that they aren’t executable; the C compiler, on the other hand, requests 0777 (rwxrwxrwx) because the output of the C compiler should be an executable program.

This requested permission is limited by the current umask, which is an octal value representing the permissions that should not be granted to new files. If you want to prohibit anyone in your group from writing to or executing your files, and prevent others from doing anything at all with your files, the permissions that you want to restrict are ----wxrwx. In octal, that translates to 037.

You can set the umask with the shell command of the same name:

$ umask 
                  
                     037
                  

umask by itself displays the current mask value:

$ umask
0037

This value is inherited by child processes, including all applications started by the shell.

The actual permissions set on a new file will be the permissions requested by the application after the permissions restricted by the umask are removed:

OpenOffice.org requested permission:    rw-rw-rw-
Permissions restricted by umask:        ----wxrwx
Permission applied to a new file:       rw-r-----

The normal umask on Fedora systems is 002, which gives full read and write permission to everyone in your group. This works well in group-collaboration directories that have SGID permission set; other group members will be able to edit the files you have created, and vice versa. The beauty of the Fedora user-private-group system is that when you’re not in a collaboration directory, new files default to ownership by your private group. This makes group permissions moot, since they apply only to you and are therefore effectively the same as the user permissions.

Changing file ownership

The superuser can change the ownership of a file using the chown command:

# chown 
                  
                     accountfile barbara
                  

This is useful when moving files between user accounts (for example, when an employee has left a company).

How Does It Work?

A file’s user, group, and mode information is stored in a file’s inode—a small disk-based data structure containing vital information about a file. The user and group are stored as 32-bit numbers, which means that the maximum GID and UID are both 4,294,967,295 (232 – 1). However, some older applications still use 16-bit GID and UID values, so it’s best to use IDs under 65,532 (216 – 4)—plenty for most systems. IDs under 500 are reserved for system services; this is really just a convention adopted to avoid conflicts, since there is nothing special about user IDs with low numbers.

There is something special about user ID 0, though: it’s reserved for the superuser, root. It is possible to create multiple accounts with the same ID, and this is sometimes used to create a second superuser account with a different password from the root account.

Each process also has a data structure that stores its real UID and GID, the effective UID and GID (which are different from the real IDs when a SUID or SGID program is running), and the umask. This data is copied to child processes automatically, but if the child process is a bash or csh shell, the umask value is reset by the shell startup scripts (/etc/bashrc or /etc/csh.cshrc).

What About...

...viewing file permissions and ownership in the icon view of Nautilus?

You can configure the icon view of Nautilus by selecting Edit→Preferences and going to the Display tab. Up to three fields can be configured, in addition to the filename; by default, the first field is blank, the second field is the file size, and the third field is the date modified. Normally, only the first field is shown beneath each icon, but zooming in and out (using the menu options View→Zoom In and View→Zoom Out) will adjust the amount of information displayed.

This feature is not available in Konqueror.

...changing the group of a file graphically?

The permissions tab of the file properties window in both Nautilus (Figure 4-12) and Konqueror has a drop-down menu that permits you to change the group ownership if you are a member of multiple groups and you own the file.

...deleting someone else’s file in /tmp?

/tmp is a special directory used to store temporary files ( /var/tmp is another). Since this directory is shared among all users, the sticky bit has been set to prevent users from deleting one other’s files.

...changing a file’s owner and group at the same time?

The chown command permits you to specify a group after the username, separated by a colon. To make /tmp/input owned by the user barbara and the group smilies, use:

# chown 
                  
                     barbara:smilies /tmp/input
                  

Where Can I Find More Information?

Get Fedora Linux now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.