LDAP groups and how to filter

classic Classic list List threaded Threaded
12 messages Options
| Threaded
Open this post in threaded view
|

LDAP groups and how to filter

Daniel Oakes
Hi there,

I've got FreeRadius working off a FreeIPA backend to try and sort some issues with a firewall that won't filter on LDAP groups correctly.

I've got my queries working, but now want to use post-auth to update a Group Name that the firewall will expect.  

Just wondering how in debug mode I could print out to debug all the groups that the user is a memberOf so I can write that logic.  Sorry if this has been answered previously, I've not found an example, and I'm not much of an LDAP person.

Cheers,
Daniel


-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
| Threaded
Open this post in threaded view
|

Re: LDAP groups and how to filter

Alan DeKok-2
On Feb 10, 2020, at 5:23 PM, Daniel Oakes <[hidden email]> wrote:
>
> I've got FreeRadius working off a FreeIPA backend to try and sort some issues with a firewall that won't filter on LDAP groups correctly.

  Firewalls typically don't do LDAP group checking.  So what exactly are you trying to do?

> I've got my queries working, but now want to use post-auth to update a Group Name that the firewall will expect.  

  Does the firewall documentation say that it expects a group name?  If so, which attribute?

  You can't just send attributes in an Access-Accept and have the firewall "do the right thing".  RADIUS doesn't work like that.  Attributes have pre-defined meaning.  If the firewall doesn't already know about an attribute, then it doesn't know what to do when it sees the attribute.

> Just wondering how in debug mode I could print out to debug all the groups that the user is a memberOf so I can write that logic.  Sorry if this has been answered previously, I've not found an example, and I'm not much of an LDAP person.

  What *what* logic to do *what*?  Please be specific.

  Vague questions get vague answers.  Detailed questions get detailed answers.

  Alan DeKok.


-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
| Threaded
Open this post in threaded view
|

Re: LDAP groups and how to filter

Daniel Oakes
I actually thought this was framed reasonably well, but okay more specifics.

It’s a fortigate – so I want to use Fortinet-Group-Name in post-auth.

I would like to get all the groups that the user is a member of from LDAP, and I’m just going to use a very simple if statement in post-auth I know the syntax is wrong, just example) :

