/*
* $Id: acct.c,v 1.4 2006/07/18 17:47:25 heas Exp $
*
* Copyright (c) 1995-1998 by Cisco systems, Inc.
*
* Permission to use, copy, modify, and distribute this software for
* any purpose and without fee is hereby granted, provided that this
* copyright and permission notice appear on all copies of the
* software and supporting documentation, the name of Cisco Systems,
* Inc. not be used in advertising or publicity pertaining to
* distribution of the program without specific prior permission, and
* notice be given in supporting documentation that modification,
* copying and distribution is by permission of Cisco Systems, Inc.
*
* Cisco Systems, Inc. makes no representations about the suitability
* of this software for any purpose. THIS SOFTWARE IS PROVIDED ``AS
* IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE.
*/
#include "tac_plus.h"
/*
* Come here when we receive an Start Accounting packet
*/
static void account(u_char *);
void
accounting(u_char *pak)
{
struct acct *acct_pak;
u_char *p;
HDR *hdr;
u_char *read_packet();
int i, len;
if (debug & DEBUG_ACCT_FLAG)
report(LOG_DEBUG, "Start accounting request");
hdr = (HDR *) pak;
acct_pak = (struct acct *) (pak + TAC_PLUS_HDR_SIZE);
/* Do some sanity checking on the packet */
/* arg counts start here */
p = pak + TAC_PLUS_HDR_SIZE + TAC_ACCT_REQ_FIXED_FIELDS_SIZE;
/* Length checks */
len = TAC_ACCT_REQ_FIXED_FIELDS_SIZE;
len += acct_pak->user_len + acct_pak->port_len +
acct_pak->rem_addr_len + acct_pak->arg_cnt;
for (i = 0; i < (int)acct_pak->arg_cnt; i++) {
len += p[i];
}
if (len != ntohl(hdr->datalength)) {
send_error_reply(TAC_PLUS_ACCT, NULL);
return;
}
account(pak);
free(pak);
}
static void
account(u_char *pak)
{
struct acct *acct_pak;
u_char *p, *argsizep;
struct acct_rec rec;
struct identity identity;
char **cmd_argp;
int i, errors, status;
acct_pak = (struct acct *) (pak + TAC_PLUS_HDR_SIZE);
/* Fill out accounting record structure */
bzero(&rec, sizeof(struct acct_rec));
if (acct_pak->flags & TAC_PLUS_ACCT_FLAG_WATCHDOG)
rec.acct_type = ACCT_TYPE_UPDATE;
if (acct_pak->flags & TAC_PLUS_ACCT_FLAG_START)
rec.acct_type = ACCT_TYPE_START;
if (acct_pak->flags & TAC_PLUS_ACCT_FLAG_STOP)
rec.acct_type = ACCT_TYPE_STOP;
rec.authen_method = acct_pak->authen_method;
rec.authen_type = acct_pak->authen_type;
rec.authen_service = acct_pak->authen_service;
/* start of variable length data is here */
p = pak + TAC_PLUS_HDR_SIZE + TAC_ACCT_REQ_FIXED_FIELDS_SIZE;
/* skip arg cnts */
p += acct_pak->arg_cnt;
/* zero out identity struct */
bzero(&identity, sizeof(struct identity));
identity.username = tac_make_string(p, (int)acct_pak->user_len);
p += acct_pak->user_len;
identity.NAS_name = tac_strdup(session.peer);
identity.NAS_port = tac_make_string(p, (int)acct_pak->port_len);
p += acct_pak->port_len;
if (acct_pak->port_len <= 0) {
strcpy(session.port, "unknown-port");
} else {
strcpy(session.port, identity.NAS_port);
}
identity.NAC_address = tac_make_string(p, (int)acct_pak->rem_addr_len);
p += acct_pak->rem_addr_len;
identity.priv_lvl = acct_pak->priv_lvl;
rec.identity = &identity;
/* Now process cmd args */
argsizep = pak + TAC_PLUS_HDR_SIZE + TAC_ACCT_REQ_FIXED_FIELDS_SIZE;
cmd_argp = (char **) tac_malloc(acct_pak->arg_cnt * sizeof(char *));
for (i = 0; i < (int)acct_pak->arg_cnt; i++) {
cmd_argp[i] = tac_make_string(p, *argsizep);
p += *argsizep++;
}
rec.args = cmd_argp;
rec.num_args = acct_pak->arg_cnt;
#ifdef MAXSESS
/*
* Tally for MAXSESS counting
*/
loguser(&rec);
#endif
/*
* Do accounting.
*/
if (wtmpfile) {
errors = do_wtmp(&rec);
} else {
errors = do_acct(&rec);
}
if (errors) {
status = TAC_PLUS_ACCT_STATUS_ERROR;
} else {
status = TAC_PLUS_ACCT_STATUS_SUCCESS;
}
send_acct_reply(status, rec.msg, rec.admin_msg);
free(identity.username);
free(identity.NAS_name);
free(identity.NAS_port);
free(identity.NAC_address);
for (i = 0; i < (int)acct_pak->arg_cnt; i++) {
free(cmd_argp[i]);
}
free(cmd_argp);
if (rec.msg)
free(rec.msg);
if (rec.admin_msg)
free(rec.admin_msg);
}
syntax highlighted by Code2HTML, v. 0.9.1