When multiple users work on the same server, their workspaces not only need to be separated in a controlled way by means of the module feature. Users are also interested in controlling who has which rights on their workspace (=module). ConceptBase includes basic support for rights definition and enforcement via a user-definable query class CB_Permitted. The signature of this query class has to conform the following format:
GenericQueryClass CB_Permitted isA CB_User with
parameter
user: CB_User;
res: Resource;
op: CB_Operation
...
end
A user is allowed to perform the operation op on the resource res iff the constraint of the query is satisfied. Then, user is returned as answer of the query. If not, the answer is nil (equals empty set). Some fundamental definitions are pre-defined objects of ConceptBase:
Resource with end Module isA Resource end CB_Operation end CB_ReadOperation isA CB_Operation end CB_WriteOperation isA CB_Operation end TELL in CB_WriteOperation end ASK in CB_ReadOperation end
Hence, at least two operations TELL and ASK are pre-defined symbolizing write and read accesses to a resource. Modules are the prime examples of resources to be access-protected. Currently, only access to them is monitored by the CBserver.
When a user wants to switch to a new module, then she must at least have the permission to execute the operation ASK on it. Otherwise, the context switch is rejected. This is the main protection scheme offered to module owners. It is recommended to define the query class CB_Permitted in the module that needs protection.
Assume that there is a user jonny who wants to protect his module Mjonny. To do so, he would first define the module and set the module context to Mjonny.
Mjonny in Module end
Then, he would set the module context to Mjonny define his rights management policy, for example:
CB_Group with
attribute
groupMember: CB_User;
permitted_read: Resource;
permitted_write: Resource;
owner_resource: Resource
end
CB_User isA CB_Group end
CB_Group in Class with
rule
rr1: $ forall p/Resource u/CB_User
(u owner_resource p) ==> (u permitted_write p) $;
rr2: $ forall p/Resource u/CB_User
(u permitted_write p) ==> (u permitted_read p) $;
rr3: $ forall u/CB_User (u groupMember u) $;
rr4: $ forall u/CB_User p/Resource
( exists g/CB_Group (g groupMember u) and
(g owner_resource p) ) ==> (u owner_resource p) $;
rr5: $ forall u/CB_User p/Resource
( exists g/CB_Group (g groupMember u) and
(g permitted_write p) ) ==> (u permitted_write p) $;
rr6: $ forall u/CB_User p/Resource
( exists g/CB_Group (g groupMember u) and
(g permitted_read p) ) ==> (u permitted_read p) $
end
GenericQueryClass CB_Permitted isA CB_User with
parameter
user: CB_User;
res: Resource;
op: CB_Operation
constraint
cperm: $ (
( not exists u/CB_User
(u owner_resource ~res) and
not (u == ~user) )
or
( (~op in CB_ReadOperation) and
(~user permitted_read ~res) )
or
( (~op in CB_WriteOperation) and
(~user permitted_write ~res) )
)
and UNIFIES(~user,~this) $
end
In the above example, access rights are granted to groups of ConceptBase users. The owner of a resource will always have full access via rules rr1 and rr2.
Then, the user would claim ownership to the module via
CB_User jonny with owner_resource r1: Mjonny end
Then, only jonny can switch to the module Mjonny. If a second user like mary was to be granted read permission, jonny would define within module Mjonny:
CB_User mary with permitted_read r1: Mjonny end
In the above example, rights can also be granted to groups of users and then inherited to its members via rules rr4 to rr6. It should be noted that the definitions of owner_resource, permitted_read and permitted_write are just for illustrating what is possible. ConceptBase only requires the query class CB_Permitted in the module where the access rights need to be enforced. If such a query class (or a local version as explained below) is not defined, then any access is permitted for any user.
When a user attempts to switch to new module context, ConceptBase checks whether the user has at least read permission, i.e. permission for executing the operation ASK, on the module. If permission is not granted, the user cannot switch the module context and an error message is presented.
The definition of the query CB_Permitted is visible in the module where it is defined and in all sub-modules of this module. One can also define a local version of the query by appending the module name to its name, e.g. CB_PermittedMjonny. This version is only tested for access to the module Mjonny. The local overrides the general version CB_Permitted and its function is not inherited to sub-modules. There are plenty of ways to combine general and local versions of CB_Permitted yielding different access policies. When using access control, at least the module System should be protected. Otherwise, users could change essential definitions affecting all other users. Examples are in the HOW-TO section of the ConceptBase Forum (see URL conceptbase.cc).
It is very well possible to make access to a ConceptBase database completely impossible by errors in the definition of CB_Permitted. For example, one could deny access to any operation by the following simple rule:
GenericQueryClass CB_Permitted isA CB_User with
parameter
user: CB_User;
res: Resource;
op: CB_Operation
constraint
cperm: $ FALSE $
end
In such cases, one has to start the CBserver with disabled access control and repair the definition if the query CB_Permitted. Access control is by default disabled (see option -s in section 3). Hence, you need to explicitely enable it when you start the CBserver.
Caution: The access control feature of ConceptBase avoids some unwanted interferences in a setting where multiple users work on the same server. The system in not save against malicious attacks! Neither does it prevent all unwanted interferences.