24RCSID(
"$Id: 7c208665c46679c3a65f86df30d9ee0421b59570 $")
26#include <freeradius-devel/curl/base.h>
27#include <freeradius-devel/curl/xlat.h>
28#include <freeradius-devel/server/base.h>
29#include <freeradius-devel/server/cf_parse.h>
31#include <freeradius-devel/server/global_lib.h>
32#include <freeradius-devel/server/tmpl.h>
33#include <freeradius-devel/util/atexit.h>
34#include <freeradius-devel/util/debug.h>
35#include <freeradius-devel/util/uri.h>
36#include <freeradius-devel/unlang/call_env.h>
37#include <freeradius-devel/unlang/xlat_func.h>
55 {
L(
"1.0"), CURL_HTTP_VERSION_1_0 },
56 {
L(
"1.1"), CURL_HTTP_VERSION_1_1 },
60#if CURL_AT_LEAST_VERSION(7,49,0)
61 {
L(
"2.0"), CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE },
63#if CURL_AT_LEAST_VERSION(7,33,0)
64 {
L(
"2.0+auto"), CURL_HTTP_VERSION_2_0 },
68#if CURL_AT_LEAST_VERSION(7,47,0)
69 {
L(
"2.0+tls"), CURL_HTTP_VERSION_2TLS },
74 {
L(
"default"), CURL_HTTP_VERSION_NONE }
92 static size_t disable_proxy_table_len =
NUM_ELEMENTS(disable_proxy_table);
103#define SECTION_REQUEST_COMMON \
104 { FR_CONF_OFFSET("body", rlm_rest_section_request_t, body_str), .dflt = "none" }, \
106 { FR_CONF_OFFSET_IS_SET("auth", FR_TYPE_VOID, 0, rlm_rest_section_request_t, auth), \
107 .func = cf_table_parse_int, .uctx = &(cf_table_parse_ctx_t){ .table = http_auth_table, .len = &http_auth_table_len }, .dflt = "none" }, \
108 { FR_CONF_OFFSET("require_auth", rlm_rest_section_request_t, require_auth), .dflt = "no" }, \
109 { FR_CONF_OFFSET("chunk", rlm_rest_section_request_t, chunk), .dflt = "0" } \
163#ifdef CURLPIPE_MULTIPLEX
175#define REST_CALL_ENV_REQUEST_COMMON(_dflt_username, _dflt_password) \
176 { FR_CALL_ENV_OFFSET("header", FR_TYPE_STRING, CALL_ENV_FLAG_MULTI, rlm_rest_call_env_t, request.header) }, \
177 { FR_CALL_ENV_OFFSET("data", FR_TYPE_STRING, CALL_ENV_FLAG_CONCAT, rlm_rest_call_env_t, request.data) }, \
178 { FR_CALL_ENV_OFFSET("username", FR_TYPE_STRING, CALL_ENV_FLAG_SINGLE | CALL_ENV_FLAG_NULLABLE | CALL_ENV_FLAG_BARE_WORD_ATTRIBUTE, \
179 rlm_rest_call_env_t, request.username), .pair.dflt_quote = T_BARE_WORD, _dflt_username }, \
180 { FR_CALL_ENV_OFFSET("password", FR_TYPE_STRING, CALL_ENV_FLAG_SINGLE | CALL_ENV_FLAG_NULLABLE | CALL_ENV_FLAG_SECRET | CALL_ENV_FLAG_BARE_WORD_ATTRIBUTE, \
181 rlm_rest_call_env_t, request.password), .pair.dflt_quote = T_BARE_WORD, _dflt_password }, \
183#define REST_CALL_ENV_RESPONSE_COMMON \
184 { FR_CALL_ENV_PARSE_ONLY_OFFSET("header", FR_TYPE_STRING, CALL_ENV_FLAG_ATTRIBUTE, rlm_rest_call_env_t, response.header) }, \
186#define REST_CALL_ENV_SECTION(_var, _section, _dflt_username, _dflt_password) \
187static const call_env_method_t _var = { \
188 FR_CALL_ENV_METHOD_OUT(rlm_rest_call_env_t), \
189 .env = (call_env_parser_t[]){ \
190 { FR_CALL_ENV_SUBSECTION(_section, NULL, CALL_ENV_FLAG_NONE, \
191 ((call_env_parser_t[]) { \
192 { FR_CALL_ENV_SUBSECTION("request", NULL, CALL_ENV_FLAG_REQUIRED, \
193 ((call_env_parser_t[]) { \
194 { FR_CALL_ENV_OFFSET("uri", FR_TYPE_STRING, CALL_ENV_FLAG_REQUIRED | CALL_ENV_FLAG_CONCAT, rlm_rest_call_env_t, request.uri), \
197 .func = fr_uri_escape, \
198 .safe_for = CURL_URI_SAFE_FOR, \
199 .always_escape = true, \
201 .mode = TMPL_ESCAPE_PRE_CONCAT, \
204 .alloc = rest_uri_part_escape_uctx_alloc, \
205 .uctx = rest_uri_parts \
207 .type = TMPL_ESCAPE_UCTX_ALLOC_FUNC\
210 .pair.literals_safe_for = CURL_URI_SAFE_FOR}, \
211 REST_CALL_ENV_REQUEST_COMMON(_dflt_username, _dflt_password) \
212 CALL_ENV_TERMINATOR \
214 { FR_CALL_ENV_SUBSECTION("response", NULL, CALL_ENV_FLAG_NONE, \
215 ((call_env_parser_t[]) { \
216 REST_CALL_ENV_RESPONSE_COMMON \
217 CALL_ENV_TERMINATOR \
219 CALL_ENV_TERMINATOR \
222 CALL_ENV_TERMINATOR \
227REST_CALL_ENV_SECTION(rest_call_env_authenticate,
"authenticate", .pair.dflt =
"User-Name", .pair.dflt =
"User-Password");
246 REST_CALL_ENV_REQUEST_COMMON(,) \
251 REST_CALL_ENV_RESPONSE_COMMON \
252 CALL_ENV_TERMINATOR \
306 RDEBUG2(
"Updating result attribute(s)");
312 RDEBUG2(
"request.REST-HTTP-Status-Code !* ANY");
317 RDEBUG2(
"request.REST-HTTP-Status-Code := %i", code);
320 vp->vp_uint32 = code;
347 memset(t_ctx, 0,
sizeof(*t_ctx));
349 t_ctx->uri_part = uctx;
366 if (!escaped)
return -1;
371 if (strlen(escaped) == vb->vb_length) {
392 RDEBUG2(
"Sending HTTP %s to \"%pV\"",
400 call_env->
request.uri->vb_strvalue,
401 call_env->
request.data ? call_env->
request.data->vb_strvalue : NULL);
402 if (ret < 0)
return -1;
409 if (ret < 0)
return -1;
453 if ((hcode >= 200) && (hcode < 300)) {
455 }
else if (hcode < 500) {
482 rest_slab_release(handle);
508 fr_value_box_list_t *
in)
526 XLAT_ARGS(
in, &method_vb, &uri_vb, &data_vb, &header_vb);
534 memcpy(&rctx->
section, &
inst->xlat,
sizeof(*section));
575 randle = rctx->
handle = rest_slab_reserve(t->
slab);
581 RDEBUG2(
"Sending HTTP %s to \"%pV\"",
590 rest_slab_release(randle);
605 uri_vb->vb_strvalue, data_vb ? data_vb->vb_strvalue : NULL);
606 if (ret < 0)
goto error_release;
615 if (ret < 0)
goto error_release;
669 if ((hcode >= 200) && (hcode < 300)) {
675 }
else if (hcode < 500) {
695 rest_slab_release(handle);
715 if (!section->
name) {
716 RDEBUG2(
"No authorize section configured");
720 handle = rest_slab_reserve(t->
slab);
725 rest_slab_release(handle);
783 if ((hcode >= 200) && (hcode < 300)) {
789 }
else if (hcode < 500) {
809 rest_slab_release(handle);
827 if (!section->
name) {
828 RDEBUG2(
"No authentication section configured");
836 if (!call_env->
request.username) {
837 REDEBUG(
"Attribute \"User-Name\" is required for authentication");
841 if (!call_env->
request.password) {
842 REDEBUG(
"Attribute \"User-Password\" is required for authentication");
849 if (call_env->
request.password->vb_length == 0) {
850 REDEBUG(
"User-Password must not be empty");
858 RDEBUG(
"Login attempt with password \"%pV\"", &call_env->
request.password);
860 RDEBUG2(
"Login attempt with password");
863 handle = rest_slab_reserve(t->
slab);
868 rest_slab_release(handle);
896 }
else if (hcode == 204) {
898 }
else if ((hcode >= 200) && (hcode < 300)) {
919 rest_slab_release(handle);
936 if (!section->
name) {
937 RDEBUG2(
"No accounting section configured");
941 handle = rest_slab_reserve(t->
slab);
946 rest_slab_release(handle);
974 }
else if (hcode == 204) {
976 }
else if ((hcode >= 200) && (hcode < 300)) {
997 rest_slab_release(handle);
1014 if (!section->
name) {
1015 RDEBUG2(
"No post-auth section configured");
1019 handle = rest_slab_reserve(t->
slab);
1024 rest_slab_release(handle);
1058 cf_log_err(cs,
"Unsupported HTTP auth type \"%s\", check libcurl version, OpenSSL build "
1059 "configuration, then recompile this module",
1103 cf_log_err(cs,
"Unsupported HTTP body type \"%s\", please submit patches",
1104 config->request.body_str);
1108 cf_log_err(cs,
"Invalid HTTP body type. \"%s\" is not a valid web API data "
1109 "markup format",
config->request.body_str);
1113 cf_log_err(cs,
"Unavailable HTTP body type. \"%s\" is not available in this "
1114 "build",
config->request.body_str);
1122 if (
config->response.force_to_str) {
1129 cf_log_err(cs,
"Unknown forced response body type '%s'",
config->response.force_to_str);
1135 cf_log_err(cs,
"Unsupported forced response body type \"%s\", please submit patches",
1136 config->response.force_to_str);
1140 cf_log_err(cs,
"Invalid HTTP forced response body type. \"%s\" is not a valid web API data "
1141 "markup format",
config->response.force_to_str);
1163 CURL *candle = randle->
candle;
1168 curl_easy_reset(candle);
1174 curl_slist_free_all(ctx->
headers);
1186 ret = curl_easy_setopt(candle, CURLOPT_PRIVATE, (
void *)0xdeadc341);
1188 ERROR(
"Failed to set private data on curl easy handle %p: %s",
1189 candle, curl_easy_strerror(ret));
1197 TALLOC_FREE(ctx->
body);
1209 curl_easy_cleanup(randle->
candle);
1218 randle->
candle = curl_easy_init();
1229 randle->
uctx = curl_ctx;
1255 if (!(t->
slab = rest_slab_list_alloc(t, mctx->
el, &
inst->conn_config.reuse,
1257 ERROR(
"Connection handle pool instantiation failed");
1262 if (!mhandle)
return -1;
1302 inst->xlat.request.method_str =
"GET";
1304 inst->xlat.request.body_str =
"application/x-www-form-urlencoded";
1305 inst->xlat.response.force_to_str =
"plain";
1313 "authorize") < 0) ||
1315 "authenticate") < 0) ||
1317 "accounting") < 0) ||
1324 inst->conn_config.reuse.num_children = 1;
1383 { .section =
SECTION_NAME(
"recv",
"accounting-request"), .method =
mod_accounting, .method_env = &rest_call_env_accounting },
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
#define fr_atexit_thread_local(_name, _free, _uctx)
#define L(_str)
Helper for initialising arrays of string literals.
#define CALL_ENV_TERMINATOR
call_env_parser_t const * env
Parsing rules for call method env.
#define FR_CALL_ENV_SUBSECTION(_name, _name2, _flags, _subcs)
Specify a call_env_parser_t which defines a nested subsection.
int cf_section_parse(TALLOC_CTX *ctx, void *base, CONF_SECTION *cs)
Parse a configuration section into user-supplied variables.
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_CONF_DEPRECATED(_name, _struct, _field)
conf_parser_t entry which raises an error if a matching CONF_PAIR is found
#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 cf_section_rules_push(_cs, _rule)
#define FR_CONF_OFFSET_SUBSECTION(_name, _flags, _struct, _field, _subcs)
conf_parser_t which populates a sub-struct using a CONF_SECTION
#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.
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_PAIR * cf_pair_find(CONF_SECTION const *cs, char const *attr)
Search for a CONF_PAIR with a specific name.
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,...)
fr_curl_handle_t * fr_curl_io_init(TALLOC_CTX *ctx, fr_event_list_t *el, bool multiplex)
request_t * request
Current request.
void * uctx
Private data for the module using the API.
int fr_curl_io_request_enqueue(fr_curl_handle_t *mhandle, request_t *request, fr_curl_io_request_t *creq)
Sends a request using libcurl.
CURL * candle
Request specific handle.
Uctx data for timer and I/O functions.
Structure representing an individual request being passed to curl for processing.
#define CURL_URI_SAFE_FOR
safe for value suitable for all users of the curl library
static int fr_dcursor_insert(fr_dcursor_t *cursor, void *v)
Insert directly after the current item.
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.
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.
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
#define GLOBAL_LIB_TERMINATOR
Structure to define how to initialise libraries with global configuration.
static xlat_action_t rest_xlat(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Simple xlat to read text data from a URL.
void fr_json_version_print(void)
Print JSON-C version.
int fr_curl_response_certinfo(request_t *request, fr_curl_io_request_t *randle)
global_lib_autoinst_t fr_curl_autoinst
CURL * fr_curl_tmp_handle(void)
Return a thread local curl easy handle.
conf_parser_t fr_curl_conn_config[]
conf_parser_t fr_curl_tls_config[]
#define REXDENT()
Exdent (unindent) R* messages by one level.
#define RDEBUG_ENABLED3
True if request debug level 1-3 messages are enabled.
#define RPEDEBUG(fmt,...)
#define RINDENT()
Indent R* messages by one level.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_SIZE
Unsigned integer capable of representing any memory address on the local system.
void * env_data
Per call environment data.
module_instance_t const * mi
Instance of the module being instantiated.
void * thread
Thread specific instance data.
void * rctx
Resume ctx that a module previously set.
fr_event_list_t * el
Event list to register any IO handlers and timers against.
void * thread
Thread instance data.
module_instance_t const * mi
Instance of the module being instantiated.
#define MODULE_CTX(_mi, _thread, _env_data, _rctx)
Wrapper to create a module_ctx_t as a compound literal.
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.
Temporary structure to hold arguments for thread_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.
void rest_io_module_signal(module_ctx_t const *mctx, request_t *request, UNUSED fr_signal_t action)
Handle asynchronous cancellation of a request.
void rest_io_xlat_signal(xlat_ctx_t const *xctx, request_t *request, fr_signal_t action)
Handle asynchronous cancellation of a request.
static const conf_parser_t config[]
#define pair_update_request(_attr, _da)
#define RETURN_UNLANG_INVALID
#define RETURN_UNLANG_RCODE(_rcode)
#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_NOTFOUND
User not found.
@ RLM_MODULE_UPDATED
OK (pairs modified).
#define RETURN_UNLANG_NOOP
fr_table_num_sorted_t const http_auth_table[]
int rest_request_config(module_ctx_t const *mctx, rlm_rest_section_t const *section, request_t *request, fr_curl_io_request_t *randle, http_method_t method, http_body_type_t type, char const *uri, char const *body_data)
Configures request curlopts.
fr_table_num_sorted_t const http_body_type_table[]
Conversion table for type config values.
fr_table_num_sorted_t const http_method_table[]
Conversion table for method config values.
size_t rest_get_handle_data(char const **out, fr_curl_io_request_t *randle)
Extracts pointer to buffer containing response data.
void rest_response_debug(request_t *request, fr_curl_io_request_t *handle)
Print out the response text.
fr_table_num_sorted_t const http_content_type_table[]
Conversion table for "Content-Type" header values.
const unsigned long http_curl_auth[REST_HTTP_AUTH_NUM_ENTRIES]
const http_body_type_t http_body_type_supported[REST_HTTP_BODY_NUM_ENTRIES]
Table of encoder/decoder support.
int rest_request_config_add_header(request_t *request, fr_curl_io_request_t *randle, char const *header, bool validate)
Adds an additional header to a handle to use in the next reques.
void rest_response_error(request_t *request, fr_curl_io_request_t *handle)
Print out the response text as error lines.
int rest_response_decode(rlm_rest_t const *instance, rlm_rest_section_t const *section, request_t *request, fr_curl_io_request_t *randle)
Sends the response to the correct decode function.
Function prototypes and datatypes for the REST (HTTP) transport.
rlm_rest_t const * instance
This instance of rlm_rest.
struct curl_slist * headers
Any HTTP headers which will be sent with the request.
tmpl_t * header
Where to create pairs representing HTTP response headers.
#define rest_get_handle_code(_handle)
char * buffer
Raw incoming HTTP data.
fr_curl_handle_t * mhandle
Thread specific multi handle.
char * body
Pointer to the buffer which contains body data/ Only used when not performing chunked encoding.
@ REST_HTTP_METHOD_UNKNOWN
@ REST_HTTP_METHOD_CUSTOM
Must always come last, should not be in method table.
@ REST_HTTP_BODY_UNSUPPORTED
@ REST_HTTP_BODY_NUM_ENTRIES
@ REST_HTTP_BODY_UNAVAILABLE
char const * method_str
The string version of the HTTP method.
struct rlm_rest_call_env_t::@186 request
rlm_rest_section_request_t request
Request configuration.
rlm_rest_response_t response
Response context data.
void * decoder
Decoder specific data.
void * encoder
Encoder specific data.
rlm_rest_request_t request
Request context data.
http_method_t method
What HTTP method should be used, GET, POST etc...
rlm_rest_section_t section
Our mutated section config.
rlm_rest_t const * inst
Instance of rlm_rest.
char const * name
Section name.
rest_slab_list_t * slab
Slab list for connection handles.
http_body_type_t body
What encoding type should be used.
fr_curl_io_request_t * handle
curl easy handle servicing our request.
rlm_rest_t const * instance
This instance of rlm_rest.
Thread specific rlm_rest instance data.
Stores the state of a yielded xlat.
static const call_env_method_t rest_call_env_xlat
static int rlm_rest_status_update(request_t *request, void *handle)
Update the status attribute.
static int mod_load(void)
static fr_dict_attr_t const * attr_user_password
static int rest_conn_alloc(fr_curl_io_request_t *randle, void *uctx)
static unlang_action_t mod_authorize_result(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static int _rest_uri_part_escape_uctx_free(void *uctx)
static unlang_action_t mod_post_auth(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static const conf_parser_t xlat_config[]
static xlat_action_t rest_xlat_resume(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, UNUSED fr_value_box_list_t *in)
static unlang_action_t mod_post_auth_result(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
fr_dict_t const * dict_freeradius
static int rlm_rest_perform(module_ctx_t const *mctx, rlm_rest_section_t const *section, fr_curl_io_request_t *randle, request_t *request)
static const conf_parser_t xlat_request_config[]
static fr_dict_t const * dict_radius
static fr_table_num_sorted_t const http_negotiation_table[]
static int instantiate(module_inst_ctx_t const *mctx)
static fr_uri_part_t const rest_uri_parts[]
static int mod_bootstrap(module_inst_ctx_t const *mctx)
fr_dict_attr_t const * attr_rest_http_header
static unlang_action_t mod_accounting(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
fr_dict_autoload_t rlm_rest_dict[]
static const conf_parser_t section_request_config[]
static const conf_parser_t section_config[]
static int _rest_request_cleanup(fr_curl_io_request_t *randle, UNUSED void *uctx)
Cleans up after a REST request.
static unlang_action_t mod_authorize(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
#define SECTION_REQUEST_COMMON
static int rest_uri_part_escape(fr_value_box_t *vb, void *uctx)
#define REST_CALL_ENV_SECTION(_var, _section, _dflt_username, _dflt_password)
static int rest_proxy_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
fr_dict_attr_t const * attr_rest_http_status_code
static unlang_action_t mod_accounting_result(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static size_t http_negotiation_table_len
static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx)
Create a thread specific multihandle.
static unlang_action_t mod_authenticate(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
fr_dict_attr_t const * attr_rest_http_body
static fr_dict_attr_t const * attr_user_name
fr_dict_attr_autoload_t rlm_rest_dict_attr[]
static const conf_parser_t section_response_config[]
static const conf_parser_t module_config[]
static int _mod_conn_free(fr_curl_io_request_t *randle)
static xlat_arg_parser_t const rest_xlat_args[]
static unlang_action_t mod_authenticate_result(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static int mod_thread_detach(module_thread_inst_ctx_t const *mctx)
Cleanup all outstanding requests associated with this thread.
static int parse_sub_section(rlm_rest_t *inst, CONF_SECTION *parent, conf_parser_t const *config_items, rlm_rest_section_t *config, char const *name)
static void * rest_uri_part_escape_uctx_alloc(UNUSED request_t *request, void const *uctx)
Allocate an escape uctx to pass to fr_uri_escape.
global_lib_autoinst_t const *const rlm_rest_lib[]
char const * rest_no_proxy
Unique pointer used to determine if we should explicitly disable proxying.
#define FR_SBUFF_TERMS(...)
Initialise a terminal structure with a list of sorted strings.
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
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_delete_request(_pair_or_da)
Delete a fr_pair_t in the request list.
@ FR_SIGNAL_CANCEL
Request has been cancelled.
unlang_action_t unlang_module_yield(request_t *request, module_method_t resume, unlang_module_signal_t signal, fr_signal_t sigmask, void *rctx)
Yield a request back to the interpreter from within a module.
eap_aka_sim_process_conf_t * inst
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.
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
#define fr_table_value_by_substr(_table, _name, _name_len, _def)
Convert a partial string to a value using an ordered or sorted table.
An element in a lexicographically sorted array of name to num mappings.
char * talloc_bstrndup(TALLOC_CTX *ctx, char const *in, size_t inlen)
Binary safe strndup function.
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
#define talloc_get_type_abort_const
xlat_action_t unlang_xlat_yield(request_t *request, xlat_func_t resume, xlat_func_signal_t signal, fr_signal_t sigmask, void *rctx)
Yield a request back to the interpreter from within a module.
uint8_t 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.
int fr_uri_escape_list(fr_value_box_list_t *uri, fr_uri_part_t const *uri_parts, void *uctx)
Parse a list of value boxes representing a URI.
#define XLAT_URI_PART_TERMINATOR
char const * name
Name of this part of the URI.
uctx to pass to fr_uri_escape
Definition for a single part of a URI.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
void fr_value_box_strdup_shallow_replace(fr_value_box_t *vb, char const *src, ssize_t len)
Free the existing buffer (if talloced) associated with the valuebox, and replace it with a new one.
int fr_value_box_bstrndup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, size_t len, bool tainted)
Copy a string to to a fr_value_box_t.
int fr_value_box_list_concat_in_place(TALLOC_CTX *ctx, fr_value_box_t *out, fr_value_box_list_t *list, fr_type_t type, fr_value_box_list_action_t proc_action, bool flatten, size_t max_size)
Concatenate a list of value boxes.
#define fr_value_box_alloc_null(_ctx)
Allocate a value box for later use with a value assignment function.
#define fr_value_box_list_foreach(_list_head, _iter)
static size_t char ** out
void * rctx
Resume context.
void * env_data
Expanded call env data.
module_ctx_t const * mctx
Synthesised module calling ctx.
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
void xlat_func_call_env_set(xlat_t *x, call_env_method_t const *env_method)
Register call environment of an xlat.