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_chase (SLAP_SET_GATHER gatherer,
25 SetCookie *cookie, BerVarray set, struct berval *attr, int closure);
26 static int set_samedn (char *dn1, char *dn2);
29 slap_set_size (BerVarray set)
42 slap_set_dispose (SetCookie *cp, BerVarray set)
44 ber_bvarray_free_x(set, cp->op->o_tmpmemctx);
48 slap_set_join (SetCookie *cp, BerVarray lset, int op, BerVarray rset)
55 if (lset == NULL || lset->bv_val == NULL) {
58 return(cp->op->o_tmpcalloc(1, sizeof(struct berval),
59 cp->op->o_tmpmemctx));
62 slap_set_dispose(cp, lset);
65 if (rset == NULL || rset->bv_val == NULL) {
66 slap_set_dispose(cp, rset);
70 i = slap_set_size(lset) + slap_set_size(rset) + 1;
71 set = cp->op->o_tmpcalloc(i, sizeof(struct berval), cp->op->o_tmpmemctx);
73 /* set_chase() depends on this routine to
74 * keep the first elements of the result
75 * set the same (and in the same order)
78 for (i = 0; lset[i].bv_val; i++)
80 cp->op->o_tmpfree(lset, cp->op->o_tmpmemctx);
81 for (i = 0; rset[i].bv_val; i++) {
82 for (j = 0; set[j].bv_val; j++) {
83 if (set_samedn(rset[i].bv_val, set[j].bv_val)) {
84 cp->op->o_tmpfree(rset[i].bv_val, cp->op->o_tmpmemctx);
85 rset[i].bv_val = NULL;
92 cp->op->o_tmpfree(rset, cp->op->o_tmpmemctx);
98 if (lset == NULL || lset->bv_val == NULL || rset == NULL || rset->bv_val == NULL) {
99 set = cp->op->o_tmpcalloc(1, sizeof(struct berval), cp->op->o_tmpmemctx);
103 last = slap_set_size(set) - 1;
104 for (i = 0; set[i].bv_val; i++) {
105 for (j = 0; rset[j].bv_val; j++) {
106 if (set_samedn(set[i].bv_val, rset[j].bv_val))
109 if (rset[j].bv_val == NULL) {
110 cp->op->o_tmpfree(set[i].bv_val, cp->op->o_tmpmemctx);
112 set[last].bv_val = NULL;
120 slap_set_dispose(cp, lset);
121 slap_set_dispose(cp, rset);
126 set_chase (SLAP_SET_GATHER gatherer,
127 SetCookie *cp, BerVarray set, struct berval *attr, int closure)
129 BerVarray vals, nset;
134 bv.bv_len = attr->bv_len;
138 return(cp->op->o_tmpcalloc(1, sizeof(struct berval), cp->op->o_tmpmemctx));
140 if (set->bv_val == NULL)
143 if (attr->bv_len > (sizeof(attrstr) - 1)) {
144 slap_set_dispose(cp, set);
147 AC_MEMCPY(attrstr, attr->bv_val, attr->bv_len);
148 attrstr[attr->bv_len] = 0;
150 nset = cp->op->o_tmpcalloc(1, sizeof(struct berval), cp->op->o_tmpmemctx);
152 slap_set_dispose(cp, set);
155 for (i = 0; set[i].bv_val; i++) {
156 vals = (gatherer)(cp, &set[i], &bv);
158 nset = slap_set_join(cp, nset, '|', vals);
160 slap_set_dispose(cp, set);
163 for (i = 0; nset[i].bv_val; i++) {
164 vals = (gatherer)(cp, &nset[i], &bv);
166 nset = slap_set_join(cp, nset, '|', vals);
176 set_samedn (char *dn1, char *dn2)
180 while (*dn1 == ' ') dn1++;
181 while (*dn2 == ' ') dn2++;
182 while (*dn1 || *dn2) {
183 if (*dn1 != '=' && *dn1 != ','
184 && *dn2 != '=' && *dn2 != ',')
188 if (c1 >= 'a' && c1 <= 'z')
190 if (c2 >= 'a' && c2 <= 'z')
195 while (*dn1 == ' ') dn1++;
196 while (*dn2 == ' ') dn2++;
197 if (*dn1++ != *dn2++)
199 while (*dn1 == ' ') dn1++;
200 while (*dn2 == ' ') dn2++;
207 slap_set_filter (SLAP_SET_GATHER gatherer,
208 SetCookie *cp, struct berval *fbv,
209 struct berval *user, struct berval *this, BerVarray *results)
211 #define IS_SET(x) ( (unsigned long)(x) >= 256 )
212 #define IS_OP(x) ( (unsigned long)(x) < 256 )
213 #define SF_ERROR(x) do { rc = -1; goto _error; } while (0)
214 #define SF_TOP() ( (BerVarray)( (stp < 0) ? 0 : stack[stp] ) )
215 #define SF_POP() ( (BerVarray)( (stp < 0) ? 0 : stack[stp--] ) )
216 #define SF_PUSH(x) do { \
217 if (stp >= 63) SF_ERROR(overflow); \
218 stack[++stp] = (BerVarray)(long)(x); \
222 BerVarray stack[64] = { 0 };
223 int len, op, rc, stp;
224 char c, *filter = fbv->bv_val;
230 while ((c = *filter++)) {
240 if (IS_SET(SF_TOP()))
249 if (SF_TOP() == (void *)'(') {
253 } else if (IS_OP(SF_TOP())) {
257 set = slap_set_join(cp, lset, op, set);
272 if (SF_TOP() == 0 || SF_TOP() == (void *)'(') {
275 } else if (IS_OP(SF_TOP())) {
278 set = slap_set_join(cp, lset, op, set);
290 if ((SF_TOP() == (void *)'/') || IS_SET(SF_TOP()))
292 for ( len = 0; (c = *filter++) && (c != ']'); len++ )
297 set = cp->op->o_tmpcalloc(2, sizeof(struct berval), cp->op->o_tmpmemctx);
300 set->bv_val = cp->op->o_tmpcalloc(len + 1, sizeof(char), cp->op->o_tmpmemctx);
301 if (set->bv_val == NULL)
303 AC_MEMCPY(set->bv_val, &filter[-len - 1], len);
313 /* fall through to next case */
323 && (c < 'A' || c > 'Z')
324 && (c < 'a' || c > 'z'))
331 && ((c >= '0' && c <= '9')
332 || (c >= 'A' && c <= 'Z')
333 || (c >= 'a' && c <= 'z'));
337 && memcmp("this", filter, len) == 0)
339 if ((SF_TOP() == (void *)'/') || IS_SET(SF_TOP()))
341 set = cp->op->o_tmpcalloc(2, sizeof(struct berval), cp->op->o_tmpmemctx);
344 ber_dupbv_x( set, this, cp->op->o_tmpmemctx );
345 if (set->bv_val == NULL)
348 && memcmp("user", filter, len) == 0)
350 if ((SF_TOP() == (void *)'/') || IS_SET(SF_TOP()))
352 set = cp->op->o_tmpcalloc(2, sizeof(struct berval), cp->op->o_tmpmemctx);
355 ber_dupbv_x( set, user, cp->op->o_tmpmemctx );
356 if (set->bv_val == NULL)
358 } else if (SF_TOP() != (void *)'/') {
365 set = set_chase( gatherer,
366 cp, SF_POP(), &fb2, c == '*' );
384 } else if (IS_OP(SF_TOP())) {
387 set = slap_set_join(cp, lset, op, set);
394 rc = slap_set_size(set) > 0 ? 1 : 0;
402 slap_set_dispose(cp, set);
403 while ((set = SF_POP())) {
405 slap_set_dispose(cp, set);