advice for breaking an array of vendor attributes into local attributes and updating a database
Greetings FR-users, Scenario: I receive an accounting packet from a Cisco NAS. It has an array of Cisco-AVPair tuples that FR processes. I am hoping to break out the various Cisco-AVPair tuples into key-value pairs to insert into a database. I am starting with a single (and specific) Cisco-AVPair. Snippets of freeradius -X follows... Here is the AVP in the accounting packet... (23) Cisco-AVPair = "mdm-tlv=device-platform-version=10.0.18363 " Here is my unlang... (23) elsif ("%{Foreach-Variable-0}" =~ /^mdm-tlv=device-platform-version=(.*?) *$/) { (23) update reply { (23) EXPAND %{1} (23) --> 10.0.18363 (23) &Local-MDM-TLV-Device-Platform-Version := 10.0.18363 (23) } # update reply = noop Here is the SQL... (23) sql_netdb: EXPAND UPDATE radius_accounting SET [...] cisco_device_platform_version = NULLIF('%{Local-MDM-TLV-Device-Platform-Version}', '') [...] WHERE AcctUniqueId = '%{Acct-Unique-Session-Id}' AND AcctStopTime IS NULL (23) sql_netdb: --> UPDATE radius_accounting SET [...] cisco_device_platform_version = NULLIF('', '') [...] WHERE AcctUniqueId = 'FOOBAR' AND AcctStopTime IS NULL You can see the attribute Local-MDM-TLV-Device-Platform-Version is the empty string in the SQL. I am having success with the foreach statement and a regex. In my default site: accounting { [...] foreach Cisco-AVPair { if ("%{Foreach-Variable-0}" =~ /^mdm-tlv=device-platform-version=(.*?) *$/) { update reply { &Local-MDM-TLV-Device-Platform-Version := "%{1}" } } } [...] } My dictionary looks like: ATTRIBUTE Local-MDM-TLV-Device-Platform-Version 7772 string Am I using the wrong section in my default site for attempting to set a local (internal) attribute? I know that I am using "update reply" in my unlang. That doesn't feel correct for accounting unlang, but I'll need correction or confirmation in that area. Any advice for breaking an array of vendor attributes into local attributes and then updating a database with those local attributes? Thank you for any help or hints! -m
On 16/02/2021 22:53, Matt Zagrabelny via Freeradius-Users wrote:
I receive an accounting packet from a Cisco NAS. It has an array of Cisco-AVPair tuples that FR processes.
Ah yes, Cisco's standard "can't be bothered to create proper dictionaries" junk.
I am hoping to break out the various Cisco-AVPair tuples into key-value pairs to insert into a database. I am starting with a single (and specific) Cisco-AVPair.
Snippets of freeradius -X follows...
Here is the AVP in the accounting packet... (23) Cisco-AVPair = "mdm-tlv=device-platform-version=10.0.18363 "
Generally speaking you can update /etc/raddb/dictionary and add a new entry that matches the "fake" Cisco key, e.g. ATTRIBUTE mdm-tlv 3000 string Then edit raddb/mods-enabled/preprocess and set with_cisco_vsa_hack = yes and call 'preprocess' in authorize (or accounting, if you need it there). You'll then get a new request attribute &mdm-tlv with the values from the Cisco-AVPair attribute. Given they've been doubly stupid and used two ='s in that string then you may come unstuck there, but if it's the only attribute in that format then this might solve it. Just add a local attribute for each of the names they used. Some of their equipment has options to use real attributes instead of the braindead stuff, so you might be able to dig around and find an option to turn that on instead.
Am I using the wrong section in my default site for attempting to set a local (internal) attribute?
Internal attributes are no different from other attributes, they just can't get sent out on the wire. Use the debug policies to view what's happening at a particular time, e.g. debug_reply or debug_all see policys.d/debug
I know that I am using "update reply" in my unlang. That doesn't feel correct for accounting unlang, but I'll need correction or confirmation in that area.
It'll get cleared before the response is sent, so it's fine to use as a temporary location. -- Matthew
participants (2)
-
Matt Zagrabelny -
Matthew Newton