FreeRADIUS 3.0.12, Ubuntu 16.04 - Python module is unable to load

Alan Buxey alan.buxey at
Mon Jul 3 20:29:24 CEST 2017

   if ("%{sql:SELECT sessions...}" >= "%{ldap:get maxconnection}") {

yep - the only 'magic' here is that you have to ensure that the SQL
and LDAP modules are correctly configured to talk to the right DB and
and then the SELECT and LDAP queries need to be correctly constructed
to get you the unique single values that you want.
a LOT of that last part can be done using command line tools....then
stick them into the server and check in full debug to see what
is actually occurring at that unlang step. FreeRADIUS with unlang is a
totally configurable beast.


On 3 July 2017 at 12:03, Alan DeKok <aland at> wrote:
> On Jul 3, 2017, at 1:52 AM, Cuong Nguyen <cuong.nguyenduy at> wrote:
>> Let me explain what I try to do:
>> 1. I'd want to limit a number of concurrent sessions a user is allowed. In
>> LDAP, there is an attribute - MaxConnection - to indicate maximum
>> concurrent sessions a user can have
>   OK...
>> 2. Since FreeRADIUS does not keep track of the number of sessions,
>   Uh... what?
>   FreeRADIUS writes session data to a database.  You can query the database from FreeRADIUS.  This is even documented with examples in the default configuration.
>> my
>> script will perform the following
>> - POST-AUTH: For the user, get the number of sessions in MySQL, and get the
>> MaxConnection from LDAP, then compare the two. If there are sessions >=
>> MaxConnection --> Reject
>   That's threelines of unlang:
>         if ("%{sql:SELECT sessions...}" >= "%{ldap:get maxconnection}") {
>                 reject
>         }
>   The only "magic" here is writing the correct SQL select query, and writing the correct LDAP query to get MaxConnection for a user.
>   And those two queries are just normal SQL / LDAP queries.  You can write them and test them in an SQL or LDAP tool, and then just copy them to FreeRADIUS.  Replace the actual user name with %{User-Name}, and you're good to go.
>> - ACCOUTING: If it is Accounting-Start --> Record in MySQL, if
>> Accounting-Interim --> Update in MySQL, if Accounting-Stop --> Delete in
>> MySQL
>   The default SQL module already does this.  It's documented as doing this.  There are tons of examples available.
>   Why are you re-inventing this?
>> Second, I did look at the LDAP module, but have no clue how to implement
>> the logic I describe above. In my debug output above, I *did* include sql
>> for the purpose of testing. In actual deployment, this will not be used
>> (MySQL operations will be done by the script).
>> I even tried this in LDAP module in order to get the MaxConnection, which
>> changes the 'request' list.
>> ldap {
>>    # TESTING
>>    request:Tmp-String-1            := 'MaxConnection'
>> }
>   What made you think that would work?  You're just trying random things in random places.  And, ignoring all of the available documentation.
>> Any suggestion is appreciated.
>   Read the documentation and examples.  Read the Wiki.  Look for "Simultaneous-Use", which does exactly this...
>   Alan DeKok.
> -
> List info/subscribe/unsubscribe? See

More information about the Freeradius-Users mailing list