24RCSID(
"$Id: 2babe01b088187acb3458170bc328856cd777858 $")
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>
30#include <freeradius-devel/server/cf_util.h>
32#include <freeradius-devel/server/global_lib.h>
33#include <freeradius-devel/server/module_rlm.h>
34#include <freeradius-devel/server/tmpl.h>
35#include <freeradius-devel/server/tmpl_escape.h>
36#include <freeradius-devel/server/pairmove.h>
37#include <freeradius-devel/server/log.h>
38#include <freeradius-devel/tls/base.h>
39#include <freeradius-devel/util/atexit.h>
40#include <freeradius-devel/util/debug.h>
41#include <freeradius-devel/util/table.h>
42#include <freeradius-devel/util/uri.h>
43#include <freeradius-devel/util/value.h>
44#include <freeradius-devel/unlang/call_env.h>
45#include <freeradius-devel/unlang/xlat_func.h>
46#include <freeradius-devel/unlang/xlat.h>
68 {
L(
"1.0"), CURL_HTTP_VERSION_1_0 },
69 {
L(
"1.1"), CURL_HTTP_VERSION_1_1 },
73#if CURL_AT_LEAST_VERSION(7,49,0)
74 {
L(
"2.0"), CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE },
76#if CURL_AT_LEAST_VERSION(7,33,0)
77 {
L(
"2.0+auto"), CURL_HTTP_VERSION_2_0 },
81#if CURL_AT_LEAST_VERSION(7,47,0)
82 {
L(
"2.0+tls"), CURL_HTTP_VERSION_2TLS },
87 {
L(
"default"), CURL_HTTP_VERSION_NONE }
105 static size_t disable_proxy_table_len =
NUM_ELEMENTS(disable_proxy_table);
116#define SECTION_REQUEST_COMMON \
117 { FR_CONF_OFFSET("body", rlm_rest_section_request_t, body_str), .dflt = "none" }, \
119 { FR_CONF_OFFSET_IS_SET("auth", FR_TYPE_VOID, 0, rlm_rest_section_request_t, auth), \
120 .func = cf_table_parse_int, .uctx = &(cf_table_parse_ctx_t){ .table = http_auth_table, .len = &http_auth_table_len }, .dflt = "none" }, \
121 { FR_CONF_OFFSET("require_auth", rlm_rest_section_request_t, require_auth), .dflt = "no" }, \
122 { FR_CONF_OFFSET("chunk", rlm_rest_section_request_t, chunk), .dflt = "0" } \
176#ifdef CURLPIPE_MULTIPLEX
188#define REST_CALL_ENV_REQUEST_COMMON(_dflt_username, _dflt_password) \
189 { FR_CALL_ENV_OFFSET("header", FR_TYPE_STRING, CALL_ENV_FLAG_MULTI, rlm_rest_call_env_t, request.header) }, \
190 { FR_CALL_ENV_OFFSET("data", FR_TYPE_STRING, CALL_ENV_FLAG_CONCAT, rlm_rest_call_env_t, request.data) }, \
191 { FR_CALL_ENV_OFFSET("username", FR_TYPE_STRING, CALL_ENV_FLAG_SINGLE | CALL_ENV_FLAG_NULLABLE, \
192 rlm_rest_call_env_t, request.username), .pair.dflt_quote = T_BARE_WORD, _dflt_username }, \
193 { FR_CALL_ENV_OFFSET("password", FR_TYPE_STRING, CALL_ENV_FLAG_SINGLE | CALL_ENV_FLAG_NULLABLE | CALL_ENV_FLAG_SECRET, \
194 rlm_rest_call_env_t, request.password), .pair.dflt_quote = T_BARE_WORD, _dflt_password }, \
196#define REST_CALL_ENV_RESPONSE_COMMON \
197 { FR_CALL_ENV_PARSE_ONLY_OFFSET("header", FR_TYPE_STRING, CALL_ENV_FLAG_ATTRIBUTE, rlm_rest_call_env_t, response.header) }, \
199#define REST_CALL_ENV_SECTION(_var, _section, _dflt_username, _dflt_password) \
200static const call_env_method_t _var = { \
201 FR_CALL_ENV_METHOD_OUT(rlm_rest_call_env_t), \
202 .env = (call_env_parser_t[]){ \
203 { FR_CALL_ENV_SUBSECTION(_section, NULL, CALL_ENV_FLAG_NONE, \
204 ((call_env_parser_t[]) { \
205 { FR_CALL_ENV_SUBSECTION("request", NULL, CALL_ENV_FLAG_REQUIRED, \
206 ((call_env_parser_t[]) { \
207 { FR_CALL_ENV_OFFSET("uri", FR_TYPE_STRING, CALL_ENV_FLAG_REQUIRED | CALL_ENV_FLAG_CONCAT, rlm_rest_call_env_t, request.uri), \
209 .func = fr_uri_escape, \
210 .mode = TMPL_ESCAPE_PRE_CONCAT, \
213 .alloc = rest_uri_part_escape_uctx_alloc, \
214 .uctx = rest_uri_parts \
216 .type = TMPL_ESCAPE_UCTX_ALLOC_FUNC\
218 .safe_for = CURL_URI_SAFE_FOR \
220 .pair.literals_safe_for = CURL_URI_SAFE_FOR}, \
221 REST_CALL_ENV_REQUEST_COMMON(_dflt_username, _dflt_password) \
222 CALL_ENV_TERMINATOR \
224 { FR_CALL_ENV_SUBSECTION("response", NULL, CALL_ENV_FLAG_NONE, \
225 ((call_env_parser_t[]) { \
226 REST_CALL_ENV_RESPONSE_COMMON \
227 CALL_ENV_TERMINATOR \
229 CALL_ENV_TERMINATOR \
232 CALL_ENV_TERMINATOR \
237REST_CALL_ENV_SECTION(rest_call_env_authenticate,
"authenticate", .pair.dflt =
"&User-Name", .pair.dflt =
"&User-Password");
256 REST_CALL_ENV_REQUEST_COMMON(,) \
261 REST_CALL_ENV_RESPONSE_COMMON \
262 CALL_ENV_TERMINATOR \
316 RDEBUG2(
"Updating result attribute(s)");
322 RDEBUG2(
"&request.REST-HTTP-Status-Code !* ANY");
327 RDEBUG2(
"&request.REST-HTTP-Status-Code := %i", code);
330 vp->vp_uint32 = code;
357 memset(t_ctx, 0,
sizeof(*t_ctx));
359 t_ctx->uri_part = uctx;
376 if (!escaped)
return -1;
381 if (strlen(escaped) == vb->vb_length) {
402 RDEBUG2(
"Sending HTTP %s to \"%pV\"",
410 call_env->
request.uri->vb_strvalue,
411 call_env->
request.data ? call_env->
request.data->vb_strvalue : NULL);
412 if (ret < 0)
return -1;
419 if (ret < 0)
return -1;
463 if ((hcode >= 200) && (hcode < 300)) {
465 }
else if (hcode < 500) {
492 rest_slab_release(handle);
518 fr_value_box_list_t *
in)
536 XLAT_ARGS(
in, &method_vb, &uri_vb, &data_vb, &header_vb);
544 memcpy(&rctx->
section, &
inst->xlat,
sizeof(*section));
585 randle = rctx->
handle = rest_slab_reserve(t->
slab);
591 RDEBUG2(
"Sending HTTP %s to \"%pV\"",
600 rest_slab_release(randle);
615 uri_vb->vb_strvalue, data_vb ? data_vb->vb_strvalue : NULL);
616 if (ret < 0)
goto error_release;
625 if (ret < 0)
goto error_release;
679 if ((hcode >= 200) && (hcode < 300)) {
685 }
else if (hcode < 500) {
705 rest_slab_release(handle);
725 if (!section->
name) {
726 RDEBUG2(
"No authorize section configured");
730 handle = rest_slab_reserve(t->
slab);
735 rest_slab_release(handle);
793 if ((hcode >= 200) && (hcode < 300)) {
799 }
else if (hcode < 500) {
819 rest_slab_release(handle);
837 if (!section->
name) {
838 RDEBUG2(
"No authentication section configured");
846 if (!call_env->
request.username) {
847 REDEBUG(
"Attribute \"User-Name\" is required for authentication");
851 if (!call_env->
request.password) {
852 REDEBUG(
"Attribute \"User-Password\" is required for authentication");
859 if (call_env->
request.password->vb_length == 0) {
860 REDEBUG(
"User-Password must not be empty");
868 RDEBUG(
"Login attempt with password \"%pV\"", &call_env->
request.password);
870 RDEBUG2(
"Login attempt with password");
873 handle = rest_slab_reserve(t->
slab);
878 rest_slab_release(handle);
906 }
else if (hcode == 204) {
908 }
else if ((hcode >= 200) && (hcode < 300)) {
929 rest_slab_release(handle);
946 if (!section->
name) {
947 RDEBUG2(
"No accounting section configured");
951 handle = rest_slab_reserve(t->
slab);
956 rest_slab_release(handle);
984 }
else if (hcode == 204) {
986 }
else if ((hcode >= 200) && (hcode < 300)) {
1007 rest_slab_release(handle);
1024 if (!section->
name) {
1025 RDEBUG2(
"No post-auth section configured");
1029 handle = rest_slab_reserve(t->
slab);
1034 rest_slab_release(handle);
1068 cf_log_err(cs,
"Unsupported HTTP auth type \"%s\", check libcurl version, OpenSSL build "
1069 "configuration, then recompile this module",
1113 cf_log_err(cs,
"Unsupported HTTP body type \"%s\", please submit patches",
1114 config->request.body_str);
1118 cf_log_err(cs,
"Invalid HTTP body type. \"%s\" is not a valid web API data "
1119 "markup format",
config->request.body_str);
1123 cf_log_err(cs,
"Unavailable HTTP body type. \"%s\" is not available in this "
1124 "build",
config->request.body_str);
1132 if (
config->response.force_to_str) {
1139 cf_log_err(cs,
"Unknown forced response body type '%s'",
config->response.force_to_str);
1145 cf_log_err(cs,
"Unsupported forced response body type \"%s\", please submit patches",
1146 config->response.force_to_str);
1150 cf_log_err(cs,
"Invalid HTTP forced response body type. \"%s\" is not a valid web API data "
1151 "markup format",
config->response.force_to_str);
1176 CURL *candle = randle->
candle;
1181 curl_easy_reset(candle);
1187 curl_slist_free_all(ctx->
headers);
1199 ret = curl_easy_setopt(candle, CURLOPT_PRIVATE, (
void *)0xdeadc341);
1201 ERROR(
"Failed to set private data on curl easy handle %p: %s",
1202 candle, curl_easy_strerror(ret));
1210 TALLOC_FREE(ctx->
body);
1222 curl_easy_cleanup(randle->
candle);
1231 randle->
candle = curl_easy_init();
1242 randle->
uctx = curl_ctx;
1268 if (!(t->
slab = rest_slab_list_alloc(t, mctx->
el, &
inst->conn_config.reuse,
1270 ERROR(
"Connection handle pool instantiation failed");
1275 if (!mhandle)
return -1;
1315 inst->xlat.request.method_str =
"GET";
1317 inst->xlat.request.body_str =
"application/x-www-form-urlencoded";
1318 inst->xlat.response.force_to_str =
"plain";
1326 "authorize") < 0) ||
1328 "authenticate") < 0) ||
1330 "accounting") < 0) ||
1337 inst->conn_config.reuse.num_children = 1;
1409 { .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_MODULE_NOOP
#define RETURN_MODULE_RCODE(_rcode)
#define RETURN_MODULE_INVALID
#define RETURN_MODULE_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).
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::@172 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)
Initialises libcurl.
static fr_dict_attr_t const * attr_user_password
static int rest_conn_alloc(fr_curl_io_request_t *randle, void *uctx)
static int _rest_uri_part_escape_uctx_free(void *uctx)
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)
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 unlang_action_t mod_post_auth_result(rlm_rcode_t *p_result, module_ctx_t const *mctx, 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 unlang_action_t mod_authenticate(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
static int mod_bootstrap(module_inst_ctx_t const *mctx)
fr_dict_attr_t const * attr_rest_http_header
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.
#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(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
static unlang_action_t mod_authorize(rlm_rcode_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.
fr_dict_attr_t const * attr_rest_http_body
static unlang_action_t mod_authenticate_result(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
static fr_dict_attr_t const * attr_user_name
static unlang_action_t mod_accounting_result(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
fr_dict_attr_autoload_t rlm_rest_dict_attr[]
static const conf_parser_t section_response_config[]
static unlang_action_t mod_authorize_result(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
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 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.
static unlang_action_t mod_post_auth(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
#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.
Functions which we wish were included in the standard talloc distribution.
#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.
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.
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_clear_value(fr_value_box_t *data)
Clear/free any existing value.
int fr_value_box_strdup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, bool tainted)
Copy a nul terminated string to a fr_value_box_t.
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.