Project

General

Profile

Access Control Lists(ACLs)

ACL items describe how security subjects relate to resources in terms of rights. This means that given a subject (security context) and a specific resource name, a list of assigned ACLs can be produced by the security manager.

The vast majority of any given directory's content (in terms of the % of the file dedicated to its use) will consist of ACL definitions. Each active resource recognized by the security environment must have a section. ACL items can be specified for the built-in resources of the FWD as well as any custom resources that were added for the application. Please see the section on Resources for more details.

FWD support two kind of plugin resources: built-in and custom made. Each resource (even the 4 “built-in” resources of FWD: admin, directory, net and system) is implemented using a resource plugin interface. The available resources are listed in the /security/config/resource-plugins/ path of the directory.xml. They are loaded and initialized at server startup. Each implemented class declares its type of resources. Here are the built-in classes and resource type they handles:

Built-in plugin class Resource type
com.goldencode.p2j.security.AdminResource admin
com.goldencode.p2j.directory.DirectoryResource directory
com.goldencode.p2j.net.NetResource net
com.goldencode.p2j.security.SystemResource system

Custom resource plugins can declare any resource type but the name must be different to avoid name-collisions.

The shared ACL is stored in /security/acl/ path of the directory. If an ACL item is defined for a private server instance, the item is stored in /security/acls/<server>/. Either case, each plugin FWD creates a branch with the associated resource type. For example, the entire list of global ACL items handled by com.goldencode.p2j.security.AdminResource is stored at /security/acl/admin/. The items that are applied only to a private server instance are stored into path /security/acls/<server_id>/admin/.

Each item has an id described below. Accordingly the directory path where an individual ACL item is to be found is /security/acl/<type>/<id> if it is global or /security/acls/<server>/<type>/<id> if it applies to a single server instance. Here <type> is the resource type and <id> is the decimal representation of the item's id prefixed by 0 s (zeroes) so that the minimum length is 6. Example: a global item handled by com.goldencode.p2j.net.NetResource plugin having the id 800 will be found at: /security/acl/net/000800>.

ACL Item components

The ACL items are a tuple of data that defines primarily:

  • the resource (resource-instance subnode),
  • a list of subjects (subjects subnode),
  • actual permission set (rights subnode).

A few other properties (the scope and the id) keep the items ordered and hierarchically structured. This sub-chapter describes each element that compose the tuple.

Scope

The scope of an ACL item represents the server instance on which this ACL item is applied. An ACL item can be declared for a specified server instance or shared by all server instances. If the item is declared global (i.e. it is shared by all servers) the item is stored directly to /security/acl/ path. Otherwise you can find it in /security/acls/<server>/, where <server> is the name of server instance. In the administration applet the global items are marked visually by “shared” in the instance / server name field.

Resource type

The resource type identifies which plugin class will handle this ACL item. Based on the type each plugin have declared, they are looked-up and the ACL tuple is sent to be applied / edited or otherwise handled by the respective plugin.

The location of the item in directory found by appending the resource type name to the path to ACL item's scope. Global items will be found in /security/acl/<type>/ and items particular to a specific server will be found in /security/acls/<server>/<type>/.

Id

The id indexes the items of the ACL. The ids must be unique for the each named resource. If two ACL items from different plugins have the same id they don't collide as they will have different names.

The id are very important because they allows to specify the order in which the ACL items are sorted and selected to be applied when multiple items fits a search criteria. When evaluating the access right over a resource for an entity, there can be three scopes that should be taken into consideration: the user, the group to which the user belongs and the special scope, all_other that matches all entities. The lookup algorithm check the following:

  1. The items for specified resource type are sorted ascendantly.
  2. If there is a ACL item for user or the group that contains the user, the first item (with minimum id) is selected.
  3. Otherwise, check if there is a item with all_other scope (no matter what its id is). If it is found it is selected.
  4. Otherwise, use the default rights for the user to access the resource or fall-back to another resource.

Since the ACL items are applied in the order given by the Id they form a collection that resemble to an array list rather than a set. It is a well know issue that moving (deleting and inserting) items in this kind of structure is not trivial. In order to simplify the editing and insertion of new items in the list at a specified position, the values of the id is recommended not to be consequentially. Instead a “gap” of 100 should be kept when creating new items so, if a new item should be inserted in between a new id could be assigned. This does not fixes the issue, but usually will help when in need to insert a new ACL item or move an existing one before or after another. For the rare cases when the minimum gap between the list ids is down to 1 and there is the possibility that no item can be inserted between list's items, the admin applet expose a “resequencing” functionality that allows to change id of all ACL items using a base number and an increment (the new gap).

