3.0.8: Matching request attribute against multiple check items using unlang

Adam Hammond adam.hammond at wicoms.com
Thu Jun 25 16:57:36 CEST 2015


Hi list,

I need your help again. 

I am revisiting a solution I had worked out using version 2.x and the 'checkval' module: I had the module checking the Calling-Station-Id attribute in the request against multiple values I had added for a user in the 'radcheck' table. e.g.

radcheck:

id |  username   |     attribute   	     | op |              value
----+----------------+----------------------+----+----------------------------------
 1 | callingtest | MD5-Password     | :=  | ae2b1fca515949e5d54fb22b8ed95575
 2 | callingtest | Calling-Station-Id | += | 07-08-09-04-05-06
 3 | callingtest | Calling-Station-Id | += | 01-02-03-04-05-06
 4 | callingtest | Calling-Station-Id | += | 11-11-11-22-22-22

Only if the attribute in the request matched any of these entries could the request be granted. It worked well.

Noting that this module has been removed in 3.x and that I should use unlang instead I have been trying to make this work and have got stuck. I haven't been able to find a solution looking through the list archives and I've probably misunderstood how unlang works somehow.

Testing my solution thus far, and using the same entries in radcheck as above, only a request with a Calling-Station-Id that matches the value with the lowest id in radcheck gets accepted - the first attribute of it's name in the control list.

Here is my messy unlang attempt. Reject a request unless I can match the Calling-Station-Id. 
NOTE: I've expanded the attributes in the if statement to show you what I mean in the debug output below.

authorize {
       sql
       pap

       update control {
               Auth-Type := "Reject"
       }
       foreach &control:Calling-Station-Id {
               if ("%{request:Calling-Station-Id}" == "%{control:Calling-Station-Id}") {
                       update control {
                               Auth-Type := "Accept"
                       }
                       break
               }
       }

       debug_control
}

NOTE: 'break' doesn't seem to do what I'm expecting it to here (break out of the for loop) so should I just remind myself unlang isn't a programming language (not that I'm a coder) and not try such things? If I put it before the update command then the update isn't executed either: it seems to be breaking the if statement.

In debug the server appears to be looping through the entries the right number of times (if I have x number of Called-Station-Id entries in radcheck for the user then it loops x times) and the control list certainly has all the entries in it, yet only the first is ever checked and therefore matched.

Any pointers to what I'm doing wrong most appreciated.

Cheers in advance,
Adam

Debug splurge (2 requests, both which should be accepted. Output edited for the sake of brevity)

Received Access-Request Id 30 from 10.0.10.30:39227 to 10.0.10.31:31812 length 107
	User-Name = 'callingtest'
	User-Password = 'testing'
	Acct-Session-Id = '5371b4ba00000008'
	Calling-Station-Id = '01-02-03-04-05-06'
	Called-Station-Id = '00-01-C0-12-36-88'
