Section 11.1. The File Mode

   


11.1. The File Mode

Every file on a system has a file type (such as unnamed pipe or character device), as well as a set of access permissions that define what processes may access that file. A file's type and access permissions are combined in a 16-bit value (a C short) called the file mode.

The bottom 12 bits of a file's mode represent the access permissions that govern access to the file, as well as file permission modifiers. The file permission modifiers serve a variety of functions. The most important functions are allowing the effective user and group IDs to change when the file is executed.

The file mode is usually written in up to six octal (base 8) digits. When represented in octal, the low-order three digits are the access bits, the next digit contains the file permission modifiers, and the high-order two digits indicate the file type. For example, a file whose mode is 0041777 has a file type of 04, a file permission modifier of 1, and access bits 0777.[7] Similarly, a file of mode 0100755 is of type 010, has no file permission modifiers set, and has access permissions of 0755.

[7] This is the mode usually used for the /tmp directory.

11.1.1. File Access Permissions

Each of the three access digits represents the permissions for a different class of users. The first digit represents the permissions for the file's owner, the second digit represents permissions for users in the file's group, and the final digit represents the permissions for all other users. Each octal digit is made up of three bits, which represent read permission, write permission, and execute permission, from most significant to least significant bit. The term world permissions is commonly used to refer to the permission given to all three classes of users.

Let's try to make the previous paragraph a little more concrete through some examples. Linux's chmod command allows the user to specify an access mode in octal and then applies that mode to one or more files. If we have a file, somefile, which we would like to allow only the owner to write to but any user (including the owner) to read from, we would use mode 0644 (remember, this is in octal). The leading 6 is 110 in binary, which indicates that the type of user to which it refers (in this case, the owner) is given both read and write permission; the 4s are 010 binary, giving the other types of users (group and other) only read permissions.

 $ chmod 0644 somefile $ ls -l somefile -rw-r--r--   1 ewt       devel       31 Feb 15 15:12 somefile 


If we wanted to allow any member of group devel to write to the file, we would use mode 0664 instead.

 $ chmod 0664 somefile $ ls -l somefile -rw-rw-r--   1 ewt      devel       31 Feb 15 15:12 somefile 


