/openldap-2.4.31/evo-openldap-2.4.31/servers/slapd/sets.c

# · C · 832 lines · 654 code · 121 blank · 57 comment · 231 complexity · bf393d9195d7b3d708558e94327d349f MD5 · raw file

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