25#include <freeradius-devel/ldap/base.h> 
   39#define FILTER_ATTR_MAX_LEN 256 
   40#define FILTER_VALUE_MAX_LEN 256 
   89        if (ret < 0) 
return ret;
 
  103                if (ret < 0) 
return ret;
 
 
  132        fr_sbuff_marker(&marker, sbuff);
 
  144        MEM(node->attr = talloc_zero_array(node, 
char, len+1));
 
  145        memcpy(node->attr, attr_buffer, len);
 
  219        fr_sbuff_set_to_start(&val_sbuff);
 
  245                                          val_buffer, len, NULL) < 0) {
 
 
  290        static bool const       logical_op_chars[
UINT8_MAX +1] = {
 
  291                                        [
'!'] = 
true, [
'&'] = 
true, [
'|'] = 
true,
 
  303        fr_sbuff_marker(&marker, sbuff);
 
  311        if (ret < 0) 
return ret;
 
 
  380        bool            filter_state = 
false;
 
  407        DEBUG3(
"%*sLDAP filter group %s results in %s", 
depth, 
"", group->
orig, (filter_state ? 
"TRUE" : 
"FALSE"));
 
 
  411#define DEBUG_LDAP_ATTR_VAL if (DEBUG_ENABLED3) { \ 
  412        fr_value_box_t  value_box; \ 
  413        fr_ldap_berval_to_value_str_shallow(&value_box, values[i]); \ 
  414        DEBUG3("%*s  Evaluating attribute \"%s\", value \"%pV\"", depth, "", node->attr, &value_box); \ 
 
  427        struct berval   **values;
 
  429        bool            filter_state = 
false;
 
  437                values = ldap_get_values_len(conn->
handle, 
msg, node->attr);
 
  438                count = ldap_count_values_len(values);
 
  442                        filter_state = (
count > 0 ? true : 
false);
 
  446                        for (i = 0; i < 
count; i++) {
 
  448                                if ((node->value->vb_length == values[i]->bv_len) &&
 
  449                                    (
strncasecmp(values[i]->bv_val, node->value->vb_strvalue, values[i]->bv_len) == 0)) {
 
  462                        char const      *v, *t, *v_end, *t_end;
 
  469                        t_end = node->value->vb_strvalue + node->value->vb_length - 1;
 
  471                        for (i = 0; i < 
count; i++) {
 
  473                                t = node->value->vb_strvalue;
 
  474                                v = values[i]->bv_val;
 
  475                                v_end = values[i]->bv_val + values[i]->bv_len - 1;
 
  482                                while ((v <= v_end) && (t <= t_end)) {
 
  494                                                while ((tolower((
uint8_t) *t) != tolower((
uint8_t) *v)) && (v <= v_end)) v++;
 
  507                                if (((v > v_end) && (t > t_end)) || ((t >= t_end) && (*t_end == 
'*'))) {
 
  525                        for (i = 0; i < 
count; i++) {
 
  530                                if (values[i]->bv_len > 10) 
continue;
 
  536                                memcpy(
buffer, values[i]->bv_val, values[i]->bv_len);
 
  537                                buffer[values[i]->bv_len] = 
'\0';
 
  542                                        if (
value >= node->value->vb_uint32) filter_state = 
true;
 
  545                                        if (value <= node->
value->vb_uint32) filter_state = 
true;
 
  548                                        if (
value & node->value->vb_uint32) filter_state = 
true;
 
  551                                        if (
value | node->value->vb_uint32) filter_state = 
true;
 
  557                                if (filter_state) 
break;
 
  568                ldap_value_free_len(values);
 
  571        DEBUG3(
"%*sLDAP filter returns %s", 
depth, 
"", (filter_state ? 
"TRUE" : 
"FALSE"));
 
 
static int const char char buffer[256]
#define L(_str)
Helper for initialising arrays of string literals.
#define fr_dlist_init(_head, _type, _field)
Initialise the head structure of a doubly linked 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 int fr_dlist_insert_head(fr_dlist_head_t *list_head, void *ptr)
Insert an item into the head 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.
Head of a doubly linked list.
fr_slen_t fr_ldap_filter_parse(TALLOC_CTX *ctx, fr_dlist_head_t **root, fr_sbuff_t *filter, filter_attr_check_t attr_check, void *uctx)
Parse an LDAP filter into its component nodes.
static fr_slen_t ldap_filter_parse_filter(ldap_filter_t *node, fr_sbuff_t *sbuff, int depth, filter_attr_check_t attr_check, void *uctx)
Parse individual LDAP filter.
static size_t ldap_filter_op_table_len
bool fr_ldap_filter_eval(fr_dlist_head_t *root, fr_ldap_connection_t *conn, LDAPMessage *msg)
Evaluate an LDAP filter.
static bool const fr_ldap_attr_allowed_chars[UINT8_MAX+1]
static bool ldap_filter_group_eval(ldap_filter_t *group, fr_ldap_connection_t *conn, LDAPMessage *msg, int depth)
Evaluate a group of LDAP filters.
#define FILTER_VALUE_MAX_LEN
#define DEBUG_LDAP_ATTR_VAL
#define FILTER_ATTR_MAX_LEN
static fr_slen_t ldap_filter_parse_node(ldap_filter_t *node, fr_sbuff_t *sbuff, int depth, filter_attr_check_t attr_check, void *uctx)
Parse individual LDAP filter nodes.
static fr_table_num_sorted_t const ldap_filter_op_table[]
static bool ldap_filter_node_eval(ldap_filter_t *node, fr_ldap_connection_t *conn, LDAPMessage *msg, int depth)
Evaluate a single LDAP filter node.
static fr_slen_t ldap_filter_parse_logic(ldap_filter_t *node, fr_sbuff_t *sbuff, int depth, filter_attr_check_t attr_check, void *uctx)
Parse LDAP filter logic group.
LDAP * handle
libldap handle.
#define LDAP_MATCHING_RULE_BIT_OR
OID of bit-wise OR LDAP match rule.
@ LDAP_FILTER_GROUP
The filter node is a parent of a group which will be combined using a logical operator.
@ LDAP_FILTER_NODE
The filter node is an individual one to be evaluated against an attribute.
ldap_filter_op_t
Operators for use in LDAP filters.
@ LDAP_FILTER_OP_BIT_AND
Bitwise AND comparison.
@ LDAP_FILTER_OP_PRESENT
Attribute present.
@ LDAP_FILTER_OP_SUBSTR
Attribute matches string with wildcards.
@ LDAP_FILTER_OP_EQ
Attribute equals value.
@ LDAP_FILTER_OP_LE
Attribute less than or equal to value.
@ LDAP_FILTER_OP_BIT_OR
Bitwise OR comparison.
@ LDAP_FILTER_OP_GE
Attribute greater than or equal to value.
@ LDAP_FILTER_OP_UNSET
Attribute not set yet.
char * orig
Text representation of filter for debug messages,.
ldap_filter_type_t filter_type
Type of this filter node.
#define LDAP_MATCHING_RULE_BIT_AND
OID of bit-wise AND LDAP match rule.
int(* filter_attr_check_t)(char const *attr, void *uctx)
Tracks the state of a libldap connection handle.
Structure to hold parsed details of LDAP filters.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
size_t fr_sbuff_out_bstrncpy_until(fr_sbuff_t *out, fr_sbuff_t *in, size_t len, fr_sbuff_term_t const *tt, fr_sbuff_unescape_rules_t const *u_rules)
size_t fr_sbuff_out_bstrncpy_allowed(fr_sbuff_t *out, fr_sbuff_t *in, size_t len, bool const allowed[static UINT8_MAX+1])
static uint8_t depth(fr_minmax_heap_index_t i)
int strncasecmp(char *s1, char *s2, int n)
static int attr_check(CONF_SECTION *conf, tmpl_t *tmpl, char const *name, fr_dict_attr_flags_t *flags)
size_t fr_sbuff_adv_past_allowed(fr_sbuff_t *sbuff, size_t len, bool const allowed[static UINT8_MAX+1], fr_sbuff_term_t const *tt)
Wind position past characters in the allowed set.
char * fr_sbuff_adv_to_chr(fr_sbuff_t *sbuff, size_t len, char c)
Wind position to first instance of specified char.
bool fr_sbuff_next_if_char(fr_sbuff_t *sbuff, char c)
Return true if the current char matches, and if it does, advance.
#define fr_sbuff_out_by_longest_prefix(_match_len, _out, _table, _sbuff, _def)
#define fr_sbuff_adv_past_str_literal(_sbuff, _needle)
#define fr_sbuff_set(_dst, _src)
#define fr_sbuff_diff(_a, _b)
#define FR_SBUFF_IN(_start, _len_or_end)
#define fr_sbuff_current(_sbuff_or_marker)
#define fr_sbuff_extend(_sbuff_or_marker)
#define SBUFF_CHAR_CLASS_ALPHA_NUM
#define fr_sbuff_is_char(_sbuff_or_marker, _c)
#define FR_SBUFF_ERROR_RETURN(_sbuff_or_marker)
#define fr_sbuff_advance(_sbuff_or_marker, _len)
#define fr_sbuff_switch(_sbuff_or_marker, _eob)
#define FR_SBUFF_TERM(_str)
Initialise a terminal structure with a single string.
An element in a lexicographically sorted array of name to num mappings.
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
#define fr_strerror_const(_msg)
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)
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.
#define fr_value_box_alloc_null(_ctx)
Allocate a value box for later use with a value assignment function.