J. SYSTEMS SOFTWARE 1990; 13:3-12
An Access Control Language Programming Systems Masaaki
Mizuno
Department
of Computing
Arthur Department
and Information
3
for Object-oriented
Sciences, Kansas State University, Manhattan,
Kansas
E. Oldehoeft of Computer Science, Iowa State University, Ames, Iowa
An extended access control language and implementation mechanism is specified for use in the protection of modules (or objects) in object-oriented programming systems. Described within the context of a “resource module” as the standard programming construct, the language may be readily adapted for use in other object-oriented systems and is designed for ease of use by a normal programmer. The protection, afforded to program modules, captures the advantages of access control lists, provides the power of “least privilege” found in capability based systems, and allows for extended control on individual subjects through the use of access rights expressions.
‘I. INTRODUCTION
The modular approach to the design of computer systems has been the subject of considerable attention in the study of programming languages, operating systems, and computer architecture. As a result, attributes such as encapsulation and data abstraction, synchronization of concurrent access, protection, and reliability have emerged as fundamental characteristics to be enforced by modularization. The system we are designing is a highly structured, highly concurrent, object-oriented programming system in a distributed network environment-its usefulness is in the construction of operating systems and user application programs. While our overall objectives are similar to those of other researchers [l-3], our work is unique in several respects. The goals of our system are to realize
Address correspondence to Prof. Masaaki Mizuno, Department of Computing and Information Sciences, Kansas State University, Manhattan, KS 66506. 0 Elsevier Science Publishing CO., Inc. 655 Avenue of the Americas, New York, NY 10010
1. total encapsulation of data (along with operations on the data). 2. resource sharing with powerful mechanisms for enforcing synchronization of access and protection. of protection, synchroniza3. separate specification tion, and access in order to facilitate programming and proofs of correctness. 4. high software reusability. The fundamental building block for constructing a network object is a “Resource Module (RM)” [4], which is in complete charge of its own protection, synchronization, and resource access. By integrating into a single programming system numerous principles of software design, the system can provide an effective easy-to-use facility for building network software systems. The initial focus of our attention has been on the specification and implementation of protection. In order to share resources in the system effectively, two types of protection are significant: access control and information flow control [5-71. Access control specifies authorization for access to objects based on the identity of subjects. Information flow control regulates the flow of classified information between objects. An information flow control mechanism designed for object-oriented systems is described in Mizuno [8] and Mizuno and Oldehoeft [9]. The focus of attention in this article is on the design and implementation of access control in object-oriented systems. Our goal is to develop a mechanism that (1) captures the advantages of two common implementations of access control: capabilities and access control lists; and (2) enforces constraints on the sequence of operations that may be performed by an individual subject. The body of this article consists of three sections.
0164-1212190/$3.50
4
J. SYSTEMS SOFTWARE 1990; 13:3-12
M. Mizuno and A. E. Oldehoeft
Section 2 gives a brief overview of the RM system in order to provide a programming context for the discussion. The concepts in subsequent sections, however, are general and may be implemented in many other object-oriented implementations. Section 3 briefly describes the advantages and disadvantages of capabilities and access control lists. This discussion motivates the method developed to enforce access control in the RM system. Section 4 presents an access control mechanism that combines the concepts of access control lists and access rights expressions. This allows the enforcement of protocols for operation usage by individual subjects. By using a fine-grained identification of subjects, this method realizes the principle of least privilege as provided by capability systems. The resulting power is illustrated by several examples. 2. OVERVIEW
OF THE RM SOFTWARE
Structure
I resource value
MODEL
This section presents an overview of an RM and illustrates how it can be used to construct software. An RM is an encapsulated, self-protected, and self-synchronized unit of computation in a distributed environment. Data abstraction and encapsulation are the fundamental facilities offered by a module. The concept of a class, along with related ideas, has been used by other researchers [lo], and a similar approach is adopted in the RM system. A “class” describes the implementation of a set of RMs, all of which have the same interface and synchronization specifications and the same set of procedures. Individual RMs, described by a class, are called “instances” of a class. As illustrated in Figure 1, an RM is internally constructed from three components: protection, synchronization and access. Each of the three components is separately specified and encapsulated within the module, and the three may be implemented as concurrent communicating processes. RMs can communicate with each other by calling exported procedures or by replying to such a call. 2.1 Internal
: synchronization state
of a Module
Access component. This component may encapsulate the state values for data or devices along with operations on the values, or it may provide the facility for defining an executable program. More precisely, the access component contains 1. a resource state (called state variables) that is local to the RM. 2. program bodies of exported procedures and local procedures within the RM. 3. an initialization procedure that is executed when the RM is first instantiated.
Figure 1. Internal structure of a resource module.
The invocation of an exported procedure or the initialization procedure results in the creation of an independent active entity (in the access component) called a process. Synchronous communication occurs when a process in the access component in one RM invokes an exported procedure in another RM. The calling process is suspended awaiting a reply. Synchronization component. As a result of procedure calls made to an RM, numerous processes may be executing concurrently in the access component. The synchronization component controls the initiation of new processes and manages any necessary blocking and resumption of those processes that communicate with processes in other RMs. The synchronization language is an extension of open path expressions [ll] and allows for the specification of integrity constraints at the procedure level. The language is described more fully in Oldehoeft and Mizuno [4]. Protection component. In order to construct a system for secure resource sharing, powerful protection mechanisms are needed at the base language level for (1) parameter type checking, (2) information flow control, and (3) access control. In our model, the protection component deals with all three types of protection on incoming messages.
2.2 Flow of Messages
Within
a Module
The intermodule and intramodule tlow can be described in the following manner. A message, arriving from some external module, is first processed by the protec-
Object-oriented Systems
J. SYSTEMS 1990;
tion component of the receiving module. If the message is to invoke a procedure exported by this module, it is checked for the correct designation of the class of the receiver, a valid exported procedure name, and acceptable parameter types. Then access control is checked, and the information flows caused by this invocation are verified. If the specified protection is violated, the message is rejected; otherwise the protection component records the message identifier (which is generated by the calling module when the invocation was initiated) and forwards the message to the synchronization component. The synchronization component, based on the integrity specification of an extended path expression, may temporarily delay the message. When the integrity specifications are satisfied, the message is forwarded to the access component, and the access component initiates a new process to execute the procedure. If the message to the module is a return from an exported procedure in another previously invoked module, the message identifier is validated, and type checking and information flow certification of the return values are performed in the protection component. If no error is detected, the message is forwarded to the synchronization component. The synchronization component updates the synchronization state and forwards the message to the access component. The access component resumes the process that is blocked awaiting the reply. A procedure in the access component may either call a procedure in another module, or reply to a calling module (after a termination of a procedure). The resulting message is forwarded to the synchronization component, which records the corresponding suspension or possible termination of the calling procedure. The message is then forwarded to the protection component, which 1. generates a message identifier (for validating the reply from the called module) if it is a request for an external procedure invocation in another module. 2. finds the corresponding message identifier if it is a reply message.
teldir
5
SOFTWARE
13:3-12
= class
epeciflcation
=
LOOKUP(IN protection
: string,OUT number : integer); : string, number : integer);
name
ENTER(IN
name =
(accaa
: LOOKUP : ENTER
control specification)
(acceas control ape&cation) synchronization path *ccew
1
=
: ({LOOKUP},
ENTER)
end
=
type entry = record
: string; : integer;
uname telao end state directory
: array [l..lOO] of entry;
: O..lOO;
numJlune8
procedure
LOOKUP(IN
: integer;
var ptr
: string; : boolean;
name
found
OUT
number
: integer);
begin ptr := 1; found := false; while
(ptr <=
numaames)
if directoryIptr].uname then
and not found do
= name
found := true
else ptr := ptr + 1; if found then
number := directory[ptr].telmo
else number := 0; end procedure
)
ENTER(
initialize begin nummames
:= 0;
end end teldir
Figure 2. A program for a telephone directory.
array of directory entries with components for names and telephone numbers. The two operations on this resource are specified as procedures LOOKUP and ENTER (code left unspecified). Since LOOKUP is a read-type operation and ENTER is a write-type operation, the synchronization of concurrent operations is specified as a readers-writers open path expression. The path expression specifies that, at any point in time, either a single ENTER procedure or a composite set of overlapping LOOKUP procedures may be executing.
3. GENERAL REVIEW OF ACCESS CONTROL
The protection component also certifies the information flow through the corresponding parameters or return values. Finally, the message is forwarded to the underlying communication system for delivery to the destination module.
This section reviews the general topic of access control along with two common methods of implementation: access control lists and capabilities. This discussion motivates the access control mechanism used in the RM system.
2.3 A Program Example
3.1 Access
Figure 2 shows a module class definition for the construction of a telephone directory. The shared resource value is implemented in the access component as an
Access control regulates the authorization of access to objects based on the identity of subjects. The access matrix model was developed as a framework for de-
Matrix
Model
6
J. SYSTEMS 1990;
M. Mizuno and A. E. Oldehoeft
SOFTWARE
13:3-12
scribing protection systems [ 12, 131. The defined in terms of a triple (S, 0, A) where
model
is
1. S is a set of subjects that are active entities that access objects. 2. 0 is a set of objects to which access must be controlled. 3. A is an access matrix in which rows correspond to subjects and columns correspond to objects, where an entry A[s,o] stores the access rights of subject s to object o.
ACL approach Rlel (Sl. U?WE)). 63. (REN We2 : (sl, (RI). (S2. (RWN dlrl : (s1.6)). W 6))
:
Capobllit’+ approach Sl (fllel, (flle2. (RD. (dlrl, 6)) S2 : (flle2.(rw) 53 : (fllel ,(RE)). (dir1 , (9)
:
WWE)).
~::=g$l$t E : execute d@t S : search rtght
Figure 3. Access matrix and corresponding ACL and capability representations.
1. S is a set of subjects, which may be users. 2. 0 is a set of modules in the system. 3. A is an access matrix in which entry A[s,o] lists those exported procedures of module o that subject s is authorized to invoke.
reference monitor [5]. Conceptually, in order to implement access control mechanisms, the reference monitor needs to refer to the access matrix. Direct realization of the access matrix as a two-dimensional structure is impractical because of the sparseness of the matrix. Instead, the access matrix is retained in either a rowbased or column-based representation in real implementations. Two types of implementations are commonly used: capabilities and access control lists (ACLs). In a capability-based system, each subject “s” holds a list of pairs (0, A[s,o]) called capabilities, derived from the nonempty entries in row “s” of the access matrix. This list is called a capability list or C-list and defines the domain of subject “s.” The capability is like a ticket in that possession authorizes its holder “s” to access object “0” with rights specified in A[s,o]. An ACL is an implementation of the column-based representation. Each object has an associated list of pairs (s, A[s,o]) derived from the nonempty entries A[s,o] in column “0” of the access matrix. For each object “0,” only subject “s” whose id is on the access control list is allowed access to “0” with rights given in A[s,o]. Figure 3 shows an example of an access matrix along with corresponding ACL and capability representations. The comparative advantages of capabilities versus ACLs are well documented [6, 7, 141. In summary, capability-based systems are more efficient but have difficulties in the following areas: revocation of access, control of propagation of access, and review of access. These problems seem to stem from a fundamental characteristic of capability-based systems-diffuseness of ownership. ACL-based systems solve these problems nicely but are less efficient. Another fundamentally important problem is the implementation of the principle of “least privilege” or “need to know.” The following subsection describes the principle of least privilege in more detail and the difficulty of implementing this principle in conventional ACL systems.
3.2 Implementation
3.3 The Principle
In operating systems, the objects may be files, directories, memory segments, or processes, and the subjects may include users or processes. Typical access rights are read, write, search (in the case of a directory), and execute rights. At any point of execution, a subject is associated with a protection environment called a domain. A domain is a set of objects that the subject is authorized to access; thus, a domain may be represented by a list of objects and the corresponding access rights that the subject currently has to these objects. In object-oriented systems, two levels of access rights must be considered. 1. Encapsulation of objects: read/write access authorizations of exported procedures to state variables, local variables, and parameters (if basic types are passed as parameters). 2. Procedure invocation rights: rights of subjects to invoke exported procedures of an object. For example, from the user’s point of view, the access rights for an object of type integer-stack may be invocation rights to push and pop procedures. However, the pop and push procedures have access authorization only to the internal representation of the stack (which may be an array of integer and a pointer to the array), and an integer parameter to be pushed on to the stack (in the case of the push procedure). This article focuses attention on the representation of invocation rights to exported procedures. Mechanisms for encapsulation of objects are assumed to be implemented by the underlying layers of software and/or hardware. Thus, in the protection state of the system (S, 0, A),
of Access
Control
An implementation of a protection mechanism requires complete mediation of every access to an object by a
of Least Privilege
in ACLs
The principle of least privilege states that each program should be executed in the smallest possible domain in
Object-oriented
J. SYSTEMS SOFTWARE 1990; 13:3-12
Systems
Figure 4. Example least privilege.
of an implementation
of the principle
7
of
order to minimize compromise of protection by a “Trojan Horse” or undebugged program. Capabilitybased systems nicely implement the least privilege principle at the procedure invocation level since they naturally provide a mechanism to change domains dynamically for each procedure invocation. The principal feature used to realize this mechanism is the “enter” capability [15] or “call” operation and CALLRTS access rights [ 141. Conventional ACL-based systems do not implement the least-privilege principle as effectively as capability-based systems, as illustrated by the following example. Assume that an object HEALTH stores medical information and an object SALARY stores income information about a community of users. As illustrated in Figure 4, the exported procedures GET and PUT are used for retrieving or inserting records to/from these objects. Two other objects are INSURANCE and TAX. One of the exported procedures HEALTH-CHECK in INSURANCE takes object HEALTH as a parameter to determine the current health status of a user. Exported procedure FEDERAL_TAX_CALC in TAX takes object SALARY as a parameter to calculate the federal tax of a user. There are two protection issues related to the least privilege principle. 1. Users should not be able to access data stored in HEALTH and SALARY objects even though users have capabilities for (or can locate) these objects. Thus, GET and PUT procedures of these objects should not be invoked directly by users. This may appear to be a protection issue for encapsulating objects as mentioned earlier, since the whole problem may be avoided by combining object HEALTH and SALARY with INSURANCE and TAX objects, respectively. However, there may be other totally independent objects that require access to HEALTH and SALARY objects, and a decision to structure the problem in this manner is totally up to the programmer. Therefore, this situation must also be considered as an issue involving procedure invocation rights.
t3
s’s domain
Figure 5. Example of difficulty with implementation principle of least privilege in ACL systems.
of the
2. Procedure HEALTH-CHECK should have call access to only the GET procedure of HEALTH when it is invoked with HEALTH as a parameter. It should not have access authorization to PUT of HEALTH and GET/PUT of SALARY. Similarly, FEDERAL _TAX_CALC should have call access to only the GET procedure of its parameter SALARY object and should not have access to PUT of SALARY nor any access to HEALTH. In a typical ACL system, a subject corresponds to a user. Under this assumption, the same level of least privilege as provided by capability-based systems cannot be achieved. In the previous example, in order for the HEALTH-CHECK procedure executing on behalf of user S to acquire a call access authorization for GET in the HEALTH object, the ACL for HEALTH must contain the entry (S, GET). Similarly, SALARY must contain the (S, GET) entry in its ACL in order for FEDERAL_TAX_CALC executing on behalf of S to access GET in SALARY. As shown in Figure 5, this allows S to directly invoke GET procedures in HEALTH and SALARY. Moreover, HEALTH -CHECK can access not only GET in HEALTH but also GET in SALARY. In the same manner, FEDERAL_TAX_CALC has access authorizations for GET in both SALARY and HEALTH. The concept of a group allows for some refinement in attempting to realize least privilege [6, 161. A group is a mechanism for representing a set of subjects; thus, multiple subjects are identified by a group name. In Multics, a subject can be active in only one group at a time, even though it can be a member of more than one group. The allows for the following improvement in the above example:
8
l
l
l
M. Mizuno and A. E. Oldehoeft
J. SYSTEMS SOFTWARE 1990; 13:3-12
User S is a member of two different groups, say Gl and G2. The ACLs for HEALTH and INSURANCE contain entries (Gl, GET) and (Gl, HEALTH-CHECK), respectively. The ACLs for SALARY and TAX contain (G2, GET) and (G2, FEDERAL_TAX_CALC), respectively .
HEALTH-CHECK, executing on behalf of S, can access only GET in HEALTH, and FEDERAL-TAX _CALC, executing on behalf of S, has access only to GET in SALARY. However, even with the group mechanism, S can still access GET in HEALTH or SALARY directly. The problem is that ACL systems typically do not have a mechanism to change domains dynamically for each procedure invocation.
4. IMPLEMENTATION RMS
OF ACCESS CONTROL
IN
This section shows how the advantages of both capabilities and ACLs are captured in the RM system. The fundamental difficulties of capabilities are avoided by starting with an ACL as a basis. Since access control checks in RM systems are based on invocation rights to the exported procedures, they need to be performed only when messages arrive at modules. Therefore, the inefficiency typically associated with ACLs is less serious in our system. The following subsections describe the realization of the principle of least privilege in ACLs and enforcement of constraints on the order of exported procedures invoked by individual subjects.
4.1 Four-tuple
ACL Entry
In order to realize the principle of least privilege at procedure invocation level, as provided by capabilitybased systems, each subject “s” in an ACL entry (s, A[s,o]) is represented by a four-tuple (user ID, class ID, module ID, exported procedure name) rather than a simple user ID. As in other ACL systems, subject IDS are in one-to-one correspondence with their domains [7]. Since each procedure invocation dynamically defines a subject, the same level of least privilege as found in capability-based systems is realized. From another point of view, the four-tuple gives users a fine grain of access control. The first component provides access control at the user level. The second component may be used to enforce access through a front-end module of a specified class. This is useful in presenting a “view” for the user, as in database systems, and preventing direct access that would circumvent the view. Since numerous instances
of the same class may exist in the system, the third component of an entity may be used to further qualify the second component and force access through a specific instantiation of a designated class. The fourth component allows fine grain control by forcing the calling module through a specified procedure. These four levels comprise a natural feature of the system. Since owners of classes, owners of instantiations, and users of instantiations may all be different, the four levels of control provide significant flexibility in structuring and specifying protection for a system of modules. An “*” may be used in any component of a four tuple to denote a wild card (don’t care) specification in the case the owner of a module does not need this level of fine grain of control. The general problem with ACLs, as illustrated by the example in the previous section, can be solved in the following way : The ACL of object HEALTH contains the entry ((S, INSURANCE-CLASS, INSURANCE, HEALTH-CHECK), GET). The ACL of SALARY contains the entry ((S, TAX -CLASS, TAX, FEDERAL_TAX_CALC), GET). Object INSURANCE has the ((S, *, *, *), HEALTH -CHECK) in its ACL. The TAX object contains the ((S, *, *, *), FEDERAL_TAX_CALC) in its ACL. On behalf of S, procedure HEALTH-CHECK has call access only to the GET procedure of object HEALTH, and procedure FEDERAL_TAX_CALC has call access only to procedure GET of the SALARY object. S can invoke HEALTH-CHECK in INSURANCE and FEDERAL_TAX_CALC in TAX from any procedure of any instance of any class. S cannot access the GET procedure in the HEALTH or SALARY object directly . Default ACL specifications may be given in the protection specification in a class definition. When a module is instantiated, such default specifications become the initial ACL entries of the module. ACL entries may be modified at any time. In order to modify an entroy of an ACL, a subject must hold the “ACL modification right. ” An instantiator of a module automatically becomes the owner of the module and by default is granted the ACL modification right to the module. Each module has only one owner. An owner can transfer the ownership of a module to another subject. However, once transferred, the ownership cannot be regained unless a new owner transfers the ownership to the old owner. In addition to the owner of a module, two sets of subjects have rights to modify an ACL of a module; the system administrator and managers. The system administrator is a special user with
Object-oriented Systems no access restrictions, including the ACL modification rights, to any modules. The system administrator is similar to the UNIX super user [ 171. A manager must be granted the right to modify ACL entries of the module by the owner, and the owner can revoke the right from the manager any time. In order to implement a concept of managers, the system provides a special The subjects whose operation “MODIFY_ACL.” identifiers are listed in the ACL for MODIFY_ACL operation are managers of the module. Managers can modify ACLs for all operations but MODIFY_ACL. Only the owner of the module and the system administrator can modify the entries of the ACL for MODIFY _ACL operation. 4.2 Access-rights
Expressions
There are two types of consistency for typed objects [ 181: internal and external. Internal consistency is concerned with maintaining the truth of a set of predicates defined on the state variables encapsulated by an object. Each operator (exported procedure), executed in isolation, must transfer a consistent resource state into a new consistent state. The internal consistency of an RM can be determined from an examination of its class definition. External consistency specifies certain constraints on the order of operators invoked by individual users. For example, in order to access a file, each user might be required to first open the file, then perform read or write operations, and finally close the file. The enforcement of external consistency requires observation of the run-time behavior of each program that uses objects. The concept of access-rights expressions has been proposed to enforce external consistency in Concurrent Pascal [ 181. An access-rights expression constrains the order of invocation of procedures for each individual user. These constraints are specified by the use of procedure names and four separators: the semicolon to denote sequencing, the comma to denote alternation, the bracket to denote repetition, and parentheses to designate association. For example, the access-rights expression “P; Q; R” specifies that a user must invoke procedures P, Q and R in the specified order. Expression “P, Q, R” allows a user to invoke any one of P, Q, or R. Expression “[P; RI” specifies that a user is allowed zero or more invocations of the sequence P followed by R. Parentheses are used for grouping, for example, “P; (Q, R); S” specifies two possible sequence of invocations: “P; Q; S” or “P; R; S.” In Concurrent Pascal, the control of external consistency requires the cooperation of the programmer of the classes and the users. Because monitor-based systems generally do not totally encapsulate resources, it is
J. SYSTEMS SOFTWARE 1990:13:3-12
9
possible for a user to forego the constraints [ 181. Since the RM system provides for total encapsulation, access-rights expressions can effectively enforce external consistency constraints on the users of a module. The specification of external consistency is in hands of a programmer of a module. In an RM, access-rights expressions are combined with the four-tuple identifications of subjects to form extended ACLs. The A[s,o] part of an access control list entry (s, A[s,o]) lists access-rights expressions that specify not only procedures in module “0” that “s” can invoke but also specifies constraints on the order of invocations of these procedures that “s” must follow. It is not possible for “s” to circumvent these constraints. Syntactically, each ACL is a list of four-tuple entities, followed by an access-rights expression that governs the behavior of each entity in the list. As an example, suppose that a subject is required to open a file for reading (writing) prior to attempting to read (write) or close the file. The ACLs, in an instance of a file module, may appear as {(uidl ,*.*.*),(uidZ *,*,*)}:OpenR;[Read];CloseR {(uidl,Rh41,instl,procl)}:OpenW;[Write];CloseW. The first ACL specifies that any procedure of any instance of any class, executing on behalf of users “uidl” or “uid2,” is constrained to the sequence “OpenR” followed by any number of “Reads” followed by “ CloseR. ” The second ACL specifies that procedure “procl” of the “instl” instance of the module class “RMl” executing on behalf of user “uidl” is constrained to the sequence ‘ ‘OpenW,” followed by any number of “Writes” followed by “CloseW.” In the degenerate case, an access-rights expression is simply a set of procedure identifiers. For example, the ACL for a procedure X might be {(A,stack,stackl,push),(*,queue,*,*)}:X. In the context of RMs, access-rights expressions specify procedure invocation constraints within a single module. If external consistency requires constraints on invocations of exported procedures defined in more than one module, the programmer can simply create a front-end module that accepts all the requests and invokes the corresponding requests in other modules. In the above file example, assume that procedures OpenR, OpenW, Read, Write, CloseR, and CloseW are defined in totally different modules, say, in modules M_OpenR, M_OpenW, M-Read, M-Write, M_CloseR, and M _CloseW, respectively (even though this is probably an unusual arrangement). Then, the programmer may create a front-end module, called FILE of class FILE -CLASS, which declares exported procedures P _OpenR, P_OpenW, P-Read, P-Write, P_CloseR and
10
M. Mizuno and A. E. Oldehoeft
J. SYSTEMS SOFTWARE 1990; 13:3- 12
P_CloseW, respectively tended ACLs :
and specifies the following
ex-
{ (uid 1,*,*,*),(uid’& * , *, *)} :P_OpenR; [P-Read] ;P_CloseR {(uidl,RMl,instl,procl)}:P_OpenW;[P_Write];P _CloseW. Each exported procedure is defined to call a corresponding procedure in another module. For example, the body of P_OpenR may be declared as follows: procedure P_OpenR( ); begin M_OpenR.OpenR( end. The access control as follows:
may be defined as follows:
procedure Q_OpenR( ); begin FILE.OpenR( ); end. The other exported procedures are defined in a similar manner. The access control list of module FILE is defined as follows: {(*, FM-CLASS, FM, *)} : OpenR; [Read]; CloseR.
);
list of module M_OpenR
is defined
{(*, FILE-CLASS, FILE,P_OpenR)}:OpenR. The access control lists of other modules can be similarly defined. In order to grant or revoke access rights, only the ACLs in module FILE need to be modified. This is another example of the usefulness of the *specification in four-tuple entities. Uidl and uid2 cannot invoke OpenR, OpenW, Read, Write, CloseR, or CloseW without going through front-end module FILE. If uidl and uid2 invoke the operations in FILE, they have to follow one of two sequences specified by the access-rights expression: P_OpenR; [P-Read] ;P_CloseR P_OpenW;[P_Write];P_CloseW. The following example further illustrates how extended ACLs can be effectively used in a layered systems of modules. Assume operations OpenR,, Read, and CloseR operations are defined in module FILE. Furthermore, the operations must be invoked in a specified order, each by a different entity. For example, OpenR must be invoked from procedure Pl of instance Ml of class Cl. This must be followed by any number of Read invocations from procedure P2 of instance M2 of class C2. Finally, CloseR must be invoked from procedure P3 of instance M3 of class C3. All invocations must be executed on behalf of user uidl. The programmer may create a front-end module, called FM of class FM-CLASS, which declares exported procedures Q_OpenR, Q-Read and Q_ClaseR. The corresponding access-rights expressions of FM are as follows: {(uidl, Cl, Ml, Pl)} : Q_OpenR {(uidl, C2, M2, P2)) : Q-Read {(uidl, C3, M3, P3)) : Q_CloseR
The body of Q_OpenR
The reader may note that access-rights expressions appear to be syntactically similar to path expressions [ 11, 191. However, a path expression imposes synchronization constraints on concurrent access by a collection of subjects but does not control the behavior of each individual subject. If the path expression is not satisfied, the corresponding invocation request is blocked. On the other hand, an access-rights expression specifies the behavior of each subject, and if the expression is not satisfied, the corresponding invocation request is rejected as a protection violation.
4.3 An Example
of a Mailbox
System
Using RMs
This section presents a sample program for implementing a private mail service, the use of which is restricted to a specified set of users. The relvant aspects of the program are presented in Figure 6 with a diagram of message flows shown in Figure 7. For simplicity, a fixed number of users with identities “user1 ” through “userm” are assumed. A two-level module construction is used for the program. The outer-level module is an instance “MAIL” of class “post-office” that presents the users with the view of having two available operations: SND and RCV for sending and receiving mail. MAIL encapsulates an array of queues of modules, one queue for each user of the mail service. Each member of the queue is an instance of the class “message-bin” that is dynamically created by the program to encapsulate an arriving message (via SND) and is destroyed once the mail is delivered (via RCV). Dynamic instantiations of message-bin are assigned system generated names (denoted as $Mi). To trace the flow of messages, assume a subject sends mail to useri by invoking the SND operation in MAIL. SND calls on a system defined operation “INSTANTIATE” to create an instance, say $M3, of class message-bin. SND then invokes $M3. WRITE, requesting $M3 to store the message and then invokes $M2.PUTNEXT to accomplish the linking of $M2 to $M3. The internal array “mess_buf” is then changed
Object-oriented
post&ice
Systems
J. SYSTEMS
1990; 13:3-12
begin
= class
specification = SND(IN receiver1 RCV(IN protection
receiver2
: userl..userm, : userl..userm,
: string); message : string);
message OUT
begin procedure
=
begin
{(userl,*,*,.)
,.,., (userm,+,+,*)}
synchronization
SND,
RCV
procedure
=
begin
(synchronization access
procedure
specification
for SNC and RCV)
end
:= message end
message
: string);
message := mailmessagemessage GETNEXT(IN mailmessagenext
end
: message-bin);
next
:= next end
PUTNEXT(Q.UT
: message-bin);
next
next := mailmessage.next
end
message-bin.
Figure 6. (continued).
=
type
mailmessage.message READ(OUT
11
SOFTWARE
msg.buf_type
=
record
: message-bin; : message.bin;
first last end state
mess_buff
procedure
: array [userl..userm]
SND (IN
receiver1
of msg.buf.type;
: userl..userm;
message
: string);
: message-bin;
var tmp begin
measage_bin.INSTANTIATE(OUT tmp.WRITE(IN
tmp);
message);
if msg_buf[receiverl].first
= null
then begin msg_buf[receiverl].first
:= tmp;
msg_buf[receiverl].last:=
tmp;
end else begin msg_buf[receiverl].last.PUTNEXT(IN msg_buf[receiverl].last:=
tmp);
tmp;
end end procedure w
RCV
(IN
: userl..userm;
receiver2
: message-bin;
tmp
OUT
message
: string);
begin if msg_buf[receiver2].first then
message
= null
:= ‘NO
MAIL’
elrre begin tmp := msg_buf[receiver2].first; tmp.READ(OUT
message);
tmp.GETNEXT(OUT
to reflect the fact that $M3 is now the tail of the queue for useri. Suppose that useri subsequently invokes MAIL.RCV to retrieve some mail. RCV invokes $Ml .READ to retrieve the first item of mail for useri. It then determines the new head of the queue by invoking $Ml .GETNEXT and changes its internal table to reflect the fact that $M2 is the new head of the queue. Finally, SND calls on a system defined operation DESTROY to eliminate $Ml , and it returns the mail message to useri. In the class definitions of post-office and message _bin in Figure 3, default access control specifications are given. The ACL in MAIL allows any of the m users to invoke the SND and RCV operations from any procedures in any instances of any classes. The ACLs for instances of message-bin allow calls only from specific procedures in the MAIL instance of post-office. The user identification is not needed in the four-tuples since MAIL itself provided that level of access control. In particular, WRITE and PUTNEXT may be called
msg.buf[receiverl].first);
tmp.DESTROY(); end
Figure 7. Modules for implementing a private mail service.
end initialize var i
amlvlngmesxlges
: userl..userm;
1
(SND. RCV)
begin
Fe
departing messages (READ. WRITE. GEINEXI,
PUTNEXT)
f or i := 1 to m do begin msg_buf[i].first
:= null;
msg_buf[i].last
:= null;
MAIL
end end end
poetoffice
message-bin
= class
specification
=
WRITE(IN
: string) : string) next : message-bin) next : message-bin)
message
READ(OUT
message
PUTNEXT(IN GETNEXT(OUT protection
=
{e, post&ice,
MAIL,
SND}
WRITE,
{e, post&ice,
MAIL,
RCV}
READ;
synchronization
=
(sync4wmization WRITE, access
PUTNEXT GETNEXT
specification
READ,
PUTNEXT,
orrIvingmessages (READ.
for
WRITE.
GETNEXT,
$M,
message-type
-&-
record
: string; : message-type;
message next end; state
mailmessage
procedure
: messagefype;
WRITE(IN
message
: string);
Figure 6. A program for a private mail service.
ativing messages (READ.
WRITE, --
GETNEXT)
=
type
PUTNDO
PROTECTION
GETNEXI,
PUTNEXT)
12
M. Mizuno and A. E. Oldehoeft
J SYSTEMS SOFTWARE 1990; 13:3-12
only by the SND operation in MAIL. The access rights expression “READ;GETNEXT” specifies a sequence of calls that must be followed by the RCV operation of MAIL.
6. D. D. Downs, J. R. Rub, K. C. Kung, and C. S. Jordan. Issues in discretionary access control. In Proceedings of
the 1985 Symposium 7.
5. CONCLUSION An access control language and implementation mechanism has been presented for an object-oriented system in which resource modules are the programming language construct. The method combines the advantages of both capabilities and traditional access control lists and is general enough to be used in any object-oriented system. The concept of a “four-tuple access control list” was introduced in order to allow the enforcement of the principle of least privilege at the procedure invocation level. The four-tuple concept was combined with access-rights expressions in order to allow the programmer and owner of a module to specify constraints on the order of use of operations by specific subjects.
REFERENCES 1. M. Ahamad,
R. J. LeBlanc,
of Reliability in Distributed Systems, 1987, pp. 115-125. 2. B. Liskov and R. Scheifler, support
9.
10.
11.
12.
13. D. Partha,
and T. Wilkes,
Fault tolerant computing in object based distributed operating systems, in Proceedings of the Sixth Symposium
guistic
8.
for robut,
Software
and Database
Guardians and actions: lindistributed programs, ACM
Trans. Programming Languages and Systems, 5(3), 381-404 (1983). 3. C. Pu and J. D. Noe, Design and implementation of nested transactions in eden, in Proceedings of the Sixth Symposium of Reliability in Distributed Software and Database Systems, 1987, pp. 126- 136. 4. A. E. Oldehoeft and M. Mizuno, Preliminary design specifications, for highly-structured distributed software using resource modules, In Proceedings of the Hawaii
International Conference on System Sciences-19, 1986, pp. 330-340. 5. D. E. Denning, Cryptography dison-Wesley, Reading, Mass.,
and Data Security. Ad1982.
on Security and Privacy, 1985,
pp. 208-218. J. H. Saltzer and M. D. Schroeder, The protection of information in computer systems, In Proceedings of the IEEE, 1975, pp. 1278-1308. M. Mizuno, Highly-Structured Software for Network Systems and its Protection. PhD thesis, Iowa State University, 1987. M. Mizuno and A. E. Oldehoeft, Information flow control in a distributed object-oriented system with statically bound object variables, In Proceedings of the 10th National Computer Security Conference, 1987, pp. 56-67. A. Goldberg and D. Robson. Smalltalk-80: The Language and its Implementation. Addison-Wesley, Reading, Mass., 1983. R. H. Campbell, A Definition of Open Path Expressions. Technical Report TR UIUCDCS-R-82-1102., University of Illinois, Urbana, Illinois, 1982. G. S. Graham and P. J. Denning, Protection-principles and practice. In Proceedings of the Spring Joint Computer Conference, 1972, pp. 417-429. B. W. Lampson. Protection. In Proceedings of Fifth
Princeton Conference on Information Systems, 1971, pp. 437-443.
Science and
14. E. Cohen and D. Jefferson, Protection in the hydra operating system. In Proceedings of the Fifth Symposium on Operating Systems Principles, 1975, pp. 141- 159. 15. J. B. Dennis and E. C. VanHorn. Programming semantics for multiprogrammed computations. Commun.
ACM 9(3), 143-155 (1966). The Mu/tics System: An Examination of its Structure, MIT Press, Cambridge, Mass. 1972.
16. E. I. Organick,
Unix time-sharing 17. D. M. Ritchie and K. Thompson, system, The Bell System Technical Journal, 57(6),
1905-1929 (1978). Access-right expres18. R. Kieburtz and A. Silberschatz, sions. ACM Trans. Programming Languages and
Systems 5(l), 78-96 (1983). 19. R. H. Campbell and A. N. Habermann, The specification of process synchronization by path expressions. Lecture Notes in Computer Science 16, 89-102 (1974).