man unlang - attribute lists. *** The "<list>:" prefix is optional, and if omitted, is assumed to refer to the "request" list. *** Ivan Kalik Kalik Informatika ISP Dana 9/6/2008, "Sylvain Robitaille" <syl@alcor.concordia.ca> piše:
Background:
We're using FreeRADIUS-2.0.3 with an OpenLDAP backend, on two separate systems for authentication and authorization of users to our wireless network and a lesser-used VPN service. I would like to be able to modify the LDAP query filter based on (for example) which NAS device sent the RADIUS request so that (again, for example) a different filter might be used to search for wireless users than for VPN users.
In an effort to be able to setup a "dynamic" LDAP query filter, I have tried adding a string-type attribute to our local dictionary file, to hold the filter that would be updated on-the-fly:
ATTRIBUTE CU-LDAP-Filter 3000 string
The radiusd.conf file then has ldap module instances (one per LDAP server) with the following reference to this attribute:
ldap ldap_host1 { server = "ldap_host1" identity = "cn=...,ou=...,dc=concordia,dc=ca" password = "**SANITIZED**" basedn = "ou=people,dc=concordia,dc=ca" filter = "%{CU-LDAP-Filter}" base_filter = "(objectclass=ConcordiaPerson)" ... }
ldap ldap_host2 { server = "ldap_host2" identity = "cn=...,ou=...,dc=concordia,dc=ca" password = "**SANITIZED**" basedn = "ou=people,dc=concordia,dc=ca" filter = "%{CU-LDAP-Filter}" base_filter = "(objectclass=ConcordiaPerson)" ... }
I'm presently testing with the radeapclient client (on localhost), so am testing with the following configured into sites-enabled/default:
authorize { ... switch "%{NAS-IP-Address}" { case 192.168.198.20 { # test update control { CU-LDAP-Filter = "(&(cn=%{%{Stripped-User-Name}:-%{User-Name}})(***LDAP QUERY1 TRIMMED FOR BREVITY***))" } } case 127.0.0.1 { # test update control { CU-LDAP-Filter = "(&(cn=%{%{Stripped-User-Name}:-%{User-Name}})(***LDAP QUERY2 TRIMMED FOR BREVITY***))" } } ... case { # default noop } }
if ("%{CU-LDAP-Filter}" != "") { redundant-load-balance { ldap_host1 ldap_host2 } } ... }
The LDAP query filters, though not included above (these things are quite long and site-specific anyway) are known to work, as they're copied from our currently in-production configuration that is selecting the ldap module instance based on the NAS-IP-Address (ie. if NAS-IP-Address is the VPN server we call the ldap_vpn module which is configured with an appropriate filter, else we call the ldap_wireless module which is also appropriately configured). The present setup works, but based on what I'm reading it would give is a much more flexible and fault-tolerant (and dare-I-say, more manageable?) setup if I could get the LDAP module instances configured into a redundant-load-balance stanza, with a dynamically determined LDAP query filter (so that if one LDAP server is unavailable, one or more others could be tried instead, instead of having a hard-coded query to specific LDAP servers for each service).
I hope I'm making sense so far ...
The following command is issued to test:
radeapclient -x localhost:1815 auth testing123 << END_OF_EAP User-Name = "j_doe" Cleartext-Password = "**SANITIZED**" NAS-IP-Address = 192.168.198.20 NAS-Port-Type = "Wireless-802.11" EAP-Code = Response EAP-Id = 210 EAP-Type-Identity = "j_doe" Message-Authenticator = 0x00 NAS-Port = 0 END_OF_EAP
Radiusd, running in debug mode shows the following (config-file parsing output skipped; it is not showing any errors at all, so although the configuration I show above may not be producing the intended result, it at least seems syntactically correct):
Listening on authentication address * port 1815 Listening on accounting address * port 1816 Listening on proxy address * port 1817 Ready to process requests. User-Name = "j_doe" NAS-IP-Address = 192.168.198.20 NAS-Port-Type = Wireless-802.11 Message-Authenticator = 0x8499bae7c162d5f0ef2e587fdb9086a0 NAS-Port = 0 EAP-Message = 0x02d200080173796c +- entering group authorize ++[preprocess] returns ok ++[chap] returns noop ++[mschap] returns noop rlm_realm: No '@' in User-Name = "j_doe", looking up realm NULL rlm_realm: No such realm "NULL" ++[suffix] returns noop rlm_eap: EAP packet type response id 210 length 8 rlm_eap: No EAP Start, assuming it's an on-going EAP conversation ++[eap] returns updated ++[unix] returns notfound ++[files] returns noop expand: %{NAS-IP-Address} -> 192.168.198.20 ++- entering switch %{NAS-IP-Address} +++- entering case 192.168.198.20 expand: %{Stripped-User-Name} -> expand: %{User-Name} -> j_doe expand: (&(cn=%{%{Stripped-User-Name}:-%{User-Name}})**LDAP QUERY1 FILTER TRIMMED**) -> (&(cn=j_doe)**LDAP QUERY1 FILTER TRIMMED**) ++++[control] returns noop +++- case 192.168.198.20 returns noop ++- switch %{NAS-IP-Address} returns noop ++? if ("%{CU-LDAP-Filter}" != "") expand: %{CU-LDAP-Filter} -> ? Evaluating ("%{CU-LDAP-Filter}" != "") -> FALSE ++? if ("%{CU-LDAP-Filter}" != "") -> FALSE ++[expiration] returns noop ++[logintime] returns noop rlm_pap: WARNING! No "known good" password found for the user. Authentication may fail because of this. ++[pap] returns noop rad_check_password: Found Auth-Type EAP auth: type "EAP" +- entering group authenticate rlm_eap: EAP Identity rlm_eap: processing type tls rlm_eap_tls: Initiate rlm_eap_tls: Start returned 1 rlm_eap: RT Modif EAP-Type = 21 EAP-LENGTH = 1 ++[eap] returns handled EAP-Message = 0x01d300061520 Message-Authenticator = 0x00000000000000000000000000000000 State = 0x1c870d031c541859b55d17dd8af5914a Finished request 0. Going to the next request Waking up in 4.9 seconds. Cleaning up request 0 ID 232 with timestamp +4 Ready to process requests.
Note that of the above, I believe the following is relevant to my question:
expand: %{NAS-IP-Address} -> 192.168.198.20 ++- entering switch %{NAS-IP-Address} +++- entering case 192.168.198.20 expand: %{Stripped-User-Name} -> expand: %{User-Name} -> j_doe expand: (&(cn=%{%{Stripped-User-Name}:-%{User-Name}})**LDAP QUERY1 FILTER TRIMMED**) -> (&(cn=j_doe)**LDAP QUERY1 FILTER TRIMMED**) ++++[control] returns noop +++- case 192.168.198.20 returns noop ++- switch %{NAS-IP-Address} returns noop ++? if ("%{CU-LDAP-Filter}" != "") expand: %{CU-LDAP-Filter} -> ? Evaluating ("%{CU-LDAP-Filter}" != "") -> FALSE ++? if ("%{CU-LDAP-Filter}" != "") -> FALSE
This corresponds to the following from the "authorize" section in my sites-enabled/default file:
switch "%{NAS-IP-Address}" { case 192.168.198.20 { # test update control { CU-LDAP-Filter = "(&(cn=%{%{Stripped-User-Name}:-%{User-Name}})(***LDAP QUERY TRIMMED FOR BREVITY***))" } } }
We see that the line where I intend to assign a value to CU-LDAP-Filter is indeed encountered and the variables referred to in that line are expanded correctly, but it seems as though the assignment to CU-LDAP-Filter isn't done: if ("%{CU-LDAP-Filter}" != "") is evaluated as "FALSE".
I suspect that my "update" statement is likely incorrect, since the only mention of it in the debug output is:
++++[control] returns noop
Can anyone help me with this? I've read as much of the relevant documentation as I'm aware exists, especially "man unlang" without which I certainly wouldn't have gotten even this far, but I'd be very grateful if someone could point me to further documentation that would help with what I'm trying to do ...
Thanks ...
-- ---------------------------------------------------------------------- Sylvain Robitaille syl@alcor.concordia.ca
Systems and Network analyst Concordia University Instructional & Information Technology Montreal, Quebec, Canada ---------------------------------------------------------------------- - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html