If somefile is a shell script (programs that use #! at their beginning to specify a command interpreter) we want to execute, we must tell the system that the file is executable by turning on the execute bit in this case, we are allowing the owner to read, write, and execute the file and members of group devel to read and execute the file. Other users may not manipulate the file in any way.

 $ chmod 0750 somefile $ ls -l somefile -rwxr-x---   1 ewt      devel       31 Feb 15 15:12 somefile 


Directories use the same set of access bits as normal files, but with slightly different semantics. Read permissions allow a process to access the directory itself, which lets a user list the contents of a directory. Write permissions allow a process to create new files in the directory and delete existing ones. The execute bit does not translate as well, however (what does it mean to execute a directory?). It allows a process to search a directory, which means it can access a file in that directory, as long as it knows the name of that file.

Most system directories on Linux machines have 0755 permissions and are owned by the root user. This lets all users on the system list the files in a directory and access those files by name, but restricts writing in that directory to the root user. Anonymous ftp sites that allow any person to submit files but do not want to let people download them until an administrator has looked at the contents of the files, normally set their incoming file directories to 0772. That allows all users to create new files in the directory without being allowed either to see the contents of the directory or access files in it.

More information on file access permissions may be found in any introductory Linux or Unix book [Sobell, 2002] [Welsh, 1996].

11.1.2. File Permission Modifiers

The file permission modifier digit is also a bitmask, whose values represent setuid, setgid, and the sticky bit. If the setuid bit is set for an executable file, the process's effective user ID is set to the owner of the file when the program is executed (see page 111 for information on why this is useful). The setgid bit behaves the same way, but sets the effective group ID to the file's group. The setuid bit has no meaning for files that are not executable, but if the setgid bit is set for a nonexecutable file, any locking done on the file is mandatory rather than advisory.[8] Under Linux, the setuid and setgid bits are ignored for shell scripts because setuid scripts tend to be insecure.

[8] See Chapter 13 for more information on file locking.

Neither setuid nor setgid bits have any obvious meaning for directories. The setuid bit actually has no semantics when it is set on a directory. If a directory's setgid bit is set, all new files created in that directory are owned by the same group that owns the directory itself. This makes it easier to use directories for collaborative work among users.

The sticky bit, the least significant bit in the file permission modifier digit, has an interesting history behind its name. Older Unix implementations had to load an entire program into memory before they could begin executing it. This meant big programs had long startup times, which could get quite annoying. If a program had the sticky bit set, the operating system would attempt to leave the program "stuck" in memory for as long as possible, even when the program was not running, reducing the startup time for those programs. Although this was a bit of a kludge, it worked reasonably well for commonly used programs, such as the C compiler. Modern Unix implementations, including Linux, use demand loading to run programs that load the program piece by piece, making the sticky bit unnecessary, and so Linux ignores the sticky bit for regular files.

The sticky bit is still used for directories. Usually, any user with write permissions to a directory can erase any file in that directory. If a directory's sticky bit is set, however, files may be removed only by the user who owns the file and the root user. This behavior is handy for directories that are repositories for files created by a wide variety of users, such as /tmp.

The final section of a file's mode specifies the file's type. It is contained in the high-order octal digits of the mode and is not a bitmask. Instead, the value of those digits equates to a specific file type (04 indicates a directory; 06 indicates a block device). A file's type is set when the file is created. It can never be changed except by removing the file.

The include file <sys/stat.h> provides symbolic constants for all of the access bits, which can make code more readable. Both Linux and Unix users usually become comfortable with the octal representation of file modes, however, so it is common for programs to use the octal values directly. Table 11.1 lists the symbolic names used for both file access permissions and file permission modifiers.

Table 11.1. File Permission Constants

Name

Value

Description

S_ISUID

0004000

The program is setuid.

S_ISGID

0002000

The program is setgid.

S_ISVTX

0001000

The sticky bit.

S_IRWXU

00700

The file's owner has read, write, and execute permissions.

S_IRUSR

00400

The file's owner has read permission.

S_IWUSR

00200

The file's owner has write permission.

S_IXUSR

00100

The file's owner has execute permission.

S_IRWXG

00070

The file's group has read, write, and execute permissions.

S_IRGRP

00040

The file's group has read permission.

S_IWGRP

00020

The file's group has write permission.

S_IXGRP

00010

The file's group has execute permission.

S_IRWXO

00007

Other users have read, write, and execute permissions.

S_IROTH

00004

Other users have read permission.

S_IWOTH

00002

Other users have write permission.

S_IXOTH

00001

Other users have execute permission.


11.1.3. File Types

The upper four bits of a file mode specify the file's type. Table 11.2 lists the constants that relate to the file's type. Bitwise AND'ing any of these constants with a file's mode yields non-0 if the bit is set.

Table 11.2. File Type Constants

Name

Value (Octal)

Description

S_IFMT

00170000

This value, bitwise ANDed with the mode, gives the file type (which equals one of the other S_IF values).

S_IFSOCK

0140000

The file is a socket.

S_IFLNK

0120000

The file is a symbolic link.

S_IFREG

0100000

The file is a regular file.

S_IFBLK

0060000

The file represents a block device.

S_IFDIR

0040000

The file is a directory.

S_IFCHR

0020000

The file represents a character device.

S_IFIFO

0010000

The file represents a first-in/first-out communications pipe.


The following macros take a file mode as an argument and return true or false:

S_ISLNK(m)

True if the file is a symbolic link

S_ISREG(m)

True if the file is a regular file

S_ISDIR(m)

True if the file is a directory

S_ISCHR(m)

True if the file represents a character device

S_ISBLK(m)

True if the file represents a block device

S_ISFIFO(m)

True if the file is a first-in/first-out pipe

S_ISSOCK(m)

True if the file is a socket


11.1.4. The Process's umask

The permissions given to newly created files depend on both a system's setup and an individual user's preferences. To relieve individual programs of the need to guess the permissions to use for a file, the system allows users to turn off particular permissions for newly created files (and directories, which are just special files). Every process has a umask, which specifies the permission bits to turn off when files are created. This allows a process to specify fairly liberal permissions (usually, world read and write permissions) and end up with the permissions the user would like. If the file is particularly sensitive, the creating process can specify more restrictive permissions than normal, because the umask never results in less restrictive permissions, only in more restrictive permissions.

The process's current umask is set by the umask() system call.

 #include <sys/stat.h> int umask(int newmask); 


The old umask is returned, and the process's umask is set to the new value. Only read, write, and execute permissions may be specified for the file you cannot use the umask to prevent the setuid, setgid, or sticky bits from being set. The umask command present in most shells allows the user to set the umask for the shell itself and its subsequent child processes.

As an example, the touch command creates new files with 0666 (world read and write) permissions. Because the user rarely wants this, he could force the touch command to turn off world and group write permissions for a file with a umask of 022, as shown by this example:

 $ umask 022 $ touch foo $ ls -l foo -rw-r--r--   1 ewt     ewt        0 Feb 24 21:24 foo 


If he prefers group write permissions, he can use a umask of 002 instead.

 $ umask 002 $ touch foo2 $ ls -l foo2 -rw-rw-r--   1 ewt     ewt        0 Feb 24 21:24 foo2 


If he wants all his files to be accessible only by himself, a 077 umask will accomplish the task.

 $ umask 077 $ touch foo3 $ ls -l foo3 -rw-------   1 ewt     ewt         0 Feb 24 21:26 foo3 


The process's umask affects the open(), creat(), mknod(), and mkdir() system calls.


       
    top
     


    Linux Application Development
    Linux Application Development (paperback) (2nd Edition)
    ISBN: 0321563220
    EAN: 2147483647
    Year: 2003
    Pages: 168

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net