25 #include <freeradius-devel/protocol/freeradius/freeradius.internal.h>
27 #include <freeradius-devel/radius/radius.h>
29 #include <freeradius-devel/server/main_config.h>
30 #include <freeradius-devel/server/module.h>
31 #include <freeradius-devel/server/pair.h>
32 #include <freeradius-devel/server/protocol.h>
33 #include <freeradius-devel/server/state.h>
34 #include <freeradius-devel/server/log.h>
35 #include <freeradius-devel/unlang/xlat.h>
37 #include <freeradius-devel/unlang/module.h>
38 #include <freeradius-devel/unlang/interpret.h>
39 #include <freeradius-devel/unlang/xlat_func.h>
41 #include <freeradius-devel/util/debug.h>
42 #include <freeradius-devel/util/pair.h>
43 #include <freeradius-devel/util/value.h>
159 #define FR_RADIUS_PROCESS_CODE_VALID(_x) (FR_RADIUS_PACKET_CODE_VALID(_x) || (_x == FR_RADIUS_CODE_DO_NOT_RESPOND))
161 #define PROCESS_PACKET_TYPE fr_radius_packet_code_t
162 #define PROCESS_CODE_MAX FR_RADIUS_CODE_MAX
163 #define PROCESS_CODE_DO_NOT_RESPOND FR_RADIUS_CODE_DO_NOT_RESPOND
164 #define PROCESS_PACKET_CODE_VALID FR_RADIUS_PROCESS_CODE_VALID
165 #define PROCESS_INST process_radius_t
166 #define PROCESS_CODE_DYNAMIC_CLIENT FR_RADIUS_CODE_ACCESS_ACCEPT
167 #include <freeradius-devel/server/process.h>
195 #ifdef WITH_IFINDEX_NAME_RESOLUTION
196 char if_name[IFNAMSIZ];
203 #ifdef WITH_IFINDEX_NAME_RESOLUTION
207 received ?
"Received" :
"Sending",
210 packet->
socket.inet.src_ipaddr.
af == AF_INET6 ?
"[" :
"",
212 packet->
socket.inet.src_ipaddr.
af == AF_INET6 ?
"]" :
"",
213 packet->
socket.inet.src_port,
214 packet->
socket.inet.dst_ipaddr.
af == AF_INET6 ?
"[" :
"",
216 packet->
socket.inet.dst_ipaddr.
af == AF_INET6 ?
"]" :
"",
217 packet->
socket.inet.dst_port
218 #ifdef WITH_IFINDEX_NAME_RESOLUTION
219 , packet->
socket.inet.ifindex ?
"via " :
"",
220 packet->
socket.inet.ifindex ? fr_ifname_from_ifindex(if_name, packet->
socket.inet.ifindex) :
"",
221 packet->
socket.inet.ifindex ?
" " :
""
225 if (received || request->parent) {
235 static inline CC_HINT(always_inline)
245 if (!proxy_state)
return 0;
258 fr_value_box_list_insert_tail(&rctx->
proxy_state, proxy_state_value);
264 static inline CC_HINT(always_inline)
289 RDEBUG3(
"Adding Proxy-State attributes from request");
312 return CALL_RECV(
generic);
322 return CALL_RESUME(send_generic);
338 return CALL_RECV(generic_radius_request);
349 fr_process_state_t
const *state;
359 UPDATE_STATE(packet);
361 request->reply->code = state->packet_type[rcode];
362 if (!request->reply->code) request->reply->code = state->default_reply;
368 RDEBUG(
"The 'recv Access-Request' section returned %s - rejecting the request",
375 return CALL_SEND_STATE(state);
378 if (request->reply->code) {
385 if (!request->reply->code) {
388 request->reply->code =
vp->vp_uint32;
401 RDEBUG(
"No 'Auth-Type' attribute found, cannot authenticate the user - rejecting the request");
410 RDEBUG(
"Invalid value for 'Auth-Type' attribute, cannot authenticate the user - rejecting the request");
434 RDEBUG2(
"No 'authenticate %s { ... }' section found - rejecting the request", dv->
name);
446 NULL, 0, mctx->rctx);
451 static const fr_process_rcode_t auth_type_rcode = {
464 fr_process_state_t
const *state;
471 request->reply->code = auth_type_rcode[rcode];
474 RDEBUG(
"The 'authenticate' section returned %s - not sending a response",
478 return state->send(p_result, mctx, request);
484 if (auth_type_rcode[rcode]) request->reply->code = auth_type_rcode[rcode];
486 switch (request->reply->code) {
488 RDEBUG(
"No reply code was set. Forcing to Access-Reject");
496 RDEBUG2(
"Failed to authenticate the user");
512 RWDEBUG(
"Unprintable characters in the password. "
513 "Double-check the shared secret on the server "
547 return state->send(p_result, mctx, request);
563 if (!request->parent &&
565 (
vp->vp_strvalue[0] ==
'@') &&
567 RWDEBUG(
"User-Name is anonymized, and no Stripped-User-Name exists.");
568 RWDEBUG(
"It may be difficult or impossible to identify the user.");
569 RWDEBUG(
"Please update Stripped-User-Name with information which identifies the user.");
629 if (!event_timestamp) {
636 if (acct_delay->vp_uint32 < ((365 * 86400))) {
639 RDEBUG(
"Accounting-Request packet contains %pP. Creating %pP",
640 acct_delay, event_timestamp);
643 RDEBUG(
"Accounting-Request packet is missing Event-Timestamp. Adding it to packet as %pP.", event_timestamp);
647 return CALL_RECV(
generic);
652 static const fr_process_rcode_t acct_type_rcode = {
661 fr_process_state_t
const *state;
668 if (acct_type_rcode[rcode]) {
671 request->reply->code = acct_type_rcode[rcode];
674 RDEBUG(
"The 'accounting' section returned %s - not sending a response",
678 return state->send(p_result, mctx, request);
685 return state->send(p_result, mctx, request);
694 fr_process_state_t
const *state;
701 UPDATE_STATE(packet);
702 fr_assert(state->packet_type[rcode] != 0);
704 request->reply->code = state->packet_type[rcode];
705 UPDATE_STATE_CS(reply);
708 RDEBUG(
"The 'recv Accounting-Request' section returned %s - not sending a response",
713 return CALL_SEND_STATE(state);
727 RDEBUG2(
"No 'accounting %s { ... }' section found - skipping...", dv->
name);
738 NULL, 0, mctx->rctx);
769 vp->vp_uint32 = request->packet->code;
781 vp->vp_uint32 = FR_ERROR_CAUSE_VALUE_INVALID_REQUEST;
789 return CALL_RESUME(send_generic);
794 fr_process_state_t
const *state;
800 request->component =
"radius";
801 request->module = NULL;
806 UPDATE_STATE(packet);
809 REDEBUG(
"Invalid packet type (%u)", request->packet->code);
816 return new_client(p_result, mctx, request);
819 return state->recv(p_result, mctx, request);
844 bool require_message_authenticator =
false;
866 RPEDEBUG(
"Failed verifying secret");
870 RPDEBUG2(
"Provided secret was not used to sign this packet");
886 inst->auth.session_timeout,
inst->auth.state_server_id,
933 .recv = recv_access_request,
934 .resume = resume_access_request,
945 .send = send_generic,
946 .resume = resume_access_accept,
957 .send = send_generic,
958 .resume = resume_access_reject,
969 .send = send_generic,
970 .resume = resume_access_challenge,
988 .recv = recv_accounting_request,
989 .resume = resume_accounting_request,
1001 .send = send_generic,
1002 .resume = resume_generic_radius_response,
1018 .recv = recv_generic,
1019 .resume = resume_recv_generic,
1035 .recv = recv_generic_radius_request,
1036 .resume = resume_recv_generic,
1047 .send = send_generic,
1048 .resume = resume_generic_radius_response,
1059 .send = send_generic,
1060 .resume = resume_generic_radius_response,
1076 .recv = recv_generic,
1077 .resume = resume_recv_generic,
1088 .send = send_generic,
1089 .resume = resume_generic_radius_response,
1100 .send = send_generic,
1101 .resume = resume_generic_radius_response,
1112 .send = send_generic,
1113 .resume = resume_protocol_error,
1130 .send = send_generic,
1131 .resume = resume_send_generic,
1140 .offset = PROCESS_CONF_OFFSET(access_request),
1145 .offset = PROCESS_CONF_OFFSET(access_accept),
1150 .offset = PROCESS_CONF_OFFSET(access_challenge),
1155 .offset = PROCESS_CONF_OFFSET(access_reject),
1161 .offset = PROCESS_CONF_OFFSET(accounting_request),
1164 .section =
SECTION_NAME(
"send",
"Accounting-Response"),
1166 .offset = PROCESS_CONF_OFFSET(accounting_response),
1172 .offset = PROCESS_CONF_OFFSET(status_server),
1177 .offset = PROCESS_CONF_OFFSET(coa_request),
1182 .offset = PROCESS_CONF_OFFSET(coa_ack),
1187 .offset = PROCESS_CONF_OFFSET(coa_nak),
1192 .offset = PROCESS_CONF_OFFSET(disconnect_request),
1197 .offset = PROCESS_CONF_OFFSET(disconnect_ack),
1202 .offset = PROCESS_CONF_OFFSET(disconnect_nak),
1207 .offset = PROCESS_CONF_OFFSET(protocol_error),
1212 .offset = PROCESS_CONF_OFFSET(do_not_respond),
1223 DYNAMIC_CLIENT_SECTIONS,
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
static int const char char buffer[256]
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
#define CONF_PARSER_TERMINATOR
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
#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.
CONF_SECTION * cf_section_find(CONF_SECTION const *cs, char const *name1, char const *name2)
Find a CONF_SECTION with name1 and optionally name2.
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
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.
#define fr_assert_msg(_x, _msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
@ FR_RADIUS_CODE_ACCESS_CHALLENGE
RFC2865 - Access-Challenge.
@ FR_RADIUS_CODE_ACCESS_REQUEST
RFC2865 - Access-Request.
@ FR_RADIUS_CODE_DISCONNECT_REQUEST
RFC3575/RFC5176 - Disconnect-Request.
@ FR_RADIUS_CODE_DO_NOT_RESPOND
Special rcode to indicate we will not respond.
@ FR_RADIUS_CODE_DISCONNECT_ACK
RFC3575/RFC5176 - Disconnect-Ack (positive)
@ FR_RADIUS_CODE_STATUS_SERVER
RFC2865/RFC5997 - Status Server (request)
@ FR_RADIUS_CODE_COA_REQUEST
RFC3575/RFC5176 - CoA-Request.
@ FR_RADIUS_CODE_ACCESS_ACCEPT
RFC2865 - Access-Accept.
@ FR_RADIUS_CODE_ACCOUNTING_RESPONSE
RFC2866 - Accounting-Response.
@ FR_RADIUS_CODE_COA_NAK
RFC3575/RFC5176 - CoA-Nak (not willing to perform)
@ FR_RADIUS_CODE_COA_ACK
RFC3575/RFC5176 - CoA-Ack (positive)
@ FR_RADIUS_CODE_DISCONNECT_NAK
RFC3575/RFC5176 - Disconnect-Nak (not willing to perform)
@ FR_RADIUS_CODE_PROTOCOL_ERROR
RFC7930 - Protocol-Error (generic NAK)
@ FR_RADIUS_CODE_ACCOUNTING_REQUEST
RFC2866 - Accounting-Request.
@ FR_RADIUS_CODE_ACCESS_REJECT
RFC2865 - Access-Reject.
fr_value_box_t const ** out
Enumeration value.
fr_dict_enum_value_t * 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.
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).
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_radius_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 know shared secret.
uint32_t fr_hash_string(char const *p)
TALLOC_CTX * unlang_interpret_frame_talloc_ctx(request_t *request)
Get a talloc_ctx which is valid only for this frame.
fr_dict_attr_t const * attr_packet_type
fr_dict_attr_t const * attr_state
fr_dict_t const * dict_freeradius
fr_dict_t const * dict_radius
fr_dict_attr_t const * attr_user_name
void log_request_proto_pair_list(fr_log_lvl_t lvl, request_t *request, fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix)
Print a list of protocol fr_pair_ts.
void log_request(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, char const *fmt,...)
Marshal variadic log arguments into a va_list and pass to normal logging functions.
void log_request_pair_list(fr_log_lvl_t lvl, request_t *request, fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix)
Print a fr_pair_list_t.
#define REXDENT()
Exdent (unindent) R* messages by one level.
#define RPDEBUG2(fmt,...)
#define RPEDEBUG(fmt,...)
#define RINDENT()
Indent R* messages by one level.
@ L_DBG_LVL_1
Highest priority debug messages (-x).
@ L_DBG
Only displayed when debugging is enabled.
main_config_t const * main_config
Main server configuration.
bool spawn_workers
Should the server spawn threads.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_DATE
Unix time stamp, always has value >2^31.
@ 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_preacct
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
module_instance_t const * mi
Instance of the module being instantiated.
void * rctx
Resume ctx that a module previously set.
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.
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.
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.
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.
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
int fr_pair_delete_by_da(fr_pair_list_t *list, fr_dict_attr_t const *da)
Delete matching pairs from the specified list.
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.
size_t fr_utf8_char(uint8_t const *str, ssize_t inlen)
Checks for utf-8, taken from http://www.w3.org/International/questions/qa-forms-utf-8.
RECV(for_any_server)
Validate a solicit/rebind/confirm message.
process_radius_auth_t auth
Authentication configuration.
static int mod_load(void)
CONF_SECTION * access_challenge
static fr_dict_attr_t const * attr_user_password
static fr_dict_attr_t const * attr_module_failure_message
static unlang_action_t mod_process(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
static virtual_server_compile_t const compile_list[]
static xlat_arg_parser_t const xlat_func_radius_secret_verify_args[]
CONF_SECTION * disconnect_ack
CONF_SECTION * protocol_error
CONF_SECTION * new_client
static fr_dict_attr_t const * attr_stripped_user_name
fr_dict_attr_autoload_t process_radius_dict_attr[]
fr_value_box_list_head_t proxy_state
These need to be copied into the response in exactly the same order as they were added.
static const conf_parser_t session_config[]
CONF_SECTION * coa_request
uint8_t state_server_id
Sets a specific byte in the state to allow the authenticating server to be identified in packet captu...
fr_dict_enum_autoload_t process_radius_dict_enum[]
static int mod_bootstrap(module_inst_ctx_t const *mctx)
fr_process_module_t process_radius
static fr_dict_attr_t const * attr_auth_type
#define FR_RADIUS_PROCESS_CODE_VALID(_x)
static void radius_request_pairs_to_reply(request_t *request, process_radius_request_pairs_t *rctx)
CONF_SECTION * disconnect_nak
CONF_SECTION * access_accept
static fr_value_box_t const * enum_auth_type_reject
static fr_dict_attr_t const * attr_error_cause
static void mod_unload(void)
CONF_SECTION * add_client
static const conf_parser_t auth_config[]
fr_time_delta_t session_timeout
Maximum time between the last response and next request.
CONF_SECTION * server_cs
Our virtual server.
static fr_process_state_t const process_state[]
CONF_SECTION * access_request
static fr_dict_attr_t const * attr_proxy_state
static void radius_packet_debug(request_t *request, fr_packet_t *packet, fr_pair_list_t *list, bool received)
static fr_value_box_t const * enum_auth_type_accept
uint32_t max_session
Maximum ongoing session allowed.
CONF_SECTION * status_server
CONF_SECTION * access_reject
static fr_dict_attr_t const * attr_acct_status_type
CONF_SECTION * disconnect_request
CONF_SECTION * accounting_request
CONF_SECTION * do_not_respond
process_radius_sections_t sections
Pointers to various config sections we need to execute.
static process_radius_request_pairs_t * radius_request_pairs_store(request_t *request)
Keep a copy of some attributes to keep them from being tamptered with.
static fr_dict_attr_t const * attr_original_packet_code
static const conf_parser_t config[]
fr_dict_autoload_t process_radius_dict[]
fr_state_tree_t * state_tree
State tree to link multiple requests/responses.
static fr_dict_attr_t const * attr_event_timestamp
CONF_SECTION * accounting_response
static int mod_instantiate(module_inst_ctx_t const *mctx)
static fr_dict_attr_t const * attr_module_success_message
CONF_SECTION * deny_client
Records fields from the original request so we have a known good copy.
#define PROCESS_TRACE
Trace each state function as it's entered.
module_t common
Common fields for all loadable modules.
Common public symbol definition for all process modules.
int fr_radius_verify(uint8_t *packet, uint8_t const *vector, uint8_t const *secret, size_t secret_len, bool require_message_authenticator, bool limit_proxy_state)
Verify a request / response packet.
char const * fr_radius_packet_name[FR_RADIUS_CODE_MAX]
#define RDEBUG_ENABLED2()
static void send_reply(int sockfd, fr_channel_data_t *reply)
#define FR_RADIUS_PACKET_CODE_VALID(_x)
void fr_rand_buffer(void *start, size_t length)
fr_table_num_sorted_t const rcode_table[]
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_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)
static int instantiate(module_inst_ctx_t const *mctx)
#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 pair_update_reply(_attr, _da)
Return or allocate a fr_pair_t in the reply list.
fr_state_tree_t * fr_state_tree_init(TALLOC_CTX *ctx, fr_dict_attr_t const *da, bool thread_safe, uint32_t max_sessions, fr_time_delta_t timeout, uint8_t server_id, uint32_t context_id)
Initialise a new state tree.
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_request_to_state(fr_state_tree_t *state, request_t *request)
Transfer ownership of the state fr_pair_ts and ctx, back to a state entry.
int fr_state_to_request(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.
unlang_action_t unlang_module_yield_to_section(rlm_rcode_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)
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
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.
#define talloc_get_type_abort_const
static fr_unix_time_t fr_unix_time_sub_time_delta(fr_unix_time_t a, fr_time_delta_t b)
static fr_time_delta_t fr_time_delta_from_sec(int64_t sec)
static fr_unix_time_t fr_time_to_unix_time(fr_time_t when)
Convert an fr_time_t (internal time) to our version of unix time (wallclock time)
A time delta, a difference in time measured in nanoseconds.
bool required
Argument must be present, and non-empty.
#define XLAT_ARGS(_list,...)
Populate local variables with value boxes from the input list.
#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 consumend by an xlat function.
unsigned int code
Packet code (type).
fr_socket_t socket
This packet was received on.
int id
Packet ID (used to link requests/responses).
int af
AF_INET, AF_INET6, or AF_UNIX.
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.
#define fr_box_ipaddr(_val)
static fr_value_box_t * fr_value_box_acopy(TALLOC_CTX *ctx, fr_value_box_t const *src)
Copy an existing box, allocating a new box to hold its contents.
#define fr_value_box_list_foreach(_list_head, _iter)
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.
#define COMPILE_TERMINATOR
section_name_t const * section
Identifier for the section.
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.