Creating User Roles for ACEs

Describes how to create and use roles for access control.

NOTE MapR recommends that you use Unix groups over roles whenever possible for centralized maintenance. Use Roles only if you are unable to modify LDAP or AD groups easily.

A role is a label attached to a set of users and defines a common task or set of behaviors for those users. Roles enable you to use functionality similar to Unix groups for your users without requiring you to alter the existing group hierarchy of your system. Role names can be up to 64 characters long and cannot use the :, &, |, or ! characters.

Standard Reference Implementation

User Information

The standard reference implementation is a library called libmapr_roles_refimpl.so. This library is located at /opt/mapr/server/permissions. This library opens a configuration file named m7_permissions_roles_refimpl.conf, which should contain a list of all the roles and the users associated with them. This configuration file is located at /opt/mapr/conf and should be identical across all clusters.

The structure of the configuration file is shown below. Roles end with : and user names are written on each subsequent line. For example:

Role_1:
            user_a
            user_b
Role_2:
            user_b
            user_c
            user_d
            #comment
            

The above example file states that there are two roles from which to choose while assigning permissions: Role_1 and Role_2. The users located under Role_1 are user_aand user_b. Role_2 contains user_b, user_c, and user_d. Blank lines and lines beginning with # are ignored.

Assume a table has permissions r:Role_2. user_b has access to this table while user_a does not have access.

After adding a new role to the m7_permissions_roles_refimpl.conf file, you must issue the following command to enable the MapR File System layer to pick up the new role: $ /opt/mapr/server/mrconfig dbrolescache invalidate

Run this command on all the nodes whenever a change is needed in the roles configuration file.

Developer Information

The functions that the libmapr_roles_refimpl.so exposes are found in the extensibility implementation. If the library is called initially through GetSecurityMembership, it parses the m7_permissions_roles_refimpl.conf file and loads it into memory. All user names are read and parsed into user IDs (uid_t). If a user ID is not found, the ID is skipped.

The library uses a HashTable. The roles are the keys. The values are a Binary Tree of user IDs.

Each call checks the given user ID and role. The HashTable keys off the role and then searches the Binary Tree for the user ID. If the HashTable finds a user ID, it sets the boolean value of that role to true. If the HashTable does not find a user ID or if any errors occur, such as Role not found, it sets the boolean value to false.

A cleanup method frees the memory allocated to the HashTable along with all of its children. If the GetSecurityMembership method is called again, the library reloads the configuration file and loads all the values into memory.

Extensible Implementation

If users decide not to use the reference implementation, they can replace the shared library with their own. In the mfs.conf file, add a parameter that specifies the name of the file. If the name of the file is changed, then MFS searches /opt/mapr/server/permissions for the new file. If the file is found, it is loaded into memory. If not, then all roles become false.

The user's shared library should contain two functions specified under the mapr::fs namespace:

extern "C"
            void GetSecurityMembership(uid_t uid, const char *roles[], int numRoles, bool truthValue[]) {
            }
extern "C"
            void cleanup() {
            }

GetSecurityMembership takes the given user ID with a list of all the roles, the amount of roles in the array, and an array of all the results, as booleans.

Users must code their own implementation of populating the truthValue array with either true or false. The truthValue array has the same length as numRoles and is initialized. Do not modify any other variables.

Use the cleanup method to reset the shared library to an initialized state. This method resets all values and frees memory since the shared library is not closed until the class that is calling it is destructed.

Invoke Shared Library from MFS

The TablePermissions class opens and closes the shared library. During class initialization, the name of the shared library that is read from the mfs.conf file is passed to the constructor. The constructor loads the shared library into memory using the LoadSO method from filterutils.cc. The constructor also loads the GetSecurityMembership method with the cleanup method and are variables that can be called.

TablePermissions contains two methods that can be called to access the shared library:
  • The GetSecurityMembership method. This method takes three arguments: the user ID, the array of roles, and the amount of roles in the array. This method returns a RolePermission structure, which contains all the same data, as well as the boolean of the successful roles for that given user ID. To evaluate the user roles, pass this RolePermission structure to the TablePermission::checkTablePermissions method.
  • The cleanup method. This method calls the cleanup method in the shared library. This method takes no arguments.

The entity that allocates the RolePermission structure into memory also needs to deallocate this structure. Deallocating the TablePermissions class calls the cleanup method, and closes the shared library.

Shared Library Security

The /opt/mapr/server/permissions folder is initialized with 755 permissions. This implies that only the user who installed MapR has access to writing to that folder. These permissions prevent a user from replacing a shared library with a malicious file.

The m7_permissions_roles_refimpl.conf file has 755 permission. This permission allows only an administrator to make changes to the file.

The Roles Library Shared Object and ACEs

If you access an object that is secured by an Access Control Expression (ACE) , the MapR File System layer calls the roles library a shared object and checks the permissions of the entity requesting access against the contents of the roles file. The roles library shared object reads the roles file every 600 seconds. You can specify your own roles library shared object and specify the location of that object by using the mfs.dbroles.sopath parameter in the /opt/mapr/conf/mfs.conf file.