What I am trying to achieve, and have so far been sucesfull, is to have groups of users and NAS groups (using regex). I then use unlang to create conditionals in order to accept/reject/update reply items accordingly. I use this to specify different access levels using Cisco-AV-Pair values and to allow users of some groups to access some NASes and not others. This is all running in post_auth and works fine. Anything that is not matching withing the if conditionals is trickled down to a "catch-all" else that rejects the request. Now I want some of these users to also be able to access VPNs to specific sites. So I am trying to use a Reply item of "Realm" to match the NAS-Identifier of the VPN endpoints. Unfortunately, even though the conditional matched this, it returns noop, therefore evaluation is continuing to match another conditional, until it is rejected by the "catch-all" else statement at the end. User bsup belongs to group BB, thus reply:Group=BB User bsup also has a reply item set for VPN to SITE1, reply:Realm=VPN-SITE1 In users file: DEFAULT NAS-IP-Address == 1.1.1.1 NAS-Identifier := "VPN-SITE1" IP 1.1.1.1 is the VPN server of SITE1, thus reply:NAS-Identifier=VPN-SITE1 [DEBUG LOG STARTS] rad_recv: Access-Request packet from host 192.168.4.1 port 50070, id=34, length=50 User-Name = "bsup" User-Password = "SAvwxNsqGeaJw" NAS-IP-Address = 1.1.1.1 # Executing section authorize from file /etc/freeradius/sites-enabled/default +- entering group authorize {...} ++[preprocess] returns ok ++[chap] returns noop ++[mschap] returns noop ++[digest] returns noop [suffix] No '@' in User-Name = "bsup", looking up realm NULL [suffix] No such realm "NULL" ++[suffix] returns noop [eap] No EAP-Message, not doing EAP ++[eap] returns noop [files] users: Matched entry DEFAULT at line 51 ++[files] returns ok [sql] expand: %{User-Name} -> bsup [sql] sql_set_user escaped user --> 'bsup' rlm_sql (sql): Reserving sql socket id: 4 [sql] expand: SELECT id, username, attribute, value, op FROM radcheck WHERE username = '%{SQL-User-Name}' ORDER BY id -> SELECT id, username, attribute, value, op FROM radcheck WHERE username = 'bsup' ORDER BY id [sql] User found in radcheck table [sql] expand: SELECT id, username, attribute, value, op FROM radreply WHERE username = '%{SQL-User-Name}' ORDER BY id -> SELECT id, username, attribute, value, op FROM radreply WHERE username = 'bsup' ORDER BY id [sql] expand: SELECT groupname FROM radusergroup WHERE username = '%{SQL-User-Name}' ORDER BY priority -> SELECT groupname FROM radusergroup WHERE username = 'bsup' ORDER BY priority [sql] expand: SELECT id, groupname, attribute, Value, op FROM radgroupcheck WHERE groupname = '%{Sql-Group}' ORDER BY id -> SELECT id, groupname, attribute, Value, op FROM radgroupcheck WHERE groupname = 'BB' ORDER BY id [sql] User found in group BB [sql] expand: SELECT id, groupname, attribute, value, op FROM radgroupreply WHERE groupname = '%{Sql-Group}' ORDER BY id -> SELECT id, groupname, attribute, value, op FROM radgroupreply WHERE groupname = 'BB' ORDER BY id rlm_sql (sql): Released sql socket id: 4 ++[sql] returns ok ++[expiration] returns noop ++[logintime] returns noop ++[pap] returns updated Found Auth-Type = PAP # Executing group from file /etc/freeradius/sites-enabled/default +- entering group PAP {...} [pap] login attempt with password "SAvwxNsqGeaJw" [pap] Using clear text password "SAvwxNsqGeaJw" [pap] User authenticated successfully ++[pap] returns ok # Executing section post-auth from file /etc/freeradius/sites-enabled/default +- entering group post-auth {...} [sql] expand: %{User-Name} -> bsup [sql] sql_set_user escaped user --> 'bsup' [sql] expand: %{User-Password} -> SAvwxNsqGeaJw [sql] expand: INSERT INTO radpostauth (username, pass, reply, authdate) VALUES ( '%{User-Name}', '%{%{User-Password}:-%{Chap-Password}}', '%{reply:Packet-Type}', '%S') -> INSERT INTO radpostauth (username, pass, reply, authdate) VALUES ( 'bsup', 'SAvwxNsqGeaJw', 'Access-Accept', '2016-07-25 16:55:58') rlm_sql (sql) in sql_postauth: query is INSERT INTO radpostauth (username, pass, reply, authdate) VALUES ( 'bsup', 'SAvwxNsqGeaJw', 'Access-Accept', '2016-07-25 16:55:58') rlm_sql (sql): Reserving sql socket id: 3 rlm_sql (sql): Released sql socket id: 3 ++[sql] returns ok ++[exec] returns noop ++? if ("%{reply:NAS-Identifier}" =~ /VPN-/) expand: %{reply:NAS-Identifier} -> VPN-SITE1 ? Evaluating ("%{reply:NAS-Identifier}" =~ /VPN-/) -> TRUE ++? if ("%{reply:NAS-Identifier}" =~ /VPN-/) -> TRUE ++- entering if ("%{reply:NAS-Identifier}" =~ /VPN-/) {...} +++? if ("%{reply:NAS-Identifier}" == "%{reply:Realm}") expand: %{reply:NAS-Identifier} -> VPN-SITE1 expand: %{reply:Realm} -> VPN-SITE1 ? Evaluating ("%{reply:NAS-Identifier}" == "%{reply:Realm}") -> TRUE +++? if ("%{reply:NAS-Identifier}" == "%{reply:Realm}") -> TRUE +++- entering if ("%{reply:NAS-Identifier}" == "%{reply:Realm}") {...} ++++[reply] returns noop +++- if ("%{reply:NAS-Identifier}" == "%{reply:Realm}") returns noop ++- if ("%{reply:NAS-Identifier}" =~ /VPN-/) returns noop ++? if ("%{reply:Group}" == "GOD") expand: %{reply:Group} -> BB ? Evaluating ("%{reply:Group}" == "GOD") -> FALSE ++? if ("%{reply:Group}" == "GOD") -> FALSE ++? if ("%{reply:NAS-Identifier}" == "GOD" && "%{reply:Group}" != "GOD") expand: %{reply:NAS-Identifier} -> VPN-SITE1 ? Evaluating ("%{reply:NAS-Identifier}" == "GOD" ) -> FALSE ? Skipping ("%{reply:Group}" != "GOD") ++? if ("%{reply:NAS-Identifier}" == "GOD" && "%{reply:Group}" != "GOD") -> FALSE ++? if ("%{reply:Group}" == "BB") expand: %{reply:Group} -> BB ? Evaluating ("%{reply:Group}" == "BB") -> TRUE ++? if ("%{reply:Group}" == "BB") -> TRUE ++- entering if ("%{reply:Group}" == "BB") {...} +++? if ("%{reply:NAS-Identifier}" =~ /^CUST./ || "%{reply:NAS-Identifier}" == "BB") expand: %{reply:NAS-Identifier} -> VPN-SITE1 ? Evaluating ("%{reply:NAS-Identifier}" =~ /^CUST./) -> FALSE expand: %{reply:NAS-Identifier} -> VPN-SITE1 ? Evaluating ("%{reply:NAS-Identifier}" == "BB") -> FALSE +++? if ("%{reply:NAS-Identifier}" =~ /^CUST./ || "%{reply:NAS-Identifier}" == "BB") -> FALSE +++- entering else else {...} expand: Rejected (BB: %{NAS-IP-Address}) -> Rejected (BB: 1.1.1.1) ++++[reply] returns noop ++++[reject] returns reject +++- else else returns reject ++- if ("%{reply:Group}" == "BB") returns reject Using Post-Auth-Type Reject # Executing group from file /etc/freeradius/sites-enabled/default +- entering group REJECT {...} [sql] expand: %{User-Name} -> bsup [sql] sql_set_user escaped user --> 'bsup' [sql] expand: %{User-Password} -> SAvwxNsqGeaJw [sql] expand: INSERT INTO radpostauth (username, pass, reply, authdate) VALUES ( '%{User-Name}', '%{%{User-Password}:-%{Chap-Password}}', '%{reply:Packet-Type}', '%S') -> INSERT INTO radpostauth (username, pass, reply, authdate) VALUES ( 'bsup', 'SAvwxNsqGeaJw', 'Access-Reject', '2016-07-25 16:55:58') rlm_sql (sql) in sql_postauth: query is INSERT INTO radpostauth (username, pass, reply, authdate) VALUES ( 'bsup', 'SAvwxNsqGeaJw', 'Access-Reject', '2016-07-25 16:55:58') rlm_sql (sql): Reserving sql socket id: 2 rlm_sql (sql): Released sql socket id: 2 ++[sql] returns ok [attr_filter.access_reject] expand: %{User-Name} -> bsup attr_filter: Matched entry DEFAULT at line 11 ++[attr_filter.access_reject] returns updated Delaying reject of request 0 for 1 seconds Going to the next request Waking up in 0.9 seconds. Sending delayed reject for request 0 Sending Access-Reject of id 34 to 192.168.4.1 port 50070 Reply-Message = "Rejected (BB: 1.1.1.1)" Waking up in 4.9 seconds. Cleaning up request 0 ID 34 with timestamp +5 [DEBUG LOG ENDS] Hopefully this make sense now.