if (LDAP-Group == "LDAP Group One") {
        update reply FG group1
if (LDAP-Group == "LDAP Group Two") {
        update reply FG group 2

And update the reply with the Fortinet-Group-Name.

What I don't understand how to do, is to do the ldap bit for the groups so that it shows in the FreeRadius debug (using radiusd -X).  I want to see all the groups they may be a member of, so I can develop the logic further.

Excuse me if this is the wrong way to go about it - I'm happy to go away and learn ldap, but thought there might be some gems that others have done previously.

Regards,
Daniel



From: Freeradius-Users <freeradius-users-bounces+daniel=[hidden email]>
Date: Tuesday, 11 February 2020 at 2:19 PM
To: FreeRadius users mailing list <[hidden email]>
Subject: Re: LDAP groups and how to filter
On Feb 10, 2020, at 5:23 PM, Daniel Oakes <[hidden email]> wrote:
>
> I've got FreeRadius working off a FreeIPA backend to try and sort some issues with a firewall that won't filter on LDAP groups correctly.

  Firewalls typically don't do LDAP group checking.  So what exactly are you trying to do?

> I've got my queries working, but now want to use post-auth to update a Group Name that the firewall will expect. 

  Does the firewall documentation say that it expects a group name?  If so, which attribute?

  You can't just send attributes in an Access-Accept and have the firewall "do the right thing".  RADIUS doesn't work like that.  Attributes have pre-defined meaning.  If the firewall doesn't already know about an attribute, then it doesn't know what to do when it sees the attribute.

> Just wondering how in debug mode I could print out to debug all the groups that the user is a memberOf so I can write that logic.  Sorry if this has been answered previously, I've not found an example, and I'm not much of an LDAP person.

  What *what* logic to do *what*?  Please be specific.

  Vague questions get vague answers.  Detailed questions get detailed answers.

  Alan DeKok.


-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html

-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
| Threaded
Open this post in threaded view
|

Re: LDAP groups and how to filter

Alan DeKok-2
On Feb 10, 2020, at 8:56 PM, Daniel Oakes <[hidden email]> wrote:
>
> I actually thought this was framed reasonably well, but okay more specifics.

  It was a solution in search of an answer.  I need to understand the problem.  That way you get the best solution.  The alternative is to give you an answer which did what you asked, but not what you wanted.

> It’s a fortigate – so I want to use Fortinet-Group-Name in post-auth.
>
> I would like to get all the groups that the user is a member of from LDAP, and I’m just going to use a very simple if statement in post-auth I know the syntax is wrong, just example) :
>
> if (LDAP-Group == "LDAP Group One") {
> update reply FG group1
> if (LDAP-Group == "LDAP Group Two") {
> update reply FG group 2
>
> And update the reply with the Fortinet-Group-Name.

  Sure.

> What I don't understand how to do, is to do the ldap bit for the groups so that it shows in the FreeRadius debug (using radiusd -X).  I want to see all the groups they may be a member of, so I can develop the logic further.

  FreeRADIUS isn't for LDAP debugging.  The LDAP server may return dozens, if not hundreds of groups.  FreeRADIUS won't print them all out.

  It *does* print out the LDAP queries it's using.  So you can take those queries, and use "ldapsearch" to run the search yourself, and then get the complete answer.

  Alan DeKok.


-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
| Threaded
Open this post in threaded view
|

Re: LDAP groups and how to filter

uj2.hahn
In reply to this post by Daniel Oakes
Hi, Daniel!
I think I understand what you want to achieve. Recently I implemented
something similar. Propably not the same
but maybe I can give you an idea :
Problem: Users in a school can be in more than one LDAP group (e.g. in
"student" group but in "blocked" group as well).
The default code in LDAP module get these groups and write them into
attribute LDAP-Group. Note this is not a simple scalar variable
but a list (or you can see it as stack). When you write  if (LDAP-Group
== "LDAP Group One") , than you compare the top element of LDAP-Group
only.
When you use LDAP-Group[*] instead you get ALL groups, concatenated into
a string.
So please see my code in post-auth section (sorry, comments are in
German):

if ("%{control:LDAP-Group[*]}" =~ /gesperrt/) {
         update reply {
                         Reply-Message := "Nutzer ist gesperrt!"
                        }
        reject
}
if ("%{control:LDAP-Group[*]}" =~ /schueler/) {
        if (Current-Time !=
"%{%{ldap:ldap:///cn=schueler,ou=groups,dc=kms,dc=de?radiusLoginTime}:-Any}")
{
           update reply {
                         Reply-Message := "Außerhalb der erlaubten
Zeit!"
                        }
           reject
        }
}
elsif ("%{control:LDAP-Group[*]}" =~ /lehrer/) {
        if (Current-Time !=
"%{%{ldap:ldap:///cn=lehrer,ou=groups,dc=kms,dc=de?radiusLoginTime}:-Any}")
{
           update reply {
                         Reply-Message := "Außerhalb der erlaubten
Zeit!"
                        }
           reject
        }
}
elsif ("%{control:LDAP-Group[*]}" =~ /gast/) {
        if (Current-Time !=
"%{%{ldap:ldap:///cn=gast,ou=groups,dc=kms,dc=de?radiusLoginTime}:-Any}")
{
           update reply {
                         Reply-Message := "Außerhalb der erlaubten
Zeit!"
                        }
           reject
        }
}
elsif (&User-Name == "RadiusClient") {
        noop
}
else {
          update reply {
                         Reply-Message := "Nutzer muss einer Gruppe
angehören (lehrer oder schueler oder gast)"
                        }
          reject

}


For debug purpose you can temporary use the Reply-Message to output all
groups:

         update reply {
                         Reply-Message := "%{control:LDAP-Group[*]}"
                        }


Does this help?

Regards
Uwe

Am 11.02.2020 02:56 schrieb Daniel Oakes:

> I actually thought this was framed reasonably well, but okay more
> specifics.
>
> It’s a fortigate – so I want to use Fortinet-Group-Name in post-auth.
>
> I would like to get all the groups that the user is a member of from
> LDAP, and I’m just going to use a very simple if statement in
> post-auth I know the syntax is wrong, just example) :
>
> if (LDAP-Group == "LDAP Group One") {
> update reply FG group1
> if (LDAP-Group == "LDAP Group Two") {
> update reply FG group 2
>
> And update the reply with the Fortinet-Group-Name.
>
> What I don't understand how to do, is to do the ldap bit for the
> groups so that it shows in the FreeRadius debug (using radiusd -X).  I
> want to see all the groups they may be a member of, so I can develop
> the logic further.
>
> Excuse me if this is the wrong way to go about it - I'm happy to go
> away and learn ldap, but thought there might be some gems that others
> have done previously.
>
> Regards,
> Daniel
>
>
>
> From: Freeradius-Users
> <freeradius-users-bounces+daniel=[hidden email]>
> Date: Tuesday, 11 February 2020 at 2:19 PM
> To: FreeRadius users mailing list
> <[hidden email]>
> Subject: Re: LDAP groups and how to filter
> On Feb 10, 2020, at 5:23 PM, Daniel Oakes <[hidden email]> wrote:
>>
>> I've got FreeRadius working off a FreeIPA backend to try and sort some
>> issues with a firewall that won't filter on LDAP groups correctly.
>
>   Firewalls typically don't do LDAP group checking.  So what exactly
> are you trying to do?
>
>> I've got my queries working, but now want to use post-auth to update a
>> Group Name that the firewall will expect. 
>
>   Does the firewall documentation say that it expects a group name? 
> If so, which attribute?
>
>   You can't just send attributes in an Access-Accept and have the
> firewall "do the right thing".  RADIUS doesn't work like that. 
> Attributes have pre-defined meaning.  If the firewall doesn't already
> know about an attribute, then it doesn't know what to do when it sees
> the attribute.
>
>> Just wondering how in debug mode I could print out to debug all the
>> groups that the user is a memberOf so I can write that logic.  Sorry
>> if this has been answered previously, I've not found an example, and
>> I'm not much of an LDAP person.
>
>   What *what* logic to do *what*?  Please be specific.
>
>   Vague questions get vague answers.  Detailed questions get detailed
> answers.
>
>   Alan DeKok.
>
>
> -
> List info/subscribe/unsubscribe? See
> http://www.freeradius.org/list/users.html
>
> -
> List info/subscribe/unsubscribe? See
> http://www.freeradius.org/list/users.html

-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
| Threaded
Open this post in threaded view
|

Re: LDAP groups and how to filter

Daniel Oakes
Thanks that definitely got me a lot closer – but for some reason I’m not getting an expansion of the groups, so suspect that it’s probably something to do with the bind user:

0)   post-auth {
(0)     if ("%{control:LDAP-Group[*]}" =~ /operations/) {
(0)     EXPAND %{control:LDAP-Group[*]}
(0)        -->
(0)     if ("%{control:LDAP-Group[*]}" =~ /operations/)  -> FALSE
(0)     update {
(0)       No attributes updated
(0)     } # update = noop

And if I put the debug version, printing out all the groups I’m seeing nothing.

Suspect it’s all purely the LDAP config at this point, but authentication is working.

Cheers,
Daniel


From: [hidden email] <[hidden email]>
Date: Wednesday, 12 February 2020 at 9:07 AM
To: FreeRadius users mailing list <[hidden email]>
Cc: Freeradius-Users <freeradius-users-bounces+uj2.hahn=[hidden email]>, Daniel Oakes <[hidden email]>
Subject: Re: LDAP groups and how to filter
Hi, Daniel!
I think I understand what you want to achieve. Recently I implemented
something similar. Propably not the same
but maybe I can give you an idea :
Problem: Users in a school can be in more than one LDAP group (e.g. in
"student" group but in "blocked" group as well).
The default code in LDAP module get these groups and write them into
attribute LDAP-Group. Note this is not a simple scalar variable
but a list (or you can see it as stack). When you write  if (LDAP-Group
== "LDAP Group One") , than you compare the top element of LDAP-Group
only.
When you use LDAP-Group[*] instead you get ALL groups, concatenated into
a string.
So please see my code in post-auth section (sorry, comments are in
German):

if ("%{control:LDAP-Group[*]}" =~ /gesperrt/) {
         update reply {
                         Reply-Message := "Nutzer ist gesperrt!"
                        }
        reject
}
if ("%{control:LDAP-Group[*]}" =~ /schueler/) {
        if (Current-Time !=
"%{%{ldap:ldap:///cn=schueler,ou=groups,dc=kms,dc=de?radiusLoginTime}:-Any}")
{
           update reply {
                         Reply-Message := "Außerhalb der erlaubten
Zeit!"
                        }
           reject
        }
}
elsif ("%{control:LDAP-Group[*]}" =~ /lehrer/) {
        if (Current-Time !=
"%{%{ldap:ldap:///cn=lehrer,ou=groups,dc=kms,dc=de?radiusLoginTime}:-Any}")
{
           update reply {
                         Reply-Message := "Außerhalb der erlaubten
Zeit!"
                        }
           reject
        }
}
elsif ("%{control:LDAP-Group[*]}" =~ /gast/) {
        if (Current-Time !=
"%{%{ldap:ldap:///cn=gast,ou=groups,dc=kms,dc=de?radiusLoginTime}:-Any}")
{
           update reply {
                         Reply-Message := "Außerhalb der erlaubten
Zeit!"
                        }
           reject
        }
}
elsif (&User-Name == "RadiusClient") {
        noop
}
else {
          update reply {
                         Reply-Message := "Nutzer muss einer Gruppe
angehören (lehrer oder schueler oder gast)"
                        }
          reject

}


For debug purpose you can temporary use the Reply-Message to output all
groups:

         update reply {
                         Reply-Message := "%{control:LDAP-Group[*]}"
                        }


Does this help?

Regards
Uwe

Am 11.02.2020 02:56 schrieb Daniel Oakes:

> I actually thought this was framed reasonably well, but okay more
> specifics.
>
> It’s a fortigate – so I want to use Fortinet-Group-Name in post-auth.
>
> I would like to get all the groups that the user is a member of from
> LDAP, and I’m just going to use a very simple if statement in
> post-auth I know the syntax is wrong, just example) :
>
> if (LDAP-Group == "LDAP Group One") {
>        update reply FG group1
> if (LDAP-Group == "LDAP Group Two") {
>        update reply FG group 2
>
> And update the reply with the Fortinet-Group-Name.
>
> What I don't understand how to do, is to do the ldap bit for the
> groups so that it shows in the FreeRadius debug (using radiusd -X).  I
> want to see all the groups they may be a member of, so I can develop
> the logic further.
>
> Excuse me if this is the wrong way to go about it - I'm happy to go
> away and learn ldap, but thought there might be some gems that others
> have done previously.
>
> Regards,
> Daniel
>
>
>
> From: Freeradius-Users
> <freeradius-users-bounces+daniel=[hidden email]>
> Date: Tuesday, 11 February 2020 at 2:19 PM
> To: FreeRadius users mailing list
> <[hidden email]>
> Subject: Re: LDAP groups and how to filter
> On Feb 10, 2020, at 5:23 PM, Daniel Oakes <[hidden email]> wrote:
>>
>> I've got FreeRadius working off a FreeIPA backend to try and sort some
>> issues with a firewall that won't filter on LDAP groups correctly.
>
>   Firewalls typically don't do LDAP group checking.  So what exactly
> are you trying to do?
>
>> I've got my queries working, but now want to use post-auth to update a
>> Group Name that the firewall will expect.
>
>   Does the firewall documentation say that it expects a group name?
> If so, which attribute?
>
>   You can't just send attributes in an Access-Accept and have the
> firewall "do the right thing".  RADIUS doesn't work like that.
> Attributes have pre-defined meaning.  If the firewall doesn't already
> know about an attribute, then it doesn't know what to do when it sees
> the attribute.
>
>> Just wondering how in debug mode I could print out to debug all the
>> groups that the user is a memberOf so I can write that logic.  Sorry
>> if this has been answered previously, I've not found an example, and
>> I'm not much of an LDAP person.
>
>   What *what* logic to do *what*?  Please be specific.
>
>   Vague questions get vague answers.  Detailed questions get detailed
> answers.
>
>   Alan DeKok.
>
>
> -
> List info/subscribe/unsubscribe? See
> http://www.freeradius.org/list/users.html
>
> -
> List info/subscribe/unsubscribe? See
> http://www.freeradius.org/list/users.html
-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
| Threaded
Open this post in threaded view
|

Re: LDAP groups and how to filter

Matthew Newton-3
On Tue, 2020-02-11 at 23:53 +0000, Daniel Oakes wrote:
> Thanks that definitely got me a lot closer – but for some reason I’m
> not getting an expansion of the groups, so suspect that it’s probably
> something to do with the bind user:

Don't try and enumerate all the groups in FreeRADIUS. Configure the
LDAP module correctly and then use unlang to check groups, similar to
how you posted earlier.

if (LDAP-Group == "LDAP Group One") {
        update reply {
                Fortinet-Group-Name := 'group1'
        }
}
elsif (LDAP-Group == "LDAP Group Two") {
        update reply {
                Fortinet-Group-Name := 'group2'
        }
}
elsif
(....) {
}

There are two ways you can check LDAP group membership. Most efficient
is normally to use the "memberOf" attribute, see "membership_attribute"
in mods-available/ldap. This is a virtual attribute maintained by the
LDAP server for each entry with a list of all the groups that entry is
a member of. Not all LDAP servers provide it, or it might not be
enabled.

The alternative is to use a filter and look for all groups that contain
"member={search DN}". This may be slower, but should be supported on
all LDAP servers. See "membership_filter" in the ldap config.

In both cases, you need server permission to be able to either read all
relevant groups (membership_filter), or the memberOf attribute
(membership_attribute).

So, like Alan said, use `ldapsearch` to do the search to check that
FreeRADIUS can get the result, then configure the group member options
in LDAP as required and use the special LDAP-Group attribute above to
do the checking. Don't try and enumerate group memberships in unlang,
the module does the checking for you. Using &LDAP-Group[*] is likely
the wrong approach.

There's a lot more at https://wiki.freeradius.org/modules/Rlm_ldap

--
Matthew


-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
| Threaded
Open this post in threaded view
|

Re: LDAP groups and how to filter

uj2.hahn
I was going to explain something similar but Matthew was much faster.
In addition: You should definitely use ldapsearch on Linux command line
first to find the right
ldap module configuration. Because this has to match your ldap server
structure (did you mention what that
is? AD or OpenLDAP or what?).
ldapsearch is much easier for debugging.
In case you are not so familiar I give you an example:

Matthew described the two ways of getting group ownership.
The memberOf method would (in my case, you have to check for yours!)
translate into the following
ldap query on Ubuntu commandline:

> ldapsearch -D "cn=<queryUser>,dc=kms,dc=de" -w <queryUserPasswd> -h
> LDAPserver -s sub "(objectclass=posixAccount)" -b
> "uid=uhahn,ou=people,dc=kms,dc=de" memberOf

Result is:

# extended LDIF
#
# LDAPv3
# base <uid=uhahn,ou=people,dc=kms,dc=de> with scope subtree
# filter: (objectclass=posixAccount)
# requesting: memberOf
#

# uhahn, people, kms.de
dn: uid=uhahn,ou=people,dc=kms,dc=de
memberOf: cn=lehrer,ou=groups,dc=kms,dc=de
memberOf: cn=gast,ou=groups,dc=kms,dc=de

# search result
search: 2
result: 0 Success

Note: Result are two memberOf: lines, i.e. user uhahn belongs to two
groups: lehrer and gast.
This is the most efficient way because you have to check this one user
only for his memberOf attribute.
---------------------------------
The other method without memberOf is to check ALL groups to see if the
user is part of it, i.e. if this name is part
of the member attribute of the group.

The ldapsearch command is:

> ldapsearch -D "cn=<queryUser>,dc=kms,dc=de" -w <queryUserPasswd> -h
> LDAPserver -s sub
> "(&(member="uid=uhahn,ou=people,dc=kms,dc=de")(objectClass=groupOfNames))"
> -b "ou=groups,dc=kms,dc=de" cn

Result is:

  extended LDIF
#
# LDAPv3
# base <ou=groups,dc=kms,dc=de> with scope subtree
# filter:
(&(member=uid=uhahn,ou=people,dc=kms,dc=de)(objectClass=groupOfNames))
# requesting: cn
#

# lehrer, groups, kms.de
dn: cn=lehrer,ou=groups,dc=kms,dc=de
cn: lehrer

# gast, groups, kms.de
dn: cn=gast,ou=groups,dc=kms,dc=de
cn: gast

# search result
search: 2
result: 0 Success


You get the same result: User uhahn belongs to two groups: lehrer and
gast.
So:
- understand the structure of your underlaying LDAP structure
- test the queries by ldapsearch
- once ldapsearch is working and shows the expected results: configure
the ldap module accordingly

Regards
Uwe
Am 12.02.2020 11:29 schrieb Matthew Newton:

> On Tue, 2020-02-11 at 23:53 +0000, Daniel Oakes wrote:
>> Thanks that definitely got me a lot closer – but for some reason I’m
>> not getting an expansion of the groups, so suspect that it’s probably
>> something to do with the bind user:
>
> Don't try and enumerate all the groups in FreeRADIUS. Configure the
> LDAP module correctly and then use unlang to check groups, similar to
> how you posted earlier.
>
> if (LDAP-Group == "LDAP Group One") {
>         update reply {
> Fortinet-Group-Name := 'group1'
> }
> }
> elsif (LDAP-Group == "LDAP Group Two") {
>         update reply {
> Fortinet-Group-Name := 'group2'
> }
> }
> elsif
> (....) {
> }
>
> There are two ways you can check LDAP group membership. Most efficient
> is normally to use the "memberOf" attribute, see "membership_attribute"
> in mods-available/ldap. This is a virtual attribute maintained by the
> LDAP server for each entry with a list of all the groups that entry is
> a member of. Not all LDAP servers provide it, or it might not be
> enabled.
>
> The alternative is to use a filter and look for all groups that contain
> "member={search DN}". This may be slower, but should be supported on
> all LDAP servers. See "membership_filter" in the ldap config.
>
> In both cases, you need server permission to be able to either read all
> relevant groups (membership_filter), or the memberOf attribute
> (membership_attribute).
>
> So, like Alan said, use `ldapsearch` to do the search to check that
> FreeRADIUS can get the result, then configure the group member options
> in LDAP as required and use the special LDAP-Group attribute above to
> do the checking. Don't try and enumerate group memberships in unlang,
> the module does the checking for you. Using &LDAP-Group[*] is likely
> the wrong approach.
>
> There's a lot more at https://wiki.freeradius.org/modules/Rlm_ldap

-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
| Threaded
Open this post in threaded view
|

Re: LDAP groups and how to filter

Daniel Oakes
Thanks – for the record it’s FreeIPA.

So your first query works, but returns A LOT:

ldapsearch -D 'uid=admin,cn=users,cn=accounts,dc=server,dc=domain,dc=net' -w<password>' -h localhost -s sub '(objectclass=posixAccount)' -b 'uid=doakes,cn=users,cn=accounts,dc=server,dc=domain,dc=net'

# extended LDIF
#
# LDAPv3
# base <uid=doakes,cn=users,cn=accounts,dc=server,dc=domain,dc=net> with scope subtree
# filter: (objectclass=posixAccount)
# requesting: ALL
#

# doakes, users, accounts, shield.zswitch.net
dn: uid=doakes,cn=users,cn=accounts,dc=server,dc=domain,dc=net
krbLoginFailedCount: 0
krbLastFailedAuth: 20200210075459Z
memberOf: cn=ipausers,cn=groups,cn=accounts,dc=server,dc=domain,dc=net
memberOf: cn=employees,cn=groups,cn=accounts,dc=server,dc=domain,dc=net
memberOf: cn=ops_training_wheels,cn=groups,cn=accounts,dc=server,dc=domain,dc
=net


Much output later.

So that works – I’m struggling with how that translates to the group filter.

My mods-enabled/ldap has an identity and password configured in the ldap section.

My base_dn is ‘cn=accounts,dc=server,dc=domain,dc=net’

In the group section I change the filter to '(objectClass=posixAccount)' and uncommented scope = ‘sub’

Currently the membership filter is the default of :

membership_filter = "(|(member=%{control:Ldap-UserDn})(memberUid=%{%{Stripped-User-Name
}:-%{User-Name}}))"

How is that modified to handle that above query so I get the groups?

Sorry, bit of a noob on ldap.

Cheers,
Daniel


From: Freeradius-Users <freeradius-users-bounces+daniel=[hidden email]>
Date: Thursday, 13 February 2020 at 12:33 AM
To: FreeRadius users mailing list <[hidden email]>
Subject: Re: LDAP groups and how to filter
I was going to explain something similar but Matthew was much faster.
In addition: You should definitely use ldapsearch on Linux command line
first to find the right
ldap module configuration. Because this has to match your ldap server
structure (did you mention what that
is? AD or OpenLDAP or what?).
ldapsearch is much easier for debugging.
In case you are not so familiar I give you an example:

Matthew described the two ways of getting group ownership.
The memberOf method would (in my case, you have to check for yours!)
translate into the following
ldap query on Ubuntu commandline:

> ldapsearch -D "cn=<queryUser>,dc=kms,dc=de" -w <queryUserPasswd> -h
> LDAPserver -s sub "(objectclass=posixAccount)" -b
> "uid=uhahn,ou=people,dc=kms,dc=de" memberOf

Result is:

# extended LDIF
#
# LDAPv3
# base <uid=uhahn,ou=people,dc=kms,dc=de> with scope subtree
# filter: (objectclass=posixAccount)
# requesting: memberOf
#

# uhahn, people, kms.de
dn: uid=uhahn,ou=people,dc=kms,dc=de
memberOf: cn=lehrer,ou=groups,dc=kms,dc=de
memberOf: cn=gast,ou=groups,dc=kms,dc=de

# search result
search: 2
result: 0 Success

Note: Result are two memberOf: lines, i.e. user uhahn belongs to two
groups: lehrer and gast.
This is the most efficient way because you have to check this one user
only for his memberOf attribute.
---------------------------------
The other method without memberOf is to check ALL groups to see if the
user is part of it, i.e. if this name is part
of the member attribute of the group.

The ldapsearch command is:

> ldapsearch -D "cn=<queryUser>,dc=kms,dc=de" -w <queryUserPasswd> -h
> LDAPserver -s sub
> "(&(member="uid=uhahn,ou=people,dc=kms,dc=de")(objectClass=groupOfNames))"
> -b "ou=groups,dc=kms,dc=de" cn

Result is:

  extended LDIF
#
# LDAPv3
# base <ou=groups,dc=kms,dc=de> with scope subtree
# filter:
(&(member=uid=uhahn,ou=people,dc=kms,dc=de)(objectClass=groupOfNames))
# requesting: cn
#

# lehrer, groups, kms.de
dn: cn=lehrer,ou=groups,dc=kms,dc=de
cn: lehrer

# gast, groups, kms.de
dn: cn=gast,ou=groups,dc=kms,dc=de
cn: gast

# search result
search: 2
result: 0 Success


You get the same result: User uhahn belongs to two groups: lehrer and
gast.
So:
- understand the structure of your underlaying LDAP structure
- test the queries by ldapsearch
- once ldapsearch is working and shows the expected results: configure
the ldap module accordingly

Regards
Uwe
Am 12.02.2020 11:29 schrieb Matthew Newton:

> On Tue, 2020-02-11 at 23:53 +0000, Daniel Oakes wrote:
>> Thanks that definitely got me a lot closer – but for some reason I’m
>> not getting an expansion of the groups, so suspect that it’s probably
>> something to do with the bind user:
>
> Don't try and enumerate all the groups in FreeRADIUS. Configure the
> LDAP module correctly and then use unlang to check groups, similar to
> how you posted earlier.
>
> if (LDAP-Group == "LDAP Group One") {
>         update reply {
>                Fortinet-Group-Name := 'group1'
>        }
> }
> elsif (LDAP-Group == "LDAP Group Two") {
>         update reply {
>                Fortinet-Group-Name := 'group2'
>        }
> }
> elsif
> (....) {
> }
>
> There are two ways you can check LDAP group membership. Most efficient
> is normally to use the "memberOf" attribute, see "membership_attribute"
> in mods-available/ldap. This is a virtual attribute maintained by the
> LDAP server for each entry with a list of all the groups that entry is
> a member of. Not all LDAP servers provide it, or it might not be
> enabled.
>
> The alternative is to use a filter and look for all groups that contain
> "member={search DN}". This may be slower, but should be supported on
> all LDAP servers. See "membership_filter" in the ldap config.
>
> In both cases, you need server permission to be able to either read all
> relevant groups (membership_filter), or the memberOf attribute
> (membership_attribute).
>
> So, like Alan said, use `ldapsearch` to do the search to check that
> FreeRADIUS can get the result, then configure the group member options
> in LDAP as required and use the special LDAP-Group attribute above to
> do the checking. Don't try and enumerate group memberships in unlang,
> the module does the checking for you. Using &LDAP-Group[*] is likely
> the wrong approach.
>
> There's a lot more at https://wiki.freeradius.org/modules/Rlm_ldap

-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
| Threaded
Open this post in threaded view
|

Re: LDAP groups and how to filter

Alan DeKok-2
On Feb 12, 2020, at 3:21 PM, Daniel Oakes <[hidden email]> wrote:
> So your first query works, but returns A LOT:
>
> ldapsearch -D 'uid=admin,cn=users,cn=accounts,dc=server,dc=domain,dc=net' -w<password>' -h localhost -s sub '(objectclass=posixAccount)' -b 'uid=doakes,cn=users,cn=accounts,dc=server,dc=domain,dc=net'

  Which is asking for *all* of the user information.  Not just groups.

> ...
> memberOf: cn=ipausers,cn=groups,cn=accounts,dc=server,dc=domain,dc=net
> memberOf: cn=employees,cn=groups,cn=accounts,dc=server,dc=domain,dc=net
> memberOf: cn=ops_training_wheels,cn=groups,cn=accounts,dc=server,dc=domain,dc
> =net
> …

  Those are the groups.

> Much output later.
>
> So that works – I’m struggling with how that translates to the group filter.

  In recent versions of the server, see mods-available/ldap.  It shows a sample of the query to use when asking for groups:

        #  Group membership can be queried by using the above "ldapsearch" string,
        #  and adding "memberof" qualifiers.  For ActiveDirectory, use:
        #
        #    ldapsearch ... '(&(objectClass=user)(sAMAccountName=user)(memberof=CN=group,${base_dn}))'

 That's for AD "samaccountname".  But you can modify that for your LDAP server.


> My mods-enabled/ldap has an identity and password configured in the ldap section.
>
> My base_dn is ‘cn=accounts,dc=server,dc=domain,dc=net’

  That's all good.

> In the group section I change the filter to '(objectClass=posixAccount)' and uncommented scope = ‘sub’
>
> Currently the membership filter is the default of :
>
> membership_filter = "(|(member=%{control:Ldap-UserDn})(memberUid=%{%{Stripped-User-Name
> }:-%{User-Name}}))"
>
> How is that modified to handle that above query so I get the groups?

 It should pretty much just work.  Follow the documentation in the most recent versions of the server.

  If you're running something from 5 years ago, well, the documentation has been updated.

  Alan DeKok.


