25RCSID(
"$Id: 6e7db7083f93277371155493b53cd8194761d6a2 $")
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>
124 rcode =
pairlist_read(ctx, dict, filename, &users, v3_compat);
139 map_t *sub_head, *set_head;
146 while ((map = map_list_next(&entry->
check, map))) {
148 ERROR(
"%s[%d] Left side of check item %s is not an attribute",
167 prev = map_list_remove(&entry->
check, map);
168 map_list_insert_after(&entry->
reply, reply_head, map);
181 sub_head = set_head = NULL;
190 for (map = map_list_head(&entry->
reply);
195 ERROR(
"%s[%d] Left side of reply item %s is not an attribute",
202 ERROR(
"%s[%d] Invalid operator reply item %s %s ...",
213 ERROR(
"%s[%d] Invalid right-hand side of assignment for attribute %s",
220 ERROR(
"%s[%d] Cannot use %s when key is not an IP / IP prefix",
226 ERROR(
"%s[%d] Value for %s must be static boolean",
232 (void) map_list_remove(&entry->
reply, map);
246 ERROR(
"%s[%d] Value for %s must be static boolean",
252 (void) map_list_remove(&entry->
reply, map);
260 if (sub_head == map)
continue;
262 (void) map_list_remove(&entry->
reply, map);
263 map_list_insert_after(&entry->
reply, sub_head, map);
272 if (set_head == map)
continue;
274 if (!set_head) set_head = sub_head;
276 (void) map_list_remove(&entry->
reply, map);
277 map_list_insert_after(&entry->
reply, set_head, map);
321 if (strcmp(entry->
name,
"DEFAULT") == 0) {
332 *pdefault = default_list;
347 search_list.
box = box;
353 entry->
name, strlen(entry->
name), NULL,
false) < 0) {
354 ERROR(
"%s[%d] Failed parsing key %s - %s",
375 ERROR(
"%s[%d] Failed inserting key %s - %s",
406 bool found =
false, trie =
false;
416 RERROR(
"Missing key value");
422 RDEBUG2(
"%s - Looking for key \"%pV\"", env->
name, key_vb);
429 my_list.
box = key_vb;
440 if (user_list && trie) {
442 keylen =
sizeof(key_buffer) * 8;
447 RHEXDUMP3(key, (keylen + 7) >> 3,
"KEY ");
462 while (user_pl || default_pl) {
470 if (!default_pl && user_pl) {
476 }
else if (!user_pl && default_pl) {
481 }
else if (user_pl->
order < default_pl->
order) {
496 while ((map = map_list_next(&pl->
check, map))) {
520 RPWARN(
"Failed parsing map for check item %s, skipping it", map->
lhs->name);
536 if (!match)
continue;
549 match_map = (
map_t) {
557 talloc_array_length(pl->
name) - 1,
false);
563 if (map_list_num_elements(&pl->
reply) > 0) {
564 RDEBUG2(
"%s - Preparing attribute updates:", env->
name);
568 RPWARN(
"Failed parsing reply item");
596 if (keylen > user_list->
box->vb_ip.prefix) keylen = user_list->
box->vb_ip.prefix;
607 RDEBUG(
"%s - Found matching shorter subnet %s at key length %ld", env->
name, user_pl->
name, keylen);
609 }
while (keylen > 0);
636 fr_value_box_list_init(&env->
values);
668 t_rules) < 0)
return -1;
683 keytype, key_enum, t_rules->
attr.
dict_def,
inst->v3_compat) < 0)
goto error;
685 *(
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_parser_t const * env
Parsing rules for call method env.
@ 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(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
#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.
fr_token_t cf_pair_value_quote(CONF_PAIR const *pair)
Return the value (rhs) quoting of a pair.
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_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_head(fr_dlist_head_t const *list_head)
Return the HEAD item of a list or NULL if the list is empty.
static void * fr_dlist_remove(fr_dlist_head_t *list_head, void *ptr)
Remove an item from the list.
static void * fr_dlist_pop_head(fr_dlist_head_t *list_head)
Remove the head item in a list.
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_next(fr_dlist_head_t const *list_head, void const *ptr)
Get the next item in a 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 bool fr_htrie_insert(fr_htrie_t *ht, void const *data)
Insert data into a htrie.
static void * fr_htrie_match(fr_htrie_t *ht, void const *data)
Match data in 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
#define RETURN_MODULE_FAIL
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, bool v3_compat)
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.
size_t inst_size
Size of the module's instance data.
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)
#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)
#define tmpl_value_type(_tmpl)
tmpl_attr_rules_t attr
Rules/data for parsing attribute references.
static fr_dict_attr_t const * tmpl_attr_tail_da(tmpl_t const *vpt)
Return the last attribute reference da.
#define tmpl_is_regex(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.
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.
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, bool v3_compat)
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