Crowd LDAP, group nesting and LDAP queries
Asked by Sys Admin:

Hi!

We're trying to use the underlying LDAP server used by our Crowd instance to manage access to 3rd party applications, but we are facing some strange behaviour.

We use Nested Groups in Crowd/LDAP to manage application access / JIRA Project /Confluence Space/ Bitbucket Repository permissions. Users belong to groups which belong to jira-users, confluence-users, stash-users and they have different permissions for each application.

As I can see with Apache Directory Studio, groups in LDAP are kind of "special users" with the attribute objectClass=groupOfUniqueNames, I think they should be in a different OU (groups) instead of OU=people and this is what is causing most headache.

I want to retrieve all users who belong into the group "internal" directly or by inheritance to allow access to a LDAP connected app, but I can't use the attribute memberOf=internal since it doesn't exist in any user.

User membership into a group if defined by a custom attribute in each group asset called "uniqueMember" which stores the cn of a user. Each group has as many "uniqueMember" attributes as users inside that group.

How can I retrieve only the users who belong into "internal" with a single query? I'm trying

\`(\&(objectClass=inetOrgPerson)(memberOf=cn=internal,ou=people,dc=company,dc=com))\`

Thanks!


Answers:
author: AnnWorley
body: It turned out that the question was not about using Crowd for the applications, it was regarding whether changing the OpenLDAP schema to accommodate other apps will break Crowd. The recommendation was to try on a test instance first to avoid surprises in Production.

If changing the OpenLDAP schema leaves the attributes in place that Crowd uses in the User Directory setup, then Crowd would not be negatively impacted; but a test instance is the best way to make sure the changes don't interfere with Crowd.


author: AnnWorley
body: Hello! I understand you want to use a nested group in LDAP to assign application access in Crowd, but first we have to sync over the members of that group. You didn't mention what LDAP directory service you are using but since Active Directory is the most common, I wanted to let you know about the nested group attribute that has to be added for AD. Please see: [How to write LDAP search filters](https://confluence.atlassian.com/kb/how-to-write-ldap-search-filters-792496933.html)

The example in the guide is:

```
(&(objectCategory=Person)(sAMAccountName=*)(memberOf:1.2.840.113556.1.4.1941:=cn=CaptainPlanet,ou=users,dc=company,dc=com))
```

For your filter it would be more like:

```
(&(objectClass=inetOrgPerson)(memberOf:1.2.840.113556.1.4.1941:=cn=internal,ou=people,dc=company,dc=com))
```

If you are not using Active Directory please let me know what LDAP you are using so I can research further.

comments: author: Sys Admin
body: Hi Ann,

we're using an underlying OpenLDAP server, the one bundled with Crowd.

I've already taken a look at that page, but we cannot use the "memberOf" attribute since it doesn't exist among the inetOrgPerson objects in the LDAP.

Our implementation has enabled the "nested groups" configuration of Crowd.


author: AnnWorley
body: I cannot find an OpenLDAP server bundled with Crowd, but I have heard of [OpenLDAP](http://www.openldap.org/). You are right that the memberOf attribute is not present by default in OpenLDAP. Without an equivalent attribute to search on we will not be able to filter users by group membership.

However, once the users are in Crowd, you can use the group to allow authentication to the specific application: [Specifying which Groups can access an Application](https://confluence.atlassian.com/crowd/specifying-which-groups-can-access-an-application-25788430.html)

I found instructions for adding memberOf to an OpenLDAP instance: [How to enable MemberOf using OpenLDAP](https://adimian.com/blog/2014/10/how-to-enable-memberof-using-openldap/)

A limitation I noticed is that it only applies the attribute when a new group is created, it wouldn't apply to your existing groups. Depending on how many groups you need the attribute for, that could be a lot of trouble or just recreating a couple of groups.


author: Sys Admin
body: We used to have this memberOf setting but we have to disable it to enable nested groups in Atlassian applications. I'm afraid if we enable it again we will lose access to Jira, Confluence, Bitbucket and others. Isn't there any other solution to retrieve all members (direct and inherited) of a group (objectClass=groupOfUniqueNames) ?


author: AnnWorley
body: I would like to re-state the issue to make sure we are on the same page. You need to use the group Internal to assign application access in Crowd. You are working on a user filter to limit the LDAP sync to members of that group.

Perhaps we should define the LDAP search more broadly, so the group and it's members are pulled into Crowd, along with some users that are not in the group necessarily. Then we could use the group for application access within Crowd.

Please let me know if I am missing something.


author: Sys Admin
body: Hi Ann,

I'll try to explain myself better, you're being very helpful and I'm sure we'll get to a solution if I can state the current issue properly.

We have a crowd server instance, relying on OpenLDAP as directory. We use that Crowd to manage login / access level to other Atlassian tools (JIRA, Confluence, Bitbucket) and some 3rd Party tools with Crowd plugin.

We enabled nested groups in Crowd ( <https://confluence.atlassian.com/crowd/nested-groups-in-crowd-153749260.html> ) and we created a hierarchy based on roles. E.e:

* **internal** (group)
  * **internal-marketing** (group inside internal)
    * **user1** (user in internal-marketing)
  * **internal-hr** (group inside internal)
    * **user2** (user inside internal-hr)
* **external** (group)
  * **external-collaborators**
    * **user3** (user in external-collaborators)

In this way we can control user access and access level by groups, for example **internal** belongs to **jira-users** and **confluence-users** so every user inside **internal** group or its sub-groups has access to JIRA and Confluence, but not those on the **external** group or sub-groups.

This Crowd configuration changes the LDAP behaviour and ignores the **memberOf** attribute. All users we have created using Crowd interface lack this attribute. The organization is managed in another way:

* All objects (groups or users, we just have those 2 types) belong to ou=people,dc=domain,dc=com
* User objects have the attribute (objectClass=inetOrgPerson)
* Group objects have the attribute (objectClass=groupOfUniqueNames) and as many **uniqueMember** attributes as users/groups belong to it. For example, the group **internal** has these attributes:  
  * **o** **bjectClass**='groupOfUniqueNames'
  * **uniqueMember**='cn=internal-marketing,ou=people,dc=domain,dc=com'
  * **uniqueMember**='cn=internal-hr,ou=people,dc=domain,dc=com'

Now we have a problem with 3rd party applications which cannot be connected to Crowd Rest API, but they can be configured to use OpenLDAP.

One possibility is to revert OpenLDAP configuration to use the memberOf attribute, but I'm afraid we could break Crowd's configuration and lose access to applications

So, I'm trying to keep everything as it is, and find a way to configure those 3rd party applications to do pretty much the same as we're doing with Atlassian ones: grant access **only** to members of the group **internal** or its sub-groups.


author: AnnWorley
body: I created a support ticket using your email address - you should be getting an email soon asking for logs and a Directory Configuration Summary.

When the issue is resolved I can circle back and let the Community know our findings.


author: Sys Admin
body: I answered the ticket and attached requested information.

Thanks Ann.


Tags: ldap

user