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