Limit Users To One Login
Here are some pointers on how to modify RADIUS (TM) 1.16 to only allow each user to log in once. This simple version doesn't handle power losses or having your UNIX server crash, dealing with those situations would be more complex.
You'll need to modify acct.c and radiusd.c.
In acct.c in the rad_accounting() function You'll want to look at the incoming packet and extract the following attributes:
PW_USER_NAME PW_CLIENT_ID PW_CLIENT_PORT_ID PW_ACCT_STATUS_TYPE PW_ACCT_SESSION_ID
If the first two characters of PW_ACCT_SESSION_ID are different for this PW_CLIENT_ID than they were for the last record you saw from this client, that means the PortMaster (TM) has been rebooted since its previous accounting record and you should go through your list of users for this client and consider them logged out.
Next, if PW_ACCT_STATUS_TYPE equals PW_STATUS_START and you don't have a stop entry for this user, add a start entry for this user, recording the client and port as well.
OR If PW_ACCT_STATUS_TYPE equals PW_STATUS_START and you do have a stop entry for this user on the same client and port, remove the stop entry.
OR If PW_ACCT_STATUS_TYPE equals PW_STATUS_STOP and you don't have a start entry for this user, add a stop entry for this user, recording the client and port as well.
OR If PW_ACCT_STATUS_TYPE equals PW_STATUS_STOP and you have a start entry for this user on the same client and port, remove the start entry.
OTHERWISE something's happened that you weren't expecting and you should write to your error log so a human can investigate.
Around line 264 don't spawn the accounting daemon even if spawn_flag is 1.
Around line 1073 in radiusd.c, in the rad_authenticate() function, just before you call send_accept, check whether the username (namepair->strvalue) already has a start entry. If it doesn't have an entry, call send_accept to accept it. If it does already have a start entry, that means he's logged in somewhere else, and you should set user_msg to be some string up to 127 characters long including a \r\n at the end telling him he appears to already be logged in, and call send_reject(authreq, user_msg, activefd) to reject him.
Note that there can be a brief delay between OK-ing him and having his start of service
accounting record come in, and he could log in a second time during those few seconds, but
it's probably better to err on the side of letting a customer on too many times once in a
while rather than reject him when he really shouldn't be rejected..
© 2000 Lucent Technologies. Use of this site indicates you accept the