void send_error_reply(int type, char *msg) { switch (type) { case TAC_PLUS_AUTHEN: send_authen_error(msg); return; case TAC_PLUS_AUTHOR: send_author_reply(AUTHOR_STATUS_ERROR, msg, NULL, 0, NULL); return; case TAC_PLUS_ACCT: send_acct_reply(TAC_PLUS_ACCT_STATUS_ERROR, msg, NULL); return; default: report(LOG_ERR, "Illegal type %d for send_error_reply", type); return; } /*NOTREACHED*/ return; }
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 = 0, status; acct_pak = (struct acct *) (pak + TAC_PLUS_HDR_SIZE); /* Fill out accounting record structure */ memset(&rec, 0, 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 */ memset(&identity, 0, 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); if (session.acctfile != NULL) errors += do_acct_file(&rec); if (session.flags & SESS_FLAG_ACCTSYSL) errors += do_acct_syslog(&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); }
void accounting(tac_session * session, tac_pak_hdr * hdr) { rb_tree_t *rbt = session->ctx->aaa_realm->acct; report(session, LOG_DEBUG, DEBUG_ACCT_FLAG, "Start accounting request"); if (rbt) { struct acct *acct = tac_payload(hdr, struct acct *); int i; char *acct_type, *username, *portname, *argstart, *msgid; u_char *argsizep; u_char *p = (u_char *) acct + TAC_ACCT_REQ_FIXED_FIELDS_SIZE + acct->arg_cnt; if (acct->flags & TAC_PLUS_ACCT_FLAG_STOP) acct_type = "stop", msgid = "ACCTSTOP"; else if (acct->flags & TAC_PLUS_ACCT_FLAG_START) acct_type = "start", msgid = "ACCTSTART"; else if (acct->flags & TAC_PLUS_ACCT_FLAG_WATCHDOG) acct_type = "update", msgid = "ACCTUPDATE"; else acct_type = "unknown", msgid = "ACCTUNKNOWN"; log_start(rbt, session->ctx->nas_address_ascii, msgid); log_write(rbt, (char *) p, acct->user_len); username = (char *) p; p += acct->user_len; log_write_separator(rbt); log_write(rbt, (char *) p, acct->port_len); portname = (char *) p; p += acct->port_len; log_write_separator(rbt); log_write(rbt, (char *) p, acct->rem_addr_len); p += acct->rem_addr_len; log_write_separator(rbt); log_write(rbt, acct_type, strlen(acct_type)); argsizep = (u_char *) acct + TAC_ACCT_REQ_FIXED_FIELDS_SIZE; argstart = (char *) p; for (i = 0; i < (int) acct->arg_cnt; i++) { log_write_separator(rbt); log_write(rbt, (char *) p, *argsizep); p += *argsizep++; } log_flush(rbt); if (acct->flags & TAC_PLUS_ACCT_FLAG_STOP) { p = (u_char *) argstart; argsizep = (u_char *) acct + TAC_ACCT_REQ_FIXED_FIELDS_SIZE; for (i = 0; i < (int) acct->arg_cnt; i++) { if (!strcmp((char *) p, "service=exec")) { char *mu = alloca(acct->user_len + 1); char *mp = alloca(acct->port_len + 1); strncpy(mu, username, acct->user_len); mu[acct->user_len] = 0; strncpy(mp, portname, acct->port_len); mp[acct->port_len] = 0; tac_script_set_exec_context(session, mu, mp, NULL); break; } p += *argsizep++; } } } send_acct_reply(session, TAC_PLUS_ACCT_STATUS_SUCCESS, NULL, NULL); }