Establishing Access Rights

Some special security considerations arise from the ability of different processes to share a logical file. The use of a shared logical file can override the file access privileges of some processes. The use of a shared logical file can make a physical file available to processes that would otherwise not have been able to access it. A shared logical file can also prevent a process from using a physical file that it would normally have had access to. You can control the effects of the shared logical file through careful program design.

Before reading the following discussion, you should be familiar with the concepts introduced in Establishing Process Identity and Privileges.

The access rights allowed for a logical file are determined at file-open time. Once the logical file is opened, all the processes that share the logical file have equal access rights to the physical file. This is true even if the processes have different usercodes, accesscodes, names, and security statuses.

When a process attempts to open a file, the system examines the physical file to determine the access rights that can be granted to the logical file. The system evaluates these rights according to one of the following two rules:

  • Actor rule

    File access rights are based on the security status and task attributes of the process that opens the file.

  • Declarer rule

    File access rights are based on the security status and task attributes of the process that declares the file.

    The actor rule was formerly the only method used for file security checking. The declarer rule was introduced to provide an alternative that gives more predictable behavior. By default, the declarer rule is now used to determine file access rights.

You can override the default method of file access by assigning the FILEACCESSRULE task attribute of the process that opens the file. The default value of DECLARER results in file access rights being based on the declarer rule. A value of ACTOR causes file access rights to be based strictly on the actor rule. The value of ACTOR can be assigned only by a privileged process.

The following subsections give examples of how the actor and declarer rules apply to file access through libraries and file access restricted by guard files.

Example: Nonprivileged Library Program

Suppose there is a SHAREDBYALL library program. The library object code file is nonprivileged and has a SECURITYTYPE of PUBLIC. An instance of the library is running under a privileged usercode called U1. This library declares a file with usercode U2. The library also exports procedures that can be used to open, close, read from, and write to the file. It happens that a physical file with the specified title already exists and has a SECURITYTYPE of PRIVATE. There are also a number of user processes, including one called A that has usercode U3 and runs with nonprivileged status, and another user process B that has usercode U4 and runs with privileged status.

Under the actor rule, if the library process attempts to open the file before freezing, then the file open operation is successful and all user processes are able to access the file by way of the exported procedures. The file open operation succeeds because the library runs under a privileged usercode and therefore has the right to access a private file stored under a different usercode.

On the other hand, if the library process freezes before it opens the file, and user process A enters a library procedure that opens the file, then the file open operation fails. This is because user process A is nonprivileged and, therefore, does not have the right to access private files stored under different usercodes. However, if user process B enters the library procedure that opens the file, the file open operation succeeds. Once the file is open, all user processes, including user process A, are able to access the file by way of library procedures.

Under the declarer rule, the file open operation will be successful regardless of whether the library process opens the file directly or exports a procedure to a user process that opens the file. In either case, file access is evaluated based on the declaring process, which is the library. The library, because it is privileged, has the ability to access a file stored under a different usercode.

Example: Privileged Transparent Library Program

The concept of privileged transparent status was introduced under “Transparent Object Code File Privileges” in Establishing Process Identity and Privileges. For library procedures that open files, the effects of privileged transparent status vary, depending on whether the file to be opened is globally declared, locally declared, or passed as a parameter. The following ALGOL library, named FILELIB, illustrates these three possibilities.

100 $ SHARING = SHAREDBYALL
110 BEGIN
120 FILE GLOBALFILE;
130
140 PROCEDURE GLOBAL_OPEN;
150   OPEN(GLOBALFILE);
160
170 PROCEDURE LOCAL_OPEN;
180 BEGIN
190   FILE LOCALFILE;
200   OPEN(LOCALFILE);
210 END;
220
230 PROCEDURE USER_OPEN(PASSEDFILE);
240   FILE PASSEDFILE;
250 BEGIN
260   OPEN(PASSEDFILE);
270 END;
280
290 EXPORT GLOBAL_OPEN, LOCAL_OPEN, USER_OPEN;
300 FREEZE(PERMANENT);
310 END.

