#include "tacacs.h"
+static fr_dict_t const *dict_freeradius;
+static fr_dict_t const *dict_radius;
+static fr_dict_t const *dict_tacacs;
+
+extern fr_dict_autoload_t proto_tacacs_dict[];
+fr_dict_autoload_t proto_tacacs_dict[] = {
+ { .out = &dict_freeradius, .proto = "freeradius" },
+ { .out = &dict_radius, .proto = "radius" },
+ { .out = &dict_tacacs, .proto = "tacacs" },
+
+ { NULL }
+};
+
+static fr_dict_attr_t const *attr_auth_type;
+
+static fr_dict_attr_t const *attr_state;
+
+fr_dict_attr_t const *attr_tacacs_accounting_flags;
+fr_dict_attr_t const *attr_tacacs_accounting_status;
+fr_dict_attr_t const *attr_tacacs_action;
+fr_dict_attr_t const *attr_tacacs_authentication_flags;
+fr_dict_attr_t const *attr_tacacs_authentication_method;
+fr_dict_attr_t const *attr_tacacs_authentication_service;
+fr_dict_attr_t const *attr_tacacs_authentication_status;
+fr_dict_attr_t const *attr_tacacs_authentication_type;
+fr_dict_attr_t const *attr_tacacs_authorization_status;
+fr_dict_attr_t const *attr_tacacs_client_port;
+fr_dict_attr_t const *attr_tacacs_data;
+fr_dict_attr_t const *attr_tacacs_packet_type;
+fr_dict_attr_t const *attr_tacacs_privilege_level;
+fr_dict_attr_t const *attr_tacacs_remote_address;
+fr_dict_attr_t const *attr_tacacs_sequence_number;
+fr_dict_attr_t const *attr_tacacs_server_message;
+fr_dict_attr_t const *attr_tacacs_session_id;
+fr_dict_attr_t const *attr_tacacs_user_message;
+fr_dict_attr_t const *attr_tacacs_user_name;
+fr_dict_attr_t const *attr_tacacs_version_minor;
+
+extern fr_dict_attr_autoload_t proto_tacacs_dict_attr[];
+fr_dict_attr_autoload_t proto_tacacs_dict_attr[] = {
+ { .out = &attr_auth_type, .name = "Auth-Type", .type = FR_TYPE_UINT32, .dict = &dict_freeradius },
+ { .out = &attr_state, .name = "State", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
+ { .out = &attr_tacacs_accounting_flags, .name = "TACACS-Accounting-Flags", .type = FR_TYPE_UINT8, .dict = &dict_tacacs },
+ { .out = &attr_tacacs_accounting_status, .name = "TACACS-Accounting-Status", .type = FR_TYPE_UINT8, .dict = &dict_tacacs },
+ { .out = &attr_tacacs_action, .name = "TACACS-Action", .type = FR_TYPE_UINT8, .dict = &dict_tacacs },
+ { .out = &attr_tacacs_authentication_flags, .name = "TACACS-Authentication-Flags", .type = FR_TYPE_UINT8, .dict = &dict_tacacs },
+ { .out = &attr_tacacs_authentication_method, .name = "TACACS-Authentication-Method", .type = FR_TYPE_UINT8, .dict = &dict_tacacs },
+ { .out = &attr_tacacs_authentication_service, .name = "TACACS-Authentication-Service", .type = FR_TYPE_UINT8, .dict = &dict_tacacs },
+ { .out = &attr_tacacs_authentication_status, .name = "TACACS-Authentication-Status", .type = FR_TYPE_UINT8, .dict = &dict_tacacs },
+ { .out = &attr_tacacs_authentication_type, .name = "TACACS-Authentication-Type", .type = FR_TYPE_UINT8, .dict = &dict_tacacs },
+ { .out = &attr_tacacs_authorization_status, .name = "TACACS-Authorization-Status", .type = FR_TYPE_UINT8, .dict = &dict_tacacs },
+ { .out = &attr_tacacs_client_port, .name = "TACACS-Client-Port", .type = FR_TYPE_STRING, .dict = &dict_tacacs },
+ { .out = &attr_tacacs_data, .name = "TACACS-Data", .type = FR_TYPE_STRING, .dict = &dict_tacacs },
+ { .out = &attr_tacacs_packet_type, .name = "TACACS-Packet-Type", .type = FR_TYPE_UINT8, .dict = &dict_tacacs },
+ { .out = &attr_tacacs_privilege_level, .name = "TACACS-Privilege-Level", .type = FR_TYPE_UINT8, .dict = &dict_tacacs },
+ { .out = &attr_tacacs_remote_address, .name = "TACACS-Remote-Address", .type = FR_TYPE_STRING, .dict = &dict_tacacs },
+ { .out = &attr_tacacs_sequence_number, .name = "TACACS-Sequence-Number", .type = FR_TYPE_UINT8, .dict = &dict_tacacs },
+ { .out = &attr_tacacs_server_message, .name = "TACACS-Server-Message", .type = FR_TYPE_STRING, .dict = &dict_tacacs },
+ { .out = &attr_tacacs_session_id, .name = "TACACS-Session-Id", .type = FR_TYPE_UINT32, .dict = &dict_tacacs },
+ { .out = &attr_tacacs_user_message, .name = "TACACS-User-Message", .type = FR_TYPE_STRING, .dict = &dict_tacacs },
+ { .out = &attr_tacacs_user_name, .name = "TACACS-User-Name", .type = FR_TYPE_STRING, .dict = &dict_tacacs },
+ { .out = &attr_tacacs_version_minor, .name = "TACACS-Version-Minor", .type = FR_TYPE_UINT8, .dict = &dict_tacacs },
+ { NULL }
+};
+
/*
* Debug the packet if requested - cribbed from common_packet_debug
*/
static void tacacs_status(REQUEST * const request, rlm_rcode_t rcode)
{
- char const *k = "Unknown";
- char const *v = "Unknown";
+ VALUE_PAIR *vp;
switch (tacacs_type(request->packet)) {
case TAC_PLUS_AUTHEN:
- k = "TACACS-Authentication-Status";
switch (rcode) {
case RLM_MODULE_OK:
- v = "Pass";
+ MEM(pair_update_reply(&vp, attr_tacacs_authentication_status) >= 0);
+ fr_pair_value_from_str(vp, "Pass", -1);
break;
+
case RLM_MODULE_FAIL:
case RLM_MODULE_REJECT:
case RLM_MODULE_USERLOCK:
- v = "Fail";
+ MEM(pair_update_reply(&vp, attr_tacacs_authentication_status) >= 0);
+ fr_pair_value_from_str(vp, "Fail", -1);
break;
+
case RLM_MODULE_INVALID:
- v = "Error";
+ MEM(pair_update_reply(&vp, attr_tacacs_authentication_status) >= 0);
+ fr_pair_value_from_str(vp, "Error", -1);
break;
+
case RLM_MODULE_HANDLED: /* unlang set status */
return;
+
default:
noop:
WARN("ignoring request to add TACACS status with code %d", rcode);
return;
}
break;
+
case TAC_PLUS_AUTHOR:
- k = "TACACS-Authorization-Status";
switch (rcode) {
case RLM_MODULE_OK:
- v = "Pass-Repl";
+ MEM(pair_update_reply(&vp, attr_tacacs_authorization_status) >= 0);
+ fr_pair_value_from_str(vp, "Pass-Repl", -1);
break;
+
case RLM_MODULE_FAIL:
case RLM_MODULE_REJECT:
case RLM_MODULE_USERLOCK:
- v = "Fail";
+ MEM(pair_update_reply(&vp, attr_tacacs_authorization_status) >= 0);
+ fr_pair_value_from_str(vp, "Fail", -1);
break;
+
case RLM_MODULE_INVALID:
- v = "Error";
+ MEM(pair_update_reply(&vp, attr_tacacs_authorization_status) >= 0);
+ fr_pair_value_from_str(vp, "Error", -1);
break;
+
default:
goto noop;
}
break;
+
case TAC_PLUS_ACCT:
- k = "TACACS-Accounting-Status";
switch (rcode) {
case RLM_MODULE_OK:
- v = "Success";
+ MEM(pair_update_reply(&vp, attr_tacacs_accounting_status) >= 0);
+ fr_pair_value_from_str(vp, "Success", -1);
break;
+
case RLM_MODULE_FAIL:
case RLM_MODULE_REJECT:
case RLM_MODULE_USERLOCK:
case RLM_MODULE_INVALID:
- v = "Error";
+ MEM(pair_update_reply(&vp, attr_tacacs_accounting_status) >= 0);
+ fr_pair_value_from_str(vp, "Error", -1);
break;
+
default:
goto noop;
}
break;
}
-
- fr_pair_make(request->reply, &request->reply->vps, k, v, T_OP_EQ);
}
static void state_add(REQUEST *request, RADIUS_PACKET *packet)
session_id = tacacs_session_id(request->packet);
memcpy(&buf[sizeof(buf) - sizeof(session_id)], &session_id, sizeof(session_id));
- vp = fr_pair_afrom_num(packet, 0, FR_STATE);
- rad_assert(vp != NULL);
+ MEM(vp = fr_pair_afrom_da(packet, attr_state));
fr_pair_value_memcpy(vp, (uint8_t const *)buf, sizeof(buf));
fr_pair_add(&packet->vps, vp);
}
static void tacacs_running(REQUEST *request, fr_state_signal_t action)
{
- rlm_rcode_t rcode;
- CONF_SECTION *unlang;
- fr_dict_attr_t const *da;
- fr_dict_enum_t const *dv = NULL;
- VALUE_PAIR *vp, *auth_type;
- vp_cursor_t cursor;
- int rc;
+ rlm_rcode_t rcode;
+ CONF_SECTION *unlang;
+ fr_dict_enum_t const *dv = NULL;
+ VALUE_PAIR *vp, *auth_type;
+ vp_cursor_t cursor;
+ int rc;
REQUEST_VERIFY(request);
*/
fr_pair_cursor_init(&cursor, &request->control);
auth_type = NULL;
- while ((vp = fr_pair_cursor_next_by_num(&cursor, 0, FR_AUTH_TYPE, TAG_ANY)) != NULL) {
+ while ((vp = fr_pair_cursor_next_by_da(&cursor, attr_auth_type, TAG_ANY)) != NULL) {
if (!auth_type) {
auth_type = vp;
continue;
gettimeofday(&request->reply->timestamp, NULL);
if (tacacs_type(request->packet) == TAC_PLUS_AUTHEN) {
- fr_dict_attr_t const *authda;
-
- authda = fr_dict_attr_by_name(NULL, "TACACS-Authentication-Status");
- rad_assert(authda != NULL);
- vp = fr_pair_find_by_da(request->reply->vps, authda, TAG_ANY);
-
+ vp = fr_pair_find_by_da(request->reply->vps, attr_tacacs_authentication_status, TAG_ANY);
if (vp) {
switch ((tacacs_authen_reply_status_t)vp->vp_uint8) {
case TAC_PLUS_AUTHEN_STATUS_PASS:
fr_state_discard(global_state, request, request->packet);
break;
default:
- da = fr_dict_attr_by_name(NULL, "TACACS-Sequence-Number");
- rad_assert(da != NULL);
- vp = fr_pair_find_by_da(request->packet->vps, da, TAG_ANY);
- rad_assert(vp != NULL);
+ vp = fr_pair_find_by_da(request->packet->vps,
+ attr_tacacs_sequence_number, TAG_ANY);
+ if (!vp) {
+ REDEBUG("No sequence number found");
+ goto done;
+ }
/* authentication would continue but seq_no cannot continue */
if (vp->vp_uint8 == 253) {
fr_state_discard(global_state, request, request->packet);
fr_pair_list_free(&request->reply->vps);
- vp = fr_pair_afrom_da(request->reply, authda);
- rad_assert(vp != NULL);
- vp->vp_uint8 = (tacacs_authen_reply_status_t)TAC_PLUS_AUTHEN_STATUS_RESTART;
- fr_pair_add(&request->reply->vps, vp);
+ MEM(pair_update_reply(&vp, attr_tacacs_authentication_status) >= 0);
+ vp->vp_uint8 = TAC_PLUS_AUTHEN_STATUS_RESTART;
} else {
state_add(request, request->reply);
request->reply->code = 1; /* FIXME: util.c:request_verify() */
- fr_request_to_state(global_state, request, request->packet, request->reply);
+ fr_request_to_state(global_state, request,
+ request->packet, request->reply);
}
}
- } else
+ } else {
fr_state_discard(global_state, request, request->packet);
+ }
}
if (RDEBUG_ENABLED) tacacs_packet_debug(request, request->reply, false);
return 0;
}
-static int tacacs_load(void)
-{
- dict_tacacs_root = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal), FR_TACACS_ROOT);
- if (!dict_tacacs_root) {
- ERROR("Missing TACACS-Root attribute");
- return -1;
- }
- return 0;
-}
-
extern rad_protocol_t proto_tacacs;
rad_protocol_t proto_tacacs = {
.name = "tacacs",
.magic = RLM_MODULE_INIT,
- .load = tacacs_load,
.inst_size = sizeof(listen_socket_t),
.transports = TRANSPORT_TCP,
.tls = false,
{
VALUE_PAIR const *vp;
- vp = fr_pair_find_by_child_num(packet->vps, dict_tacacs_root, FR_TACACS_PACKET_TYPE, TAG_ANY);
- rad_assert(vp != NULL);
+ vp = fr_pair_find_by_da(packet->vps, attr_tacacs_packet_type, TAG_ANY);
+ if (!vp) return 0;
return (tacacs_type_t)vp->vp_uint8;
}
-char const * tacacs_lookup_packet_code(RADIUS_PACKET const * const packet)
+char const *tacacs_lookup_packet_code(RADIUS_PACKET const * const packet)
{
- fr_dict_attr_t const *da;
fr_dict_enum_t const *dv;
tacacs_type_t type;
type = tacacs_type(packet);
- da = fr_dict_attr_child_by_num(dict_tacacs_root, FR_TACACS_PACKET_TYPE);
- rad_assert(da != NULL);
- dv = fr_dict_enum_by_value(da, fr_box_uint32(type));
- rad_assert(dv != NULL);
+ dv = fr_dict_enum_by_value(attr_tacacs_packet_type, fr_box_uint32(type));
+ if (!dv) return NULL;
return dv->alias;
}
{
VALUE_PAIR const *vp;
- vp = fr_pair_find_by_child_num(packet->vps, dict_tacacs_root, FR_TACACS_SESSION_ID, TAG_ANY);
- rad_assert(vp != NULL);
+ vp = fr_pair_find_by_da(packet->vps, attr_tacacs_session_id, TAG_ANY);
+ if (!vp) return 0;
return vp->vp_uint32;
}
fr_strerror_printf("client sent seq_no set to 255");
return false;
}
-
break;
+
case TAC_PLUS_AUTHOR:
case TAC_PLUS_ACCT:
if ((from_client && pkt->hdr.seq_no != 1) || (!from_client && pkt->hdr.seq_no != 2))
}
}
break;
+
case TAC_PLUS_AUTHOR:
if (from_client) {
len = pkt->author.req.user_len + pkt->author.req.port_len + pkt->author.req.rem_addr_len + pkt->author.req.arg_cnt;
}
}
break;
+
case TAC_PLUS_ACCT:
if (from_client) {
uint8_t flags;
if (!vp->da->flags.internal) continue;
- switch (vp->da->attr) {
- case FR_TACACS_VERSION_MINOR:
+ if (vp->da == attr_tacacs_version_minor) {
pkt->hdr.ver.minor = vp->vp_uint8;
- break;
- case FR_TACACS_PACKET_TYPE:
+ } else if (vp->da == attr_tacacs_packet_type) {
pkt->hdr.type = vp->vp_uint8;
- break;
- case FR_TACACS_SEQUENCE_NUMBER:
+ } else if (vp->da == attr_tacacs_sequence_number) {
pkt->hdr.seq_no = vp->vp_uint8;
- break;
- case FR_TACACS_SESSION_ID:
+ } else if (vp->da == attr_tacacs_session_id) {
pkt->hdr.session_id = htonl(vp->vp_uint32);
- break;
- case FR_TACACS_AUTHENTICATION_STATUS:
+ } else if (vp->da == attr_tacacs_authentication_status) {
pkt->authen.reply.status = vp->vp_uint8;
status = vp->vp_uint8;
- break;
- case FR_TACACS_AUTHENTICATION_FLAGS:
+ } else if (vp->da == attr_tacacs_authentication_status) {
authen_reply_flags |= vp->vp_uint8;
- break;
- case FR_TACACS_AUTHORIZATION_STATUS:
+ } else if (vp->da == attr_tacacs_authorization_status) {
pkt->author.res.status = vp->vp_uint8;
status = vp->vp_uint8;
- break;
- case FR_TACACS_ACCOUNTING_STATUS:
+ } else if (vp->da == attr_tacacs_accounting_status) {
pkt->acct.res.status = vp->vp_uint8;
status = vp->vp_uint8;
- break;
- case FR_TACACS_SERVER_MESSAGE:
+ } else if (vp->da == attr_tacacs_server_message) {
length_body += vp->vp_length;
field.server_msg = vp;
- break;
- case FR_TACACS_DATA:
+ } else if (vp->da == attr_tacacs_data) {
length_body += vp->vp_length;
field.data = vp;
- break;
- default:
+ } else {
WARN("Unhandled %s", vp->da->name);
}
}
pkt->authen.reply.server_msg_len = htons(0);
pkt->authen.reply.data_len = htons(0);
break;
+
case TAC_PLUS_AUTHOR:
length_hdr += offsetof(tacacs_packet_author_res_hdr_t, body);
pkt->author.res.arg_cnt = 0;
pkt->author.res.server_msg_len = htons(0);
pkt->author.res.data_len = htons(0);
break;
+
case TAC_PLUS_ACCT:
length_hdr += offsetof(tacacs_packet_acct_res_hdr_t, body);
pkt->acct.res.server_msg_len = htons(0);
pkt->acct.res.data_len = htons(0);
break;
+
/* unsupported type as per draft-ietf-opsawg-tacacs section 3.6 */
default:
fail:
}
-static int tacacs_decode_field(TALLOC_CTX *ctx, vp_cursor_t *cursor, unsigned int attr, char const *field_name,
- uint8_t **field_data, size_t field_len, size_t *remaining)
+static int tacacs_decode_field(TALLOC_CTX *ctx, vp_cursor_t *cursor, fr_dict_attr_t const *da,
+ char const *field_name, uint8_t **field_data, size_t field_len, size_t *remaining)
{
uint8_t *p;
VALUE_PAIR *vp;
return -1;
}
- vp = fr_pair_afrom_child_num(ctx, dict_tacacs_root, attr);
- if (!vp) return -1;
+ MEM(vp = fr_pair_afrom_da(ctx, da));
fr_pair_value_bstrncpy(vp, p, field_len);
p += field_len;
remaining = ntohl(pkt->hdr.length);
- vp = fr_pair_afrom_child_num(packet, dict_tacacs_root, FR_TACACS_VERSION_MINOR);
- if (!vp) return -1;
+ MEM(vp = fr_pair_afrom_da(packet, attr_tacacs_version_minor));
vp->vp_uint8 = pkt->hdr.ver.minor;
fr_pair_cursor_append(&cursor, vp);
- vp = fr_pair_afrom_child_num(packet, dict_tacacs_root, FR_TACACS_PACKET_TYPE);
- if (!vp) return -1;
+ MEM(vp = fr_pair_afrom_da(packet, attr_tacacs_packet_type));
vp->vp_uint8 = pkt->hdr.type;
fr_pair_cursor_append(&cursor, vp);
packet->code = pkt->hdr.type;
- vp = fr_pair_afrom_child_num(packet, dict_tacacs_root, FR_TACACS_SEQUENCE_NUMBER);
- if (!vp) return -1;
+ MEM(vp = fr_pair_afrom_da(packet, attr_tacacs_sequence_number));
vp->vp_uint8 = pkt->hdr.seq_no;
fr_pair_cursor_append(&cursor, vp);
- vp = fr_pair_afrom_child_num(packet, dict_tacacs_root, FR_TACACS_SESSION_ID);
- if (!vp) return -1;
+ MEM(vp = fr_pair_afrom_da(packet, attr_tacacs_session_id));
vp->vp_uint32 = ntohl(pkt->hdr.session_id);
fr_pair_cursor_append(&cursor, vp);
session_id = vp->vp_uint32;
/*
* Decode 4 octets of various flags.
*/
- vp = fr_pair_afrom_child_num(packet, dict_tacacs_root, FR_TACACS_ACTION);
- if (!vp) return -1;
+ MEM(vp = fr_pair_afrom_da(packet, attr_tacacs_action));
vp->vp_uint8 = pkt->authen.start.action;
fr_pair_cursor_append(&cursor, vp);
- vp = fr_pair_afrom_child_num(packet, dict_tacacs_root, FR_TACACS_PRIVILEGE_LEVEL);
- if (!vp) return -1;
+ MEM(vp = fr_pair_afrom_da(packet, attr_tacacs_privilege_level));
vp->vp_uint8 = pkt->authen.start.priv_lvl;
fr_pair_cursor_append(&cursor, vp);
- vp = fr_pair_afrom_child_num(packet, dict_tacacs_root, FR_TACACS_AUTHENTICATION_TYPE);
- if (!vp) return -1;
+ MEM(vp = fr_pair_afrom_da(packet, attr_tacacs_authentication_type));
vp->vp_uint8 = pkt->authen.start.authen_type;
fr_pair_cursor_append(&cursor, vp);
- vp = fr_pair_afrom_child_num(packet, dict_tacacs_root, FR_TACACS_AUTHENTICATION_SERVICE);
+ MEM(vp = fr_pair_afrom_da(packet, attr_tacacs_authentication_service));
if (!vp) return -1;
vp->vp_uint8 = pkt->authen.start.authen_service;
fr_pair_cursor_append(&cursor, vp);
*/
p = pkt->authen.start.body;
- if (tacacs_decode_field(packet, &cursor, FR_TACACS_USER_NAME, "User",
+ if (tacacs_decode_field(packet, &cursor, attr_tacacs_user_name, "User",
&p, pkt->authen.start.user_len, &remaining) < 0) {
return -1;
}
- if (tacacs_decode_field(packet, &cursor, FR_TACACS_CLIENT_PORT, "Port",
+ if (tacacs_decode_field(packet, &cursor, attr_tacacs_client_port, "Port",
&p, pkt->authen.start.port_len, &remaining) < 0) {
return -1;
}
- if (tacacs_decode_field(packet, &cursor, FR_TACACS_REMOTE_ADDRESS, "Remote address",
+ if (tacacs_decode_field(packet, &cursor, attr_tacacs_remote_address, "Remote address",
&p, pkt->authen.start.rem_addr_len, &remaining) < 0) {
return -1;
}
- if (tacacs_decode_field(packet, &cursor, FR_TACACS_DATA, "Data",
+ if (tacacs_decode_field(packet, &cursor, attr_tacacs_data, "Data",
&p, pkt->authen.start.data_len, &remaining) < 0) {
return -1;
}
*/
p = pkt->authen.cont.body;
- if (tacacs_decode_field(packet, &cursor, FR_TACACS_USER_MESSAGE, "User message",
+ if (tacacs_decode_field(packet, &cursor, attr_tacacs_user_message, "User message",
&p, ntohs(pkt->authen.cont.user_msg_len), &remaining) < 0) {
return -1;
}
- if (tacacs_decode_field(packet, &cursor, FR_TACACS_DATA, "Data",
+ if (tacacs_decode_field(packet, &cursor, attr_tacacs_data, "Data",
&p, ntohs(pkt->authen.cont.data_len), &remaining) < 0) {
return -1;
}
if (pkt->authen.cont.flags & TAC_PLUS_CONTINUE_FLAG_ABORT) {
if (!ntohs(pkt->authen.cont.data_len) ||
!(vp = fr_pair_cursor_last(&cursor))) {
- fr_strerror_printf("Client aborted authentication session %u with no message", session_id);
+ fr_strerror_printf("Client aborted authentication session %u "
+ "with no message", session_id);
return -2;
}
if (ntohs(pkt->authen.cont.data_len) > 128) {
- fr_strerror_printf("Client aborted authentication session %u with too long message", session_id);
+ fr_strerror_printf("Client aborted authentication session %u "
+ "with too long message", session_id);
return -2;
}
/*
* Decode 4 octets of various flags.
*/
- vp = fr_pair_afrom_child_num(packet, dict_tacacs_root, FR_TACACS_AUTHENTICATION_METHOD);
- if (!vp) return -1;
+ MEM(vp = fr_pair_afrom_da(packet, attr_tacacs_authentication_method));
vp->vp_uint8 = pkt->author.req.authen_method;
fr_pair_cursor_append(&cursor, vp);
- vp = fr_pair_afrom_child_num(packet, dict_tacacs_root, FR_TACACS_PRIVILEGE_LEVEL);
- if (!vp) return -1;
+ MEM(vp = fr_pair_afrom_da(packet, attr_tacacs_privilege_level));
vp->vp_uint8 = pkt->author.req.priv_lvl;
fr_pair_cursor_append(&cursor, vp);
- vp = fr_pair_afrom_child_num(packet, dict_tacacs_root, FR_TACACS_AUTHENTICATION_TYPE);
- if (!vp) return -1;
+ MEM(vp = fr_pair_afrom_da(packet, attr_tacacs_authentication_type));
vp->vp_uint8 = pkt->author.req.authen_type;
fr_pair_cursor_append(&cursor, vp);
- vp = fr_pair_afrom_child_num(packet, dict_tacacs_root, FR_TACACS_AUTHENTICATION_SERVICE);
- if (!vp) return -1;
+ MEM(vp = fr_pair_afrom_da(packet, attr_tacacs_authentication_service));
vp->vp_uint8 = pkt->author.req.authen_service;
fr_pair_cursor_append(&cursor, vp);
/*
* Decode 3 fields, based on their "length"
*/
- if (tacacs_decode_field(packet, &cursor, FR_TACACS_USER_NAME, "User",
+ if (tacacs_decode_field(packet, &cursor, attr_tacacs_user_name, "User",
&p, pkt->author.req.user_len, &remaining) < 0) {
return -1;
}
- if (tacacs_decode_field(packet, &cursor, FR_TACACS_CLIENT_PORT, "Port",
+ if (tacacs_decode_field(packet, &cursor, attr_tacacs_client_port, "Port",
&p, pkt->authen.start.port_len, &remaining) < 0) {
return -1;
}
- if (tacacs_decode_field(packet, &cursor, FR_TACACS_REMOTE_ADDRESS, "Remote address",
+ if (tacacs_decode_field(packet, &cursor, attr_tacacs_remote_address, "Remote address",
&p, pkt->authen.start.rem_addr_len, &remaining) < 0) {
return -1;
}
/*
* Decode 8 octets of various fields.
*/
- vp = fr_pair_afrom_child_num(packet, dict_tacacs_root, FR_TACACS_ACCOUNTING_FLAGS);
- if (!vp) return -1;
+ MEM(vp = fr_pair_afrom_da(packet, attr_tacacs_accounting_flags));
vp->vp_uint8 = pkt->acct.req.flags;
fr_pair_cursor_append(&cursor, vp);
- vp = fr_pair_afrom_child_num(packet, dict_tacacs_root, FR_TACACS_AUTHENTICATION_METHOD);
- if (!vp) return -1;
+ MEM(vp = fr_pair_afrom_da(packet, attr_tacacs_authentication_method));
vp->vp_uint8 = pkt->acct.req.authen_method;
fr_pair_cursor_append(&cursor, vp);
- vp = fr_pair_afrom_child_num(packet, dict_tacacs_root, FR_TACACS_PRIVILEGE_LEVEL);
- if (!vp) return -1;
+ MEM(vp = fr_pair_afrom_da(packet, attr_tacacs_privilege_level));
vp->vp_uint8 = pkt->acct.req.priv_lvl;
fr_pair_cursor_append(&cursor, vp);
- vp = fr_pair_afrom_child_num(packet, dict_tacacs_root, FR_TACACS_AUTHENTICATION_TYPE);
- if (!vp) return -1;
+ MEM(vp = fr_pair_afrom_da(packet, attr_tacacs_authentication_type));
vp->vp_uint8 = pkt->acct.req.authen_type;
fr_pair_cursor_append(&cursor, vp);
- vp = fr_pair_afrom_child_num(packet, dict_tacacs_root, FR_TACACS_AUTHENTICATION_SERVICE);
- if (!vp) return -1;
+ MEM(vp = fr_pair_afrom_da(packet, attr_tacacs_authentication_service));
vp->vp_uint8 = pkt->acct.req.authen_service;
fr_pair_cursor_append(&cursor, vp);
/*
* Decode 3 fields, based on their "length"
*/
- if (tacacs_decode_field(packet, &cursor, FR_TACACS_USER_NAME, "User",
- &p, pkt->acct.req.user_len, &remaining) < 0) {
- return -1;
- }
+ if (tacacs_decode_field(packet, &cursor, attr_tacacs_user_name, "User",
+ &p, pkt->acct.req.user_len, &remaining) < 0) return -1;
- if (tacacs_decode_field(packet, &cursor, FR_TACACS_CLIENT_PORT, "Port",
- &p, pkt->acct.req.port_len, &remaining) < 0) {
- return -1;
- }
+ if (tacacs_decode_field(packet, &cursor, attr_tacacs_client_port, "Port",
+ &p, pkt->acct.req.port_len, &remaining) < 0) return -1;
- if (tacacs_decode_field(packet, &cursor, FR_TACACS_REMOTE_ADDRESS, "Remote address",
- &p, pkt->acct.req.rem_addr_len, &remaining) < 0) {
- return -1;
- }
+ if (tacacs_decode_field(packet, &cursor, attr_tacacs_remote_address, "Remote address",
+ &p, pkt->acct.req.rem_addr_len, &remaining) < 0) return -1;
/* FIXME fully support arg */
p = pkt->acct.req.body;
uint8_t seq_no;
VALUE_PAIR *vp;
- vp = fr_pair_find_by_child_num(original->vps, dict_tacacs_root, FR_TACACS_VERSION_MINOR, TAG_ANY);
- rad_assert(vp != NULL);
+ vp = fr_pair_find_by_da(original->vps, attr_tacacs_version_minor, TAG_ANY);
+ if (!vp) {
+ fr_strerror_printf("Missing %s", attr_tacacs_version_minor->name);
+ return -1;
+ }
vminor = vp->vp_uint8;
- vp = fr_pair_afrom_da(packet, vp->da);
- if (!vp) return -1;
+ vp = fr_pair_find_by_da(original->vps, attr_tacacs_sequence_number, TAG_ANY);
+ if (!vp) {
+ fr_strerror_printf("Missing %s", attr_tacacs_sequence_number->name);
+ return -1;
+ }
+ seq_no = vp->vp_uint8 + 1; /* we catch client 255 on ingress */
+
+ MEM(vp = fr_pair_afrom_da(packet, vp->da));
vp->vp_uint8 = vminor;
fr_pair_add(&packet->vps, vp);
type = tacacs_type(original);
- vp = fr_pair_afrom_child_num(packet, dict_tacacs_root, FR_TACACS_PACKET_TYPE);
+ MEM(vp = fr_pair_afrom_da(packet, attr_tacacs_packet_type));
vp->vp_uint8 = type;
fr_pair_add(&packet->vps, vp);
- vp = fr_pair_find_by_child_num(original->vps, dict_tacacs_root, FR_TACACS_SEQUENCE_NUMBER, TAG_ANY);
- rad_assert(vp != NULL);
- seq_no = vp->vp_uint8 + 1; /* we catch client 255 on ingress */
-
- vp = fr_pair_afrom_da(packet, vp->da);
- if (!vp) return -1;
+ MEM(vp = fr_pair_afrom_da(packet, attr_tacacs_sequence_number));
vp->vp_uint8 = seq_no;
fr_pair_add(&packet->vps, vp);
- vp = fr_pair_afrom_child_num(packet, dict_tacacs_root, FR_TACACS_SESSION_ID);
- if (!vp) return -1;
+ MEM(vp = fr_pair_afrom_da(packet, attr_tacacs_session_id));
vp->vp_uint32 = tacacs_session_id(original);
fr_pair_add(&packet->vps, vp);