Not at this time, it is planned but other OSs are before it in line.
>Is there a possibility to deny the same user to login twice ?
Not with defaults. You can try this:
---cut---
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.
---cut---
>Are there utility programs to stat the PM work and users accounting (in perl
>for example).
If you use Radius accounting you can use some:
---cut---
RADIUS 1.16 is included in the 3.1 release (3.1.2 is the latest).
RADIUS 1.16 adds support for RADIUS Accounting (requires ComOS 3.1),
hooks for Challenge/Response via the new Access-Challenge packet type,
and ports to Alpha OSF/1, BSDI BSD/386, Linux, SCO, and Unixware
It already ran on SunOS, Solaris, AIX, HP/UX and Ultrix. It includes
a new /etc/raddb/dictionary file that defines the additional attributes
required for Accounting support.
There is now a -v flag to print the version and an -a flag to specify
an alternative accounting directory, the same way -d specifies an
alternative raddb directory.
To use RADIUS Accounting install the new radiusd and dictionary file,
then use the "set accounting" command on any PortMasters running ComOS 3.1
or later.
RADIUS Accounting
RADIUS Accounting has been added in ComOS 3.1 and RADIUS 1.16.
The three big improvements over using syslog accounting records are:
1. Unique accounting IDs to make it easier to match start and end records.
2. Elapsed time recorded in end record so you don't have to match start
and end records to produce billing information
3. Up to 100 records are buffered in the PortMaster until acknowledged as
received by the accounting server.
RADIUS Accounting uses the RADIUS protocol for its packet format and
adds Attributes to handle the additional information needed for
accounting. The Accounting Server listens for UDP packets at port
1646, and is not required to run on the same host as the RADIUS server,
although that can be done and is often convenient. A Backup Accounting
Server is supported.
Accounting records are buffered until acknowledged. The PortMaster
sends an Accounting-Request packet to the Accounting Server, which
sends back an Accounting-Response packet to acknowledge that it has
received that record. The PortMaster will keep the record and continue
sending Accounting-Requests until it receives an Accounting-Response.
An exponential backoff algorithm is used since accounting records do
not have the time-critical nature of Access-Requests (there's no user
waiting on the transaction). The Acct-Delay-Time attribute tells how
many seconds have passed between the event generating the record and
the current attempt to send the record.
In addition to the accounting attributes, various RADIUS attributes are
included in the accounting packets to describe the type of service provided.
A formal description of RADIUS Accounting is available in an Internet-Draft
on ftp://ftp.livingston.com/pub/radius/draft-ietf-radius-accounting-00.txt
Here are the Attributes that Accounting adds:
ATTRIBUTE Acct-Status-Type 40 integer
Start 1
Stop 2
A Start record is sent when service begins, and a Stop
record is sent when service ends.
ATTRIBUTE Acct-Delay-Time 41 integer
Acct-Delay-Time is how many seconds the PortMaster has been trying to
submit this record for, and should be subtracted from the time of
arrival to find the approximate time of the event (it'll actually
be the time of the event plus transit time of this packet through
the network.)
ATTRIBUTE Acct-Session-Id 44 string
Acct-Session-ID is a unique Accounting ID to make it easy to match
records up in a logfile. The Start and Stop records for a given
session have the same Acct-Session-Id.
In our implementation on the PortMaster we use a string of an 8-digit
uppercase hexadecimal number, the first two digits increment on each
reboot (wrapping after 256 reboots, which for a PortMaster in normal
service should take decades) and the next 6 digits counting from 0 for
the first person logging in after a reboot up to 2^24-1, about 16
million, or one person logging in per port per minute for an entire
year on a 30-port unit.
ATTRIBUTE Acct-Authentic 45 integer
RADIUS 1
Local 2
Acct-Authentic is how the user was authenticated, whether by
RADIUS or by the local User Table in the PortMaster.
Passthrough users do not generate Accounting records, since they
are authenticated by the host.
ATTRIBUTE Acct-Session-Time 46 integer
Acct-Session-Time is how many seconds the user was connected
for, and is only present in Stop records.
Restrictions
A future release will implement Acct-Input-Octets (42) and
Acct-Output-Octets (43).
Acct-Session-Time is not accurate for "!root" administrative logins.
Framed-Compression is not included in Accounting records.
Examples
Here are some examples of the RADIUS accounting output.
We log the records for each PortMaster into its own file under
/usr/adm/radacct/{portmaster-hostname}/detail but that location can be
changed with the -a flag. The timestamps are generated by the host
running the accounting server.
We provide source to both the RADIUS server and RADIUS accounting
server so if you want to modify this output you'll be able to do so; in
particular large sites may want to make calls to SQL or other database
routines rather than printing to an ASCII text file.
Wed Oct 5 22:00:55 1994
Acct-Session-Id = "06000003"
User-Name = "carl"
Client-Id = 149.198.1.18
Client-Port-Id = 19
Acct-Status-Type = Start
Acct-Authentic = RADIUS
User-Service-Type = Login-User
Login-Service = PortMaster
Login-Host = 149.198.1.70
Acct-Delay-Time = 0
Wed Oct 5 23:15:31 1994
Acct-Session-Id = "06000003"
User-Name = "carl"
Client-Id = 149.198.1.18
Client-Port-Id = 19
Acct-Status-Type = Stop
Acct-Session-Time = 4480
Acct-Authentic = RADIUS
User-Service-Type = Login-User
Login-Service = PortMaster
Login-Host = 149.198.1.70
Acct-Delay-Time = 0
Thu Oct 6 16:14:53 1994
Acct-Session-Id = "06000004"
User-Name = "Pdan"
Client-Id = 149.198.1.18
Client-Port-Id = 19
Acct-Status-Type = Start
Acct-Authentic = Local
User-Service-Type = Framed-User
Framed-Protocol = PPP
Framed-IPX-Network = 108.144.16.16
Acct-Delay-Time = 0
Thu Oct 6 16:15:57 1994
Acct-Session-Id = "06000004"
User-Name = "Pdan"
Client-Id = 149.198.1.18
Client-Port-Id = 19
Acct-Status-Type = Stop
Acct-Session-Time = 64
Acct-Authentic = Local
User-Service-Type = Framed-User
Framed-Protocol = PPP
Framed-IPX-Network = 108.144.16.16
Acct-Delay-Time = 0
---- Attachment
ACCOUNTING
You'll see two radiusd processes running when you run radiusd 1.16;
the child is a RADIUS accounting server.
To use RADIUS accounting you must use ComOS 3.1 (or later) and RADIUS 1.16.
Set up the client as described above, then use "set accounting <address>"
on the PortMaster to set an accounting server, and optionally
"set accounting 2 <address2>" to set up a backup accounting server.
Both local User Table entries and RADIUS entries get logged via
accounting, but passthrough entries do NOT get logged.
You should see accounting records showing up in
/usr/adm/radacct/{portmastername}/detail.
Troubleshooting Checklist for RADIUS Accounting:
Make sure the directory /usr/adm/radacct exists and is writeable by
whatever uid you're running radiusd as.
Make sure the radiusd you're running is 1.16, use the -v flag to check.
Make sure that you don't have any other process bound to port 1646.
Kill radiusd and use netstat -a, there shouldn't be anything on
1645 or 1646. Start radiusd and use netstat -a again; you should now
see something listening on both those ports.
make sure you've done "set accounting <address>" on the PortMaster,
where <address> is the IP address of the host running radiusd.
You can check with "show global".
Check /etc/raddb/logfile for error messages. In normal use it should
be non-existent or empty or have a few log messages about duplicate IDs.
ping the PortMaster from your radiusd host to make sure there's connectivity.
If none of that turns up the problem, run radiusd -x on your UNIX host
and see if accounting records are displayed.
---- Attachment
#!/usr/local/bin/perl
# raquick - create a quick summary of RADIUS Accounting detail file
#
# 94/11/28 Author: Carl Rigney; cdr@livingston.com
# 94/12/03 last modified
#
# input files = /usr/adm/radacct/*/detail
# Currently must specify only one input file as an argument
#
# output format is username followed by hours:minutes:seconds
# dave 1:36:48
$/ = ''; # read paragraph at a time
while (<>) {
next if /Acct-Session-Id = "00000000"/;
if (/Acct-Status-Type = Stop/) {
if (/Acct-Session-Id = "([^"]+)"/) {
$id = $1;
if ($seen{$id}++) {
$dup++;
next;
}
} else {
$err{'No ID'}++;
next;
}
if (/User-Name = "([^"]+)"/) {
$user = $1;
if (/Acct-Session-Time = (\d+)/) {
$elapsed = $1;
if ($elapsed > 0) {
$used{$user} += $elapsed;
}
}
}
}
}
print "# $dup duplicates\n" if $dup;
print "# $err{'No ID'} stop records without Acct-Session-ID\n" if $err{'No Id'};
for $user (sort keys %used) {
printf "%-16s\t%s\n",$user,&hms($used{$user});
}
sub hms {
local($h,$m);
local ($s) = shift(@_);
$m = int($s / 60);
$s = $s % 60;
$h = int($m / 60);
$m = $m % 60;
sprintf("%4d:%02d:%02d",$h,$m,$s);
}
---- Attachment
#!/usr/local/bin/perl
# raport - create a quick port-by-port summary of RADIUS Accounting detail files
#
# 94/12/04 Author: Carl Rigney; cdr@livingston.com
#
# input files = /usr/adm/radacct/*/detail
#
# output:
# 158.222.1.9 0 361 147:36:27
# PortMaster, Port, number of accesses, total elapsed time used
$/ = ''; # read paragraph at a time
while (<>) {
next if /Acct-Session-Id = "00000000"/;
if (/Acct-Status-Type = Stop/) {
if (/Acct-Session-Id = "([^"]+)"/) {
$id = $1;
if (/Client-Id = (\S+)/) {
$nas = $1;
$id .= '@'.$nas;
if ($seen{$id}++) {
$dup++;
next;
}
}
} else {
$err{'No ID'}++;
next;
}
if (/Client-Id = (\S+)/) {
$nas = $1;
if (/Client-Port-Id = (\d+)/) {
$port = $1;
$user = sprintf("%s\t%2d",$nas,$port);
if (/Acct-Session-Time = (\d+)/) {
$elapsed = $1;
if ($elapsed > 0) {
$uses{$user}++;
$used{$user} += $elapsed;
}
}
}
}
}
}
print "# $dup duplicates\n" if $dup;
print "# $err{'No ID'} stop records without Acct-Session-ID\n" if $err{'No Id'};
for $user (sort keys %used) {
printf "%-16s\t%4d\t%s\n",$user,$uses{$user},&hms($used{$user});
}
sub hms {
local($h,$m);
local ($s) = shift(@_);
$m = int($s / 60);
$s = $s % 60;
$h = int($m / 60);
$m = $m % 60;
sprintf("%4d:%02d:%02d",$h,$m,$s);
}
---cut---
-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