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