If statement is not evaluated consistently
Asked Answered
Q

1

6

Here is the code snippet I have deployed in copy-acct-to-home-server. Which basically checks if the username has "@" sign... if yes then it extracts huntgroup from mysql table comparing NAS-IP-Address. And finally if the result from the query is not null then it updates Proxy-to-Realm.

if(request:User-Name =~ /@/){
    update control {
        SQLQueryResult := "%{sql:SELECT `groupname` FROM `radhuntgroup` WHERE nasipaddress='%{NAS-IP-Address}'}"
    }
    if (%{control:SQLQueryResult} != '') {
        update control {
            Proxy-To-Realm := SQLQueryResult } }
        }

This code is not working as I would expect. Here is the debug message snippet outcome for both true and false conditions

When some value is extracted from the database the proxy-to-realm should have been assigned the proper value (but it's not working)

 Acct-Session-Id = "5CD8CA8B-0012B000"
    Framed-IP-Address = host.ip.address.local
    Acct-Multi-Session-Id = "24c9a18012b85c514f44f9715cd8ca8b085b"
    Acct-Link-Count = 1
    Acct-Status-Type = Start
    Acct-Authentic = RADIUS
    User-Name = "[email protected]"
    NAS-IP-Address = some.ip.add.NAS
    NAS-Identifier = "CustomNASID"

   .........



    --> [email protected]
(6)         SQL-User-Name set to '[email protected]'
rlm_sql (sql): Reserved connection (5)
(6)         EXPAND /var/log/freeradius/sqllog.sql
(6)            --> /var/log/freeradius/sqllog.sql
(6)         Executing select query: SELECT `groupname` FROM `radhuntgroup` WHERE nasipaddress='some.ip.add.NAS'
rlm_sql (sql): Released connection (5)
(6)         EXPAND %{sql:SELECT `groupname` FROM `radhuntgroup` WHERE nasipaddress='%{NAS-IP-Address}'}
(6)            --> customRealm
(6)         SQLQueryResult := customRealm
(6)       } # update control = noop
(6)       if ( %{control:SQLQueryResult} != '') {
(6)       if ( %{control:SQLQueryResult} != '')  -> TRUE
(6)       if ( %{control:SQLQueryResult} != '')  {
(6)         update control {
(6)           No attributes updated
(6)         } # update control = noop
(6)       } # if ( %{control:SQLQueryResult} != '')  = noop
(6)     } # if (request:User-Name =~ /@/) = noop
(6)   } # preacct = ok

As could be seen from the log it is not updating the attribute proxy-to-realm with the value fetched from the database even though both the if conditions are true (the username contains @ and SQLQueryResult is not null)

If condition seems to be true even when there is no value fetched from the database. Here is the log snippet.

 Acct-Session-Id = "5CD8C9F7-C1DA2D04"
    Framed-IP-Address = host.ip.address.local
    Acct-Multi-Session-Id = "441e98b16388185680b4a7355cd8c9f7000a"
    Acct-Link-Count = 5
    Acct-Status-Type = Interim-Update
    Acct-Authentic = RADIUS
    User-Name = "user@somedomain"
    NAS-IP-Address = some.ip.address.nas


   ...........



    Executing section preacct from file /etc/freeradius/3.0/sites-enabled/copy-acct-to-home-server
(8)   preacct {
(8)     [preprocess] = ok
(8)     if (request:User-Name =~ /@/){
(8)     if (request:User-Name =~ /@/) -> TRUE
(8)     if (request:User-Name =~ /@/) {
(8)       update control {
(8)         EXPAND %{User-Name}
(8)            --> [email protected]
(8)         SQL-User-Name set to '[email protected]'
rlm_sql (sql): Reserved connection (6)
(8)         EXPAND /var/log/freeradius/sqllog.sql
(8)            --> /var/log/freeradius/sqllog.sql
(8)         Executing select query: SELECT `groupname` FROM `radhuntgroup` WHERE nasipaddress='nas.ip.address.local'
(8)         SQL query returned no results
rlm_sql (sql): Released connection (6)
(8)         EXPAND %{sql:SELECT `groupname` FROM `radhuntgroup` WHERE nasipaddress='%{NAS-IP-Address}'}
(8)            --> 
(8)         SQLQueryResult := 
(8)       } # update control = noop
(8)       if ( %{control:SQLQueryResult} != '') {
(8)       if ( %{control:SQLQueryResult} != '')  -> TRUE
(8)       if ( %{control:SQLQueryResult} != '')  {
(8)         update control {
(8)           No attributes updated
(8)         } # update control = noop
(8)       } # if ( %{control:SQLQueryResult} != '')  = noop
(8)     } # if (request:User-Name =~ /@/) = noop
(8)   } # preacct = ok

The strange thing is although it is not fetching any value from the db second if condition is being evaluated as true if (SQLQueryResult != '') should have been false in this case.

the attribute SQLQueryResult has been defined in the dictionary as string.

I am not sure what I am missing here... seems to be straightforward logic. Requesting help from the experts.

Quiche answered 13/5, 2019 at 2:5 Comment(2)
Check it by using !~ instead of !=Aflcio
hi @Siavas, I tried this but is not working... I think we can just include update control only once in a event script. But need to figure out how can we execute more than one query with in one update control statement that too with if conditions. Has been a bit frustrating time.Quiche
E
0

There are a couple of issues here.

First, closing braces of sections should always be on a new line. The config parser isn't great, and that might be tripping it up.

Second you're mixing attribute reference and expansion syntax.

if( %{control:SQLQueryResult} != '') {

The above isn't valid. Honestly I'm surprised the expression parser isn't throwing an error. It's probably because there are no spaces in %{control:SQLQueryResult} so it's treating it a string literal, and then comparing the string literal to an empty string.

You either need to wrap the expansion in double quotes

if ("%{control:SQLQueryResult}" != '') {

or use the attribute reference form

if (&control:SQLQueryResult != '') {

I'm fairly certain that's what's causing your issue.

Equation answered 30/10, 2019 at 23:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.