1 /* component.c -- Component Filter Match Routines */ 2 /* $OpenLDAP: pkg/ldap/servers/slapd/component.c,v 1.31.2.3 2008/02/11 23:26:43 kurt Exp $ */ 3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 4 * 5 * Copyright 2003-2008 The OpenLDAP Foundation. 6 * Portions Copyright 2004 by IBM Corporation. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted only as authorized by the OpenLDAP 11 * Public License. 12 * 13 * A copy of this license is available in the file LICENSE in the 14 * top-level directory of the distribution or, alternatively, at 15 * <http://www.OpenLDAP.org/license.html>. 16 */ 17 18 #include "portable.h" 19 20 #include <ac/string.h> 21 #include <ac/socket.h> 22 23 #include "lutil.h" 24 #include <ldap.h> 25 #include "slap.h" 26 27 #ifdef LDAP_COMP_MATCH 28 29 #include "component.h" 30 31 /* 32 * Following function pointers are initialized 33 * when a component module is loaded 34 */ 35 alloc_nibble_func* nibble_mem_allocator = NULL; 36 free_nibble_func* nibble_mem_free = NULL; 37 convert_attr_to_comp_func* attr_converter = NULL; 38 convert_assert_to_comp_func* assert_converter = NULL ; 39 free_component_func* component_destructor = NULL ; 40 test_component_func* test_components = NULL; 41 test_membership_func* is_aliased_attribute = NULL; 42 component_encoder_func* component_encoder = NULL; 43 get_component_info_func* get_component_description = NULL; 44 #define OID_ALL_COMP_MATCH "1.2.36.79672281.1.13.6" 45 #define OID_COMP_FILTER_MATCH "1.2.36.79672281.1.13.2" 46 #define MAX_LDAP_STR_LEN 128 47 48 static int 49 peek_componentId_type( ComponentAssertionValue* cav ); 50 51 static int 52 strip_cav_str( ComponentAssertionValue* cav, char* str); 53 54 static int 55 peek_cav_str( ComponentAssertionValue* cav, char* str ); 56 57 static int 58 parse_comp_filter( Operation* op, ComponentAssertionValue* cav, 59 ComponentFilter** filt, const char** text ); 60 61 static void 62 free_comp_filter( ComponentFilter* f ); 63 64 static int 65 test_comp_filter( Syntax *syn, ComponentSyntaxInfo *a, ComponentFilter *f ); 66 67 int 68 componentCertificateValidate( 69 Syntax *syntax, 70 struct berval *val ) 71 { 72 return LDAP_SUCCESS; 73 } 74 75 int 76 componentFilterValidate( 77 Syntax *syntax, 78 struct berval *val ) 79 { 80 return LDAP_SUCCESS; 81 } 82 83 int 84 allComponentsValidate( 85 Syntax *syntax, 86 struct berval *val ) 87 { 88 return LDAP_SUCCESS; 89 } 90 91 int 92 componentFilterMatch ( 93 int *matchp, 94 slap_mask_t flags, 95 Syntax *syntax, 96 MatchingRule *mr, 97 struct berval *value, 98 void *assertedValue ) 99 { 100 ComponentSyntaxInfo *csi_attr = (ComponentSyntaxInfo*)value; 101 MatchingRuleAssertion * ma = (MatchingRuleAssertion*)assertedValue; 102 int rc; 103 104 if ( !mr || !ma->ma_cf ) return LDAP_INAPPROPRIATE_MATCHING; 105 106 /* Check if the component module is loaded */ 107 if ( !attr_converter || !nibble_mem_allocator ) { 108 return LDAP_OTHER; 109 } 110 111 rc = test_comp_filter( syntax, csi_attr, ma->ma_cf ); 112 113 if ( rc == LDAP_COMPARE_TRUE ) { 114 *matchp = 0; 115 return LDAP_SUCCESS; 116 } 117 else if ( rc == LDAP_COMPARE_FALSE ) { 118 *matchp = 1; 119 return LDAP_SUCCESS; 120 } 121 else { 122 return LDAP_INAPPROPRIATE_MATCHING; 123 } 124 } 125 126 int 127 directoryComponentsMatch( 128 int *matchp, 129 slap_mask_t flags, 130 Syntax *syntax, 131 MatchingRule *mr, 132 struct berval *value, 133 void *assertedValue ) 134 { 135 /* Only for registration */ 136 *matchp = 0; 137 return LDAP_SUCCESS; 138 } 139 140 int 141 allComponentsMatch( 142 int *matchp, 143 slap_mask_t flags, 144 Syntax *syntax, 145 MatchingRule *mr, 146 struct berval *value, 147 void *assertedValue ) 148 { 149 /* Only for registration */ 150 *matchp = 0; 151 return LDAP_SUCCESS; 152 } 153 154 static int 155 slapd_ber2cav( struct berval* bv, ComponentAssertionValue* cav ) 156 { 157 cav->cav_ptr = cav->cav_buf = bv->bv_val; 158 cav->cav_end = bv->bv_val + bv->bv_len; 159 160 return LDAP_SUCCESS; 161 } 162 163 ComponentReference* 164 dup_comp_ref ( Operation* op, ComponentReference* cr ) 165 { 166 ComponentReference* dup_cr; 167 ComponentId* ci_curr; 168 ComponentId** ci_temp; 169 170 dup_cr = op->o_tmpalloc( sizeof( ComponentReference ), op->o_tmpmemctx ); 171 172 dup_cr->cr_len = cr->cr_len; 173 dup_cr->cr_string = cr->cr_string; 174 175 ci_temp = &dup_cr->cr_list; 176 ci_curr = cr->cr_list; 177 178 for ( ; ci_curr != NULL ; 179 ci_curr = ci_curr->ci_next, ci_temp = &(*ci_temp)->ci_next ) 180 { 181 *ci_temp = op->o_tmpalloc( sizeof( ComponentId ), op->o_tmpmemctx ); 182 if ( !*ci_temp ) return NULL; 183 **ci_temp = *ci_curr; 184 } 185 186 dup_cr->cr_curr = dup_cr->cr_list; 187 188 return dup_cr; 189 } 190 191 static int 192 dup_comp_filter_list ( 193 Operation *op, 194 struct berval *bv, 195 ComponentFilter* in_f, 196 ComponentFilter** out_f ) 197 { 198 ComponentFilter **new, *f; 199 int rc; 200 201 new = out_f; 202 for ( f = in_f; f != NULL; f = f->cf_next ) { 203 rc = dup_comp_filter( op, bv, f, new ); 204 if ( rc != LDAP_SUCCESS ) { 205 return rc; 206 } 207 new = &(*new)->cf_next; 208 } 209 return LDAP_SUCCESS; 210 } 211 212 int 213 get_len_of_next_assert_value ( struct berval* bv, char separator ) 214 { 215 int i = 0; 216 while (1) { 217 if ( (bv->bv_val[ i ] == separator) || ( i >= bv->bv_len) ) 218 break; 219 i++; 220 } 221 bv->bv_val += (i + 1); 222 bv->bv_len -= (i + 1); 223 return i; 224 } 225 226 int 227 dup_comp_filter_item ( 228 Operation *op, 229 struct berval* assert_bv, 230 ComponentAssertion* in_ca, 231 ComponentAssertion** out_ca ) 232 { 233 int len; 234 235 if ( !in_ca->ca_comp_ref ) return SLAPD_DISCONNECT; 236 237 *out_ca = op->o_tmpalloc( sizeof( ComponentAssertion ), op->o_tmpmemctx ); 238 if ( !(*out_ca) ) return LDAP_NO_MEMORY; 239 240 (*out_ca)->ca_comp_data.cd_tree = NULL; 241 (*out_ca)->ca_comp_data.cd_mem_op = NULL; 242 243 (*out_ca)->ca_comp_ref = dup_comp_ref ( op, in_ca->ca_comp_ref ); 244 (*out_ca)->ca_use_def = 0; 245 (*out_ca)->ca_ma_rule = in_ca->ca_ma_rule; 246 247 (*out_ca)->ca_ma_value.bv_val = assert_bv->bv_val; 248 len = get_len_of_next_assert_value ( assert_bv, '$' ); 249 if ( len <= 0 ) return SLAPD_DISCONNECT; 250 (*out_ca)->ca_ma_value.bv_len = len; 251 252 return LDAP_SUCCESS; 253 } 254 255 int 256 dup_comp_filter ( 257 Operation* op, 258 struct berval *bv, 259 ComponentFilter *in_f, 260 ComponentFilter **out_f ) 261 { 262 int rc; 263 ComponentFilter dup_f = {0}; 264 265 if ( !in_f ) return LDAP_PROTOCOL_ERROR; 266 267 switch ( in_f->cf_choice ) { 268 case LDAP_COMP_FILTER_AND: 269 rc = dup_comp_filter_list( op, bv, in_f->cf_and, &dup_f.cf_and); 270 dup_f.cf_choice = LDAP_COMP_FILTER_AND; 271 break; 272 case LDAP_COMP_FILTER_OR: 273 rc = dup_comp_filter_list( op, bv, in_f->cf_or, &dup_f.cf_or); 274 dup_f.cf_choice = LDAP_COMP_FILTER_OR; 275 break; 276 case LDAP_COMP_FILTER_NOT: 277 rc = dup_comp_filter( op, bv, in_f->cf_not, &dup_f.cf_not); 278 dup_f.cf_choice = LDAP_COMP_FILTER_NOT; 279 break; 280 case LDAP_COMP_FILTER_ITEM: 281 rc = dup_comp_filter_item( op, bv, in_f->cf_ca ,&dup_f.cf_ca ); 282 dup_f.cf_choice = LDAP_COMP_FILTER_ITEM; 283 break; 284 default: 285 rc = LDAP_PROTOCOL_ERROR; 286 } 287 288 if ( rc == LDAP_SUCCESS ) { 289 *out_f = op->o_tmpalloc( sizeof(dup_f), op->o_tmpmemctx ); 290 **out_f = dup_f; 291 } 292 293 return( rc ); 294 } 295 296 int 297 get_aliased_filter_aa ( Operation* op, AttributeAssertion* a_assert, AttributeAliasing* aa, const char** text ) 298 { 299 struct berval assert_bv; 300 301 Debug( LDAP_DEBUG_FILTER, "get_aliased_filter\n", 0, 0, 0 ); 302 303 if ( !aa->aa_cf ) 304 return LDAP_PROTOCOL_ERROR; 305 306 assert_bv = a_assert->aa_value; 307 /* 308 * Duplicate aa->aa_cf to ma->ma_cf by replacing the 309 * the component assertion value in assert_bv 310 * Multiple values may be separated with '$' 311 */ 312 return dup_comp_filter ( op, &assert_bv, aa->aa_cf, &a_assert->aa_cf ); 313 } 314 315 int 316 get_aliased_filter( Operation* op, 317 MatchingRuleAssertion* ma, AttributeAliasing* aa, 318 const char** text ) 319 { 320 struct berval assert_bv; 321 322 Debug( LDAP_DEBUG_FILTER, "get_aliased_filter\n", 0, 0, 0 ); 323 324 if ( !aa->aa_cf ) return LDAP_PROTOCOL_ERROR; 325 326 assert_bv = ma->ma_value; 327 /* Attribute Description is replaced with aliased one */ 328 ma->ma_desc = aa->aa_aliased_ad; 329 ma->ma_rule = aa->aa_mr; 330 /* 331 * Duplicate aa->aa_cf to ma->ma_cf by replacing the 332 * the component assertion value in assert_bv 333 * Multiple values may be separated with '$' 334 */ 335 return dup_comp_filter ( op, &assert_bv, aa->aa_cf, &ma->ma_cf ); 336 } 337 338 int 339 get_comp_filter( Operation* op, struct berval* bv, 340 ComponentFilter** filt, const char **text ) 341 { 342 ComponentAssertionValue cav; 343 int rc; 344 345 Debug( LDAP_DEBUG_FILTER, "get_comp_filter\n", 0, 0, 0 ); 346 if ( (rc = slapd_ber2cav(bv, &cav) ) != LDAP_SUCCESS ) { 347 return rc; 348 } 349 rc = parse_comp_filter( op, &cav, filt, text ); 350 bv->bv_val = cav.cav_ptr; 351 352 return rc; 353 } 354 355 static void 356 eat_whsp( ComponentAssertionValue* cav ) 357 { 358 for ( ; ( *cav->cav_ptr == ' ' ) && ( cav->cav_ptr < cav->cav_end ) ; ) { 359 cav->cav_ptr++; 360 } 361 } 362 363 static int 364 cav_cur_len( ComponentAssertionValue* cav ) 365 { 366 return cav->cav_end - cav->cav_ptr; 367 } 368 369 static ber_tag_t 370 comp_first_element( ComponentAssertionValue* cav ) 371 { 372 eat_whsp( cav ); 373 if ( cav_cur_len( cav ) >= 8 && strncmp( cav->cav_ptr, "item", 4 ) == 0 ) { 374 return LDAP_COMP_FILTER_ITEM; 375 376 } else if ( cav_cur_len( cav ) >= 7 && 377 strncmp( cav->cav_ptr, "and", 3 ) == 0 ) 378 { 379 return LDAP_COMP_FILTER_AND; 380 381 } else if ( cav_cur_len( cav ) >= 6 && 382 strncmp( cav->cav_ptr, "or" , 2 ) == 0 ) 383 { 384 return LDAP_COMP_FILTER_OR; 385 386 } else if ( cav_cur_len( cav ) >= 7 && 387 strncmp( cav->cav_ptr, "not", 3 ) == 0 ) 388 { 389 return LDAP_COMP_FILTER_NOT; 390 391 } else { 392 return LDAP_COMP_FILTER_UNDEFINED; 393 } 394 } 395 396 static ber_tag_t 397 comp_next_element( ComponentAssertionValue* cav ) 398 { 399 eat_whsp( cav ); 400 if ( *(cav->cav_ptr) == ',' ) { 401 /* move pointer to the next CA */ 402 cav->cav_ptr++; 403 return comp_first_element( cav ); 404 } 405 else return LDAP_COMP_FILTER_UNDEFINED; 406 } 407 408 static int 409 get_comp_filter_list( Operation *op, ComponentAssertionValue *cav, 410 ComponentFilter** f, const char** text ) 411 { 412 ComponentFilter **new; 413 int err; 414 ber_tag_t tag; 415 416 Debug( LDAP_DEBUG_FILTER, "get_comp_filter_list\n", 0, 0, 0 ); 417 new = f; 418 for ( tag = comp_first_element( cav ); 419 tag != LDAP_COMP_FILTER_UNDEFINED; 420 tag = comp_next_element( cav ) ) 421 { 422 err = parse_comp_filter( op, cav, new, text ); 423 if ( err != LDAP_SUCCESS ) return ( err ); 424 new = &(*new)->cf_next; 425 } 426 *new = NULL; 427 428 return( LDAP_SUCCESS ); 429 } 430 431 static int 432 get_componentId( Operation *op, ComponentAssertionValue* cav, 433 ComponentId ** cid, const char** text ) 434 { 435 ber_tag_t type; 436 ComponentId _cid; 437 int len; 438 439 type = peek_componentId_type( cav ); 440 441 Debug( LDAP_DEBUG_FILTER, "get_compId [%lu]\n", 442 (unsigned long) type, 0, 0 ); 443 len = 0; 444 _cid.ci_type = type; 445 _cid.ci_next = NULL; 446 switch ( type ) { 447 case LDAP_COMPREF_IDENTIFIER : 448 _cid.ci_val.ci_identifier.bv_val = cav->cav_ptr; 449 for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' && 450 cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' ; len++ ); 451 _cid.ci_val.ci_identifier.bv_len = len; 452 cav->cav_ptr += len; 453 break; 454 case LDAP_COMPREF_FROM_BEGINNING : 455 for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' && 456 cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' ; len++ ); 457 _cid.ci_val.ci_from_beginning = strtol( cav->cav_ptr, NULL, 0 ); 458 cav->cav_ptr += len; 459 break; 460 case LDAP_COMPREF_FROM_END : 461 for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' && 462 cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' ; len++ ); 463 _cid.ci_val.ci_from_end = strtol( cav->cav_ptr, NULL, 0 ); 464 cav->cav_ptr += len; 465 break; 466 case LDAP_COMPREF_COUNT : 467 _cid.ci_val.ci_count = 0; 468 cav->cav_ptr++; 469 break; 470 case LDAP_COMPREF_CONTENT : 471 _cid.ci_val.ci_content = 1; 472 cav->cav_ptr += strlen("content"); 473 break; 474 case LDAP_COMPREF_SELECT : 475 if ( cav->cav_ptr[len] != '(' ) return LDAP_COMPREF_UNDEFINED; 476 for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' && 477 cav->cav_ptr[len] != '\"' && cav->cav_ptr[len] != ')' 478 ; len++ ); 479 _cid.ci_val.ci_select_value.bv_val = cav->cav_ptr + 1; 480 _cid.ci_val.ci_select_value.bv_len = len - 1 ; 481 cav->cav_ptr += len + 1; 482 break; 483 case LDAP_COMPREF_ALL : 484 _cid.ci_val.ci_all = '*'; 485 cav->cav_ptr++; 486 break; 487 default : 488 return LDAP_COMPREF_UNDEFINED; 489 } 490 491 if ( op ) { 492 *cid = op->o_tmpalloc( sizeof( ComponentId ), op->o_tmpmemctx ); 493 } else { 494 *cid = malloc( sizeof( ComponentId ) ); 495 } 496 **cid = _cid; 497 return LDAP_SUCCESS; 498 } 499 500 static int 501 peek_componentId_type( ComponentAssertionValue* cav ) 502 { 503 eat_whsp( cav ); 504 505 if ( cav->cav_ptr[0] == '-' ) { 506 return LDAP_COMPREF_FROM_END; 507 508 } else if ( cav->cav_ptr[0] == '(' ) { 509 return LDAP_COMPREF_SELECT; 510 511 } else if ( cav->cav_ptr[0] == '*' ) { 512 return LDAP_COMPREF_ALL; 513 514 } else if ( cav->cav_ptr[0] == '0' ) { 515 return LDAP_COMPREF_COUNT; 516 517 } else if ( cav->cav_ptr[0] > '0' && cav->cav_ptr[0] <= '9' ) { 518 return LDAP_COMPREF_FROM_BEGINNING; 519 520 } else if ( (cav->cav_end - cav->cav_ptr) >= 7 && 521 strncmp(cav->cav_ptr,"content",7) == 0 ) 522 { 523 return LDAP_COMPREF_CONTENT; 524 } else if ( (cav->cav_ptr[0] >= 'a' && cav->cav_ptr[0] <= 'z') || 525 (cav->cav_ptr[0] >= 'A' && cav->cav_ptr[0] <= 'Z') ) 526 { 527 return LDAP_COMPREF_IDENTIFIER; 528 } 529 530 return LDAP_COMPREF_UNDEFINED; 531 } 532 533 static ber_tag_t 534 comp_next_id( ComponentAssertionValue* cav ) 535 { 536 if ( *(cav->cav_ptr) == '.' ) { 537 cav->cav_ptr++; 538 return LDAP_COMPREF_DEFINED; 539 } 540 541 return LDAP_COMPREF_UNDEFINED; 542 } 543 544 545 546 static int 547 get_component_reference( 548 Operation *op, 549 ComponentAssertionValue* cav, 550 ComponentReference** cr, 551 const char** text ) 552 { 553 int rc, count = 0; 554 ber_int_t type; 555 ComponentReference* ca_comp_ref; 556 ComponentId** cr_list; 557 char* start, *end; 558 559 eat_whsp( cav ); 560 561 start = cav->cav_ptr; 562 if ( ( rc = strip_cav_str( cav,"\"") ) != LDAP_SUCCESS ) return rc; 563 if ( op ) { 564 ca_comp_ref = op->o_tmpalloc( sizeof( ComponentReference ), 565 op->o_tmpmemctx ); 566 } else { 567 ca_comp_ref = malloc( sizeof( ComponentReference ) ); 568 } 569 570 if ( !ca_comp_ref ) return LDAP_NO_MEMORY; 571 572 cr_list = &ca_comp_ref->cr_list; 573 574 for ( type = peek_componentId_type( cav ) ; type != LDAP_COMPREF_UNDEFINED 575 ; type = comp_next_id( cav ), count++ ) 576 { 577 rc = get_componentId( op, cav, cr_list, text ); 578 if ( rc == LDAP_SUCCESS ) { 579 if ( count == 0 ) ca_comp_ref->cr_curr = ca_comp_ref->cr_list; 580 cr_list = &(*cr_list)->ci_next; 581 582 } else if ( rc == LDAP_COMPREF_UNDEFINED ) { 583 if ( op ) { 584 op->o_tmpfree( ca_comp_ref , op->o_tmpmemctx ); 585 } else { 586 free( ca_comp_ref ); 587 } 588 return rc; 589 } 590 } 591 ca_comp_ref->cr_len = count; 592 end = cav->cav_ptr; 593 if ( ( rc = strip_cav_str( cav,"\"") ) != LDAP_SUCCESS ) { 594 if ( op ) { 595 op->o_tmpfree( ca_comp_ref , op->o_tmpmemctx ); 596 } else { 597 free( ca_comp_ref ); 598 } 599 return rc; 600 } 601 602 *cr = ca_comp_ref; 603 **cr = *ca_comp_ref; 604 605 (*cr)->cr_string.bv_val = start; 606 (*cr)->cr_string.bv_len = end - start + 1; 607 608 return rc; 609 } 610 611 int 612 insert_component_reference( 613 ComponentReference *cr, 614 ComponentReference** cr_list) 615 { 616 if ( !cr ) return LDAP_PARAM_ERROR; 617 618 if ( !(*cr_list) ) { 619 *cr_list = cr; 620 cr->cr_next = NULL; 621 } else { 622 cr->cr_next = *cr_list; 623 *cr_list = cr; 624 } 625 return LDAP_SUCCESS; 626 } 627 628 /* 629 * If there is '.' in the name of a given attribute 630 * the first '.'- following characters are considered 631 * as a component reference of the attribute 632 * EX) userCertificate.toBeSigned.serialNumber 633 * attribute : userCertificate 634 * component reference : toBeSigned.serialNumber 635 */ 636 int 637 is_component_reference( char* attr ) { 638 int i; 639 for ( i=0; attr[i] != '\0' ; i++ ) { 640 if ( attr[i] == '.' ) return (1); 641 } 642 return (0); 643 } 644 645 int 646 extract_component_reference( 647 char* attr, 648 ComponentReference** cr ) 649 { 650 int i, rc; 651 char* cr_ptr; 652 int cr_len; 653 ComponentAssertionValue cav; 654 char text[1][128]; 655 656 for ( i=0; attr[i] != '\0' ; i++ ) { 657 if ( attr[i] == '.' ) break; 658 } 659 660 if (attr[i] != '.' ) return LDAP_PARAM_ERROR; 661 attr[i] = '\0'; 662 663 cr_ptr = attr + i + 1 ; 664 cr_len = strlen ( cr_ptr ); 665 if ( cr_len <= 0 ) return LDAP_PARAM_ERROR; 666 667 /* enclosed between double quotes*/ 668 cav.cav_ptr = cav.cav_buf = ch_malloc (cr_len+2); 669 memcpy( cav.cav_buf+1, cr_ptr, cr_len ); 670 cav.cav_buf[0] = '"'; 671 cav.cav_buf[cr_len+1] = '"'; 672 cav.cav_end = cr_ptr + cr_len + 2; 673 674 rc = get_component_reference ( NULL, &cav, cr, (const char**)text ); 675 if ( rc != LDAP_SUCCESS ) return rc; 676 (*cr)->cr_string.bv_val = cav.cav_buf; 677 (*cr)->cr_string.bv_len = cr_len + 2; 678 679 return LDAP_SUCCESS; 680 } 681 682 static int 683 get_ca_use_default( Operation *op, 684 ComponentAssertionValue* cav, 685 int* ca_use_def, const char** text ) 686 { 687 strip_cav_str( cav, "useDefaultValues" ); 688 689 if ( peek_cav_str( cav, "TRUE" ) == LDAP_SUCCESS ) { 690 strip_cav_str( cav, "TRUE" ); 691 *ca_use_def = 1; 692 693 } else if ( peek_cav_str( cav, "FALSE" ) == LDAP_SUCCESS ) { 694 strip_cav_str( cav, "FALSE" ); 695 *ca_use_def = 0; 696 697 } else { 698 return LDAP_INVALID_SYNTAX; 699 } 700 701 return LDAP_SUCCESS; 702 } 703 704 static int 705 get_matching_rule( Operation *op, ComponentAssertionValue* cav, 706 MatchingRule** mr, const char** text ) 707 { 708 int count = 0; 709 struct berval rule_text = { 0L, NULL }; 710 711 eat_whsp( cav ); 712 713 for ( ; ; count++ ) { 714 if ( cav->cav_ptr[count] == ' ' || cav->cav_ptr[count] == ',' || 715 cav->cav_ptr[count] == '\0' || cav->cav_ptr[count] == '{' || 716 cav->cav_ptr[count] == '}' || cav->cav_ptr[count] == '\n' ) 717 { 718 break; 719 } 720 } 721 722 if ( count == 0 ) { 723 *text = "component matching rule not recognized"; 724 return LDAP_INAPPROPRIATE_MATCHING; 725 } 726 727 rule_text.bv_len = count; 728 rule_text.bv_val = cav->cav_ptr; 729 *mr = mr_bvfind( &rule_text ); 730 cav->cav_ptr += count; 731 Debug( LDAP_DEBUG_FILTER, "get_matching_rule: %s\n", 732 (*mr)->smr_mrule.mr_oid, 0, 0 ); 733 if ( *mr == NULL ) { 734 *text = "component matching rule not recognized"; 735 return LDAP_INAPPROPRIATE_MATCHING; 736 } 737 return LDAP_SUCCESS; 738 } 739 740 static int 741 get_GSER_value( ComponentAssertionValue* cav, struct berval* bv ) 742 { 743 int count, sequent_dquote, unclosed_brace, succeed; 744 745 eat_whsp( cav ); 746 /* 747 * Four cases of GSER <Values> 748 * 1) "..." : 749 * StringVal, GeneralizedTimeVal, UTCTimeVal, ObjectDescriptorVal 750 * 2) '...'B or '...'H : 751 * BitStringVal, OctetStringVal 752 * 3) {...} : 753 * SEQUENCE, SEQUENCEOF, SETOF, SET, CHOICE 754 * 4) Between two white spaces 755 * INTEGER, BOOLEAN, NULL,ENUMERATE, etc 756 */ 757 758 succeed = 0; 759 if ( cav->cav_ptr[0] == '"' ) { 760 for( count = 1, sequent_dquote = 0 ; ; count++ ) { 761 /* In order to find escaped double quote */ 762 if ( cav->cav_ptr[count] == '"' ) sequent_dquote++; 763 else sequent_dquote = 0; 764 765 if ( cav->cav_ptr[count] == '\0' || 766 (cav->cav_ptr+count) > cav->cav_end ) 767 { 768 break; 769 } 770 771 if ( ( cav->cav_ptr[count] == '"' && 772 cav->cav_ptr[count-1] != '"') || 773 ( sequent_dquote > 2 && (sequent_dquote%2) == 1 ) ) 774 { 775 succeed = 1; 776 break; 777 } 778 } 779 780 if ( !succeed || cav->cav_ptr[count] != '"' ) { 781 return LDAP_FILTER_ERROR; 782 } 783 784 bv->bv_val = cav->cav_ptr + 1; 785 bv->bv_len = count - 1; /* exclude '"' */ 786 787 } else if ( cav->cav_ptr[0] == '\'' ) { 788 for( count = 1 ; ; count++ ) { 789 if ( cav->cav_ptr[count] == '\0' || 790 (cav->cav_ptr+count) > cav->cav_end ) 791 { 792 break; 793 } 794 if ((cav->cav_ptr[count-1] == '\'' && cav->cav_ptr[count] == 'B') || 795 (cav->cav_ptr[count-1] == '\'' && cav->cav_ptr[count] == 'H') ) 796 { 797 succeed = 1; 798 break; 799 } 800 } 801 802 if ( !succeed || 803 !(cav->cav_ptr[count] == 'H' || cav->cav_ptr[count] == 'B') ) 804 { 805 return LDAP_FILTER_ERROR; 806 } 807 808 bv->bv_val = cav->cav_ptr + 1;/*the next to '"' */ 809 bv->bv_len = count - 2;/* exclude "'H" or "'B" */ 810 811 } else if ( cav->cav_ptr[0] == '{' ) { 812 for( count = 1, unclosed_brace = 1 ; ; count++ ) { 813 if ( cav->cav_ptr[count] == '{' ) unclosed_brace++; 814 if ( cav->cav_ptr[count] == '}' ) unclosed_brace--; 815 816 if ( cav->cav_ptr[count] == '\0' || 817 (cav->cav_ptr+count) > cav->cav_end ) 818 { 819 break; 820 } 821 if ( unclosed_brace == 0 ) { 822 succeed = 1; 823 break; 824 } 825 } 826 827 if ( !succeed || cav->cav_ptr[count] != '}' ) return LDAP_FILTER_ERROR; 828 829 bv->bv_val = cav->cav_ptr + 1;/*the next to '"' */ 830 bv->bv_len = count - 1;/* exclude "'B" */ 831 832 } else { 833 succeed = 1; 834 /*Find following white space where the value is ended*/ 835 for( count = 1 ; ; count++ ) { 836 if ( cav->cav_ptr[count] == '\0' || 837 cav->cav_ptr[count] == ' ' || cav->cav_ptr[count] == '}' || 838 cav->cav_ptr[count] == '{' || 839 (cav->cav_ptr+count) > cav->cav_end ) 840 { 841 break; 842 } 843 } 844 bv->bv_val = cav->cav_ptr; 845 bv->bv_len = count; 846 } 847 848 cav->cav_ptr += bv->bv_len; 849 return LDAP_SUCCESS; 850 } 851 852 static int 853 get_matching_value( Operation *op, ComponentAssertion* ca, 854 ComponentAssertionValue* cav, struct berval* bv, 855 const char** text ) 856 { 857 if ( !(ca->ca_ma_rule->smr_usage & (SLAP_MR_COMPONENT)) ) { 858 if ( get_GSER_value( cav, bv ) != LDAP_SUCCESS ) { 859 return LDAP_FILTER_ERROR; 860 } 861 862 } else { 863 /* embeded componentFilterMatch Description */ 864 bv->bv_val = cav->cav_ptr; 865 bv->bv_len = cav_cur_len( cav ); 866 } 867 868 return LDAP_SUCCESS; 869 } 870 871 /* Don't move the position pointer, just peek given string */ 872 static int 873 peek_cav_str( ComponentAssertionValue* cav, char* str ) 874 { 875 eat_whsp( cav ); 876 if ( cav_cur_len( cav ) >= strlen( str ) && 877 strncmp( cav->cav_ptr, str, strlen( str ) ) == 0 ) 878 { 879 return LDAP_SUCCESS; 880 } 881 882 return LDAP_INVALID_SYNTAX; 883 } 884 885 static int 886 strip_cav_str( ComponentAssertionValue* cav, char* str) 887 { 888 eat_whsp( cav ); 889 if ( cav_cur_len( cav ) >= strlen( str ) && 890 strncmp( cav->cav_ptr, str, strlen( str ) ) == 0 ) 891 { 892 cav->cav_ptr += strlen( str ); 893 return LDAP_SUCCESS; 894 } 895 896 return LDAP_INVALID_SYNTAX; 897 } 898 899 /* 900 * TAG : "item", "and", "or", "not" 901 */ 902 static ber_tag_t 903 strip_cav_tag( ComponentAssertionValue* cav ) 904 { 905 906 eat_whsp( cav ); 907 if ( cav_cur_len( cav ) >= 8 && strncmp( cav->cav_ptr, "item", 4 ) == 0 ) { 908 strip_cav_str( cav , "item:" ); 909 return LDAP_COMP_FILTER_ITEM; 910 911 } else if ( cav_cur_len( cav ) >= 7 && 912 strncmp( cav->cav_ptr, "and", 3 ) == 0 ) 913 { 914 strip_cav_str( cav , "and:" ); 915 return LDAP_COMP_FILTER_AND; 916 917 } else if ( cav_cur_len( cav ) >= 6 && 918 strncmp( cav->cav_ptr, "or" , 2 ) == 0 ) 919 { 920 strip_cav_str( cav , "or:" ); 921 return LDAP_COMP_FILTER_OR; 922 923 } else if ( cav_cur_len( cav ) >= 7 && 924 strncmp( cav->cav_ptr, "not", 3 ) == 0 ) 925 { 926 strip_cav_str( cav , "not:" ); 927 return LDAP_COMP_FILTER_NOT; 928 } 929 930 return LBER_ERROR; 931 } 932 933 /* 934 * when encoding, "item" is denotation of ComponentAssertion 935 * ComponentAssertion :: SEQUENCE { 936 * component ComponentReference (SIZE(1..MAX)) OPTIONAL, 937 * useDefaultValues BOOLEAN DEFAULT TRUE, 938 * rule MATCHING-RULE.&id, 939 * value MATCHING-RULE.&AssertionType } 940 */ 941 static int 942 get_item( Operation *op, ComponentAssertionValue* cav, ComponentAssertion** ca, 943 const char** text ) 944 { 945 int rc; 946 ComponentAssertion* _ca; 947 struct berval value; 948 MatchingRule* mr; 949 950 Debug( LDAP_DEBUG_FILTER, "get_item \n", 0, 0, 0 ); 951 if ( op ) 952 _ca = op->o_tmpalloc( sizeof( ComponentAssertion ), op->o_tmpmemctx ); 953 else 954 _ca = malloc( sizeof( ComponentAssertion ) ); 955 956 if ( !_ca ) return LDAP_NO_MEMORY; 957 958 _ca->ca_comp_data.cd_tree = NULL; 959 _ca->ca_comp_data.cd_mem_op = NULL; 960 961 rc = peek_cav_str( cav, "component" ); 962 if ( rc == LDAP_SUCCESS ) { 963 strip_cav_str( cav, "component" ); 964 rc = get_component_reference( op, cav, &_ca->ca_comp_ref, text ); 965 if ( rc != LDAP_SUCCESS ) { 966 if ( op ) 967 op->o_tmpfree( _ca, op->o_tmpmemctx ); 968 else 969 free( _ca ); 970 return LDAP_INVALID_SYNTAX; 971 } 972 if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS ) 973 return rc; 974 } else { 975 _ca->ca_comp_ref = NULL; 976 } 977 978 rc = peek_cav_str( cav, "useDefaultValues"); 979 if ( rc == LDAP_SUCCESS ) { 980 rc = get_ca_use_default( op, cav, &_ca->ca_use_def, text ); 981 if ( rc != LDAP_SUCCESS ) { 982 if ( op ) 983 op->o_tmpfree( _ca, op->o_tmpmemctx ); 984 else 985 free( _ca ); 986 return LDAP_INVALID_SYNTAX; 987 } 988 if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS ) 989 return rc; 990 } 991 else _ca->ca_use_def = 1; 992 993 if ( !( strip_cav_str( cav, "rule" ) == LDAP_SUCCESS && 994 get_matching_rule( op, cav , &_ca->ca_ma_rule, text ) == LDAP_SUCCESS )) { 995 if ( op ) 996 op->o_tmpfree( _ca, op->o_tmpmemctx ); 997 else 998 free( _ca ); 999 return LDAP_INAPPROPRIATE_MATCHING; 1000 } 1001 1002 if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS ) 1003 return rc; 1004 if ( !(strip_cav_str( cav, "value" ) == LDAP_SUCCESS && 1005 get_matching_value( op, _ca, cav,&value ,text ) == LDAP_SUCCESS )) { 1006 if ( op ) 1007 op->o_tmpfree( _ca, op->o_tmpmemctx ); 1008 else 1009 free( _ca ); 1010 return LDAP_INVALID_SYNTAX; 1011 } 1012 1013 /* 1014 * Normalize the value of this component assertion when the matching 1015 * rule is one of existing matching rules 1016 */ 1017 mr = _ca->ca_ma_rule; 1018 if ( op && !(mr->smr_usage & (SLAP_MR_COMPONENT)) && mr->smr_normalize ) { 1019 1020 value.bv_val[value.bv_len] = '\0'; 1021 rc = mr->smr_normalize ( 1022 SLAP_MR_VALUE_OF_ASSERTION_SYNTAX, 1023 NULL, mr, 1024 &value, &_ca->ca_ma_value, op->o_tmpmemctx ); 1025 if ( rc != LDAP_SUCCESS ) 1026 return rc; 1027 } 1028 else 1029 _ca->ca_ma_value = value; 1030 /* 1031 * Validate the value of this component assertion 1032 */ 1033 if ( op && mr->smr_syntax->ssyn_validate( mr->smr_syntax, &_ca->ca_ma_value) != LDAP_SUCCESS ) { 1034 return LDAP_INVALID_SYNTAX; 1035 } 1036 1037 1038 /* componentFilterMatch contains componentFilterMatch in it */ 1039 if ( strcmp(_ca->ca_ma_rule->smr_mrule.mr_oid, OID_COMP_FILTER_MATCH ) == 0) { 1040 struct berval bv; 1041 bv.bv_val = cav->cav_ptr; 1042 bv.bv_len = cav_cur_len( cav ); 1043 rc = get_comp_filter( op, &bv,(ComponentFilter**)&_ca->ca_cf, text ); 1044 if ( rc != LDAP_SUCCESS ) { 1045 if ( op ) 1046 op->o_tmpfree( _ca, op->o_tmpmemctx ); 1047 else 1048 free( _ca ); 1049 return rc; 1050 } 1051 cav->cav_ptr = bv.bv_val; 1052 assert( cav->cav_end >= bv.bv_val ); 1053 } 1054 1055 *ca = _ca; 1056 return LDAP_SUCCESS; 1057 } 1058 1059 static int 1060 parse_comp_filter( Operation* op, ComponentAssertionValue* cav, 1061 ComponentFilter** filt, const char** text ) 1062 { 1063 /* 1064 * A component filter looks like this coming in: 1065 * Filter ::= CHOICE { 1066 * item [0] ComponentAssertion, 1067 * and [1] SEQUENCE OF ComponentFilter, 1068 * or [2] SEQUENCE OF ComponentFilter, 1069 * not [3] ComponentFilter, 1070 * } 1071 */ 1072 1073 ber_tag_t tag; 1074 int err; 1075 ComponentFilter f; 1076 /* TAG : item, and, or, not in RFC 4515 */ 1077 tag = strip_cav_tag( cav ); 1078 1079 if ( tag == LBER_ERROR ) { 1080 *text = "error decoding comp filter"; 1081 return LDAP_PROTOCOL_ERROR; 1082 } 1083 1084 if ( tag != LDAP_COMP_FILTER_NOT ) 1085 strip_cav_str( cav, "{"); 1086 1087 err = LDAP_SUCCESS; 1088 1089 f.cf_next = NULL; 1090 f.cf_choice = tag; 1091 1092 switch ( f.cf_choice ) { 1093 case LDAP_COMP_FILTER_AND: 1094 Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_AND\n", 0, 0, 0 ); 1095 err = get_comp_filter_list( op, cav, &f.cf_and, text ); 1096 if ( err != LDAP_SUCCESS ) { 1097 break; 1098 } 1099 if ( f.cf_and == NULL ) { 1100 f.cf_choice = SLAPD_FILTER_COMPUTED; 1101 f.cf_result = LDAP_COMPARE_TRUE; 1102 } 1103 break; 1104 1105 case LDAP_COMP_FILTER_OR: 1106 Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_OR\n", 0, 0, 0 ); 1107 err = get_comp_filter_list( op, cav, &f.cf_or, text ); 1108 if ( err != LDAP_SUCCESS ) { 1109 break; 1110 } 1111 if ( f.cf_or == NULL ) { 1112 f.cf_choice = SLAPD_FILTER_COMPUTED; 1113 f.cf_result = LDAP_COMPARE_FALSE; 1114 } 1115 /* no assert - list could be empty */ 1116 break; 1117 1118 case LDAP_COMP_FILTER_NOT: 1119 Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_NOT\n", 0, 0, 0 ); 1120 err = parse_comp_filter( op, cav, &f.cf_not, text ); 1121 if ( err != LDAP_SUCCESS ) { 1122 break; 1123 } 1124 1125 assert( f.cf_not != NULL ); 1126 if ( f.cf_not->cf_choice == SLAPD_FILTER_COMPUTED ) { 1127 int fresult = f.cf_not->cf_result; 1128 f.cf_choice = SLAPD_FILTER_COMPUTED; 1129 op->o_tmpfree( f.cf_not, op->o_tmpmemctx ); 1130 f.cf_not = NULL; 1131 1132 switch ( fresult ) { 1133 case LDAP_COMPARE_TRUE: 1134 f.cf_result = LDAP_COMPARE_FALSE; 1135 break; 1136 case LDAP_COMPARE_FALSE: 1137 f.cf_result = LDAP_COMPARE_TRUE; 1138 break; 1139 default: ; 1140 /* (!Undefined) is Undefined */ 1141 } 1142 } 1143 break; 1144 1145 case LDAP_COMP_FILTER_ITEM: 1146 Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_ITEM\n", 0, 0, 0 ); 1147 err = get_item( op, cav, &f.cf_ca, text ); 1148 if ( err != LDAP_SUCCESS ) { 1149 break; 1150 } 1151 1152 assert( f.cf_ca != NULL ); 1153 break; 1154 1155 default: 1156 f.cf_choice = SLAPD_FILTER_COMPUTED; 1157 f.cf_result = SLAPD_COMPARE_UNDEFINED; 1158 break; 1159 } 1160 1161 if ( err != LDAP_SUCCESS && err != SLAPD_DISCONNECT ) { 1162 *text = "Component Filter Syntax Error"; 1163 return err; 1164 } 1165 1166 if ( tag != LDAP_COMP_FILTER_NOT ) 1167 strip_cav_str( cav, "}"); 1168 1169 if ( err == LDAP_SUCCESS ) { 1170 if ( op ) { 1171 *filt = op->o_tmpalloc( sizeof(f), op->o_tmpmemctx ); 1172 } else { 1173 *filt = malloc( sizeof(f) ); 1174 } 1175 **filt = f; 1176 } 1177 1178 return( err ); 1179 } 1180 1181 static int 1182 test_comp_filter_and( 1183 Syntax *syn, 1184 ComponentSyntaxInfo *a, 1185 ComponentFilter *flist ) 1186 { 1187 ComponentFilter *f; 1188 int rtn = LDAP_COMPARE_TRUE; 1189 1190 for ( f = flist ; f != NULL; f = f->cf_next ) { 1191 int rc = test_comp_filter( syn, a, f ); 1192 if ( rc == LDAP_COMPARE_FALSE ) { 1193 rtn = rc; 1194 break; 1195 } 1196 1197 if ( rc != LDAP_COMPARE_TRUE ) { 1198 rtn = rc; 1199 } 1200 } 1201 1202 return rtn; 1203 } 1204 1205 static int 1206 test_comp_filter_or( 1207 Syntax *syn, 1208 ComponentSyntaxInfo *a, 1209 ComponentFilter *flist ) 1210 { 1211 ComponentFilter *f; 1212 int rtn = LDAP_COMPARE_TRUE; 1213 1214 for ( f = flist ; f != NULL; f = f->cf_next ) { 1215 int rc = test_comp_filter( syn, a, f ); 1216 if ( rc == LDAP_COMPARE_TRUE ) { 1217 rtn = rc; 1218 break; 1219 } 1220 1221 if ( rc != LDAP_COMPARE_FALSE ) { 1222 rtn = rc; 1223 } 1224 } 1225 1226 return rtn; 1227 } 1228 1229 int 1230 csi_value_match( MatchingRule *mr, struct berval* bv_attr, 1231 struct berval* bv_assert ) 1232 { 1233 int rc; 1234 int match; 1235 1236 assert( mr != NULL ); 1237 assert( !(mr->smr_usage & SLAP_MR_COMPONENT) ); 1238 1239 if( !mr->smr_match ) return LDAP_INAPPROPRIATE_MATCHING; 1240 1241 rc = (mr->smr_match)( &match, 0, NULL /*ad->ad_type->sat_syntax*/, 1242 mr, bv_attr, bv_assert ); 1243 1244 if ( rc != LDAP_SUCCESS ) return rc; 1245 1246 return match ? LDAP_COMPARE_FALSE : LDAP_COMPARE_TRUE; 1247 } 1248 1249 /* 1250 * return codes : LDAP_COMPARE_TRUE, LDAP_COMPARE_FALSE 1251 */ 1252 static int 1253 test_comp_filter_item( 1254 Syntax *syn, 1255 ComponentSyntaxInfo *csi_attr, 1256 ComponentAssertion *ca ) 1257 { 1258 int rc; 1259 void *attr_nm, *assert_nm; 1260 1261 if ( strcmp(ca->ca_ma_rule->smr_mrule.mr_oid, 1262 OID_COMP_FILTER_MATCH ) == 0 && ca->ca_cf ) { 1263 /* componentFilterMatch inside of componentFilterMatch */ 1264 rc = test_comp_filter( syn, csi_attr, ca->ca_cf ); 1265 return rc; 1266 } 1267 1268 /* Memory for storing will-be-extracted attribute values */ 1269 attr_nm = nibble_mem_allocator ( 1024*4 , 1024 ); 1270 if ( !attr_nm ) return LDAP_PROTOCOL_ERROR; 1271 1272 /* Memory for storing component assertion values */ 1273 if( !ca->ca_comp_data.cd_mem_op ) { 1274 assert_nm = nibble_mem_allocator ( 256, 64 ); 1275 if ( !assert_nm ) { 1276 nibble_mem_free ( attr_nm ); 1277 return LDAP_PROTOCOL_ERROR; 1278 } 1279 ca->ca_comp_data.cd_mem_op = assert_nm; 1280 1281 } else { 1282 assert_nm = ca->ca_comp_data.cd_mem_op; 1283 } 1284 1285 /* component reference initialization */ 1286 if ( ca->ca_comp_ref ) { 1287 ca->ca_comp_ref->cr_curr = ca->ca_comp_ref->cr_list; 1288 } 1289 rc = test_components( attr_nm, assert_nm, csi_attr, ca ); 1290 1291 /* free memory used for storing extracted attribute value */ 1292 nibble_mem_free ( attr_nm ); 1293 return rc; 1294 } 1295 1296 static int 1297 test_comp_filter( 1298 Syntax *syn, 1299 ComponentSyntaxInfo *a, 1300 ComponentFilter *f ) 1301 { 1302 int rc; 1303 1304 if ( !f ) return LDAP_PROTOCOL_ERROR; 1305 1306 Debug( LDAP_DEBUG_FILTER, "test_comp_filter\n", 0, 0, 0 ); 1307 switch ( f->cf_choice ) { 1308 case SLAPD_FILTER_COMPUTED: 1309 rc = f->cf_result; 1310 break; 1311 case LDAP_COMP_FILTER_AND: 1312 rc = test_comp_filter_and( syn, a, f->cf_and ); 1313 break; 1314 case LDAP_COMP_FILTER_OR: 1315 rc = test_comp_filter_or( syn, a, f->cf_or ); 1316 break; 1317 case LDAP_COMP_FILTER_NOT: 1318 rc = test_comp_filter( syn, a, f->cf_not ); 1319 1320 switch ( rc ) { 1321 case LDAP_COMPARE_TRUE: 1322 rc = LDAP_COMPARE_FALSE; 1323 break; 1324 case LDAP_COMPARE_FALSE: 1325 rc = LDAP_COMPARE_TRUE; 1326 break; 1327 } 1328 break; 1329 case LDAP_COMP_FILTER_ITEM: 1330 rc = test_comp_filter_item( syn, a, f->cf_ca ); 1331 break; 1332 default: 1333 rc = LDAP_PROTOCOL_ERROR; 1334 } 1335 1336 return( rc ); 1337 } 1338 1339 static void 1340 free_comp_filter_list( ComponentFilter* f ) 1341 { 1342 ComponentFilter* tmp; 1343 for ( tmp = f; tmp; tmp = tmp->cf_next ) { 1344 free_comp_filter( tmp ); 1345 } 1346 } 1347 1348 static void 1349 free_comp_filter( ComponentFilter* f ) 1350 { 1351 if ( !f ) { 1352 Debug( LDAP_DEBUG_FILTER, 1353 "free_comp_filter: Invalid filter so failed to release memory\n", 1354 0, 0, 0 ); 1355 return; 1356 } 1357 switch ( f->cf_choice ) { 1358 case LDAP_COMP_FILTER_AND: 1359 case LDAP_COMP_FILTER_OR: 1360 free_comp_filter_list( f->cf_any ); 1361 break; 1362 case LDAP_COMP_FILTER_NOT: 1363 free_comp_filter( f->cf_any ); 1364 break; 1365 case LDAP_COMP_FILTER_ITEM: 1366 if ( nibble_mem_free && f->cf_ca->ca_comp_data.cd_mem_op ) { 1367 nibble_mem_free( f->cf_ca->ca_comp_data.cd_mem_op ); 1368 } 1369 break; 1370 default: 1371 break; 1372 } 1373 } 1374 1375 void 1376 component_free( ComponentFilter *f ) { 1377 free_comp_filter( f ); 1378 } 1379 1380 void 1381 free_ComponentData( Attribute *a ) { 1382 if ( a->a_comp_data->cd_mem_op ) 1383 component_destructor( a->a_comp_data->cd_mem_op ); 1384 free ( a->a_comp_data ); 1385 a->a_comp_data = NULL; 1386 } 1387 #endif 1388