Thank you all, I poked around with unlang and were able to fulfill my requirement with LDAP and MySQL, as shown below: *- /etc/freeradius/mods-enabled/ldap* ldap { update { .... control:Tmp-Integer-9 := 'MaxConnection' } } *- /etc/freeradius/sites-enabled/default* authorize { ... ldap if ("%{sql:SELECT COUNT(*) FROM radacct WHERE username LIKE '%{%{Stripped-User-Name}:-%{User-Name}}@%%.%%' AND acctstoptime IS NULL}"
= %{control:Tmp-Integer-9}){ reject } }
My intention to use "control:Tmp-Integer-9" is to reduce the number of queries to LDAP. I realized that radacct still keeps records for sessions that have "Accounting Stop", hence "AND acctstoptime IS NULL " is needed. Will play with unlang further to get better idea how it works. *Back to my original question*, is there anything I could do to make python loads ldap3 package successfully? I don't need it for the original purposes, but I may in future. Cheers, Cuong. On Tue, Jul 4, 2017 at 2:30 AM Alan Buxey <alan.buxey@gmail.com> wrote:
if ("%{sql:SELECT sessions...}" >= "%{ldap:get maxconnection}") { reject }
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 LDAP 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.
alan
On Jul 3, 2017, at 1:52 AM, Cuong Nguyen <cuong.nguyenduy@gmail.com> 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 http://www.freeradius.org/list/users.html
On 3 July 2017 at 12:03, Alan DeKok <aland@deployingradius.com> wrote: - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html