rwmmap.c revision 1.1 1 1.1 lukem /* rwmmap.c - rewrite/mapping routines */
2 1.1 lukem /* $OpenLDAP: pkg/ldap/servers/slapd/overlays/rwmmap.c,v 1.31.2.6 2008/02/11 23:26:49 kurt Exp $ */
3 1.1 lukem /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 1.1 lukem *
5 1.1 lukem * Copyright 1999-2008 The OpenLDAP Foundation.
6 1.1 lukem * Portions Copyright 1999-2003 Howard Chu.
7 1.1 lukem * Portions Copyright 2000-2003 Pierangelo Masarati.
8 1.1 lukem * All rights reserved.
9 1.1 lukem *
10 1.1 lukem * Redistribution and use in source and binary forms, with or without
11 1.1 lukem * modification, are permitted only as authorized by the OpenLDAP
12 1.1 lukem * Public License.
13 1.1 lukem *
14 1.1 lukem * A copy of this license is available in the file LICENSE in the
15 1.1 lukem * top-level directory of the distribution or, alternatively, at
16 1.1 lukem * <http://www.OpenLDAP.org/license.html>.
17 1.1 lukem */
18 1.1 lukem /* ACKNOWLEDGEMENTS:
19 1.1 lukem * This work was initially developed by the Howard Chu for inclusion
20 1.1 lukem * in OpenLDAP Software and subsequently enhanced by Pierangelo
21 1.1 lukem * Masarati.
22 1.1 lukem */
23 1.1 lukem
24 1.1 lukem #include "portable.h"
25 1.1 lukem
26 1.1 lukem #ifdef SLAPD_OVER_RWM
27 1.1 lukem
28 1.1 lukem #include <stdio.h>
29 1.1 lukem
30 1.1 lukem #include <ac/string.h>
31 1.1 lukem #include <ac/socket.h>
32 1.1 lukem
33 1.1 lukem #include "slap.h"
34 1.1 lukem #include "rwm.h"
35 1.1 lukem
36 1.1 lukem #undef ldap_debug /* silence a warning in ldap-int.h */
37 1.1 lukem #include "../../../libraries/libldap/ldap-int.h"
38 1.1 lukem
39 1.1 lukem int
40 1.1 lukem rwm_mapping_cmp( const void *c1, const void *c2 )
41 1.1 lukem {
42 1.1 lukem struct ldapmapping *map1 = (struct ldapmapping *)c1;
43 1.1 lukem struct ldapmapping *map2 = (struct ldapmapping *)c2;
44 1.1 lukem int rc = map1->m_src.bv_len - map2->m_src.bv_len;
45 1.1 lukem
46 1.1 lukem if ( rc ) {
47 1.1 lukem return rc;
48 1.1 lukem }
49 1.1 lukem
50 1.1 lukem return strcasecmp( map1->m_src.bv_val, map2->m_src.bv_val );
51 1.1 lukem }
52 1.1 lukem
53 1.1 lukem int
54 1.1 lukem rwm_mapping_dup( void *c1, void *c2 )
55 1.1 lukem {
56 1.1 lukem struct ldapmapping *map1 = (struct ldapmapping *)c1;
57 1.1 lukem struct ldapmapping *map2 = (struct ldapmapping *)c2;
58 1.1 lukem int rc = map1->m_src.bv_len - map2->m_src.bv_len;
59 1.1 lukem
60 1.1 lukem if ( rc ) {
61 1.1 lukem return 0;
62 1.1 lukem }
63 1.1 lukem
64 1.1 lukem return ( ( strcasecmp( map1->m_src.bv_val, map2->m_src.bv_val ) == 0 ) ? -1 : 0 );
65 1.1 lukem }
66 1.1 lukem
67 1.1 lukem int
68 1.1 lukem rwm_map_init( struct ldapmap *lm, struct ldapmapping **m )
69 1.1 lukem {
70 1.1 lukem struct ldapmapping *mapping;
71 1.1 lukem const char *text;
72 1.1 lukem int rc;
73 1.1 lukem
74 1.1 lukem assert( m != NULL );
75 1.1 lukem
76 1.1 lukem *m = NULL;
77 1.1 lukem
78 1.1 lukem mapping = (struct ldapmapping *)ch_calloc( 2,
79 1.1 lukem sizeof( struct ldapmapping ) );
80 1.1 lukem if ( mapping == NULL ) {
81 1.1 lukem return LDAP_NO_MEMORY;
82 1.1 lukem }
83 1.1 lukem
84 1.1 lukem /* FIXME: I don't think this is needed any more... */
85 1.1 lukem rc = slap_str2ad( "objectClass", &mapping[0].m_src_ad, &text );
86 1.1 lukem if ( rc != LDAP_SUCCESS ) {
87 1.1 lukem ch_free( mapping );
88 1.1 lukem return rc;
89 1.1 lukem }
90 1.1 lukem
91 1.1 lukem mapping[0].m_dst_ad = mapping[0].m_src_ad;
92 1.1 lukem ber_dupbv( &mapping[0].m_src, &mapping[0].m_src_ad->ad_cname );
93 1.1 lukem ber_dupbv( &mapping[0].m_dst, &mapping[0].m_src );
94 1.1 lukem
95 1.1 lukem mapping[1].m_src = mapping[0].m_src;
96 1.1 lukem mapping[1].m_dst = mapping[0].m_dst;
97 1.1 lukem mapping[1].m_src_ad = mapping[0].m_src_ad;
98 1.1 lukem mapping[1].m_dst_ad = mapping[1].m_src_ad;
99 1.1 lukem
100 1.1 lukem avl_insert( &lm->map, (caddr_t)&mapping[0],
101 1.1 lukem rwm_mapping_cmp, rwm_mapping_dup );
102 1.1 lukem avl_insert( &lm->remap, (caddr_t)&mapping[1],
103 1.1 lukem rwm_mapping_cmp, rwm_mapping_dup );
104 1.1 lukem
105 1.1 lukem *m = mapping;
106 1.1 lukem
107 1.1 lukem return rc;
108 1.1 lukem }
109 1.1 lukem
110 1.1 lukem int
111 1.1 lukem rwm_mapping( struct ldapmap *map, struct berval *s, struct ldapmapping **m, int remap )
112 1.1 lukem {
113 1.1 lukem Avlnode *tree;
114 1.1 lukem struct ldapmapping fmapping;
115 1.1 lukem
116 1.1 lukem if ( map == NULL ) {
117 1.1 lukem return 0;
118 1.1 lukem }
119 1.1 lukem
120 1.1 lukem assert( m != NULL );
121 1.1 lukem
122 1.1 lukem if ( remap == RWM_REMAP ) {
123 1.1 lukem tree = map->remap;
124 1.1 lukem
125 1.1 lukem } else {
126 1.1 lukem tree = map->map;
127 1.1 lukem }
128 1.1 lukem
129 1.1 lukem fmapping.m_src = *s;
130 1.1 lukem *m = (struct ldapmapping *)avl_find( tree, (caddr_t)&fmapping,
131 1.1 lukem rwm_mapping_cmp );
132 1.1 lukem
133 1.1 lukem if ( *m == NULL ) {
134 1.1 lukem return map->drop_missing;
135 1.1 lukem }
136 1.1 lukem
137 1.1 lukem return 0;
138 1.1 lukem }
139 1.1 lukem
140 1.1 lukem void
141 1.1 lukem rwm_map( struct ldapmap *map, struct berval *s, struct berval *bv, int remap )
142 1.1 lukem {
143 1.1 lukem struct ldapmapping *mapping;
144 1.1 lukem
145 1.1 lukem /* map->map may be NULL when mapping is configured,
146 1.1 lukem * but map->remap can't */
147 1.1 lukem if ( map->remap == NULL ) {
148 1.1 lukem *bv = *s;
149 1.1 lukem return;
150 1.1 lukem }
151 1.1 lukem
152 1.1 lukem BER_BVZERO( bv );
153 1.1 lukem ( void )rwm_mapping( map, s, &mapping, remap );
154 1.1 lukem if ( mapping != NULL ) {
155 1.1 lukem if ( !BER_BVISNULL( &mapping->m_dst ) ) {
156 1.1 lukem *bv = mapping->m_dst;
157 1.1 lukem }
158 1.1 lukem return;
159 1.1 lukem }
160 1.1 lukem
161 1.1 lukem if ( !map->drop_missing ) {
162 1.1 lukem *bv = *s;
163 1.1 lukem }
164 1.1 lukem }
165 1.1 lukem
166 1.1 lukem /*
167 1.1 lukem * Map attribute names in place
168 1.1 lukem */
169 1.1 lukem int
170 1.1 lukem rwm_map_attrnames(
171 1.1 lukem struct ldapmap *at_map,
172 1.1 lukem struct ldapmap *oc_map,
173 1.1 lukem AttributeName *an,
174 1.1 lukem AttributeName **anp,
175 1.1 lukem int remap )
176 1.1 lukem {
177 1.1 lukem int i, j;
178 1.1 lukem
179 1.1 lukem assert( anp != NULL );
180 1.1 lukem
181 1.1 lukem *anp = NULL;
182 1.1 lukem
183 1.1 lukem if ( an == NULL ) {
184 1.1 lukem return LDAP_SUCCESS;
185 1.1 lukem }
186 1.1 lukem
187 1.1 lukem for ( i = 0; !BER_BVISNULL( &an[i].an_name ); i++ )
188 1.1 lukem /* just count */ ;
189 1.1 lukem *anp = ch_malloc( ( i + 1 )* sizeof( AttributeName ) );
190 1.1 lukem if ( *anp == NULL ) {
191 1.1 lukem return LDAP_NO_MEMORY;
192 1.1 lukem }
193 1.1 lukem
194 1.1 lukem for ( i = 0, j = 0; !BER_BVISNULL( &an[i].an_name ); i++ ) {
195 1.1 lukem struct ldapmapping *m;
196 1.1 lukem int at_drop_missing = 0,
197 1.1 lukem oc_drop_missing = 0;
198 1.1 lukem
199 1.1 lukem if ( an[i].an_desc ) {
200 1.1 lukem if ( !at_map ) {
201 1.1 lukem /* FIXME: better leave as is? */
202 1.1 lukem continue;
203 1.1 lukem }
204 1.1 lukem
205 1.1 lukem at_drop_missing = rwm_mapping( at_map, &an[i].an_name, &m, remap );
206 1.1 lukem if ( at_drop_missing || ( m && BER_BVISNULL( &m->m_dst ) ) ) {
207 1.1 lukem continue;
208 1.1 lukem }
209 1.1 lukem
210 1.1 lukem if ( !m ) {
211 1.1 lukem (*anp)[j] = an[i];
212 1.1 lukem j++;
213 1.1 lukem continue;
214 1.1 lukem }
215 1.1 lukem
216 1.1 lukem (*anp)[j] = an[i];
217 1.1 lukem if ( remap == RWM_MAP ) {
218 1.1 lukem (*anp)[j].an_name = m->m_dst;
219 1.1 lukem (*anp)[j].an_desc = m->m_dst_ad;
220 1.1 lukem } else {
221 1.1 lukem (*anp)[j].an_name = m->m_src;
222 1.1 lukem (*anp)[j].an_desc = m->m_src_ad;
223 1.1 lukem
224 1.1 lukem }
225 1.1 lukem
226 1.1 lukem j++;
227 1.1 lukem continue;
228 1.1 lukem
229 1.1 lukem } else if ( an[i].an_oc ) {
230 1.1 lukem if ( !oc_map ) {
231 1.1 lukem /* FIXME: better leave as is? */
232 1.1 lukem continue;
233 1.1 lukem }
234 1.1 lukem
235 1.1 lukem oc_drop_missing = rwm_mapping( oc_map, &an[i].an_name, &m, remap );
236 1.1 lukem
237 1.1 lukem if ( oc_drop_missing || ( m && BER_BVISNULL( &m->m_dst ) ) ) {
238 1.1 lukem continue;
239 1.1 lukem }
240 1.1 lukem
241 1.1 lukem if ( !m ) {
242 1.1 lukem (*anp)[j] = an[i];
243 1.1 lukem j++;
244 1.1 lukem continue;
245 1.1 lukem }
246 1.1 lukem
247 1.1 lukem (*anp)[j] = an[i];
248 1.1 lukem if ( remap == RWM_MAP ) {
249 1.1 lukem (*anp)[j].an_name = m->m_dst;
250 1.1 lukem (*anp)[j].an_oc = m->m_dst_oc;
251 1.1 lukem } else {
252 1.1 lukem (*anp)[j].an_name = m->m_src;
253 1.1 lukem (*anp)[j].an_oc = m->m_src_oc;
254 1.1 lukem }
255 1.1 lukem
256 1.1 lukem } else {
257 1.1 lukem at_drop_missing = rwm_mapping( at_map, &an[i].an_name, &m, remap );
258 1.1 lukem
259 1.1 lukem if ( at_drop_missing || !m ) {
260 1.1 lukem oc_drop_missing = rwm_mapping( oc_map, &an[i].an_name, &m, remap );
261 1.1 lukem
262 1.1 lukem /* if both at_map and oc_map required to drop missing,
263 1.1 lukem * then do it */
264 1.1 lukem if ( oc_drop_missing && at_drop_missing ) {
265 1.1 lukem continue;
266 1.1 lukem }
267 1.1 lukem
268 1.1 lukem /* if no oc_map mapping was found and at_map required
269 1.1 lukem * to drop missing, then do it; otherwise, at_map wins
270 1.1 lukem * and an is considered an attr and is left unchanged */
271 1.1 lukem if ( !m ) {
272 1.1 lukem if ( at_drop_missing ) {
273 1.1 lukem continue;
274 1.1 lukem }
275 1.1 lukem (*anp)[j] = an[i];
276 1.1 lukem j++;
277 1.1 lukem continue;
278 1.1 lukem }
279 1.1 lukem
280 1.1 lukem if ( BER_BVISNULL( &m->m_dst ) ) {
281 1.1 lukem continue;
282 1.1 lukem }
283 1.1 lukem
284 1.1 lukem (*anp)[j] = an[i];
285 1.1 lukem if ( remap == RWM_MAP ) {
286 1.1 lukem (*anp)[j].an_name = m->m_dst;
287 1.1 lukem (*anp)[j].an_oc = m->m_dst_oc;
288 1.1 lukem } else {
289 1.1 lukem (*anp)[j].an_name = m->m_src;
290 1.1 lukem (*anp)[j].an_oc = m->m_src_oc;
291 1.1 lukem }
292 1.1 lukem j++;
293 1.1 lukem continue;
294 1.1 lukem }
295 1.1 lukem
296 1.1 lukem if ( !BER_BVISNULL( &m->m_dst ) ) {
297 1.1 lukem (*anp)[j] = an[i];
298 1.1 lukem if ( remap == RWM_MAP ) {
299 1.1 lukem (*anp)[j].an_name = m->m_dst;
300 1.1 lukem (*anp)[j].an_desc = m->m_dst_ad;
301 1.1 lukem } else {
302 1.1 lukem (*anp)[j].an_name = m->m_src;
303 1.1 lukem (*anp)[j].an_desc = m->m_src_ad;
304 1.1 lukem }
305 1.1 lukem j++;
306 1.1 lukem continue;
307 1.1 lukem }
308 1.1 lukem }
309 1.1 lukem }
310 1.1 lukem
311 1.1 lukem if ( j == 0 && i != 0 ) {
312 1.1 lukem memset( &(*anp)[0], 0, sizeof( AttributeName ) );
313 1.1 lukem BER_BVSTR( &(*anp)[0].an_name, LDAP_NO_ATTRS );
314 1.1 lukem j = 1;
315 1.1 lukem }
316 1.1 lukem memset( &(*anp)[j], 0, sizeof( AttributeName ) );
317 1.1 lukem
318 1.1 lukem return LDAP_SUCCESS;
319 1.1 lukem }
320 1.1 lukem
321 1.1 lukem int
322 1.1 lukem rwm_map_attrs(
323 1.1 lukem struct ldapmap *at_map,
324 1.1 lukem AttributeName *an,
325 1.1 lukem int remap,
326 1.1 lukem char ***mapped_attrs )
327 1.1 lukem {
328 1.1 lukem int i, j;
329 1.1 lukem char **na;
330 1.1 lukem
331 1.1 lukem if ( an == NULL ) {
332 1.1 lukem *mapped_attrs = NULL;
333 1.1 lukem return LDAP_SUCCESS;
334 1.1 lukem }
335 1.1 lukem
336 1.1 lukem for ( i = 0; !BER_BVISNULL( &an[ i ].an_name ); i++ )
337 1.1 lukem /* count'em */ ;
338 1.1 lukem
339 1.1 lukem na = (char **)ch_calloc( i + 1, sizeof( char * ) );
340 1.1 lukem if ( na == NULL ) {
341 1.1 lukem *mapped_attrs = NULL;
342 1.1 lukem return LDAP_NO_MEMORY;
343 1.1 lukem }
344 1.1 lukem
345 1.1 lukem for ( i = j = 0; !BER_BVISNULL( &an[i].an_name ); i++ ) {
346 1.1 lukem struct ldapmapping *mapping;
347 1.1 lukem
348 1.1 lukem if ( rwm_mapping( at_map, &an[i].an_name, &mapping, remap ) ) {
349 1.1 lukem continue;
350 1.1 lukem }
351 1.1 lukem
352 1.1 lukem if ( !mapping ) {
353 1.1 lukem na[ j++ ] = an[ i ].an_name.bv_val;
354 1.1 lukem
355 1.1 lukem } else if ( !BER_BVISNULL( &mapping->m_dst ) ) {
356 1.1 lukem na[ j++ ] = mapping->m_dst.bv_val;
357 1.1 lukem }
358 1.1 lukem }
359 1.1 lukem
360 1.1 lukem if ( j == 0 && i != 0 ) {
361 1.1 lukem na[ j++ ] = LDAP_NO_ATTRS;
362 1.1 lukem }
363 1.1 lukem
364 1.1 lukem na[ j ] = NULL;
365 1.1 lukem
366 1.1 lukem *mapped_attrs = na;
367 1.1 lukem
368 1.1 lukem return LDAP_SUCCESS;
369 1.1 lukem }
370 1.1 lukem
371 1.1 lukem static int
372 1.1 lukem map_attr_value(
373 1.1 lukem dncookie *dc,
374 1.1 lukem AttributeDescription **adp,
375 1.1 lukem struct berval *mapped_attr,
376 1.1 lukem struct berval *value,
377 1.1 lukem struct berval *mapped_value,
378 1.1 lukem int remap )
379 1.1 lukem {
380 1.1 lukem struct berval vtmp = BER_BVNULL;
381 1.1 lukem int freeval = 0;
382 1.1 lukem AttributeDescription *ad = *adp;
383 1.1 lukem struct ldapmapping *mapping = NULL;
384 1.1 lukem
385 1.1 lukem rwm_mapping( &dc->rwmap->rwm_at, &ad->ad_cname, &mapping, remap );
386 1.1 lukem if ( mapping == NULL ) {
387 1.1 lukem if ( dc->rwmap->rwm_at.drop_missing ) {
388 1.1 lukem return -1;
389 1.1 lukem }
390 1.1 lukem
391 1.1 lukem *mapped_attr = ad->ad_cname;
392 1.1 lukem
393 1.1 lukem } else {
394 1.1 lukem *mapped_attr = mapping->m_dst;
395 1.1 lukem }
396 1.1 lukem
397 1.1 lukem if ( value != NULL ) {
398 1.1 lukem assert( mapped_value != NULL );
399 1.1 lukem
400 1.1 lukem if ( ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName
401 1.1 lukem || ( mapping != NULL && mapping->m_dst_ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName ) )
402 1.1 lukem {
403 1.1 lukem dncookie fdc = *dc;
404 1.1 lukem int rc;
405 1.1 lukem
406 1.1 lukem fdc.ctx = "searchFilterAttrDN";
407 1.1 lukem
408 1.1 lukem vtmp = *value;
409 1.1 lukem rc = rwm_dn_massage_normalize( &fdc, value, &vtmp );
410 1.1 lukem switch ( rc ) {
411 1.1 lukem case LDAP_SUCCESS:
412 1.1 lukem if ( vtmp.bv_val != value->bv_val ) {
413 1.1 lukem freeval = 1;
414 1.1 lukem }
415 1.1 lukem break;
416 1.1 lukem
417 1.1 lukem case LDAP_UNWILLING_TO_PERFORM:
418 1.1 lukem case LDAP_OTHER:
419 1.1 lukem default:
420 1.1 lukem return -1;
421 1.1 lukem }
422 1.1 lukem
423 1.1 lukem } else if ( ad->ad_type->sat_equality->smr_usage & SLAP_MR_MUTATION_NORMALIZER ) {
424 1.1 lukem if ( ad->ad_type->sat_equality->smr_normalize(
425 1.1 lukem (SLAP_MR_DENORMALIZE|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX),
426 1.1 lukem NULL, NULL, value, &vtmp, NULL ) )
427 1.1 lukem {
428 1.1 lukem return -1;
429 1.1 lukem }
430 1.1 lukem freeval = 1;
431 1.1 lukem
432 1.1 lukem } else if ( ad == slap_schema.si_ad_objectClass
433 1.1 lukem || ad == slap_schema.si_ad_structuralObjectClass )
434 1.1 lukem {
435 1.1 lukem rwm_map( &dc->rwmap->rwm_oc, value, &vtmp, remap );
436 1.1 lukem if ( BER_BVISNULL( &vtmp ) || BER_BVISEMPTY( &vtmp ) ) {
437 1.1 lukem vtmp = *value;
438 1.1 lukem }
439 1.1 lukem
440 1.1 lukem } else {
441 1.1 lukem vtmp = *value;
442 1.1 lukem }
443 1.1 lukem
444 1.1 lukem filter_escape_value( &vtmp, mapped_value );
445 1.1 lukem
446 1.1 lukem if ( freeval ) {
447 1.1 lukem ch_free( vtmp.bv_val );
448 1.1 lukem }
449 1.1 lukem }
450 1.1 lukem
451 1.1 lukem if ( mapping != NULL ) {
452 1.1 lukem assert( mapping->m_dst_ad != NULL );
453 1.1 lukem *adp = mapping->m_dst_ad;
454 1.1 lukem }
455 1.1 lukem
456 1.1 lukem return 0;
457 1.1 lukem }
458 1.1 lukem
459 1.1 lukem static int
460 1.1 lukem rwm_int_filter_map_rewrite(
461 1.1 lukem Operation *op,
462 1.1 lukem dncookie *dc,
463 1.1 lukem Filter *f,
464 1.1 lukem struct berval *fstr )
465 1.1 lukem {
466 1.1 lukem int i;
467 1.1 lukem Filter *p;
468 1.1 lukem AttributeDescription *ad;
469 1.1 lukem struct berval atmp,
470 1.1 lukem vtmp,
471 1.1 lukem *tmp;
472 1.1 lukem static struct berval
473 1.1 lukem /* better than nothing... */
474 1.1 lukem ber_bvfalse = BER_BVC( "(!(objectClass=*))" ),
475 1.1 lukem ber_bvtf_false = BER_BVC( "(|)" ),
476 1.1 lukem /* better than nothing... */
477 1.1 lukem ber_bvtrue = BER_BVC( "(objectClass=*)" ),
478 1.1 lukem ber_bvtf_true = BER_BVC( "(&)" ),
479 1.1 lukem #if 0
480 1.1 lukem /* no longer needed; preserved for completeness */
481 1.1 lukem ber_bvundefined = BER_BVC( "(?=undefined)" ),
482 1.1 lukem #endif
483 1.1 lukem ber_bverror = BER_BVC( "(?=error)" ),
484 1.1 lukem ber_bvunknown = BER_BVC( "(?=unknown)" ),
485 1.1 lukem ber_bvnone = BER_BVC( "(?=none)" );
486 1.1 lukem ber_len_t len;
487 1.1 lukem
488 1.1 lukem assert( fstr != NULL );
489 1.1 lukem BER_BVZERO( fstr );
490 1.1 lukem
491 1.1 lukem if ( f == NULL ) {
492 1.1 lukem ber_dupbv( fstr, &ber_bvnone );
493 1.1 lukem return LDAP_OTHER;
494 1.1 lukem }
495 1.1 lukem
496 1.1 lukem switch ( f->f_choice & SLAPD_FILTER_MASK ) {
497 1.1 lukem case LDAP_FILTER_EQUALITY:
498 1.1 lukem ad = f->f_av_desc;
499 1.1 lukem if ( map_attr_value( dc, &ad, &atmp,
500 1.1 lukem &f->f_av_value, &vtmp, RWM_MAP ) )
501 1.1 lukem {
502 1.1 lukem goto computed;
503 1.1 lukem }
504 1.1 lukem
505 1.1 lukem fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(=)" );
506 1.1 lukem fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
507 1.1 lukem
508 1.1 lukem snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=%s)",
509 1.1 lukem atmp.bv_val, vtmp.bv_len ? vtmp.bv_val : "" );
510 1.1 lukem
511 1.1 lukem ch_free( vtmp.bv_val );
512 1.1 lukem break;
513 1.1 lukem
514 1.1 lukem case LDAP_FILTER_GE:
515 1.1 lukem ad = f->f_av_desc;
516 1.1 lukem if ( map_attr_value( dc, &ad, &atmp,
517 1.1 lukem &f->f_av_value, &vtmp, RWM_MAP ) )
518 1.1 lukem {
519 1.1 lukem goto computed;
520 1.1 lukem }
521 1.1 lukem
522 1.1 lukem fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(>=)" );
523 1.1 lukem fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
524 1.1 lukem
525 1.1 lukem snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s>=%s)",
526 1.1 lukem atmp.bv_val, vtmp.bv_len ? vtmp.bv_val : "" );
527 1.1 lukem
528 1.1 lukem ch_free( vtmp.bv_val );
529 1.1 lukem break;
530 1.1 lukem
531 1.1 lukem case LDAP_FILTER_LE:
532 1.1 lukem ad = f->f_av_desc;
533 1.1 lukem if ( map_attr_value( dc, &ad, &atmp,
534 1.1 lukem &f->f_av_value, &vtmp, RWM_MAP ) )
535 1.1 lukem {
536 1.1 lukem goto computed;
537 1.1 lukem }
538 1.1 lukem
539 1.1 lukem fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(<=)" );
540 1.1 lukem fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
541 1.1 lukem
542 1.1 lukem snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s<=%s)",
543 1.1 lukem atmp.bv_val, vtmp.bv_len ? vtmp.bv_val : "" );
544 1.1 lukem
545 1.1 lukem ch_free( vtmp.bv_val );
546 1.1 lukem break;
547 1.1 lukem
548 1.1 lukem case LDAP_FILTER_APPROX:
549 1.1 lukem ad = f->f_av_desc;
550 1.1 lukem if ( map_attr_value( dc, &ad, &atmp,
551 1.1 lukem &f->f_av_value, &vtmp, RWM_MAP ) )
552 1.1 lukem {
553 1.1 lukem goto computed;
554 1.1 lukem }
555 1.1 lukem
556 1.1 lukem fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(~=)" );
557 1.1 lukem fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
558 1.1 lukem
559 1.1 lukem snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s~=%s)",
560 1.1 lukem atmp.bv_val, vtmp.bv_len ? vtmp.bv_val : "" );
561 1.1 lukem
562 1.1 lukem ch_free( vtmp.bv_val );
563 1.1 lukem break;
564 1.1 lukem
565 1.1 lukem case LDAP_FILTER_SUBSTRINGS:
566 1.1 lukem ad = f->f_sub_desc;
567 1.1 lukem if ( map_attr_value( dc, &ad, &atmp,
568 1.1 lukem NULL, NULL, RWM_MAP ) )
569 1.1 lukem {
570 1.1 lukem goto computed;
571 1.1 lukem }
572 1.1 lukem
573 1.1 lukem /* cannot be a DN ... */
574 1.1 lukem
575 1.1 lukem fstr->bv_len = atmp.bv_len + STRLENOF( "(=*)" );
576 1.1 lukem fstr->bv_val = ch_malloc( fstr->bv_len + 128 );
577 1.1 lukem
578 1.1 lukem snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
579 1.1 lukem atmp.bv_val );
580 1.1 lukem
581 1.1 lukem if ( !BER_BVISNULL( &f->f_sub_initial ) ) {
582 1.1 lukem len = fstr->bv_len;
583 1.1 lukem
584 1.1 lukem filter_escape_value( &f->f_sub_initial, &vtmp );
585 1.1 lukem
586 1.1 lukem fstr->bv_len += vtmp.bv_len;
587 1.1 lukem fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
588 1.1 lukem
589 1.1 lukem snprintf( &fstr->bv_val[len - 2], vtmp.bv_len + 3,
590 1.1 lukem /* "(attr=" */ "%s*)",
591 1.1 lukem vtmp.bv_len ? vtmp.bv_val : "" );
592 1.1 lukem
593 1.1 lukem ch_free( vtmp.bv_val );
594 1.1 lukem }
595 1.1 lukem
596 1.1 lukem if ( f->f_sub_any != NULL ) {
597 1.1 lukem for ( i = 0; !BER_BVISNULL( &f->f_sub_any[i] ); i++ ) {
598 1.1 lukem len = fstr->bv_len;
599 1.1 lukem filter_escape_value( &f->f_sub_any[i], &vtmp );
600 1.1 lukem
601 1.1 lukem fstr->bv_len += vtmp.bv_len + 1;
602 1.1 lukem fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
603 1.1 lukem
604 1.1 lukem snprintf( &fstr->bv_val[len - 1], vtmp.bv_len + 3,
605 1.1 lukem /* "(attr=[init]*[any*]" */ "%s*)",
606 1.1 lukem vtmp.bv_len ? vtmp.bv_val : "" );
607 1.1 lukem ch_free( vtmp.bv_val );
608 1.1 lukem }
609 1.1 lukem }
610 1.1 lukem
611 1.1 lukem if ( !BER_BVISNULL( &f->f_sub_final ) ) {
612 1.1 lukem len = fstr->bv_len;
613 1.1 lukem
614 1.1 lukem filter_escape_value( &f->f_sub_final, &vtmp );
615 1.1 lukem
616 1.1 lukem fstr->bv_len += vtmp.bv_len;
617 1.1 lukem fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
618 1.1 lukem
619 1.1 lukem snprintf( &fstr->bv_val[len - 1], vtmp.bv_len + 3,
620 1.1 lukem /* "(attr=[init*][any*]" */ "%s)",
621 1.1 lukem vtmp.bv_len ? vtmp.bv_val : "" );
622 1.1 lukem
623 1.1 lukem ch_free( vtmp.bv_val );
624 1.1 lukem }
625 1.1 lukem
626 1.1 lukem break;
627 1.1 lukem
628 1.1 lukem case LDAP_FILTER_PRESENT:
629 1.1 lukem ad = f->f_desc;
630 1.1 lukem if ( map_attr_value( dc, &ad, &atmp,
631 1.1 lukem NULL, NULL, RWM_MAP ) )
632 1.1 lukem {
633 1.1 lukem goto computed;
634 1.1 lukem }
635 1.1 lukem
636 1.1 lukem fstr->bv_len = atmp.bv_len + STRLENOF( "(=*)" );
637 1.1 lukem fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
638 1.1 lukem
639 1.1 lukem snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
640 1.1 lukem atmp.bv_val );
641 1.1 lukem break;
642 1.1 lukem
643 1.1 lukem case LDAP_FILTER_AND:
644 1.1 lukem case LDAP_FILTER_OR:
645 1.1 lukem case LDAP_FILTER_NOT:
646 1.1 lukem fstr->bv_len = STRLENOF( "(%)" );
647 1.1 lukem fstr->bv_val = ch_malloc( fstr->bv_len + 128 );
648 1.1 lukem
649 1.1 lukem snprintf( fstr->bv_val, fstr->bv_len + 1, "(%c)",
650 1.1 lukem f->f_choice == LDAP_FILTER_AND ? '&' :
651 1.1 lukem f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
652 1.1 lukem
653 1.1 lukem for ( p = f->f_list; p != NULL; p = p->f_next ) {
654 1.1 lukem int rc;
655 1.1 lukem
656 1.1 lukem len = fstr->bv_len;
657 1.1 lukem
658 1.1 lukem rc = rwm_int_filter_map_rewrite( op, dc, p, &vtmp );
659 1.1 lukem if ( rc != LDAP_SUCCESS ) {
660 1.1 lukem return rc;
661 1.1 lukem }
662 1.1 lukem
663 1.1 lukem fstr->bv_len += vtmp.bv_len;
664 1.1 lukem fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
665 1.1 lukem
666 1.1 lukem snprintf( &fstr->bv_val[len-1], vtmp.bv_len + 2,
667 1.1 lukem /*"("*/ "%s)", vtmp.bv_len ? vtmp.bv_val : "" );
668 1.1 lukem
669 1.1 lukem ch_free( vtmp.bv_val );
670 1.1 lukem }
671 1.1 lukem
672 1.1 lukem break;
673 1.1 lukem
674 1.1 lukem case LDAP_FILTER_EXT: {
675 1.1 lukem if ( f->f_mr_desc ) {
676 1.1 lukem ad = f->f_mr_desc;
677 1.1 lukem if ( map_attr_value( dc, &ad, &atmp,
678 1.1 lukem &f->f_mr_value, &vtmp, RWM_MAP ) )
679 1.1 lukem {
680 1.1 lukem goto computed;
681 1.1 lukem }
682 1.1 lukem
683 1.1 lukem } else {
684 1.1 lukem BER_BVSTR( &atmp, "" );
685 1.1 lukem filter_escape_value( &f->f_mr_value, &vtmp );
686 1.1 lukem }
687 1.1 lukem
688 1.1 lukem
689 1.1 lukem fstr->bv_len = atmp.bv_len +
690 1.1 lukem ( f->f_mr_dnattrs ? STRLENOF( ":dn" ) : 0 ) +
691 1.1 lukem ( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len + 1 : 0 ) +
692 1.1 lukem vtmp.bv_len + STRLENOF( "(:=)" );
693 1.1 lukem fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
694 1.1 lukem
695 1.1 lukem snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)",
696 1.1 lukem atmp.bv_val,
697 1.1 lukem f->f_mr_dnattrs ? ":dn" : "",
698 1.1 lukem !BER_BVISEMPTY( &f->f_mr_rule_text ) ? ":" : "",
699 1.1 lukem !BER_BVISEMPTY( &f->f_mr_rule_text ) ? f->f_mr_rule_text.bv_val : "",
700 1.1 lukem vtmp.bv_len ? vtmp.bv_val : "" );
701 1.1 lukem ch_free( vtmp.bv_val );
702 1.1 lukem break;
703 1.1 lukem }
704 1.1 lukem
705 1.1 lukem case -1:
706 1.1 lukem computed:;
707 1.1 lukem filter_free_x( op, f );
708 1.1 lukem f->f_choice = SLAPD_FILTER_COMPUTED;
709 1.1 lukem f->f_result = SLAPD_COMPARE_UNDEFINED;
710 1.1 lukem /* fallthru */
711 1.1 lukem
712 1.1 lukem case SLAPD_FILTER_COMPUTED:
713 1.1 lukem switch ( f->f_result ) {
714 1.1 lukem case LDAP_COMPARE_FALSE:
715 1.1 lukem /* FIXME: treat UNDEFINED as FALSE */
716 1.1 lukem case SLAPD_COMPARE_UNDEFINED:
717 1.1 lukem if ( dc->rwmap->rwm_flags & RWM_F_SUPPORT_T_F ) {
718 1.1 lukem tmp = &ber_bvtf_false;
719 1.1 lukem break;
720 1.1 lukem }
721 1.1 lukem tmp = &ber_bvfalse;
722 1.1 lukem break;
723 1.1 lukem
724 1.1 lukem case LDAP_COMPARE_TRUE:
725 1.1 lukem if ( dc->rwmap->rwm_flags & RWM_F_SUPPORT_T_F ) {
726 1.1 lukem tmp = &ber_bvtf_true;
727 1.1 lukem break;
728 1.1 lukem }
729 1.1 lukem tmp = &ber_bvtrue;
730 1.1 lukem break;
731 1.1 lukem
732 1.1 lukem default:
733 1.1 lukem tmp = &ber_bverror;
734 1.1 lukem break;
735 1.1 lukem }
736 1.1 lukem
737 1.1 lukem ber_dupbv( fstr, tmp );
738 1.1 lukem break;
739 1.1 lukem
740 1.1 lukem default:
741 1.1 lukem ber_dupbv( fstr, &ber_bvunknown );
742 1.1 lukem break;
743 1.1 lukem }
744 1.1 lukem
745 1.1 lukem return LDAP_SUCCESS;
746 1.1 lukem }
747 1.1 lukem
748 1.1 lukem int
749 1.1 lukem rwm_filter_map_rewrite(
750 1.1 lukem Operation *op,
751 1.1 lukem dncookie *dc,
752 1.1 lukem Filter *f,
753 1.1 lukem struct berval *fstr )
754 1.1 lukem {
755 1.1 lukem int rc;
756 1.1 lukem dncookie fdc;
757 1.1 lukem struct berval ftmp;
758 1.1 lukem
759 1.1 lukem rc = rwm_int_filter_map_rewrite( op, dc, f, fstr );
760 1.1 lukem
761 1.1 lukem if ( rc != 0 ) {
762 1.1 lukem return rc;
763 1.1 lukem }
764 1.1 lukem
765 1.1 lukem fdc = *dc;
766 1.1 lukem ftmp = *fstr;
767 1.1 lukem
768 1.1 lukem fdc.ctx = "searchFilter";
769 1.1 lukem
770 1.1 lukem switch ( rewrite_session( fdc.rwmap->rwm_rw, fdc.ctx,
771 1.1 lukem ( !BER_BVISEMPTY( &ftmp ) ? ftmp.bv_val : "" ),
772 1.1 lukem fdc.conn, &fstr->bv_val ) )
773 1.1 lukem {
774 1.1 lukem case REWRITE_REGEXEC_OK:
775 1.1 lukem if ( !BER_BVISNULL( fstr ) ) {
776 1.1 lukem fstr->bv_len = strlen( fstr->bv_val );
777 1.1 lukem if ( fstr->bv_val != ftmp.bv_val ) {
778 1.1 lukem ch_free( ftmp.bv_val );
779 1.1 lukem }
780 1.1 lukem
781 1.1 lukem } else {
782 1.1 lukem *fstr = ftmp;
783 1.1 lukem }
784 1.1 lukem
785 1.1 lukem Debug( LDAP_DEBUG_ARGS,
786 1.1 lukem "[rw] %s: \"%s\" -> \"%s\"\n",
787 1.1 lukem fdc.ctx, ftmp.bv_val, fstr->bv_val );
788 1.1 lukem rc = LDAP_SUCCESS;
789 1.1 lukem break;
790 1.1 lukem
791 1.1 lukem case REWRITE_REGEXEC_UNWILLING:
792 1.1 lukem if ( fdc.rs ) {
793 1.1 lukem fdc.rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
794 1.1 lukem fdc.rs->sr_text = "Operation not allowed";
795 1.1 lukem }
796 1.1 lukem rc = LDAP_UNWILLING_TO_PERFORM;
797 1.1 lukem break;
798 1.1 lukem
799 1.1 lukem case REWRITE_REGEXEC_ERR:
800 1.1 lukem if ( fdc.rs ) {
801 1.1 lukem fdc.rs->sr_err = LDAP_OTHER;
802 1.1 lukem fdc.rs->sr_text = "Rewrite error";
803 1.1 lukem }
804 1.1 lukem rc = LDAP_OTHER;
805 1.1 lukem break;
806 1.1 lukem }
807 1.1 lukem
808 1.1 lukem return rc;
809 1.1 lukem }
810 1.1 lukem
811 1.1 lukem /*
812 1.1 lukem * I don't like this much, but we need two different
813 1.1 lukem * functions because different heap managers may be
814 1.1 lukem * in use in back-ldap/meta to reduce the amount of
815 1.1 lukem * calls to malloc routines, and some of the free()
816 1.1 lukem * routines may be macros with args
817 1.1 lukem */
818 1.1 lukem int
819 1.1 lukem rwm_referral_rewrite(
820 1.1 lukem Operation *op,
821 1.1 lukem SlapReply *rs,
822 1.1 lukem void *cookie,
823 1.1 lukem BerVarray a_vals,
824 1.1 lukem BerVarray *pa_nvals )
825 1.1 lukem {
826 1.1 lukem slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
827 1.1 lukem struct ldaprwmap *rwmap =
828 1.1 lukem (struct ldaprwmap *)on->on_bi.bi_private;
829 1.1 lukem
830 1.1 lukem int i, last;
831 1.1 lukem
832 1.1 lukem dncookie dc;
833 1.1 lukem struct berval dn = BER_BVNULL,
834 1.1 lukem ndn = BER_BVNULL;
835 1.1 lukem
836 1.1 lukem assert( a_vals != NULL );
837 1.1 lukem
838 1.1 lukem /*
839 1.1 lukem * Rewrite the dn if needed
840 1.1 lukem */
841 1.1 lukem dc.rwmap = rwmap;
842 1.1 lukem dc.conn = op->o_conn;
843 1.1 lukem dc.rs = rs;
844 1.1 lukem dc.ctx = (char *)cookie;
845 1.1 lukem
846 1.1 lukem for ( last = 0; !BER_BVISNULL( &a_vals[last] ); last++ )
847 1.1 lukem ;
848 1.1 lukem last--;
849 1.1 lukem
850 1.1 lukem if ( pa_nvals != NULL ) {
851 1.1 lukem if ( *pa_nvals == NULL ) {
852 1.1 lukem *pa_nvals = ch_malloc( ( last + 2 ) * sizeof(struct berval) );
853 1.1 lukem memset( *pa_nvals, 0, ( last + 2 ) * sizeof(struct berval) );
854 1.1 lukem }
855 1.1 lukem }
856 1.1 lukem
857 1.1 lukem for ( i = 0; !BER_BVISNULL( &a_vals[i] ); i++ ) {
858 1.1 lukem struct berval olddn = BER_BVNULL,
859 1.1 lukem oldval;
860 1.1 lukem int rc;
861 1.1 lukem LDAPURLDesc *ludp;
862 1.1 lukem
863 1.1 lukem oldval = a_vals[i];
864 1.1 lukem rc = ldap_url_parse( oldval.bv_val, &ludp );
865 1.1 lukem if ( rc != LDAP_URL_SUCCESS ) {
866 1.1 lukem /* leave attr untouched if massage failed */
867 1.1 lukem if ( pa_nvals && BER_BVISNULL( &(*pa_nvals)[i] ) ) {
868 1.1 lukem ber_dupbv( &(*pa_nvals)[i], &oldval );
869 1.1 lukem }
870 1.1 lukem continue;
871 1.1 lukem }
872 1.1 lukem
873 1.1 lukem /* FIXME: URLs like "ldap:///dc=suffix" if passed
874 1.1 lukem * thru ldap_url_parse() and ldap_url_desc2str()
875 1.1 lukem * get rewritten as "ldap:///dc=suffix??base";
876 1.1 lukem * we don't want this to occur... */
877 1.1 lukem if ( ludp->lud_scope == LDAP_SCOPE_BASE ) {
878 1.1 lukem ludp->lud_scope = LDAP_SCOPE_DEFAULT;
879 1.1 lukem }
880 1.1 lukem
881 1.1 lukem ber_str2bv( ludp->lud_dn, 0, 0, &olddn );
882 1.1 lukem
883 1.1 lukem dn = olddn;
884 1.1 lukem if ( pa_nvals ) {
885 1.1 lukem ndn = olddn;
886 1.1 lukem rc = rwm_dn_massage_pretty_normalize( &dc, &olddn,
887 1.1 lukem &dn, &ndn );
888 1.1 lukem } else {
889 1.1 lukem rc = rwm_dn_massage_pretty( &dc, &olddn, &dn );
890 1.1 lukem }
891 1.1 lukem
892 1.1 lukem switch ( rc ) {
893 1.1 lukem case LDAP_UNWILLING_TO_PERFORM:
894 1.1 lukem /*
895 1.1 lukem * FIXME: need to check if it may be considered
896 1.1 lukem * legal to trim values when adding/modifying;
897 1.1 lukem * it should be when searching (e.g. ACLs).
898 1.1 lukem */
899 1.1 lukem ch_free( a_vals[i].bv_val );
900 1.1 lukem if (last > i ) {
901 1.1 lukem a_vals[i] = a_vals[last];
902 1.1 lukem if ( pa_nvals ) {
903 1.1 lukem (*pa_nvals)[i] = (*pa_nvals)[last];
904 1.1 lukem }
905 1.1 lukem }
906 1.1 lukem BER_BVZERO( &a_vals[last] );
907 1.1 lukem if ( pa_nvals ) {
908 1.1 lukem BER_BVZERO( &(*pa_nvals)[last] );
909 1.1 lukem }
910 1.1 lukem last--;
911 1.1 lukem break;
912 1.1 lukem
913 1.1 lukem case LDAP_SUCCESS:
914 1.1 lukem if ( !BER_BVISNULL( &dn ) && dn.bv_val != olddn.bv_val ) {
915 1.1 lukem char *newurl;
916 1.1 lukem
917 1.1 lukem ludp->lud_dn = dn.bv_val;
918 1.1 lukem newurl = ldap_url_desc2str( ludp );
919 1.1 lukem ludp->lud_dn = olddn.bv_val;
920 1.1 lukem ch_free( dn.bv_val );
921 1.1 lukem if ( newurl == NULL ) {
922 1.1 lukem /* FIXME: leave attr untouched
923 1.1 lukem * even if ldap_url_desc2str failed...
924 1.1 lukem */
925 1.1 lukem break;
926 1.1 lukem }
927 1.1 lukem
928 1.1 lukem ber_str2bv( newurl, 0, 1, &a_vals[i] );
929 1.1 lukem LDAP_FREE( newurl );
930 1.1 lukem
931 1.1 lukem if ( pa_nvals ) {
932 1.1 lukem ludp->lud_dn = ndn.bv_val;
933 1.1 lukem newurl = ldap_url_desc2str( ludp );
934 1.1 lukem ludp->lud_dn = olddn.bv_val;
935 1.1 lukem ch_free( ndn.bv_val );
936 1.1 lukem if ( newurl == NULL ) {
937 1.1 lukem /* FIXME: leave attr untouched
938 1.1 lukem * even if ldap_url_desc2str failed...
939 1.1 lukem */
940 1.1 lukem ch_free( a_vals[i].bv_val );
941 1.1 lukem a_vals[i] = oldval;
942 1.1 lukem break;
943 1.1 lukem }
944 1.1 lukem
945 1.1 lukem if ( !BER_BVISNULL( &(*pa_nvals)[i] ) ) {
946 1.1 lukem ch_free( (*pa_nvals)[i].bv_val );
947 1.1 lukem }
948 1.1 lukem ber_str2bv( newurl, 0, 1, &(*pa_nvals)[i] );
949 1.1 lukem LDAP_FREE( newurl );
950 1.1 lukem }
951 1.1 lukem
952 1.1 lukem ch_free( oldval.bv_val );
953 1.1 lukem ludp->lud_dn = olddn.bv_val;
954 1.1 lukem }
955 1.1 lukem break;
956 1.1 lukem
957 1.1 lukem default:
958 1.1 lukem /* leave attr untouched if massage failed */
959 1.1 lukem if ( pa_nvals && BER_BVISNULL( &(*pa_nvals)[i] ) ) {
960 1.1 lukem ber_dupbv( &(*pa_nvals)[i], &a_vals[i] );
961 1.1 lukem }
962 1.1 lukem break;
963 1.1 lukem }
964 1.1 lukem ldap_free_urldesc( ludp );
965 1.1 lukem }
966 1.1 lukem
967 1.1 lukem return 0;
968 1.1 lukem }
969 1.1 lukem
970 1.1 lukem /*
971 1.1 lukem * I don't like this much, but we need two different
972 1.1 lukem * functions because different heap managers may be
973 1.1 lukem * in use in back-ldap/meta to reduce the amount of
974 1.1 lukem * calls to malloc routines, and some of the free()
975 1.1 lukem * routines may be macros with args
976 1.1 lukem */
977 1.1 lukem int
978 1.1 lukem rwm_dnattr_rewrite(
979 1.1 lukem Operation *op,
980 1.1 lukem SlapReply *rs,
981 1.1 lukem void *cookie,
982 1.1 lukem BerVarray a_vals,
983 1.1 lukem BerVarray *pa_nvals )
984 1.1 lukem {
985 1.1 lukem slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
986 1.1 lukem struct ldaprwmap *rwmap =
987 1.1 lukem (struct ldaprwmap *)on->on_bi.bi_private;
988 1.1 lukem
989 1.1 lukem int i, last;
990 1.1 lukem
991 1.1 lukem dncookie dc;
992 1.1 lukem struct berval dn = BER_BVNULL,
993 1.1 lukem ndn = BER_BVNULL;
994 1.1 lukem BerVarray in;
995 1.1 lukem
996 1.1 lukem if ( a_vals ) {
997 1.1 lukem in = a_vals;
998 1.1 lukem
999 1.1 lukem } else {
1000 1.1 lukem if ( pa_nvals == NULL || *pa_nvals == NULL ) {
1001 1.1 lukem return LDAP_OTHER;
1002 1.1 lukem }
1003 1.1 lukem in = *pa_nvals;
1004 1.1 lukem }
1005 1.1 lukem
1006 1.1 lukem /*
1007 1.1 lukem * Rewrite the dn if needed
1008 1.1 lukem */
1009 1.1 lukem dc.rwmap = rwmap;
1010 1.1 lukem dc.conn = op->o_conn;
1011 1.1 lukem dc.rs = rs;
1012 1.1 lukem dc.ctx = (char *)cookie;
1013 1.1 lukem
1014 1.1 lukem for ( last = 0; !BER_BVISNULL( &in[last] ); last++ );
1015 1.1 lukem last--;
1016 1.1 lukem if ( pa_nvals != NULL ) {
1017 1.1 lukem if ( *pa_nvals == NULL ) {
1018 1.1 lukem *pa_nvals = ch_malloc( ( last + 2 ) * sizeof(struct berval) );
1019 1.1 lukem memset( *pa_nvals, 0, ( last + 2 ) * sizeof(struct berval) );
1020 1.1 lukem }
1021 1.1 lukem }
1022 1.1 lukem
1023 1.1 lukem for ( i = 0; !BER_BVISNULL( &in[i] ); i++ ) {
1024 1.1 lukem int rc;
1025 1.1 lukem
1026 1.1 lukem if ( a_vals ) {
1027 1.1 lukem dn = in[i];
1028 1.1 lukem if ( pa_nvals ) {
1029 1.1 lukem ndn = (*pa_nvals)[i];
1030 1.1 lukem rc = rwm_dn_massage_pretty_normalize( &dc, &in[i], &dn, &ndn );
1031 1.1 lukem } else {
1032 1.1 lukem rc = rwm_dn_massage_pretty( &dc, &in[i], &dn );
1033 1.1 lukem }
1034 1.1 lukem } else {
1035 1.1 lukem ndn = in[i];
1036 1.1 lukem rc = rwm_dn_massage_normalize( &dc, &in[i], &ndn );
1037 1.1 lukem }
1038 1.1 lukem
1039 1.1 lukem switch ( rc ) {
1040 1.1 lukem case LDAP_UNWILLING_TO_PERFORM:
1041 1.1 lukem /*
1042 1.1 lukem * FIXME: need to check if it may be considered
1043 1.1 lukem * legal to trim values when adding/modifying;
1044 1.1 lukem * it should be when searching (e.g. ACLs).
1045 1.1 lukem */
1046 1.1 lukem ch_free( in[i].bv_val );
1047 1.1 lukem if (last > i ) {
1048 1.1 lukem in[i] = in[last];
1049 1.1 lukem if ( a_vals && pa_nvals ) {
1050 1.1 lukem (*pa_nvals)[i] = (*pa_nvals)[last];
1051 1.1 lukem }
1052 1.1 lukem }
1053 1.1 lukem BER_BVZERO( &in[last] );
1054 1.1 lukem if ( a_vals && pa_nvals ) {
1055 1.1 lukem BER_BVZERO( &(*pa_nvals)[last] );
1056 1.1 lukem }
1057 1.1 lukem last--;
1058 1.1 lukem break;
1059 1.1 lukem
1060 1.1 lukem case LDAP_SUCCESS:
1061 1.1 lukem if ( a_vals ) {
1062 1.1 lukem if ( !BER_BVISNULL( &dn ) && dn.bv_val != a_vals[i].bv_val ) {
1063 1.1 lukem ch_free( a_vals[i].bv_val );
1064 1.1 lukem a_vals[i] = dn;
1065 1.1 lukem
1066 1.1 lukem if ( pa_nvals ) {
1067 1.1 lukem if ( !BER_BVISNULL( &(*pa_nvals)[i] ) ) {
1068 1.1 lukem ch_free( (*pa_nvals)[i].bv_val );
1069 1.1 lukem }
1070 1.1 lukem (*pa_nvals)[i] = ndn;
1071 1.1 lukem }
1072 1.1 lukem }
1073 1.1 lukem
1074 1.1 lukem } else {
1075 1.1 lukem if ( !BER_BVISNULL( &ndn ) && ndn.bv_val != (*pa_nvals)[i].bv_val ) {
1076 1.1 lukem ch_free( (*pa_nvals)[i].bv_val );
1077 1.1 lukem (*pa_nvals)[i] = ndn;
1078 1.1 lukem }
1079 1.1 lukem }
1080 1.1 lukem break;
1081 1.1 lukem
1082 1.1 lukem default:
1083 1.1 lukem /* leave attr untouched if massage failed */
1084 1.1 lukem if ( a_vals && pa_nvals && BER_BVISNULL( &(*pa_nvals)[i] ) ) {
1085 1.1 lukem dnNormalize( 0, NULL, NULL, &a_vals[i], &(*pa_nvals)[i], NULL );
1086 1.1 lukem }
1087 1.1 lukem break;
1088 1.1 lukem }
1089 1.1 lukem }
1090 1.1 lukem
1091 1.1 lukem return 0;
1092 1.1 lukem }
1093 1.1 lukem
1094 1.1 lukem int
1095 1.1 lukem rwm_referral_result_rewrite(
1096 1.1 lukem dncookie *dc,
1097 1.1 lukem BerVarray a_vals )
1098 1.1 lukem {
1099 1.1 lukem int i, last;
1100 1.1 lukem
1101 1.1 lukem for ( last = 0; !BER_BVISNULL( &a_vals[last] ); last++ );
1102 1.1 lukem last--;
1103 1.1 lukem
1104 1.1 lukem for ( i = 0; !BER_BVISNULL( &a_vals[i] ); i++ ) {
1105 1.1 lukem struct berval dn,
1106 1.1 lukem olddn = BER_BVNULL;
1107 1.1 lukem int rc;
1108 1.1 lukem LDAPURLDesc *ludp;
1109 1.1 lukem
1110 1.1 lukem rc = ldap_url_parse( a_vals[i].bv_val, &ludp );
1111 1.1 lukem if ( rc != LDAP_URL_SUCCESS ) {
1112 1.1 lukem /* leave attr untouched if massage failed */
1113 1.1 lukem continue;
1114 1.1 lukem }
1115 1.1 lukem
1116 1.1 lukem /* FIXME: URLs like "ldap:///dc=suffix" if passed
1117 1.1 lukem * thru ldap_url_parse() and ldap_url_desc2str()
1118 1.1 lukem * get rewritten as "ldap:///dc=suffix??base";
1119 1.1 lukem * we don't want this to occur... */
1120 1.1 lukem if ( ludp->lud_scope == LDAP_SCOPE_BASE ) {
1121 1.1 lukem ludp->lud_scope = LDAP_SCOPE_DEFAULT;
1122 1.1 lukem }
1123 1.1 lukem
1124 1.1 lukem ber_str2bv( ludp->lud_dn, 0, 0, &olddn );
1125 1.1 lukem
1126 1.1 lukem dn = olddn;
1127 1.1 lukem rc = rwm_dn_massage_pretty( dc, &olddn, &dn );
1128 1.1 lukem switch ( rc ) {
1129 1.1 lukem case LDAP_UNWILLING_TO_PERFORM:
1130 1.1 lukem /*
1131 1.1 lukem * FIXME: need to check if it may be considered
1132 1.1 lukem * legal to trim values when adding/modifying;
1133 1.1 lukem * it should be when searching (e.g. ACLs).
1134 1.1 lukem */
1135 1.1 lukem ch_free( a_vals[i].bv_val );
1136 1.1 lukem if ( last > i ) {
1137 1.1 lukem a_vals[i] = a_vals[last];
1138 1.1 lukem }
1139 1.1 lukem BER_BVZERO( &a_vals[last] );
1140 1.1 lukem last--;
1141 1.1 lukem i--;
1142 1.1 lukem break;
1143 1.1 lukem
1144 1.1 lukem default:
1145 1.1 lukem /* leave attr untouched if massage failed */
1146 1.1 lukem if ( !BER_BVISNULL( &dn ) && olddn.bv_val != dn.bv_val ) {
1147 1.1 lukem char *newurl;
1148 1.1 lukem
1149 1.1 lukem ludp->lud_dn = dn.bv_val;
1150 1.1 lukem newurl = ldap_url_desc2str( ludp );
1151 1.1 lukem if ( newurl == NULL ) {
1152 1.1 lukem /* FIXME: leave attr untouched
1153 1.1 lukem * even if ldap_url_desc2str failed...
1154 1.1 lukem */
1155 1.1 lukem break;
1156 1.1 lukem }
1157 1.1 lukem
1158 1.1 lukem ch_free( a_vals[i].bv_val );
1159 1.1 lukem ber_str2bv( newurl, 0, 1, &a_vals[i] );
1160 1.1 lukem LDAP_FREE( newurl );
1161 1.1 lukem ludp->lud_dn = olddn.bv_val;
1162 1.1 lukem }
1163 1.1 lukem break;
1164 1.1 lukem }
1165 1.1 lukem
1166 1.1 lukem ldap_free_urldesc( ludp );
1167 1.1 lukem }
1168 1.1 lukem
1169 1.1 lukem return 0;
1170 1.1 lukem }
1171 1.1 lukem
1172 1.1 lukem int
1173 1.1 lukem rwm_dnattr_result_rewrite(
1174 1.1 lukem dncookie *dc,
1175 1.1 lukem BerVarray a_vals )
1176 1.1 lukem {
1177 1.1 lukem int i, last;
1178 1.1 lukem
1179 1.1 lukem for ( last = 0; !BER_BVISNULL( &a_vals[last] ); last++ );
1180 1.1 lukem last--;
1181 1.1 lukem
1182 1.1 lukem for ( i = 0; !BER_BVISNULL( &a_vals[i] ); i++ ) {
1183 1.1 lukem struct berval dn;
1184 1.1 lukem int rc;
1185 1.1 lukem
1186 1.1 lukem dn = a_vals[i];
1187 1.1 lukem rc = rwm_dn_massage_pretty( dc, &a_vals[i], &dn );
1188 1.1 lukem switch ( rc ) {
1189 1.1 lukem case LDAP_UNWILLING_TO_PERFORM:
1190 1.1 lukem /*
1191 1.1 lukem * FIXME: need to check if it may be considered
1192 1.1 lukem * legal to trim values when adding/modifying;
1193 1.1 lukem * it should be when searching (e.g. ACLs).
1194 1.1 lukem */
1195 1.1 lukem ch_free( a_vals[i].bv_val );
1196 1.1 lukem if ( last > i ) {
1197 1.1 lukem a_vals[i] = a_vals[last];
1198 1.1 lukem }
1199 1.1 lukem BER_BVZERO( &a_vals[last] );
1200 1.1 lukem last--;
1201 1.1 lukem break;
1202 1.1 lukem
1203 1.1 lukem default:
1204 1.1 lukem /* leave attr untouched if massage failed */
1205 1.1 lukem if ( !BER_BVISNULL( &dn ) && a_vals[i].bv_val != dn.bv_val ) {
1206 1.1 lukem ch_free( a_vals[i].bv_val );
1207 1.1 lukem a_vals[i] = dn;
1208 1.1 lukem }
1209 1.1 lukem break;
1210 1.1 lukem }
1211 1.1 lukem }
1212 1.1 lukem
1213 1.1 lukem return 0;
1214 1.1 lukem }
1215 1.1 lukem
1216 1.1 lukem void
1217 1.1 lukem rwm_mapping_dst_free( void *v_mapping )
1218 1.1 lukem {
1219 1.1 lukem struct ldapmapping *mapping = v_mapping;
1220 1.1 lukem
1221 1.1 lukem if ( BER_BVISEMPTY( &mapping[0].m_dst ) ) {
1222 1.1 lukem rwm_mapping_free( &mapping[ -1 ] );
1223 1.1 lukem }
1224 1.1 lukem }
1225 1.1 lukem
1226 1.1 lukem void
1227 1.1 lukem rwm_mapping_free( void *v_mapping )
1228 1.1 lukem {
1229 1.1 lukem struct ldapmapping *mapping = v_mapping;
1230 1.1 lukem
1231 1.1 lukem if ( !BER_BVISNULL( &mapping[0].m_src ) ) {
1232 1.1 lukem ch_free( mapping[0].m_src.bv_val );
1233 1.1 lukem }
1234 1.1 lukem
1235 1.1 lukem if ( mapping[0].m_flags & RWMMAP_F_FREE_SRC ) {
1236 1.1 lukem if ( mapping[0].m_flags & RWMMAP_F_IS_OC ) {
1237 1.1 lukem if ( mapping[0].m_src_oc ) {
1238 1.1 lukem ch_free( mapping[0].m_src_oc );
1239 1.1 lukem }
1240 1.1 lukem
1241 1.1 lukem } else {
1242 1.1 lukem if ( mapping[0].m_src_ad ) {
1243 1.1 lukem ch_free( mapping[0].m_src_ad );
1244 1.1 lukem }
1245 1.1 lukem }
1246 1.1 lukem }
1247 1.1 lukem
1248 1.1 lukem if ( !BER_BVISNULL( &mapping[0].m_dst ) ) {
1249 1.1 lukem ch_free( mapping[0].m_dst.bv_val );
1250 1.1 lukem }
1251 1.1 lukem
1252 1.1 lukem if ( mapping[0].m_flags & RWMMAP_F_FREE_DST ) {
1253 1.1 lukem if ( mapping[0].m_flags & RWMMAP_F_IS_OC ) {
1254 1.1 lukem if ( mapping[0].m_dst_oc ) {
1255 1.1 lukem ch_free( mapping[0].m_dst_oc );
1256 1.1 lukem }
1257 1.1 lukem
1258 1.1 lukem } else {
1259 1.1 lukem if ( mapping[0].m_dst_ad ) {
1260 1.1 lukem ch_free( mapping[0].m_dst_ad );
1261 1.1 lukem }
1262 1.1 lukem }
1263 1.1 lukem }
1264 1.1 lukem
1265 1.1 lukem ch_free( mapping );
1266 1.1 lukem
1267 1.1 lukem }
1268 1.1 lukem
1269 1.1 lukem #endif /* SLAPD_OVER_RWM */
1270