Wrong roles (nsrole) management in Kolab WAP
Open, Needs TriagePublic

Description

By default Kolab is using 389 Directory Server as LDAP server. Besides regular group management this server supports roles as an alternative group management. There are 3 types of roles:

  • Managed role
  • Filtered role
  • Nested role

Managed role is the only type supported by Kolab WAP. A user can be assigned to a Managed role by adding nsroledn attribute to users. A user is a member of Filtered role if the user can be found with filter defined in role's definition with attribute nsRoleFilter. Nested roles are roles in role. So in case of Filtered and Nested roles no changes to user object are required to assign user to the role as opposed to Managed role. In Kolab WAP user can be assigned to the role by edditing roles attribute in System tab.
The list of available roles in Kolab WAP is created with this piece of code in ./lib/Auth/LDAP.php:

706-    public function list_roles($attributes = array(), $search = array(), $params = array())
707-    {
708-        $this->_log(LOG_DEBUG, "Auth::LDAP::list_roles(" . var_export($attributes, true) . ", " . var_export($search, true) . ", " . var_export($params, true));
709-
710-        $base_dn = $this->_subject_base_dn('role');
711-        $filter  = $this->conf->get('role_filter');
712-
713-        if (empty($filter)) {
714:            $filter  = "(&(objectclass=ldapsubentry)(objectclass=nsroledefinition))";
715-        }
716-
717-        return $this->_list($base_dn, $filter, 'sub', $attributes, $search, $params);
718-    }

The filter to find available roles is "(&(objectclass=ldapsubentry)(objectclass=nsroledefinition))". This filter finds all types of roles and creates an impression that user can be assigned to any of those roles. That is not correct.

The filter should be:

(&(objectclass=ldapsubentry)(objectclass=nsManagedRoleDefinition))

That should list only Managed roles, the ones which user can be assigned by adding nsroledn attribute to user's object.
I think that is a minimal change we need to do to Kolab WAP.
I've noticed that analysing how 389 Directory Server manages user locking (account locking). The wrong filter creates a confusion and allows Kolab admins to do wrong things in LDAP server, thinking they have locked the account while they did not.

The next change I'd like to propose in this regard is to create separate list of roles user belongs. One list of roles should be Managed roles, the other is Filtered and Nested roles user belongs to. Managed roles list should be modifiable, while list of Filtered and Nested roles should be read-only. That should make Kolab Web Admin panel to better represent actual LDAP database and admins in large organizations should benefit from that.
To distinguish roles a comparison between nsrole and nsroledn attributes should be made. For example result of ldap query fetching user's nsrole and nsroledn attributes could look like:

dn: uid=user1,ou=People,dc=example,dc=org
nsrole: cn=role1,dc=example,dc=org
nsrole: cn=role2,dc=example,dc=org
nsrole: cn=role3,dc=example,dc=org
nsroledn: cn=role1,dc=example,dc=org

User's role membership can be determined only by using nsrole attribute values, however to distiguish which roles are managed and which are not nsroledn attribute can be used. In this example there is only one nsroledn attribute present and nsroledn attribute's value is equal to one value of nsrole attribute. That means that only role cn=role1,dc=example,dc=org membership can be managed by directly modifying user dn: uid=user1,ou=People,dc=example,dc=org (in other words this is Managed role Kolab WAP supports), other roles membership is indirect and can be managed in role's definition not in user and Kolab WAP does not support, so these roles should be listed as read-only.

Kolab WAP version:
kolab-webadmin-3.2.12-2.1.el7.kolab_16.noarch

Details

Ticket Type
Task
adomaitis created this task.Thu, Jan 3, 6:06 PM

I guess, we could change the roles filter to fix the immediate issue, but if we want to display non-managed roles we'll need possibility to list both types of roles, i.e. the filter would depend on what we want to achieve at the moment.

Right, the complete fix might be very complicated because:

  • we need different filters to list all roles, just non-managed roles or managed roles.

the alternative filters could be:
'(&(objectclass=ldapsubentry)(objectclass=nsComplexRoleDefinition))' - list all non-managed roles
'(&(objectclass=ldapsubentry)(objectclass=nsSimpleRoleDefinition))' - list all manged roles
'(&(objectclass=ldapsubentry)(objectclass=nsRoleDefinition))' - list all roles

  • we need a separate code to implement user's roles listing (including editing managed roles). Currently, by default, Kolab User has a nsroledn attribute defined in WAP Settings. That implies that LDAP roles manaement follows logic of getting and changing regular multivalue LDAP attributes, but roles does not work like that. To set a role you need to add or remove nsroledn attribute, but checking role membership nsrole attribute should be used.