2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 2000-2004 The OpenLDAP Foundation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
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>.
19 #include <ac/string.h>
24 static BerVarray set_join (SetCookie *cp, BerVarray lset, int op, BerVarray rset);
25 static BerVarray set_chase (SLAP_SET_GATHER gatherer,
26 SetCookie *cookie, BerVarray set, struct berval *attr, int closure);
27 static int set_samedn (char *dn1, char *dn2);
30 slap_set_size (BerVarray set)
43 slap_set_dispose (SetCookie *cp, BerVarray set)
45 ber_bvarray_free_x(set, cp->op->o_tmpmemctx);
49 set_join (SetCookie *cp, BerVarray lset, int op, BerVarray rset)
56 if (lset == NULL || lset->bv_val == NULL) {
59 return(cp->op->o_tmpcalloc(1, sizeof(struct berval),
60 cp->op->o_tmpmemctx));
63 slap_set_dispose(cp, lset);
66 if (rset == NULL || rset->bv_val == NULL) {
67 slap_set_dispose(cp, rset);
71 i = slap_set_size(lset) + slap_set_size(rset) + 1;
72 set = cp->op->o_tmpcalloc(i, sizeof(struct berval), cp->op->o_tmpmemctx);
74 /* set_chase() depends on this routine to
75 * keep the first elements of the result
76 * set the same (and in the same order)
79 for (i = 0; lset[i].bv_val; i++)
81 cp->op->o_tmpfree(lset, cp->op->o_tmpmemctx);
82 for (i = 0; rset[i].bv_val; i++) {
83 for (j = 0; set[j].bv_val; j++) {
84 if (set_samedn(rset[i].bv_val, set[j].bv_val)) {
85 cp->op->o_tmpfree(rset[i].bv_val, cp->op->o_tmpmemctx);
86 rset[i].bv_val = NULL;
93 cp->op->o_tmpfree(rset, cp->op->o_tmpmemctx);
99 if (lset == NULL || lset->bv_val == NULL || rset == NULL || rset->bv_val == NULL) {
100 set = cp->op->o_tmpcalloc(1, sizeof(struct berval), cp->op->o_tmpmemctx);
104 last = slap_set_size(set) - 1;
105 for (i = 0; set[i].bv_val; i++) {
106 for (j = 0; rset[j].bv_val; j++) {
107 if (set_samedn(set[i].bv_val, rset[j].bv_val))
110 if (rset[j].bv_val == NULL) {
111 cp->op->o_tmpfree(set[i].bv_val, cp->op->o_tmpmemctx);
113 set[last].bv_val = NULL;
121 slap_set_dispose(cp, lset);
122 slap_set_dispose(cp, rset);
127 set_chase (SLAP_SET_GATHER gatherer,
128 SetCookie *cp, BerVarray set, struct berval *attr, int closure)
130 BerVarray vals, nset;
135 bv.bv_len = attr->bv_len;
139 return(cp->op->o_tmpcalloc(1, sizeof(struct berval), cp->op->o_tmpmemctx));
141 if (set->bv_val == NULL)
144 if (attr->bv_len > (sizeof(attrstr) - 1)) {
145 slap_set_dispose(cp, set);
148 AC_MEMCPY(attrstr, attr->bv_val, attr->bv_len);
149 attrstr[attr->bv_len] = 0;
151 nset = cp->op->o_tmpcalloc(1, sizeof(struct berval), cp->op->o_tmpmemctx);
153 slap_set_dispose(cp, set);
156 for (i = 0; set[i].bv_val; i++) {
157 vals = (gatherer)(cp, &set[i], &bv);
159 nset = set_join(cp, nset, '|', vals);
161 slap_set_dispose(cp, set);
164 for (i = 0; nset[i].bv_val; i++) {
165 vals = (gatherer)(cp, &nset[i], &bv);
167 nset = set_join(cp, nset, '|', vals);
177 set_samedn (char *dn1, char *dn2)
181 while (*dn1 == ' ') dn1++;
182 while (*dn2 == ' ') dn2++;
183 while (*dn1 || *dn2) {
184 if (*dn1 != '=' && *dn1 != ','
185 && *dn2 != '=' && *dn2 != ',')
189 if (c1 >= 'a' && c1 <= 'z')
191 if (c2 >= 'a' && c2 <= 'z')
196 while (*dn1 == ' ') dn1++;
197 while (*dn2 == ' ') dn2++;
198 if (*dn1++ != *dn2++)
200 while (*dn1 == ' ') dn1++;
201 while (*dn2 == ' ') dn2++;
208 slap_set_filter (SLAP_SET_GATHER gatherer,
209 SetCookie *cp, struct berval *fbv,
210 struct berval *user, struct berval *this, BerVarray *results)
212 #define IS_SET(x) ( (unsigned long)(x) >= 256 )
213 #define IS_OP(x) ( (unsigned long)(x) < 256 )
214 #define SF_ERROR(x) do { rc = -1; goto _error; } while (0)
215 #define SF_TOP() ( (BerVarray)( (stp < 0) ? 0 : stack[stp] ) )
216 #define SF_POP() ( (BerVarray)( (stp < 0) ? 0 : stack[stp--] ) )
217 #define SF_PUSH(x) do { \
218 if (stp >= 63) SF_ERROR(overflow); \
219 stack[++stp] = (BerVarray)(long)(x); \
223 BerVarray stack[64] = { 0 };
224 int len, op, rc, stp;
225 char c, *filter = fbv->bv_val;
231 while ((c = *filter++)) {
241 if (IS_SET(SF_TOP()))
250 if (SF_TOP() == (void *)'(') {
254 } else if (IS_OP(SF_TOP())) {
258 set = set_join(cp, lset, op, set);
273 if (SF_TOP() == 0 || SF_TOP() == (void *)'(') {
276 } else if (IS_OP(SF_TOP())) {
279 set = set_join(cp, lset, op, set);
291 if ((SF_TOP() == (void *)'/') || IS_SET(SF_TOP()))
294 (c = *filter++) && (c != ']');
300 set = cp->op->o_tmpcalloc(2, sizeof(struct berval), cp->op->o_tmpmemctx);
303 set->bv_val = cp->op->o_tmpcalloc(len + 1, sizeof(char), cp->op->o_tmpmemctx);
304 if (set->bv_val == NULL)
306 AC_MEMCPY(set->bv_val, &filter[-len - 1], len);
316 /* fall through to next case */
326 && (c < 'A' || c > 'Z')
327 && (c < 'a' || c > 'z'))
334 && ((c >= '0' && c <= '9')
335 || (c >= 'A' && c <= 'Z')
336 || (c >= 'a' && c <= 'z'));
340 && memcmp("this", filter, len) == 0)
342 if ((SF_TOP() == (void *)'/') || IS_SET(SF_TOP()))
344 set = cp->op->o_tmpcalloc(2, sizeof(struct berval), cp->op->o_tmpmemctx);
347 ber_dupbv_x( set, this, cp->op->o_tmpmemctx );
348 if (set->bv_val == NULL)
351 && memcmp("user", filter, len) == 0)
353 if ((SF_TOP() == (void *)'/') || IS_SET(SF_TOP()))
355 set = cp->op->o_tmpcalloc(2, sizeof(struct berval), cp->op->o_tmpmemctx);
358 ber_dupbv_x( set, user, cp->op->o_tmpmemctx );
359 if (set->bv_val == NULL)
361 } else if (SF_TOP() != (void *)'/') {
368 set = set_chase(gatherer,
369 cp, SF_POP(), &fb2, c == '*');
387 } else if (IS_OP(SF_TOP())) {
390 set = set_join(cp, lset, op, set);
397 rc = slap_set_size(set) > 0 ? 1 : 0;
405 slap_set_dispose(cp, set);
406 while ((set = SF_POP())) {
408 slap_set_dispose(cp, set);