Variables usage and %explode function

Matthew Newton mcn at freeradius.org
Wed Mar 6 10:44:31 UTC 2024


On 06/03/2024 10:25, Ted S. wrote:
> im using freeradius 3.2. I want extract from the TLS-Client-Cert-Common-Name only the Hostname and strip off the fqdn part and update
> the User-Name for further processings. I found the split string function with %explode in the documentation.
> 
> I dont get it working, i tried following 2 variants:
> 
> Variant 1 with variables:

Variables are in version 4, which is in development and not released. So 
you can't use those in 3.2.


> Variant 2 without helping variables, in one line:
> 
>          update request {
>                  &User-Name := "%explode(%{TLS-Client-Cert-Common-Name}, '.')[0]"
>          }
> 
> 
> -> Log:
> (10)       update request {
> (10)         EXPAND %explode(%{TLS-Client-Cert-Common-Name}, '.')[0]
> (10)            --> 1xplode(testclient.prod.company.net, '.')[0]
> (10)         &User-Name := 1xplode(testclient.prod.company.net, '.')[0]
> (10)       } # update request = noop
> 
> 
> Can someone helping me, getting one of both variants working? Im also not sure if i can use [0] in the variant 2.

Your syntax is wrong, and you can't do it all in one go. "Explode" the 
attribute, then access individual components.

This example shows how it works:


update request {
         &Tmp-String-1 := "a.b.c.d"
}

debug_request

update request {
         &Tmp-Integer-1 := "%{explode:&Tmp-String-1 .}"
}

debug_request

update request {
         &Tmp-String-2 := &Tmp-String-1[2]
}


Leads to:


(0)     update request {
(0)       &Tmp-String-1 := "a.b.c.d"
(0)     } # update request = noop
(0)     policy debug_request {
(0)       if ("%{debug_attr:request:}" == '') {
(0)       Attributes matching "request:"
(0)         &request:User-Name = bob
(0)         &request:User-Password = bob
(0)         &request:NAS-IP-Address = 127.0.1.1
(0)         &request:NAS-Port = 0
(0)         &request:Message-Authenticator = 
0x5f288ae1e364d5419ddb4121ea27359b
(0)         &request:Tmp-String-1 := a.b.c.d

^^ This is the attribute we want to split.

(0)       EXPAND %{debug_attr:request:}
(0)          -->
(0)       if ("%{debug_attr:request:}" == '')  -> TRUE
(0)       if ("%{debug_attr:request:}" == '')  {
(0)         [noop] = noop
(0)       } # if ("%{debug_attr:request:}" == '')  = noop
(0)     } # policy debug_request = noop
(0)     update request {
(0)       EXPAND %{explode:&Tmp-String-1 .}
(0)          --> 4
(0)       &Tmp-Integer-1 := 4
(0)     } # update request = noop

^^ Exploded, returned number of components it was split into.

(0)     policy debug_request {
(0)       if ("%{debug_attr:request:}" == '') {
(0)       Attributes matching "request:"
(0)         &request:User-Name = bob
(0)         &request:User-Password = bob
(0)         &request:NAS-IP-Address = 127.0.1.1
(0)         &request:NAS-Port = 0
(0)         &request:Message-Authenticator = 
0x5f288ae1e364d5419ddb4121ea27359b
(0)         &request:Tmp-String-1 = a
(0)         &request:Tmp-String-1 = b
(0)         &request:Tmp-String-1 = c
(0)         &request:Tmp-String-1 = d
(0)         &request:Tmp-Integer-1 := 4

^^ Note there are now four Tmp-String-1 attributes.

(0)       EXPAND %{debug_attr:request:}
(0)          -->
(0)       if ("%{debug_attr:request:}" == '')  -> TRUE
(0)       if ("%{debug_attr:request:}" == '')  {
(0)         [noop] = noop
(0)       } # if ("%{debug_attr:request:}" == '')  = noop
(0)     } # policy debug_request = noop
(0)     update request {
(0)       &Tmp-String-2 := &Tmp-String-1[2] -> 'c'
(0)     } # update request = noop

^^ Extracted index 2 from &Tmp-String-1 is "c".

As it breaks up (and removes) the original attribute you may want to 
copy it to a temporary attribute before exploding, if you want to use it 
again.


Most configs use regexes to do this, so that's another option to 
consider. You'll see a number of examples of how to do that in the 
default config, especially in the policy.d directory.

-- 
Matthew


More information about the Freeradius-Users mailing list