When storing the items their id is appended to the path of their respective resource type: /security/acl/<type>/<id> is the path for a global item and /security/acls/<server>/<type>/<id> for a instance specific item. The <id> is the decimal representation of the item's id prefixed by 0 s so that the minimum length is 6. The physical order in which they appear in the directory is irrelevant as they will be sorted by id before processing so they can appear in directory in various order.

Instance name

The instance name name of resource exposed by plugin. A plugin resource usually handles multiple resources and the list of resources is specific to each plugin. Some plugins can have a limited list of handled resources, others may have a well structured resource naming system like a Unix file path or java full class name.

One special case is when the instance name is not explicitly set. Instead a regexp is used to define a set of resources that matches the expression's value. For example, a directory plugin can handle user accesses to a file system, granting different access rights over a group of files using a asterisk file-pattern as named resource.

When serialized to directory, the instance name resource node with two node attributes:

<node class="resource" name="resource-instance">
   <node-attribute name="reference" value="myFineResource"/>
   <node-attribute name="reftype" value="TRUE"/>
</node>

The reference attribute represent the reference to actual resource instance name and reftype is a boolean that is FALSE for regexps that match multiple instances and TRUE for true references to real instance resources.

Subject(s)

The subject defines the entity or entities on which the current ACL item applies to. Can be a user, a process, a defined group of users or can be associated to all accounts. An item having as subject a group grants or denies access for all users in it. A special subject is “all_others”. It is used as a last resort when no other group or user is defined for a resource.

See the Id paragraph for the algorithm for selecting the ACL item that handles the access rights when multiple items concur in handling permissions over a resource.

Here it is an example of a serialized list of subjects to directory.xml. It is composed from the user-group admins, a process/server my_server and an individual user, john_doe:

<node class="strings" name="subjects">
   <node-attribute name="values" value="admins"/>
   <node-attribute name="values" value="my_server"/>
   <node-attribute name="values" value="john_doe"/>
</node>
Rights

They are the actual rights the subject(s) is entitled to. Depending on the resource type, it can be a simple boolean flag that allows or disallows access to resource or a bit-field of complex right system. Each resource plugin exposes through the common interface a rights editor that allows the admin user to add/edit rights for its resources. In the directory the rights are serialized, read and interpreted also by the plugins.

In the directory, all items have the following structure:

<node class="container" name="000100">
   <node class="resource" name="resource-instance">
      <node-attribute name="reference" value="admin"/>
      <node-attribute name="reftype" value="TRUE"/>
   </node>
   <node class="systemRights" name="rights">
      <node-attribute name="check" value="true"/>
   </node>
   <node class="strings" name="subjects">
      <node-attribute name="values" value="admins"/>
   </node>
</node>

This particular items allows the admin group the administration privileges and can be found as a system resource type. It occurs usually on every server so it likely you will find it as a global (shared) ACL item.

The first line declares the id of the item, the name of the node is the decimal representation of the item's id prefixed by 0 s. This is the root node for the ACL item.

The first sub-node (resource-instance) describes the instance name. The value of reference node attribute represents the expression on which the access right is declared, in this particular case the “admin” privileges. The reftype node-attribute is a boolean that specify if this is a direct reference (true in this case) or a regular expression.

The actual rights are written in the second sub-node named righs. The class value is <resource_type>Rights and the attributes differ from a resource type to another. It's up to the plugin how it serializes the value(s). in this case it's a simple boolean checked = true, but other plugins can encode it binary as permissions='00111111'B. In the admin applet the same permissions can be presented differently, more user-friendly like a char-string or a set of check-boxes in an rights editor.

The last sub-node (subjects) encodes the list of subjects, ie. the entities that this ACL item acts upon. There can be a list of entities, each of them having the same set of permissions. In this particular case the subject is only the admin group.

Search Algorithm

There is no search algorithm involved from the view-point explained at the beginning of this chapter. However, the ACL items are looked-up instead by scope and then if multiple items describe a user access to a resource, then the simple algorithm described in Id paragraph above is used.

System Resources

This section defines the rights which users, processes (including servers) and groups have to the specific features of the core system. This security decision process is handled by the com.goldencode.p2j.security.SecurityManager in combination with the plugin class com.goldencode.p2j.security.SystemResource that is in charge with the management of access rights to these features. Every time the application reaches an important point in the execution where it is required by application logic or security policy to check the user's rights before the application may proceed, we say the application is about to check the user's access right to some resource. Resources exist only because applications name them and want the SecurityManager to check if the user has enough rights to continue.

