6.3 chmod: Changing a File's Permissions

When you create a file, its initial permissions depend on your umask value (which is discussed later). You can change a file's permissions with the chmod command or the chmod( ) system call. You can change a file's permissions only if you are the file's owner. The one exception to this rule is the superuser: if you are logged in as the superuser, you can change the permissions of any file.[7]

[7] That is, any file that is not mounted using NFS or another distributed filesystem, or that is mounted read-only. See Chapter 15 for details.

In its simplest form, the chmod command lets you specify which of a file's permissions you wish to change. This usage is called symbolic form. The symbolic form of the chmod command[8] has the form:

[8] The Unix kernel actually supports two system calls for changing a file's mode: chmod( ), which changes the mode of a file, and fchmod( ), which changes the mode of a file associated with an open file descriptor.

chmod [-Rfh] [agou][+-=][rwxXstugol] filelist

This command changes the permissions of filelist, which can be either a single file or a group of files. The letters agou specify whose privileges are being modified. You may provide none, one, or more, as shown in Table 6-7.

Table 6-7. Whose privileges are being modified?

Letter

Meaning

a

Modifies privileges for all users

g

Modifies group privileges

o

Modifies others' privileges

u

Modifies the owner's privileges

The symbols specify what is supposed to be done with the privilege. You must type only one symbol, as shown in Table 6-8.

Table 6-8. What to do with privilege

Symbol

Meaning

+

Adds to the current privilege

-

Removes from the current privilege

=

Replaces the current privilege

The last letters specify which privilege will be modified, as shown in Table 6-9.

Table 6-9. Which privileges are being changed?

Letter

Meaning

Options for all versions of Unix

r

Read access

w

Write access

x

Execute access

s

SUID or SGID

t

Sticky bit[9]

Options for BSD-derived versions of Unix only

X

Sets execute only if the file is a directory or already has some other execute bit set

u

Takes permissions from the user permissions

g

Takes permissions from the group permissions

o

Takes permissions from other permissions

Option for System V-derived versions of Unix only

l

Enables mandatory locking on file

[9] The sticky bit is discussed in detail later in this chapter. On most systems, only the superuser can set the sticky bit on a non-directory filesystem entry.

In versions that support it, the -R option causes the chmod command to run recursively. If you specify a directory in filelist, that directory's permissions change, as do all of the files contained in that directory. If the directory contains any subdirectories, the process is repeated.

In versions that support it, the -f option prevents chmod from reporting any errors encountered. This processing is sometimes useful in shell scripts if you don't know whether the filelist exists or if you don't want to generate an error message.

The -h option is specified in some systems to change how chmod works with symbolic links. If the -h option is specified and one of the arguments is a symbolic link, the permissions of the file or directory pointed to by the link are not changed.

The symbolic form of the chmod command is useful if you only want to add or remove a specific privilege from a file. For example, if Sian wanted to give everybody in her group write permission to the file notes, she could issue the command:

% ls -l notes
-rw-r--r-- 1 sian     biochem    4320 Feb  9 13:20 notes
% chmod g+w notes
% ls -l notes
-rw-rw-r-- 1 sian     biochem    4320 Feb  9 13:20 notes
%

To change this file further so people who aren't in her group can't read it, she could use the command:

% chmod o-r notes
% ls -l notes
-rw-rw---- 1 sian     biochem    4320 Feb  9 13:20 notes
%

To change the permissions of the invoice file so nobody else on the system can read or write it, Sian could use the command:

% chmod go= invoice
% ls -l invoice
-rw------- 1 sian     user    4320 Feb  9 13:20 invoice
% date
Sun Feb 10 00:32:55 EST 1991
%

Notice that changing a file's permissions does not change its modification time (although it will alter the inode's ctime).

6.3.1 Setting a File's Permissions

You can also use the chmod command to set a file's permissions, without regard to the settings that existed before the command was executed. This format is called the absolute form of the chmod command. The absolute form of chmod has the syntax:[10]

[10] Note that some versions of Unix support additional flags covering cases of symbolic links in hierarchies and special file types. See your manuals.

% chmod [-Rfh] mode filelist

in which the options have the following meanings:

-R

As described earlier

-f

As described earlier

-h

As described earlier

mode

The mode to which you wish to set the file, expressed as an octal[11] value

[11] Octal means "base 8." Normally, we use base 10, which uses the digits 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9. The octal system uses the digits 0, 1, 2, 3, 4, 5, 6, and 7. If you are confused, don't be. For most purposes, you can pretend that the numbers are in decimal notation and never know the difference.

filelist

The list of the files whose modes you wish to set

To use this form of the chmod command, you must calculate the octal value of the file permissions that you want. The next section describes how to do this.

