Access control under the Commercial Security Pak has been described in general earlier in this guide. This chapter contains a detailed description of the Discretionary access control mechanisms. The Discretionary Access Control mechanisms are the standard system of file permissions, the use of Access Control Lists on files and directories, and the use of Capability attributes on system executable files.
Discretionary access control is the name of the standard UNIX system of access permissions that allow the user to control access to files, directories, and other system resources.The added feature of Access Control Lists is implemented in the Commercial Security Pack. The owner of any file or other system object can control access to that object, even by those with equal or dominating clearances, by setting the DAC permissions. Further, the user may set an Access Control List (ACL) for any file or directory. ACLs are discussed completely below in the section titled “Access Control Lists (ACLs).”
The Commercial Security Pak allows users to control access to their own files and change that access at will. The only user who can override those access decisions is the Superuser (root). Thus, DAC fills an otherwise unmet need for system security at the personal level.
IRIX divides permissions into three categories, and users into three relationships. The three relationships are the owner of the file, the owner's user group, and all users. If you view a long listing of a directory, you see that the permissions field for each file in the directory looks something like this:
-rwxrwxrwx |
Note that the line of permissions has the string rwx repeated three times. The first instance of rwx applies to the file owner, the next instance applies to the group members, and the third applies to all other users on the system. The example above shows full permissions. A more restricted permission set might look like this:
-rw-r--r--
The three categories of permissions are read, write, and execute. They are denoted as “r” for read, “w” for write, and “x” for execute in long listings of files. To get a long listing, enter:
ls -l |
at your system prompt in any directory. Along with the permission information, the ls -l command lists the owners and the sizes of the files and the date they were last modified.
Read permission allows you to look at the contents of a file. Write permission allows you to make changes to or remove a file. Execute permission allows you to run the file as a command from your shell prompt.
Each character is separately significant in the permissions listing. Starting at the left, the first character is a dash. A dash in any other position means that no permission is granted and the actions associated with that permission are denied. However, in the leftmost place, the contents of that space describes whether the file is a file or a directory. If it is a directory, a “d” appears in that space. Other characters in this place indicate that the file is a pipe, a block or character special device file, or other type of file. See the ls(1) reference page.
Directories use the same permissions as files, but their meanings are slightly different. For example, read permission on a directory means that you can use the ls command to look at the contents of that directory. Write permission allows you to add, change, or remove files in that directory. (However, even though you may have write permission in that directory, you must also have write permission on the individual files to change or remove them, unless you own the directory.) Finally, execute permission on a directory allows you to use the cd command to change directories into that directory.
The first series of three places after the leftmost place in the permissions field describe the permissions for the owner of the file. Here is an example of a long listing for a file:
-rwx------ 1 owner grp 6680 Apr 24 16:26 shell.script |
The file is not a directory, so the leftmost space is blank. The characters rwx indicate that the owner of the file, owner, has read, write, and execute permission on this file. The second series of three spaces describe permissions for the owner's group. In this case, the group is grp. Suppose permissions for this file were slightly different, like this:
-rwxr-x--- 1 owner grp 6680 Apr 24 16:26 shell.script |
In that case, any member of the group grp could read or execute the file, but not change it or remove it. All members of group grp can share a pool of files that are individually owned. Through careful use of group read and write permissions, you can create a set of doc source files that are owned by one person, but any group member can work on them.
The third series of spaces provides for all other users on the system and is called the public permissions. A file that is set to be readable by any user on the system is called publicly readable.
Here is a long listing of a sample Projects directory:
total 410 drw------- 1 owner grp 48879 Mar 29 18:10 critical -rw-r--r-- 1 owner grp 1063 Mar 29 18:10 meeting.notes -rw-rw-rw- 1 owner grp 2780 Mar 29 18:10 new.deal -rwxrwxrwx 1 owner grp 8169 Jun 7 13:41 new.items -rw-rw-rw- 1 owner grp 4989 Mar 29 18:10 response -rw------- 1 owner grp 23885 Mar 29 18:10 project1 -rw-r----- 1 owner grp 3378 Jun 7 13:42 saved_mail -rw-r--r-- 1 owner grp 2570 Mar 29 18:10 schedules -rwxrwxr-x 1 owner grp 6680 Apr 24 16:26 shell.script |
The files in this directory have varying permissions. Some are restricted to the owner, some can be read only by members of the owner's group, and some can be read, changed, or removed by anybody. The shell script is executable by any user.
You change the permissions on a file by means of the chmod(1) command. You can use chmod only to change files that you own. Generally, you use this command to protect files you want to keep secret or private, to protect private directories, and to grant permissions to files that need to be used by others. The command to restrict access to a file or directory to yourself only is this:
chmod 600 filename chmod 700 dirname |
Other permissions may be added by using the chmod command with the letter associated with the permission. For example, the command to add general write permission to a file is this:
chmod +w filename |
For more examples, see the chmod(1) reference page.
You can decide what default permissions your files have by placing the umask command in your .cshrc, .profile, or .login file. There is a default umask setting for the entire system in the /etc/profile and /etc/cshrc files. By changing the setting of your umask, you can alter the default permissions on your files and directories to any available DAC permission. See the umask(1) reference page for more information.
A drawback to the umask command is that it makes every file you create receive the same permissions. For most purposes, you want the files you create to be accessible by the members of your group. For example, if an individual is suddenly called away and another person must take over that person's portion of a project, the source files must be accessible by the new user. However, you might want the personal files you keep in your home directory to be private, and if you set your umask to allow group read and write privileges, any member of the group can access your personal files. But mechanisms are available to prevent this access. For example, you can create a directory of private files and alter the permissions on that directory with the chmod command to restrict all but your own access. Then no other user would be allowed into the directory.
You can also use the IRIX utilities to change all the files in your home directory to your chosen permission automatically at your convenience. You can set up your account so that this action happens to any files or directories you indicate every time you log out. For example, say you have three directories, called personal, letters, and budget. You can set up a .logout file in your home directory with commands to be executed each time you log out from the system. The following commands, placed in the .logout file will prevent access to the three example directories to anyone but you:
chmod 700 budget personal letters chmod 600 budget/* personal/* letters/* |
The umask command is an important part of DAC. It allows you to maintain security and still allow convenient access to your files. To set your account up to allow group read and write privileges and no other privileges, place this line in your .cshrc or .profile file:
umask 006 |
This makes every file you create have the following permissions:
-rw-rw---- |
With your umask set to 006, directories that you create have the following permissions:
drwxrwx--- |
In plainer terms, you and your group will have full use of the file or directory. No other user, except the Superuser (root), will have access to your files.
An ACL works in the same way as standard file permissions, but it allows you to get a finer level of control over who may access the file or directory than standard permissions allow. ACLs allow you to specify file permissions on a user-by-user basis.
Every system file or directory has an Access Control List that governs its discretionary access. This ACL is referred to as the access ACL for the file or directory. In addition, a directory may have an associated ACL that governs the initial access for files and subdirectories created within that directory. This ACL is referred to as a default ACL. A user who wishes to gain access to the files in a directory must be on both ACLs and must be allowed by IRIX file permissions to successfully gain access. If you have not created an access ACL for a file, the default ACL serves both ACL functions.
Hereafter in this section, directories are treated as files, and where the term file is used, consider that it also applies to directories.
An ACL is stored in the same way that standard file permissions are stored; as an attribute of the file or directory. To view the ACL of a file, use the -D option to ls(1) as shown in this example:
ls -D /usr/people/ernie/testfile |
The command above produces output similar to this:
testfile [user::rwx ,user:332:r--,user:ernie:rw-] |
This example shows full permissions for the owner with the first entry on the line, sets read permission for user ID 332 with the second entry, and sets read/write permission for the user account ernie. The specific format of an ACL entry is discussed in the section titled “Long ACL Text Form.”
To set or change an ACL, use the chacl(1) command:
chacl acl_entry[,acl_entry]... |
An ACL consists of a set of ACL entries separated by commas. An ACL entry specifies the access permissions on the associated file for an individual user or a group of users. The order of internal storage of entries within an ACL does not affect the order of evaluation. To read an ACL from an object, a process must have read access to the file.To create or change an ACL, the process must own the file.
ACLs have long and short text forms. The long text form is defined first in order to give a complete specification with no exceptions. The short text form is defined afterwards because it is specified relative to the long text form.
The long text form is used for either input or output of ACLs and is set up as follows:
acl_entry[,acl_entry]... |
Though it is acceptable to place more than one entry on a physical line in a file, placing only one entry per line improves readability.
Each entry contains one ACL statement with three required colon-separated fields and an optional comment:
entry tag type:entry qualifier:discretionary access permissions#comment |
Comments may be included with any entry. If a comment starts at the beginning of a line, then the entire line is interpreted as a comment. The first field must always contain the ACL entry tag type.
One of the following ACL entry tag type keywords must appear in the first field:
user | Access granted to either the file owner or to a specified user account. | |
group | Access granted to either the file owning user group or to a specified user group. | |
other | Access granted to any process that does not match any user, group, or implementation-defined ACL entries. | |
mask | Maximum access that can be granted by any ACL entry except the user entry for the file owner and the other entry. |
The second field contains the ACL entry qualifier (referred to in the remainder of this section as simply qualifier). The following qualifiers are defined by default:
uid | User account name or a user ID number. | |
gid | User group name or a group ID number. | |
empty | No uid or gid information is to be applied to the ACL entry. The entry applies to the file owner only. An empty qualifier is represented by an empty string or by white space. |
The third field contains the discretionary access permissions that are to apply to the user or group specified in the first field. The discretionary access permissions field must contain exactly one each of the following characters in the following order:
r | Read access. | |
w | Write access. | |
x | Execute access. |
Any or all of these may be replaced by the no-access dash(–).
A user entry with an empty qualifier specifies the access granted to the file owner. A user entry with a uid qualifier specifies the access permissions granted to the user name matching the uid value. If the uid value does not match a user name, then the ACL entry specifies the access permissions granted to the user ID matching the uid value.
A group entry with an empty qualifier specifies the access granted to the default user group of the file owner. A group entry with a gid qualifier specifies the access permissions granted to the group name matching the gid value. If the gid value does not match a group name, then the ACL entry specifies the access permissions granted to the group ID matching the gid value. The umask and other entries contain an empty qualifier. A crosshatch (#) starts a comment on an ACL entry. A comment may start at the beginning of a line, or after the required fields and after any custom-defined, colon-separated fields. The end of the line denotes the end of the comment.
If an ACL entry contains permissions that are not also contained in the umask entry, then the output text form for that entry must be displayed as described above followed by a crosshatch (#), the string “effective:“ and the effective file access permissions for that ACL entry.
White space is permitted (but not required) in the entries as follows:
at the start of the line
immediately before and after a colon (:) separator
immediately before the first crosshatch (#) comment character
at any point after the first crosshatch (#) comment character
Comments have no effect on the discretionary access check of the object with which they are associated.
Here is an example of a correct long text form ACL for a file:
user::rwx,user:332:r--,user:ernie:rw- |
The above example sets full permissions for the owner with the first entry on the line, sets read permission for user ID 332 with the second entry, and sets read/write permission for the user account ernie.
Here are some examples with comments:
group:10:rw-# User Group 10 has read/write access other::---# No one else has any permission mask::rw-# The maximum permission except for the owner is read/write |
The short text form is used by the chacl(1) command for input of ACLs, and is set up as follows:
acl_entry[,acl_entry]... |
Though it is acceptable to place more than one entry on a physical line in a file, placing only one entry per line improves readability.
Each command line contains one ACL entry, with the exception that the ACL entry tag type keyword must appear in the first field in either its full unabbreviated form or its single-letter abbreviated form.
The abbreviation for user is u, the abbreviation for group is g.The abbreviation for other is o, and the abbreviation for mask is m.
There are no exceptions for the second field in the short text form for ACLs. The discretionary access permissions must appear in the third field in either absolute symbolic form or relative symbolic form.
The relative symbolic form must be preceded by a plus sign (+) to indicate additional access or a caret (^) to indicate that access is to be removed. The relative symbolic string must be at least one character.
The symbolic string contains at most one each of the following characters in any order:
r
w
x
For example, the short form should look very similar to the following:
u: :rwx # The file owner has complete access u:332:+r # User Acct 332 has read access only g:10:rw- # User Group 10 has read/write access u:653:^w # User Acct 653 (who is in group 10) has read access only o::--- # No one else has any permission m::rw- # The maximum permission except for the owner is read/write |
You can use the output from the ls -D command as the input to chacl. This is convenient for situations where you wish to duplicate a complex custom ACL onto a new file in a directory that does not use the complex ACL as the default.
Consider this example:
ls -dD testdir |
The command given above produces the following output:
testdir [u::rwx,g::r-x,o::--x/u::rwx,g::r-x,o::---] |
Create a new directory (it doesn't matter where) with this command:
mkdir newdir |
Then use the following command to edit and copy the ACL (give this command all on one line):
chacl -b `ls -dD testdir | cut -d"[" -f2 | cut -d"/" -f1``ls -dD testdir | cut -d"[" -f2 | cut -d"/" -f2 | cut -d"]" -f1`newdir |
The ACL from testdir will be replicated in newdir. Note that the cut(1) command is used within the above command line. For complete information on the correct use of cut in any command line, see the cut(1) reference page.
After giving the above command, an ACL listing of newdir shows that the ACL from testdir has been duplicated:
ls -dD newdir newdir [u::rwx,g::r-x,o::--x/u::rwx,g::r-x,o::---] |
Note that the cut and paste functions of the window manager can also be used to duplicate ACL entries from ls -D to chacl.
Capabilities are privileges assigned to specific accounts to allow those accounts to perform operations formerly reserved to the Superuser. To maintain the principle of least privilege, the capabilities of the Superuser account have been subdivided into various capabilities, which can be assigned to separate individual accounts. The corresponding capability is placed on sensitive executable files and programs on your system. The account capability and the executable capability must be compatible for the user to execute the program. For a more technical discussion, see the capabilities(4) reference page.
The fundamental purpose of capabilities is to allow you to perform system administration from standard login accounts without requiring the use of Superuser or other sorts of privileged accounts. A capability may be granted to any user account, and a corresponding capability attached to only those system objects that the owner of the account has a legitimate need to use. This follows the trusted systems principle of least privilege—using the lowest possible promotion of privileges necessary to get the job done. Capabilities implement least privilege both by limiting the number of users privileged to perform various tasks and by limiting the privilege to just that program, or section of code within a program, necessary to perform the proper action.
It is usually inappropriate to grant capabilities to ordinary users of the system. Should you decide to do so, remember the principle of least privilege: A user should have only those capabilities for which a need can be demonstrated and no others.
Capabilities provide fine-grained control over the privileges of a process. A process can be granted specific capabilities to perform privileged system calls, but not be granted general override of the system's protection scheme as is the case with a setuid root program. The IRIX capability mechanism is designed to comply with Draft 15 of the POSIX P1003.1e Draft 15 specification.
The file /etc/capability is the database of capabilities for user accounts. Here is a sample /etc/capability file:
root:all+eip:all+eip auditor:CAP_AUDIT_WRITE,CAP_AUDIT_CONTROL,CAP_KILL+eip ernie:all=:CAP_FOWNER,CAP_SETFCAP+eip casey:all=:all+eip # We trust Casey. jeff:all+eip CAP_NETWORK_MGT-eip:all+eip fred:all=:all= |
Each entry consists of up to three colon-separated fields, as follows:
username : default_capability : maximum_capability |
The username is the user's login name. This must be exactly the same as that found in the /etc/passwd file.
The default capability set is applied at login time to the user's shell process. A user may request additional capabilities at login time. If capabilities not present in this entry are requested at login time, the login attempt will fail.
The maximum capability field describes all those capabilities that may be requested and received by the user's processes.
The default and maximum capability fields are of the following form:
capname,capname operator flags |
The capname element(s) are taken from the list of capabilities supplied in the section titled “Capabilities in This Release.”
The operator can be any one of the following:
+ | Add this capability (or list of capabilities) to the following sets. | |
- | Delete this capability (or list of capabilities) to the following sets. | |
= | Revoke this capability (or list of capabilities) for the duration of this process for the following sets. |
The flags that represent the capability sets are one or more of the following:
i | Inheritable set of capabilities. The inheritable set is the capabilities that can be passed to child processes. | |
e | Effective set of capabilities. The effective set is the capabilities currently active. | |
p | Permitted set of capabilities. The permitted set is the maximum set of capabilities for the process. |
Each field contains a list of clauses. Each clause is a space-separated list of capabilities and an operator/set statement. All characters after # to the end of the entry line are interpreted as comments and are ignored. The clauses are interpreted sequentially, as read (left to right). This means that the last operation specified for a capability within an entry is the one that counts.
Now look at the sample /etc/capability file again:
root:all+eip:all+eip auditor:CAP_AUDIT_WRITE,CAP_AUDIT_CONTROL,CAP_KILL+eip: ernie:all=:CAP_FOWNER,CAP_SETFCAP+eip casey:all=:all+eip # We trust Casey. jeff:all+eip CAP_NETWORK_MGT-eip:all+eip fred:all=:all= |
In this sample file, note the following:
The root account has all capabilities added by default with all flags.
The auditor account has only those capabilities necessary to manage the system audit trail, and the capability to kill processes.
The ernie account has no default capabilities, but if necessary can acquire the capabilities to work on other people's files and set capability requirements for executable files.
The casey account has no default capabilities, but can acquire full capabilities if necessary. There is also a comment to that effect.
The jeff account has a default set of full capabilities, modified by a subsequent clause to delete the network management capability. However, Jeff can request a full capability set if needed.
The fred account has no capabilities, nor can Fred request any.
Every running process has three capability sets: effective, permitted, and inheritable.
The effective set is used in access control decisions for that process.
The inheritable set is used in the calculation of new capability sets during exec(2) processing, when a user invokes an executable file.
The permitted set is the maximum set of capabilities that the process may attain.
Each executable file has the same three capability sets as well. These sets influence the final effective capability set of the new process created when a user invokes the program:
The new effective set is the intersection of the permitted set of the parent process and the executable file's effective set. That is, if the executable file's effective set of capabilities includes a capability that is within the permitted set of the calling process, but not within that process' effective set, the capability will be added to the child process' effective set.
The new inheritable capability set is the intersection of the inheritable capabilities of the calling process and the inheritable capability set of the executable file. That is, only those capabilities that are inheritable by the executable file and are designated inheritable by the parent process will be inheritable in the new process.
The new permitted capability set is the union of the executable file's permitted set and the intersection of the new inheritable set and the parent process' permitted set. That is, all permitted capabilities of both the file and the parent process are permitted so long as each capability is inheritable by both the parent process and the executable file.
The effective capability set of the parent process does not influence any of the new sets, and the executable file's inheritable set defines an upper bound on the capabilities available to the new process.
The following capabilities are shipped in this distribution:
ALL | Indicates all capabilities. | |
CAP_ACCT_MGT |
| |
CAP_AUDIT_CONTROL |
| |
CAP_AUDIT_WRITE |
| |
CAP_CHOWN | Privilege to change the owner of a file not owned by the process and with the system configured for _POSIX_CHOWN_RESTRICTED on changing file ownership. | |
CAP_CHROOT |
| |
CAP_DAC_EXECUTE |
| |
CAP_DAC_READ_SEARCH |
| |
CAP_DAC_WRITE |
| |
CAP_DEVICE_MGT |
| |
CAP_FOWNER |
| |
CAP_FSETID | Privilege to set the setuid or setgid bits of a file without being the owner. Also, the privilege to change the owner of a file with setuid or setgid bits set. This capability overrides the following restrictions:
| |
CAP_KILL | Privilege to send a kill(1M) signal to another process not owned by the sender. Also, privilege to use process synchronization calls (procblk) to a process. | |
CAP_MEMORY_MGT |
| |
CAP_MKNOD | This is an alias for CAP_DEVICE_MGT. | |
CAP_MOUNT_MGT |
| |
CAP_NETWORK_MGT |
| |
CAP_NVRAM_MGT |
| |
CAP_PRIV_PORT |
| |
CAP_PROC_MGT |
| |
CAP_QUOTA_MGT |
| |
CAP_SCHED_MGT |
| |
CAP_SETFCAP |
| |
CAP_SETFPRIV |
| |
CAP_SETGID | Privilege to change the real, effective, and saved GID of the process. Also the privilege to change the process group ID. | |
CAP_SETPCAP | This is an alias for CAP_SETPPRIV. | |
CAP_SETPPRIV |
| |
CAP_SETUID | Privilege to change the real, effective, and saved UID of the process. | |
CAP_SHUTDOWN |
| |
CAP_STREAMS_MGT |
| |
CAP_SWAP_MGT |
| |
CAP_SYSINFO_MGT |
| |
CAP_TIME_MGT |
|
Capabilities on a file are only meaningful for executable files on XFS format file systems. Capability requirements on files can be set by the Site Security Officer with the chcap(1M) command. The syntax is as follows:
chcap CAP, CAP, CAP file |
For example, suppose you want to set capabilities to match those associated with the Auditor account:
auditor:CAP_AUDIT_WRITE,CAP_AUDIT_CONTROL,CAP_KILL+eip |
Use this command:
chcap CAP_AUDIT_WRITE,CAP_AUDIT_CONTROL,CAP_KILL+eip file |
To list the capability requirements of a file or directory, use this command:
ls -P
The -P flag stands for “Privilege.” Note that you must have the appropriate capabilities to read the file in order to read the capabilities of the file.
You can create unique capabilities at your site. Simply add the capability tag you want (it must be unique) to your /etc/capability file on the line for the user or users who are to have the capability, then use the chcap(1) command to add the capability to the files you desire.
If you believe you have experienced corruption of some capability requirements on files or directories , you can use the attrinit(1) command to restore those capability requirements.
The /etc/irixcap file is used with the attrinit command as follows:
Log in as root and change directories to the root (/) directory. Next, give this command:
attrinit -script=/etc/irixcap |
Your capability integrity will be restored. The process may take a few moments.