Nested LDAP groups

We are using LDAP for authentication. We’ve found that Dremio does not support nested groups. If we add an LDAP group to Dremio, users in child groups of that parent group are not automatically granted access – we have to add the child groups along with the parents.

Is there any way to avoid having to add all groups? Can Dremio recognize nested groups in LDAP?

@Joe, are these users not able to login to Dremio or are they able to login but their group membership is not recognized? There are 2 different components to the LDAP config file Dremio uses that deal with this.

Also, what LDAP implementation are you using. Active Directory?

Hi, Ben.

They are able to log in – we have logins enabled for the entire domain. But they are not able to see spaces/sources that have been shared to parent LDAP groups.

Yes, it’s AD.

Any chance you can share the LDAP config file? ad.json

Sure, sensitive info removed:

{
    "connectionMode": "PLAIN",
    "servers": [
        {
            "hostname": "xxx",
            "port":  nnn
        }
    ],
    "names": {
        "bindDN": "CN=xx,OU=xxx,DC=xx,DC=xx",
        "bindPassword": "xxx",
        "baseDN": "DC=xxx,DC=xxx",
        "userFilter": "&(objectClass=user)",
        "userAttributes": {
            "baseDNs": [
                "DC=xxx,DC=xxx",
                "DC=xxx,DC=xxx"
            ],
            "searchScope": "SUB_TREE",
            "id": "sAMAccountName",
            "firstname": "givenName",
            "lastname": "sn",
            "email": "mail"
        },
        "groupMembership": "memberOf",
        "groupRecursive": "transitive-memberOf",
        "groupAttributes" : {
            "baseDNs": ["ou=groups,dc=xxx,dc=xxx",
                        "ou=Roles,ou=xxx,dc=xxx,dc=xxx",
                        "ou=groups,dc=xxx,dc=xxx",
                        "ou=Roles,ou=xxx,dc=ad2,dc=xxx"
                        ],
            "searchScope": "SUB_TREE",
            "id": "CN"
        },

        "groupFilter": "objectclass=group",
        "autoAdminFirstUser": true
    }
}

@Joe,

Try removing the "groupRecursive": "transitive-memberOf" completely. You’ll have to restart Dremio for the change to take effect.

If that works, then you might also try adding in "groupRecursive": "msds-memberOfTransitive" to see if it produces the same results and is faster. Again, you will have to restart Dremio for that change to take effect.

Thanks, Ben! Removing groupRecursive does appear to do it. Are there any other implications of making this change?

I tried adding it back with with msds-memberOfTransitive, but then I was unable to even log in.

Dremio will recursively look up each group a user is a member of, but this can be expensive.

Some LDAP implementations have a property that can be part of a user or group object that provides the pre-computed result of this lookup. If you know the name of that property, you can provide it as the value of “groupRecursive” in Dremio’s ad.json configuration file.

For Active Directory, it may be “msds-memberOfTransitive”. This works in my test AD server. You may have a different property.

It appears that by supplying the example property we show in our docs - “transitive-memberOf” - Dremio neglects to do the recursive lookup, probably because it expects to find that property and use it to determine group membership. Instead it just looks at the immediate “memberOf” groups for a user without going any deeper, which explains the behavior you saw before making the change I suggested.

Dremio should add a note to the docs (or change the behavior) because it can lead to misconfiguration.

As for you not being able to log in, that seems odd, because you don’t have any user filter that would check the group membership. You were not able to login, or the Dremio UI did not come up at all? You can check the server.log on the coordinator node for errors on startup about this.

@Joe, the upshot of all this is the that if you can’t find the exact groupRecursive field in your implementation, just leave it out and Dremio will do the recursive lookup.

When I enabled the msds-memberOfTransitive property, I get this error in the log upon logon:
    2020-09-22 20:49:13,401 [qtp901224896-164] DEBUG c.d.extusr.ExternalUserGroupService - Fail to load user: xxx
    java.util.concurrent.CompletionException: LDAPException(resultCode=1 (operations error), numEntries=0, numReferences=0, diagnosticMessage='00002120: SvcErr: DSID-03120451, problem 5012 (DIR_ERROR), data 592060
    ^@', ldapSDKVersion=4.0.9, revision=29290')

My brief research into the error found that this attribute can’t be used in a subtree search. So I changed saerchScope to “ONE”. But then I get:

2020-09-22 20:45:41,672 [qtp979841724-162] DEBUG c.d.extusr.ldap.LdapUserProvider - Looking up user using filter [(&(sAMAccountName=xxx)(&(objectClass=user)))] with base [DC=xxx,DC=xxx] and scope [ONE] took 30 ms
2020-09-22 20:45:41,689 [qtp979841724-162] DEBUG c.d.extusr.ldap.LdapUserProvider - Looking up user using filter [(&(sAMAccountName=xxx)(&(objectClass=user)))] with base [DC=xxx,DC=xxx] and scope [ONE] took 17 ms
2020-09-22 20:45:41,689 [qtp979841724-162] DEBUG c.d.extusr.ldap.LdapUserProvider - Username 'xxx' not found. This should not fail (typically)
2020-09-22 20:45:41,690 [qtp979841724-162] DEBUG c.d.extusr.ExternalUserGroupService - Fail to load user: xxx
java.util.concurrent.CompletionException: LDAPException(resultCode=94 (no results returned), numEntries=0, numReferences=0, errorMessage='no entries matched (expected one)', ldapSDKVersion=4.0.9, revision=29290')

I am guessing this error is because I’m not specifying the complete path to the user account.

Maybe we can just delete the groupRecursive attribute and use the default behavior? Is there any way to check if this would cause delays?

You can add these loggers to Dremio’s logback.xml to observe how long the initial lookup takes:

<logger name="com.dremio.extusr.ldap.LdapUserProvider">
<level value="debug"/>
</logger>

<logger name="com.dremio.extusr.ExternalUserGroupService">
<level value="debug"/>
</logger>

These will be cached for 24 hours

Perfect - thanks agian.