The plugin recognize a fixed set of resource instances:

  • logon - allows logging on to the FWD server. Authentication procedure checks the subject's access rights on the logon instance and only allows logon if the check succeeds. This resource instance allows for a very flexible control over the logon availability.
  • context - names security context related events for audit (security context creation and deletion, security context switch, access rights check attempted as {resource type, resource instance name, requested access}, access rights check results).
  • change - controls the access to the FWD directory editing. Only those subjects having access to this instance can successfully open an editing batch.
  • shutdown - controls access to the programmatic server shutdown feature.
  • debug - controls access to the debug level change.
  • accounts - allows to obtain informations for the other accounts
  • extensions - allow (read and write) access to account extension data
  • admin - fall back to admin access to the system resource when no Admin Resource is present

All system resource instance values have attribute named check and primitive type string that is a user-defined logical expression that must evaluate to true for access to be granted. Any variable or function exposed by plugin or SecurityManager can be used.

Here follows a typical system node found on FWD configuration:

<node class="container" name="acl">
  <node class="container" name="system">
    <node class="container" name="000100">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="all_others"/>
      </node>
      <node class="systemRights" name="rights">
        <node-attribute name="check" value="true"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="logon"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000200">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="my_admin_group"/>
      </node>
      <node class="systemRights" name="rights">
        <node-attribute name="check" value="true"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="change"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000300">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="my_admin_group"/>
      </node>
      <node class="systemRights" name="rights">
        <node-attribute name="check" value="true"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="admin"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000400">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="all_others"/>
      </node>
      <node class="systemRights" name="rights">
        <node-attribute name="check" value="true"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="accounts"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000500">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="all_others"/>
      </node>
      <node class="systemRights" name="rights">
        <node-attribute name="check" value="true"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="extensions"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000600">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="my_server1"/>
        <node-attribute name="values" value="my_server2"/>
        <node-attribute name="values" value="my_admin_group"/>
      </node>
      <node class="systemRights" name="rights">
        <node-attribute name="check" value="true"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="shutdown"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000700">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="all_others"/>
      </node>
      <node class="systemRights" name="rights">
        <node-attribute name="check" value="false"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="shutdown"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000800">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="my_server1"/>
        <node-attribute name="values" value="my_server2"/>
      </node>
      <node class="systemRights" name="rights">
        <node-attribute name="check" value="debuglevel <= 9"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="debug"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000900">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="my_admin_group"/>
      </node>
      <node class="systemRights" name="rights">
        <node-attribute name="check" value="debuglevel <= 3"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="debug"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
  </node>
</node>

Admin Resource

This section defines the rights which users, processes (including servers) and groups have to the specific features of the administration console. The plugin class in charge with the management of access rights to these features is.com.goldencode.p2j.security.AdminResource The admin resource implements a hierarchical name space, where the nodes have the well-known names. Instance names are coded in a way the FWD directory nodes or the Unix file system objects are coded:

  • "/" designates the root admin permissions
  • "/console", "/accounts" etc designate the first level function groups
  • "/accounts/users" etc narrow down the scope of the function; it may or may not take some additional levels
  • a regular expression is allowed at the level 1 and below, provided it does not contain the forward slash and yields at least one match

The following tree represents the basic namespace of the admin resource:

/
   console
   accounts
      groups
      users
      processes
      certificates
   access_control
   extension
   runtime
   configuration
   target
      refresh

This hierarchy is expandable. The initial implementation is outlined below. No matter how large the tree gets expanded, the following requirements are always met:

  • for every node in the tree, the child nodes form an enumeration of the well-known names
  • non-leaf nodes give the following permissions:
    • explicit unlimited access to all the functions that may be coded in all the child nodes
    • explicit denial of access to all the functions that may be coded in all the child nodes
    • if neither of the explicit permissions is given, the access is controlled by the permissions as they are defined in the child nodes
  • leaf nodes give permissions that are specific to the node

The initial tree has the following nodes:

  • "/" - the root
  • "/accounts"
  • "/accounts/users" - the leaf node

The following access modes are defined for the /accounts/users:

  • enumerate - lists defined user accounts;
  • password - changes passwords only
  • group - allows assigning users to groups;
  • read - reads details of user accounts definitions;
  • write - changes user accounts definitions;
  • create - creates new user accounts;
  • delete - deletes user accounts

