anti-multiple-login patches for radiusd (fwd)

Brian 'MegaZone' Bikowicz ((no email))
Sun, 15 Oct 1995 15:02:34 -0700 (PDT)

Once upon a time Chris B. Wilson, VectorNet shaped the electrons to say...
>Has anyone put together any patches to prevent multiple logins to a
>Portmaster?

Here are some pointers on how to modify radiusd 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. A future version of radiusd will likely include something
like this, but if you don't want to wait for it here's information on
doing it yourself.

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

(optional):
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 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.

In radiusd.c:

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 he doesn't have an
entry, call send_accept to accept him. If he 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 OKing him and having
his start of service accounting record come in, and he could log in
a second time during those few seconds, but I'd rather 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.

-MZ

--
Livingston Enterprises Technical Support
Phone: 800-458-9966      FAX: 510-426-8951
support@livingston.com  <http://www.livingston.com/> 
6920 Koll Center Parkway  #220, Pleasanton, CA 94566