Massaging the behavior of LDAP-Group caching?

Braden McGrath braden at
Thu Apr 8 01:52:28 CEST 2021

I had one very minor thing I ran across during troubleshooting that
hopefully someone can answer, but after that question I'm going to
provide my results of a deeper dive and "final solutions" for the list

When membership_attribute is set, and cacheable_name = yes, the ldap
module pops this message in debug output during an access-request:
ldap: Adding cacheable user object memberships
ldap:    &control:LDAP-Group += "foo"
  [etc, one line per group]
ldap: Skipping caching group objects as directive
'group.membership_filter' is not set

But later, when actually running an unlang compare against
&LDAP-Group[*],  FR says:
User found. Matched cached membership

The comments in the ldap config imply that membership_filter and
membership_attribute aren't normally used simultaneously. :)
I wasn't seeing additional queries during the actual unlang
comparison, so I trust the message that it "Matched cached
membership," but that leaves me confused about what "skipping caching
group objects as directive 'group.membership_filter' is not set"

Anyway, here's my attempt at "Wisdom of the Ancients" (see, in case anybody else is trying to tie
FreeRADIUS to FreeIPA / 389DS...
On Fri, Apr 2, 2021 at 7:08 AM Alan DeKok <aland at> wrote:
> On Apr 1, 2021, at 7:48 PM, Braden McGrath <braden at> wrote:
> > I was thinking the same way... I suspect it's something LDAP
> > permissions-related, where those groups are only used internally by
> > FreeIPA. If they are "internal," presumably 389DS (the underlying LDAP
> > server for FreeIPA) doesn't normally expect a "user" (or even a
> > "service" account, which is what my FR server is using) to query for
> > details on those groups, hence it is denying access. I need to go play
> > with ldapsearch to confirm that.
>   Then 389DS shouldn't be returning them.  :(

FreeIPA / 389DS returns the "unfiltered" contents of a DN's "memberOf"
attribute, even if the LDAP bind account in use doesn't have the
ability to directly access each of the individual DNs listed in that
In other words, it will *return* the list of everything a user is a
"memberOf," but it won't necessarily allow you to pull more details
about each of those DNs (like the friendly name). I don't know enough
about LDAP to know if this is "correct" behavior for the memberOf
attribute or not, but it's how 389DS seems to work. :)

By default, an account able to bind to a FreeIPA server *can* pull all
of the groups and users out of the "cn=accounts,dn=example,dn=org"
tree. But, FreeIPA uses other sub-trees (cn=pbac and cn=hbac and
probably a few more) in order to store its own permissions and other
Magic, and a typical bind account with no extra privileges does _not_
have the ability to read those other sub-trees and return the actual
names of the groups. A test with ldapsearch will get you a result of
"0 Success" with a "numResponses: 1" but no actual LDAP Entries (i.e.
no usable data) in the response.

FR will Have A Bad Time if it attempts to query those permission
groups for short names and gets blank stares from FreeIPA/389DS LDAP
server. So, you need to be able to read them *if* you are using
friendly/short name matches. (You can ignore all of this if you match
on the full DN, because FR doesn't waste its time trying to turn the
contents in memberOf into friendly names if it seems like you're doing
a full DN match.)

Long story short, as long as you don't mind the bind account you're
using having *read* access to the names and other details of those
FreeIPA permissions / etc, you can add a "Role" of your own naming in
FreeIPA, grant it the permission "RBAC Readers" (this is a predefined
permission in FreeIPA), and then assign that role to your LDAP bind
account(s). The bind account will then be able to read all of the
names on these otherwise "hidden" permission groups, and things should
work. ;)

If you don't want the bind account to have permissions to read
about... permissions, the other option is to comment out
membership_attribute and use membership_filter *instead*. In this
case, FR walks through the group tree, and checks to make sure the
user is in each of the groups. In many cases this is probably slower.
However, if the user has a lot of these hidden FreeIPA permission
groups (which are not part of the normal user-defined groups
container/tree, and hence wouldn't be walked when using
membership_attribute), and you do _not_ have many user-created groups,
the membership_filter may actually have *fewer* LDAP queries involved.

Personally, I'm just leaving my config with full DN matches, but I
also granted the above role on the bind account in case I ever need to
move to friendly name matches in the future.
Good luck!

More information about the Freeradius-Users mailing list