Rights objects for this resource are made of one bitfield having 2 bits for the non-leaf nodes and another 8 bits for the leaf nodes. See the integer node attribute type in the following two examples which selects which of the two bitfields is in use: 0 for non-leaf nodes and 1 for /accounts/users/ leaf nodes.

For the non-leaf nodes, the permissions bits are defined as follows:

  • unlimited access
  • denied access .

When serialized in directory they are encoded in '<unlimited><denied>'B format where <unlimited> and <denied> are the binary values (0 and 1) for granting the respective right. Here is a simple example that grants full permission access to admin user over the /console resource.

<node class="container" name="000200">
   <node class="strings" name="subjects">
      <node-attribute name="values" value="admin"/>
   </node>
   <node class="adminRights" name="rights">
      <node-attribute name="permissions" value="'10'B"/>
      <node-attribute name="type" value="0"/>
   </node>
   <node class="resource" name="resource-instance">
      <node-attribute name="reference" value="/console"/>
      <node-attribute name="reftype" value="TRUE"/>
   </node>
</node>

For the /accounts/users/ leaf nodes, the permissions bits are defined as follows:

  • enumerate
  • password
  • group
  • read
  • write
  • create
  • delete
  • denied.

Bits from "enumerate" through "delete" control the corresponding access modes. Bit "denied" explicitly denies any access, regardless of the boolean value of other bits. When showing as a string this appear as: EPGRWCDN. Missing permissions are replaced by (.) dots. When serialized by the java.util.BitSet, the binary values of the permissions appears in reverse order. The following small example shows how enumerate and password permissions are granted to admin user:

<node class="container" name="000500">
   <node class="strings" name="subjects">
      <node-attribute name="values" value="admin"/>
   </node>
   <node class="adminRights" name="rights">
      <node-attribute name="permissions" value="'00000011'B"/>
      <node-attribute name="type" value="1"/>
   </node>
   <node class="resource" name="resource-instance">
      <node-attribute name="reference" value="/accounts/users"/>
      <node-attribute name="reftype" value="TRUE"/>
   </node>
</node>

The following extensive example shows 2 groups that have administrative rights (my_admin_group that has full control/access to all features of the administration console and pw_change_admin which only can change user passwords). All other users (all_others) have no rights and cannot even logon to the administration console:

<node class="container" name="acl">
  <node class="container" name="admin">
    <node class="container" name="000100">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="pw_change_admin"/>
      </node>
      <node class="adminRights" name="rights">
        <node-attribute name="permissions" value="'00'B"/>
        <node-attribute name="type" value="0"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="/"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000200">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="pw_change_admin"/>
      </node>
      <node class="adminRights" name="rights">
        <node-attribute name="permissions" value="'10'B"/>
        <node-attribute name="type" value="0"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="/console"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000300">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="pw_change_admin"/>
      </node>
      <node class="adminRights" name="rights">
        <node-attribute name="permissions" value="'00'B"/>
        <node-attribute name="type" value="0"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="/accounts"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000400">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="pw_change_admin"/>
      </node>
      <node class="adminRights" name="rights">
        <node-attribute name="permissions" value="'10'B"/>
        <node-attribute name="type" value="0"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="/accounts/groups"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000500">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="pw_change_admin"/>
      </node>
      <node class="adminRights" name="rights">
        <node-attribute name="permissions" value="'00000011'B"/>
        <node-attribute name="type" value="1"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="/accounts/users"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000600">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="pw_change_admin"/>
      </node>
      <node class="adminRights" name="rights">
        <node-attribute name="permissions" value="'10'B"/>
        <node-attribute name="type" value="0"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="/accounts/processes"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000700">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="pw_change_admin"/>
      </node>
      <node class="adminRights" name="rights">
        <node-attribute name="permissions" value="'10'B"/>
        <node-attribute name="type" value="0"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="/accounts/certificates"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000800">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="pw_change_admin"/>
      </node>
      <node class="adminRights" name="rights">
        <node-attribute name="permissions" value="'10'B"/>
        <node-attribute name="type" value="0"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="/access_control"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000900">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="pw_change_admin"/>
      </node>
      <node class="adminRights" name="rights">
        <node-attribute name="permissions" value="'10'B"/>
        <node-attribute name="type" value="0"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="/extension"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="001000">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="pw_change_admin"/>
      </node>
      <node class="adminRights" name="rights">
        <node-attribute name="permissions" value="'10'B"/>
        <node-attribute name="type" value="0"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="/runtime"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="001100">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="pw_change_admin"/>
      </node>
      <node class="adminRights" name="rights">
        <node-attribute name="permissions" value="'10'B"/>
        <node-attribute name="type" value="0"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="/configuration"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="001200">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="pw_change_admin"/>
      </node>
      <node class="adminRights" name="rights">
        <node-attribute name="permissions" value="'10'B"/>
        <node-attribute name="type" value="0"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="/target"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="001300">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="my_admin_group"/>
      </node>
      <node class="adminRights" name="rights">
        <node-attribute name="permissions" value="'01'B"/>
        <node-attribute name="type" value="0"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="/"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="001400">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="all_others"/>
      </node>
      <node class="adminRights" name="rights">
        <node-attribute name="permissions" value="'10'B"/>
        <node-attribute name="type" value="0"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="/"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
  </node>
