1 /* $NetBSD: filter.c,v 1.1.1.3 2010/12/12 15:22:30 adam Exp $ */ 2 3 /* filter.c - routines for parsing and dealing with filters */ 4 /* OpenLDAP: pkg/ldap/servers/slapd/filter.c,v 1.134.2.18 2010/04/13 20:23:14 kurt Exp */ 5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 6 * 7 * Copyright 1998-2010 The OpenLDAP Foundation. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted only as authorized by the OpenLDAP 12 * Public License. 13 * 14 * A copy of this license is available in the file LICENSE in the 15 * top-level directory of the distribution or, alternatively, at 16 * <http://www.OpenLDAP.org/license.html>. 17 */ 18 /* Portions Copyright (c) 1995 Regents of the University of Michigan. 19 * All rights reserved. 20 * 21 * Redistribution and use in source and binary forms are permitted 22 * provided that this notice is preserved and that due credit is given 23 * to the University of Michigan at Ann Arbor. The name of the University 24 * may not be used to endorse or promote products derived from this 25 * software without specific prior written permission. This software 26 * is provided ``as is'' without express or implied warranty. 27 */ 28 29 #include "portable.h" 30 31 #include <stdio.h> 32 33 #include <ac/socket.h> 34 #include <ac/string.h> 35 36 #include "slap.h" 37 #include "lutil.h" 38 39 const Filter *slap_filter_objectClass_pres; 40 const struct berval *slap_filterstr_objectClass_pres; 41 42 static int get_filter_list( 43 Operation *op, 44 BerElement *ber, 45 Filter **f, 46 const char **text ); 47 48 static int get_ssa( 49 Operation *op, 50 BerElement *ber, 51 Filter *f, 52 const char **text ); 53 54 static void simple_vrFilter2bv( 55 Operation *op, 56 ValuesReturnFilter *f, 57 struct berval *fstr ); 58 59 static int get_simple_vrFilter( 60 Operation *op, 61 BerElement *ber, 62 ValuesReturnFilter **f, 63 const char **text ); 64 65 int 66 filter_init( void ) 67 { 68 static Filter filter_objectClass_pres = { LDAP_FILTER_PRESENT }; 69 static struct berval filterstr_objectClass_pres = BER_BVC("(objectClass=*)"); 70 71 filter_objectClass_pres.f_desc = slap_schema.si_ad_objectClass; 72 73 slap_filter_objectClass_pres = &filter_objectClass_pres; 74 slap_filterstr_objectClass_pres = &filterstr_objectClass_pres; 75 76 return 0; 77 } 78 79 void 80 filter_destroy( void ) 81 { 82 return; 83 } 84 85 int 86 get_filter( 87 Operation *op, 88 BerElement *ber, 89 Filter **filt, 90 const char **text ) 91 { 92 ber_tag_t tag; 93 ber_len_t len; 94 int err; 95 Filter f; 96 97 Debug( LDAP_DEBUG_FILTER, "begin get_filter\n", 0, 0, 0 ); 98 /* 99 * A filter looks like this coming in: 100 * Filter ::= CHOICE { 101 * and [0] SET OF Filter, 102 * or [1] SET OF Filter, 103 * not [2] Filter, 104 * equalityMatch [3] AttributeValueAssertion, 105 * substrings [4] SubstringFilter, 106 * greaterOrEqual [5] AttributeValueAssertion, 107 * lessOrEqual [6] AttributeValueAssertion, 108 * present [7] AttributeType, 109 * approxMatch [8] AttributeValueAssertion, 110 * extensibleMatch [9] MatchingRuleAssertion 111 * } 112 * 113 * SubstringFilter ::= SEQUENCE { 114 * type AttributeType, 115 * SEQUENCE OF CHOICE { 116 * initial [0] IA5String, 117 * any [1] IA5String, 118 * final [2] IA5String 119 * } 120 * } 121 * 122 * MatchingRuleAssertion ::= SEQUENCE { 123 * matchingRule [1] MatchingRuleId OPTIONAL, 124 * type [2] AttributeDescription OPTIONAL, 125 * matchValue [3] AssertionValue, 126 * dnAttributes [4] BOOLEAN DEFAULT FALSE 127 * } 128 * 129 */ 130 131 tag = ber_peek_tag( ber, &len ); 132 133 if( tag == LBER_ERROR ) { 134 *text = "error decoding filter"; 135 return SLAPD_DISCONNECT; 136 } 137 138 err = LDAP_SUCCESS; 139 140 f.f_next = NULL; 141 f.f_choice = tag; 142 143 switch ( f.f_choice ) { 144 case LDAP_FILTER_EQUALITY: 145 Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 ); 146 err = get_ava( op, ber, &f, SLAP_MR_EQUALITY, text ); 147 if ( err != LDAP_SUCCESS ) { 148 break; 149 } 150 151 assert( f.f_ava != NULL ); 152 break; 153 154 case LDAP_FILTER_SUBSTRINGS: 155 Debug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n", 0, 0, 0 ); 156 err = get_ssa( op, ber, &f, text ); 157 if( err != LDAP_SUCCESS ) { 158 break; 159 } 160 assert( f.f_sub != NULL ); 161 break; 162 163 case LDAP_FILTER_GE: 164 Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 ); 165 err = get_ava( op, ber, &f, SLAP_MR_ORDERING, text ); 166 if ( err != LDAP_SUCCESS ) { 167 break; 168 } 169 assert( f.f_ava != NULL ); 170 break; 171 172 case LDAP_FILTER_LE: 173 Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 ); 174 err = get_ava( op, ber, &f, SLAP_MR_ORDERING, text ); 175 if ( err != LDAP_SUCCESS ) { 176 break; 177 } 178 assert( f.f_ava != NULL ); 179 break; 180 181 case LDAP_FILTER_PRESENT: { 182 struct berval type; 183 184 Debug( LDAP_DEBUG_FILTER, "PRESENT\n", 0, 0, 0 ); 185 if ( ber_scanf( ber, "m", &type ) == LBER_ERROR ) { 186 err = SLAPD_DISCONNECT; 187 *text = "error decoding filter"; 188 break; 189 } 190 191 f.f_desc = NULL; 192 err = slap_bv2ad( &type, &f.f_desc, text ); 193 194 if( err != LDAP_SUCCESS ) { 195 f.f_choice |= SLAPD_FILTER_UNDEFINED; 196 err = slap_bv2undef_ad( &type, &f.f_desc, text, 197 SLAP_AD_PROXIED|SLAP_AD_NOINSERT ); 198 199 if ( err != LDAP_SUCCESS ) { 200 /* unrecognized attribute description or other error */ 201 Debug( LDAP_DEBUG_ANY, 202 "get_filter: conn %lu unknown attribute " 203 "type=%s (%d)\n", 204 op->o_connid, type.bv_val, err ); 205 206 err = LDAP_SUCCESS; 207 f.f_desc = slap_bv2tmp_ad( &type, op->o_tmpmemctx ); 208 } 209 *text = NULL; 210 } 211 212 assert( f.f_desc != NULL ); 213 } break; 214 215 case LDAP_FILTER_APPROX: 216 Debug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 ); 217 err = get_ava( op, ber, &f, SLAP_MR_EQUALITY_APPROX, text ); 218 if ( err != LDAP_SUCCESS ) { 219 break; 220 } 221 assert( f.f_ava != NULL ); 222 break; 223 224 case LDAP_FILTER_AND: 225 Debug( LDAP_DEBUG_FILTER, "AND\n", 0, 0, 0 ); 226 err = get_filter_list( op, ber, &f.f_and, text ); 227 if ( err != LDAP_SUCCESS ) { 228 break; 229 } 230 if ( f.f_and == NULL ) { 231 f.f_choice = SLAPD_FILTER_COMPUTED; 232 f.f_result = LDAP_COMPARE_TRUE; 233 } 234 /* no assert - list could be empty */ 235 break; 236 237 case LDAP_FILTER_OR: 238 Debug( LDAP_DEBUG_FILTER, "OR\n", 0, 0, 0 ); 239 err = get_filter_list( op, ber, &f.f_or, text ); 240 if ( err != LDAP_SUCCESS ) { 241 break; 242 } 243 if ( f.f_or == NULL ) { 244 f.f_choice = SLAPD_FILTER_COMPUTED; 245 f.f_result = LDAP_COMPARE_FALSE; 246 } 247 /* no assert - list could be empty */ 248 break; 249 250 case LDAP_FILTER_NOT: 251 Debug( LDAP_DEBUG_FILTER, "NOT\n", 0, 0, 0 ); 252 (void) ber_skip_tag( ber, &len ); 253 err = get_filter( op, ber, &f.f_not, text ); 254 if ( err != LDAP_SUCCESS ) { 255 break; 256 } 257 258 assert( f.f_not != NULL ); 259 if ( f.f_not->f_choice == SLAPD_FILTER_COMPUTED ) { 260 int fresult = f.f_not->f_result; 261 f.f_choice = SLAPD_FILTER_COMPUTED; 262 op->o_tmpfree( f.f_not, op->o_tmpmemctx ); 263 f.f_not = NULL; 264 265 switch( fresult ) { 266 case LDAP_COMPARE_TRUE: 267 f.f_result = LDAP_COMPARE_FALSE; 268 break; 269 case LDAP_COMPARE_FALSE: 270 f.f_result = LDAP_COMPARE_TRUE; 271 break; 272 default: ; 273 /* (!Undefined) is Undefined */ 274 } 275 } 276 break; 277 278 case LDAP_FILTER_EXT: 279 Debug( LDAP_DEBUG_FILTER, "EXTENSIBLE\n", 0, 0, 0 ); 280 281 err = get_mra( op, ber, &f, text ); 282 if ( err != LDAP_SUCCESS ) { 283 break; 284 } 285 286 assert( f.f_mra != NULL ); 287 break; 288 289 default: 290 (void) ber_scanf( ber, "x" ); /* skip the element */ 291 Debug( LDAP_DEBUG_ANY, "get_filter: unknown filter type=%lu\n", 292 f.f_choice, 0, 0 ); 293 f.f_choice = SLAPD_FILTER_COMPUTED; 294 f.f_result = SLAPD_COMPARE_UNDEFINED; 295 break; 296 } 297 298 if( err != LDAP_SUCCESS && err != SLAPD_DISCONNECT ) { 299 /* ignore error */ 300 *text = NULL; 301 f.f_choice = SLAPD_FILTER_COMPUTED; 302 f.f_result = SLAPD_COMPARE_UNDEFINED; 303 err = LDAP_SUCCESS; 304 } 305 306 if ( err == LDAP_SUCCESS ) { 307 *filt = op->o_tmpalloc( sizeof(f), op->o_tmpmemctx ); 308 **filt = f; 309 } 310 311 Debug( LDAP_DEBUG_FILTER, "end get_filter %d\n", err, 0, 0 ); 312 313 return( err ); 314 } 315 316 static int 317 get_filter_list( Operation *op, BerElement *ber, 318 Filter **f, 319 const char **text ) 320 { 321 Filter **new; 322 int err; 323 ber_tag_t tag; 324 ber_len_t len; 325 char *last; 326 327 Debug( LDAP_DEBUG_FILTER, "begin get_filter_list\n", 0, 0, 0 ); 328 new = f; 329 for ( tag = ber_first_element( ber, &len, &last ); 330 tag != LBER_DEFAULT; 331 tag = ber_next_element( ber, &len, last ) ) 332 { 333 err = get_filter( op, ber, new, text ); 334 if ( err != LDAP_SUCCESS ) 335 return( err ); 336 new = &(*new)->f_next; 337 } 338 *new = NULL; 339 340 Debug( LDAP_DEBUG_FILTER, "end get_filter_list\n", 0, 0, 0 ); 341 return( LDAP_SUCCESS ); 342 } 343 344 static int 345 get_ssa( 346 Operation *op, 347 BerElement *ber, 348 Filter *f, 349 const char **text ) 350 { 351 ber_tag_t tag; 352 ber_len_t len; 353 int rc; 354 struct berval desc, value, nvalue; 355 char *last; 356 SubstringsAssertion ssa; 357 358 *text = "error decoding filter"; 359 360 Debug( LDAP_DEBUG_FILTER, "begin get_ssa\n", 0, 0, 0 ); 361 if ( ber_scanf( ber, "{m" /*}*/, &desc ) == LBER_ERROR ) { 362 return SLAPD_DISCONNECT; 363 } 364 365 *text = NULL; 366 367 ssa.sa_desc = NULL; 368 ssa.sa_initial.bv_val = NULL; 369 ssa.sa_any = NULL; 370 ssa.sa_final.bv_val = NULL; 371 372 rc = slap_bv2ad( &desc, &ssa.sa_desc, text ); 373 374 if( rc != LDAP_SUCCESS ) { 375 f->f_choice |= SLAPD_FILTER_UNDEFINED; 376 rc = slap_bv2undef_ad( &desc, &ssa.sa_desc, text, 377 SLAP_AD_PROXIED|SLAP_AD_NOINSERT ); 378 379 if( rc != LDAP_SUCCESS ) { 380 Debug( LDAP_DEBUG_ANY, 381 "get_ssa: conn %lu unknown attribute type=%s (%ld)\n", 382 op->o_connid, desc.bv_val, (long) rc ); 383 384 ssa.sa_desc = slap_bv2tmp_ad( &desc, op->o_tmpmemctx ); 385 } 386 } 387 388 rc = LDAP_PROTOCOL_ERROR; 389 390 /* If there is no substring matching rule, there's nothing 391 * we can do with this filter. But we continue to parse it 392 * for logging purposes. 393 */ 394 if ( ssa.sa_desc->ad_type->sat_substr == NULL ) { 395 f->f_choice |= SLAPD_FILTER_UNDEFINED; 396 Debug( LDAP_DEBUG_FILTER, 397 "get_ssa: no substring matching rule for attributeType %s\n", 398 desc.bv_val, 0, 0 ); 399 } 400 401 for ( tag = ber_first_element( ber, &len, &last ); 402 tag != LBER_DEFAULT; 403 tag = ber_next_element( ber, &len, last ) ) 404 { 405 unsigned usage; 406 407 rc = ber_scanf( ber, "m", &value ); 408 if ( rc == LBER_ERROR ) { 409 rc = SLAPD_DISCONNECT; 410 goto return_error; 411 } 412 413 if ( value.bv_val == NULL || value.bv_len == 0 ) { 414 rc = LDAP_INVALID_SYNTAX; 415 goto return_error; 416 } 417 418 switch ( tag ) { 419 case LDAP_SUBSTRING_INITIAL: 420 if ( ssa.sa_initial.bv_val != NULL 421 || ssa.sa_any != NULL 422 || ssa.sa_final.bv_val != NULL ) 423 { 424 rc = LDAP_PROTOCOL_ERROR; 425 goto return_error; 426 } 427 usage = SLAP_MR_SUBSTR_INITIAL; 428 break; 429 430 case LDAP_SUBSTRING_ANY: 431 if ( ssa.sa_final.bv_val != NULL ) { 432 rc = LDAP_PROTOCOL_ERROR; 433 goto return_error; 434 } 435 usage = SLAP_MR_SUBSTR_ANY; 436 break; 437 438 case LDAP_SUBSTRING_FINAL: 439 if ( ssa.sa_final.bv_val != NULL ) { 440 rc = LDAP_PROTOCOL_ERROR; 441 goto return_error; 442 } 443 444 usage = SLAP_MR_SUBSTR_FINAL; 445 break; 446 447 default: 448 Debug( LDAP_DEBUG_FILTER, 449 " unknown substring choice=%ld\n", 450 (long) tag, 0, 0 ); 451 452 rc = LDAP_PROTOCOL_ERROR; 453 goto return_error; 454 } 455 456 /* validate/normalize using equality matching rule validator! */ 457 rc = asserted_value_validate_normalize( 458 ssa.sa_desc, ssa.sa_desc->ad_type->sat_equality, 459 usage, &value, &nvalue, text, op->o_tmpmemctx ); 460 if( rc != LDAP_SUCCESS ) { 461 f->f_choice |= SLAPD_FILTER_UNDEFINED; 462 Debug( LDAP_DEBUG_FILTER, 463 "get_ssa: illegal value for attributeType %s (%d) %s\n", 464 desc.bv_val, rc, *text ); 465 ber_dupbv_x( &nvalue, &value, op->o_tmpmemctx ); 466 } 467 468 switch ( tag ) { 469 case LDAP_SUBSTRING_INITIAL: 470 Debug( LDAP_DEBUG_FILTER, " INITIAL\n", 0, 0, 0 ); 471 ssa.sa_initial = nvalue; 472 break; 473 474 case LDAP_SUBSTRING_ANY: 475 Debug( LDAP_DEBUG_FILTER, " ANY\n", 0, 0, 0 ); 476 ber_bvarray_add_x( &ssa.sa_any, &nvalue, op->o_tmpmemctx ); 477 break; 478 479 case LDAP_SUBSTRING_FINAL: 480 Debug( LDAP_DEBUG_FILTER, " FINAL\n", 0, 0, 0 ); 481 ssa.sa_final = nvalue; 482 break; 483 484 default: 485 assert( 0 ); 486 slap_sl_free( nvalue.bv_val, op->o_tmpmemctx ); 487 rc = LDAP_PROTOCOL_ERROR; 488 489 return_error: 490 Debug( LDAP_DEBUG_FILTER, " error=%ld\n", 491 (long) rc, 0, 0 ); 492 slap_sl_free( ssa.sa_initial.bv_val, op->o_tmpmemctx ); 493 ber_bvarray_free_x( ssa.sa_any, op->o_tmpmemctx ); 494 if ( ssa.sa_desc->ad_flags & SLAP_DESC_TEMPORARY ) 495 op->o_tmpfree( ssa.sa_desc, op->o_tmpmemctx ); 496 slap_sl_free( ssa.sa_final.bv_val, op->o_tmpmemctx ); 497 return rc; 498 } 499 500 *text = NULL; 501 rc = LDAP_SUCCESS; 502 } 503 504 if( rc == LDAP_SUCCESS ) { 505 f->f_sub = op->o_tmpalloc( sizeof( ssa ), op->o_tmpmemctx ); 506 *f->f_sub = ssa; 507 } 508 509 Debug( LDAP_DEBUG_FILTER, "end get_ssa\n", 0, 0, 0 ); 510 return rc /* LDAP_SUCCESS */ ; 511 } 512 513 void 514 filter_free_x( Operation *op, Filter *f, int freeme ) 515 { 516 Filter *p, *next; 517 518 if ( f == NULL ) { 519 return; 520 } 521 522 f->f_choice &= SLAPD_FILTER_MASK; 523 524 switch ( f->f_choice ) { 525 case LDAP_FILTER_PRESENT: 526 break; 527 528 case LDAP_FILTER_EQUALITY: 529 case LDAP_FILTER_GE: 530 case LDAP_FILTER_LE: 531 case LDAP_FILTER_APPROX: 532 ava_free( op, f->f_ava, 1 ); 533 break; 534 535 case LDAP_FILTER_SUBSTRINGS: 536 if ( f->f_sub_initial.bv_val != NULL ) { 537 op->o_tmpfree( f->f_sub_initial.bv_val, op->o_tmpmemctx ); 538 } 539 ber_bvarray_free_x( f->f_sub_any, op->o_tmpmemctx ); 540 if ( f->f_sub_final.bv_val != NULL ) { 541 op->o_tmpfree( f->f_sub_final.bv_val, op->o_tmpmemctx ); 542 } 543 if ( f->f_sub->sa_desc->ad_flags & SLAP_DESC_TEMPORARY ) 544 op->o_tmpfree( f->f_sub->sa_desc, op->o_tmpmemctx ); 545 op->o_tmpfree( f->f_sub, op->o_tmpmemctx ); 546 break; 547 548 case LDAP_FILTER_AND: 549 case LDAP_FILTER_OR: 550 case LDAP_FILTER_NOT: 551 for ( p = f->f_list; p != NULL; p = next ) { 552 next = p->f_next; 553 filter_free_x( op, p, 1 ); 554 } 555 break; 556 557 case LDAP_FILTER_EXT: 558 mra_free( op, f->f_mra, 1 ); 559 break; 560 561 case SLAPD_FILTER_COMPUTED: 562 break; 563 564 default: 565 Debug( LDAP_DEBUG_ANY, "filter_free: unknown filter type=%lu\n", 566 f->f_choice, 0, 0 ); 567 break; 568 } 569 570 if ( freeme ) { 571 op->o_tmpfree( f, op->o_tmpmemctx ); 572 } 573 } 574 575 void 576 filter_free( Filter *f ) 577 { 578 Operation op; 579 Opheader ohdr; 580 581 op.o_hdr = &ohdr; 582 op.o_tmpmemctx = slap_sl_context( f ); 583 op.o_tmpmfuncs = &slap_sl_mfuncs; 584 filter_free_x( &op, f, 1 ); 585 } 586 587 void 588 filter2bv_x( Operation *op, Filter *f, struct berval *fstr ) 589 { 590 int i; 591 Filter *p; 592 struct berval tmp, value; 593 static struct berval 594 ber_bvfalse = BER_BVC( "(?=false)" ), 595 ber_bvtrue = BER_BVC( "(?=true)" ), 596 ber_bvundefined = BER_BVC( "(?=undefined)" ), 597 ber_bverror = BER_BVC( "(?=error)" ), 598 ber_bvunknown = BER_BVC( "(?=unknown)" ), 599 ber_bvnone = BER_BVC( "(?=none)" ); 600 ber_len_t len; 601 ber_tag_t choice; 602 int undef; 603 char *sign; 604 605 if ( f == NULL ) { 606 ber_dupbv_x( fstr, &ber_bvnone, op->o_tmpmemctx ); 607 return; 608 } 609 610 undef = f->f_choice & SLAPD_FILTER_UNDEFINED; 611 choice = f->f_choice & SLAPD_FILTER_MASK; 612 613 switch ( choice ) { 614 case LDAP_FILTER_EQUALITY: 615 fstr->bv_len = STRLENOF("(=)"); 616 sign = "="; 617 goto simple; 618 case LDAP_FILTER_GE: 619 fstr->bv_len = STRLENOF("(>=)"); 620 sign = ">="; 621 goto simple; 622 case LDAP_FILTER_LE: 623 fstr->bv_len = STRLENOF("(<=)"); 624 sign = "<="; 625 goto simple; 626 case LDAP_FILTER_APPROX: 627 fstr->bv_len = STRLENOF("(~=)"); 628 sign = "~="; 629 630 simple: 631 value = f->f_av_value; 632 if ( f->f_av_desc->ad_type->sat_equality && 633 !undef && 634 ( f->f_av_desc->ad_type->sat_equality->smr_usage & SLAP_MR_MUTATION_NORMALIZER )) 635 { 636 f->f_av_desc->ad_type->sat_equality->smr_normalize( 637 (SLAP_MR_DENORMALIZE|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX), 638 NULL, NULL, &f->f_av_value, &value, op->o_tmpmemctx ); 639 } 640 641 filter_escape_value_x( &value, &tmp, op->o_tmpmemctx ); 642 /* NOTE: tmp can legitimately be NULL (meaning empty) 643 * since in a Filter values in AVAs are supposed 644 * to have been normalized, meaning that an empty value 645 * is legal for that attribute's syntax */ 646 647 fstr->bv_len += f->f_av_desc->ad_cname.bv_len + tmp.bv_len; 648 if ( undef ) 649 fstr->bv_len++; 650 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx ); 651 652 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s)", 653 undef ? "?" : "", 654 f->f_av_desc->ad_cname.bv_val, sign, 655 tmp.bv_len ? tmp.bv_val : "" ); 656 657 if ( value.bv_val != f->f_av_value.bv_val ) { 658 ber_memfree_x( value.bv_val, op->o_tmpmemctx ); 659 } 660 661 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx ); 662 break; 663 664 case LDAP_FILTER_SUBSTRINGS: 665 fstr->bv_len = f->f_sub_desc->ad_cname.bv_len + 666 STRLENOF("(=*)"); 667 if ( undef ) 668 fstr->bv_len++; 669 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 128, op->o_tmpmemctx ); 670 671 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s=*)", 672 undef ? "?" : "", 673 f->f_sub_desc->ad_cname.bv_val ); 674 675 if ( f->f_sub_initial.bv_val != NULL ) { 676 ber_len_t tmplen; 677 678 len = fstr->bv_len; 679 680 filter_escape_value_x( &f->f_sub_initial, &tmp, op->o_tmpmemctx ); 681 tmplen = tmp.bv_len; 682 683 fstr->bv_len += tmplen; 684 fstr->bv_val = op->o_tmprealloc( fstr->bv_val, 685 fstr->bv_len + 1, op->o_tmpmemctx ); 686 687 snprintf( &fstr->bv_val[len - 2], 688 tmplen + STRLENOF( /*(*/ "*)" ) + 1, 689 /* "(attr=" */ "%s*)", 690 tmp.bv_len ? tmp.bv_val : ""); 691 692 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx ); 693 } 694 695 if ( f->f_sub_any != NULL ) { 696 for ( i = 0; f->f_sub_any[i].bv_val != NULL; i++ ) { 697 ber_len_t tmplen; 698 699 len = fstr->bv_len; 700 filter_escape_value_x( &f->f_sub_any[i], 701 &tmp, op->o_tmpmemctx ); 702 tmplen = tmp.bv_len; 703 704 fstr->bv_len += tmplen + STRLENOF( /*(*/ ")" ); 705 fstr->bv_val = op->o_tmprealloc( fstr->bv_val, 706 fstr->bv_len + 1, op->o_tmpmemctx ); 707 708 snprintf( &fstr->bv_val[len - 1], 709 tmplen + STRLENOF( /*(*/ "*)" ) + 1, 710 /* "(attr=[init]*[any*]" */ "%s*)", 711 tmp.bv_len ? tmp.bv_val : ""); 712 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx ); 713 } 714 } 715 716 if ( f->f_sub_final.bv_val != NULL ) { 717 ber_len_t tmplen; 718 719 len = fstr->bv_len; 720 721 filter_escape_value_x( &f->f_sub_final, &tmp, op->o_tmpmemctx ); 722 tmplen = tmp.bv_len; 723 724 fstr->bv_len += tmplen; 725 fstr->bv_val = op->o_tmprealloc( fstr->bv_val, 726 fstr->bv_len + 1, op->o_tmpmemctx ); 727 728 snprintf( &fstr->bv_val[len - 1], 729 tmplen + STRLENOF( /*(*/ ")" ) + 1, 730 /* "(attr=[init*][any*]" */ "%s)", 731 tmp.bv_len ? tmp.bv_val : ""); 732 733 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx ); 734 } 735 736 break; 737 738 case LDAP_FILTER_PRESENT: 739 fstr->bv_len = f->f_desc->ad_cname.bv_len + 740 STRLENOF("(=*)"); 741 if ( undef ) 742 fstr->bv_len++; 743 744 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx ); 745 746 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s=*)", 747 undef ? "?" : "", 748 f->f_desc->ad_cname.bv_val ); 749 break; 750 751 case LDAP_FILTER_AND: 752 case LDAP_FILTER_OR: 753 case LDAP_FILTER_NOT: 754 fstr->bv_len = STRLENOF("(%)"); 755 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 128, op->o_tmpmemctx ); 756 757 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%c)", 758 f->f_choice == LDAP_FILTER_AND ? '&' : 759 f->f_choice == LDAP_FILTER_OR ? '|' : '!' ); 760 761 for ( p = f->f_list; p != NULL; p = p->f_next ) { 762 len = fstr->bv_len; 763 764 filter2bv_x( op, p, &tmp ); 765 766 fstr->bv_len += tmp.bv_len; 767 fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, 768 op->o_tmpmemctx ); 769 770 snprintf( &fstr->bv_val[len-1], 771 tmp.bv_len + STRLENOF( /*(*/ ")" ) + 1, 772 /*"("*/ "%s)", tmp.bv_val ); 773 774 op->o_tmpfree( tmp.bv_val, op->o_tmpmemctx ); 775 } 776 777 break; 778 779 case LDAP_FILTER_EXT: { 780 struct berval ad; 781 782 filter_escape_value_x( &f->f_mr_value, &tmp, op->o_tmpmemctx ); 783 /* NOTE: tmp can legitimately be NULL (meaning empty) 784 * since in a Filter values in MRAs are supposed 785 * to have been normalized, meaning that an empty value 786 * is legal for that attribute's syntax */ 787 788 if ( f->f_mr_desc ) { 789 ad = f->f_mr_desc->ad_cname; 790 } else { 791 ad.bv_len = 0; 792 ad.bv_val = ""; 793 } 794 795 fstr->bv_len = ad.bv_len + 796 ( f->f_mr_dnattrs ? STRLENOF(":dn") : 0 ) + 797 ( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len+1 : 0 ) + 798 tmp.bv_len + STRLENOF("(:=)"); 799 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx ); 800 801 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s%s:=%s)", 802 undef ? "?" : "", 803 ad.bv_val, 804 f->f_mr_dnattrs ? ":dn" : "", 805 f->f_mr_rule_text.bv_len ? ":" : "", 806 f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_val : "", 807 tmp.bv_len ? tmp.bv_val : "" ); 808 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx ); 809 } break; 810 811 case SLAPD_FILTER_COMPUTED: 812 switch ( f->f_result ) { 813 case LDAP_COMPARE_FALSE: 814 tmp = ber_bvfalse; 815 break; 816 817 case LDAP_COMPARE_TRUE: 818 tmp = ber_bvtrue; 819 break; 820 821 case SLAPD_COMPARE_UNDEFINED: 822 tmp = ber_bvundefined; 823 break; 824 825 default: 826 tmp = ber_bverror; 827 break; 828 } 829 830 ber_dupbv_x( fstr, &tmp, op->o_tmpmemctx ); 831 break; 832 833 default: 834 ber_dupbv_x( fstr, &ber_bvunknown, op->o_tmpmemctx ); 835 break; 836 } 837 } 838 839 void 840 filter2bv( Filter *f, struct berval *fstr ) 841 { 842 Operation op; 843 Opheader ohdr; 844 845 op.o_hdr = &ohdr; 846 op.o_tmpmemctx = NULL; 847 op.o_tmpmfuncs = &ch_mfuncs; 848 849 filter2bv_x( &op, f, fstr ); 850 } 851 852 Filter * 853 filter_dup( Filter *f, void *memctx ) 854 { 855 BerMemoryFunctions *mf = &slap_sl_mfuncs; 856 Filter *n; 857 858 if ( !f ) 859 return NULL; 860 861 n = mf->bmf_malloc( sizeof(Filter), memctx ); 862 n->f_choice = f->f_choice; 863 n->f_next = NULL; 864 865 switch( f->f_choice & SLAPD_FILTER_MASK ) { 866 case SLAPD_FILTER_COMPUTED: 867 n->f_result = f->f_result; 868 break; 869 case LDAP_FILTER_PRESENT: 870 if ( f->f_desc->ad_flags & SLAP_DESC_TEMPORARY ) 871 n->f_desc = slap_bv2tmp_ad( &f->f_desc->ad_cname, memctx ); 872 else 873 n->f_desc = f->f_desc; 874 break; 875 case LDAP_FILTER_EQUALITY: 876 case LDAP_FILTER_GE: 877 case LDAP_FILTER_LE: 878 case LDAP_FILTER_APPROX: 879 /* Should this be ava_dup() ? */ 880 n->f_ava = mf->bmf_calloc( 1, sizeof(AttributeAssertion), memctx ); 881 *n->f_ava = *f->f_ava; 882 if ( f->f_av_desc->ad_flags & SLAP_DESC_TEMPORARY ) 883 n->f_av_desc = slap_bv2tmp_ad( &f->f_av_desc->ad_cname, memctx ); 884 ber_dupbv_x( &n->f_av_value, &f->f_av_value, memctx ); 885 break; 886 case LDAP_FILTER_SUBSTRINGS: 887 n->f_sub = mf->bmf_calloc( 1, sizeof(SubstringsAssertion), memctx ); 888 if ( f->f_sub_desc->ad_flags & SLAP_DESC_TEMPORARY ) 889 n->f_sub_desc = slap_bv2tmp_ad( &f->f_sub_desc->ad_cname, memctx ); 890 else 891 n->f_sub_desc = f->f_sub_desc; 892 if ( !BER_BVISNULL( &f->f_sub_initial )) 893 ber_dupbv_x( &n->f_sub_initial, &f->f_sub_initial, memctx ); 894 if ( f->f_sub_any ) { 895 int i; 896 for ( i = 0; !BER_BVISNULL( &f->f_sub_any[i] ); i++ ); 897 n->f_sub_any = mf->bmf_malloc(( i+1 )*sizeof( struct berval ), 898 memctx ); 899 for ( i = 0; !BER_BVISNULL( &f->f_sub_any[i] ); i++ ) { 900 ber_dupbv_x( &n->f_sub_any[i], &f->f_sub_any[i], memctx ); 901 } 902 BER_BVZERO( &n->f_sub_any[i] ); 903 } 904 if ( !BER_BVISNULL( &f->f_sub_final )) 905 ber_dupbv_x( &n->f_sub_final, &f->f_sub_final, memctx ); 906 break; 907 case LDAP_FILTER_EXT: { 908 /* Should this be mra_dup() ? */ 909 ber_len_t length; 910 length = sizeof(MatchingRuleAssertion); 911 if ( !BER_BVISNULL( &f->f_mr_rule_text )) 912 length += f->f_mr_rule_text.bv_len + 1; 913 n->f_mra = mf->bmf_calloc( 1, length, memctx ); 914 *n->f_mra = *f->f_mra; 915 if ( f->f_mr_desc && ( f->f_sub_desc->ad_flags & SLAP_DESC_TEMPORARY )) 916 n->f_mr_desc = slap_bv2tmp_ad( &f->f_mr_desc->ad_cname, memctx ); 917 ber_dupbv_x( &n->f_mr_value, &f->f_mr_value, memctx ); 918 if ( !BER_BVISNULL( &f->f_mr_rule_text )) { 919 n->f_mr_rule_text.bv_val = (char *)(n->f_mra+1); 920 AC_MEMCPY(n->f_mr_rule_text.bv_val, 921 f->f_mr_rule_text.bv_val, f->f_mr_rule_text.bv_len ); 922 } 923 } break; 924 case LDAP_FILTER_AND: 925 case LDAP_FILTER_OR: 926 case LDAP_FILTER_NOT: { 927 Filter **p; 928 for ( p = &n->f_list, f = f->f_list; f; f = f->f_next ) { 929 *p = filter_dup( f, memctx ); 930 p = &(*p)->f_next; 931 } 932 } break; 933 } 934 return n; 935 } 936 937 static int 938 get_simple_vrFilter( 939 Operation *op, 940 BerElement *ber, 941 ValuesReturnFilter **filt, 942 const char **text ) 943 { 944 ber_tag_t tag; 945 ber_len_t len; 946 int err; 947 ValuesReturnFilter vrf; 948 949 Debug( LDAP_DEBUG_FILTER, "begin get_simple_vrFilter\n", 0, 0, 0 ); 950 951 tag = ber_peek_tag( ber, &len ); 952 953 if( tag == LBER_ERROR ) { 954 *text = "error decoding filter"; 955 return SLAPD_DISCONNECT; 956 } 957 958 vrf.vrf_next = NULL; 959 960 err = LDAP_SUCCESS; 961 vrf.vrf_choice = tag; 962 963 switch ( vrf.vrf_choice ) { 964 case LDAP_FILTER_EQUALITY: 965 Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 ); 966 err = get_ava( op, ber, (Filter *)&vrf, SLAP_MR_EQUALITY, text ); 967 if ( err != LDAP_SUCCESS ) { 968 break; 969 } 970 971 assert( vrf.vrf_ava != NULL ); 972 break; 973 974 case LDAP_FILTER_SUBSTRINGS: 975 Debug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n", 0, 0, 0 ); 976 err = get_ssa( op, ber, (Filter *)&vrf, text ); 977 break; 978 979 case LDAP_FILTER_GE: 980 Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 ); 981 err = get_ava( op, ber, (Filter *)&vrf, SLAP_MR_ORDERING, text ); 982 if ( err != LDAP_SUCCESS ) { 983 break; 984 } 985 break; 986 987 case LDAP_FILTER_LE: 988 Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 ); 989 err = get_ava( op, ber, (Filter *)&vrf, SLAP_MR_ORDERING, text ); 990 if ( err != LDAP_SUCCESS ) { 991 break; 992 } 993 break; 994 995 case LDAP_FILTER_PRESENT: { 996 struct berval type; 997 998 Debug( LDAP_DEBUG_FILTER, "PRESENT\n", 0, 0, 0 ); 999 if ( ber_scanf( ber, "m", &type ) == LBER_ERROR ) { 1000 err = SLAPD_DISCONNECT; 1001 *text = "error decoding filter"; 1002 break; 1003 } 1004 1005 vrf.vrf_desc = NULL; 1006 err = slap_bv2ad( &type, &vrf.vrf_desc, text ); 1007 1008 if( err != LDAP_SUCCESS ) { 1009 vrf.vrf_choice |= SLAPD_FILTER_UNDEFINED; 1010 err = slap_bv2undef_ad( &type, &vrf.vrf_desc, text, 1011 SLAP_AD_PROXIED); 1012 1013 if( err != LDAP_SUCCESS ) { 1014 /* unrecognized attribute description or other error */ 1015 Debug( LDAP_DEBUG_ANY, 1016 "get_simple_vrFilter: conn %lu unknown " 1017 "attribute type=%s (%d)\n", 1018 op->o_connid, type.bv_val, err ); 1019 1020 vrf.vrf_choice = SLAPD_FILTER_COMPUTED; 1021 vrf.vrf_result = LDAP_COMPARE_FALSE; 1022 err = LDAP_SUCCESS; 1023 break; 1024 } 1025 } 1026 } break; 1027 1028 case LDAP_FILTER_APPROX: 1029 Debug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 ); 1030 err = get_ava( op, ber, (Filter *)&vrf, SLAP_MR_EQUALITY_APPROX, text ); 1031 if ( err != LDAP_SUCCESS ) { 1032 break; 1033 } 1034 break; 1035 1036 case LDAP_FILTER_EXT: 1037 Debug( LDAP_DEBUG_FILTER, "EXTENSIBLE\n", 0, 0, 0 ); 1038 1039 err = get_mra( op, ber, (Filter *)&vrf, text ); 1040 if ( err != LDAP_SUCCESS ) { 1041 break; 1042 } 1043 1044 assert( vrf.vrf_mra != NULL ); 1045 break; 1046 1047 default: 1048 (void) ber_scanf( ber, "x" ); /* skip the element */ 1049 Debug( LDAP_DEBUG_ANY, "get_simple_vrFilter: unknown filter type=%lu\n", 1050 vrf.vrf_choice, 0, 0 ); 1051 vrf.vrf_choice = SLAPD_FILTER_COMPUTED; 1052 vrf.vrf_result = SLAPD_COMPARE_UNDEFINED; 1053 break; 1054 } 1055 1056 if ( err != LDAP_SUCCESS && err != SLAPD_DISCONNECT ) { 1057 /* ignore error */ 1058 vrf.vrf_choice = SLAPD_FILTER_COMPUTED; 1059 vrf.vrf_result = SLAPD_COMPARE_UNDEFINED; 1060 err = LDAP_SUCCESS; 1061 } 1062 1063 if ( err == LDAP_SUCCESS ) { 1064 *filt = op->o_tmpalloc( sizeof vrf, op->o_tmpmemctx ); 1065 **filt = vrf; 1066 } 1067 1068 Debug( LDAP_DEBUG_FILTER, "end get_simple_vrFilter %d\n", err, 0, 0 ); 1069 1070 return err; 1071 } 1072 1073 int 1074 get_vrFilter( Operation *op, BerElement *ber, 1075 ValuesReturnFilter **vrf, 1076 const char **text ) 1077 { 1078 /* 1079 * A ValuesReturnFilter looks like this: 1080 * 1081 * ValuesReturnFilter ::= SEQUENCE OF SimpleFilterItem 1082 * SimpleFilterItem ::= CHOICE { 1083 * equalityMatch [3] AttributeValueAssertion, 1084 * substrings [4] SubstringFilter, 1085 * greaterOrEqual [5] AttributeValueAssertion, 1086 * lessOrEqual [6] AttributeValueAssertion, 1087 * present [7] AttributeType, 1088 * approxMatch [8] AttributeValueAssertion, 1089 * extensibleMatch [9] SimpleMatchingAssertion -- LDAPv3 1090 * } 1091 * 1092 * SubstringFilter ::= SEQUENCE { 1093 * type AttributeType, 1094 * SEQUENCE OF CHOICE { 1095 * initial [0] IA5String, 1096 * any [1] IA5String, 1097 * final [2] IA5String 1098 * } 1099 * } 1100 * 1101 * SimpleMatchingAssertion ::= SEQUENCE { -- LDAPv3 1102 * matchingRule [1] MatchingRuleId OPTIONAL, 1103 * type [2] AttributeDescription OPTIONAL, 1104 * matchValue [3] AssertionValue } 1105 */ 1106 1107 ValuesReturnFilter **n; 1108 ber_tag_t tag; 1109 ber_len_t len; 1110 char *last; 1111 1112 Debug( LDAP_DEBUG_FILTER, "begin get_vrFilter\n", 0, 0, 0 ); 1113 1114 tag = ber_peek_tag( ber, &len ); 1115 1116 if( tag == LBER_ERROR ) { 1117 *text = "error decoding vrFilter"; 1118 return SLAPD_DISCONNECT; 1119 } 1120 1121 if( tag != LBER_SEQUENCE ) { 1122 *text = "error decoding vrFilter, expect SEQUENCE tag"; 1123 return SLAPD_DISCONNECT; 1124 } 1125 1126 n = vrf; 1127 for ( tag = ber_first_element( ber, &len, &last ); 1128 tag != LBER_DEFAULT; 1129 tag = ber_next_element( ber, &len, last ) ) 1130 { 1131 int err = get_simple_vrFilter( op, ber, n, text ); 1132 1133 if ( err != LDAP_SUCCESS ) return( err ); 1134 1135 n = &(*n)->vrf_next; 1136 } 1137 *n = NULL; 1138 1139 Debug( LDAP_DEBUG_FILTER, "end get_vrFilter\n", 0, 0, 0 ); 1140 return( LDAP_SUCCESS ); 1141 } 1142 1143 void 1144 vrFilter_free( Operation *op, ValuesReturnFilter *vrf ) 1145 { 1146 ValuesReturnFilter *p, *next; 1147 1148 if ( vrf == NULL ) { 1149 return; 1150 } 1151 1152 for ( p = vrf; p != NULL; p = next ) { 1153 next = p->vrf_next; 1154 1155 switch ( vrf->vrf_choice & SLAPD_FILTER_MASK ) { 1156 case LDAP_FILTER_PRESENT: 1157 break; 1158 1159 case LDAP_FILTER_EQUALITY: 1160 case LDAP_FILTER_GE: 1161 case LDAP_FILTER_LE: 1162 case LDAP_FILTER_APPROX: 1163 ava_free( op, vrf->vrf_ava, 1 ); 1164 break; 1165 1166 case LDAP_FILTER_SUBSTRINGS: 1167 if ( vrf->vrf_sub_initial.bv_val != NULL ) { 1168 op->o_tmpfree( vrf->vrf_sub_initial.bv_val, op->o_tmpmemctx ); 1169 } 1170 ber_bvarray_free_x( vrf->vrf_sub_any, op->o_tmpmemctx ); 1171 if ( vrf->vrf_sub_final.bv_val != NULL ) { 1172 op->o_tmpfree( vrf->vrf_sub_final.bv_val, op->o_tmpmemctx ); 1173 } 1174 op->o_tmpfree( vrf->vrf_sub, op->o_tmpmemctx ); 1175 break; 1176 1177 case LDAP_FILTER_EXT: 1178 mra_free( op, vrf->vrf_mra, 1 ); 1179 break; 1180 1181 case SLAPD_FILTER_COMPUTED: 1182 break; 1183 1184 default: 1185 Debug( LDAP_DEBUG_ANY, "filter_free: unknown filter type=%lu\n", 1186 vrf->vrf_choice, 0, 0 ); 1187 break; 1188 } 1189 1190 op->o_tmpfree( vrf, op->o_tmpmemctx ); 1191 } 1192 } 1193 1194 void 1195 vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr ) 1196 { 1197 ValuesReturnFilter *p; 1198 struct berval tmp; 1199 ber_len_t len; 1200 1201 if ( vrf == NULL ) { 1202 ber_str2bv_x( "No filter!", STRLENOF("No filter!"), 1203 1, fstr, op->o_tmpmemctx ); 1204 return; 1205 } 1206 1207 fstr->bv_len = STRLENOF("()"); 1208 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 128, op->o_tmpmemctx ); 1209 1210 snprintf( fstr->bv_val, fstr->bv_len + 1, "()"); 1211 1212 for ( p = vrf; p != NULL; p = p->vrf_next ) { 1213 len = fstr->bv_len; 1214 1215 simple_vrFilter2bv( op, p, &tmp ); 1216 1217 fstr->bv_len += tmp.bv_len; 1218 fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, 1219 op->o_tmpmemctx ); 1220 1221 snprintf( &fstr->bv_val[len-1], tmp.bv_len + 2, 1222 /*"("*/ "%s)", tmp.bv_val ); 1223 1224 op->o_tmpfree( tmp.bv_val, op->o_tmpmemctx ); 1225 } 1226 } 1227 1228 static void 1229 simple_vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr ) 1230 { 1231 struct berval tmp; 1232 ber_len_t len; 1233 int undef; 1234 1235 if ( vrf == NULL ) { 1236 ber_str2bv_x( "No filter!", STRLENOF("No filter!"), 1, fstr, 1237 op->o_tmpmemctx ); 1238 return; 1239 } 1240 undef = vrf->vrf_choice & SLAPD_FILTER_UNDEFINED; 1241 1242 switch ( vrf->vrf_choice & SLAPD_FILTER_MASK ) { 1243 case LDAP_FILTER_EQUALITY: 1244 filter_escape_value_x( &vrf->vrf_av_value, &tmp, op->o_tmpmemctx ); 1245 1246 fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len + 1247 tmp.bv_len + STRLENOF("(=)"); 1248 if ( undef ) fstr->bv_len++; 1249 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx ); 1250 1251 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=%s)", 1252 vrf->vrf_av_desc->ad_cname.bv_val, 1253 tmp.bv_val ); 1254 1255 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx ); 1256 break; 1257 1258 case LDAP_FILTER_GE: 1259 filter_escape_value_x( &vrf->vrf_av_value, &tmp, op->o_tmpmemctx ); 1260 1261 fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len + 1262 tmp.bv_len + STRLENOF("(>=)"); 1263 if ( undef ) fstr->bv_len++; 1264 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx ); 1265 1266 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s>=%s)", 1267 vrf->vrf_av_desc->ad_cname.bv_val, 1268 tmp.bv_val ); 1269 1270 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx ); 1271 break; 1272 1273 case LDAP_FILTER_LE: 1274 filter_escape_value_x( &vrf->vrf_av_value, &tmp, op->o_tmpmemctx ); 1275 1276 fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len + 1277 tmp.bv_len + STRLENOF("(<=)"); 1278 if ( undef ) fstr->bv_len++; 1279 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx ); 1280 1281 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s<=%s)", 1282 vrf->vrf_av_desc->ad_cname.bv_val, 1283 tmp.bv_val ); 1284 1285 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx ); 1286 break; 1287 1288 case LDAP_FILTER_APPROX: 1289 filter_escape_value_x( &vrf->vrf_av_value, &tmp, op->o_tmpmemctx ); 1290 1291 fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len + 1292 tmp.bv_len + STRLENOF("(~=)"); 1293 if ( undef ) fstr->bv_len++; 1294 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx ); 1295 1296 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s~=%s)", 1297 vrf->vrf_av_desc->ad_cname.bv_val, 1298 tmp.bv_val ); 1299 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx ); 1300 break; 1301 1302 case LDAP_FILTER_SUBSTRINGS: 1303 fstr->bv_len = vrf->vrf_sub_desc->ad_cname.bv_len + 1304 STRLENOF("(=*)"); 1305 if ( undef ) fstr->bv_len++; 1306 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 128, op->o_tmpmemctx ); 1307 1308 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)", 1309 vrf->vrf_sub_desc->ad_cname.bv_val ); 1310 1311 if ( vrf->vrf_sub_initial.bv_val != NULL ) { 1312 len = fstr->bv_len; 1313 1314 filter_escape_value_x( &vrf->vrf_sub_initial, &tmp, op->o_tmpmemctx ); 1315 1316 fstr->bv_len += tmp.bv_len; 1317 fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, 1318 op->o_tmpmemctx ); 1319 1320 snprintf( &fstr->bv_val[len-2], tmp.bv_len+3, 1321 /* "(attr=" */ "%s*)", 1322 tmp.bv_val ); 1323 1324 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx ); 1325 } 1326 1327 if ( vrf->vrf_sub_any != NULL ) { 1328 int i; 1329 for ( i = 0; vrf->vrf_sub_any[i].bv_val != NULL; i++ ) { 1330 len = fstr->bv_len; 1331 filter_escape_value_x( &vrf->vrf_sub_any[i], &tmp, 1332 op->o_tmpmemctx ); 1333 1334 fstr->bv_len += tmp.bv_len + 1; 1335 fstr->bv_val = op->o_tmprealloc( fstr->bv_val, 1336 fstr->bv_len + 1, op->o_tmpmemctx ); 1337 1338 snprintf( &fstr->bv_val[len-1], tmp.bv_len+3, 1339 /* "(attr=[init]*[any*]" */ "%s*)", 1340 tmp.bv_val ); 1341 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx ); 1342 } 1343 } 1344 1345 if ( vrf->vrf_sub_final.bv_val != NULL ) { 1346 len = fstr->bv_len; 1347 1348 filter_escape_value_x( &vrf->vrf_sub_final, &tmp, op->o_tmpmemctx ); 1349 1350 fstr->bv_len += tmp.bv_len; 1351 fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, 1352 op->o_tmpmemctx ); 1353 1354 snprintf( &fstr->bv_val[len-1], tmp.bv_len+3, 1355 /* "(attr=[init*][any*]" */ "%s)", 1356 tmp.bv_val ); 1357 1358 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx ); 1359 } 1360 1361 break; 1362 1363 case LDAP_FILTER_PRESENT: 1364 fstr->bv_len = vrf->vrf_desc->ad_cname.bv_len + 1365 STRLENOF("(=*)"); 1366 if ( undef ) fstr->bv_len++; 1367 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx ); 1368 1369 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)", 1370 vrf->vrf_desc->ad_cname.bv_val ); 1371 break; 1372 1373 case LDAP_FILTER_EXT: { 1374 struct berval ad; 1375 filter_escape_value_x( &vrf->vrf_mr_value, &tmp, op->o_tmpmemctx ); 1376 1377 if ( vrf->vrf_mr_desc ) { 1378 ad = vrf->vrf_mr_desc->ad_cname; 1379 } else { 1380 ad.bv_len = 0; 1381 ad.bv_val = ""; 1382 } 1383 1384 fstr->bv_len = ad.bv_len + 1385 ( vrf->vrf_mr_dnattrs ? STRLENOF(":dn") : 0 ) + 1386 ( vrf->vrf_mr_rule_text.bv_len 1387 ? vrf->vrf_mr_rule_text.bv_len+1 : 0 ) + 1388 tmp.bv_len + STRLENOF("(:=)"); 1389 if ( undef ) fstr->bv_len++; 1390 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx ); 1391 1392 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)", 1393 ad.bv_val, 1394 vrf->vrf_mr_dnattrs ? ":dn" : "", 1395 vrf->vrf_mr_rule_text.bv_len ? ":" : "", 1396 vrf->vrf_mr_rule_text.bv_len ? vrf->vrf_mr_rule_text.bv_val : "", 1397 tmp.bv_val ); 1398 1399 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx ); 1400 } break; 1401 1402 case SLAPD_FILTER_COMPUTED: 1403 ber_str2bv_x( 1404 vrf->vrf_result == LDAP_COMPARE_FALSE ? "(?=false)" : 1405 vrf->vrf_result == LDAP_COMPARE_TRUE ? "(?=true)" : 1406 vrf->vrf_result == SLAPD_COMPARE_UNDEFINED 1407 ? "(?=undefined)" : "(?=error)", 1408 vrf->vrf_result == LDAP_COMPARE_FALSE ? STRLENOF("(?=false)") : 1409 vrf->vrf_result == LDAP_COMPARE_TRUE ? STRLENOF("(?=true)") : 1410 vrf->vrf_result == SLAPD_COMPARE_UNDEFINED 1411 ? STRLENOF("(?=undefined)") : STRLENOF("(?=error)"), 1412 1, fstr, op->o_tmpmemctx ); 1413 break; 1414 1415 default: 1416 ber_str2bv_x( "(?=unknown)", STRLENOF("(?=unknown)"), 1417 1, fstr, op->o_tmpmemctx ); 1418 break; 1419 } 1420 } 1421