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;
if ( !mr || !ma->ma_cf )
return LDAP_INAPPROPRIATE_MATCHING;
/* Check if the component module is loaded */
if ( !attr_converter || !nibble_mem_allocator )
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 )
{
/* Only for Registeration */
*matchp = 0;
return LDAP_SUCCESS;
}
int
allComponentsMatch(
int *matchp,
slap_mask_t flags,
Syntax *syntax,
MatchingRule *mr,
struct berval *value,
void *assertedValue )
{
/* Only for Registeration */
*matchp = 0;
return LDAP_SUCCESS;
}
static int
slapd_ber2cav( struct berval* bv, ComponentAssertionValue* cav )
{
int len;
cav->cav_ptr = cav->cav_buf = bv->bv_val;
cav->cav_end = bv->bv_val + bv->bv_len;
}
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
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
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
dup_comp_ref ( Operation* op, ComponentReference* cr )
{
int rc, count = 0;
ComponentReference* dup_cr;
ComponentId* ci_curr;
ComponentId** ci_temp;
ber_int_t type;
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 ; ci_curr = ci_curr->ci_next, ci_temp = &(*ci_temp)->ci_next ) {
*ci_temp = op->o_tmpalloc( sizeof( ComponentId ), op->o_tmpmemctx );
if ( !ci_temp ) return NULL;
**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 )
{
int i = 0;
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 )
{
ComponentAssertion* ca;
int len;
if ( !in_ca->ca_comp_ref )
return SLAPD_DISCONNECT;
*out_ca = op->o_tmpalloc( sizeof( ComponentAssertion ), op->o_tmpmemctx );
if ( !(*out_ca) )
return LDAP_NO_MEMORY;
(*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, '$' );
if ( len <= 0 )
return SLAPD_DISCONNECT;
(*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;
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
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
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 ( Operation* op, MatchingRuleAssertion* ma, AttributeAliasing* aa, const char** text )
{
int rc;
struct berval assert_bv;
ComponentAssertion* ca;
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++;
}
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
}
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;
}
else
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** f, const char** text )
{
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 );
if ( err != LDAP_SUCCESS )
return ( err );
new = &(*new)->cf_next;
}
*new = NULL;
return( LDAP_SUCCESS );
}
static int
get_componentId( Operation *op, ComponentAssertionValue* cav,
ComponentId ** cid, const char** text )
{
ber_tag_t type;
ComponentId _cid;
int len;
type = peek_componentId_type( cav );
Debug( LDAP_DEBUG_FILTER, "get_compId [%d]\n", type, 0, 0 );
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 :
if ( cav->cav_ptr[len] != '(' )
return LDAP_COMPREF_UNDEFINED;
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;
}
if ( op )
*cid = op->o_tmpalloc( sizeof( ComponentId ), op->o_tmpmemctx );
else
*cid = malloc( sizeof( ComponentId ) );
**cid = _cid;
return LDAP_SUCCESS;
}
static int
peek_componentId_type( ComponentAssertionValue* cav )
{
eat_whsp( cav );
if ( cav->cav_ptr[0] == '-' )
return LDAP_COMPREF_FROM_END;
else if ( cav->cav_ptr[0] == '(' )
return LDAP_COMPREF_SELECT;
else if ( cav->cav_ptr[0] == '*' )
return LDAP_COMPREF_ALL;
else if ( cav->cav_ptr[0] == '0' )
return LDAP_COMPREF_COUNT;
else if ( cav->cav_ptr[0] > '0' && cav->cav_ptr[0] <= '9' )
return LDAP_COMPREF_FROM_BEGINNING;
else if ( (cav->cav_end - cav->cav_ptr) >= 7 &&
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;
else
return LDAP_COMPREF_UNDEFINED;
}
static ber_tag_t
comp_next_id( ComponentAssertionValue* cav )
{
if ( *(cav->cav_ptr) == '.' ) {
cav->cav_ptr++;
return LDAP_COMPREF_DEFINED;
}
else return LDAP_COMPREF_UNDEFINED;
}
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 = 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
; type = comp_next_id( cav ), count++ ) {
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;
}
else if ( rc == LDAP_COMPREF_UNDEFINED )
return rc;
}
ca_comp_ref->cr_len = count;
if ( ( rc = strip_cav_str( cav,"\"") ) != LDAP_SUCCESS ) {
if ( op )
op->o_tmpfree( ca_comp_ref , op->o_tmpmemctx );
else
free( ca_comp_ref );
if ( rc == LDAP_SUCCESS ) {
*cr = ca_comp_ref;
**cr = *ca_comp_ref;
}
else if ( op )
op->o_tmpfree( ca_comp_ref , op->o_tmpmemctx );
else
free( ca_comp_ref ) ;
(*cr)->cr_string.bv_val = start;
(*cr)->cr_string.bv_len = end - start + 1;
return rc;
}
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
int
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++ ) {
if ( attr[i] == '.' )
return (1);
}
return (0);
}
int
extract_component_reference( char* attr, ComponentReference** cr ) {
int i, rc;
char* cr_ptr;
int cr_len;
ComponentAssertionValue cav;
char text[1][128];
for ( i=0; attr[i] != '\0' ; i++ ) {
if ( attr[i] == '.' ) break;
}
if (attr[i] != '.' )
return LDAP_PARAM_ERROR;
else
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] = '"';
cav.cav_end = cr_ptr + cr_len + 2;
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;
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
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 ) {
break;
}
if ( ( cav->cav_ptr[count] == '"' && cav->cav_ptr[count-1] != '"') ||
( sequent_dquote > 2 && (sequent_dquote%2) == 1 ) ) {
succeed = 1;
break;
}
if ( !succeed || cav->cav_ptr[count] != '"' )
return LDAP_FILTER_ERROR;
bv->bv_val = cav->cav_ptr + 1;
bv->bv_len = count - 1; /* exclude '"' */
}
else if ( cav->cav_ptr[0] == '\'' ) {
if ( cav->cav_ptr[count] == '\0' || (cav->cav_ptr+count) > cav->cav_end ) {
break;
}
if ((cav->cav_ptr[count-1] == '\'' && cav->cav_ptr[count] == 'B')||
(cav->cav_ptr[count-1] == '\'' && cav->cav_ptr[count] == 'H') ) {
succeed = 1;
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" */
}
else if ( cav->cav_ptr[0] == '{' ) {
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 ( unclosed_brace == 0 ) {
succeed = 1;
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" */
}
else {
/*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 ) {
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
/* 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;
else
return LDAP_INVALID_SYNTAX;
}
static int
strip_cav_str( ComponentAssertionValue* cav, char* str)
{
eat_whsp( cav );
if ( cav_cur_len( cav ) >= strlen( str ) &&
strncmp( cav->cav_ptr, str, strlen( str ) ) == 0 ) {
cav->cav_ptr += strlen( str );
return LDAP_SUCCESS;
}
else
return LDAP_INVALID_SYNTAX;
}
/*
* TAG : "item", "and", "or", "not"
*/
static int
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;
}
else
return LBER_ERROR;
}
/*
* 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 t_bv;
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
_ca = malloc( sizeof( ComponentAssertion ) );
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
free( _ca );
return LDAP_INAPPROPRIATE_MATCHING;
}
if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS )
return rc;
if ( !(strip_cav_str( cav, "value" ) == LDAP_SUCCESS &&
get_matching_value( op, _ca, cav,&value ,text ) == LDAP_SUCCESS )) {
if ( op )
op->o_tmpfree( _ca, op->o_tmpmemctx );
else
free( _ca );
return LDAP_INVALID_SYNTAX;
}
/*
* Normalize the value of this component assertion when the matching
* rule is one of existing matching rules
*/
mr = _ca->ca_ma_rule;
if ( op && !(mr->smr_usage & (SLAP_MR_COMPONENT)) && mr->smr_normalize ) {
value.bv_val[value.bv_len] = '\0';
rc = mr->smr_normalize (
SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
NULL, mr,
&value, &_ca->ca_ma_value, op->o_tmpmemctx );
if ( rc != LDAP_SUCCESS )
return rc;
}
else
_ca->ca_ma_value = value;
/*
* Validate the value of this component assertion
*/
if ( op && mr->smr_syntax->ssyn_validate( mr->smr_syntax, &_ca->ca_ma_value) != LDAP_SUCCESS ) {
return LDAP_INVALID_SYNTAX;
}
/* componentFilterMatch contains componentFilterMatch in it */
if ( strcmp(_ca->ca_ma_rule->smr_mrule.mr_oid, OID_COMP_FILTER_MATCH ) == 0) {
struct berval bv;
bv.bv_val = cav->cav_ptr;
bv.bv_len = cav_cur_len( cav );
rc = get_comp_filter( op, &bv,(ComponentFilter**)&_ca->ca_cf, text );
if ( rc != LDAP_SUCCESS ) {
if ( op )
op->o_tmpfree( _ca, op->o_tmpmemctx );
else
free( _ca );
return rc;
}
cav->cav_ptr = bv.bv_val;
assert( cav->cav_end >= bv.bv_val );
}
*ca = _ca;
return LDAP_SUCCESS;
}
static int
parse_comp_filter( Operation* op, ComponentAssertionValue* cav,
ComponentFilter** filt, const char** text )
{
/*
* A component filter looks like this coming in:
* Filter ::= CHOICE {
* item [0] ComponentAssertion,