</node>

Directory Resource

Instances of com.goldencode.p2j.directory.DirectoryResource resource control access to the FWD directory objects. The integration with the security manager enables a highly flexible security policy. This allows granular control over the users/groups (security subjects) and the operations that those subjects are allowed to do on specific portions of the directory tree. For example, a specific group may have rights to read from certain parts of the directory and may be allowed to write to a specific directory object, while another group (or user) may have completely different rights to those same locations. Rights can be assigned down to the specific directory object or can be set at any parent object (which allows a policy to be set for the subtree of objects contained under that parent object).

The handled resources map naturally in Unix file-paths strings that match the actual FWD directory structure described at the beginning of the chapter. Because of this nature, the exposed resource is usually a regular expression matching a full branch rather than pointing to a single entity in the directory tree. Here is how a simple reference resource (/security) is represented:

<node class="resource" name="resource-instance">
   <node-attribute name="reference" value="/security"/>
   <node-attribute name="reftype" value="TRUE"/>
</node>

When you want to specify a regexp resource that matches multiple references (locations):

<node class="resource" name="resource-instance">
   <node-attribute name="reference" value=".*"/>
   <node-attribute name="reftype" value="FALSE"/>
</node>

The rights are composed from a 7-bit bitfield (with displayable label permissions) node attribute NCDAERW and optional logical expression (with displayable label condition) that must evaluate true for the access defined in the attribute permissions to be granted.

The following access mode are defined:

  • enumerate - make this node/attribute visible when listing (enumerating) parent node;
  • read - reads meta class of the nodes and attribute values;
  • write - permission to change node state or attribute values;
  • add - allows adding a child node to this node or allows adding another values to existing attributes;
  • create - creates new nodes and a value can be set for the previously non-existent attribute;
  • delete - deletes nodes and attributes.

Based on these 6 modes, the 8 permission bits are defined as follows:

  • enumerate
  • read
  • write
  • add
  • create
  • delete
  • denied - access is denied without further checks
  • logic

Bits from enumerate through delete control the corresponding access modes. The bit denied explicitly denies any access, regardless of the boolean expression and the logic bit (veto).

The bit logic specifies the operation of the optional boolean expression and is only taken into consideration when the expression is present:

  • if set to 1, the AND operation is performed between the result of the permissions check and the boolean expression; the effect of the expression in this case is restrictive;
  • if set to 0, the OR operation is performed between the result of the permissions check and the boolean expression; the effect of the expression in this case is permissive.

When printed, the full set of permissions is shown as ERWACDN. When serialized to directory, the binary values of the permissions appears in reverse order (less significant bit last) so '00000011'B stands for enumerate and read combination and '01000000'B is just deny.

This section defines the rights which users, processes (including servers) and groups have to the specific paths in the directory itself.

