Newer
Older
/* component.c -- Component Filter Match Routines */
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
* Portions Copyright 2004 by IBM Corporation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted only as authorized by the OpenLDAP
* Public License.
*
* A copy of this license is available in the file LICENSE in the
* top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>.
*/
#include "portable.h"
#include <ac/string.h>
#include <ac/socket.h>
#include "lutil.h"
#include <ldap.h>
#include "slap.h"
#ifdef LDAP_COMP_MATCH
* Following function pointers are initialized
alloc_nibble_func* nibble_mem_allocator = NULL;
free_nibble_func* nibble_mem_free = NULL;
convert_attr_to_comp_func* attr_converter = NULL;
convert_assert_to_comp_func* assert_converter = NULL ;
free_component_func* component_destructor = NULL ;
test_component_func* test_components = NULL;
test_membership_func* is_aliased_attribute = NULL;
component_encoder_func* component_encoder = NULL;
get_component_info_func* get_component_description = NULL;
#define OID_ALL_COMP_MATCH "1.2.36.79672281.1.13.6"
#define OID_COMP_FILTER_MATCH "1.2.36.79672281.1.13.2"
#define MAX_LDAP_STR_LEN 128
static int
peek_componentId_type( ComponentAssertionValue* cav );
static int
strip_cav_str( ComponentAssertionValue* cav, char* str);
static int
peek_cav_str( ComponentAssertionValue* cav, char* str );
static int
parse_comp_filter( Operation* op, ComponentAssertionValue* cav,
ComponentFilter** filt, const char** text );
static void
free_comp_filter( ComponentFilter* f );
static int
test_comp_filter( Syntax *syn, ComponentSyntaxInfo *a, ComponentFilter *f );
componentCertificateValidate(
Syntax *syntax,
struct berval *val )
{
return LDAP_SUCCESS;
}
componentFilterValidate(
Syntax *syntax,
struct berval *val )
{
return LDAP_SUCCESS;
}
int
allComponentsValidate(
Syntax *syntax,
struct berval *val )
{
return LDAP_SUCCESS;
}
int
componentFilterMatch (
int *matchp,
slap_mask_t flags,
Syntax *syntax,
MatchingRule *mr,
struct berval *value,
void *assertedValue )
{
ComponentSyntaxInfo *csi_attr = (ComponentSyntaxInfo*)value;
MatchingRuleAssertion * ma = (MatchingRuleAssertion*)assertedValue;
/* Check if the component module is loaded */
if ( !attr_converter || !nibble_mem_allocator ) {
return LDAP_OTHER;
}
rc = test_comp_filter( syntax, csi_attr, ma->ma_cf );
if ( rc == LDAP_COMPARE_TRUE ) {
*matchp = 0;
return LDAP_SUCCESS;
}
else if ( rc == LDAP_COMPARE_FALSE ) {
*matchp = 1;
return LDAP_SUCCESS;
}
else {
return LDAP_INAPPROPRIATE_MATCHING;
int
directoryComponentsMatch(
int *matchp,
slap_mask_t flags,
Syntax *syntax,
MatchingRule *mr,
struct berval *value,
void *assertedValue )
{
*matchp = 0;
return LDAP_SUCCESS;
}
int
allComponentsMatch(
int *matchp,
slap_mask_t flags,
Syntax *syntax,
MatchingRule *mr,
struct berval *value,
void *assertedValue )
{
*matchp = 0;
return LDAP_SUCCESS;
}
static int
slapd_ber2cav( struct berval* bv, ComponentAssertionValue* cav )
{
cav->cav_ptr = cav->cav_buf = bv->bv_val;
cav->cav_end = bv->bv_val + bv->bv_len;
}
dup_comp_ref ( Operation* op, ComponentReference* cr )
{
ComponentReference* dup_cr;
ComponentId* ci_curr;
ComponentId** ci_temp;
dup_cr = op->o_tmpalloc( sizeof( ComponentReference ), op->o_tmpmemctx );
dup_cr->cr_len = cr->cr_len;
dup_cr->cr_string = cr->cr_string;
ci_temp = &dup_cr->cr_list;
ci_curr = cr->cr_list;
for ( ; ci_curr != NULL ;
ci_curr = ci_curr->ci_next, ci_temp = &(*ci_temp)->ci_next )
{
*ci_temp = op->o_tmpalloc( sizeof( ComponentId ), op->o_tmpmemctx );
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
**ci_temp = *ci_curr;
}
dup_cr->cr_curr = dup_cr->cr_list;
return dup_cr;
}
static int
dup_comp_filter_list (
Operation *op,
struct berval *bv,
ComponentFilter* in_f,
ComponentFilter** out_f )
{
ComponentFilter **new, *f;
int rc;
new = out_f;
for ( f = in_f; f != NULL; f = f->cf_next ) {
rc = dup_comp_filter( op, bv, f, new );
if ( rc != LDAP_SUCCESS ) {
return rc;
}
new = &(*new)->cf_next;
}
return LDAP_SUCCESS;
}
int
get_len_of_next_assert_value ( struct berval* bv, char separator )
{
while (1) {
if ( (bv->bv_val[ i ] == separator) || ( i >= bv->bv_len) )
break;
i++;
}
bv->bv_val += (i + 1);
bv->bv_len -= (i + 1);
return i;
}
int
dup_comp_filter_item (
Operation *op,
struct berval* assert_bv,
ComponentAssertion* in_ca,
ComponentAssertion** out_ca )
{
int len;
*out_ca = op->o_tmpalloc( sizeof( ComponentAssertion ), op->o_tmpmemctx );
(*out_ca)->ca_comp_data.cd_tree = NULL;
(*out_ca)->ca_comp_data.cd_mem_op = NULL;
(*out_ca)->ca_comp_ref = dup_comp_ref ( op, in_ca->ca_comp_ref );
(*out_ca)->ca_use_def = 0;
(*out_ca)->ca_ma_rule = in_ca->ca_ma_rule;
(*out_ca)->ca_ma_value.bv_val = assert_bv->bv_val;
len = get_len_of_next_assert_value ( assert_bv, '$' );
(*out_ca)->ca_ma_value.bv_len = len;
return LDAP_SUCCESS;
}
int
dup_comp_filter (
Operation* op,
struct berval *bv,
ComponentFilter *in_f,
ComponentFilter **out_f )
{
int rc;
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
if ( !in_f ) return LDAP_PROTOCOL_ERROR;
switch ( in_f->cf_choice ) {
case LDAP_COMP_FILTER_AND:
rc = dup_comp_filter_list( op, bv, in_f->cf_and, &dup_f.cf_and);
dup_f.cf_choice = LDAP_COMP_FILTER_AND;
break;
case LDAP_COMP_FILTER_OR:
rc = dup_comp_filter_list( op, bv, in_f->cf_or, &dup_f.cf_or);
dup_f.cf_choice = LDAP_COMP_FILTER_OR;
break;
case LDAP_COMP_FILTER_NOT:
rc = dup_comp_filter( op, bv, in_f->cf_not, &dup_f.cf_not);
dup_f.cf_choice = LDAP_COMP_FILTER_NOT;
break;
case LDAP_COMP_FILTER_ITEM:
rc = dup_comp_filter_item( op, bv, in_f->cf_ca ,&dup_f.cf_ca );
dup_f.cf_choice = LDAP_COMP_FILTER_ITEM;
break;
default:
rc = LDAP_PROTOCOL_ERROR;
}
if ( rc == LDAP_SUCCESS ) {
*out_f = op->o_tmpalloc( sizeof(dup_f), op->o_tmpmemctx );
**out_f = dup_f;
}
return( rc );
}
int
get_aliased_filter_aa ( Operation* op, AttributeAssertion* a_assert, AttributeAliasing* aa, const char** text )
{
struct berval assert_bv;
Debug( LDAP_DEBUG_FILTER, "get_aliased_filter\n", 0, 0, 0 );
if ( !aa->aa_cf )
return LDAP_PROTOCOL_ERROR;
assert_bv = a_assert->aa_value;
/*
* Duplicate aa->aa_cf to ma->ma_cf by replacing the
* the component assertion value in assert_bv
* Multiple values may be separated with '$'
*/
return dup_comp_filter ( op, &assert_bv, aa->aa_cf, &a_assert->aa_cf );
}
get_aliased_filter( Operation* op,
MatchingRuleAssertion* ma, AttributeAliasing* aa,
const char** text )
{
struct berval assert_bv;
Debug( LDAP_DEBUG_FILTER, "get_aliased_filter\n", 0, 0, 0 );
if ( !aa->aa_cf ) return LDAP_PROTOCOL_ERROR;
assert_bv = ma->ma_value;
/* Attribute Description is replaced with aliased one */
ma->ma_desc = aa->aa_aliased_ad;
ma->ma_rule = aa->aa_mr;
/*
* Duplicate aa->aa_cf to ma->ma_cf by replacing the
* the component assertion value in assert_bv
* Multiple values may be separated with '$'
*/
return dup_comp_filter ( op, &assert_bv, aa->aa_cf, &ma->ma_cf );
int
get_comp_filter( Operation* op, struct berval* bv,
ComponentFilter** filt, const char **text )
{
ComponentAssertionValue cav;
Debug( LDAP_DEBUG_FILTER, "get_comp_filter\n", 0, 0, 0 );
if ( (rc = slapd_ber2cav(bv, &cav) ) != LDAP_SUCCESS ) {
return rc;
}
rc = parse_comp_filter( op, &cav, filt, text );
bv->bv_val = cav.cav_ptr;
return rc;
}
static void
eat_whsp( ComponentAssertionValue* cav )
{
for ( ; ( *cav->cav_ptr == ' ' ) && ( cav->cav_ptr < cav->cav_end ) ; ) {
cav->cav_ptr++;
}
}
static int
cav_cur_len( ComponentAssertionValue* cav )
{
return cav->cav_end - cav->cav_ptr;
}
static ber_tag_t
comp_first_element( ComponentAssertionValue* cav )
{
eat_whsp( cav );
if ( cav_cur_len( cav ) >= 8 && strncmp( cav->cav_ptr, "item", 4 ) == 0 ) {
return LDAP_COMP_FILTER_ITEM;
} else if ( cav_cur_len( cav ) >= 7 &&
strncmp( cav->cav_ptr, "and", 3 ) == 0 )
{
return LDAP_COMP_FILTER_AND;
} else if ( cav_cur_len( cav ) >= 6 &&
strncmp( cav->cav_ptr, "or" , 2 ) == 0 )
{
return LDAP_COMP_FILTER_OR;
} else if ( cav_cur_len( cav ) >= 7 &&
strncmp( cav->cav_ptr, "not", 3 ) == 0 )
{
return LDAP_COMP_FILTER_NOT;
return LDAP_COMP_FILTER_UNDEFINED;
}
static ber_tag_t
comp_next_element( ComponentAssertionValue* cav )
{
eat_whsp( cav );
if ( *(cav->cav_ptr) == ',' ) {
/* move pointer to the next CA */
cav->cav_ptr++;
return comp_first_element( cav );
}
else return LDAP_COMP_FILTER_UNDEFINED;
}
static int
get_comp_filter_list( Operation *op, ComponentAssertionValue *cav,
{
ComponentFilter **new;
int err;
ber_tag_t tag;
Debug( LDAP_DEBUG_FILTER, "get_comp_filter_list\n", 0, 0, 0 );
new = f;
for ( tag = comp_first_element( cav );
tag != LDAP_COMP_FILTER_UNDEFINED;
tag = comp_next_element( cav ) )
{
err = parse_comp_filter( op, cav, new, text );
new = &(*new)->cf_next;
}
*new = NULL;
return( LDAP_SUCCESS );
}
static int
get_componentId( Operation *op, ComponentAssertionValue* cav,
{
ber_tag_t type;
ComponentId _cid;
int len;
type = peek_componentId_type( cav );
Debug( LDAP_DEBUG_FILTER, "get_compId [%lu]\n",
(unsigned long) type, 0, 0 );
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
len = 0;
_cid.ci_type = type;
_cid.ci_next = NULL;
switch ( type ) {
case LDAP_COMPREF_IDENTIFIER :
_cid.ci_val.ci_identifier.bv_val = cav->cav_ptr;
for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' ; len++ );
_cid.ci_val.ci_identifier.bv_len = len;
cav->cav_ptr += len;
break;
case LDAP_COMPREF_FROM_BEGINNING :
for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' ; len++ );
_cid.ci_val.ci_from_beginning = strtol( cav->cav_ptr, NULL, 0 );
cav->cav_ptr += len;
break;
case LDAP_COMPREF_FROM_END :
for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' ; len++ );
_cid.ci_val.ci_from_end = strtol( cav->cav_ptr, NULL, 0 );
cav->cav_ptr += len;
break;
case LDAP_COMPREF_COUNT :
_cid.ci_val.ci_count = 0;
cav->cav_ptr++;
break;
case LDAP_COMPREF_CONTENT :
_cid.ci_val.ci_content = 1;
cav->cav_ptr += strlen("content");
break;
case LDAP_COMPREF_SELECT :
for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
cav->cav_ptr[len] != '\"' && cav->cav_ptr[len] != ')'
; len++ );
_cid.ci_val.ci_select_value.bv_val = cav->cav_ptr + 1;
_cid.ci_val.ci_select_value.bv_len = len - 1 ;
cav->cav_ptr += len + 1;
break;
case LDAP_COMPREF_ALL :
_cid.ci_val.ci_all = '*';
cav->cav_ptr++;
break;
default :
return LDAP_COMPREF_UNDEFINED;
}
*cid = op->o_tmpalloc( sizeof( ComponentId ), op->o_tmpmemctx );
*cid = SLAP_MALLOC( sizeof( ComponentId ) );
}
if (*cid == NULL) {
return LDAP_NO_MEMORY;
**cid = _cid;
return LDAP_SUCCESS;
}
static int
peek_componentId_type( ComponentAssertionValue* cav )
{
eat_whsp( cav );
return LDAP_COMPREF_FROM_END;
return LDAP_COMPREF_SELECT;
return LDAP_COMPREF_ALL;
return LDAP_COMPREF_COUNT;
} else if ( cav->cav_ptr[0] > '0' && cav->cav_ptr[0] <= '9' ) {
return LDAP_COMPREF_FROM_BEGINNING;
strncmp(cav->cav_ptr,"content",7) == 0 )
return LDAP_COMPREF_CONTENT;
} else if ( (cav->cav_ptr[0] >= 'a' && cav->cav_ptr[0] <= 'z') ||
(cav->cav_ptr[0] >= 'A' && cav->cav_ptr[0] <= 'Z') )
return LDAP_COMPREF_IDENTIFIER;
}
static ber_tag_t
comp_next_id( ComponentAssertionValue* cav )
{
if ( *(cav->cav_ptr) == '.' ) {
cav->cav_ptr++;
return LDAP_COMPREF_DEFINED;
}
}
static int
get_component_reference(
Operation *op,
ComponentAssertionValue* cav,
ComponentReference** cr,
const char** text )
{
int rc, count = 0;
ber_int_t type;
ComponentReference* ca_comp_ref;
ComponentId** cr_list;
eat_whsp( cav );
if ( ( rc = strip_cav_str( cav,"\"") ) != LDAP_SUCCESS ) return rc;
if ( op ) {
ca_comp_ref = op->o_tmpalloc( sizeof( ComponentReference ),
op->o_tmpmemctx );
} else {
ca_comp_ref = SLAP_MALLOC( sizeof( ComponentReference ) );
if ( !ca_comp_ref ) return LDAP_NO_MEMORY;
cr_list = &ca_comp_ref->cr_list;
for ( type = peek_componentId_type( cav ) ; type != LDAP_COMPREF_UNDEFINED
rc = get_componentId( op, cav, cr_list, text );
if ( rc == LDAP_SUCCESS ) {
if ( count == 0 ) ca_comp_ref->cr_curr = ca_comp_ref->cr_list;
cr_list = &(*cr_list)->ci_next;
if ( op ) {
op->o_tmpfree( ca_comp_ref , op->o_tmpmemctx );
} else {
free( ca_comp_ref );
}
}
ca_comp_ref->cr_len = count;
if ( ( rc = strip_cav_str( cav,"\"") ) != LDAP_SUCCESS ) {
op->o_tmpfree( ca_comp_ref , op->o_tmpmemctx );
free( ca_comp_ref );
(*cr)->cr_string.bv_val = start;
(*cr)->cr_string.bv_len = end - start + 1;
return rc;
}
insert_component_reference(
ComponentReference *cr,
ComponentReference** cr_list)
{
if ( !cr ) return LDAP_PARAM_ERROR;
if ( !(*cr_list) ) {
*cr_list = cr;
cr->cr_next = NULL;
} else {
cr->cr_next = *cr_list;
*cr_list = cr;
}
return LDAP_SUCCESS;
}
/*
* If there is '.' in the name of a given attribute
* the first '.'- following characters are considered
* as a component reference of the attribute
* EX) userCertificate.toBeSigned.serialNumber
* attribute : userCertificate
* component reference : toBeSigned.serialNumber
*/
int
is_component_reference( char* attr ) {
int i;
for ( i=0; attr[i] != '\0' ; i++ ) {
extract_component_reference(
char* attr,
ComponentReference** cr )
{
int i, rc;
char* cr_ptr;
int cr_len;
ComponentAssertionValue cav;
for ( i=0; attr[i] != '\0' ; i++ ) {
if ( attr[i] == '.' ) break;
}
if (attr[i] != '.' ) return LDAP_PARAM_ERROR;
attr[i] = '\0';
cr_ptr = attr + i + 1 ;
cr_len = strlen ( cr_ptr );
if ( cr_len <= 0 ) return LDAP_PARAM_ERROR;
/* enclosed between double quotes*/
cav.cav_ptr = cav.cav_buf = ch_malloc (cr_len+2);
memcpy( cav.cav_buf+1, cr_ptr, cr_len );
cav.cav_buf[0] = '"';
cav.cav_buf[cr_len+1] = '"';
rc = get_component_reference ( NULL, &cav, cr, (const char**)text );
if ( rc != LDAP_SUCCESS ) return rc;
(*cr)->cr_string.bv_val = cav.cav_buf;
(*cr)->cr_string.bv_len = cr_len + 2;
return LDAP_SUCCESS;
}
static int
get_ca_use_default( Operation *op,
ComponentAssertionValue* cav,
int* ca_use_def, const char** text )
{
strip_cav_str( cav, "useDefaultValues" );
if ( peek_cav_str( cav, "TRUE" ) == LDAP_SUCCESS ) {
strip_cav_str( cav, "TRUE" );
*ca_use_def = 1;
} else if ( peek_cav_str( cav, "FALSE" ) == LDAP_SUCCESS ) {
strip_cav_str( cav, "FALSE" );
*ca_use_def = 0;
} else {
return LDAP_INVALID_SYNTAX;
return LDAP_SUCCESS;
}
static int
get_matching_rule( Operation *op, ComponentAssertionValue* cav,
MatchingRule** mr, const char** text )
{
int count = 0;
struct berval rule_text = { 0L, NULL };
eat_whsp( cav );
for ( ; ; count++ ) {
if ( cav->cav_ptr[count] == ' ' || cav->cav_ptr[count] == ',' ||
cav->cav_ptr[count] == '\0' || cav->cav_ptr[count] == '{' ||
cav->cav_ptr[count] == '}' || cav->cav_ptr[count] == '\n' )
break;
}
if ( count == 0 ) {
*text = "component matching rule not recognized";
return LDAP_INAPPROPRIATE_MATCHING;
}
rule_text.bv_len = count;
rule_text.bv_val = cav->cav_ptr;
*mr = mr_bvfind( &rule_text );
cav->cav_ptr += count;
Debug( LDAP_DEBUG_FILTER, "get_matching_rule: %s\n",
(*mr)->smr_mrule.mr_oid, 0, 0 );
if ( *mr == NULL ) {
*text = "component matching rule not recognized";
return LDAP_INAPPROPRIATE_MATCHING;
}
return LDAP_SUCCESS;
}
get_GSER_value( ComponentAssertionValue* cav, struct berval* bv )
{
int count, sequent_dquote, unclosed_brace, succeed;
eat_whsp( cav );
/*
* Four cases of GSER <Values>
* 1) "..." :
* StringVal, GeneralizedTimeVal, UTCTimeVal, ObjectDescriptorVal
* 2) '...'B or '...'H :
* BitStringVal, OctetStringVal
* 3) {...} :
* SEQUENCE, SEQUENCEOF, SETOF, SET, CHOICE
* 4) Between two white spaces
* INTEGER, BOOLEAN, NULL,ENUMERATE, etc
*/
if ( cav->cav_ptr[0] == '"' ) {
for( count = 1, sequent_dquote = 0 ; ; count++ ) {
/* In order to find escaped double quote */
if ( cav->cav_ptr[count] == '"' ) sequent_dquote++;
else sequent_dquote = 0;
if ( cav->cav_ptr[count] == '\0' ||
(cav->cav_ptr+count) > cav->cav_end )
{
if ( ( cav->cav_ptr[count] == '"' &&
cav->cav_ptr[count-1] != '"') ||
( sequent_dquote > 2 && (sequent_dquote%2) == 1 ) )
{
break;
}
return LDAP_FILTER_ERROR;
bv->bv_val = cav->cav_ptr + 1;
bv->bv_len = count - 1; /* exclude '"' */
if ( cav->cav_ptr[count] == '\0' ||
(cav->cav_ptr+count) > cav->cav_end )
{
if ((cav->cav_ptr[count-1] == '\'' && cav->cav_ptr[count] == 'B') ||
(cav->cav_ptr[count-1] == '\'' && cav->cav_ptr[count] == 'H') )
{
break;
}
if ( !succeed ||
!(cav->cav_ptr[count] == 'H' || cav->cav_ptr[count] == 'B') )
{
return LDAP_FILTER_ERROR;
}
bv->bv_val = cav->cav_ptr + 1;/*the next to '"' */
bv->bv_len = count - 2;/* exclude "'H" or "'B" */
for( count = 1, unclosed_brace = 1 ; ; count++ ) {
if ( cav->cav_ptr[count] == '{' ) unclosed_brace++;
if ( cav->cav_ptr[count] == '}' ) unclosed_brace--;
if ( cav->cav_ptr[count] == '\0' ||
(cav->cav_ptr+count) > cav->cav_end )
{
break;
}
if ( !succeed || cav->cav_ptr[count] != '}' ) return LDAP_FILTER_ERROR;
bv->bv_val = cav->cav_ptr + 1;/*the next to '"' */
bv->bv_len = count - 1;/* exclude "'B" */
/*Find following white space where the value is ended*/
for( count = 1 ; ; count++ ) {
if ( cav->cav_ptr[count] == '\0' ||
cav->cav_ptr[count] == ' ' || cav->cav_ptr[count] == '}' ||
cav->cav_ptr[count] == '{' ||
(cav->cav_ptr+count) > cav->cav_end )
{
bv->bv_val = cav->cav_ptr;
bv->bv_len = count;
}
cav->cav_ptr += bv->bv_len;
}
static int
get_matching_value( Operation *op, ComponentAssertion* ca,
ComponentAssertionValue* cav, struct berval* bv,
const char** text )
{
if ( !(ca->ca_ma_rule->smr_usage & (SLAP_MR_COMPONENT)) ) {
if ( get_GSER_value( cav, bv ) != LDAP_SUCCESS ) {
/* embeded componentFilterMatch Description */
bv->bv_val = cav->cav_ptr;
bv->bv_len = cav_cur_len( cav );
}
return LDAP_SUCCESS;
}
/* Don't move the position pointer, just peek given string */
static int
peek_cav_str( ComponentAssertionValue* cav, char* str )
{
eat_whsp( cav );
if ( cav_cur_len( cav ) >= strlen( str ) &&
strncmp( cav->cav_ptr, str, strlen( str ) ) == 0 )
return LDAP_SUCCESS;
}
static int
strip_cav_str( ComponentAssertionValue* cav, char* str)
{
eat_whsp( cav );
if ( cav_cur_len( cav ) >= strlen( str ) &&
cav->cav_ptr += strlen( str );
return LDAP_SUCCESS;
}
}
/*
* TAG : "item", "and", "or", "not"
*/
strip_cav_tag( ComponentAssertionValue* cav )
{
eat_whsp( cav );
if ( cav_cur_len( cav ) >= 8 && strncmp( cav->cav_ptr, "item", 4 ) == 0 ) {
strip_cav_str( cav , "item:" );
return LDAP_COMP_FILTER_ITEM;
} else if ( cav_cur_len( cav ) >= 7 &&
strncmp( cav->cav_ptr, "and", 3 ) == 0 )
{
strip_cav_str( cav , "and:" );
return LDAP_COMP_FILTER_AND;
} else if ( cav_cur_len( cav ) >= 6 &&
strncmp( cav->cav_ptr, "or" , 2 ) == 0 )
{
strip_cav_str( cav , "or:" );
return LDAP_COMP_FILTER_OR;
} else if ( cav_cur_len( cav ) >= 7 &&
strncmp( cav->cav_ptr, "not", 3 ) == 0 )
{
strip_cav_str( cav , "not:" );
return LDAP_COMP_FILTER_NOT;
}
}
/*
* when encoding, "item" is denotation of ComponentAssertion
* ComponentAssertion :: SEQUENCE {
* component ComponentReference (SIZE(1..MAX)) OPTIONAL,
* useDefaultValues BOOLEAN DEFAULT TRUE,
* rule MATCHING-RULE.&id,
* value MATCHING-RULE.&AssertionType }
*/
static int
get_item( Operation *op, ComponentAssertionValue* cav, ComponentAssertion** ca,
const char** text )
{
int rc;
ComponentAssertion* _ca;
struct berval value;
MatchingRule* mr;
Debug( LDAP_DEBUG_FILTER, "get_item \n", 0, 0, 0 );
if ( op )
_ca = op->o_tmpalloc( sizeof( ComponentAssertion ), op->o_tmpmemctx );
else
if ( !_ca ) return LDAP_NO_MEMORY;
_ca->ca_comp_data.cd_tree = NULL;
_ca->ca_comp_data.cd_mem_op = NULL;
rc = peek_cav_str( cav, "component" );
if ( rc == LDAP_SUCCESS ) {
strip_cav_str( cav, "component" );
rc = get_component_reference( op, cav, &_ca->ca_comp_ref, text );
if ( rc != LDAP_SUCCESS ) {
if ( op )
op->o_tmpfree( _ca, op->o_tmpmemctx );
else
free( _ca );
return LDAP_INVALID_SYNTAX;
}
if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS )
return rc;
} else {
_ca->ca_comp_ref = NULL;
}
rc = peek_cav_str( cav, "useDefaultValues");
if ( rc == LDAP_SUCCESS ) {
rc = get_ca_use_default( op, cav, &_ca->ca_use_def, text );
if ( rc != LDAP_SUCCESS ) {
if ( op )
op->o_tmpfree( _ca, op->o_tmpmemctx );
else
free( _ca );
return LDAP_INVALID_SYNTAX;
}
if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS )
return rc;
}
if ( !( strip_cav_str( cav, "rule" ) == LDAP_SUCCESS &&
get_matching_rule( op, cav , &_ca->ca_ma_rule, text ) == LDAP_SUCCESS )) {
if ( op )
op->o_tmpfree( _ca, op->o_tmpmemctx );
else