示例#1
0
文件: packet.c 项目: Babar/tac_plus
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;
}
示例#2
0
文件: acct.c 项目: Babar/tac_plus
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);
}
示例#3
0
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);
}