<node class="container" name="acl">
  <node class="container" name="directory">
    <node class="container" name="000100">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="my_admin_group"/>
      </node>
      <node class="directoryRights" name="rights">
        <node-attribute name="permissions" value="'00111111'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="/security"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000200">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="my_server1"/>
        <node-attribute name="values" value="my_server2"/>
        <node-attribute name="values" value="my_admin_group"/>
        <node-attribute name="values" value="pw_change_admins"/>
      </node>
      <node class="directoryRights" name="rights">
        <node-attribute name="permissions" value="'00111111'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value=".*"/>
        <node-attribute name="reftype" value="FALSE"/>
      </node>
    </node>
    <node class="container" name="000300">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="my_server1"/>
        <node-attribute name="values" value="my_server2"/>
        <node-attribute name="values" value="my_admin_group"/>
        <node-attribute name="values" value="pw_change_admins"/>
      </node>
      <node class="directoryRights" name="rights">
        <node-attribute name="permissions" value="'00111111'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="/meta"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000400">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="my_server1"/>
        <node-attribute name="values" value="my_server2"/>
        <node-attribute name="values" value="my_admin_group"/>
        <node-attribute name="values" value="pw_change_admins"/>
      </node>
      <node class="directoryRights" name="rights">
        <node-attribute name="permissions" value="'00111111'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="/meta/class/user/password"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000500">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="all_others"/>
      </node>
      <node class="directoryRights" name="rights">
        <node-attribute name="permissions" value="'01000000'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="/meta/class/user/password"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000600">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="all_others"/>
      </node>
      <node class="directoryRights" name="rights">
        <node-attribute name="permissions" value="'00000011'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value=".*"/>
        <node-attribute name="reftype" value="FALSE"/>
      </node>
    </node>
  </node>
</node>

Net Resource

This section defines the rights which users, processes (including servers) and groups have to call, lookup and export network APIs. The plugin that must be added to resource list is com.goldencode.p2j.net.NetResource. The net resource is a set of all exportable server methods that are potentially callable by client applications. Instances of this it control access to exported server's entry points. They form a two level hierarchy of names, with the top level name being a group name and the bottom level name being a member of the group. The syntax for this composite name is group:api. Valid names contain no slashes and at most one colon (:).

If no access rights are specified for the method specified as group:method, the group is checked next and the result is used as if it was found for the full name. This is an example of the tree propagation of rights.

The protection model is based on the following three access modes:

  • read - getting routing key for a known group:method;
  • write - add a group:method to the registry (export);
  • execute - call a method by specified routing key.

Rights objects for this resource are made of one bitfield with 4 bits. First three bits correspond to the listed access modes above. The last bit is for explicit denial of access. When printed, they are shown as RWXN. However, the binary values of the permissions appears in reverse order (less significant bit last) so '0011'B stands for read and write combination and '1000'B is just deny.

There is a predefined "system" group of methods, containing the following method names:

  • route - this method is used by peers to resolve exported symbolic API names into registry indexes
  • authenticate - this method is used internally by the net package to do remote subject authentication in a routed configuration
  • terminate - this method is used internally by the net package to do remote session termination in a routed configuration
  • shutdown - this method is used to request the net package shutdown, which normally also initiates the server shutdown

These names can be used in ACLs. The server's account should provide ACLs that allow the server's process have RWX rights for the "system" group. On the other hand, application related accounts never need any access to system:authenticate and system:terminate. They need RX access to system:route to be able to perform remote calls. system:shutdown may be given RX or N access.