-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
| Threaded
Open this post in threaded view
|

Re: LDAP groups and how to filter

uj2.hahn
And you should enable cacheable_name or cacheable_dn (=yes)  if not done
already!
Regards
Uwe

On 12.02.2020 22:54, Alan DeKok wrote:

> On Feb 12, 2020, at 3:21 PM, Daniel Oakes <[hidden email]> wrote:
>> So your first query works, but returns A LOT:
>>
>> ldapsearch -D 'uid=admin,cn=users,cn=accounts,dc=server,dc=domain,dc=net' -w<password>' -h localhost -s sub '(objectclass=posixAccount)' -b 'uid=doakes,cn=users,cn=accounts,dc=server,dc=domain,dc=net'
>    Which is asking for *all* of the user information.  Not just groups.
>
>> ...
>> memberOf: cn=ipausers,cn=groups,cn=accounts,dc=server,dc=domain,dc=net
>> memberOf: cn=employees,cn=groups,cn=accounts,dc=server,dc=domain,dc=net
>> memberOf: cn=ops_training_wheels,cn=groups,cn=accounts,dc=server,dc=domain,dc
>> =net
>> …
>    Those are the groups.
>
>> Much output later.
>>
>> So that works – I’m struggling with how that translates to the group filter.
>    In recent versions of the server, see mods-available/ldap.  It shows a sample of the query to use when asking for groups:
>
> #  Group membership can be queried by using the above "ldapsearch" string,
> #  and adding "memberof" qualifiers.  For ActiveDirectory, use:
> #
> #    ldapsearch ... '(&(objectClass=user)(sAMAccountName=user)(memberof=CN=group,${base_dn}))'
>
>   That's for AD "samaccountname".  But you can modify that for your LDAP server.
>
>
>> My mods-enabled/ldap has an identity and password configured in the ldap section.
>>
>> My base_dn is ‘cn=accounts,dc=server,dc=domain,dc=net’
>    That's all good.
>
>> In the group section I change the filter to '(objectClass=posixAccount)' and uncommented scope = ‘sub’
>>
>> Currently the membership filter is the default of :
>>
>> membership_filter = "(|(member=%{control:Ldap-UserDn})(memberUid=%{%{Stripped-User-Name
>> }:-%{User-Name}}))"
>>
>> How is that modified to handle that above query so I get the groups?
>   It should pretty much just work.  Follow the documentation in the most recent versions of the server.
>
>    If you're running something from 5 years ago, well, the documentation has been updated.
>
>    Alan DeKok.
>
>
> -
> List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html

