25 RCSID(
"$Id: 72413589333cbc5bcdf8576bd87256d798aee1cd $")
27 #define LOG_PREFIX mctx->mi->name
29 #include <freeradius-devel/server/base.h>
30 #include <freeradius-devel/server/module_rlm.h>
31 #include <freeradius-devel/util/debug.h>
32 #include <freeradius-devel/server/users_file.h>
87 if (check_item->op ==
T_OP_SET)
return;
90 if (compare < 0)
RPEDEBUG(
"Comparison failed");
98 RDEBUG3(
"%pP %s %pP", reply_item, compare == 1 ?
"allowed by" :
"disallowed by", check_item);
121 if (!map_list_empty(&entry->
check)) {
122 WARN(
"%s[%d] Check list is not empty for entry \"%s\".\n",
127 while ((map = map_list_next(&entry->
reply, map))) {
129 ERROR(
"%s[%d] Left side of filter %s is not an attribute",
130 filename, entry->
lineno, map->
lhs->name);
135 ERROR(
"%s[%d] Left side of filter %s is not in the reply list",
136 filename, entry->
lineno, map->
lhs->name);
141 ERROR(
"%s[%d] Filter %s contains invalid operator '%s'",
150 ERROR(
"%s[%d] Right side of filter %s is a nested attribute - this is not (yet) supported",
151 filename, entry->
lineno, map->
lhs->name);
156 ERROR(
"%s[%d] Right side of filter %s is not a static value",
157 filename, entry->
lineno, map->
lhs->name);
177 ERROR(
"Errors reading %s",
inst->filename);
198 char const *keyname = NULL;
221 int relax_filter =
inst->relaxed;
233 if ((strcmp(pl->
name,
"DEFAULT") != 0) &&
234 (strcmp(keyname, pl->
name) != 0)) {
243 while ((map = map_list_next(&pl->
reply, map))) {
244 if (
map_to_vp(ctx, &tmp_list, request, map, NULL) < 0) {
245 RPWARN(
"Failed parsing map %s for check item, skipping it", map->
lhs->name);
251 if (check_item->vp_uint32 == 1) {
257 relax_filter = check_item->vp_bool;
311 if (input_item->
da == check_item->
da) {
312 check_pair(request, check_item, input_item, &pass, &fail);
316 RDEBUG3(
"Attribute \"%s\" allowed by %i rules, disallowed by %i rules",
317 input_item->
da->name, pass, fail);
322 if (fail == 0 && (pass > 0 || relax_filter)) {
326 RDEBUG3(
"Attribute \"%s\" allowed by relaxed mode", input_item->
da->name);
358 #define RLM_AF_FUNC(_x, _y) static unlang_action_t CC_HINT(nonnull) mod_##_x(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request) \
360 return attr_filter_common(request->_y##_ctx, p_result, mctx, request, &request->_y##_pairs); \
373 .name =
"attr_filter",
386 { .section =
SECTION_NAME(
"recv",
"accounting-request"), .method = mod_request },
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
static int const char char buffer[256]
#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.
static fr_control_t * control
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.
static uint32_t fr_dict_vendor_num_by_da(fr_dict_attr_t const *da)
Return the vendor number for an attribute.
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
static void * fr_dlist_next(fr_dlist_head_t const *list_head, void const *ptr)
Get the next item in a list.
#define RPEDEBUG(fmt,...)
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.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_BOOL
A truth value.
@ FR_TYPE_VSA
Vendor-Specific, for RADIUS attribute 26.
module_instance_t const * mi
Instance of the module being instantiated.
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.
module_t common
Common fields presented by all modules.
int fr_pair_cmp(fr_pair_t const *a, fr_pair_t const *b)
Compare two pairs, using the operator from "a".
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
#define is_truncated(_ret, _max)
static const conf_parser_t config[]
#define RETURN_MODULE_NOOP
#define RETURN_MODULE_UPDATED
rlm_rcode_t
Return codes indicating the result of the module call.
fr_dict_attr_t const * request_attr_reply
static fr_dict_attr_t const * attr_relax_filter
static int attr_filter_getfile(TALLOC_CTX *ctx, module_inst_ctx_t const *mctx, char const *filename, PAIR_LIST_LIST *pair_list)
static void check_pair(request_t *request, fr_pair_t *check_item, fr_pair_t *reply_item, int *pass, int *fail)
static fr_dict_attr_t const * attr_stripped_user_name
static fr_dict_attr_t const * attr_fall_through
static fr_dict_t const * dict_freeradius
module_rlm_t rlm_attr_filter
static fr_dict_t const * dict_radius
#define RLM_AF_FUNC(_x, _y)
fr_dict_attr_autoload_t rlm_attr_filter_dict_attr[]
static fr_dict_attr_t const * attr_vendor_specific
static unlang_action_t attr_filter_common(TALLOC_CTX *ctx, rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request, fr_pair_list_t *list)
static const conf_parser_t module_config[]
static int mod_instantiate(module_inst_ctx_t const *mctx)
fr_dict_autoload_t rlm_attr_filter_dict[]
static int instantiate(module_inst_ctx_t const *mctx)
static sql_fall_through_t fall_through(map_list_t *maps)
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
void * data
Module's instance data.
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Named methods exported by a module.
#define tmpl_is_attr(vpt)
#define tmpl_is_data(vpt)
static fr_dict_attr_t const * tmpl_list(tmpl_t const *vpt)
#define tmpl_expand(_out, _buff, _buff_len, _request, _vpt, _escape, _escape_ctx)
Expand a tmpl to a C type, using existing storage to hold variably sized types.
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.
Stores an attribute, a value and various bits of other data.
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
#define talloc_get_type_abort_const
const bool fr_assignment_op[T_TOKEN_LAST]
char const * fr_tokens[T_TOKEN_LAST]
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.
int lineno
Line number entry read from.
static void pairlist_list_init(PAIR_LIST_LIST *list)
map_list_t check
List of maps for comparison / modifying control list.
map_list_t reply
List of maps for modifying reply list.
fr_pair_t * fr_pair_list_head(fr_pair_list_t const *list)
Get the head of a valuepair list.
fr_pair_t * fr_pair_remove(fr_pair_list_t *list, fr_pair_t *vp)
Remove fr_pair_t from a list without freeing.
bool fr_pair_list_empty(fr_pair_list_t const *list)
Is a valuepair list empty.
fr_pair_t * fr_pair_list_next(fr_pair_list_t const *list, fr_pair_t const *item))
Get the next item in a valuepair list after a specific entry.
void fr_pair_list_free(fr_pair_list_t *list)
Free memory used by a valuepair list.
void fr_pair_list_append(fr_pair_list_t *dst, fr_pair_list_t *src)
Appends a list of fr_pair_t from a temporary list to a destination list.
fr_pair_t * fr_pair_list_prev(fr_pair_list_t const *list, fr_pair_t const *item))
Get the previous item in a valuepair list before a specific entry.