<node class="container" name="acl">
  <node class="container" name="net">
    <node class="container" name="000100">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="my_server1"/>
        <node-attribute name="values" value="my_server2"/>
      </node>
      <node class="netRights" name="rights">
        <node-attribute name="permissions" value="'0111'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="system:route"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000200">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="my_server1"/>
        <node-attribute name="values" value="my_server2"/>
      </node>
      <node class="netRights" name="rights">
        <node-attribute name="permissions" value="'0111'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="system:interrupt"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000300">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="my_server1"/>
        <node-attribute name="values" value="my_server2"/>
      </node>
      <node class="netRights" name="rights">
        <node-attribute name="permissions" value="'0111'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="com.goldencode.p2j.main.MainEntry"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000400">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="my_server1"/>
        <node-attribute name="values" value="my_server2"/>
      </node>
      <node class="netRights" name="rights">
        <node-attribute name="permissions" value="'0111'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="system:authenticate"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000500">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="my_server1"/>
        <node-attribute name="values" value="my_server2"/>
      </node>
      <node class="netRights" name="rights">
        <node-attribute name="permissions" value="'0111'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="system:terminate"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000600">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="my_admin_group"/>
        <node-attribute name="values" value="pw_change_admin"/>
      </node>
      <node class="netRights" name="rights">
        <node-attribute name="permissions" value="'0101'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="com.goldencode.p2j.admin.AdminExports"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000700">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="my_admin_group"/>
        <node-attribute name="values" value="pw_change_admin"/>
      </node>
      <node class="netRights" name="rights">
        <node-attribute name="permissions" value="'0101'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="directory"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="001100">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="all_others"/>
      </node>
      <node class="netRights" name="rights">
        <node-attribute name="permissions" value="'0101'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="system:route"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="001200">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="all_others"/>
      </node>
      <node class="netRights" name="rights">
        <node-attribute name="permissions" value="'0101'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="system:interrupt"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="001300">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="all_others"/>
      </node>
      <node class="netRights" name="rights">
        <node-attribute name="permissions" value="'0101'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="com.goldencode.p2j.main.MainEntry"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="001400">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="all_others"/>
      </node>
      <node class="netRights" name="rights">
        <node-attribute name="permissions" value="'0101'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="com.goldencode.p2j.ui.ServerExports"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="001500">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="all_others"/>
      </node>
      <node class="netRights" name="rights">
        <node-attribute name="permissions" value="'0101'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="com.goldencode.p2j.util.RemoteErrorData"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="001550">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="all_others"/>
      </node>
      <node class="netRights" name="rights">
        <node-attribute name="permissions" value="'0101'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="com.goldencode.p2j.util.ServerPropertiesInspector"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="001600">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="all_others"/>
      </node>
      <node class="netRights" name="rights">
        <node-attribute name="permissions" value="'0101'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="com.goldencode.p2j.persist.DatabaseManager$DatabaseConfigFetcher"/>
         <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="001700">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="all_others"/>
      </node>
      <node class="netRights" name="rights">
        <node-attribute name="permissions" value="'0101'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="com.goldencode.p2j.persist.remote.LockManagerMultiplexer"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="001800">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="all_others"/>
      </node>
      <node class="netRights" name="rights">
        <node-attribute name="permissions" value="'0101'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="com.goldencode.p2j.persist.remote.DirtyShareMultiplexer"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="001900">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="all_others"/>
      </node>
      <node class="netRights" name="rights">
        <node-attribute name="permissions" value="'0101'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="com.goldencode.p2j.persist.remote.IdentityManagerMultiplexer"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="002000">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="all_others"/>
      </node>
      <node class="netRights" name="rights">
        <node-attribute name="permissions" value="'0101'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="system:authenticate"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="002100">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="all_others"/>
      </node>
      <node class="netRights" name="rights">
        <node-attribute name="permissions" value="'0101'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="system:terminate"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="002200">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="all_others"/>
      </node>
      <node class="netRights" name="rights">
        <node-attribute name="permissions" value="'0101'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="com.goldencode.p2j.directory.Directory"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="002250">
      <node class="resource" name="resource-instance">
        <node-attribute name="reftype" value="TRUE"/>
        <node-attribute name="reference" value="com.goldencode.p2j.main.Spawner"/>
      </node>
      <node class="netRights" name="rights">
        <node-attribute name="permissions" value="'0101'B"/>
      </node>
      <node class="strings" name="subjects">
        <node-attribute name="values" value="all_others"/>
      </node>
    </node>
    <node class="container" name="002275">
      <node class="resource" name="resource-instance">
        <node-attribute name="reftype" value="TRUE"/>
        <node-attribute name="reference" value="com.goldencode.p2j.main.RemoteSpawner"/>
      </node>
      <node class="netRights" name="rights">
        <node-attribute name="permissions" value="'0101'B"/>
      </node>
      <node class="strings" name="subjects">
        <node-attribute name="values" value="all_others"/>
      </node>
    </node>
    <node class="container" name="002300">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="my_server1"/>
        <node-attribute name="values" value="my_server2"/>
      </node>
      <node class="netRights" name="rights">
        <node-attribute name="permissions" value="'0111'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value=".+"/>
        <node-attribute name="reftype" value="FALSE"/>
      </node>
    </node>
    <node class="container" name="002325">
      <node class="resource" name="resource-instance">
        <node-attribute name="reftype" value="TRUE"/>
        <node-attribute name="reference" value="com.goldencode.p2j.main.BrokerServerServices"/>
      </node>
      <node class="netRights" name="rights">
        <node-attribute name="permissions" value="'0101'B"/>
      </node>
      <node class="strings" name="subjects">
        <node-attribute name="values" value="all_others"/>
      </node>
    </node>
  </node>
</node>

Custom Resources

Beside the above four standard built-in resource types, new plugins can be developed that will handle any additional needed resource. Those are custom resources. For more details on how to develop a custom plugin see the chapter 5 Runtime Hooks and Plug-Ins from second part of FWD Developer Guide book.

