Access-Accept / Access-Reject based on LDAP Group & SSID

Ben Humpert ben at
Mon Mar 23 22:21:07 CET 2015

>>> On Mar 20, 2015, at 5:05 PM, Ben Humpert <ben at> wrote:
>>> RADIUS should check if the users group has a radiusCalledStationId
>>> attribute matching the Called-Station-Id. If not it should check if
>>> the user itself has a matching attribute. If not, Access-Reject. In
>>> case a match is found and Called-Station-Ssid is set RADIUS should now
>>> check if the users group has a matching radiusCalledStationSsid
>>> attribute. If not it should check if the user itself has a matching
>>> attribute. If not, Access-Reject. In case a match is found RADIUS
>>> should finally check the users group for other attributes (eg.
>>> radiusTunnelType, etc.) and apply them as long as the user itself
>>> doesn't have these attributes set too. In that case the users
>>> attributes take precedence.

Finally I got everything I wanted. However I don't know if how it's
done is the right or at least a good way. I would appreciate if
someone could quickly check my implementation and comment it :)

In server default authorize {} I first sanitize supplied
Called-Station-Id (& create Called-Station-Ssid if supplied) and
Calling-Station-Id using policies and at the very end I use policies
again to check supplied Called-Station-Id, Called-Station-Ssid and
Calling-Station-Id values with those stored in LDAP. In server default
post-auth {} the first policy is for applying dynamic vlan assignment

policy.ldap_called-station-ssid {
        if (&Called-Station-Ssid) {
|| "%{ldap:ldap:///ou=Users,dc=home,dc=lan?uidNumber?sub?(&(uid=%{User-Name})(radiusCalledStationSsid=%{Called-Station-Ssid}))}")
                else {
        else {

policy.ldap_called-station-id and policy.ldap_calling-station-id are
the same, respectively. These are checked only once after the first
Access-Request package directly after eap so I guess it's fine. The
next policy is maybe not a good solution since the LDAP is queried up
to eight times.

policy.ldap_vlan-assignment {
        if ("%{ldap:ldap:///ou=Users,dc=home,dc=lan?uidNumber?sub?(&(uid=%{User-Name})(radiusTunnelType=VLAN))}")
                update reply {
                        &Tunnel-Medium-Type :=
                        &Tunnel-Private-Group-Id :=
                        &Tunnel-Type :=
        elsif ("%{ldap:ldap:///ou=Groups,dc=home,dc=lan?gidNumber?sub?(&(objectClass=posixGroup)(memberUid=%{User-Name})(radiusTunnelType=VLAN))}")
                update reply {
                        &Tunnel-Medium-Type :=
                        &Tunnel-Private-Group-Id :=
                        &Tunnel-Type :=
        else {
                update reply {
                        &Tunnel-Medium-Type := "IEEE-802"
                        &Tunnel-Private-Group-Id := "1"
                        &Tunnel-Type := "VLAN"

That policy is only executed once directly before the final
Access-Accept package is sent. However, if one (existing) user wants
to login the LDAP is queried 14 times (worst-case) or 7 times
(best-case). Generally said, is that a very good, acceptable or
extremely worse amount of queries per user?

I also found some configurations I couldn't understand. First is in
sites-enabled/default line 494: why is eap not called as "Auth-Type
EAP { eap }" like pap, chap and ms-chap?
I also noticed that the server looks for a Post-Auth-Type Challenge {}
but couldn't find it thus ignoring it (debug output), so I added it to
the post-auth section with attr_filter.access_challenge in it.
Shouldn't this be the default?
At last I got confused by the commented out routine in
sites-enabled/default line 502 to 510. Here we have "Auth-Type EAP {
eap }" and the attr_filter.access_challenge but doesn't the added
Post-Auth-Type Challenge routine do exactly the same (except setting
handled = 1)?

Thank you very much in advance.

Best regards,

Ben Humpert

More information about the Freeradius-Users mailing list