(0) Received Access-Request packet from host 10.0.10.30 port 39227, id=30, length=107
(0) 	User-Name = 'callingtest'
(0) 	User-Password = 'testing'
(0) 	Acct-Session-Id = '5371b4ba00000008'
(0) 	Calling-Station-Id = '01-02-03-04-05-06'
(0) 	Called-Station-Id = '00-01-C0-12-36-88'
(0) # Executing section authorize from file /etc/raddb/sites-enabled/test
(0)   authorize {

… edited out…

(0)   [sql] = ok
(0)  pap : Normalizing MD5-Password from hex encoding, 32 bytes -> 16 bytes
(0)   [pap] = updated
(0)   update control {
(0) 	Auth-Type := Reject
(0)   } # update control = noop
(0)   foreach &control:Calling-Station-Id
(0)     if ("%{request:Calling-Station-Id}" == "%{control:Calling-Station-Id}")
(0) EXPAND %{control:Calling-Station-Id}
(0)    --> 07-08-09-04-05-06
(0) EXPAND %{request:Calling-Station-Id}
(0)    --> 01-02-03-04-05-06
(0)     if ("%{request:Calling-Station-Id}" == "%{control:Calling-Station-Id}")  -> FALSE
(0)     if ("%{request:Calling-Station-Id}" == "%{control:Calling-Station-Id}")
(0) EXPAND %{control:Calling-Station-Id}
(0)    --> 07-08-09-04-05-06
(0) EXPAND %{request:Calling-Station-Id}
(0)    --> 01-02-03-04-05-06
(0)     if ("%{request:Calling-Station-Id}" == "%{control:Calling-Station-Id}")  -> FALSE
(0)     if ("%{request:Calling-Station-Id}" == "%{control:Calling-Station-Id}")
(0) EXPAND %{control:Calling-Station-Id}
(0)    --> 07-08-09-04-05-06
(0) EXPAND %{request:Calling-Station-Id}
(0)    --> 01-02-03-04-05-06
(0)     if ("%{request:Calling-Station-Id}" == "%{control:Calling-Station-Id}")  -> FALSE
(0)   } # foreach &control:Calling-Station-Id = updated
(0)   debug_control debug_control {
(0)     if ("%{debug_attr:control:}" == '')
(0) Attributes matching "control:"
(0) 	control:MD5-Password = 0xae2b1fca515949e5d54fb22b8ed95575
(0) 	control:Calling-Station-Id = '07-08-09-04-05-06'
(0) 	control:Calling-Station-Id = '01-02-03-04-05-06'
(0) 	control:Calling-Station-Id = '11-11-11-22-22-22'
(0) 	control:Auth-Type := Reject
(0) EXPAND %{debug_attr:control:}
(0)    -->
(0)     if ("%{debug_attr:control:}" == '')  -> TRUE
(0)    if ("%{debug_attr:control:}" == '')  {
(0)     [noop] = noop
(0)    } # if ("%{debug_attr:control:}" == '')  = noop
(0)   } # debug_control debug_control = noop
(0)  } #  authorize = updated
(0) Found Auth-Type = Reject
(0) Auth-Type = Reject, rejecting user
(0) Failed to authenticate the user
(0) Using Post-Auth-Type Reject
(0) Sending Access-Reject packet to host 10.0.10.30 port 39227, id=30, length=0
(0) 	Session-Timeout = 320
Sending Access-Reject Id 30 from 10.0.10.31:31812 to 10.0.10.30:39227
	Session-Timeout = 320
(0) Finished request
Waking up in 0.3 seconds.
Waking up in 4.6 seconds.
(0) Cleaning up request packet ID 30 with timestamp +4
Ready to process requests



Received Access-Request Id 78 from 10.0.10.30:34511 to 10.0.10.31:31812 length 107
	User-Name = 'callingtest'
	User-Password = 'testing'
	Acct-Session-Id = '5371b4ba00000007'
	Calling-Station-Id = '07-08-09-04-05-06'
	Called-Station-Id = '00-01-C0-12-36-88'