Suppose that you have developed a class, along with any needed utilities class and an access manger that will enforce the access restrictions on a virtual EPABX, with a set of phone numbers. The first step, as with the standard resources, is to declare the newly created plugins in /security/config/resource-plugins part of the directory so FWD to load and initialize them:

<node class="container" name="security">
   <node class="container" name="config">
     <node class="strings" name="resource-plugins">
       <node-attribute name="values" value="com.mycompany.myapp.security.PhoneResource"/>
     </node>
   </node>
</node>

All resource plugins must extend com.goldencode.p2j.security.AbstractResource. This will guarantee that our class NewResource will implement getTypeName() method that will returns the plugin resource type name as a string “phones”. This string (without quotes) is further used to declare the location of the ACL in directory tree: /security/acl/phones/ for shared ACL and /security/acls/<server>/phones/ for private instances of server.

Also, among other methods of the com.goldencode.p2j.security.Resource interface, the new plugin will implement isInstanceNameValid() boolean method that will check instance names (phone numbers in our case), and describeRights() method that returns an array of objects that describe how the access rights to the resources are formed. Suppose that we have two permissions for our example: to make a phone call and to receive.

Here is a configuration set that:

  • allows anybody to receive an incoming call but deny the calling (id 300)
  • allows the admins user-group to place any call (id 100)
  • allow the rest of the users to make a call to a specified number (id 200)
<node class="container" name="acl">
  <node class="container" name="phone">
    <node class="container" name="000100">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="admins"/>
      </node>
      <node class="phoneRights" name="rights">
        <node-attribute name="permissions" value="'11'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="*"/>
        <node-attribute name="reftype" value="FLASE"/>
      </node>
    </node>
    <node class="container" name="000200">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="admins"/>
      </node>
      <node class="phoneRights" name="rights">
        <node-attribute name="permissions" value="'11'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="001234567890"/>
        <node-attribute name="reftype" value="TRUE"/>
      </node>
    </node>
    <node class="container" name="000300">
      <node class="strings" name="subjects">
        <node-attribute name="values" value="any_other"/>
      </node>
      <node class="phoneRights" name="rights">
        <node-attribute name="permissions" value="'10'B"/>
      </node>
      <node class="resource" name="resource-instance">
        <node-attribute name="reference" value="*"/>
        <node-attribute name="reftype" value="FLASE"/>
      </node>
    </node>
  </node>
</node>

Reference

The following options can be specified for shared ACL items:

Option ID Data Type Default Value Required Details
/security/acl/<type> container N/A no The resource type for shared instances of ACL items
/security/acl/<type>/<id> container N/A no The id of ACL item for shared instances of ACL items
/security/acl/<type>/<id>/subjects strings N/A yes The list of the subjects to which the rights applies to.
/security/acl/<type>/<id>/rights <type>Rights N/A yes The container for rights of this type. Each plugin have the liberty of serializing the rights as they find suitable. Usually there are one or two node attributes that describe the rights granted to subjects. The <type> is declared individually by the resource plugin that handles it.
/security/acl/<type>/<id>/resource-instance resource N/A yes The container for resource instance. It has two node-attributes described below.
/security/acl/<type>/<id>/resource-instance/reference string N/A yes The resource name over which the ACL item sets the access rights.
/security/acl/<type>/<id>/resource-instance/reftype boolean N/A yes TRUE if ACL item refers a resource instance or FALSE if it is a regular expression that matches multiple resources.
/security/acls/<server>/<type> container N/A no The resource type for private instances of ACL items.
/security/acls/<server>/<type>/<id> container N/A no The id of ACL item for private instances of ACL items.
/security/acls/<server>/<type>/<id>/subjects strings N/A yes The list of the subjects to which the rights applies to.
/security/acls/<server>/<type>/<id>/rights <type>Rights N/A yes The container for rights of this type. Each plugin have the liberty of serializing the rights as they find suitable. Usually there are one or two node attributes that describe the rights granted to subjects. The <type> is declared individually by the resource plugin that handles it.
/security/acls/<server>/<type>/<id>/resource-instance resource N/A yes The container for resource instance. It has two node-attributes described below.
/security/acls/<server>/<type>/<id>/resource-instance/reference string N/A yes The resource name over which the ACL item sets the access rights.
/security/acls/<server>/<type>/<id>/resource-instance/reftype boolean N/A yes TRUE if ACL item refers a resource instance or FALSE if it is a regular expression that matches multiple resources.

© 2004-2017 Golden Code Development Corporation. ALL RIGHTS RESERVED.