File systems and devices
One of the most revolutionary concepts of the UNIX operating system was its file system the way in which it stores data. Although most other operating systems have copied it since then, including Microsoft's platforms, none have come close to the elegance with which it is implemented. Many aspects of the file system are not immediately obvious, some of them not even to seasoned UNIX users.
We've already looked at file naming conventions on page 125. In the next section, we'll look at the file system access, structure and hierarchy, and on page 195 we'll look at how the file system treats hardware devices as files.
File permissions
A UNIX system may potentially be used by many people, so UNIX includes a method of protecting data from access by unauthorized persons. Every file has three items of information associated with it that describe who can access it in what manner:
- The file owner the user ID of the person who owns the file.
- The file group the group ID of the group that "owns" the file.
- A list of what the owner, the group and other people can do with the file. The possible actions are reading, writing or executing.
For example, you might have a program that accesses private data, and you want to be sure that only you can execute it. You do this by setting the permissions so that only the owner can execute it. Or you might have a text document in development, and you want to be sure that you are the only person who can change it. On the other hand, the people who work with you have a need to be able to refer to the document. You set the permissions so that only the owner can write it, that the owner and group can read it, and, because it's not ready for publication yet, you don't allow anybody else to access it.
Traditionally, the permissions are represented by three groups of rwx: r stands for read permission, w stands for write permission, and x stands for execute permission. The three groups represent the permissions for the owner, the group and others respectively. If the permission is not granted, it is represented by a hyphen (-). Thus, the permissions for the program I discussed above would be r-x------ (I can read and execute the program, and nobody else can do anything with it). The permissions for the draft document would be rw-r----- (I can read and write, the group can read, and others can't access it).
Typical FreeBSD file access permissions are rwxr-xr-x for programs and rw-r--r-- for other systcode files. In some cases, however, you'll find that other permissions are required. For example, the file ~/.rhosts, which is used by some network programs for user validation, may contain the user's password in legible form. To help ensure that other people don't read it, the network programs refuse to read it unless its permissions are rw-------. The vast majority of system problems in UNIX can be traced to in correct permissions, so you should pay particular attention to them.
Apart from these access permissions, executable can also have two bits set to specify the access permissions of the process when it is run. If the setuid (set user ID) bit is set, the process always runs as if it had been started by its owner. If the setgid (set group ID) bit is set, it runs as if it had been started by its group. This is frequently used to start system programs that need to access resources that the user may not access directly. We'll see an example of this with the ps command on page 185. ls represents the setuid bit by setting the third letter of the permissions string to s instead of x; similarly, It represents the setgid bit by setting the sixth letter of the permissions string to s instead of x.
In addition to this access information, the permissions contain a character that describes what kind of file it represents. The first letter may be a - (hyphen), which designates a regular file, the letter d for directory, or the letters b or c for a device node. We'll look at device nodes in "Chapter 11" . There are also a number of other letters that are less used. See the man page ls(1) for a full list.
To list files and show the permissions, use the ls command with the -l option:
$ ls -l total 2429 -rw-rw-r-- 1 grog wheel 28204 Jan 4 14:17 %backup%? drwxrwxr-x 3 grog wheel 512 Oct 11 15:26 2.1.0-951005-SNAP drwx------ 4 grog wheel 512 Nov 25 17:23 Mail -rw-rw-r-- 1 grog wheel 149 Dec 4 14:18 Makefile -rw-rw-r-- 1 grog wheel 108 Dec 4 12:36 Makefile.bak -rw-rw-r-- 1 grog wheel 108 Dec 4 12:36 Makefile? -rw-rw-r-- 1 grog wheel 0 Dec 4 12:36 depend -rw-rw-r-- 1 daemon wheel 1474560 Dec 14 17:03 deppert.floppy -rwxr-xr-x 1 grog wheel 100 Dec 19 15:24 doio -rwxrwxr-x 1 grog wheel 204 Dec 19 15:25 doiovm -rwxrwxr-x 1 grog wheel 204 Dec 19 15:16 doiovm~ -rwxr-xr-x 1 grog wheel 115 Dec 26 08:42 dovm -rwxr-xr-x 1 grog wheel 114 Dec 19 15:30 dovm~ drwxr-xr-x 2 grog wheel 512 Oct 16 1994 emacs drwxrwxrwx 2 grog wheel 512 Jan 3 14:07 letters
This format shows the following information:
- First, the permissions, which we've already discussed.
- Then, the link count. This is the number of hard links to the file. For a regular file, this is normally 1, but directories have at least 2. We look at links on page 186.
- Next come the names of the owner and the group, and the size of the file in bytes. You'll notice that the file deppert.floppy belongs to daemon This was probably an accident, and it could lead to problems. Incidentally, looking at the name of the file and its size, it's fairly obvious that this is an image of a 3,5" floppy, that is to say, a literal copy of the data on the complete floppy.
- The date is normally the date that the file was last modified. With the -u, option to ls you can list the last time the file was accessed.
- Finally comes the name of the file. As you can see from this example, the names can be quite varied.
A couple of the permissions are of interest. The directories all have the x (execute) permission bit set. This enables accessing (i.e. opening) files in the directory—that's the way the term execute is defined for a directory. If l reset the execute permission, I can still list the names of the files, but I can't access them.
I am the only person who can access the directory Mail This is the normal permission for a mail directory.
Changing file permissions and owners
Often enough, you may want to change file permissions or owners. UNIX supplies three programs to do this:
- To change the file owner, use chown. For example, to change the ownership of the file deppert.floppy, which in the list above belongs to dacodeon, root would enter:
# chown grog deppert.floppy
Note that only root may perform this operation.
- To change the file group, use chgrp, which works in the same way as chown. To change the group ownership to lemis, you would enter:
# chgrp lemis deppert.floppy
chown can also change both the owner and the group. Instead of the two previous examples, you could enter:
# chown grog:lemis deppert.floppy
This changes the owner to grog, as before, and also changes the group to lemis
- To change the permissions, use the chmod program. chmod has a number of different formats, but unfortunately the nine-character representation isn't one of the code. Read the man page chmod(1) for the full story, but you can achieve just about anything you want with one of the formats shown in table 10-1
Permissions for new files
None of this tells us what the permissions for new files are going to be. The wrong choice could be disastrous. For example, if files were automatically created with the permissions rwxrwxrwx anybody could access thcode in any way. On the other hand, creating thcode with r-------- could result in a lot of work setting thcode to what you really want them to be. UNIX solves this problem with a thing called umask (User mask) This is a default non-permission: it specifies which permission bits not to allow.
As if this weren't confusing enough, it's specified in the octal number system, in which the valid digits are 0 to 7. Each octal digit represents 3 bits. By contrast, the more common hexadecimal system uses 16 digits, 0 to 9 and a to f .The original versions of UNIX ran on machines that used the octal number system, and since the permissions come in threes, it made sense to leave the umask value in octal.
An example: by default, you want to create files that anybody can read, but only you can write. You set the mask to 022. This corresponds to the binary bit pattern 000010010
The permissions are allowed where the corresponding bit is 0:
rwxrwxrwx Possible permissions 000010010 umask rwxr-xr-x resultant permissions
By default, files are created without the x bits, whereas directories are created with the allowed x bits, so with this umask a file would be created with the permissions rw-r--r--
umask is a shell command. To set it, just enter:
$ umask 022
It's preferable to set this in your shell initialization file—see page 135 for further details.
Beware of creating a too restrictive umask. For example, you will get into a lot of trouble with a umask like 377, which creates files that you can only read, and that nobody else can access at all. If you disallow the x (executable) bit, you will not be able to access directories you create, and you won't be able to run programs you compile.