Using ldap_xlat in unlang with Chars not allowed in an ldap search
Hi! I have a Problem using the ldap Module to search in the ldap Tree for a specific Attribute Containing a (. I am using FreeRadius (2.1.12) for 802.1X Authentification (EAP-TLS) which is working fine. After successful EAP Authentication, I want to check if the User has an Entry in the LDAP: During authenticate (I just changed a bit of formattig to have it readable here): Auth-Type eap { eap # Some Code to react to EAP Auth Failures if ( "%{TLS-Client-Cert-Common-Name}" != "" ) { update control { Tmp-String-1 = "%{ldap_WLAN_auth: ldap:///cn=UserAccounts,dc=DE?cn?sub? ( & (CommonName=%{TLS-Client-Cert-Common-Name}) (allowedSSID=%{Aruba-Essid-Name}) )}" } if ("%{control:Tmp-String-1}" == "") { update control { Auth-Type := "Reject" } update reply { Reply-Message = "The user %{User-Name} is not known or allowed to access the SSID %{Aruba-Essid- Name}" } reject } Now the {TLS-Client-Cert-Common-Name} contains a ( and a ) which leads to a bad search filter: |Debug: [ldap_WLAN_auth] - ldap_xlat |Info: expand: ldap:///cn=UserAccounts,dc=NI-NGN,dc=DE?cn?sub?(&(CommonName=%{TLS-Client-Cert-Common-Name})(allowedSSID=%{Aruba-Essid-Name})) -> ldap:///cn=UserAccounts,dc=DE?cn?sub?(&(CommonName=Testuser(10) Daniel)(allowedSSID=ssid-data)) |Debug: [ldap_WLAN_auth] ldap_get_conn: Checking Id: 0 |Debug: [ldap_WLAN_auth] ldap_get_conn: Got Id: 0 |Debug: [ldap_WLAN_auth] performing search in cn=UserAccounts,dc=DE, with filter (&(CommonName=Testuser(10) Daniel)(allowedSSID=ssid-data)) |ldap_search() failed: Bad search filter: (&(CommonName=Testuser(10) Daniel)(allowedSSID=ssid-data)) |Debug: [ldap_WLAN_auth] Search returned error |Debug: [ldap_WLAN_auth] ldap_release_conn: Release Id: 0 |Info: expand: %{ldap_WLAN_auth:ldap:///cn=UserAccounts,dc=DE?cn?sub?(&(CommonName=%{TLS-Client-Cert-Common-Name})(allowedSSID=%{Aruba-Essid-Name}))} -> If I have searched correctly it should work if I rewrite the Attribute with \28 for ( and \29 for ) (as ascii string, not escaped :-)) As it seems the rewrite Module is not the solution as i could not get it to do this :-) It works as I expected it to do if the CommonName does not contain the Parentheses. Any Ideas to work around these Parentheses? Preferably using any Char allowed in the Common Name, as i expect it to contain Umlauts or an & Char. Greetings, Daniel
On 29/08/12 16:00, Daniel Finger wrote:
If I have searched correctly it should work if I rewrite the Attribute with \28 for ( and \29 for ) (as ascii string, not escaped :-))
Shouldn't that be %28 and %29? Relevant docs here are RFC 4516 section 2.1, which references RFC 3986 section 2.1.
As it seems the rewrite Module is not the solution as i could not get it to do this :-)
It works as I expected it to do if the CommonName does not contain the Parentheses. Any Ideas to work around these Parentheses? Preferably using any Char allowed in the Common Name, as i expect it to contain Umlauts or an & Char.
There's no easy way to do this with the built-in LDAP code. When the "xlat" is called, it's called with one big string i.e. the un-escaped value is already inside the string, and can't be escaped. Maybe there's room for an xlat in the server core: %{urlquote:%{Value}} ...which might be generally useful. In the meantime, you can probably emulate this with rlm_perl - define a simple perl module: perl urlquote { module = ${confdir}/urlquote.pl func_xlat = xlat } ...and in "urlquote.pl" use strict; use URI::Escape; sub xlat { my $input = shift; return uri_escape($input); } ...then use the xlat like this: Attr := "%{ldap:....?cn=%{urlquote:%{TLS-Client-...}}?...}
On 29/08/12 17:42, Phil Mayers wrote:
There's no easy way to do this with the built-in LDAP code. When the "xlat" is called, it's called with one big string i.e. the un-escaped value is already inside the string, and can't be escaped.
Actually, following this up: I'm wrong here, due to misunderstanding how the xlat & escape stuff applies. I think the actual problem is that ldap_xlat doesn't use the ldap_escape_func on the URL, because the escape func was added after the xlat, and the xlat not updated. That is, it's a simple bug. If you edit rlm_ldap.c around line 1231, and change: if (!radius_xlat(url, sizeof(url), fmt, request, func)) ...to: if (!radius_xlat(url, sizeof(url), fmt, request, ldap_escape_func)) ...this should work. I'll submit a one-liner.
Am 20.09.2012 18:28, schrieb Phil Mayers:
If you edit rlm_ldap.c around line 1231, and change: if (!radius_xlat(url, sizeof(url), fmt, request, func)) ...to: if (!radius_xlat(url, sizeof(url), fmt, request, ldap_escape_func)) ...this should work. I'll submit a one-liner.
I just upgraded to Version 2.2.0, included that small patch (and the one from John Dennis to keep the Radius Clients in LDAP) and it works perfecly. Thanks a lot!
participants (2)
-
Daniel Finger -
Phil Mayers