FILELIB is a permanent, SHAREDBYALL library. The object code file is marked with privileged transparent status. FILELIB exports three procedures: GLOBAL_OPEN, which opens a file declared globally in the library; LOCAL_OPEN, which declares and opens a file; and USER_OPEN, which opens a file received as a parameter from the user process.

FILELIB is used by the following user program, called USERPROC.

100 BEGIN
110 FILE USERFILE;
120 LIBRARY L(LIBACCESS=BYTITLE,TITLE=“OBJECT/TEST/ALGOL/LIB.”);
130
140 PROCEDURE GLOBAL_OPEN;
150   LIBRARY L;
160
170 PROCEDURE LOCAL_OPEN;
180   LIBRARY L;
190
200 PROCEDURE USER_OPEN(PASSEDFILE);
210   FILE PASSEDFILE;
220   LIBRARY L;
230
240 GLOBAL_OPEN;
250 LOCAL_OPEN;
260 USER_OPEN(USERFILE);
270 END.

USERPROC invokes all of the library procedures: GLOBAL_OPEN, LOCAL_OPEN, and USER_OPEN.

Suppose that USERPROC runs with a FILEACCESSRULE value of ACTOR. If USERPROC is privileged, then it succeeds in opening all three files: LOCALFILE, GLOBALFILE, and PASSEDFILE. If USERPROC is nonprivileged, then the procedures might or might not succeed in opening the files. The success of each file open operation depends on the TITLE and SECURITYTYPE attributes of the file.

Suppose instead that the user process USERPROC has a FILEACCESSRULE value of DECLARER. In this case, USERPROC has different file access rights with regard to PASSEDFILE than it does with regard to GLOBALFILE and LOCALFILE. The rules are as follows:

  • Because PASSEDFILE is ultimately declared by USERPROC, the security status of USERPROC determines whether it has the right to open PASSEDFILE. If USERPROC runs under a privileged usercode, the file open operation is executed with privileged status. Similarly, if the object code file for USERPROC is privileged, the library procedures inherit this status because they are privileged transparent.

  • Because GLOBALFILE and LOCALFILE are declared in the library program, the rights to open these files are determined solely by the security status of the library process. Even if the object code file of USERPROC is privileged, the privileges inherited by GLOBAL_OPEN and LOCAL_OPEN do not extend to files declared in the library program. This behavior is a special exception to the rule that privileged transparent procedures inherit the privileged status of the code that invokes them.

There is a good reason for this strict treatment of files declared in privileged transparent libraries. The file access rights for a file declared in a library are permanently established at file-open time. Thus, a privileged user process opening a file in a shared library can have the effect of granting file access to other, nonprivileged user processes. The behavior under the default declarer rule prevents this file access from being granted accidentally.

You can overcome this restriction by assigning a FILEACCESSRULE value of ACTOR to the privileged user process that opens the file.

Example: Parent and Task Accessing a Guarded File

Suppose that a process with a NAME task attribute value of (SMITH)PROC1 declares a file titled (SMITH)FILEA ON DISK. The process (SMITH)PROC1 initiates a second process with a NAME of (SMITH)PROC2 and passes the file as a call-by-reference parameter. Both of these processes are nonprivileged. Suppose, further, that (SMITH)FILEA ON DISK has a SECURITYTYPE of CONTROLLED and a guard file that allows only processes named (SMITH)PROC1 to access this file.

Under the actor rule, if (SMITH)PROC1 opens the file, then both (SMITH)PROC1 and (SMITH)PROC2 are granted access to the file. However, if (SMITH)PROC2 attempts to open the file before (SMITH)PROC1 opens it, the file open operation fails. The process (SMITH)PROC2 cannot use the file until it has been opened by (SMITH)PROC1.

Under the declarer rule, both processes are granted access to the file, regardless of which one opens the file first. This is because (SMITH)PROC1, which declares the file, is allowed access rights by the guard file.