25 RCSID(
"$Id: f8e96ec7f41a8c40c96119b5d61e6b1c9a7f186d $")
27 #include <freeradius-devel/server/base.h>
28 #include <freeradius-devel/server/module_rlm.h>
29 #include <freeradius-devel/server/pairmove.h>
30 #include <freeradius-devel/server/users_file.h>
31 #include <freeradius-devel/util/htrie.h>
32 #include <freeradius-devel/unlang/call_env.h>
33 #include <freeradius-devel/unlang/function.h>
34 #include <freeradius-devel/unlang/transaction.h>
137 map_t *sub_head, *set_head;
144 while ((map = map_list_next(&entry->
check, map))) {
146 ERROR(
"%s[%d] Left side of check item %s is not an attribute",
165 prev = map_list_remove(&entry->
check, map);
166 map_list_insert_after(&entry->
reply, reply_head, map);
179 sub_head = set_head = NULL;
188 for (map = map_list_head(&entry->
reply);
193 ERROR(
"%s[%d] Left side of reply item %s is not an attribute",
200 ERROR(
"%s[%d] Invalid operator reply item %s %s ...",
211 ERROR(
"%s[%d] Invalid right-hand side of assignment for attribute %s",
218 ERROR(
"%s[%d] Cannot use %s when key is not an IP / IP prefix",
224 ERROR(
"%s[%d] Value for %s must be static boolean",
230 (void) map_list_remove(&entry->
reply, map);
244 ERROR(
"%s[%d] Value for %s must be static boolean",
250 (void) map_list_remove(&entry->
reply, map);
258 if (sub_head == map)
continue;
260 (void) map_list_remove(&entry->
reply, map);
261 map_list_insert_after(&entry->
reply, sub_head, map);
270 if (set_head == map)
continue;
272 if (!set_head) set_head = sub_head;
274 (void) map_list_remove(&entry->
reply, map);
275 map_list_insert_after(&entry->
reply, set_head, map);
319 if (strcmp(entry->
name,
"DEFAULT") == 0) {
330 *pdefault = default_list;
345 search_list.
box = box;
351 entry->
name, strlen(entry->
name), NULL,
false) < 0) {
352 ERROR(
"%s[%d] Failed parsing key %s - %s",
373 ERROR(
"%s[%d] Failed inserting key %s - %s",
404 bool found =
false, trie =
false;
414 RERROR(
"Missing key value");
420 RDEBUG2(
"%s - Looking for key \"%pV\"", env->
name, key_vb);
427 my_list.
box = key_vb;
438 if (user_list && trie) {
440 keylen =
sizeof(key_buffer) * 8;
445 RHEXDUMP3(key, (keylen + 7) >> 3,
"KEY ");
460 while (user_pl || default_pl) {
468 if (!default_pl && user_pl) {
474 }
else if (!user_pl && default_pl) {
479 }
else if (user_pl->
order < default_pl->
order) {
494 while ((map = map_list_next(&pl->
check, map))) {
518 RPWARN(
"Failed parsing map for check item %s, skipping it", map->
lhs->name);
534 if (!match)
continue;
547 match_map = (
map_t) {
555 talloc_array_length(pl->
name) - 1,
false);
561 if (map_list_num_elements(&pl->
reply) > 0) {
562 RDEBUG2(
"%s - Preparing attribute updates:", env->
name);
566 RPWARN(
"Failed parsing reply item");
594 if (keylen > user_list->
box->vb_ip.prefix) keylen = user_list->
box->vb_ip.prefix;
605 RDEBUG(
"%s - Found matching shorter subnet %s at key length %ld", env->
name, user_pl->
name, keylen);
607 }
while (keylen > 0);
634 fr_value_box_list_init(&env->
values);
666 t_rules) < 0)
return -1;
681 keytype, key_enum, t_rules->
attr.
dict_def) < 0)
goto error;
683 *(
void **)
out = files_data;
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
@ UNLANG_ACTION_PUSHED_CHILD
unlang_t pushed a new child onto the stack, execute it instead of continuing.
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
#define CALL_ENV_TERMINATOR
#define FR_CALL_ENV_METHOD_OUT(_inst)
Helper macro for populating the size/type fields of a call_env_method_t from the output structure typ...
@ CALL_ENV_FLAG_ATTRIBUTE
Tmpl must contain an attribute reference.
@ CALL_ENV_FLAG_PARSE_ONLY
The result of parsing will not be evaluated at runtime.
module_instance_t const * mi
Module instance that the callenv is registered to.
#define FR_CALL_ENV_PARSE_ONLY_OFFSET(_name, _cast_type, _flags, _struct, _parse_field)
Specify a call_env_parser_t which writes out the result of the parsing phase to the field specified.
#define CONF_PARSER_TERMINATOR
#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
@ CONF_FLAG_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
@ CONF_FLAG_FILE_INPUT
File matching value must exist, and must be readable.
Defines a CONF_PAIR to C data type mapping.
Common header for all CONF_* types.
Configuration AVP similar to a fr_pair_t.
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.
fr_token_t cf_pair_value_quote(CONF_PAIR const *pair)
Return the value (rhs) quoting of a pair.
#define cf_log_err(_cf, _fmt,...)
fr_dcursor_eval_t void const * uctx
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.
static void * fr_dlist_pop_head(fr_dlist_head_t *list_head)
Remove the head item in a list.
static void * fr_dlist_next(fr_dlist_head_t const *list_head, void const *ptr)
Get the next item in a list.
static void * fr_dlist_head(fr_dlist_head_t const *list_head)
Return the HEAD item of a list or NULL if the list is empty.
static int fr_dlist_insert_tail(fr_dlist_head_t *list_head, void *ptr)
Insert an item into the tail of a list.
static void * fr_dlist_remove(fr_dlist_head_t *list_head, void *ptr)
Remove an item from the list.
#define unlang_function_push(_request, _func, _repeat, _signal, _sigmask, _top_frame, _uctx)
Push a generic function onto the unlang stack.
fr_htrie_t * fr_htrie_alloc(TALLOC_CTX *ctx, fr_htrie_type_t type, fr_hash_t hash_data, fr_cmp_t cmp_data, fr_trie_key_t get_key, fr_free_t free_data)
An abstraction over our internal hashes, rb trees, and prefix tries.
@ FR_HTRIE_TRIE
Data is stored in a prefix trie.
static fr_htrie_type_t fr_htrie_hint(fr_type_t type)
static void * fr_htrie_match(fr_htrie_t *ht, void const *data)
Match data in a htrie.
static bool fr_htrie_insert(fr_htrie_t *ht, void const *data)
Insert data into a htrie.
void * store
What we're using to store node data.
fr_htrie_type_t type
type of the htrie
static void * fr_htrie_find(fr_htrie_t *ht, void const *data)
Find data in a htrie.
A hash/rb/prefix trie abstraction.
#define REXDENT()
Exdent (unindent) R* messages by one level.
#define RHEXDUMP3(_data, _len, _fmt,...)
#define RINDENT()
Indent R* messages by one level.
int map_to_vp(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *request, map_t const *map, UNUSED void *uctx)
Convert a map to a fr_pair_t.
int map_to_request(request_t *request, map_t const *map, radius_map_getvalue_t func, void *ctx)
Convert map_t to fr_pair_t (s) and add them to a request_t.
@ FR_TYPE_BOOL
A truth value.
void * env_data
Per call environment data.
module_instance_t const * mi
Instance of the module being instantiated.
Temporary structure to hold arguments for module calls.
module_t common
Common fields presented by all modules.
int radius_legacy_map_cmp(request_t *request, map_t const *map)
int radius_legacy_map_list_apply(request_t *request, map_list_t const *list, fr_edit_list_t *el)
static const conf_parser_t config[]
#define RETURN_MODULE_NOOP
rlm_rcode_t
Return codes indicating the result of the module call.
fr_dict_attr_autoload_t rlm_files_dict_attr[]
static int pairlist_to_key(uint8_t **out, size_t *outlen, void const *a)
static unlang_action_t mod_files_resume(rlm_rcode_t *p_result, UNUSED int *priority, request_t *request, void *uctx)
Lookup the expanded key value in files data.
PAIR_LIST_LIST * def
parsed files DEFAULT data.
static int8_t pairlist_cmp(void const *a, void const *b)
static const call_env_method_t method_env
static fr_dict_attr_t const * attr_fall_through
static fr_dict_t const * dict_freeradius
fr_htrie_t * htrie
parsed files "user" data.
static int call_env_parse(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *t_rules, CONF_ITEM *ci, call_env_ctx_t const *cec, UNUSED call_env_parser_t const *rule)
Custom call_env parser for loading files data.
static unlang_action_t mod_files(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Initiate a files data lookup.
tmpl_t * match_attr
Attribute to populate with matched key value.
static int getrecv_filename(TALLOC_CTX *ctx, char const *filename, fr_htrie_t **ptree, PAIR_LIST_LIST **pdefault, fr_type_t data_type, fr_dict_attr_t const *key_enum, fr_dict_t const *dict)
static uint32_t pairlist_hash(void const *a)
fr_dict_autoload_t rlm_files_dict[]
tmpl_t * key_tmpl
tmpl used to evaluate lookup key.
rlm_files_data_t * data
Data from parsed call_env.
static fr_dict_attr_t const * attr_next_shortest_prefix
char const * name
Name of module instance - for debug output.
fr_value_box_list_t values
Where the expanded tmpl value will be written.
static const conf_parser_t module_config[]
Structure produced by custom call_env parser.
#define FR_SBUFF_IN(_start, _len_or_end)
#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.
void * data
Module's instance data.
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Named methods exported by a module.
#define tmpl_value(_tmpl)
#define tmpl_contains_regex(vpt)
static fr_dict_attr_t const * tmpl_attr_tail_da(tmpl_t const *vpt)
Return the last attribute reference da.
#define tmpl_is_attr(vpt)
#define tmpl_is_exec(vpt)
@ TMPL_TYPE_ATTR
Reference to one or more attributes.
@ TMPL_TYPE_DATA
Value in native boxed format.
ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, fr_token_t quote, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules))
Convert an arbitrary string into a tmpl_t.
#define tmpl_is_data(vpt)
tmpl_t * tmpl_init_shallow(tmpl_t *vpt, tmpl_type_t type, fr_token_t quote, char const *name, ssize_t len, tmpl_rules_t const *t_rules))
Initialise a tmpl without copying the input name string.
#define tmpl_value_type(_tmpl)
tmpl_attr_rules_t attr
Rules/data for parsing attribute references.
#define tmpl_is_regex(vpt)
fr_type_t tmpl_expanded_type(tmpl_t const *vpt)
Return the native data type of the expression.
Optional arguments passed to vp_tmpl functions.
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
fr_token_t op
The operator that controls insertion of the dst attribute.
tmpl_t * lhs
Typically describes the attribute to add, modify or compare.
tmpl_t * rhs
Typically describes a literal value or a src attribute to copy or compare.
fr_dict_t const * dict_def
Default dictionary to use with unqualified attribute references.
#define talloc_get_type_abort_const
int unlang_tmpl_push(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, tmpl_t const *tmpl, unlang_tmpl_args_t *args)
Push a tmpl onto the stack for evaluation.
char const * fr_tokens[T_TOKEN_LAST]
const bool fr_comparison_op[T_TOKEN_LAST]
fr_edit_list_t * unlang_interpret_edit_list(request_t *request)
void * fr_trie_lookup_by_key(fr_trie_t const *ft, void const *key, size_t keylen)
Lookup a key in a trie and return user ctx, if any.
static fr_event_list_t * el
static int next_map(UNUSED request_t *request, UNUSED unlang_frame_state_edit_t *state, edit_map_t *current)
int pairlist_read(TALLOC_CTX *ctx, fr_dict_t const *dict, char const *file, PAIR_LIST_LIST *list)
char const * name
Key for matching entry.
fr_dlist_head_t head
Head of the list of PAIR_LISTs.
char const * filename
Filename entry read from.
int lineno
Line number entry read from.
char const * name
name of the key used for matching entry.
bool fall_through
go to the next one
static void pairlist_list_init(PAIR_LIST_LIST *list)
int order
Sequence of entry in source file.
map_list_t check
List of maps for comparison / modifying control list.
fr_value_box_t * box
parsed version of "name".
bool next_shortest_prefix
for prefix tries
map_list_t reply
List of maps for modifying reply list.
void fr_edit_list_commit(fr_edit_list_t *el)
Commit an edit list.
void fr_edit_list_abort(fr_edit_list_t *el)
Abort the entries in an edit list.
fr_edit_list_t * fr_edit_list_alloc(TALLOC_CTX *ctx, int hint, fr_edit_list_t *parent)
Allocate an edit list.
char const * fr_strerror(void)
Get the last library error.
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
ssize_t fr_value_box_from_str(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, char const *in, size_t inlen, fr_sbuff_unescape_rules_t const *erules, bool tainted)
uint32_t fr_value_box_hash(fr_value_box_t const *vb)
Hash the contents of a value box.
fr_sbuff_parse_rules_t const * value_parse_rules_quoted[T_TOKEN_LAST]
Parse rules for quoted strings.
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.
void fr_value_box_clear_value(fr_value_box_t *data)
Clear/free any existing value.
int fr_value_box_to_key(uint8_t **out, size_t *outlen, fr_value_box_t const *value)
Get a key from a value box.
void fr_value_box_bstrndup_shallow(fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, size_t len, bool tainted)
Assign a string to to a fr_value_box_t.
#define fr_value_box_alloc(_ctx, _type, _enumv)
Allocate a value box of a specific type.
static size_t char ** out