Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
/*
 *  Come here when we receive an authorization START packet
 */
void
author(u_char *pak)
{
    HDR *hdr;
    struct author *apak;
    struct identity identity;
#ifdef ACLS
    struct authen_data authen_data;
#endif
    struct author_data author_data;
    u_char *p;
    u_char *argsizep;
    char **cmd_argp;
    int i, len;

    if (debug & DEBUG_AUTHOR_FLAG)
	report(LOG_DEBUG, "Start authorization request");

    hdr = (HDR *)pak;
    apak = (struct author *)(pak + TAC_PLUS_HDR_SIZE);

    /* Do some sanity checks */
    if (hdr->seq_no != 1) {
	send_error_reply(TAC_PLUS_AUTHOR, NULL);
	return;
    }

    /* Check if there's at least sizeof(struct author) of useful data */
    if (ntohl(hdr->datalength) < TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE) {
	report(LOG_ERR, "%s: author minimum payload length: %zu, got: %u",
	       session.peer, TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE,
	       ntohl(hdr->datalength));
	send_error_reply(TAC_PLUS_AUTHOR, NULL);
	return;
    }

    /* arg counts start here */
    p = pak + TAC_PLUS_HDR_SIZE + TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE;

    /* Length checks */
    len = TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE;
    len += apak->user_len + apak->port_len + apak->rem_addr_len + apak->arg_cnt;

    /* Is there enough space for apak->arg_cnt arguments? */
    if (ntohl(hdr->datalength) <
	(TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE + apak->arg_cnt)) {
	report(LOG_ERR, "%s: author minimum payload length: %zu, got: %u",
	       session.peer, TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE + apak->arg_cnt,
	       ntohl(hdr->datalength));
	send_error_reply(TAC_PLUS_AUTHOR, NULL);
	return;
    }

    for (i = 0; i < (int)apak->arg_cnt; i++) {
	len += p[i];
    }

    if (len != ntohl(hdr->datalength)) {
	send_error_reply(TAC_PLUS_AUTHOR, NULL);
	return;
    }

    /* start of variable length data is here */
    p = pak + TAC_PLUS_HDR_SIZE + TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE;

    /* arg length data starts here */
    argsizep = p;

    p += apak->arg_cnt;

    memset(&author_data, 0, sizeof(struct author_data));

    /* The identity structure */

    /* zero out identity struct */
    memset(&identity, 0, sizeof(struct identity));
    identity.username = tac_make_string(p, (int)apak->user_len);
    p += apak->user_len;

    identity.NAS_name = tac_strdup(session.peer);
#ifdef ACLS
    identity.NAS_ip = tac_strdup(session.peerip);
#endif

    identity.NAS_port = tac_make_string(p, (int)apak->port_len);
    p += apak->port_len;
    if (apak->port_len <= 0) {
	strcpy(session.port, "unknown-port");
    } else {
	strcpy(session.port, identity.NAS_port);
    }

    identity.NAC_address = tac_make_string(p, (int)apak->rem_addr_len);
    p += apak->rem_addr_len;

    identity.priv_lvl = apak->priv_lvl;

    /* The author_data structure */

    author_data.id = &identity;	/* user id */

    /* FIXME: validate these fields */
    author_data.authen_method = apak->authen_method;
    author_data.authen_type = apak->authen_type;
    author_data.service = apak->service;
    author_data.num_in_args = apak->arg_cnt;

    /* Space for args + NULL */
    cmd_argp = (char **)tac_malloc(apak->arg_cnt * sizeof(char *));

    /* p points to the start of args. Step thru them making strings */
    for (i = 0; i < (int)apak->arg_cnt; i++) {
	cmd_argp[i] = tac_make_string(p, *argsizep);
	p += *argsizep++;
    }

    author_data.input_args = cmd_argp;	/* input command arguments */

#ifdef ACLS
    authen_data.NAS_id = &identity;
    if (verify_host(author_data.id->username, &authen_data, S_acl,
		    TAC_PLUS_RECURSE) != S_permit) {
	author_data.status = AUTHOR_STATUS_FAIL;
    } else
#endif
	if (do_author(&author_data)) {
	    report(LOG_ERR, "%s: do_author returned an error", session.peer);
	    send_author_reply(AUTHOR_STATUS_ERROR,
			      author_data.msg, author_data.admin_msg,
			      author_data.num_out_args,
			      author_data.output_args);
	    return;
        }

    /* Send a reply packet */
    send_author_reply(author_data.status, author_data.msg,
		      author_data.admin_msg, author_data.num_out_args,
		      author_data.output_args);

    if (debug)
	report(LOG_INFO, "authorization query for '%s' %s from %s %s",
	       author_data.id->username && author_data.id->username[0] ?
	       author_data.id->username : "******",
	       author_data.id->NAS_port && author_data.id->NAS_port[0] ?
	       author_data.id->NAS_port : "unknown",
	       session.peer,
	       (author_data.status == AUTHOR_STATUS_PASS_ADD ||
		author_data.status == AUTHOR_STATUS_PASS_REPL) ?
	       "accepted" : "rejected");

    /* free the input args */
    if (author_data.input_args) {
	for (i = 0; i < author_data.num_in_args; i++)
	    free(author_data.input_args[i]);

	free(author_data.input_args);
	author_data.input_args = NULL;
    }

    /* free the output args */
    if (author_data.output_args) {
	for (i = 0; i < author_data.num_out_args; i++)
	    free(author_data.output_args[i]);

	free(author_data.output_args);
	author_data.output_args = NULL;
    }

    if (author_data.msg)
	free(author_data.msg);

    if (author_data.admin_msg)
	free(author_data.admin_msg);

    free(identity.username);
    free(identity.NAS_name);
#ifdef ACLS
    free(identity.NAS_ip);
#endif
    free(identity.NAS_port);
    free(identity.NAC_address);
}