-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
| Threaded
Open this post in threaded view
|

Re: LDAP groups and how to filter

Daniel Oakes
Many thanks – that was the kicker – adding the cacheable_name menat the groups ended up in the response and the unlang works!

Cheers,
Daniel


From: Freeradius-Users <freeradius-users-bounces+daniel=[hidden email]>
Date: Thursday, 13 February 2020 at 10:58 AM
To: [hidden email] <[hidden email]>
Subject: Re: LDAP groups and how to filter
And you should enable cacheable_name or cacheable_dn (=yes)  if not done
already!
Regards
Uwe

On 12.02.2020 22:54, Alan DeKok wrote:

> On Feb 12, 2020, at 3:21 PM, Daniel Oakes <[hidden email]> wrote:
>> So your first query works, but returns A LOT:
>>
>> ldapsearch -D 'uid=admin,cn=users,cn=accounts,dc=server,dc=domain,dc=net' -w<password>' -h localhost -s sub '(objectclass=posixAccount)' -b 'uid=doakes,cn=users,cn=accounts,dc=server,dc=domain,dc=net'
>    Which is asking for *all* of the user information.  Not just groups.
>
>> ...
>> memberOf: cn=ipausers,cn=groups,cn=accounts,dc=server,dc=domain,dc=net
>> memberOf: cn=employees,cn=groups,cn=accounts,dc=server,dc=domain,dc=net
>> memberOf: cn=ops_training_wheels,cn=groups,cn=accounts,dc=server,dc=domain,dc
>> =net
>> …
>    Those are the groups.
>
>> Much output later.
>>
>> So that works – I’m struggling with how that translates to the group filter.
>    In recent versions of the server, see mods-available/ldap.  It shows a sample of the query to use when asking for groups:
>
>        #  Group membership can be queried by using the above "ldapsearch" string,
>        #  and adding "memberof" qualifiers.  For ActiveDirectory, use:
>        #
>        #    ldapsearch ... '(&(objectClass=user)(sAMAccountName=user)(memberof=CN=group,${base_dn}))'
>
>   That's for AD "samaccountname".  But you can modify that for your LDAP server.
>
>
>> My mods-enabled/ldap has an identity and password configured in the ldap section.
>>
>> My base_dn is ‘cn=accounts,dc=server,dc=domain,dc=net’
>    That's all good.
>
>> In the group section I change the filter to '(objectClass=posixAccount)' and uncommented scope = ‘sub’
>>
>> Currently the membership filter is the default of :
>>
>> membership_filter = "(|(member=%{control:Ldap-UserDn})(memberUid=%{%{Stripped-User-Name
>> }:-%{User-Name}}))"
>>
>> How is that modified to handle that above query so I get the groups?
>   It should pretty much just work.  Follow the documentation in the most recent versions of the server.
>
>    If you're running something from 5 years ago, well, the documentation has been updated.
>
>    Alan DeKok.
>
>
> -
> List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html

-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html