6.3.1.1 Calculating octal file permissions

chmod allows you to specify a file's permissions with a four-digit octal number. You calculate the number by adding[12] the permissions. Use Table 6-10 to determine the octal number that corresponds to each file permission.

[12] Technically, we are OR-ing the values together, but as there is no carry, it's the same as adding.

Table 6-10. Octal numbers and permissions

Octal number

Permission

4000

Set user ID on execution (SUID)

2000

Set group ID on execution (SGID)

1000

"Sticky bit"

0400

Read by owner

0200

Written by owner

0100

Executed by owner

0040

Read by group

0020

Written by group

0010

Executed by group

0004

Read by other

0002

Written by other

0001

Executed by other

Thus, a file with the permissions "-rwxr-x?-" has a mode of 0750, calculated as follows:

0400

Read by owner

0200

Written by owner

0100

Executed by owner

0040

Read by group

0010

Executed by group

0750

Result

Table 6-11 contains some common file permissions and their uses.

Table 6-11. Common file permissions

Octal number

File

Permission

0755

/bin/ls

Anybody can copy or run the program; the file's owner can modify it.

0711

$HOME

Locks a user's home directory so that no other users on the system can display its contents, but allows other users to access files or subdirectories contained within the directory if they know the names of the files or directories.

0700

$HOME

Locks a user's home directory so that no other users on the system can access its contents, or the contents of any subdirectory.

0600

/usr/mail/$USER and other mailboxes

The user can read or write the contents of the mailbox, but no other users (except the superuser) may access it.

0644

Any file

The file's owner can read or modify the file; everybody else can only read it.

0664

groupfile

The file's owner or anybody in the group can modify the file; everybody else can only read it.

0666

writable

Anybody can read or modify the file.

0444

readable

Anybody can read the file; only the superuser can modify it without changing the permissions.

Table 6-12 contains some common directory permissions and their uses.

Table 6-12. Common directory permissions

Octal number

Directory

Permission

0755

/

Anybody can view the contents of the directory, but only the owner or superuser can make changes.

1777

/tmp

Any user can create a file in the directory, but a user cannot delete another user's files.

0700

$HOME

A user can access the contents of his home directory, but nobody else can.

6.3.1.2 Using octal file permissions

After you have calculated the octal file permission that you want, you can use the chmod command to set the permissions of files you own.

For example, to make all of the C language source files in a directory writable by the owner and readable by everybody else, type the command:

% chmod 644 *.c
% ls -l *.c
-rw-r--r-- 1 kevin     okisrc   28092 Aug  9 9:52 cdrom.c
-rw-r--r-- 1 kevin     okisrc    5496 Aug  9 9:52 cfs_subr.c
-rw-r--r-- 1 kevin     okisrc    5752 Aug  9 9:52 cfs_vfsops.c
-rw-r--r-- 1 kevin     okisrc   11998 Aug  9 9:53 cfs_vnodeops.c
-rw-r--r-- 1 kevin     okisrc    3031 Aug  9 9:53 load_unld.c
-rw-r--r-- 1 kevin     okisrc    1928 Aug  9 9:54 Unix_rw.c
-rw-r--r-- 1 kevin     okisrc     153 Aug  9 9:54 vers.c
%

To change the permissions of a file so it can be read or modified by anybody in the file's group, but can't be read or written by anybody else in the system, type the command:

% chmod 660 memberlist
% ls -l memberlist
-rw-rw---- 1 kevin    okisrc     153 Aug 10 8:32 memberlist
%

6.3.2 Access Control Lists

ACLs are a mechanism for providing fine-grained control over the access to files. Without ACLs, the only way that you can grant permission to a single person or a group of people to access a specific file or directory is to create a group for that person or group of people. With ACLs you can grant the access directly. For example, you can allow four different groups to a read a file without making it world-readable, or allow two users to create files in a directory without putting them in a group together.

Many Unix vendors (most notably IBM and HP) developed their own proprietary ACL implementations in the mid to early 1990s. In the 1990s the POSIX 1.e committee developed a working draft for a standard ACL implementation. Unfortunately, after 13 years of work, the IEEE/PASC/SEC working group formally withdrew the POSIX 1.e draft from the standards process on January 15, 1998. You can read the last draft at http://wt.xpilot.org/publications/posix.1e/.

Despite the decision to withdraw the draft, it continues to serve as a basis for adding ACLs to the Unix operating system. Parts of this implementation were implemented in the Solaris and FreeBSD operating systems. Although ACL support is not yet in the standard Linux kernel, a set of patches for implementing it has been written by Andreas Grünbacher, and is available at http://acl.bestbits.at/.



    Part VI: Appendixes