(1) Received Access-Request packet from host 10.0.10.30 port 34511, id=78, length=107
(1) 	User-Name = 'callingtest'
(1) 	User-Password = 'testing'
(1) 	Acct-Session-Id = '5371b4ba00000007'
(1) 	Calling-Station-Id = '07-08-09-04-05-06'
(1) 	Called-Station-Id = '00-01-C0-12-36-88'
(1) # Executing section authorize from file /etc/raddb/sites-enabled/test
(1)   authorize {

… edited out …

(1)   [sql] = ok
(1)  pap : Normalizing MD5-Password from hex encoding, 32 bytes -> 16 bytes
(1)   [pap] = updated
(1)   update control {
(1) 	Auth-Type := Reject
(1)   } # update control = noop
(1)   foreach &control:Calling-Station-Id
(1)     if ("%{request:Calling-Station-Id}" == "%{control:Calling-Station-Id}")
(1) EXPAND %{control:Calling-Station-Id}
(1)    --> 07-08-09-04-05-06
(1) EXPAND %{request:Calling-Station-Id}
(1)    --> 07-08-09-04-05-06
(1)     if ("%{request:Calling-Station-Id}" == "%{control:Calling-Station-Id}")  -> TRUE
(1)    if ("%{request:Calling-Station-Id}" == "%{control:Calling-Station-Id}")  {
(1)     update control {
(1) 	Auth-Type := Accept
(1)     } # update control = noop
(1)      # break Foreach-Variable-0
(1)    } # if ("%{request:Calling-Station-Id}" == "%{control:Calling-Station-Id}")  = noop
(1)     # unwind to enclosing foreach
(1)     if ("%{request:Calling-Station-Id}" == "%{control:Calling-Station-Id}")
(1) EXPAND %{control:Calling-Station-Id}
(1)    --> 07-08-09-04-05-06
(1) EXPAND %{request:Calling-Station-Id}
(1)    --> 07-08-09-04-05-06
(1)     if ("%{request:Calling-Station-Id}" == "%{control:Calling-Station-Id}")  -> TRUE
(1)    if ("%{request:Calling-Station-Id}" == "%{control:Calling-Station-Id}")  {
(1)     update control {
(1) 	Auth-Type := Accept
(1)     } # update control = noop
(1)      # break Foreach-Variable-0
(1)    } # if ("%{request:Calling-Station-Id}" == "%{control:Calling-Station-Id}")  = noop
(1)     # unwind to enclosing foreach
(1)     if ("%{request:Calling-Station-Id}" == "%{control:Calling-Station-Id}")
(1) EXPAND %{control:Calling-Station-Id}
(1)    --> 07-08-09-04-05-06
(1) EXPAND %{request:Calling-Station-Id}
(1)    --> 07-08-09-04-05-06
(1)     if ("%{request:Calling-Station-Id}" == "%{control:Calling-Station-Id}")  -> TRUE
(1)    if ("%{request:Calling-Station-Id}" == "%{control:Calling-Station-Id}")  {
(1)     update control {
(1) 	Auth-Type := Accept
(1)     } # update control = noop
(1)      # break Foreach-Variable-0
(1)    } # if ("%{request:Calling-Station-Id}" == "%{control:Calling-Station-Id}")  = noop
(1)     # unwind to enclosing foreach
(1)   } # foreach &control:Calling-Station-Id = noop
(1)   debug_control debug_control {
(1)     if ("%{debug_attr:control:}" == '')
(1) Attributes matching "control:"
(1) 	control:MD5-Password = 0xae2b1fca515949e5d54fb22b8ed95575
(1) 	control:Calling-Station-Id = '07-08-09-04-05-06'
(1) 	control:Calling-Station-Id = '01-02-03-04-05-06'
(1) 	control:Calling-Station-Id = '11-11-11-22-22-22'
(1) 	control:Auth-Type := Accept
(1) EXPAND %{debug_attr:control:}
(1)    -->
(1)     if ("%{debug_attr:control:}" == '')  -> TRUE
(1)    if ("%{debug_attr:control:}" == '')  {
(1)     [noop] = noop
(1)    } # if ("%{debug_attr:control:}" == '')  = noop
(1)   } # debug_control debug_control = noop
(1)  } #  authorize = updated
(1) Found Auth-Type = Accept
(1) Auth-Type = Accept, accepting the user
(1) Found Auth-Type = Accept
(1) Auth-Type = Accept, accepting the user
(1) Sending Access-Accept packet to host 10.0.10.30 port 34511, id=78, length=0
(1) 	Session-Timeout = 320
Sending Access-Accept Id 78 from 10.0.10.31:31812 to 10.0.10.30:34511
	Session-Timeout = 320
(1) Finished request





More information about the Freeradius-Users mailing list