26#include <freeradius-devel/io/listen.h>
27#include <freeradius-devel/io/master.h>
28#include <freeradius-devel/tacacs/tacacs.h>
29#include <freeradius-devel/unlang/call.h>
30#include <freeradius-devel/unlang/xlat_func.h>
31#include <freeradius-devel/util/debug.h>
33#include <freeradius-devel/protocol/tacacs/tacacs.h>
185#define PROCESS_PACKET_TYPE fr_tacacs_packet_code_t
186#define PROCESS_CODE_MAX FR_TACACS_CODE_MAX
187#define PROCESS_CODE_DO_NOT_RESPOND FR_TACACS_CODE_DO_NOT_RESPOND
188#define PROCESS_PACKET_CODE_VALID FR_TACACS_PACKET_CODE_VALID
189#define PROCESS_INST process_tacacs_t
190#define PROCESS_CODE_DYNAMIC_CLIENT FR_TACACS_CODE_AUTH_PASS
192#include <freeradius-devel/server/process.h>
217 if (!request->async->listen)
return -1;
232 sequence =
vp->vp_uint8 + ((int) reply << 1);
283 code = status2code[
vp->vp_uint8];
285 RDEBUG(
"Setting reply Packet-Type from %pP",
vp);
289 REDEBUG(
"Ignoring invalid status %pP",
vp);
293 code = state->packet_type[rcode];
307 RDEBUG(
"Setting reply Packet-Type from %pV", &
vp->data);
308 return vp->vp_uint32;
316 fr_process_state_t
const *state;
330 return CALL_SEND_STATE(state);
333 if (
vp->vp_uint8 != FR_ACTION_VALUE_LOGIN) {
334 RDEBUG(
"Invalid authentication action %u",
vp->vp_uint8);
342 return CALL_RECV(generic);
363 fr_process_state_t
const *state;
373 UPDATE_STATE(packet);
381 if (!request->reply->code) {
398 if (!request->reply->code) {
419 RDEBUG(
"No User-Name, replying with Authentication-GetUser");
422 RDEBUG(
"User-Name = %pV, replying with Authentication-GetPass", &
vp->data);
434 RDEBUG(
"No User-Password, replying with Authentication-GetPass");
446 RPEDEBUG(
"Failed creating Authentication-Flags attribute with No-Echo flag");
465 if (request->reply->code) {
466 switch (request->reply->code) {
468 RDEBUG(
"The 'recv Authentication-Start' section returned %s - failing the request",
473 RDEBUG(
"Reply packet type was set to Do-Not-Respond");
486 return CALL_SEND_STATE(state);
501 RDEBUG(
"No 'Auth-Type' or 'Authentication-Type' attribute found, "
502 "cannot authenticate the user - rejecting the request");
511 RDEBUG(
"Invalid value for '%s' attribute, cannot authenticate the user - rejecting the request",
535 RDEBUG2(
"No 'authenticate %s { ... }' section found - rejecting the request", dv->
name);
547 NULL, 0, mctx->rctx);
552 static const fr_process_rcode_t auth_type_rcode = {
564 fr_process_state_t
const *state;
578 if (!request->reply->code) {
586 switch (request->reply->code) {
588 RDEBUG(
"No reply code was set. Forcing to Authentication-Fail");
597 RDEBUG2(
"Failed to authenticate the user");
604 if (
vp && (
vp->vp_uint8 != FR_AUTHENTICATION_TYPE_VALUE_ASCII)) {
605 RDEBUG2(
"Cannot send challenges for %pP",
vp);
617 return state->send(p_result, mctx, request);
687#define COPY(_attr) do { \
688 vp = fr_pair_find_by_da(&request->request_pairs, NULL, _attr); \
690 MEM(copy = fr_pair_copy(session, vp)); \
691 fr_pair_append(&session->list, copy); \
692 RDEBUG2("%pP", copy); \
695 RDEBUG2(
"Caching session attributes:");
710#define COPY_MISSING(_attr) do { \
711 vp = fr_pair_find_by_da(&session->list, NULL, _attr); \
716 RDEBUG2(
"Caching additional session attributes:");
722 session->
reply = request->reply->code;
723 session->
seq_no = request->packet->data[2];
729 if ((
state_create(request->reply_ctx, &request->reply_pairs, request,
true) < 0) ||
742 if ((
state_create(request->request_ctx, &request->request_pairs, request,
false) < 0) ||
754 if (request->packet->data[2] <= session->
seq_no) {
755 REDEBUG(
"Client sent invalid sequence number %02x, expected >%02x", request->packet->data[2], session->
seq_no);
761 RDEBUG2(
"Restoring session attributes:");
768 if (
fr_pair_list_copy(request->request_ctx, &request->request_pairs, &session->
list) < 0)
goto error;
773#define EXTRACT(_attr) \
774 vp = fr_pair_find_by_da(&request->request_pairs, NULL, attr_tacacs_user_message); \
776 fr_value_box_set_secret(&vp->data, _attr->flags.secret); \
777 if (pair_append_request(©, _attr) < 0) break; \
778 if (fr_pair_value_copy(copy, vp) < 0) { \
779 fr_pair_remove(&request->request_pairs, copy); \
783 RDEBUG2("Populated %pP from user_message", copy)
785 switch (session->
reply) {
799 return CALL_RECV(generic);
809 if ((
state_create(request->request_ctx, &request->request_pairs, request,
false) < 0) ||
814 return CALL_RECV(generic);
820 fr_process_state_t
const *state;
822 UPDATE_STATE(packet);
824 if (!request->reply->code) {
846 return CALL_SEND_STATE(state);
861 fr_process_state_t
const *state;
870 UPDATE_STATE(packet);
878 if (!request->reply->code) {
892 return CALL_SEND_STATE(state);
902 static const fr_process_rcode_t acct_type_rcode = {
914 fr_process_state_t
const *state;
921 if (!request->reply->code) {
923 NULL, acct_type_rcode, rcode);
932 return state->send(p_result, mctx, request);
936 false,
true,
true,
false,
937 true,
true,
false,
false,
950 RWDEBUG(
"Invalid accounting request flag field %02x",
vp->vp_uint8);
954 return CALL_RECV(generic);
963 fr_process_state_t
const *state;
970 UPDATE_STATE(packet);
978 if (!request->reply->code) {
988 if (request->reply->code) {
997 return CALL_SEND_STATE(state);
1007 UPDATE_STATE(reply);
1009 return CALL_SEND_STATE(state);
1017 RDEBUG2(
"No 'accounting %s { ... }' section found - skipping...", dv->
name);
1028 NULL, 0, mctx->rctx);
1033 fr_process_state_t
const *state;
1040 request->component =
"tacacs";
1041 request->module = NULL;
1044 UPDATE_STATE(packet);
1047 REDEBUG(
"Invalid packet type (%u)", request->packet->code);
1055 return new_client(p_result, mctx, request);
1058 return state->recv(p_result, mctx, request);
1083 TALLOC_CTX *local = talloc_new(NULL);
1097 ret =
fr_tacacs_decode(local, &list, NULL, request->packet->data, request->packet->data_len, NULL,
1102 RPEDEBUG(
"Failed to verify the TACACS secret");
1103 vb->vb_bool =
false;
1177 .recv = recv_auth_start,
1178 .resume = resume_auth_start,
1191 .send = send_generic,
1192 .resume = resume_auth_pass,
1205 .send = send_generic,
1206 .resume = resume_auth_fail,
1219 .send = send_generic,
1220 .resume = resume_auth_get,
1233 .send = send_generic,
1234 .resume = resume_auth_get,
1247 .send = send_generic,
1248 .resume = resume_auth_get,
1256 .send = send_generic,
1257 .resume = resume_auth_restart,
1265 .send = send_generic,
1266 .resume = resume_auth_restart,
1281 .recv = recv_auth_cont,
1282 .resume = resume_auth_start,
1296 .recv = recv_auth_cont_abort,
1297 .resume = resume_auth_cont_abort,
1319 .recv = recv_generic,
1320 .resume = resume_autz_request,
1334 .send = send_generic,
1335 .resume = resume_send_generic,
1349 .send = send_generic,
1350 .resume = resume_send_generic,
1358 .send = send_generic,
1359 .resume = resume_send_generic,
1367 .send = send_generic,
1368 .resume = resume_send_generic,
1385 .recv = recv_accounting_request,
1386 .resume = resume_accounting_request,
1400 .send = send_generic,
1401 .resume = resume_send_generic,
1409 .send = send_generic,
1410 .resume = resume_send_generic,
1429 .send = send_generic,
1430 .resume = resume_send_generic,
1456 .section =
SECTION_NAME(
"send",
"Authentication-Pass"),
1461 .section =
SECTION_NAME(
"send",
"Authentication-Fail"),
1466 .section =
SECTION_NAME(
"send",
"Authentication-GetData"),
1471 .section =
SECTION_NAME(
"send",
"Authentication-GetUser"),
1476 .section =
SECTION_NAME(
"send",
"Authentication-GetPass"),
1481 .section =
SECTION_NAME(
"send",
"Authentication-Restart"),
1486 .section =
SECTION_NAME(
"send",
"Authentication-Error"),
1491 .section =
SECTION_NAME(
"recv",
"Authentication-Continue"),
1496 .section =
SECTION_NAME(
"recv",
"Authentication-Continue-Abort"),
1509 .section =
SECTION_NAME(
"recv",
"Authorization-Request"),
1514 .section =
SECTION_NAME(
"send",
"Authorization-Pass-Add"),
1519 .section =
SECTION_NAME(
"send",
"Authorization-Pass-Replace"),
1529 .section =
SECTION_NAME(
"send",
"Authorization-Error"),
1563 DYNAMIC_CLIENT_SECTIONS,
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
@ UNLANG_ACTION_CALCULATE_RESULT
Calculate a new section rlm_rcode_t value.
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
#define CONF_PARSER_TERMINATOR
#define FR_INTEGER_BOUND_CHECK(_name, _var, _op, _bound)
#define FR_CONF_POINTER(_name, _type, _flags, _res_p)
conf_parser_t which parses a single CONF_PAIR producing a single global result
@ CONF_FLAG_SUBSECTION
Instead of putting the information into a configuration structure, the configuration file routines MA...
Defines a CONF_PAIR to C data type mapping.
A section grouping multiple CONF_PAIR.
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
CONF_SECTION * cf_section_find(CONF_SECTION const *cs, char const *name1, char const *name2)
Find a CONF_SECTION with name1 and optionally name2.
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
fr_value_box_t const ** out
Enumeration value.
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
fr_value_box_t const * value
Enum value (what name maps to).
fr_dict_enum_value_t const * fr_dict_enum_by_value(fr_dict_attr_t const *da, fr_value_box_t const *value)
Lookup the structure representing an enum value in a fr_dict_attr_t.
#define DICT_AUTOLOAD_TERMINATOR
char const * name
Enum name.
Specifies an attribute which must be present for the module to function.
Specifies a dictionary which must be loaded/loadable for the module to function.
Specifies a value which must be present for the module to function.
Value of an enumerated attribute.
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
static xlat_action_t xlat_func_tacacs_secret_verify(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Validates a request against a known shared secret.
uint64_t fr_hash64(void const *data, size_t size)
uint32_t fr_hash_string(char const *p)
uint64_t fr_hash64_update(void const *data, size_t size, uint64_t hash)
static fr_dict_t const * dict_freeradius
fr_dict_attr_t const * attr_packet_type
fr_dict_attr_t const * attr_user_name
static fr_dict_attr_t const * attr_module_failure_message
#define REXDENT()
Exdent (unindent) R* messages by one level.
#define RPEDEBUG(fmt,...)
#define RINDENT()
Indent R* messages by one level.
@ L_DBG_LVL_2
2nd highest priority debug messages (-xx | -X).
main_config_t const * main_config
Main server configuration.
bool spawn_workers
Should the server spawn threads.
static int mod_instantiate(module_inst_ctx_t const *mctx)
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT8
8 Bit unsigned integer.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_BOOL
A truth value.
@ FR_TYPE_OCTETS
Raw octets.
unlang_mod_actions_t const mod_actions_authenticate
unlang_mod_actions_t const mod_actions_accounting
unlang_mod_actions_t const mod_actions_authorize
unlang_mod_actions_t const mod_actions_postauth
unlang_mod_action_t actions[RLM_MODULE_NUMCODES]
module_instance_t const * mi
Instance of the module being instantiated.
module_instance_t * mi
Instance of the module being instantiated.
Temporary structure to hold arguments for module calls.
Temporary structure to hold arguments for instantiation calls.
int fr_pair_list_copy(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from)
Duplicate a list of pairs.
int fr_pair_value_memdup(fr_pair_t *vp, uint8_t const *src, size_t len, bool tainted)
Copy data into an "octets" data type.
fr_pair_t * fr_pair_find_by_da_nested(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find a pair with a matching fr_dict_attr_t, by walking the nested fr_dict_attr_t tree.
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
fr_pair_t * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute and assign a fr_dict_attr_t.
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
static unlang_action_t mod_process(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static const virtual_server_compile_t compile_list[]
static fr_process_state_t const process_state[]
RESUME_FLAG(recv_bfd, UNUSED,)
static fr_dict_attr_t const * attr_module_success_message
RECV(for_any_server)
Validate a solicit/rebind/confirm message.
static int mod_load(void)
static void mod_unload(void)
static fr_dict_attr_t const * attr_user_password
static fr_dict_attr_t const * attr_stripped_user_name
static int mod_bootstrap(module_inst_ctx_t const *mctx)
static fr_dict_attr_t const * attr_auth_type
static fr_value_box_t const * enum_auth_type_reject
static const conf_parser_t auth_config[]
static fr_value_box_t const * enum_auth_type_accept
static const conf_parser_t config[]
fr_process_module_t process_tacacs
static fr_dict_attr_t const * attr_tacacs_authentication_flags
CONF_SECTION * autz_pass_add
fr_pair_list_t list
copied from the request
CONF_SECTION * new_client
static fr_value_box_t const * enum_tacacs_auth_type_ascii
CONF_SECTION * add_client
CONF_SECTION * auth_start
CONF_SECTION * acct_success
CONF_SECTION * auth_error
CONF_SECTION * acct_request
CONF_SECTION * auth_cont_abort
fr_dict_attr_autoload_t process_tacacs_dict_attr[]
static xlat_arg_parser_t const xlat_func_tacacs_secret_verify_args[]
static fr_dict_attr_t const * attr_tacacs_user_message
CONF_SECTION * server_cs
Our virtual server.
static fr_dict_attr_t const * attr_chap_password
static const uint32_t acct_status_to_packet_code[UINT8_MAX+1]
CONF_SECTION * auth_restart
static const uint32_t authen_status_to_packet_code[UINT8_MAX+1]
process_tacacs_sections_t sections
Pointers to various config sections we need to execute.
static uint32_t reply_code(request_t *request, fr_dict_attr_t const *status_da, uint32_t const status2code[static UINT8_MAX+1], fr_process_state_t const *state, fr_process_rcode_t const process_rcode, rlm_rcode_t rcode)
Try and determine what the response packet type should be.
static fr_dict_t const * dict_tacacs
fr_dict_enum_autoload_t process_tacacs_dict_enum[]
#define COPY_MISSING(_attr)
static fr_dict_attr_t const * attr_tacacs_session_id
static fr_dict_attr_t const * attr_tacacs_server_message
CONF_SECTION * autz_error
CONF_SECTION * do_not_respond
static const uint32_t author_status_to_packet_code[UINT8_MAX+1]
static fr_value_box_t const * enum_auth_flags_noecho
CONF_SECTION * autz_pass_replace
uint32_t reply
for multiround state machine
CONF_SECTION * auth_getuser
static fr_dict_attr_t const * attr_tacacs_privilege_level
CONF_SECTION * auth_getdata
static fr_dict_attr_t const * attr_tacacs_authentication_type
CONF_SECTION * acct_error
static fr_dict_attr_t const * attr_tacacs_accounting_status
CONF_SECTION * autz_request
fr_state_config_t session
track state session information.
static const bool acct_flag_valid[8]
static fr_dict_attr_t const * attr_tacacs_authentication_service
static fr_dict_attr_t const * attr_tacacs_authentication_status
CONF_SECTION * deny_client
static fr_dict_attr_t const * attr_tacacs_authentication_action
static fr_dict_attr_t const * attr_tacacs_client_port
process_tacacs_auth_t auth
Authentication configuration.
static fr_dict_attr_t const * attr_tacacs_remote_address
uint8_t seq_no
sequence number of last request.
fr_state_tree_t * state_tree
State tree to link multiple requests/responses.
static fr_dict_attr_t const * attr_tacacs_action
static fr_dict_attr_t const * attr_tacacs_sequence_number
static fr_dict_attr_t const * attr_tacacs_authorization_status
static fr_dict_attr_t const * attr_tacacs_accounting_flags
static fr_dict_attr_t const * attr_tacacs_data
static fr_dict_attr_t const * attr_tacacs_state
uint32_t session_id
current session ID
CONF_SECTION * auth_getpass
fr_dict_autoload_t process_tacacs_dict[]
static int state_create(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *request, bool reply)
#define PROCESS_TRACE
Trace each state function as it's entered.
#define PROCESS_CONF_OFFSET(_x)
module_t common
Common fields for all loadable modules.
Common public symbol definition for all process modules.
char const * fr_tacacs_packet_names[FR_TACACS_CODE_MAX]
ssize_t fr_tacacs_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *vendor, uint8_t const *buffer, size_t buffer_len, const uint8_t *original, char const *const secret, size_t secret_len, int *code)
Decode a TACACS+ packet.
static void send_reply(int sockfd, fr_channel_data_t *reply)
fr_table_num_sorted_t const rcode_table[]
#define RETURN_UNLANG_FAIL
rlm_rcode_t
Return codes indicating the result of the module call.
@ RLM_MODULE_INVALID
The module considers the request invalid.
@ RLM_MODULE_OK
The module is OK, continue.
@ RLM_MODULE_FAIL
Module failed, don't reply.
@ RLM_MODULE_DISALLOW
Reject the request (user is locked out).
@ RLM_MODULE_REJECT
Immediately reject the request.
@ RLM_MODULE_TIMEOUT
Module (or section) timed out.
@ RLM_MODULE_NOTFOUND
User not found.
@ RLM_MODULE_UPDATED
OK (pairs modified).
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
@ RLM_MODULE_NUMCODES
How many valid return codes there are.
@ RLM_MODULE_HANDLED
The module handled the request, so stop.
#define request_is_dynamic_client(_x)
void * request_data_reference(request_t *request, void const *unique_ptr, int unique_int)
Get opaque data from a request without removing it.
#define request_data_talloc_add(_request, _unique_ptr, _unique_int, _type, _opaque, _free_on_replace, _free_on_parent, _persist)
Add opaque data to a request_t.
static unlang_action_t process_rcode(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static unsigned int hash(char const *username, unsigned int tablesize)
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
CONF_SECTION * conf
Module's instance configuration.
void * data
Module's instance data.
#define MODULE_RCTX(_ctype)
#define MODULE_INST(_ctype)
conf_parser_t const * config
How to convert a CONF_SECTION to a module instance.
#define pair_delete_reply(_pair_or_da)
Delete a fr_pair_t in the reply list.
#define pair_append_reply(_attr, _da)
Allocate and append a fr_pair_t to reply list.
int fr_state_restore(fr_state_tree_t *state, request_t *request)
Copy a pointer to the head of the list of state fr_pair_ts (and their ctx) into the request.
void fr_state_discard(fr_state_tree_t *state, request_t *request)
Called when sending an Access-Accept/Access-Reject to discard state information.
int fr_state_store(fr_state_tree_t *state, request_t *request)
Transfer ownership of the state fr_pair_ts and ctx, back to a state entry.
const conf_parser_t state_session_config[]
fr_state_tree_t * fr_state_tree_init(TALLOC_CTX *ctx, fr_dict_attr_t const *da, fr_state_config_t const *config)
Initialise a new state tree.
unlang_action_t unlang_module_yield_to_section(unlang_result_t *p_result, request_t *request, CONF_SECTION *subcs, rlm_rcode_t default_rcode, module_method_t resume, unlang_module_signal_t signal, fr_signal_t sigmask, void *rctx)
eap_aka_sim_process_conf_t * inst
Stores an attribute, a value and various bits of other data.
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
@ FR_TAC_PLUS_AUTHOR_STATUS_PASS_ADD
@ FR_TAC_PLUS_AUTHOR_STATUS_ERROR
@ FR_TAC_PLUS_AUTHOR_STATUS_FAIL
@ FR_TAC_PLUS_AUTHOR_STATUS_PASS_REPL
#define FR_TACACS_PACKET_CODE_VALID(_code)
#define packet_is_authen_start_request(p)
3.4.
@ FR_TACACS_CODE_ACCT_ERROR
@ FR_TACACS_CODE_DO_NOT_RESPOND
@ FR_TACACS_CODE_ACCT_REQUEST
@ FR_TACACS_CODE_AUTZ_REQUEST
@ FR_TACACS_CODE_AUTH_GETDATA
@ FR_TACACS_CODE_AUTH_RESTART
@ FR_TACACS_CODE_AUTZ_PASS_REPLACE
@ FR_TACACS_CODE_AUTH_GETUSER
@ FR_TACACS_CODE_AUTH_GETPASS
@ FR_TACACS_CODE_AUTZ_FAIL
@ FR_TACACS_CODE_AUTH_CONT_ABORT
@ FR_TACACS_CODE_AUTH_PASS
@ FR_TACACS_CODE_AUTH_CONT
@ FR_TACACS_CODE_AUTZ_PASS_ADD
@ FR_TACACS_CODE_AUTH_START
@ FR_TACACS_CODE_AUTH_FAIL
@ FR_TACACS_CODE_AUTH_ERROR
@ FR_TACACS_CODE_AUTZ_ERROR
@ FR_TACACS_CODE_ACCT_SUCCESS
@ FR_TAC_PLUS_ACCT_STATUS_SUCCESS
@ FR_TAC_PLUS_ACCT_STATUS_ERROR
@ FR_TAC_PLUS_AUTHEN_STATUS_PASS
@ FR_TAC_PLUS_AUTHEN_STATUS_GETDATA
@ FR_TAC_PLUS_AUTHEN_STATUS_ERROR
@ FR_TAC_PLUS_AUTHEN_STATUS_GETUSER
@ FR_TAC_PLUS_AUTHEN_STATUS_FAIL
@ FR_TAC_PLUS_AUTHEN_STATUS_RESTART
@ FR_TAC_PLUS_AUTHEN_STATUS_GETPASS
#define talloc_get_type_abort_const
#define XLAT_ARGS(_list,...)
Populate local variables with value boxes from the input list.
unsigned int required
Argument must be present, and non-empty.
#define XLAT_ARG_PARSER_TERMINATOR
@ XLAT_ACTION_FAIL
An xlat function failed.
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
Definition for a single argument consumed by an xlat function.
fr_pair_t * fr_pair_list_next(fr_pair_list_t const *list, fr_pair_t const *item))
Get the next item in a valuepair list after a specific entry.
int8_t fr_value_box_cmp(fr_value_box_t const *a, fr_value_box_t const *b)
Compare two values.
int fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t *src)
Copy value data verbatim duplicating any buffers.
#define fr_value_box_alloc(_ctx, _type, _enumv)
Allocate a value box of a specific type.
static size_t char ** out
int virtual_server_section_attribute_define(CONF_SECTION *server_cs, char const *subcs_name, fr_dict_attr_t const *da)
Define a values for Auth-Type attributes by the sections present in a virtual-server.
section_name_t const * section
Identifier for the section.
#define COMPILE_TERMINATOR
Processing sections which are allowed in this virtual server.
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
xlat_t * xlat_func_register(TALLOC_CTX *ctx, char const *name, xlat_func_t func, fr_type_t return_type)
Register an xlat function.
void xlat_func_unregister(char const *name)
Unregister an xlat function.