This chapter does not cover the individual UNIX commands but focuses on communicating the fundamental concepts. The UNIX commands associated with the topics of this chapter, and in many cases the topics themselves, are described in greater detail in subsequent chapters. In many ways this chapter is designed to be an "executive summary" of the inner workings of UNIX, with an emphasis on issues related to security.
The goal of this chapter is to characterize UNIX as simply a set of processes that operates on files, and to familiarize you with the general attributes of processes and files. It describes the relationships that exist between processes (for example, "parent" and "child" processes) and the various ways processes are initiated under UNIX.
All information permanently stored in UNIX is stored in the form of files on a disk. Computer files contain a wide variety of information. Some files may be simple word processing documents that users are editing at a terminal. Other files may be programs that the computer can run. Still others may contain information about the computer's configuration, and are used internally by the operating system. When a program is executed under UNIX it is loaded from the appropriate disk file into memory, where it runs.
Because UNIX is a complex, multiuser system, files also contain certain standard information that enables user access to files to be controlled. Each file has an owner and a group, and each file has read, write, and execute permissions stored for the owner, the group, and everyone else.
In UNIX, file systems are devices that can store files. Most often a file system is a partition of a hard disk. When a file system is created, a data block is allocated for each file that can possibly exist on the device. (Needless to say, there can be thousands and tens of thousands of these blocks on a single disk partition.) This data block is called an inode, and among other things it contains the ID of the owner of the file, the user group assigned to the file, and file access permissions. The inode also contains information indicating the type of file to which it refers. In UNIX, files may be regular files, directories, device files, or symbolic links. Regular files contain stored information that is read and written by processes on the system. Directories are special files that assign filenames to inode numbers. Device files contain instructions for opening, closing, reading, and writing to system devices such as tape drives and disk partitions. Symbolic links are files that contain the names of other files or directories, and when they are accessed for input/output (I/O) they redirect the access to the named file.
All the normal UNIX commands interact with directories. Directories are most easily thought of as tables that map filenames to inode numbers. (See Figure 1.1.) By referencing directories, you can refer to files with names, rather than being forced to remember and specify inode numbers.
Filenames actually contain three distinct sections: the directory, the body of the filename, and the filename extensions. You might have a file named todo.lis in your directory. (The directory is much like a directory under DOS--it's simply a logical "place" where you can keep files.) In this case the filename is todo and the extension is lis. UNIX filenames are separated from extensions with the . character. A file may have several extensions separated by the . character or it may have no extension at all. The following are valid UNIX filenames:
todo todo.lis todo.lis.new
Some file extensions are recognized universally; for example, the .c extension indicates that a file contains the source code to a C program (C is a common language resident on virtually all UNIX systems). You may, however, assign file extensions to the files you create as you see fit. It is very common to see file extensions of three characters; for example, files with the extension .txt may contain general text information, .doc files may contain documents, and .tmp files may contain temporary information that is subject to deletion at any time. File extensions are not limited to just 3 characters. Generally filenames should be limited to 14 characters, because filenames that agree up to the first 14 characters are taken to be identical by some UNIX facilities.
The following are common file extension that you may encounter on UNIX systems:
If the thousands or tens of thousands of files on a typical UNIX system could not somehow be segregated into groups of related files and be viewed and treated as groups, UNIX would certainly be an unwieldy working environment. Fortunately UNIX supports the notion of separate directories in which files may be stored, managed, and manipulated. In fact, directories can and often do contain their own subdirectories, which may then contain subdirectories of their own, nested to virtually any level. Such a directory arrangement is often termed the "inverted tree" structure, because a graphic diagram of directory relationships shows innumerable directories spreading out from one main "root" directory, much like the trunk and branches extending from the root system of a tree. If you are comfortable with the inverted tree directory organization of DOS, you've got a good picture of the organization of files under UNIX. The primary difference in the organization of the typical UNIX directory structure is the large number of directories that tend to come into existence on a multitasking, multiuser system. Figure 1.2 shows a portion of a typical UNIX directory structure.
If files are contained in directories, to specify a file you must specify not only the name of the file but the directory path to get to the file. UNIX directories in a directory path are separated by the / character, with a / character at the beginning of the filename indicating the highest-level (or root) directory. For example, suppose the file usernames.txt is located in a directory russell, which is itself contained in the higher-level directory users. The full name of this file, then, would be /users/russell/usernames.txt. Of course it would be cumbersome to specify a full path each time you wanted to work with any file on the system, and the UNIX shells (the programs that interact with the user to process user commands) provide a number of shortcuts that greatly reduce the need for you to specify file paths when referencing files and directories from the UNIX command line. One common example of such a technique is to first use the cd command to move to a particular directory, and then to refer to all files contained in that directory by leaving out the path specification altogether (in such cases it's understood that the path is the current directory).
There are some standard directories that are common to most UNIX systems. Here are some of these common directories:
Each inode tracks how many links have been established to it so that only when all directory entries referencing the inode have been deleted is the actual inode data deleted.
Note that system information about a file is stored as part of the inode data and not within the directory. The directory only associates a name to an inode.
Suppose that your system has recently had a second fixed disk installed, and the original fixed disk is reaching capacity. Of course you could use various methods to copy an entire directory from the old disk to the new disk, but that directory would then be located within a new base directory, and all programs that referenced the old directory would suddenly require adjustments that would cost a significant amount of time (and entail a certain amount of risk, because you may not be aware of all references to the original directory). Symbolic links address this problem. After the new directory has been created and copied on the new file system, the old directory can be deleted and a symbolic link with the name of the old directory can be created to point to the new directory on the new device.
One approach to performing this operation is to use cpio to copy the current directory structure to a new device, and then to delete the entire directory structure and replace it with a symbolic link that points to the new home for the file set. Suppose, for example, that you used this technique to move an installed product (maintained under the directory /usr/product) to the directory /newdir, which is resident on a different disk device. The UNIX command sequence to perform this is the following:
$ cd /usr $ find product -print | cpio -pmd /newdir $ rm -r -f product $ ln -s /newdir/product productLine 2 uses the cpio command (described in Chapter 7, "Backup and Recovery") to copy the product directory to an identical directory under the /newdir directory. The command-line switches -pmd, supplied to the cpio command, tell cpio to copy from one file system to another (-p), to preserve the modification times of files as they were before they were backed up (-m), and to create new directories as needed (-d). Line 3 removes all files and directories in the product subdirectory and below (including the product subdirectory itself). The ln -s command creates a new symbolic link, product, to the newly created /newdir/product directory. Now you've moved an entire directory tree to a new disk, and applications continue to run unaffected.
By their very nature, some devices communicate best with blocks of data and other devices operate better on one character at a time. For example, if a terminal did not communicate one character at a time, you could not see each keystroke echoed to the screen as you type, and you could not produce applications that perform operations based on single-user keystrokes. At the same time, disk drives tend to perform much better when they process blocks of data. For this reason some special device files may operate in character mode and some may operate in block mode.
Under UNIX you will often find multiple device files set up to support a single device on the system, depending on how the device is being utilized. For example, a terminal device file may configure a hardware port for I/O to a terminal as part of the device "open" logic (establish baud rate, parity, and so on), whereas an entirely separate device file may contain open logic that not only initializes the port but assumes that a modem is connected to the port and sends out a modem initialization command. The "close" logic for such a device file might send the command string out to the modem to ensure that the communications connection has been broken.
Another example of multiple device files for a single device is device files used to communicate with a tape drive. One device file may put the tape drive into compressed mode as part of opening the device for output, whereas another might not; or perhaps one command would cause the tape to rewind as part of the open logic, whereas another device file associated with the tape drive might simply begin recording at the current head position on the tape. You will find that virtually all special device files under UNIX appear immediately under the /dev directory or in a subdirectory thereof. You will find that the name of the special device file often reflects the options it implements, as well as whether it operates in character mode or in block mode (consult the vendor's documentation for details, because these conventions vary).
Listing 1.1. A sample UNIX directory listing.
$ls -alFNotice that the first field of each line looks something like drwxrw-rw-. The first character of this field indicates the type of file being listed. A - indicates a regular file (login.sql), a d indicates a directory (cfg), an l indicates a symbolic link (etc -> /usr3/etc), a c indicates a character-mode device file, a b indicates a block- mode device file, and a p indicates a special pipe file sometimes used to store data communications between processes. The remaining nine characters of this field indicate the read, write, and execute permissions granted to the owner, the group, and all others, respectively. (A - indicates that the permission is not allowed.) The second and third fields give the username and group name, respectively (although if the user and group are undefined, the user and group numbers are printed). The remainder of each line indicates the time and date the file was created and the name of the file. Note that the file pointed to by symbolic links is indicated with the -> notation.
lrwxrwx--x 1 root sys 23 Apr 5 14:18 bin -> /usr3/bin drwxrwxrwx 2 root sys 24 Feb 7 14:03 cfg -rw-rw-rw- 1 john adm 530 Dec 17 17:35 cmbu0101.tmpl -rwxr-xr-x 1 john users 33412 Oct 21 13:39 login.sql -rw-rw--" 1 mike users 400 Apr 6 14:26 serial.dat -rw-rw-rw- 1 allen users 27912 Jan 5 17:58 sqlnet.log -rwxr-xr-x 1 john users 918 Aug 3 1993 sscurq03.sql drwxrwxrwx 2 root sys 1024 Apr 6 10:58 com lrwxrwx--x 1 root sys 23 Apr 5 14:19 etc -> /usr3/etc drwxrwxrwx 2 root sys 24 Feb 7 14:03 exp lrwxrwx--x 1 root sys 23 Apr 5 14:19 fil -> /usr3/fil drwxrwxrwx 2 root sys 24 Feb 7 14:03 log drwxrwxrwx 2 root sys 24 Feb 7 14:03 msc crw-r--" 1 root sys 69 0x000000 Jun 22 1993 config crw--w--w- 1 root sys 0 0x000000 Apr 6 16:22 console brw----" 1 root root 7 0x000102 Jun 22 1993 src_device $
As you might suspect, UNIX tracks certain information about each user who has been set up to log in to the system. Critical user information is kept in the file /etc/passwd. This is a normal text file that can be edited, viewed, or printed by anyone with the proper access permissions (generally only the root user has the ability to actually modify this file). UNIX maintains one line per user, each containing several items of user information, separated by the : character. Information kept in this file includes the user's name, the user's password, the user's ID number (internally, UNIX likes to track everything, including users, by number rather than by name), the user's default group ID number, the name of the directory into which the user initially logs in to the system, and the name of the UNIX shell that the user runs when logging in to the system. (As described later in this chapter, the shell is the program that allows the user to execute commands from a system prompt.) Provisions are also made to track other miscellaneous user information. Because this file is often readable by everyone on the system, the password is encrypted. See Listing 1.2 for a depiction of a typical /etc/passwd file.
Listing 1.2. A sample /etc/passwd file.
$cat /etc/passwd root:fRBdpqobjKT1Y:0:3::/:/bin/ksh daemon:*:1:5::/:/bin/ksh bin:*:2:2::/bin:/bin/ksh adm:*:4:4::/usr/adm:/bin/ksh uucp:*:5:3::/usr/spool/uucppublic:/usr/lib/uucp/uucico lp:*:9:7::/usr/spool/lp:/bin/ksh james:i5QiQ1K9pNml6:201:20:John James:/users/james:/bin/ksh rich:cE78tWjuM9ER.:202:20:Richard Styles:/users/rich:/bin/ksh watts:ZETejgJiU:203:20:Tim Watts,x2311:/users/watts:/bin/ksh hanson:1yzkc2tvo:204:20:Mickie Hanson:/users/hanson:/bin/ksh oswald:5uzfMDRwUw:205:20:Donald Oswald:/users/oswald:/bin/ksh $The /etc/passwd file must be made readable for everyone on the system for various common UNIX commands to execute properly. For example, the ls command that produces directory listings reads this file to translate user IDs of files into the corresponding usernames. The su command must be able to find the user ID number based on the name of the user, which also requires /etc/passwd to be readable. Because this file also contains the encrypted passwords for all users, you might correctly suspect that the availability of this file represents a security risk. A persistent password cracker might encrypt a large number of common passwords and compare them to the passwords in /etc/passwd. In fact, there are a few programs that are designed to perform this very act, and they invariably decipher poorly chosen passwords. As of System V, Release 2, this problem has been addressed by placing encrypted passwords in a separate file named /etc/shadow. This file is protected such that it can be accessed only by the root user, or by the login process to verify users" passwords as they log in. Under such systems you generally see the field of the /etc/passwd file that previously contained the encrypted password set to a single placeholder character (such as *).
Listing 1.3 is a listing of a typical /etc/shadow file. The first field in this file is the user's name. The second field is the encrypted password. The third field is the day the password was last changed (stored as the number of days since January 1, 1970). The fourth field is the minimum number of days required to elapse before the password may be changed (to prevent a user from changing a password to a new value and immediately changing it back to the old password to defeat the password-aging protection). The fifth field is the maximum number of days that may elapse before the user is required to change the password. The sixth field is the number of days during which the user will be warned to change the password before the password expires. The seventh field is the number of days of account inactivity allowed before the account is automatically disabled. The eighth field specifies the date when the account may no longer be used (expressed as the number of days since January 1, 1970). The ninth field of the /etc/shadow file is currently unused. Leaving any field of this file empty disables the corresponding security check.
Listing 1.3. A sample listing of the /etc/shadow file.
$cat /etc/shadow root:fRBdpqobjKT1Y:8002:1:30:3:10::: daemon:*:8049::::::: bin:*:8027::::::: adm:*:8030::::::: uucp:*:8012::::::: lp:*:8023:::::: james:i5QiQ1K9pNml6:8023:1:30:3:10:8200: rich:cE78tWjuM9ER.:8017:1:30:3:10:8200: wyatt:ZETejgJiU:8010;1:30:3:10:8200: benson:1yzkc2tvo:8019:1:30:3:10:8200: riswald:5uzfMDRwUw:8015:1:30:3:10:8200:
Listing 1.4. An example of an /etc/group file.
$cat /etc/group root::0:root other::1:root,hpdb bin::2:root,bin sys::3:root,uucp adm::4:root,adm,rbb,rjemgr daemon::5:root,daemon mail::6:root lp::7:root,lp users::20:root,james,rich,watts,hanson,oswald nogroup:*:-2: $
Every file created by a user logged in to UNIX is assigned that user's numeric user and group IDs as the owner and group IDs of the file itself. It is also assigned a default set of access permission flags. These default permissions are generally established as system defaults when the user logs in, but may be changed by the user at any time through execution of the standard UNIX umask command. (See Chapter 5, "User Account Security.")
On virtually all UNIX systems the standard file permission flags form the heart and soul of processing control security. (Keep in mind that access control is used in this book to mean the set of mechanisms put in place to limit who can access the system, and process control is used in this book to mean the set of mechanisms put into place to limit user activity when access has been attained.) Each file has read, write, and execute permissions that are granted separately to the user who created the file, the group under which the file was created, and others. Only the owner of a file can change the file permission flags as well as the user and the group associated with the file.
The three file access permissions, which may be granted or revoked by the owner of the file, are read permission, write permission, and execute permission. Other file attribute flags also associated with UNIX files are covered later. Broadly stated, when a user attempts to perform an operation on a file, the user's user ID and group ID are compared to the ownership and permissions associated with the file, and the operating system either accepts or denies the operation. Because I/O devices are also controlled through device special files, and because directories are also simply a special type of UNIX file, these permission flags can be used to control a user's total access to the system. By appropriately setting the permission flags for a directory, you can protect every file beneath that directory.
Modern security standards defined by the Department of Defense in the manuscript "Department of Defense Trusted Computer System Evaluation Criteria" (known popularly as the "Orange Book") describe security requirements that are more strict than the capabilities provided by the file access permissions described in this chapter. See Appendix E for a full summary of the requirements outlined in the Orange Book. To achieve higher levels of security classification under this standard, major UNIX vendors have augmented the standard UNIX security with the implementation of access control lists (ACLs), which have been utilized successfully in other computing environments.
The mechanics of the standard UNIX file permissions and ACLs, as well as the UNIX commands that manipulate them, are described in detail in Chapter 3.
The init process can be considered the ancestor of all processes that run under UNIX. This is because, directly or indirectly, all processes can trace their roots to a process started by init. When this program (resident in the file /etc/init) runs, it scans a special file on the system, named /etc/inittab. Each line of this file contains the command to be executed, how it is to be handled, and in which run state the command is valid (run states are discussed in greater detail later in this chapter). For example, all the system getty processes (the processes that allow a user to log in over a serial line or via modem) are specified to run in the /etc/inittab file. All processes started by init are run with an owner ID of root. Hence, there are some very significant security considerations associated with the init process. Only the root user should have write permission for the /etc/inittab file, and all processes run directly or indirectly from the inittab file should also be protected. Listing 1.5 shows the contents of a typical inittab file.
Listing 1.5. A sample /etc/inittab file.
$cat /etc/inittab i2:2:initdefault: io:s:sysinit:/etc/ioinit -i >/dev/console 2>&1 br::wait:/etc/rc.single >/dev/console 2>&1 rc:2:wait:/etc/rc </dev/console >/dev/console 2>&1 po::wait:/etc/powerfail >/dev/console 2>&1 co::respawn:/etc/getty console console a0:2:respawn:/etc/getty -h ttyd0p1 2400 $
The second field indicates the run states for which this process is allowed to exist. Valid run states are 0, 1, 2, 3, 4, 5, 6, and s, with state 0 often being reserved by the manufacturer, states 1 and s being single-user states in which only the minimum number of processes required to run the file system are started and logins are often allowed only from the system console, state 2 being the standard multiuser state, and other states being defined to support alternate system configurations. (For example, it's not uncommon to find state 3 defined as the networked multiuser state.) If this second field is left empty, then the process is defined for all run states.
The third field tells UNIX how to handle the action being performed. The following standard contents are recognized for field three of the /etc/inittab file:
In Listing 1.5 the two shell scripts /etc/rc.single and /etc/rc are executed as part of the system initialization process. In this case, /etc/rc.single would execute as part of an init into single-user state and /etc/rc would execute as part of an init into multiuser state. It is not uncommon to find a number of rc files in the /etc directory that are responsible for starting various software subsystems. Sometimes these rc files are referenced in the /etc/inittab file and are run directly by root, and sometimes these files are evoked from a shell program referenced in inittab. These files are all very important from a security perspective because they are all run as root by the init process. Hence, the ownership and file access permissions of these files are critical to UNIX system security.
The UNIX system call kill enables processes to send various types of simple signals to one another. A signal is a message sent to the process to inform it that some external event has taken place. This is just one way processes can communicate with one another in the UNIX environment. A standard UNIX command, kill, is also defined. It provides the user with a means of sending signals to processes from the UNIX command line.
Along with the process ID that is maintained for each running process, the process ID of the parent process (the process that initiated the process) is also maintained by UNIX. Whenever a process terminates it sends a signal to its parent, saying that it has terminated. Another item of information stored for each process is the process group to which it belongs. In the case of some major signals (for example, signals telling a process to terminate unconditionally) the signal is sent to every process in that process's group. In this fashion, the termination of a user's main process (for example, the login session) can cause all associated processes to terminate also. Note that a process group is not related to user groups. A process group is a set of processes associated with a terminal through a common login session.
The internal process table also tracks the UNIX user ID and group ID of the owner of the process. This is extremely important because UNIX uses this information, coupled with the effective owner ID, group ID, and protections of a file, to determine what types of file operations to allow a process to perform on a file. Therefore, one user may execute a program that prints out the contents of a file, while some other user may execute the same program in the same manner, but fail due to file permission restrictions.
As you might guess from this discussion of processes having parent processes, there is a hierarchic relationship for all processes running under UNIX, and ultimately all processes may be tracked back to a common ancestor, the init process.
The analogy of process relationships to family relationships extends beyond the notion that processes have parent and child processes to the inheritance of the process environment. The process environment consists of a set of environment variables, maintained for each process, which provide a means for the user to tailor the behavior of various commands and programs. These environment variables contain text strings that are referenced by commands and programs. A good example of a UNIX environment variable is the HOME environment variable, which always contains the name of the directory that a user logs in to. If a program has been written that always prints the contents of the file userlist in the directory pointed to by the HOME environment variable, the behavior of that program depends on the user executing it. Proper use of UNIX environment variables is critical for programs that need to execute in a variety of contexts, such as on different machines that have unknown directory structures or on a single machine that must maintain multiple runtime environments. A process always gets a copy of its parent's environment, which it is then free to modify and expand in accordance with its own programming. With the Bourne and Korn shells you can utilize the export command to define environment variables. Under the C shell the setenv command serves the same purpose.
The following are some common UNIX environment variables:
Examples of UNIX daemons include the ftp daemon, which allows files to be transferred between UNIX systems; the mail daemon, which routes electronic messages between UNIX systems; the cron process, which runs user programs according to a programmed schedule; the spooling process, which services system printers; database engines, which are continuously monitoring for data requests; and other daemons that are required to support third-party software as well as user-written applications.
Daemon processes, like any other processes, have real and effective user and group IDs, and like any other process they are subject to the user and group ownership and permission access restrictions of UNIX. Because many daemons are started by the init process, or from one of the rc files executed by init, they have a user ID of root, giving them unlimited access to the system. Note, however, that daemons are programmed to provide only a certain group of behaviors, and so are often limited in the impact they may have on the file system.
One getty process is started for each communication port attached to a terminal (or at least for those terminals you wish to make available for login). Additionally, the init process executes the /etc/rc general-purpose startup script, which starts up all network daemons that support logins across the network. getty processes support only physical communication ports and are not used extensively in heavily networked systems, although the getty process is still required for console and modem connections.
After you enter your username and password, the login process encrypts the password and compares it to your encrypted password in the /etc/passwd file (or your /etc/shadow file if C2 security has been established for the system). If the password test succeeds, the system transfers execution to the UNIX shell program specified in the /etc/passwd file and you are deposited in the login directory also specified in the /etc/passwd file. After a successful login, the shell program that is executed on behalf of the user will be owned by the user, with a group ID set to the user's default group ID. Your UNIX shell executes its own initialization sequence before it presents you with a prompt. One major part of this process is executing startup scripts (for the Korn shell, this involves processing the shell script /etc/profile, followed by the .profile script contained in the user's home directory). At this point you may utilize the full capabilities of your shell to do work (subject to the constraints of your user ID with regard to file access permissions established systemwide).
You may generally choose to use one of the common UNIX shells. The full file path to your default shell is specified in your account line in the /etc/passwd file. As the shells begin to execute they generally process one or more startup scripts that define aliases for UNIX commands and establish environment variables for the session. These startup scripts serve much the same purpose as the AUTOEXEC.BAT file that runs when you turn on a PC, in that they perform initialization for a user when a login session is started.
In production environments it is not uncommon to establish users in captive accounts, in which a particular program is run from within the shell's initialization script and the user is logged out after exiting the program. In such situations the user never actually has access to the shell prompt to enter UNIX commands. In other situations, you may wish to tailor the user's environment to a particular specification whenever that user logs in, and you may do so by customizing the login script and setting the ownership and file permission attributes of the script to prohibit unauthorized personnel from modifying or deleting the file.
The most common shell programs in the UNIX world are the Bourne shell (sh), the C shell (csh), the Korn shell (ksh), and the restricted shell (rsh). The original UNIX shell was the Bourne shell. Early on it was recognized that this shell could be improved substantially, and the C shell was developed. This shell added some powerful capabilities to re-execute previously executed commands, as well as some more powerful programming capabilities that resembled those of the C language. Later, the Korn shell was developed. The Korn shell is a superset of the Bourne shell and includes many of the capabilities that had made the C shell desirable. The Korn shell carries the added benefit of being compliant with the generic UNIX standard known as POSIX. Many organizations have since adopted the Korn shell as a standard.
The restricted shell provides the system administrator with the means to provide users with a strictly limited environment. Users cannot execute commands that are not found in their PATH environment variable, users are restricted from changing their PATH environment variable, and no directory other than the user's login directory can appear in any command entered. The ultimate effect of all these restrictions is that the user can execute only those UNIX commands explicitly authorized by the system administrator. This is covered in greater detail in Chapter 5.
The configuration of the shell environment, and the specific security characteristics of the various UNIX shells, is also discussed in detail in Chapter 5.
Program scheduling is a system security issues for several reasons. One reason is that CPU power is an important system resource, and the execution of unexpected programs may drain CPU power during times when it is anticipated to be most available. Another reason is that some programs are interdependent; for example, a database application might be dependent on the database engine daemon being up and running. At the same time a system backup may require a database engine daemon to be down to guarantee data integrity. Additionally, the cron and at commands could provide a disruptive user with a mechanism for setting off a time bomb, which is a destructive program scheduled to run if not stopped before a specific time. Hence, access to UNIX scheduling facilities must be controlled.
The mechanisms for controlling user access to the at and cron commands are detailed in Chapter 4, "Monitoring and Controlling Processes."
Files, directories, and processes are the three fundamental parts of UNIX. Files can be described as collections of related information stored by UNIX as a single, named entity. This chapter covers user and group ownership of files, as well as the read, write, and execute permissions that are assigned to files. It also describes the organization of the UNIX file system into an inverted tree structure of directories that themselves contain subdirectories (which may then contain their own subdirectories, ad infinitum). This chapter covers the distinction between inodes and files, along with the allocation of file attributes at the inode level rather than at the directory level.
Full filenames consist of a directory path, a filename, and an optional extension. In this chapter you have learned about the concept of hard links and symbolic links, and you have seen examples of scenarios in which these mechanisms might be employed.
You have learned about processes and process inheritance, including the function of the init process and the form and function of the /etc/inittab file. You know about system run states, particularly regarding the contents of the /etc/inittab file. You can use the init process to evoke the /etc/rc file to perform system initialization as well as to start getty processes to allow user logins.
You have learned about users and groups, as well as the login process, the /etc/passwd file, and the shadow password file for systems that implement C2 security. You can use UNIX shell programs to interact with the UNIX file system through a command-line interface.
This chapter describes UNIX processes and how they relate to users, groups, and files. You can use cron to schedule processes for periodic execution.