25RCSID(
"$Id: dc2d89dbd0b4937fd8c4e415226ad33bf7546992 $")
27#include <freeradius-devel/io/application.h>
28#include <freeradius-devel/server/modpriv.h>
29#include <freeradius-devel/unlang/xlat_func.h>
30#include <freeradius-devel/util/debug.h>
31#include <freeradius-devel/util/dlist.h>
320 cf_log_err(ci,
"Unknown or invalid RADIUS packet type '%s'", type_str);
324 code = type_enum->
value->vb_uint32;
330 cf_log_err(ci,
"Invalid setting of 'type = Status-Server'. Status-Server packets cannot be proxied.");
375 cf_log_err(ci,
"Unknown or invalid RADIUS packet type '%s'", type_str);
379 code = type_enum->
value->vb_uint32;
395 memcpy(
out, &code,
sizeof(code));
424 map_list_t *
head = (map_list_t *)
out;
431 if (!name2 || (strcmp(name2,
"request") != 0)) {
432 cf_log_err(cs,
"You must specify 'request' as the destination list");
447 if (rcode < 0)
return -1;
448 if (map_list_empty(
head)) {
449 cf_log_err(cs,
"'update' sections cannot be empty");
470 RWDEBUG(
"Status-Server is reserved for internal use, and cannot be sent manually.");
474 if (!
inst->allowed[request->packet->code]) {
475 REDEBUG(
"Packet code %s is disallowed by the configuration",
486 unsigned int count = 0;
492 if (
vp->vp_length !=
sizeof(
inst->common_ctx.proxy_state))
continue;
494 if (memcmp(
vp->vp_octets, &
inst->common_ctx.proxy_state,
495 sizeof(
inst->common_ctx.proxy_state)) == 0) {
503 RWARN(
"Canceling proxy due to loop of multiple %pV",
vp);
507 RWARN(
"Proxied packet contains our own %pV",
vp);
508 RWARN(
"Check if there is a proxy loop. Perhaps the server has been configured to proxy to itself.");
538 if (!request->packet->code) {
539 REDEBUG(
"You MUST specify a packet code");
545 REDEBUG(
"Invalid packet code %u", request->packet->code);
555 REDEBUG(
"When using 'mode = unconnected-*', this module cannot be used in-place. Instead, it must be called via a function call");
561 REDEBUG(
"Cannot proxy packets which define dynamic clients");
587 inst->received_message_authenticator = talloc_zero(NULL,
bool);
597 if (
inst->replicate) {
598 if (
inst->originate) {
599 cf_log_err(
conf,
"Cannot set 'replicate=true' and 'originate=true' at the same time.");
603 if (
inst->synchronous) {
604 cf_log_warn(
conf,
"Ignoring 'synchronous=true' due to 'replicate=true'");
616 if (
inst->synchronous &&
inst->originate) {
617 cf_log_err(
conf,
"Cannot set 'synchronous=true' and 'originate=true'");
621 if (
inst->synchronous) {
632 if (
inst->fd_config.filename && (
inst->fd_config.flags != O_WRONLY)) {
633 cf_log_info(
conf,
"Setting 'flags = write-only' for writing to a file");
635 inst->fd_config.flags = O_WRONLY | O_APPEND;
637 }
else if (
inst->fd_config.filename) {
638 cf_log_err(
conf,
"When using an output 'filename', you MUST set 'mode = replicate'");
645 inst->fd_config.flags = O_RDWR;
670 if (
inst->fd_config.src_port != 0) {
682 if (!
inst->status_check) {
687 num_types = talloc_array_length(
inst->types);
692 .mrd =
inst->response_window,
696 .secret =
inst->secret,
697 .secret_length =
inst->secret ? talloc_array_length(
inst->secret) - 1 : 0,
704 for (i = 0; i < num_types; i++) {
707 code =
inst->types[i];
711 inst->allowed[code] =
true;
720 if (
inst->status_check) {
722 cf_log_warn(
conf,
"Ignoring 'status_check = %s' due to 'mode = replicate'",
724 inst->status_check =
false;
728 cf_log_warn(
conf,
"Ignoring 'status_check = %s' due to 'mode' setting",
730 inst->status_check =
false;
740 if (
inst->status_check) {
742 inst->allowed[
inst->status_check] =
true;
744 }
else if (!
inst->allowed[
inst->status_check]) {
745 cf_log_err(
conf,
"Using 'status_check = %s' requires also 'type = %s'",
756 if (
inst->fd_config.filename) {
758 inst->status_check = 0;
765 if (
inst->fd_config.filename ||
inst->fd_config.path) {
766 inst->max_send_coalesce = 1;
769 inst->trunk_conf.req_pool_headers = 4;
770 inst->trunk_conf.req_pool_size = 1024 +
sizeof(
fr_pair_t) + 20;
868 switch (
inst->mode) {
898 PERROR(
"Failed initialising protocol library");
934 .thread_inst_type =
"bio_thread_t",
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
#define L(_str)
Helper for initialising arrays of string literals.
int cf_table_parse_int(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
Generic function for parsing conf pair values as int.
#define CONF_PARSER_TERMINATOR
cf_parse_t func
Override default parsing behaviour for the specified type with a custom parsing function.
#define FR_INTEGER_BOUND_CHECK(_name, _var, _op, _bound)
#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
char const * name2
Second identifier for CONF_SECTION.
#define cf_section_rules_push(_cs, _rule)
#define FR_CONF_POINTER(_name, _type, _flags, _res_p)
conf_parser_t which parses a single CONF_PAIR producing a single global result
#define cf_section_rule_push(_cs, _rule)
#define FR_CONF_OFFSET_FLAGS(_name, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
#define FR_CONF_OFFSET_REF(_struct, _field, _subcs)
conf_parser_t which populates a sub-struct using a CONF_SECTION
#define FR_CONF_OFFSET_SUBSECTION(_name, _flags, _struct, _field, _subcs)
conf_parser_t which populates a sub-struct using a CONF_SECTION
#define FR_TIME_DELTA_BOUND_CHECK(_name, _var, _op, _bound)
@ CONF_FLAG_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
@ CONF_FLAG_MULTI
CONF_PAIR can have multiple copies.
@ CONF_FLAG_DEPRECATED
If a matching CONF_PAIR is found, error out with a deprecated message.
@ CONF_FLAG_NOT_EMPTY
CONF_PAIR is required to have a non zero length value.
@ CONF_FLAG_OPTIONAL
subsection is pushed only if a non-optional matching one is pushed
@ CONF_FLAG_SUBSECTION
Instead of putting the information into a configuration structure, the configuration file routines MA...
#define FR_CONF_OFFSET_TYPE_FLAGS(_name, _type, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Defines a CONF_PAIR to C data type mapping.
Common header for all CONF_* types.
A section grouping multiple CONF_PAIR.
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
char const * cf_section_name1(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.
bool cf_item_is_section(CONF_ITEM const *ci)
Determine if CONF_ITEM is a CONF_SECTION.
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_PAIR.
char const * cf_pair_value(CONF_PAIR const *pair)
Return the value of a CONF_PAIR.
#define cf_log_err(_cf, _fmt,...)
#define cf_log_info(_cf, _fmt,...)
#define cf_log_perr(_cf, _fmt,...)
#define cf_log_warn(_cf, _fmt,...)
static void * fr_dcursor_next(fr_dcursor_t *cursor)
Advanced the cursor to the next item.
@ FR_RADIUS_CODE_ACCESS_REQUEST
RFC2865 - Access-Request.
@ FR_RADIUS_CODE_DISCONNECT_REQUEST
RFC3575/RFC5176 - Disconnect-Request.
@ FR_RADIUS_CODE_MAX
Maximum possible protocol code.
@ FR_RADIUS_CODE_STATUS_SERVER
RFC2865/RFC5997 - Status Server (request)
@ FR_RADIUS_CODE_COA_REQUEST
RFC3575/RFC5176 - CoA-Request.
@ FR_RADIUS_CODE_ACCOUNTING_REQUEST
RFC2866 - Accounting-Request.
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 * fr_dict_enum_by_name(fr_dict_attr_t const *da, char const *name, ssize_t len)
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.
Value of an enumerated attribute.
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
@ FR_BIO_FD_CONNECTED
connected client sockets (UDP or TCP)
@ FR_BIO_FD_UNCONNECTED
unconnected UDP / datagram only
const conf_parser_t fr_bio_fd_client_config[]
int fr_bio_fd_check_config(fr_bio_fd_config_t const *cfg)
Checks the configuration without modifying anything.
bool active
for dynamic clients
bool dynamic
Whether the client was dynamically defined.
Describes a host allowed to send packets to the server.
int map_afrom_cs(TALLOC_CTX *ctx, map_list_t *out, CONF_SECTION *cs, tmpl_rules_t const *lhs_rules, tmpl_rules_t const *rhs_rules, map_validate_t validate, void *uctx, unsigned int max)
Convert a config section into an attribute map.
@ FR_TYPE_TLV
Contains nested attributes.
@ 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_OCTETS
Raw octets.
int unlang_fixup_update(map_t *map, void *ctx)
Validate and fixup a map that's part of an update section.
module_instance_t const * mi
Instance of the module being instantiated.
void * thread
Thread specific instance data.
module_instance_t * mi
Module instance to detach.
module_instance_t * mi
Instance of the module being instantiated.
Temporary structure to hold arguments for module calls.
Temporary structure to hold arguments for detach calls.
Temporary structure to hold arguments for instantiation calls.
xlat_t * module_rlm_xlat_register(TALLOC_CTX *ctx, module_inst_ctx_t const *mctx, char const *name, xlat_func_t func, fr_type_t return_type)
module_t common
Common fields presented by all modules.
static int mod_enqueue(bio_request_t **p_u, fr_retry_config_t const **p_retry_config, rlm_radius_t const *inst, trunk_t *trunk, request_t *request)
static void mod_retry(module_ctx_t const *mctx, request_t *request, fr_retry_t const *retry)
Handle module retries.
bio_handle_ctx_t ctx
for copying to bio_handle_t
static xlat_action_t xlat_radius_replicate(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
static xlat_action_t xlat_radius_client(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
trunk_t * trunk
trunk handler
static unlang_action_t mod_resume(rlm_rcode_t *p_result, module_ctx_t const *mctx, UNUSED request_t *request)
Resume execution of the request, returning the rcode set during trunk execution.
static xlat_arg_parser_t const xlat_radius_send_args[]
Connect request_t to local tracking structure.
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(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.
static const conf_parser_t config[]
size_t fr_radius_require_ma_table_len
int fr_radius_global_init(void)
void fr_radius_global_free(void)
fr_table_num_sorted_t const fr_radius_require_ma_table[]
char const * fr_radius_packet_name[FR_RADIUS_CODE_MAX]
Functions to support RADIUS bio handlers.
static fr_bio_fd_config_t fd_config
#define RADIUS_MAX_ATTRIBUTES
uint32_t fr_rand(void)
Return a 32-bit random number.
#define RETURN_MODULE_NOOP
#define RETURN_MODULE_FAIL
rlm_rcode_t
Return codes indicating the result of the module call.
static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx)
static conf_parser_t coa_config[]
static conf_parser_t disconnect_config[]
static int status_check_type_parse(TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
static int mod_detach(module_detach_ctx_t const *mctx)
static int mod_load(void)
static fr_dict_attr_t const * attr_packet_type
static fr_dict_attr_t const * attr_user_password
static unlang_action_t mod_process(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Send packets outbound.
static fr_dict_attr_t const * attr_eap_message
static int type_parse(TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
static conf_parser_t const pool_config[]
static fr_dict_attr_t const * attr_chap_password
static fr_dict_t const * dict_radius
static int mod_bootstrap(module_inst_ctx_t const *mctx)
static fr_dict_attr_t const * attr_chap_challenge
static conf_parser_t status_config[]
fr_dict_attr_autoload_t rlm_radius_dict_attr[]
static fr_dict_attr_t const * attr_extended_attribute_1
static fr_dict_attr_t const * attr_error_cause
static void mod_unload(void)
static fr_dict_attr_t const * attr_proxy_state
static int radius_fixups(rlm_radius_t const *inst, request_t *request)
Do any RADIUS-layer fixups for proxying.
static fr_dict_attr_t const * attr_nas_identifier
static conf_parser_t const type_interval_config[FR_RADIUS_CODE_MAX]
static conf_parser_t auth_config[]
static int mode_parse(TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
fr_dict_autoload_t rlm_radius_dict[]
static conf_parser_t const transport_config[]
static int status_check_update_parse(TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
static fr_dict_attr_t const * attr_original_packet_code
static fr_dict_attr_t const * attr_event_timestamp
static conf_parser_t const status_check_update_config[]
static fr_dict_attr_t const * attr_response_length
static int mod_instantiate(module_inst_ctx_t const *mctx)
static conf_parser_t const status_check_config[]
static size_t mode_names_len
static fr_table_num_sorted_t mode_names[]
static conf_parser_t const module_config[]
static conf_parser_t const connected_config[]
static fr_dict_attr_t const * attr_message_authenticator
static conf_parser_t acct_config[]
struct rlm_radius_s rlm_radius_t
@ RLM_RADIUS_MODE_XLAT_PROXY
@ RLM_RADIUS_MODE_INVALID
@ RLM_RADIUS_MODE_REPLICATE
@ RLM_RADIUS_MODE_UNCONNECTED_REPLICATE
static int instantiate(module_inst_ctx_t const *mctx)
static conf_parser_t retry_config[]
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
char const * name
Instance name e.g. user_database.
CONF_SECTION * conf
Module's instance configuration.
size_t inst_size
Size of the module's instance data.
void * data
Module's instance data.
void * boot
Data allocated during the boostrap phase.
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Named methods exported by a module.
#define pair_append_request(_attr, _da)
Allocate and append a fr_pair_t to the request list.
tmpl_attr_rules_t attr
Rules/data for parsing attribute references.
Optional arguments passed to vp_tmpl functions.
fr_client_t * client_from_request(request_t *request)
Search up a list of requests trying to locate one which has a client.
unlang_action_t unlang_module_yield_to_retry(request_t *request, module_method_t resume, unlang_module_retry_t retry, unlang_module_signal_t signal, fr_signal_t sigmask, void *rctx, fr_retry_config_t const *retry_cfg)
Yield a request back to the interpreter, with retries.
static void mod_signal(module_ctx_t const *mctx, request_t *request, UNUSED fr_signal_t action)
Cancel a call to a submodule.
eap_aka_sim_process_conf_t * inst
eap_type_t type
The preferred EAP-Type of this instance of the EAP-SIM/AKA/AKA' state machine.
fr_dict_t const * dict_def
Default dictionary to use with unqualified attribute references.
Stores an attribute, a value and various bits of other data.
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
An element in a lexicographically sorted array of name to num mappings.
#define talloc_get_type_abort_const
static fr_time_delta_t fr_time_delta_from_sec(int64_t sec)
#define fr_time_delta_ispos(_a)
conf_parser_t const trunk_config[]
Config parser definitions to populate a trunk_conf_t.
#define fr_pair_dcursor_by_da_init(_cursor, _list, _da)
Initialise a cursor that will return only attributes matching the specified fr_dict_attr_t.
struct value_pair_s fr_pair_t
static size_t char ** out
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.