1/* $OpenLDAP$ */ 2/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 3 * 4 * Copyright 2000-2011 The OpenLDAP Foundation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted only as authorized by the OpenLDAP 9 * Public License. 10 * 11 * A copy of this license is available in the file LICENSE in the 12 * top-level directory of the distribution or, alternatively, at 13 * <http://www.OpenLDAP.org/license.html>. 14 */ 15 16#include "portable.h" 17 18#include <stdio.h> 19#include <ac/string.h> 20 21#include "slap.h" 22#include "sets.h" 23 24static BerVarray set_chase( SLAP_SET_GATHER gatherer, 25 SetCookie *cookie, BerVarray set, AttributeDescription *desc, int closure ); 26 27/* Count the array members */ 28static long 29slap_set_size( BerVarray set ) 30{ 31 long i = 0; 32 33 if ( set != NULL ) { 34 while ( !BER_BVISNULL( &set[ i ] ) ) { 35 i++; 36 } 37 } 38 39 return i; 40} 41 42/* Return 0 if there is at least one array member, non-zero otherwise */ 43static int 44slap_set_isempty( BerVarray set ) 45{ 46 if ( set == NULL ) { 47 return 1; 48 } 49 50 if ( !BER_BVISNULL( &set[ 0 ] ) ) { 51 return 0; 52 } 53 54 return 1; 55} 56 57/* Dispose of the contents of the array and the array itself according 58 * to the flags value. If SLAP_SET_REFVAL, don't dispose of values; 59 * if SLAP_SET_REFARR, don't dispose of the array itself. In case of 60 * binary operators, there are LEFT flags and RIGHT flags, referring to 61 * the first and the second operator arguments, respectively. In this 62 * case, flags must be transformed using macros SLAP_SET_LREF2REF() and 63 * SLAP_SET_RREF2REF() before calling this function. 64 */ 65static void 66slap_set_dispose( SetCookie *cp, BerVarray set, unsigned flags ) 67{ 68 if ( flags & SLAP_SET_REFVAL ) { 69 if ( ! ( flags & SLAP_SET_REFARR ) ) { 70 cp->set_op->o_tmpfree( set, cp->set_op->o_tmpmemctx ); 71 } 72 73 } else { 74 ber_bvarray_free_x( set, cp->set_op->o_tmpmemctx ); 75 } 76} 77 78/* Duplicate a set. If SLAP_SET_REFARR, is not set, the original array 79 * with the original values is returned, otherwise the array is duplicated; 80 * if SLAP_SET_REFVAL is set, also the values are duplicated. 81 */ 82static BerVarray 83set_dup( SetCookie *cp, BerVarray set, unsigned flags ) 84{ 85 BerVarray newset = NULL; 86 87 if ( set == NULL ) { 88 return NULL; 89 } 90 91 if ( flags & SLAP_SET_REFARR ) { 92 int i; 93 94 for ( i = 0; !BER_BVISNULL( &set[ i ] ); i++ ) 95 ; 96 newset = cp->set_op->o_tmpcalloc( i + 1, 97 sizeof( struct berval ), 98 cp->set_op->o_tmpmemctx ); 99 if ( newset == NULL ) { 100 return NULL; 101 } 102 103 if ( flags & SLAP_SET_REFVAL ) { 104 for ( i = 0; !BER_BVISNULL( &set[ i ] ); i++ ) { 105 ber_dupbv_x( &newset[ i ], &set[ i ], 106 cp->set_op->o_tmpmemctx ); 107 } 108 109 } else { 110 AC_MEMCPY( newset, set, ( i + 1 ) * sizeof( struct berval ) ); 111 } 112 113 } else { 114 newset = set; 115 } 116 117 return newset; 118} 119 120/* Join two sets according to operator op and flags op_flags. 121 * op can be: 122 * '|' (or): the union between the two sets is returned, 123 * eliminating duplicates 124 * '&' (and): the intersection between the two sets 125 * is returned 126 * '+' (add): the inner product of the two sets is returned, 127 * namely a set containing the concatenation of 128 * all combinations of the two sets members, 129 * except for duplicates. 130 * The two sets are disposed of according to the flags as described 131 * for slap_set_dispose(). 132 */ 133BerVarray 134slap_set_join( 135 SetCookie *cp, 136 BerVarray lset, 137 unsigned op_flags, 138 BerVarray rset ) 139{ 140 BerVarray set; 141 long i, j, last, rlast; 142 unsigned op = ( op_flags & SLAP_SET_OPMASK ); 143 144 set = NULL; 145 switch ( op ) { 146 case '|': /* union */ 147 if ( lset == NULL || BER_BVISNULL( &lset[ 0 ] ) ) { 148 if ( rset == NULL ) { 149 if ( lset == NULL ) { 150 set = cp->set_op->o_tmpcalloc( 1, 151 sizeof( struct berval ), 152 cp->set_op->o_tmpmemctx ); 153 BER_BVZERO( &set[ 0 ] ); 154 goto done2; 155 } 156 set = set_dup( cp, lset, SLAP_SET_LREF2REF( op_flags ) ); 157 goto done2; 158 } 159 slap_set_dispose( cp, lset, SLAP_SET_LREF2REF( op_flags ) ); 160 set = set_dup( cp, rset, SLAP_SET_RREF2REF( op_flags ) ); 161 goto done2; 162 } 163 if ( rset == NULL || BER_BVISNULL( &rset[ 0 ] ) ) { 164 slap_set_dispose( cp, rset, SLAP_SET_RREF2REF( op_flags ) ); 165 set = set_dup( cp, lset, SLAP_SET_LREF2REF( op_flags ) ); 166 goto done2; 167 } 168 169 /* worst scenario: no duplicates */ 170 rlast = slap_set_size( rset ); 171 i = slap_set_size( lset ) + rlast + 1; 172 set = cp->set_op->o_tmpcalloc( i, sizeof( struct berval ), cp->set_op->o_tmpmemctx ); 173 if ( set != NULL ) { 174 /* set_chase() depends on this routine to 175 * keep the first elements of the result 176 * set the same (and in the same order) 177 * as the left-set. 178 */ 179 for ( i = 0; !BER_BVISNULL( &lset[ i ] ); i++ ) { 180 if ( op_flags & SLAP_SET_LREFVAL ) { 181 ber_dupbv_x( &set[ i ], &lset[ i ], cp->set_op->o_tmpmemctx ); 182 183 } else { 184 set[ i ] = lset[ i ]; 185 } 186 } 187 188 /* pointers to values have been used in set - don't free twice */ 189 op_flags |= SLAP_SET_LREFVAL; 190 191 last = i; 192 193 for ( i = 0; !BER_BVISNULL( &rset[ i ] ); i++ ) { 194 int exists = 0; 195 196 for ( j = 0; !BER_BVISNULL( &set[ j ] ); j++ ) { 197 if ( bvmatch( &rset[ i ], &set[ j ] ) ) 198 { 199 if ( !( op_flags & SLAP_SET_RREFVAL ) ) { 200 cp->set_op->o_tmpfree( rset[ i ].bv_val, cp->set_op->o_tmpmemctx ); 201 rset[ i ] = rset[ --rlast ]; 202 BER_BVZERO( &rset[ rlast ] ); 203 i--; 204 } 205 exists = 1; 206 break; 207 } 208 } 209 210 if ( !exists ) { 211 if ( op_flags & SLAP_SET_RREFVAL ) { 212 ber_dupbv_x( &set[ last ], &rset[ i ], cp->set_op->o_tmpmemctx ); 213 214 } else { 215 set[ last ] = rset[ i ]; 216 } 217 last++; 218 } 219 } 220 221 /* pointers to values have been used in set - don't free twice */ 222 op_flags |= SLAP_SET_RREFVAL; 223 224 BER_BVZERO( &set[ last ] ); 225 } 226 break; 227 228 case '&': /* intersection */ 229 if ( lset == NULL || BER_BVISNULL( &lset[ 0 ] ) 230 || rset == NULL || BER_BVISNULL( &rset[ 0 ] ) ) 231 { 232 set = cp->set_op->o_tmpcalloc( 1, sizeof( struct berval ), 233 cp->set_op->o_tmpmemctx ); 234 BER_BVZERO( &set[ 0 ] ); 235 break; 236 237 } else { 238 long llen, rlen; 239 BerVarray sset; 240 241 llen = slap_set_size( lset ); 242 rlen = slap_set_size( rset ); 243 244 /* dup the shortest */ 245 if ( llen < rlen ) { 246 last = llen; 247 set = set_dup( cp, lset, SLAP_SET_LREF2REF( op_flags ) ); 248 lset = NULL; 249 sset = rset; 250 251 } else { 252 last = rlen; 253 set = set_dup( cp, rset, SLAP_SET_RREF2REF( op_flags ) ); 254 rset = NULL; 255 sset = lset; 256 } 257 258 if ( set == NULL ) { 259 break; 260 } 261 262 for ( i = 0; !BER_BVISNULL( &set[ i ] ); i++ ) { 263 for ( j = 0; !BER_BVISNULL( &sset[ j ] ); j++ ) { 264 if ( bvmatch( &set[ i ], &sset[ j ] ) ) { 265 break; 266 } 267 } 268 269 if ( BER_BVISNULL( &sset[ j ] ) ) { 270 cp->set_op->o_tmpfree( set[ i ].bv_val, cp->set_op->o_tmpmemctx ); 271 set[ i ] = set[ --last ]; 272 BER_BVZERO( &set[ last ] ); 273 i--; 274 } 275 } 276 } 277 break; 278 279 case '+': /* string concatenation */ 280 i = slap_set_size( rset ); 281 j = slap_set_size( lset ); 282 283 /* handle empty set cases */ 284 if ( i == 0 || j == 0 ) { 285 set = cp->set_op->o_tmpcalloc( 1, sizeof( struct berval ), 286 cp->set_op->o_tmpmemctx ); 287 if ( set == NULL ) { 288 break; 289 } 290 BER_BVZERO( &set[ 0 ] ); 291 break; 292 } 293 294 set = cp->set_op->o_tmpcalloc( i * j + 1, sizeof( struct berval ), 295 cp->set_op->o_tmpmemctx ); 296 if ( set == NULL ) { 297 break; 298 } 299 300 for ( last = 0, i = 0; !BER_BVISNULL( &lset[ i ] ); i++ ) { 301 for ( j = 0; !BER_BVISNULL( &rset[ j ] ); j++ ) { 302 struct berval bv; 303 long k; 304 305 /* don't concatenate with the empty string */ 306 if ( BER_BVISEMPTY( &lset[ i ] ) ) { 307 ber_dupbv_x( &bv, &rset[ j ], cp->set_op->o_tmpmemctx ); 308 if ( bv.bv_val == NULL ) { 309 ber_bvarray_free_x( set, cp->set_op->o_tmpmemctx ); 310 set = NULL; 311 goto done; 312 } 313 314 } else if ( BER_BVISEMPTY( &rset[ j ] ) ) { 315 ber_dupbv_x( &bv, &lset[ i ], cp->set_op->o_tmpmemctx ); 316 if ( bv.bv_val == NULL ) { 317 ber_bvarray_free_x( set, cp->set_op->o_tmpmemctx ); 318 set = NULL; 319 goto done; 320 } 321 322 } else { 323 bv.bv_len = lset[ i ].bv_len + rset[ j ].bv_len; 324 bv.bv_val = cp->set_op->o_tmpalloc( bv.bv_len + 1, 325 cp->set_op->o_tmpmemctx ); 326 if ( bv.bv_val == NULL ) { 327 ber_bvarray_free_x( set, cp->set_op->o_tmpmemctx ); 328 set = NULL; 329 goto done; 330 } 331 AC_MEMCPY( bv.bv_val, lset[ i ].bv_val, lset[ i ].bv_len ); 332 AC_MEMCPY( &bv.bv_val[ lset[ i ].bv_len ], rset[ j ].bv_val, rset[ j ].bv_len ); 333 bv.bv_val[ bv.bv_len ] = '\0'; 334 } 335 336 for ( k = 0; k < last; k++ ) { 337 if ( bvmatch( &set[ k ], &bv ) ) { 338 cp->set_op->o_tmpfree( bv.bv_val, cp->set_op->o_tmpmemctx ); 339 break; 340 } 341 } 342 343 if ( k == last ) { 344 set[ last++ ] = bv; 345 } 346 } 347 } 348 BER_BVZERO( &set[ last ] ); 349 break; 350 351 default: 352 break; 353 } 354 355done:; 356 if ( lset ) slap_set_dispose( cp, lset, SLAP_SET_LREF2REF( op_flags ) ); 357 if ( rset ) slap_set_dispose( cp, rset, SLAP_SET_RREF2REF( op_flags ) ); 358 359done2:; 360 if ( LogTest( LDAP_DEBUG_ACL ) ) { 361 if ( BER_BVISNULL( set ) ) { 362 Debug( LDAP_DEBUG_ACL, " ACL set: empty\n", 0, 0, 0 ); 363 364 } else { 365 for ( i = 0; !BER_BVISNULL( &set[ i ] ); i++ ) { 366 Debug( LDAP_DEBUG_ACL, " ACL set[%ld]=%s\n", i, set[i].bv_val, 0 ); 367 } 368 } 369 } 370 371 return set; 372} 373 374static BerVarray 375set_chase( SLAP_SET_GATHER gatherer, 376 SetCookie *cp, BerVarray set, AttributeDescription *desc, int closure ) 377{ 378 BerVarray vals, nset; 379 int i; 380 381 if ( set == NULL ) { 382 set = cp->set_op->o_tmpcalloc( 1, sizeof( struct berval ), 383 cp->set_op->o_tmpmemctx ); 384 if ( set != NULL ) { 385 BER_BVZERO( &set[ 0 ] ); 386 } 387 return set; 388 } 389 390 if ( BER_BVISNULL( set ) ) { 391 return set; 392 } 393 394 nset = cp->set_op->o_tmpcalloc( 1, sizeof( struct berval ), cp->set_op->o_tmpmemctx ); 395 if ( nset == NULL ) { 396 ber_bvarray_free_x( set, cp->set_op->o_tmpmemctx ); 397 return NULL; 398 } 399 for ( i = 0; !BER_BVISNULL( &set[ i ] ); i++ ) { 400 vals = gatherer( cp, &set[ i ], desc ); 401 if ( vals != NULL ) { 402 nset = slap_set_join( cp, nset, '|', vals ); 403 } 404 } 405 ber_bvarray_free_x( set, cp->set_op->o_tmpmemctx ); 406 407 if ( closure ) { 408 for ( i = 0; !BER_BVISNULL( &nset[ i ] ); i++ ) { 409 vals = gatherer( cp, &nset[ i ], desc ); 410 if ( vals != NULL ) { 411 nset = slap_set_join( cp, nset, '|', vals ); 412 if ( nset == NULL ) { 413 break; 414 } 415 } 416 } 417 } 418 419 return nset; 420} 421 422 423static BerVarray 424set_parents( SetCookie *cp, BerVarray set ) 425{ 426 int i, j, last; 427 struct berval bv, pbv; 428 BerVarray nset, vals; 429 430 if ( set == NULL ) { 431 set = cp->set_op->o_tmpcalloc( 1, sizeof( struct berval ), 432 cp->set_op->o_tmpmemctx ); 433 if ( set != NULL ) { 434 BER_BVZERO( &set[ 0 ] ); 435 } 436 return set; 437 } 438 439 if ( BER_BVISNULL( &set[ 0 ] ) ) { 440 return set; 441 } 442 443 nset = cp->set_op->o_tmpcalloc( 1, sizeof( struct berval ), cp->set_op->o_tmpmemctx ); 444 if ( nset == NULL ) { 445 ber_bvarray_free_x( set, cp->set_op->o_tmpmemctx ); 446 return NULL; 447 } 448 449 BER_BVZERO( &nset[ 0 ] ); 450 451 for ( i = 0; !BER_BVISNULL( &set[ i ] ); i++ ) { 452 int level = 1; 453 454 pbv = bv = set[ i ]; 455 for ( ; !BER_BVISEMPTY( &pbv ); dnParent( &bv, &pbv ) ) { 456 level++; 457 bv = pbv; 458 } 459 460 vals = cp->set_op->o_tmpcalloc( level + 1, sizeof( struct berval ), cp->set_op->o_tmpmemctx ); 461 if ( vals == NULL ) { 462 ber_bvarray_free_x( set, cp->set_op->o_tmpmemctx ); 463 ber_bvarray_free_x( nset, cp->set_op->o_tmpmemctx ); 464 return NULL; 465 } 466 BER_BVZERO( &vals[ 0 ] ); 467 last = 0; 468 469 bv = set[ i ]; 470 for ( j = 0 ; j < level ; j++ ) { 471 ber_dupbv_x( &vals[ last ], &bv, cp->set_op->o_tmpmemctx ); 472 last++; 473 dnParent( &bv, &bv ); 474 } 475 BER_BVZERO( &vals[ last ] ); 476 477 nset = slap_set_join( cp, nset, '|', vals ); 478 } 479 480 ber_bvarray_free_x( set, cp->set_op->o_tmpmemctx ); 481 482 return nset; 483} 484 485 486 487static BerVarray 488set_parent( SetCookie *cp, BerVarray set, int level ) 489{ 490 int i, j, last; 491 struct berval bv; 492 BerVarray nset; 493 494 if ( set == NULL ) { 495 set = cp->set_op->o_tmpcalloc( 1, sizeof( struct berval ), 496 cp->set_op->o_tmpmemctx ); 497 if ( set != NULL ) { 498 BER_BVZERO( &set[ 0 ] ); 499 } 500 return set; 501 } 502 503 if ( BER_BVISNULL( &set[ 0 ] ) ) { 504 return set; 505 } 506 507 nset = cp->set_op->o_tmpcalloc( slap_set_size( set ) + 1, sizeof( struct berval ), cp->set_op->o_tmpmemctx ); 508 if ( nset == NULL ) { 509 ber_bvarray_free_x( set, cp->set_op->o_tmpmemctx ); 510 return NULL; 511 } 512 513 BER_BVZERO( &nset[ 0 ] ); 514 last = 0; 515 516 for ( i = 0; !BER_BVISNULL( &set[ i ] ); i++ ) { 517 bv = set[ i ]; 518 519 for ( j = 0 ; j < level ; j++ ) { 520 dnParent( &bv, &bv ); 521 } 522 523 for ( j = 0; !BER_BVISNULL( &nset[ j ] ); j++ ) { 524 if ( bvmatch( &bv, &nset[ j ] ) ) 525 { 526 break; 527 } 528 } 529 530 if ( BER_BVISNULL( &nset[ j ] ) ) { 531 ber_dupbv_x( &nset[ last ], &bv, cp->set_op->o_tmpmemctx ); 532 last++; 533 } 534 } 535 536 BER_BVZERO( &nset[ last ] ); 537 538 ber_bvarray_free_x( set, cp->set_op->o_tmpmemctx ); 539 540 return nset; 541} 542 543int 544slap_set_filter( SLAP_SET_GATHER gatherer, 545 SetCookie *cp, struct berval *fbv, 546 struct berval *user, struct berval *target, BerVarray *results ) 547{ 548#define STACK_SIZE 64 549#define IS_SET(x) ( (unsigned long)(x) >= 256 ) 550#define IS_OP(x) ( (unsigned long)(x) < 256 ) 551#define SF_ERROR(x) do { rc = -1; goto _error; } while ( 0 ) 552#define SF_TOP() ( (BerVarray)( ( stp < 0 ) ? 0 : stack[ stp ] ) ) 553#define SF_POP() ( (BerVarray)( ( stp < 0 ) ? 0 : stack[ stp-- ] ) ) 554#define SF_PUSH(x) do { \ 555 if ( stp >= ( STACK_SIZE - 1 ) ) SF_ERROR( overflow ); \ 556 stack[ ++stp ] = (BerVarray)(long)(x); \ 557 } while ( 0 ) 558 559 BerVarray set, lset; 560 BerVarray stack[ STACK_SIZE ] = { 0 }; 561 int len, rc, stp; 562 unsigned long op; 563 char c, *filter = fbv->bv_val; 564 565 if ( results ) { 566 *results = NULL; 567 } 568 569 stp = -1; 570 while ( ( c = *filter++ ) ) { 571 set = NULL; 572 switch ( c ) { 573 case ' ': 574 case '\t': 575 case '\x0A': 576 case '\x0D': 577 break; 578 579 case '(' /* ) */ : 580 if ( IS_SET( SF_TOP() ) ) { 581 SF_ERROR( syntax ); 582 } 583 SF_PUSH( c ); 584 break; 585 586 case /* ( */ ')': 587 set = SF_POP(); 588 if ( IS_OP( set ) ) { 589 SF_ERROR( syntax ); 590 } 591 if ( SF_TOP() == (void *)'(' /* ) */ ) { 592 SF_POP(); 593 SF_PUSH( set ); 594 set = NULL; 595 596 } else if ( IS_OP( SF_TOP() ) ) { 597 op = (unsigned long)SF_POP(); 598 lset = SF_POP(); 599 SF_POP(); 600 set = slap_set_join( cp, lset, op, set ); 601 if ( set == NULL ) { 602 SF_ERROR( memory ); 603 } 604 SF_PUSH( set ); 605 set = NULL; 606 607 } else { 608 SF_ERROR( syntax ); 609 } 610 break; 611 612 case '|': /* union */ 613 case '&': /* intersection */ 614 case '+': /* string concatenation */ 615 set = SF_POP(); 616 if ( IS_OP( set ) ) { 617 SF_ERROR( syntax ); 618 } 619 if ( SF_TOP() == 0 || SF_TOP() == (void *)'(' /* ) */ ) { 620 SF_PUSH( set ); 621 set = NULL; 622 623 } else if ( IS_OP( SF_TOP() ) ) { 624 op = (unsigned long)SF_POP(); 625 lset = SF_POP(); 626 set = slap_set_join( cp, lset, op, set ); 627 if ( set == NULL ) { 628 SF_ERROR( memory ); 629 } 630 SF_PUSH( set ); 631 set = NULL; 632 633 } else { 634 SF_ERROR( syntax ); 635 } 636 SF_PUSH( c ); 637 break; 638 639 case '[' /* ] */: 640 if ( ( SF_TOP() == (void *)'/' ) || IS_SET( SF_TOP() ) ) { 641 SF_ERROR( syntax ); 642 } 643 for ( len = 0; ( c = *filter++ ) && ( c != /* [ */ ']' ); len++ ) 644 ; 645 if ( c == 0 ) { 646 SF_ERROR( syntax ); 647 } 648 649 set = cp->set_op->o_tmpcalloc( 2, sizeof( struct berval ), 650 cp->set_op->o_tmpmemctx ); 651 if ( set == NULL ) { 652 SF_ERROR( memory ); 653 } 654 set->bv_val = cp->set_op->o_tmpcalloc( len + 1, sizeof( char ), 655 cp->set_op->o_tmpmemctx ); 656 if ( BER_BVISNULL( set ) ) { 657 SF_ERROR( memory ); 658 } 659 AC_MEMCPY( set->bv_val, &filter[ - len - 1 ], len ); 660 set->bv_len = len; 661 SF_PUSH( set ); 662 set = NULL; 663 break; 664 665 case '-': 666 if ( ( SF_TOP() == (void *)'/' ) 667 && ( *filter == '*' || ASCII_DIGIT( *filter ) ) ) 668 { 669 SF_POP(); 670 671 if ( *filter == '*' ) { 672 set = set_parents( cp, SF_POP() ); 673 filter++; 674 675 } else { 676 char *next = NULL; 677 long parent = strtol( filter, &next, 10 ); 678 679 if ( next == filter ) { 680 SF_ERROR( syntax ); 681 } 682 683 set = SF_POP(); 684 if ( parent != 0 ) { 685 set = set_parent( cp, set, parent ); 686 } 687 filter = next; 688 } 689 690 if ( set == NULL ) { 691 SF_ERROR( memory ); 692 } 693 694 SF_PUSH( set ); 695 set = NULL; 696 break; 697 } else { 698 c = *filter++; 699 if ( c != '>' ) { 700 SF_ERROR( syntax ); 701 } 702 /* fall through to next case */ 703 } 704 705 case '/': 706 if ( IS_OP( SF_TOP() ) ) { 707 SF_ERROR( syntax ); 708 } 709 SF_PUSH( '/' ); 710 break; 711 712 default: 713 if ( !AD_LEADCHAR( c ) ) { 714 SF_ERROR( syntax ); 715 } 716 filter--; 717 for ( len = 1; 718 ( c = filter[ len ] ) && AD_CHAR( c ); 719 len++ ) 720 { 721 /* count */ 722 if ( c == '-' && !AD_CHAR( filter[ len + 1 ] ) ) { 723 break; 724 } 725 } 726 if ( len == 4 727 && memcmp( "this", filter, len ) == 0 ) 728 { 729 assert( !BER_BVISNULL( target ) ); 730 if ( ( SF_TOP() == (void *)'/' ) || IS_SET( SF_TOP() ) ) { 731 SF_ERROR( syntax ); 732 } 733 set = cp->set_op->o_tmpcalloc( 2, sizeof( struct berval ), 734 cp->set_op->o_tmpmemctx ); 735 if ( set == NULL ) { 736 SF_ERROR( memory ); 737 } 738 ber_dupbv_x( set, target, cp->set_op->o_tmpmemctx ); 739 if ( BER_BVISNULL( set ) ) { 740 SF_ERROR( memory ); 741 } 742 BER_BVZERO( &set[ 1 ] ); 743 744 } else if ( len == 4 745 && memcmp( "user", filter, len ) == 0 ) 746 { 747 if ( ( SF_TOP() == (void *)'/' ) || IS_SET( SF_TOP() ) ) { 748 SF_ERROR( syntax ); 749 } 750 if ( BER_BVISNULL( user ) ) { 751 SF_ERROR( memory ); 752 } 753 set = cp->set_op->o_tmpcalloc( 2, sizeof( struct berval ), 754 cp->set_op->o_tmpmemctx ); 755 if ( set == NULL ) { 756 SF_ERROR( memory ); 757 } 758 ber_dupbv_x( set, user, cp->set_op->o_tmpmemctx ); 759 BER_BVZERO( &set[ 1 ] ); 760 761 } else if ( len == 8 762 && memcmp( "computer", filter, len ) == 0 ) 763 { 764 if ( ( SF_TOP() == (void *)'/' ) || IS_SET( SF_TOP() ) ) { 765 SF_ERROR( syntax ); 766 } 767 set = cp->set_op->o_tmpcalloc( 2, sizeof( struct berval ), 768 cp->set_op->o_tmpmemctx ); 769 if ( set == NULL ) { 770 SF_ERROR( memory ); 771 } 772 ber_dupbv_x( set, user, cp->set_op->o_tmpmemctx ); 773 if ( BER_BVISNULL( set ) ) { 774 SF_ERROR( memory ); 775 } 776 BER_BVZERO( &set[ 1 ] ); 777 778 } else if ( SF_TOP() != (void *)'/' ) { 779 SF_ERROR( syntax ); 780 781 } else { 782 struct berval fb2; 783 AttributeDescription *ad = NULL; 784 const char *text = NULL; 785 786 SF_POP(); 787 fb2.bv_val = filter; 788 fb2.bv_len = len; 789 790 if ( slap_bv2ad( &fb2, &ad, &text ) != LDAP_SUCCESS ) { 791 SF_ERROR( syntax ); 792 } 793 794 /* NOTE: ad must have distinguishedName syntax 795 * or expand in an LDAP URI if c == '*' 796 */ 797 798 set = set_chase( gatherer, 799 cp, SF_POP(), ad, c == '*' ); 800 if ( set == NULL ) { 801 SF_ERROR( memory ); 802 } 803 if ( c == '*' ) { 804 len++; 805 } 806 } 807 filter += len; 808 SF_PUSH( set ); 809 set = NULL; 810 break; 811 } 812 } 813 814 set = SF_POP(); 815 if ( IS_OP( set ) ) { 816 SF_ERROR( syntax ); 817 } 818 if ( SF_TOP() == 0 ) { 819 /* FIXME: ok ? */ ; 820 821 } else if ( IS_OP( SF_TOP() ) ) { 822 op = (unsigned long)SF_POP(); 823 lset = SF_POP(); 824 set = slap_set_join( cp, lset, op, set ); 825 if ( set == NULL ) { 826 SF_ERROR( memory ); 827 } 828 829 } else { 830 SF_ERROR( syntax ); 831 } 832 833 rc = slap_set_isempty( set ) ? 0 : 1; 834 if ( results ) { 835 *results = set; 836 set = NULL; 837 } 838 839_error: 840 if ( IS_SET( set ) ) { 841 ber_bvarray_free_x( set, cp->set_op->o_tmpmemctx ); 842 } 843 while ( ( set = SF_POP() ) ) { 844 if ( IS_SET( set ) ) { 845 ber_bvarray_free_x( set, cp->set_op->o_tmpmemctx ); 846 } 847 } 848 return rc; 849} 850