rwm.c revision 1.1.1.5 1 1.1.1.2 lukem /* $NetBSD: rwm.c,v 1.1.1.5 2017/02/09 01:47:03 christos Exp $ */
2 1.1.1.2 lukem
3 1.1 lukem /* rwm.c - rewrite/remap operations */
4 1.1.1.4 tron /* $OpenLDAP$ */
5 1.1 lukem /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6 1.1 lukem *
7 1.1.1.5 christos * Copyright 2003-2016 The OpenLDAP Foundation.
8 1.1 lukem * Portions Copyright 2003 Pierangelo Masarati.
9 1.1 lukem * All rights reserved.
10 1.1 lukem *
11 1.1 lukem * Redistribution and use in source and binary forms, with or without
12 1.1 lukem * modification, are permitted only as authorized by the OpenLDAP
13 1.1 lukem * Public License.
14 1.1 lukem *
15 1.1 lukem * A copy of this license is available in the file LICENSE in the
16 1.1 lukem * top-level directory of the distribution or, alternatively, at
17 1.1 lukem * <http://www.OpenLDAP.org/license.html>.
18 1.1 lukem */
19 1.1 lukem
20 1.1.1.5 christos #include <sys/cdefs.h>
21 1.1.1.5 christos __RCSID("$NetBSD: rwm.c,v 1.1.1.5 2017/02/09 01:47:03 christos Exp $");
22 1.1.1.5 christos
23 1.1 lukem #include "portable.h"
24 1.1 lukem
25 1.1 lukem #ifdef SLAPD_OVER_RWM
26 1.1 lukem
27 1.1 lukem #include <stdio.h>
28 1.1 lukem
29 1.1 lukem #include <ac/string.h>
30 1.1 lukem
31 1.1 lukem #include "slap.h"
32 1.1 lukem #include "config.h"
33 1.1 lukem #include "lutil.h"
34 1.1 lukem #include "rwm.h"
35 1.1 lukem
36 1.1 lukem typedef struct rwm_op_state {
37 1.1 lukem ber_tag_t r_tag;
38 1.1 lukem struct berval ro_dn;
39 1.1 lukem struct berval ro_ndn;
40 1.1 lukem struct berval r_dn;
41 1.1 lukem struct berval r_ndn;
42 1.1.1.4 tron struct berval rx_dn;
43 1.1.1.4 tron struct berval rx_ndn;
44 1.1 lukem AttributeName *mapped_attrs;
45 1.1 lukem OpRequest o_request;
46 1.1 lukem } rwm_op_state;
47 1.1 lukem
48 1.1 lukem typedef struct rwm_op_cb {
49 1.1 lukem slap_callback cb;
50 1.1 lukem rwm_op_state ros;
51 1.1 lukem } rwm_op_cb;
52 1.1 lukem
53 1.1 lukem static int
54 1.1.1.2 lukem rwm_db_destroy( BackendDB *be, ConfigReply *cr );
55 1.1 lukem
56 1.1.1.2 lukem static int
57 1.1.1.2 lukem rwm_send_entry( Operation *op, SlapReply *rs );
58 1.1 lukem
59 1.1.1.2 lukem static void
60 1.1.1.2 lukem rwm_op_rollback( Operation *op, SlapReply *rs, rwm_op_state *ros )
61 1.1.1.2 lukem {
62 1.1.1.4 tron /* in case of successful extended operation cleanup
63 1.1.1.4 tron * gets called *after* (ITS#6632); this hack counts
64 1.1.1.4 tron * on others to cleanup our o_req_dn/o_req_ndn,
65 1.1.1.4 tron * while we cleanup theirs. */
66 1.1.1.4 tron if ( ros->r_tag == LDAP_REQ_EXTENDED && rs->sr_err == LDAP_SUCCESS ) {
67 1.1.1.4 tron if ( !BER_BVISNULL( &ros->rx_dn ) ) {
68 1.1.1.4 tron ch_free( ros->rx_dn.bv_val );
69 1.1.1.4 tron }
70 1.1.1.4 tron if ( !BER_BVISNULL( &ros->rx_ndn ) ) {
71 1.1.1.4 tron ch_free( ros->rx_ndn.bv_val );
72 1.1.1.4 tron }
73 1.1 lukem
74 1.1.1.4 tron } else {
75 1.1.1.4 tron if ( !BER_BVISNULL( &ros->ro_dn ) ) {
76 1.1.1.4 tron op->o_req_dn = ros->ro_dn;
77 1.1.1.4 tron }
78 1.1.1.4 tron if ( !BER_BVISNULL( &ros->ro_ndn ) ) {
79 1.1.1.4 tron op->o_req_ndn = ros->ro_ndn;
80 1.1.1.4 tron }
81 1.1 lukem
82 1.1.1.4 tron if ( !BER_BVISNULL( &ros->r_dn )
83 1.1.1.4 tron && ros->r_dn.bv_val != ros->ro_dn.bv_val )
84 1.1.1.4 tron {
85 1.1.1.4 tron assert( ros->r_dn.bv_val != ros->r_ndn.bv_val );
86 1.1.1.4 tron ch_free( ros->r_dn.bv_val );
87 1.1.1.4 tron }
88 1.1.1.4 tron
89 1.1.1.4 tron if ( !BER_BVISNULL( &ros->r_ndn )
90 1.1.1.4 tron && ros->r_ndn.bv_val != ros->ro_ndn.bv_val )
91 1.1.1.4 tron {
92 1.1.1.4 tron ch_free( ros->r_ndn.bv_val );
93 1.1.1.4 tron }
94 1.1.1.2 lukem }
95 1.1 lukem
96 1.1.1.4 tron BER_BVZERO( &ros->r_dn );
97 1.1.1.4 tron BER_BVZERO( &ros->r_ndn );
98 1.1.1.2 lukem BER_BVZERO( &ros->ro_dn );
99 1.1.1.2 lukem BER_BVZERO( &ros->ro_ndn );
100 1.1.1.4 tron BER_BVZERO( &ros->rx_dn );
101 1.1.1.4 tron BER_BVZERO( &ros->rx_ndn );
102 1.1.1.2 lukem
103 1.1.1.2 lukem switch( ros->r_tag ) {
104 1.1.1.2 lukem case LDAP_REQ_COMPARE:
105 1.1.1.2 lukem if ( op->orc_ava->aa_value.bv_val != ros->orc_ava->aa_value.bv_val )
106 1.1.1.2 lukem op->o_tmpfree( op->orc_ava->aa_value.bv_val, op->o_tmpmemctx );
107 1.1.1.2 lukem op->orc_ava = ros->orc_ava;
108 1.1.1.2 lukem break;
109 1.1.1.2 lukem case LDAP_REQ_MODIFY:
110 1.1.1.2 lukem slap_mods_free( op->orm_modlist, 1 );
111 1.1.1.2 lukem op->orm_modlist = ros->orm_modlist;
112 1.1.1.2 lukem break;
113 1.1.1.2 lukem case LDAP_REQ_MODRDN:
114 1.1.1.2 lukem if ( op->orr_newSup != ros->orr_newSup ) {
115 1.1.1.4 tron if ( op->orr_newSup ) {
116 1.1.1.4 tron ch_free( op->orr_newSup->bv_val );
117 1.1.1.4 tron ch_free( op->orr_nnewSup->bv_val );
118 1.1.1.4 tron op->o_tmpfree( op->orr_newSup, op->o_tmpmemctx );
119 1.1.1.4 tron op->o_tmpfree( op->orr_nnewSup, op->o_tmpmemctx );
120 1.1.1.4 tron }
121 1.1.1.2 lukem op->orr_newSup = ros->orr_newSup;
122 1.1.1.2 lukem op->orr_nnewSup = ros->orr_nnewSup;
123 1.1.1.2 lukem }
124 1.1.1.2 lukem if ( op->orr_newrdn.bv_val != ros->orr_newrdn.bv_val ) {
125 1.1.1.2 lukem ch_free( op->orr_newrdn.bv_val );
126 1.1.1.2 lukem ch_free( op->orr_nnewrdn.bv_val );
127 1.1.1.2 lukem op->orr_newrdn = ros->orr_newrdn;
128 1.1.1.2 lukem op->orr_nnewrdn = ros->orr_nnewrdn;
129 1.1.1.2 lukem }
130 1.1.1.2 lukem break;
131 1.1.1.2 lukem case LDAP_REQ_SEARCH:
132 1.1.1.3 adam op->o_tmpfree( ros->mapped_attrs, op->o_tmpmemctx );
133 1.1.1.2 lukem filter_free_x( op, op->ors_filter, 1 );
134 1.1.1.3 adam op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
135 1.1.1.2 lukem op->ors_attrs = ros->ors_attrs;
136 1.1.1.2 lukem op->ors_filter = ros->ors_filter;
137 1.1.1.2 lukem op->ors_filterstr = ros->ors_filterstr;
138 1.1.1.2 lukem break;
139 1.1.1.2 lukem case LDAP_REQ_EXTENDED:
140 1.1.1.2 lukem if ( op->ore_reqdata != ros->ore_reqdata ) {
141 1.1.1.2 lukem ber_bvfree( op->ore_reqdata );
142 1.1.1.2 lukem op->ore_reqdata = ros->ore_reqdata;
143 1.1 lukem }
144 1.1.1.2 lukem break;
145 1.1.1.2 lukem case LDAP_REQ_BIND:
146 1.1.1.2 lukem if ( rs->sr_err == LDAP_SUCCESS ) {
147 1.1.1.2 lukem #if 0
148 1.1.1.2 lukem ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
149 1.1.1.2 lukem /* too late, c_mutex released */
150 1.1.1.3 adam Debug( LDAP_DEBUG_ANY, "*** DN: \"%s\" => \"%s\"\n",
151 1.1.1.2 lukem op->o_conn->c_ndn.bv_val,
152 1.1.1.2 lukem op->o_req_ndn.bv_val );
153 1.1.1.2 lukem ber_bvreplace( &op->o_conn->c_ndn,
154 1.1.1.2 lukem &op->o_req_ndn );
155 1.1.1.2 lukem ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
156 1.1.1.2 lukem #endif
157 1.1.1.2 lukem }
158 1.1.1.2 lukem break;
159 1.1.1.2 lukem default: break;
160 1.1.1.2 lukem }
161 1.1.1.2 lukem }
162 1.1.1.2 lukem
163 1.1.1.2 lukem static int
164 1.1.1.2 lukem rwm_op_cleanup( Operation *op, SlapReply *rs )
165 1.1.1.2 lukem {
166 1.1.1.2 lukem slap_callback *cb = op->o_callback;
167 1.1.1.2 lukem rwm_op_state *ros = cb->sc_private;
168 1.1.1.2 lukem
169 1.1.1.2 lukem if ( rs->sr_type == REP_RESULT || rs->sr_type == REP_EXTENDED ||
170 1.1.1.2 lukem op->o_abandon || rs->sr_err == SLAPD_ABANDON )
171 1.1.1.2 lukem {
172 1.1.1.2 lukem rwm_op_rollback( op, rs, ros );
173 1.1.1.2 lukem
174 1.1 lukem op->o_callback = op->o_callback->sc_next;
175 1.1 lukem op->o_tmpfree( cb, op->o_tmpmemctx );
176 1.1 lukem }
177 1.1 lukem
178 1.1 lukem return SLAP_CB_CONTINUE;
179 1.1 lukem }
180 1.1 lukem
181 1.1 lukem static rwm_op_cb *
182 1.1.1.4 tron rwm_callback_get( Operation *op )
183 1.1 lukem {
184 1.1.1.4 tron rwm_op_cb *roc;
185 1.1 lukem
186 1.1.1.5 christos roc = op->o_tmpcalloc( 1, sizeof( struct rwm_op_cb ), op->o_tmpmemctx );
187 1.1 lukem roc->cb.sc_cleanup = rwm_op_cleanup;
188 1.1 lukem roc->cb.sc_response = NULL;
189 1.1 lukem roc->cb.sc_next = op->o_callback;
190 1.1 lukem roc->cb.sc_private = &roc->ros;
191 1.1 lukem roc->ros.r_tag = op->o_tag;
192 1.1 lukem roc->ros.ro_dn = op->o_req_dn;
193 1.1 lukem roc->ros.ro_ndn = op->o_req_ndn;
194 1.1 lukem BER_BVZERO( &roc->ros.r_dn );
195 1.1 lukem BER_BVZERO( &roc->ros.r_ndn );
196 1.1.1.4 tron BER_BVZERO( &roc->ros.rx_dn );
197 1.1.1.4 tron BER_BVZERO( &roc->ros.rx_ndn );
198 1.1.1.4 tron roc->ros.mapped_attrs = NULL;
199 1.1.1.4 tron roc->ros.o_request = op->o_request;
200 1.1 lukem
201 1.1 lukem return roc;
202 1.1 lukem }
203 1.1 lukem
204 1.1 lukem
205 1.1 lukem static int
206 1.1 lukem rwm_op_dn_massage( Operation *op, SlapReply *rs, void *cookie,
207 1.1 lukem rwm_op_state *ros )
208 1.1 lukem {
209 1.1 lukem slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
210 1.1 lukem struct ldaprwmap *rwmap =
211 1.1 lukem (struct ldaprwmap *)on->on_bi.bi_private;
212 1.1 lukem
213 1.1 lukem struct berval dn = BER_BVNULL,
214 1.1 lukem ndn = BER_BVNULL;
215 1.1 lukem int rc = 0;
216 1.1 lukem dncookie dc;
217 1.1 lukem
218 1.1 lukem /*
219 1.1 lukem * Rewrite the dn if needed
220 1.1 lukem */
221 1.1 lukem dc.rwmap = rwmap;
222 1.1 lukem dc.conn = op->o_conn;
223 1.1 lukem dc.rs = rs;
224 1.1 lukem dc.ctx = (char *)cookie;
225 1.1 lukem
226 1.1 lukem /* NOTE: in those cases where only the ndn is available,
227 1.1 lukem * and the caller sets op->o_req_dn = op->o_req_ndn,
228 1.1 lukem * only rewrite the op->o_req_ndn and use it as
229 1.1 lukem * op->o_req_dn as well */
230 1.1 lukem ndn = op->o_req_ndn;
231 1.1 lukem if ( op->o_req_dn.bv_val != op->o_req_ndn.bv_val ) {
232 1.1 lukem dn = op->o_req_dn;
233 1.1 lukem rc = rwm_dn_massage_pretty_normalize( &dc, &op->o_req_dn, &dn, &ndn );
234 1.1 lukem } else {
235 1.1 lukem rc = rwm_dn_massage_normalize( &dc, &op->o_req_ndn, &ndn );
236 1.1 lukem }
237 1.1 lukem
238 1.1 lukem if ( rc != LDAP_SUCCESS ) {
239 1.1 lukem return rc;
240 1.1 lukem }
241 1.1 lukem
242 1.1 lukem if ( ( op->o_req_dn.bv_val != op->o_req_ndn.bv_val && dn.bv_val == op->o_req_dn.bv_val )
243 1.1 lukem || ndn.bv_val == op->o_req_ndn.bv_val )
244 1.1 lukem {
245 1.1 lukem return LDAP_SUCCESS;
246 1.1 lukem }
247 1.1 lukem
248 1.1 lukem if ( op->o_req_dn.bv_val != op->o_req_ndn.bv_val ) {
249 1.1 lukem op->o_req_dn = dn;
250 1.1.1.2 lukem assert( BER_BVISNULL( &ros->r_dn ) );
251 1.1 lukem ros->r_dn = dn;
252 1.1 lukem } else {
253 1.1 lukem op->o_req_dn = ndn;
254 1.1 lukem }
255 1.1 lukem op->o_req_ndn = ndn;
256 1.1.1.2 lukem assert( BER_BVISNULL( &ros->r_ndn ) );
257 1.1 lukem ros->r_ndn = ndn;
258 1.1 lukem
259 1.1.1.4 tron if ( ros->r_tag == LDAP_REQ_EXTENDED ) {
260 1.1.1.4 tron ros->rx_dn = ros->r_dn;
261 1.1.1.4 tron ros->rx_ndn = ros->r_ndn;
262 1.1.1.4 tron }
263 1.1.1.4 tron
264 1.1 lukem return LDAP_SUCCESS;
265 1.1 lukem }
266 1.1 lukem
267 1.1 lukem static int
268 1.1 lukem rwm_op_add( Operation *op, SlapReply *rs )
269 1.1 lukem {
270 1.1 lukem slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
271 1.1 lukem struct ldaprwmap *rwmap =
272 1.1 lukem (struct ldaprwmap *)on->on_bi.bi_private;
273 1.1 lukem
274 1.1 lukem int rc,
275 1.1 lukem i;
276 1.1 lukem Attribute **ap = NULL;
277 1.1 lukem char *olddn = op->o_req_dn.bv_val;
278 1.1 lukem int isupdate;
279 1.1 lukem
280 1.1.1.4 tron rwm_op_cb *roc = rwm_callback_get( op );
281 1.1 lukem
282 1.1 lukem rc = rwm_op_dn_massage( op, rs, "addDN", &roc->ros );
283 1.1 lukem if ( rc != LDAP_SUCCESS ) {
284 1.1 lukem op->o_bd->bd_info = (BackendInfo *)on->on_info;
285 1.1 lukem send_ldap_error( op, rs, rc, "addDN massage error" );
286 1.1 lukem return -1;
287 1.1 lukem }
288 1.1 lukem
289 1.1 lukem if ( olddn != op->o_req_dn.bv_val ) {
290 1.1 lukem ber_bvreplace( &op->ora_e->e_name, &op->o_req_dn );
291 1.1 lukem ber_bvreplace( &op->ora_e->e_nname, &op->o_req_ndn );
292 1.1 lukem }
293 1.1 lukem
294 1.1 lukem /* Count number of attributes in entry */
295 1.1 lukem isupdate = be_shadow_update( op );
296 1.1 lukem for ( i = 0, ap = &op->oq_add.rs_e->e_attrs; *ap; ) {
297 1.1 lukem Attribute *a;
298 1.1 lukem
299 1.1 lukem if ( (*ap)->a_desc == slap_schema.si_ad_objectClass ||
300 1.1 lukem (*ap)->a_desc == slap_schema.si_ad_structuralObjectClass )
301 1.1 lukem {
302 1.1 lukem int j, last;
303 1.1 lukem
304 1.1 lukem last = (*ap)->a_numvals - 1;
305 1.1 lukem for ( j = 0; !BER_BVISNULL( &(*ap)->a_vals[ j ] ); j++ ) {
306 1.1 lukem struct ldapmapping *mapping = NULL;
307 1.1 lukem
308 1.1 lukem ( void )rwm_mapping( &rwmap->rwm_oc, &(*ap)->a_vals[ j ],
309 1.1 lukem &mapping, RWM_MAP );
310 1.1 lukem if ( mapping == NULL ) {
311 1.1 lukem if ( rwmap->rwm_at.drop_missing ) {
312 1.1 lukem /* FIXME: we allow to remove objectClasses as well;
313 1.1 lukem * if the resulting entry is inconsistent, that's
314 1.1 lukem * the relayed database's business...
315 1.1 lukem */
316 1.1 lukem ch_free( (*ap)->a_vals[ j ].bv_val );
317 1.1 lukem if ( last > j ) {
318 1.1 lukem (*ap)->a_vals[ j ] = (*ap)->a_vals[ last ];
319 1.1 lukem }
320 1.1 lukem BER_BVZERO( &(*ap)->a_vals[ last ] );
321 1.1 lukem (*ap)->a_numvals--;
322 1.1 lukem last--;
323 1.1 lukem j--;
324 1.1 lukem }
325 1.1 lukem
326 1.1 lukem } else {
327 1.1 lukem ch_free( (*ap)->a_vals[ j ].bv_val );
328 1.1 lukem ber_dupbv( &(*ap)->a_vals[ j ], &mapping->m_dst );
329 1.1 lukem }
330 1.1 lukem }
331 1.1 lukem
332 1.1 lukem } else if ( !isupdate && !get_relax( op ) && (*ap)->a_desc->ad_type->sat_no_user_mod )
333 1.1 lukem {
334 1.1 lukem goto next_attr;
335 1.1 lukem
336 1.1 lukem } else {
337 1.1 lukem struct ldapmapping *mapping = NULL;
338 1.1 lukem
339 1.1 lukem ( void )rwm_mapping( &rwmap->rwm_at, &(*ap)->a_desc->ad_cname,
340 1.1 lukem &mapping, RWM_MAP );
341 1.1 lukem if ( mapping == NULL ) {
342 1.1 lukem if ( rwmap->rwm_at.drop_missing ) {
343 1.1 lukem goto cleanup_attr;
344 1.1 lukem }
345 1.1 lukem }
346 1.1 lukem
347 1.1 lukem if ( (*ap)->a_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName
348 1.1 lukem || ( mapping != NULL && mapping->m_dst_ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName ) )
349 1.1 lukem {
350 1.1 lukem /*
351 1.1 lukem * FIXME: rewrite could fail; in this case
352 1.1 lukem * the operation should give up, right?
353 1.1 lukem */
354 1.1 lukem rc = rwm_dnattr_rewrite( op, rs, "addAttrDN",
355 1.1 lukem (*ap)->a_vals,
356 1.1 lukem (*ap)->a_nvals ? &(*ap)->a_nvals : NULL );
357 1.1 lukem if ( rc ) {
358 1.1 lukem goto cleanup_attr;
359 1.1 lukem }
360 1.1 lukem
361 1.1 lukem } else if ( (*ap)->a_desc == slap_schema.si_ad_ref ) {
362 1.1 lukem rc = rwm_referral_rewrite( op, rs, "referralAttrDN",
363 1.1 lukem (*ap)->a_vals,
364 1.1 lukem (*ap)->a_nvals ? &(*ap)->a_nvals : NULL );
365 1.1 lukem if ( rc != LDAP_SUCCESS ) {
366 1.1 lukem goto cleanup_attr;
367 1.1 lukem }
368 1.1 lukem }
369 1.1 lukem
370 1.1 lukem if ( mapping != NULL ) {
371 1.1 lukem assert( mapping->m_dst_ad != NULL );
372 1.1 lukem (*ap)->a_desc = mapping->m_dst_ad;
373 1.1 lukem }
374 1.1 lukem }
375 1.1 lukem
376 1.1 lukem next_attr:;
377 1.1 lukem ap = &(*ap)->a_next;
378 1.1 lukem continue;
379 1.1 lukem
380 1.1 lukem cleanup_attr:;
381 1.1 lukem /* FIXME: leaking attribute/values? */
382 1.1 lukem a = *ap;
383 1.1 lukem
384 1.1 lukem *ap = (*ap)->a_next;
385 1.1 lukem attr_free( a );
386 1.1 lukem }
387 1.1 lukem
388 1.1 lukem op->o_callback = &roc->cb;
389 1.1 lukem
390 1.1 lukem return SLAP_CB_CONTINUE;
391 1.1 lukem }
392 1.1 lukem
393 1.1 lukem static int
394 1.1 lukem rwm_conn_init( BackendDB *be, Connection *conn )
395 1.1 lukem {
396 1.1 lukem slap_overinst *on = (slap_overinst *) be->bd_info;
397 1.1 lukem struct ldaprwmap *rwmap =
398 1.1 lukem (struct ldaprwmap *)on->on_bi.bi_private;
399 1.1 lukem
400 1.1 lukem ( void )rewrite_session_init( rwmap->rwm_rw, conn );
401 1.1 lukem
402 1.1 lukem return SLAP_CB_CONTINUE;
403 1.1 lukem }
404 1.1 lukem
405 1.1 lukem static int
406 1.1 lukem rwm_conn_destroy( BackendDB *be, Connection *conn )
407 1.1 lukem {
408 1.1 lukem slap_overinst *on = (slap_overinst *) be->bd_info;
409 1.1 lukem struct ldaprwmap *rwmap =
410 1.1 lukem (struct ldaprwmap *)on->on_bi.bi_private;
411 1.1 lukem
412 1.1 lukem ( void )rewrite_session_delete( rwmap->rwm_rw, conn );
413 1.1 lukem
414 1.1 lukem return SLAP_CB_CONTINUE;
415 1.1 lukem }
416 1.1 lukem
417 1.1 lukem static int
418 1.1 lukem rwm_op_bind( Operation *op, SlapReply *rs )
419 1.1 lukem {
420 1.1 lukem slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
421 1.1 lukem int rc;
422 1.1 lukem
423 1.1.1.4 tron rwm_op_cb *roc = rwm_callback_get( op );
424 1.1 lukem
425 1.1 lukem rc = rwm_op_dn_massage( op, rs, "bindDN", &roc->ros );
426 1.1 lukem if ( rc != LDAP_SUCCESS ) {
427 1.1 lukem op->o_bd->bd_info = (BackendInfo *)on->on_info;
428 1.1 lukem send_ldap_error( op, rs, rc, "bindDN massage error" );
429 1.1 lukem return -1;
430 1.1 lukem }
431 1.1 lukem
432 1.1.1.2 lukem overlay_callback_after_backover( op, &roc->cb, 1 );
433 1.1 lukem
434 1.1 lukem return SLAP_CB_CONTINUE;
435 1.1 lukem }
436 1.1 lukem
437 1.1 lukem static int
438 1.1 lukem rwm_op_unbind( Operation *op, SlapReply *rs )
439 1.1 lukem {
440 1.1 lukem slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
441 1.1 lukem struct ldaprwmap *rwmap =
442 1.1 lukem (struct ldaprwmap *)on->on_bi.bi_private;
443 1.1 lukem
444 1.1 lukem rewrite_session_delete( rwmap->rwm_rw, op->o_conn );
445 1.1 lukem
446 1.1 lukem return SLAP_CB_CONTINUE;
447 1.1 lukem }
448 1.1 lukem
449 1.1 lukem static int
450 1.1 lukem rwm_op_compare( Operation *op, SlapReply *rs )
451 1.1 lukem {
452 1.1 lukem slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
453 1.1 lukem struct ldaprwmap *rwmap =
454 1.1 lukem (struct ldaprwmap *)on->on_bi.bi_private;
455 1.1 lukem
456 1.1 lukem int rc;
457 1.1 lukem struct berval mapped_vals[2] = { BER_BVNULL, BER_BVNULL };
458 1.1 lukem
459 1.1.1.4 tron rwm_op_cb *roc = rwm_callback_get( op );
460 1.1 lukem
461 1.1 lukem rc = rwm_op_dn_massage( op, rs, "compareDN", &roc->ros );
462 1.1 lukem if ( rc != LDAP_SUCCESS ) {
463 1.1 lukem op->o_bd->bd_info = (BackendInfo *)on->on_info;
464 1.1 lukem send_ldap_error( op, rs, rc, "compareDN massage error" );
465 1.1 lukem return -1;
466 1.1 lukem }
467 1.1 lukem
468 1.1 lukem /* if the attribute is an objectClass, try to remap its value */
469 1.1 lukem if ( op->orc_ava->aa_desc == slap_schema.si_ad_objectClass
470 1.1 lukem || op->orc_ava->aa_desc == slap_schema.si_ad_structuralObjectClass )
471 1.1 lukem {
472 1.1 lukem rwm_map( &rwmap->rwm_oc, &op->orc_ava->aa_value,
473 1.1 lukem &mapped_vals[0], RWM_MAP );
474 1.1 lukem if ( BER_BVISNULL( &mapped_vals[0] ) || BER_BVISEMPTY( &mapped_vals[0] ) )
475 1.1 lukem {
476 1.1 lukem op->o_bd->bd_info = (BackendInfo *)on->on_info;
477 1.1 lukem send_ldap_error( op, rs, LDAP_OTHER, "compare objectClass map error" );
478 1.1 lukem return -1;
479 1.1 lukem
480 1.1 lukem } else if ( mapped_vals[0].bv_val != op->orc_ava->aa_value.bv_val ) {
481 1.1 lukem ber_dupbv_x( &op->orc_ava->aa_value, &mapped_vals[0],
482 1.1 lukem op->o_tmpmemctx );
483 1.1 lukem }
484 1.1 lukem
485 1.1 lukem } else {
486 1.1 lukem struct ldapmapping *mapping = NULL;
487 1.1 lukem AttributeDescription *ad = op->orc_ava->aa_desc;
488 1.1 lukem
489 1.1 lukem ( void )rwm_mapping( &rwmap->rwm_at, &op->orc_ava->aa_desc->ad_cname,
490 1.1 lukem &mapping, RWM_MAP );
491 1.1 lukem if ( mapping == NULL ) {
492 1.1 lukem if ( rwmap->rwm_at.drop_missing ) {
493 1.1 lukem op->o_bd->bd_info = (BackendInfo *)on->on_info;
494 1.1 lukem send_ldap_error( op, rs, LDAP_OTHER, "compare attributeType map error" );
495 1.1 lukem return -1;
496 1.1 lukem }
497 1.1 lukem
498 1.1 lukem } else {
499 1.1 lukem assert( mapping->m_dst_ad != NULL );
500 1.1 lukem ad = mapping->m_dst_ad;
501 1.1 lukem }
502 1.1 lukem
503 1.1 lukem if ( op->orc_ava->aa_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName
504 1.1 lukem || ( mapping != NULL && mapping->m_dst_ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName ) )
505 1.1 lukem {
506 1.1 lukem struct berval *mapped_valsp[2];
507 1.1 lukem
508 1.1 lukem mapped_valsp[0] = &mapped_vals[0];
509 1.1 lukem mapped_valsp[1] = &mapped_vals[1];
510 1.1 lukem
511 1.1 lukem mapped_vals[0] = op->orc_ava->aa_value;
512 1.1 lukem
513 1.1 lukem rc = rwm_dnattr_rewrite( op, rs, "compareAttrDN", NULL, mapped_valsp );
514 1.1 lukem
515 1.1 lukem if ( rc != LDAP_SUCCESS ) {
516 1.1 lukem op->o_bd->bd_info = (BackendInfo *)on->on_info;
517 1.1 lukem send_ldap_error( op, rs, rc, "compareAttrDN massage error" );
518 1.1 lukem return -1;
519 1.1 lukem }
520 1.1 lukem
521 1.1 lukem if ( mapped_vals[ 0 ].bv_val != op->orc_ava->aa_value.bv_val ) {
522 1.1 lukem /* NOTE: if we get here, rwm_dnattr_rewrite()
523 1.1 lukem * already freed the old value, so now
524 1.1 lukem * it's invalid */
525 1.1 lukem ber_dupbv_x( &op->orc_ava->aa_value, &mapped_vals[0],
526 1.1 lukem op->o_tmpmemctx );
527 1.1 lukem ber_memfree_x( mapped_vals[ 0 ].bv_val, NULL );
528 1.1 lukem }
529 1.1 lukem }
530 1.1 lukem op->orc_ava->aa_desc = ad;
531 1.1 lukem }
532 1.1 lukem
533 1.1 lukem op->o_callback = &roc->cb;
534 1.1 lukem
535 1.1 lukem return SLAP_CB_CONTINUE;
536 1.1 lukem }
537 1.1 lukem
538 1.1 lukem static int
539 1.1 lukem rwm_op_delete( Operation *op, SlapReply *rs )
540 1.1 lukem {
541 1.1 lukem slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
542 1.1 lukem int rc;
543 1.1 lukem
544 1.1.1.4 tron rwm_op_cb *roc = rwm_callback_get( op );
545 1.1 lukem
546 1.1 lukem rc = rwm_op_dn_massage( op, rs, "deleteDN", &roc->ros );
547 1.1 lukem if ( rc != LDAP_SUCCESS ) {
548 1.1 lukem op->o_bd->bd_info = (BackendInfo *)on->on_info;
549 1.1 lukem send_ldap_error( op, rs, rc, "deleteDN massage error" );
550 1.1 lukem return -1;
551 1.1 lukem }
552 1.1 lukem
553 1.1 lukem op->o_callback = &roc->cb;
554 1.1 lukem
555 1.1 lukem return SLAP_CB_CONTINUE;
556 1.1 lukem }
557 1.1 lukem
558 1.1 lukem static int
559 1.1 lukem rwm_op_modify( Operation *op, SlapReply *rs )
560 1.1 lukem {
561 1.1 lukem slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
562 1.1 lukem struct ldaprwmap *rwmap =
563 1.1 lukem (struct ldaprwmap *)on->on_bi.bi_private;
564 1.1 lukem
565 1.1 lukem int isupdate;
566 1.1 lukem Modifications **mlp;
567 1.1 lukem int rc;
568 1.1 lukem
569 1.1.1.4 tron rwm_op_cb *roc = rwm_callback_get( op );
570 1.1 lukem
571 1.1 lukem rc = rwm_op_dn_massage( op, rs, "modifyDN", &roc->ros );
572 1.1 lukem if ( rc != LDAP_SUCCESS ) {
573 1.1 lukem op->o_bd->bd_info = (BackendInfo *)on->on_info;
574 1.1 lukem send_ldap_error( op, rs, rc, "modifyDN massage error" );
575 1.1 lukem return -1;
576 1.1 lukem }
577 1.1 lukem
578 1.1 lukem isupdate = be_shadow_update( op );
579 1.1 lukem for ( mlp = &op->orm_modlist; *mlp; ) {
580 1.1 lukem int is_oc = 0;
581 1.1 lukem Modifications *ml = *mlp;
582 1.1 lukem struct ldapmapping *mapping = NULL;
583 1.1 lukem
584 1.1 lukem /* ml points to a temporary mod until needs duplication */
585 1.1 lukem if ( ml->sml_desc == slap_schema.si_ad_objectClass
586 1.1 lukem || ml->sml_desc == slap_schema.si_ad_structuralObjectClass )
587 1.1 lukem {
588 1.1 lukem is_oc = 1;
589 1.1 lukem
590 1.1 lukem } else if ( !isupdate && !get_relax( op ) && ml->sml_desc->ad_type->sat_no_user_mod )
591 1.1 lukem {
592 1.1 lukem ml = ch_malloc( sizeof( Modifications ) );
593 1.1 lukem *ml = **mlp;
594 1.1 lukem if ( (*mlp)->sml_values ) {
595 1.1 lukem ber_bvarray_dup_x( &ml->sml_values, (*mlp)->sml_values, NULL );
596 1.1 lukem if ( (*mlp)->sml_nvalues ) {
597 1.1 lukem ber_bvarray_dup_x( &ml->sml_nvalues, (*mlp)->sml_nvalues, NULL );
598 1.1 lukem }
599 1.1 lukem }
600 1.1 lukem *mlp = ml;
601 1.1 lukem goto next_mod;
602 1.1 lukem
603 1.1 lukem } else {
604 1.1 lukem int drop_missing;
605 1.1 lukem
606 1.1 lukem drop_missing = rwm_mapping( &rwmap->rwm_at,
607 1.1 lukem &ml->sml_desc->ad_cname,
608 1.1 lukem &mapping, RWM_MAP );
609 1.1 lukem if ( drop_missing || ( mapping != NULL && BER_BVISNULL( &mapping->m_dst ) ) )
610 1.1 lukem {
611 1.1.1.4 tron goto skip_mod;
612 1.1 lukem }
613 1.1 lukem }
614 1.1 lukem
615 1.1 lukem /* duplicate the modlist */
616 1.1 lukem ml = ch_malloc( sizeof( Modifications ));
617 1.1 lukem *ml = **mlp;
618 1.1 lukem *mlp = ml;
619 1.1 lukem
620 1.1 lukem if ( ml->sml_values != NULL ) {
621 1.1 lukem int i, num;
622 1.1 lukem struct berval *bva;
623 1.1 lukem
624 1.1 lukem for ( num = 0; !BER_BVISNULL( &ml->sml_values[ num ] ); num++ )
625 1.1 lukem /* count values */ ;
626 1.1 lukem
627 1.1 lukem bva = ch_malloc( (num+1) * sizeof( struct berval ));
628 1.1 lukem for (i=0; i<num; i++)
629 1.1 lukem ber_dupbv( &bva[i], &ml->sml_values[i] );
630 1.1 lukem BER_BVZERO( &bva[i] );
631 1.1 lukem ml->sml_values = bva;
632 1.1 lukem
633 1.1 lukem if ( ml->sml_nvalues ) {
634 1.1 lukem bva = ch_malloc( (num+1) * sizeof( struct berval ));
635 1.1 lukem for (i=0; i<num; i++)
636 1.1 lukem ber_dupbv( &bva[i], &ml->sml_nvalues[i] );
637 1.1 lukem BER_BVZERO( &bva[i] );
638 1.1 lukem ml->sml_nvalues = bva;
639 1.1 lukem }
640 1.1 lukem
641 1.1 lukem if ( is_oc ) {
642 1.1 lukem int last, j;
643 1.1 lukem
644 1.1 lukem last = num-1;
645 1.1 lukem
646 1.1 lukem for ( j = 0; !BER_BVISNULL( &ml->sml_values[ j ] ); j++ ) {
647 1.1 lukem struct ldapmapping *oc_mapping = NULL;
648 1.1 lukem
649 1.1 lukem ( void )rwm_mapping( &rwmap->rwm_oc, &ml->sml_values[ j ],
650 1.1 lukem &oc_mapping, RWM_MAP );
651 1.1 lukem if ( oc_mapping == NULL ) {
652 1.1 lukem if ( rwmap->rwm_at.drop_missing ) {
653 1.1 lukem /* FIXME: we allow to remove objectClasses as well;
654 1.1 lukem * if the resulting entry is inconsistent, that's
655 1.1 lukem * the relayed database's business...
656 1.1 lukem */
657 1.1 lukem if ( last > j ) {
658 1.1 lukem ch_free( ml->sml_values[ j ].bv_val );
659 1.1 lukem ml->sml_values[ j ] = ml->sml_values[ last ];
660 1.1 lukem }
661 1.1 lukem BER_BVZERO( &ml->sml_values[ last ] );
662 1.1 lukem last--;
663 1.1 lukem j--;
664 1.1 lukem }
665 1.1 lukem
666 1.1 lukem } else {
667 1.1 lukem ch_free( ml->sml_values[ j ].bv_val );
668 1.1 lukem ber_dupbv( &ml->sml_values[ j ], &oc_mapping->m_dst );
669 1.1 lukem }
670 1.1 lukem }
671 1.1 lukem
672 1.1 lukem } else {
673 1.1 lukem if ( ml->sml_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName
674 1.1 lukem || ( mapping != NULL && mapping->m_dst_ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName ) )
675 1.1 lukem {
676 1.1 lukem rc = rwm_dnattr_rewrite( op, rs, "modifyAttrDN",
677 1.1 lukem ml->sml_values,
678 1.1 lukem ml->sml_nvalues ? &ml->sml_nvalues : NULL );
679 1.1 lukem
680 1.1 lukem } else if ( ml->sml_desc == slap_schema.si_ad_ref ) {
681 1.1 lukem rc = rwm_referral_rewrite( op, rs,
682 1.1 lukem "referralAttrDN",
683 1.1 lukem ml->sml_values,
684 1.1 lukem ml->sml_nvalues ? &ml->sml_nvalues : NULL );
685 1.1 lukem if ( rc != LDAP_SUCCESS ) {
686 1.1 lukem goto cleanup_mod;
687 1.1 lukem }
688 1.1 lukem }
689 1.1 lukem
690 1.1 lukem if ( rc != LDAP_SUCCESS ) {
691 1.1 lukem goto cleanup_mod;
692 1.1 lukem }
693 1.1 lukem }
694 1.1 lukem }
695 1.1 lukem
696 1.1 lukem next_mod:;
697 1.1 lukem if ( mapping != NULL ) {
698 1.1 lukem /* use new attribute description */
699 1.1 lukem assert( mapping->m_dst_ad != NULL );
700 1.1 lukem ml->sml_desc = mapping->m_dst_ad;
701 1.1 lukem }
702 1.1 lukem
703 1.1 lukem mlp = &ml->sml_next;
704 1.1 lukem continue;
705 1.1 lukem
706 1.1.1.4 tron skip_mod:;
707 1.1.1.4 tron *mlp = (*mlp)->sml_next;
708 1.1.1.4 tron continue;
709 1.1.1.4 tron
710 1.1 lukem cleanup_mod:;
711 1.1 lukem ml = *mlp;
712 1.1 lukem *mlp = (*mlp)->sml_next;
713 1.1 lukem slap_mod_free( &ml->sml_mod, 0 );
714 1.1 lukem free( ml );
715 1.1 lukem }
716 1.1 lukem
717 1.1 lukem op->o_callback = &roc->cb;
718 1.1 lukem
719 1.1 lukem return SLAP_CB_CONTINUE;
720 1.1 lukem }
721 1.1 lukem
722 1.1 lukem static int
723 1.1 lukem rwm_op_modrdn( Operation *op, SlapReply *rs )
724 1.1 lukem {
725 1.1 lukem slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
726 1.1 lukem struct ldaprwmap *rwmap =
727 1.1 lukem (struct ldaprwmap *)on->on_bi.bi_private;
728 1.1 lukem
729 1.1 lukem int rc;
730 1.1.1.2 lukem dncookie dc;
731 1.1 lukem
732 1.1.1.4 tron rwm_op_cb *roc = rwm_callback_get( op );
733 1.1 lukem
734 1.1 lukem if ( op->orr_newSup ) {
735 1.1 lukem struct berval nnewSup = BER_BVNULL;
736 1.1 lukem struct berval newSup = BER_BVNULL;
737 1.1 lukem
738 1.1 lukem /*
739 1.1 lukem * Rewrite the new superior, if defined and required
740 1.1 lukem */
741 1.1 lukem dc.rwmap = rwmap;
742 1.1 lukem dc.conn = op->o_conn;
743 1.1 lukem dc.rs = rs;
744 1.1 lukem dc.ctx = "newSuperiorDN";
745 1.1 lukem newSup = *op->orr_newSup;
746 1.1 lukem nnewSup = *op->orr_nnewSup;
747 1.1 lukem rc = rwm_dn_massage_pretty_normalize( &dc, op->orr_newSup, &newSup, &nnewSup );
748 1.1 lukem if ( rc != LDAP_SUCCESS ) {
749 1.1 lukem op->o_bd->bd_info = (BackendInfo *)on->on_info;
750 1.1 lukem send_ldap_error( op, rs, rc, "newSuperiorDN massage error" );
751 1.1 lukem return -1;
752 1.1 lukem }
753 1.1 lukem
754 1.1 lukem if ( op->orr_newSup->bv_val != newSup.bv_val ) {
755 1.1 lukem op->orr_newSup = op->o_tmpalloc( sizeof( struct berval ),
756 1.1 lukem op->o_tmpmemctx );
757 1.1 lukem op->orr_nnewSup = op->o_tmpalloc( sizeof( struct berval ),
758 1.1 lukem op->o_tmpmemctx );
759 1.1 lukem *op->orr_newSup = newSup;
760 1.1 lukem *op->orr_nnewSup = nnewSup;
761 1.1 lukem }
762 1.1 lukem }
763 1.1 lukem
764 1.1 lukem /*
765 1.1.1.2 lukem * Rewrite the newRDN, if needed
766 1.1.1.2 lukem */
767 1.1.1.2 lukem {
768 1.1.1.2 lukem struct berval newrdn = BER_BVNULL;
769 1.1.1.2 lukem struct berval nnewrdn = BER_BVNULL;
770 1.1.1.2 lukem
771 1.1.1.2 lukem dc.rwmap = rwmap;
772 1.1.1.2 lukem dc.conn = op->o_conn;
773 1.1.1.2 lukem dc.rs = rs;
774 1.1.1.2 lukem dc.ctx = "newRDN";
775 1.1.1.2 lukem newrdn = op->orr_newrdn;
776 1.1.1.2 lukem nnewrdn = op->orr_nnewrdn;
777 1.1.1.2 lukem rc = rwm_dn_massage_pretty_normalize( &dc, &op->orr_newrdn, &newrdn, &nnewrdn );
778 1.1.1.2 lukem if ( rc != LDAP_SUCCESS ) {
779 1.1.1.2 lukem op->o_bd->bd_info = (BackendInfo *)on->on_info;
780 1.1.1.2 lukem send_ldap_error( op, rs, rc, "newRDN massage error" );
781 1.1.1.2 lukem goto err;
782 1.1.1.2 lukem }
783 1.1.1.2 lukem
784 1.1.1.2 lukem if ( op->orr_newrdn.bv_val != newrdn.bv_val ) {
785 1.1.1.2 lukem op->orr_newrdn = newrdn;
786 1.1.1.2 lukem op->orr_nnewrdn = nnewrdn;
787 1.1.1.2 lukem }
788 1.1.1.2 lukem }
789 1.1.1.2 lukem
790 1.1.1.2 lukem /*
791 1.1 lukem * Rewrite the dn, if needed
792 1.1 lukem */
793 1.1 lukem rc = rwm_op_dn_massage( op, rs, "renameDN", &roc->ros );
794 1.1 lukem if ( rc != LDAP_SUCCESS ) {
795 1.1 lukem op->o_bd->bd_info = (BackendInfo *)on->on_info;
796 1.1 lukem send_ldap_error( op, rs, rc, "renameDN massage error" );
797 1.1.1.2 lukem goto err;
798 1.1.1.2 lukem }
799 1.1.1.2 lukem
800 1.1.1.2 lukem op->o_callback = &roc->cb;
801 1.1.1.2 lukem
802 1.1.1.2 lukem rc = SLAP_CB_CONTINUE;
803 1.1.1.2 lukem
804 1.1.1.2 lukem if ( 0 ) {
805 1.1.1.2 lukem err:;
806 1.1 lukem if ( op->orr_newSup != roc->ros.orr_newSup ) {
807 1.1 lukem ch_free( op->orr_newSup->bv_val );
808 1.1 lukem ch_free( op->orr_nnewSup->bv_val );
809 1.1 lukem op->o_tmpfree( op->orr_newSup, op->o_tmpmemctx );
810 1.1 lukem op->o_tmpfree( op->orr_nnewSup, op->o_tmpmemctx );
811 1.1 lukem op->orr_newSup = roc->ros.orr_newSup;
812 1.1 lukem op->orr_nnewSup = roc->ros.orr_nnewSup;
813 1.1 lukem }
814 1.1 lukem
815 1.1.1.2 lukem if ( op->orr_newrdn.bv_val != roc->ros.orr_newrdn.bv_val ) {
816 1.1.1.2 lukem ch_free( op->orr_newrdn.bv_val );
817 1.1.1.2 lukem ch_free( op->orr_nnewrdn.bv_val );
818 1.1.1.2 lukem op->orr_newrdn = roc->ros.orr_newrdn;
819 1.1.1.2 lukem op->orr_nnewrdn = roc->ros.orr_nnewrdn;
820 1.1.1.2 lukem }
821 1.1.1.2 lukem }
822 1.1 lukem
823 1.1.1.2 lukem return rc;
824 1.1 lukem }
825 1.1 lukem
826 1.1 lukem
827 1.1 lukem static int
828 1.1 lukem rwm_swap_attrs( Operation *op, SlapReply *rs )
829 1.1 lukem {
830 1.1 lukem slap_callback *cb = op->o_callback;
831 1.1 lukem rwm_op_state *ros = cb->sc_private;
832 1.1 lukem
833 1.1 lukem rs->sr_attrs = ros->ors_attrs;
834 1.1 lukem
835 1.1 lukem /* other overlays might have touched op->ors_attrs,
836 1.1 lukem * so we restore the original version here, otherwise
837 1.1 lukem * attribute-mapping might fail */
838 1.1 lukem op->ors_attrs = ros->mapped_attrs;
839 1.1 lukem
840 1.1 lukem return SLAP_CB_CONTINUE;
841 1.1 lukem }
842 1.1 lukem
843 1.1.1.2 lukem /*
844 1.1.1.2 lukem * NOTE: this implementation of get/release entry is probably far from
845 1.1.1.2 lukem * optimal. The rationale consists in intercepting the request directed
846 1.1.1.2 lukem * to the underlying database, in order to rewrite/remap the request,
847 1.1.1.2 lukem * perform it using the modified data, duplicate the resulting entry
848 1.1.1.2 lukem * and finally free it when release is called.
849 1.1.1.2 lukem * This implies that subsequent overlays are not called, as the request
850 1.1.1.2 lukem * is directly shunted to the underlying database.
851 1.1.1.2 lukem */
852 1.1.1.2 lukem static int
853 1.1.1.2 lukem rwm_entry_release_rw( Operation *op, Entry *e, int rw )
854 1.1.1.2 lukem {
855 1.1.1.2 lukem slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
856 1.1.1.2 lukem
857 1.1.1.2 lukem /* can't be ours */
858 1.1.1.2 lukem if ( ((BackendInfo *)on->on_info->oi_orig)->bi_entry_get_rw == NULL ) {
859 1.1.1.2 lukem return SLAP_CB_CONTINUE;
860 1.1.1.2 lukem }
861 1.1.1.2 lukem
862 1.1.1.2 lukem /* just free entry if (probably) ours */
863 1.1.1.2 lukem if ( e->e_private == NULL && BER_BVISNULL( &e->e_bv ) ) {
864 1.1.1.2 lukem entry_free( e );
865 1.1.1.2 lukem return LDAP_SUCCESS;
866 1.1.1.2 lukem }
867 1.1.1.2 lukem
868 1.1.1.2 lukem return SLAP_CB_CONTINUE;
869 1.1.1.2 lukem }
870 1.1.1.2 lukem
871 1.1.1.2 lukem static int
872 1.1.1.2 lukem rwm_entry_get_rw( Operation *op, struct berval *ndn,
873 1.1.1.2 lukem ObjectClass *oc, AttributeDescription *at, int rw, Entry **ep )
874 1.1.1.2 lukem {
875 1.1.1.2 lukem slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
876 1.1.1.2 lukem int rc;
877 1.1.1.2 lukem BackendDB db;
878 1.1.1.2 lukem Operation op2;
879 1.1.1.2 lukem SlapReply rs = { REP_SEARCH };
880 1.1.1.2 lukem
881 1.1.1.2 lukem rwm_op_state ros = { 0 };
882 1.1.1.2 lukem struct berval mndn = BER_BVNULL;
883 1.1.1.2 lukem
884 1.1.1.2 lukem if ( ((BackendInfo *)on->on_info->oi_orig)->bi_entry_get_rw == NULL ) {
885 1.1.1.2 lukem return SLAP_CB_CONTINUE;
886 1.1.1.2 lukem }
887 1.1.1.2 lukem
888 1.1.1.2 lukem /* massage DN */
889 1.1.1.2 lukem op2.o_tag = LDAP_REQ_SEARCH;
890 1.1.1.2 lukem op2 = *op;
891 1.1.1.2 lukem op2.o_req_dn = *ndn;
892 1.1.1.2 lukem op2.o_req_ndn = *ndn;
893 1.1.1.2 lukem rc = rwm_op_dn_massage( &op2, &rs, "searchDN", &ros );
894 1.1.1.2 lukem if ( rc != LDAP_SUCCESS ) {
895 1.1.1.2 lukem return LDAP_OTHER;
896 1.1.1.2 lukem }
897 1.1.1.2 lukem
898 1.1.1.2 lukem mndn = BER_BVISNULL( &ros.r_ndn ) ? *ndn : ros.r_ndn;
899 1.1.1.2 lukem
900 1.1.1.2 lukem /* map attribute & objectClass */
901 1.1.1.2 lukem if ( at != NULL ) {
902 1.1.1.2 lukem }
903 1.1.1.2 lukem
904 1.1.1.2 lukem if ( oc != NULL ) {
905 1.1.1.2 lukem }
906 1.1.1.2 lukem
907 1.1.1.2 lukem /* fetch entry */
908 1.1.1.2 lukem db = *op->o_bd;
909 1.1.1.2 lukem op2.o_bd = &db;
910 1.1.1.2 lukem op2.o_bd->bd_info = (BackendInfo *)on->on_info->oi_orig;
911 1.1.1.2 lukem op2.ors_attrs = slap_anlist_all_attributes;
912 1.1.1.2 lukem rc = op2.o_bd->bd_info->bi_entry_get_rw( &op2, &mndn, oc, at, rw, ep );
913 1.1.1.2 lukem if ( rc == LDAP_SUCCESS && *ep != NULL ) {
914 1.1.1.2 lukem /* we assume be_entry_release() needs to be called */
915 1.1.1.2 lukem rs.sr_flags = REP_ENTRY_MUSTRELEASE;
916 1.1.1.2 lukem rs.sr_entry = *ep;
917 1.1.1.2 lukem
918 1.1.1.2 lukem /* duplicate & release */
919 1.1.1.2 lukem op2.o_bd->bd_info = (BackendInfo *)on;
920 1.1.1.2 lukem rc = rwm_send_entry( &op2, &rs );
921 1.1.1.4 tron RS_ASSERT( rs.sr_flags & REP_ENTRY_MUSTFLUSH );
922 1.1.1.2 lukem if ( rc == SLAP_CB_CONTINUE ) {
923 1.1.1.2 lukem *ep = rs.sr_entry;
924 1.1.1.2 lukem rc = LDAP_SUCCESS;
925 1.1.1.4 tron } else {
926 1.1.1.4 tron assert( rc != LDAP_SUCCESS && rs.sr_entry == *ep );
927 1.1.1.4 tron *ep = NULL;
928 1.1.1.4 tron op2.o_bd->bd_info = (BackendInfo *)on->on_info;
929 1.1.1.4 tron be_entry_release_r( &op2, rs.sr_entry );
930 1.1.1.4 tron op2.o_bd->bd_info = (BackendInfo *)on;
931 1.1.1.2 lukem }
932 1.1.1.2 lukem }
933 1.1.1.2 lukem
934 1.1.1.2 lukem if ( !BER_BVISNULL( &ros.r_ndn) && ros.r_ndn.bv_val != ndn->bv_val ) {
935 1.1.1.2 lukem op->o_tmpfree( ros.r_ndn.bv_val, op->o_tmpmemctx );
936 1.1.1.2 lukem }
937 1.1.1.2 lukem
938 1.1.1.2 lukem return rc;
939 1.1.1.2 lukem }
940 1.1.1.2 lukem
941 1.1 lukem static int
942 1.1 lukem rwm_op_search( Operation *op, SlapReply *rs )
943 1.1 lukem {
944 1.1 lukem slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
945 1.1 lukem struct ldaprwmap *rwmap =
946 1.1 lukem (struct ldaprwmap *)on->on_bi.bi_private;
947 1.1 lukem
948 1.1 lukem int rc;
949 1.1 lukem dncookie dc;
950 1.1 lukem
951 1.1 lukem struct berval fstr = BER_BVNULL;
952 1.1 lukem Filter *f = NULL;
953 1.1 lukem
954 1.1 lukem AttributeName *an = NULL;
955 1.1 lukem
956 1.1 lukem char *text = NULL;
957 1.1 lukem
958 1.1.1.4 tron rwm_op_cb *roc = rwm_callback_get( op );
959 1.1 lukem
960 1.1 lukem rc = rewrite_session_var_set( rwmap->rwm_rw, op->o_conn,
961 1.1 lukem "searchFilter", op->ors_filterstr.bv_val );
962 1.1 lukem if ( rc == LDAP_SUCCESS )
963 1.1 lukem rc = rwm_op_dn_massage( op, rs, "searchDN", &roc->ros );
964 1.1 lukem if ( rc != LDAP_SUCCESS ) {
965 1.1 lukem text = "searchDN massage error";
966 1.1 lukem goto error_return;
967 1.1 lukem }
968 1.1 lukem
969 1.1 lukem /*
970 1.1 lukem * Rewrite the dn if needed
971 1.1 lukem */
972 1.1 lukem dc.rwmap = rwmap;
973 1.1 lukem dc.conn = op->o_conn;
974 1.1 lukem dc.rs = rs;
975 1.1 lukem dc.ctx = "searchFilterAttrDN";
976 1.1 lukem
977 1.1 lukem rc = rwm_filter_map_rewrite( op, &dc, op->ors_filter, &fstr );
978 1.1 lukem if ( rc != LDAP_SUCCESS ) {
979 1.1 lukem text = "searchFilter/searchFilterAttrDN massage error";
980 1.1 lukem goto error_return;
981 1.1 lukem }
982 1.1 lukem
983 1.1 lukem f = str2filter_x( op, fstr.bv_val );
984 1.1 lukem
985 1.1 lukem if ( f == NULL ) {
986 1.1 lukem text = "massaged filter parse error";
987 1.1 lukem goto error_return;
988 1.1 lukem }
989 1.1 lukem
990 1.1 lukem op->ors_filter = f;
991 1.1 lukem op->ors_filterstr = fstr;
992 1.1 lukem
993 1.1.1.3 adam rc = rwm_map_attrnames( op, &rwmap->rwm_at, &rwmap->rwm_oc,
994 1.1 lukem op->ors_attrs, &an, RWM_MAP );
995 1.1 lukem if ( rc != LDAP_SUCCESS ) {
996 1.1 lukem text = "attribute list mapping error";
997 1.1 lukem goto error_return;
998 1.1 lukem }
999 1.1 lukem
1000 1.1 lukem op->ors_attrs = an;
1001 1.1 lukem /* store the mapped Attributes for later usage, in
1002 1.1 lukem * the case that other overlays change op->ors_attrs */
1003 1.1 lukem roc->ros.mapped_attrs = an;
1004 1.1 lukem roc->cb.sc_response = rwm_swap_attrs;
1005 1.1 lukem
1006 1.1 lukem op->o_callback = &roc->cb;
1007 1.1 lukem
1008 1.1 lukem return SLAP_CB_CONTINUE;
1009 1.1 lukem
1010 1.1 lukem error_return:;
1011 1.1 lukem if ( an != NULL ) {
1012 1.1 lukem ch_free( an );
1013 1.1 lukem }
1014 1.1 lukem
1015 1.1 lukem if ( f != NULL ) {
1016 1.1.1.2 lukem filter_free_x( op, f, 1 );
1017 1.1 lukem }
1018 1.1 lukem
1019 1.1 lukem if ( !BER_BVISNULL( &fstr ) ) {
1020 1.1.1.3 adam op->o_tmpfree( fstr.bv_val, op->o_tmpmemctx );
1021 1.1 lukem }
1022 1.1 lukem
1023 1.1.1.2 lukem rwm_op_rollback( op, rs, &roc->ros );
1024 1.1 lukem op->oq_search = roc->ros.oq_search;
1025 1.1.1.2 lukem op->o_tmpfree( roc, op->o_tmpmemctx );
1026 1.1 lukem
1027 1.1 lukem op->o_bd->bd_info = (BackendInfo *)on->on_info;
1028 1.1 lukem send_ldap_error( op, rs, rc, text );
1029 1.1 lukem
1030 1.1 lukem return -1;
1031 1.1 lukem
1032 1.1 lukem }
1033 1.1 lukem
1034 1.1 lukem static int
1035 1.1 lukem rwm_exop_passwd( Operation *op, SlapReply *rs )
1036 1.1 lukem {
1037 1.1 lukem slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
1038 1.1 lukem int rc;
1039 1.1 lukem rwm_op_cb *roc;
1040 1.1 lukem
1041 1.1 lukem struct berval id = BER_BVNULL,
1042 1.1 lukem pwold = BER_BVNULL,
1043 1.1 lukem pwnew = BER_BVNULL;
1044 1.1 lukem BerElement *ber = NULL;
1045 1.1 lukem
1046 1.1 lukem if ( !BER_BVISNULL( &op->o_req_ndn ) ) {
1047 1.1 lukem return LDAP_SUCCESS;
1048 1.1 lukem }
1049 1.1 lukem
1050 1.1 lukem if ( !SLAP_ISGLOBALOVERLAY( op->o_bd ) ) {
1051 1.1 lukem rs->sr_err = LDAP_OTHER;
1052 1.1 lukem return rs->sr_err;
1053 1.1 lukem }
1054 1.1 lukem
1055 1.1 lukem rs->sr_err = slap_passwd_parse( op->ore_reqdata, &id,
1056 1.1 lukem &pwold, &pwnew, &rs->sr_text );
1057 1.1 lukem if ( rs->sr_err != LDAP_SUCCESS ) {
1058 1.1 lukem return rs->sr_err;
1059 1.1 lukem }
1060 1.1 lukem
1061 1.1 lukem if ( !BER_BVISNULL( &id ) ) {
1062 1.1 lukem char idNul = id.bv_val[id.bv_len];
1063 1.1 lukem id.bv_val[id.bv_len] = '\0';
1064 1.1 lukem rs->sr_err = dnPrettyNormal( NULL, &id, &op->o_req_dn,
1065 1.1 lukem &op->o_req_ndn, op->o_tmpmemctx );
1066 1.1 lukem id.bv_val[id.bv_len] = idNul;
1067 1.1 lukem if ( rs->sr_err != LDAP_SUCCESS ) {
1068 1.1 lukem rs->sr_text = "Invalid DN";
1069 1.1 lukem return rs->sr_err;
1070 1.1 lukem }
1071 1.1 lukem
1072 1.1 lukem } else {
1073 1.1 lukem ber_dupbv_x( &op->o_req_dn, &op->o_dn, op->o_tmpmemctx );
1074 1.1 lukem ber_dupbv_x( &op->o_req_ndn, &op->o_ndn, op->o_tmpmemctx );
1075 1.1 lukem }
1076 1.1 lukem
1077 1.1.1.4 tron roc = rwm_callback_get( op );
1078 1.1 lukem
1079 1.1 lukem rc = rwm_op_dn_massage( op, rs, "extendedDN", &roc->ros );
1080 1.1 lukem if ( rc != LDAP_SUCCESS ) {
1081 1.1 lukem op->o_bd->bd_info = (BackendInfo *)on->on_info;
1082 1.1 lukem send_ldap_error( op, rs, rc, "extendedDN massage error" );
1083 1.1 lukem return -1;
1084 1.1 lukem }
1085 1.1 lukem
1086 1.1 lukem ber = ber_alloc_t( LBER_USE_DER );
1087 1.1 lukem if ( !ber ) {
1088 1.1 lukem rs->sr_err = LDAP_OTHER;
1089 1.1 lukem rs->sr_text = "No memory";
1090 1.1 lukem return rs->sr_err;
1091 1.1 lukem }
1092 1.1 lukem ber_printf( ber, "{" );
1093 1.1 lukem if ( !BER_BVISNULL( &id )) {
1094 1.1 lukem ber_printf( ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_ID,
1095 1.1 lukem &op->o_req_dn );
1096 1.1 lukem }
1097 1.1 lukem if ( !BER_BVISNULL( &pwold )) {
1098 1.1 lukem ber_printf( ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_OLD, &pwold );
1099 1.1 lukem }
1100 1.1 lukem if ( !BER_BVISNULL( &pwnew )) {
1101 1.1 lukem ber_printf( ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, &pwnew );
1102 1.1 lukem }
1103 1.1 lukem ber_printf( ber, "N}" );
1104 1.1 lukem ber_flatten( ber, &op->ore_reqdata );
1105 1.1 lukem ber_free( ber, 1 );
1106 1.1 lukem
1107 1.1 lukem op->o_callback = &roc->cb;
1108 1.1 lukem
1109 1.1 lukem return SLAP_CB_CONTINUE;
1110 1.1 lukem }
1111 1.1 lukem
1112 1.1 lukem static struct exop {
1113 1.1 lukem struct berval oid;
1114 1.1 lukem BI_op_extended *extended;
1115 1.1 lukem } exop_table[] = {
1116 1.1 lukem { BER_BVC(LDAP_EXOP_MODIFY_PASSWD), rwm_exop_passwd },
1117 1.1 lukem { BER_BVNULL, NULL }
1118 1.1 lukem };
1119 1.1 lukem
1120 1.1 lukem static int
1121 1.1 lukem rwm_extended( Operation *op, SlapReply *rs )
1122 1.1 lukem {
1123 1.1 lukem slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
1124 1.1 lukem int rc;
1125 1.1 lukem rwm_op_cb *roc;
1126 1.1 lukem
1127 1.1 lukem int i;
1128 1.1 lukem
1129 1.1 lukem for ( i = 0; exop_table[i].extended != NULL; i++ ) {
1130 1.1 lukem if ( bvmatch( &exop_table[i].oid, &op->oq_extended.rs_reqoid ) )
1131 1.1 lukem {
1132 1.1 lukem rc = exop_table[i].extended( op, rs );
1133 1.1 lukem switch ( rc ) {
1134 1.1 lukem case LDAP_SUCCESS:
1135 1.1 lukem break;
1136 1.1 lukem
1137 1.1 lukem case SLAP_CB_CONTINUE:
1138 1.1 lukem case SLAPD_ABANDON:
1139 1.1 lukem return rc;
1140 1.1 lukem
1141 1.1 lukem default:
1142 1.1 lukem send_ldap_result( op, rs );
1143 1.1 lukem return rc;
1144 1.1 lukem }
1145 1.1 lukem break;
1146 1.1 lukem }
1147 1.1 lukem }
1148 1.1 lukem
1149 1.1.1.4 tron roc = rwm_callback_get( op );
1150 1.1 lukem
1151 1.1 lukem rc = rwm_op_dn_massage( op, rs, "extendedDN", &roc->ros );
1152 1.1 lukem if ( rc != LDAP_SUCCESS ) {
1153 1.1 lukem op->o_bd->bd_info = (BackendInfo *)on->on_info;
1154 1.1 lukem send_ldap_error( op, rs, rc, "extendedDN massage error" );
1155 1.1 lukem return -1;
1156 1.1 lukem }
1157 1.1 lukem
1158 1.1 lukem /* TODO: rewrite/map extended data ? ... */
1159 1.1 lukem op->o_callback = &roc->cb;
1160 1.1 lukem
1161 1.1 lukem return SLAP_CB_CONTINUE;
1162 1.1 lukem }
1163 1.1 lukem
1164 1.1.1.4 tron static void
1165 1.1 lukem rwm_matched( Operation *op, SlapReply *rs )
1166 1.1 lukem {
1167 1.1 lukem slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
1168 1.1 lukem struct ldaprwmap *rwmap =
1169 1.1 lukem (struct ldaprwmap *)on->on_bi.bi_private;
1170 1.1 lukem
1171 1.1 lukem struct berval dn, mdn;
1172 1.1 lukem dncookie dc;
1173 1.1 lukem int rc;
1174 1.1 lukem
1175 1.1 lukem if ( rs->sr_matched == NULL ) {
1176 1.1.1.4 tron return;
1177 1.1 lukem }
1178 1.1 lukem
1179 1.1 lukem dc.rwmap = rwmap;
1180 1.1 lukem dc.conn = op->o_conn;
1181 1.1 lukem dc.rs = rs;
1182 1.1 lukem dc.ctx = "matchedDN";
1183 1.1 lukem ber_str2bv( rs->sr_matched, 0, 0, &dn );
1184 1.1 lukem mdn = dn;
1185 1.1 lukem rc = rwm_dn_massage_pretty( &dc, &dn, &mdn );
1186 1.1 lukem if ( rc != LDAP_SUCCESS ) {
1187 1.1 lukem rs->sr_err = rc;
1188 1.1 lukem rs->sr_text = "Rewrite error";
1189 1.1 lukem
1190 1.1.1.4 tron } else if ( mdn.bv_val != dn.bv_val ) {
1191 1.1 lukem if ( rs->sr_flags & REP_MATCHED_MUSTBEFREED ) {
1192 1.1 lukem ch_free( (void *)rs->sr_matched );
1193 1.1 lukem
1194 1.1 lukem } else {
1195 1.1 lukem rs->sr_flags |= REP_MATCHED_MUSTBEFREED;
1196 1.1 lukem }
1197 1.1 lukem rs->sr_matched = mdn.bv_val;
1198 1.1 lukem }
1199 1.1 lukem }
1200 1.1 lukem
1201 1.1 lukem static int
1202 1.1 lukem rwm_attrs( Operation *op, SlapReply *rs, Attribute** a_first, int stripEntryDN )
1203 1.1 lukem {
1204 1.1 lukem slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
1205 1.1 lukem struct ldaprwmap *rwmap =
1206 1.1 lukem (struct ldaprwmap *)on->on_bi.bi_private;
1207 1.1 lukem
1208 1.1 lukem dncookie dc;
1209 1.1 lukem int rc;
1210 1.1 lukem Attribute **ap;
1211 1.1 lukem int isupdate;
1212 1.1 lukem int check_duplicate_attrs = 0;
1213 1.1 lukem
1214 1.1 lukem /*
1215 1.1 lukem * Rewrite the dn attrs, if needed
1216 1.1 lukem */
1217 1.1 lukem dc.rwmap = rwmap;
1218 1.1 lukem dc.conn = op->o_conn;
1219 1.1 lukem dc.rs = NULL;
1220 1.1 lukem
1221 1.1 lukem /* FIXME: the entries are in the remote mapping form;
1222 1.1 lukem * so we need to select those attributes we are willing
1223 1.1 lukem * to return, and remap them accordingly */
1224 1.1 lukem
1225 1.1 lukem /* FIXME: in principle, one could map an attribute
1226 1.1 lukem * on top of another, which already exists.
1227 1.1 lukem * As such, in the end there might exist more than
1228 1.1 lukem * one instance of an attribute.
1229 1.1 lukem * We should at least check if this occurs, and issue
1230 1.1 lukem * an error (because multiple instances of attrs in
1231 1.1 lukem * response are not valid), or merge the values (what
1232 1.1 lukem * about duplicate values?) */
1233 1.1 lukem isupdate = be_shadow_update( op );
1234 1.1 lukem for ( ap = a_first; *ap; ) {
1235 1.1 lukem struct ldapmapping *mapping = NULL;
1236 1.1 lukem int drop_missing;
1237 1.1 lukem int last = -1;
1238 1.1 lukem Attribute *a;
1239 1.1 lukem
1240 1.1.1.2 lukem if ( ( rwmap->rwm_flags & RWM_F_DROP_UNREQUESTED_ATTRS ) &&
1241 1.1.1.2 lukem op->ors_attrs != NULL &&
1242 1.1.1.2 lukem !SLAP_USERATTRS( rs->sr_attr_flags ) &&
1243 1.1.1.2 lukem !ad_inlist( (*ap)->a_desc, op->ors_attrs ) )
1244 1.1 lukem {
1245 1.1.1.2 lukem goto cleanup_attr;
1246 1.1.1.2 lukem }
1247 1.1 lukem
1248 1.1.1.2 lukem drop_missing = rwm_mapping( &rwmap->rwm_at,
1249 1.1.1.2 lukem &(*ap)->a_desc->ad_cname, &mapping, RWM_REMAP );
1250 1.1.1.2 lukem if ( drop_missing || ( mapping != NULL && BER_BVISEMPTY( &mapping->m_dst ) ) )
1251 1.1.1.2 lukem {
1252 1.1.1.2 lukem goto cleanup_attr;
1253 1.1.1.2 lukem }
1254 1.1.1.2 lukem if ( mapping != NULL ) {
1255 1.1.1.2 lukem assert( mapping->m_dst_ad != NULL );
1256 1.1 lukem
1257 1.1.1.2 lukem /* try to normalize mapped Attributes if the original
1258 1.1.1.2 lukem * AttributeType was not normalized */
1259 1.1.1.2 lukem if ( (!(*ap)->a_desc->ad_type->sat_equality ||
1260 1.1.1.2 lukem !(*ap)->a_desc->ad_type->sat_equality->smr_normalize) &&
1261 1.1.1.2 lukem mapping->m_dst_ad->ad_type->sat_equality &&
1262 1.1.1.2 lukem mapping->m_dst_ad->ad_type->sat_equality->smr_normalize )
1263 1.1.1.2 lukem {
1264 1.1.1.2 lukem if ((rwmap->rwm_flags & RWM_F_NORMALIZE_MAPPED_ATTRS))
1265 1.1 lukem {
1266 1.1 lukem int i = 0;
1267 1.1 lukem
1268 1.1 lukem last = (*ap)->a_numvals;
1269 1.1 lukem if ( last )
1270 1.1 lukem {
1271 1.1 lukem (*ap)->a_nvals = ch_malloc( (last+1) * sizeof(struct berval) );
1272 1.1 lukem
1273 1.1 lukem for ( i = 0; !BER_BVISNULL( &(*ap)->a_vals[i]); i++ ) {
1274 1.1 lukem int rc;
1275 1.1 lukem /*
1276 1.1 lukem * check that each value is valid per syntax
1277 1.1 lukem * and pretty if appropriate
1278 1.1 lukem */
1279 1.1 lukem rc = mapping->m_dst_ad->ad_type->sat_equality->smr_normalize(
1280 1.1 lukem SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
1281 1.1 lukem mapping->m_dst_ad->ad_type->sat_syntax,
1282 1.1 lukem mapping->m_dst_ad->ad_type->sat_equality,
1283 1.1 lukem &(*ap)->a_vals[i], &(*ap)->a_nvals[i],
1284 1.1 lukem NULL );
1285 1.1 lukem
1286 1.1 lukem if ( rc != LDAP_SUCCESS ) {
1287 1.1.1.4 tron /* FIXME: this is wrong, putting a non-normalized value
1288 1.1.1.4 tron * into nvals. But when a proxy sends us bogus data,
1289 1.1.1.4 tron * we still need to give it to the client, even if it
1290 1.1.1.4 tron * violates the syntax. I.e., we don't want to silently
1291 1.1.1.4 tron * drop things and trigger an apparent data loss.
1292 1.1.1.4 tron */
1293 1.1.1.4 tron ber_dupbv( &(*ap)->a_nvals[i], &(*ap)->a_vals[i] );
1294 1.1 lukem }
1295 1.1 lukem }
1296 1.1 lukem BER_BVZERO( &(*ap)->a_nvals[i] );
1297 1.1 lukem }
1298 1.1.1.2 lukem
1299 1.1.1.2 lukem } else {
1300 1.1.1.2 lukem assert( (*ap)->a_nvals == (*ap)->a_vals );
1301 1.1.1.2 lukem (*ap)->a_nvals = NULL;
1302 1.1.1.2 lukem ber_bvarray_dup_x( &(*ap)->a_nvals, (*ap)->a_vals, NULL );
1303 1.1 lukem }
1304 1.1.1.2 lukem }
1305 1.1 lukem
1306 1.1.1.2 lukem /* rewrite the attribute description */
1307 1.1.1.2 lukem (*ap)->a_desc = mapping->m_dst_ad;
1308 1.1 lukem
1309 1.1.1.2 lukem /* will need to check for duplicate attrs */
1310 1.1.1.2 lukem check_duplicate_attrs++;
1311 1.1 lukem }
1312 1.1 lukem
1313 1.1 lukem if ( (*ap)->a_desc == slap_schema.si_ad_entryDN ) {
1314 1.1 lukem if ( stripEntryDN ) {
1315 1.1 lukem /* will be generated by frontend */
1316 1.1 lukem goto cleanup_attr;
1317 1.1 lukem }
1318 1.1 lukem
1319 1.1 lukem } else if ( !isupdate
1320 1.1 lukem && !get_relax( op )
1321 1.1 lukem && (*ap)->a_desc->ad_type->sat_no_user_mod
1322 1.1 lukem && (*ap)->a_desc->ad_type != slap_schema.si_at_undefined )
1323 1.1 lukem {
1324 1.1 lukem goto next_attr;
1325 1.1 lukem }
1326 1.1 lukem
1327 1.1 lukem if ( last == -1 ) { /* not yet counted */
1328 1.1 lukem last = (*ap)->a_numvals;
1329 1.1 lukem }
1330 1.1 lukem
1331 1.1 lukem if ( last == 0 ) {
1332 1.1 lukem /* empty? leave it in place because of attrsonly and vlv */
1333 1.1 lukem goto next_attr;
1334 1.1 lukem }
1335 1.1 lukem last--;
1336 1.1 lukem
1337 1.1 lukem if ( (*ap)->a_desc == slap_schema.si_ad_objectClass
1338 1.1 lukem || (*ap)->a_desc == slap_schema.si_ad_structuralObjectClass )
1339 1.1 lukem {
1340 1.1 lukem struct berval *bv;
1341 1.1 lukem
1342 1.1 lukem for ( bv = (*ap)->a_vals; !BER_BVISNULL( bv ); bv++ ) {
1343 1.1 lukem struct berval mapped;
1344 1.1 lukem
1345 1.1 lukem rwm_map( &rwmap->rwm_oc, &bv[0], &mapped, RWM_REMAP );
1346 1.1 lukem if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) ) {
1347 1.1 lukem remove_oc:;
1348 1.1 lukem ch_free( bv[0].bv_val );
1349 1.1 lukem BER_BVZERO( &bv[0] );
1350 1.1 lukem if ( &(*ap)->a_vals[last] > &bv[0] ) {
1351 1.1 lukem bv[0] = (*ap)->a_vals[last];
1352 1.1 lukem BER_BVZERO( &(*ap)->a_vals[last] );
1353 1.1 lukem }
1354 1.1 lukem last--;
1355 1.1 lukem bv--;
1356 1.1 lukem
1357 1.1.1.2 lukem } else if ( mapped.bv_val != bv[0].bv_val
1358 1.1.1.2 lukem && ber_bvstrcasecmp( &mapped, &bv[0] ) != 0 )
1359 1.1.1.2 lukem {
1360 1.1 lukem int i;
1361 1.1 lukem
1362 1.1 lukem for ( i = 0; !BER_BVISNULL( &(*ap)->a_vals[ i ] ); i++ ) {
1363 1.1 lukem if ( &(*ap)->a_vals[ i ] == bv ) {
1364 1.1 lukem continue;
1365 1.1 lukem }
1366 1.1 lukem
1367 1.1 lukem if ( ber_bvstrcasecmp( &mapped, &(*ap)->a_vals[ i ] ) == 0 ) {
1368 1.1 lukem break;
1369 1.1 lukem }
1370 1.1 lukem }
1371 1.1 lukem
1372 1.1 lukem if ( !BER_BVISNULL( &(*ap)->a_vals[ i ] ) ) {
1373 1.1 lukem goto remove_oc;
1374 1.1 lukem }
1375 1.1 lukem
1376 1.1 lukem /*
1377 1.1 lukem * FIXME: after LBER_FREEing
1378 1.1 lukem * the value is replaced by
1379 1.1 lukem * ch_alloc'ed memory
1380 1.1 lukem */
1381 1.1 lukem ber_bvreplace( &bv[0], &mapped );
1382 1.1 lukem
1383 1.1 lukem /* FIXME: will need to check
1384 1.1 lukem * if the structuralObjectClass
1385 1.1 lukem * changed */
1386 1.1 lukem }
1387 1.1 lukem }
1388 1.1 lukem
1389 1.1 lukem /*
1390 1.1 lukem * It is necessary to try to rewrite attributes with
1391 1.1 lukem * dn syntax because they might be used in ACLs as
1392 1.1 lukem * members of groups; since ACLs are applied to the
1393 1.1 lukem * rewritten stuff, no dn-based subject clause could
1394 1.1 lukem * be used at the ldap backend side (see
1395 1.1 lukem * http://www.OpenLDAP.org/faq/data/cache/452.html)
1396 1.1 lukem * The problem can be overcome by moving the dn-based
1397 1.1 lukem * ACLs to the target directory server, and letting
1398 1.1 lukem * everything pass thru the ldap backend. */
1399 1.1 lukem /* FIXME: handle distinguishedName-like syntaxes, like
1400 1.1 lukem * nameAndOptionalUID */
1401 1.1 lukem } else if ( (*ap)->a_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName
1402 1.1 lukem || ( mapping != NULL && mapping->m_src_ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName ) )
1403 1.1 lukem {
1404 1.1 lukem dc.ctx = "searchAttrDN";
1405 1.1.1.2 lukem rc = rwm_dnattr_result_rewrite( &dc, (*ap)->a_vals, (*ap)->a_nvals );
1406 1.1 lukem if ( rc != LDAP_SUCCESS ) {
1407 1.1 lukem goto cleanup_attr;
1408 1.1 lukem }
1409 1.1 lukem
1410 1.1 lukem } else if ( (*ap)->a_desc == slap_schema.si_ad_ref ) {
1411 1.1 lukem dc.ctx = "searchAttrDN";
1412 1.1 lukem rc = rwm_referral_result_rewrite( &dc, (*ap)->a_vals );
1413 1.1 lukem if ( rc != LDAP_SUCCESS ) {
1414 1.1 lukem goto cleanup_attr;
1415 1.1 lukem }
1416 1.1 lukem }
1417 1.1 lukem
1418 1.1 lukem
1419 1.1 lukem next_attr:;
1420 1.1 lukem ap = &(*ap)->a_next;
1421 1.1 lukem continue;
1422 1.1 lukem
1423 1.1 lukem cleanup_attr:;
1424 1.1 lukem a = *ap;
1425 1.1 lukem *ap = (*ap)->a_next;
1426 1.1 lukem
1427 1.1 lukem attr_free( a );
1428 1.1 lukem }
1429 1.1 lukem
1430 1.1 lukem /* only check if some mapping occurred */
1431 1.1 lukem if ( check_duplicate_attrs ) {
1432 1.1 lukem for ( ap = a_first; *ap != NULL; ap = &(*ap)->a_next ) {
1433 1.1 lukem Attribute **tap;
1434 1.1 lukem
1435 1.1 lukem for ( tap = &(*ap)->a_next; *tap != NULL; ) {
1436 1.1 lukem if ( (*tap)->a_desc == (*ap)->a_desc ) {
1437 1.1 lukem Entry e = { 0 };
1438 1.1 lukem Modification mod = { 0 };
1439 1.1 lukem const char *text = NULL;
1440 1.1 lukem char textbuf[ SLAP_TEXT_BUFLEN ];
1441 1.1 lukem Attribute *next = (*tap)->a_next;
1442 1.1 lukem
1443 1.1 lukem BER_BVSTR( &e.e_name, "" );
1444 1.1 lukem BER_BVSTR( &e.e_nname, "" );
1445 1.1 lukem e.e_attrs = *ap;
1446 1.1 lukem mod.sm_op = LDAP_MOD_ADD;
1447 1.1 lukem mod.sm_desc = (*ap)->a_desc;
1448 1.1 lukem mod.sm_type = mod.sm_desc->ad_cname;
1449 1.1 lukem mod.sm_numvals = (*tap)->a_numvals;
1450 1.1 lukem mod.sm_values = (*tap)->a_vals;
1451 1.1 lukem if ( (*tap)->a_nvals != (*tap)->a_vals ) {
1452 1.1 lukem mod.sm_nvalues = (*tap)->a_nvals;
1453 1.1 lukem }
1454 1.1 lukem
1455 1.1 lukem (void)modify_add_values( &e, &mod,
1456 1.1 lukem /* permissive */ 1,
1457 1.1 lukem &text, textbuf, sizeof( textbuf ) );
1458 1.1 lukem
1459 1.1 lukem /* should not insert new attrs! */
1460 1.1 lukem assert( e.e_attrs == *ap );
1461 1.1 lukem
1462 1.1 lukem attr_free( *tap );
1463 1.1 lukem *tap = next;
1464 1.1 lukem
1465 1.1 lukem } else {
1466 1.1 lukem tap = &(*tap)->a_next;
1467 1.1 lukem }
1468 1.1 lukem }
1469 1.1 lukem }
1470 1.1 lukem }
1471 1.1 lukem
1472 1.1 lukem return 0;
1473 1.1 lukem }
1474 1.1 lukem
1475 1.1.1.4 tron /* Should return SLAP_CB_CONTINUE or failure, never LDAP_SUCCESS. */
1476 1.1 lukem static int
1477 1.1 lukem rwm_send_entry( Operation *op, SlapReply *rs )
1478 1.1 lukem {
1479 1.1 lukem slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
1480 1.1 lukem struct ldaprwmap *rwmap =
1481 1.1 lukem (struct ldaprwmap *)on->on_bi.bi_private;
1482 1.1 lukem
1483 1.1 lukem Entry *e = NULL;
1484 1.1 lukem struct berval dn = BER_BVNULL,
1485 1.1 lukem ndn = BER_BVNULL;
1486 1.1 lukem dncookie dc;
1487 1.1 lukem int rc;
1488 1.1 lukem
1489 1.1 lukem assert( rs->sr_entry != NULL );
1490 1.1 lukem
1491 1.1 lukem /*
1492 1.1 lukem * Rewrite the dn of the result, if needed
1493 1.1 lukem */
1494 1.1 lukem dc.rwmap = rwmap;
1495 1.1 lukem dc.conn = op->o_conn;
1496 1.1 lukem dc.rs = NULL;
1497 1.1 lukem dc.ctx = "searchEntryDN";
1498 1.1 lukem
1499 1.1 lukem e = rs->sr_entry;
1500 1.1 lukem if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) {
1501 1.1 lukem /* FIXME: all we need to duplicate are:
1502 1.1 lukem * - dn
1503 1.1 lukem * - ndn
1504 1.1 lukem * - attributes that are requested
1505 1.1 lukem * - no values if attrsonly is set
1506 1.1 lukem */
1507 1.1 lukem e = entry_dup( e );
1508 1.1 lukem if ( e == NULL ) {
1509 1.1 lukem rc = LDAP_NO_MEMORY;
1510 1.1 lukem goto fail;
1511 1.1 lukem }
1512 1.1.1.4 tron } else if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) {
1513 1.1.1.4 tron /* ITS#6423: REP_ENTRY_MUSTRELEASE incompatible
1514 1.1.1.4 tron * with REP_ENTRY_MODIFIABLE */
1515 1.1.1.4 tron RS_ASSERT( 0 );
1516 1.1.1.4 tron rc = 1;
1517 1.1.1.4 tron goto fail;
1518 1.1 lukem }
1519 1.1 lukem
1520 1.1 lukem /*
1521 1.1 lukem * Note: this may fail if the target host(s) schema differs
1522 1.1 lukem * from the one known to the meta, and a DN with unknown
1523 1.1 lukem * attributes is returned.
1524 1.1 lukem */
1525 1.1 lukem dn = e->e_name;
1526 1.1 lukem ndn = e->e_nname;
1527 1.1 lukem rc = rwm_dn_massage_pretty_normalize( &dc, &e->e_name, &dn, &ndn );
1528 1.1 lukem if ( rc != LDAP_SUCCESS ) {
1529 1.1 lukem rc = 1;
1530 1.1 lukem goto fail;
1531 1.1 lukem }
1532 1.1 lukem
1533 1.1 lukem if ( e->e_name.bv_val != dn.bv_val ) {
1534 1.1 lukem ch_free( e->e_name.bv_val );
1535 1.1 lukem ch_free( e->e_nname.bv_val );
1536 1.1 lukem
1537 1.1 lukem e->e_name = dn;
1538 1.1 lukem e->e_nname = ndn;
1539 1.1 lukem }
1540 1.1 lukem
1541 1.1 lukem /* TODO: map entry attribute types, objectclasses
1542 1.1 lukem * and dn-valued attribute values */
1543 1.1 lukem
1544 1.1 lukem /* FIXME: the entries are in the remote mapping form;
1545 1.1 lukem * so we need to select those attributes we are willing
1546 1.1 lukem * to return, and remap them accordingly */
1547 1.1 lukem (void)rwm_attrs( op, rs, &e->e_attrs, 1 );
1548 1.1 lukem
1549 1.1.1.4 tron if ( e != rs->sr_entry ) {
1550 1.1.1.4 tron /* Reimplementing rs_replace_entry(), I suppose to
1551 1.1.1.4 tron * bypass our own dubious rwm_entry_release_rw() */
1552 1.1.1.4 tron if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) {
1553 1.1.1.4 tron rs->sr_flags ^= REP_ENTRY_MUSTRELEASE;
1554 1.1.1.4 tron op->o_bd->bd_info = (BackendInfo *)on->on_info;
1555 1.1.1.4 tron be_entry_release_r( op, rs->sr_entry );
1556 1.1.1.4 tron op->o_bd->bd_info = (BackendInfo *)on;
1557 1.1.1.4 tron } else if ( rs->sr_flags & REP_ENTRY_MUSTBEFREED ) {
1558 1.1.1.4 tron entry_free( rs->sr_entry );
1559 1.1.1.3 adam }
1560 1.1.1.4 tron rs->sr_entry = e;
1561 1.1.1.4 tron rs->sr_flags |= REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED;
1562 1.1 lukem }
1563 1.1 lukem
1564 1.1 lukem return SLAP_CB_CONTINUE;
1565 1.1 lukem
1566 1.1 lukem fail:;
1567 1.1 lukem if ( e != NULL && e != rs->sr_entry ) {
1568 1.1 lukem if ( e->e_name.bv_val == dn.bv_val ) {
1569 1.1 lukem BER_BVZERO( &e->e_name );
1570 1.1 lukem }
1571 1.1 lukem
1572 1.1 lukem if ( e->e_nname.bv_val == ndn.bv_val ) {
1573 1.1 lukem BER_BVZERO( &e->e_nname );
1574 1.1 lukem }
1575 1.1 lukem
1576 1.1 lukem entry_free( e );
1577 1.1 lukem }
1578 1.1 lukem
1579 1.1 lukem if ( !BER_BVISNULL( &dn ) ) {
1580 1.1 lukem ch_free( dn.bv_val );
1581 1.1 lukem }
1582 1.1 lukem
1583 1.1 lukem if ( !BER_BVISNULL( &ndn ) ) {
1584 1.1 lukem ch_free( ndn.bv_val );
1585 1.1 lukem }
1586 1.1 lukem
1587 1.1 lukem return rc;
1588 1.1 lukem }
1589 1.1 lukem
1590 1.1 lukem static int
1591 1.1 lukem rwm_operational( Operation *op, SlapReply *rs )
1592 1.1 lukem {
1593 1.1 lukem /* FIXME: the entries are in the remote mapping form;
1594 1.1 lukem * so we need to select those attributes we are willing
1595 1.1 lukem * to return, and remap them accordingly */
1596 1.1 lukem if ( rs->sr_operational_attrs ) {
1597 1.1 lukem rwm_attrs( op, rs, &rs->sr_operational_attrs, 1 );
1598 1.1 lukem }
1599 1.1 lukem
1600 1.1 lukem return SLAP_CB_CONTINUE;
1601 1.1 lukem }
1602 1.1 lukem
1603 1.1 lukem #if 0
1604 1.1 lukem /* don't use this; it cannot be reverted, and leaves op->o_req_dn
1605 1.1 lukem * rewritten for subsequent operations; fine for plain suffixmassage,
1606 1.1 lukem * but destroys everything else */
1607 1.1 lukem static int
1608 1.1 lukem rwm_chk_referrals( Operation *op, SlapReply *rs )
1609 1.1 lukem {
1610 1.1 lukem slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
1611 1.1 lukem int rc;
1612 1.1 lukem
1613 1.1 lukem rc = rwm_op_dn_massage( op, rs, "referralCheckDN" );
1614 1.1 lukem if ( rc != LDAP_SUCCESS ) {
1615 1.1 lukem op->o_bd->bd_info = (BackendInfo *)on->on_info;
1616 1.1 lukem send_ldap_error( op, rs, rc, "referralCheckDN massage error" );
1617 1.1 lukem return -1;
1618 1.1 lukem }
1619 1.1 lukem
1620 1.1 lukem return SLAP_CB_CONTINUE;
1621 1.1 lukem }
1622 1.1 lukem #endif
1623 1.1 lukem
1624 1.1 lukem static int
1625 1.1 lukem rwm_rw_config(
1626 1.1 lukem BackendDB *be,
1627 1.1 lukem const char *fname,
1628 1.1 lukem int lineno,
1629 1.1 lukem int argc,
1630 1.1 lukem char **argv )
1631 1.1 lukem {
1632 1.1 lukem slap_overinst *on = (slap_overinst *) be->bd_info;
1633 1.1 lukem struct ldaprwmap *rwmap =
1634 1.1 lukem (struct ldaprwmap *)on->on_bi.bi_private;
1635 1.1 lukem
1636 1.1 lukem return rewrite_parse( rwmap->rwm_rw,
1637 1.1 lukem fname, lineno, argc, argv );
1638 1.1 lukem
1639 1.1 lukem return 0;
1640 1.1 lukem }
1641 1.1 lukem
1642 1.1 lukem static int
1643 1.1 lukem rwm_suffixmassage_config(
1644 1.1 lukem BackendDB *be,
1645 1.1 lukem const char *fname,
1646 1.1 lukem int lineno,
1647 1.1 lukem int argc,
1648 1.1 lukem char **argv )
1649 1.1 lukem {
1650 1.1 lukem slap_overinst *on = (slap_overinst *) be->bd_info;
1651 1.1 lukem struct ldaprwmap *rwmap =
1652 1.1 lukem (struct ldaprwmap *)on->on_bi.bi_private;
1653 1.1 lukem
1654 1.1 lukem struct berval bvnc, nvnc, pvnc, brnc, nrnc, prnc;
1655 1.1 lukem int massaged;
1656 1.1 lukem int rc;
1657 1.1 lukem
1658 1.1 lukem /*
1659 1.1 lukem * syntax:
1660 1.1 lukem *
1661 1.1 lukem * suffixmassage [<suffix>] <massaged suffix>
1662 1.1 lukem *
1663 1.1 lukem * the [<suffix>] field must be defined as a valid suffix
1664 1.1 lukem * for the current database;
1665 1.1 lukem * the <massaged suffix> shouldn't have already been
1666 1.1 lukem * defined as a valid suffix for the current server
1667 1.1 lukem */
1668 1.1 lukem if ( argc == 2 ) {
1669 1.1 lukem if ( be->be_suffix == NULL ) {
1670 1.1.1.3 adam Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1671 1.1 lukem " \"suffixMassage [<suffix>]"
1672 1.1 lukem " <massaged suffix>\" without "
1673 1.1 lukem "<suffix> part requires database "
1674 1.1 lukem "suffix be defined first.\n",
1675 1.1.1.3 adam fname, lineno, 0 );
1676 1.1 lukem return 1;
1677 1.1 lukem }
1678 1.1 lukem bvnc = be->be_suffix[ 0 ];
1679 1.1 lukem massaged = 1;
1680 1.1 lukem
1681 1.1 lukem } else if ( argc == 3 ) {
1682 1.1 lukem ber_str2bv( argv[ 1 ], 0, 0, &bvnc );
1683 1.1 lukem massaged = 2;
1684 1.1 lukem
1685 1.1 lukem } else {
1686 1.1.1.3 adam Debug( LDAP_DEBUG_ANY, "%s: line %d: syntax is"
1687 1.1 lukem " \"suffixMassage [<suffix>]"
1688 1.1 lukem " <massaged suffix>\"\n",
1689 1.1.1.3 adam fname, lineno, 0 );
1690 1.1 lukem return 1;
1691 1.1 lukem }
1692 1.1 lukem
1693 1.1 lukem if ( dnPrettyNormal( NULL, &bvnc, &pvnc, &nvnc, NULL ) != LDAP_SUCCESS ) {
1694 1.1.1.3 adam Debug( LDAP_DEBUG_ANY, "%s: line %d: suffix DN %s is invalid\n",
1695 1.1 lukem fname, lineno, bvnc.bv_val );
1696 1.1 lukem return 1;
1697 1.1 lukem }
1698 1.1 lukem
1699 1.1 lukem ber_str2bv( argv[ massaged ], 0, 0, &brnc );
1700 1.1 lukem if ( dnPrettyNormal( NULL, &brnc, &prnc, &nrnc, NULL ) != LDAP_SUCCESS ) {
1701 1.1.1.3 adam Debug( LDAP_DEBUG_ANY, "%s: line %d: suffix DN %s is invalid\n",
1702 1.1 lukem fname, lineno, brnc.bv_val );
1703 1.1 lukem free( nvnc.bv_val );
1704 1.1 lukem free( pvnc.bv_val );
1705 1.1 lukem return 1;
1706 1.1 lukem }
1707 1.1 lukem
1708 1.1 lukem /*
1709 1.1 lukem * The suffix massaging is emulated
1710 1.1 lukem * by means of the rewrite capabilities
1711 1.1 lukem */
1712 1.1 lukem rc = rwm_suffix_massage_config( rwmap->rwm_rw,
1713 1.1 lukem &pvnc, &nvnc, &prnc, &nrnc );
1714 1.1 lukem free( nvnc.bv_val );
1715 1.1 lukem free( pvnc.bv_val );
1716 1.1 lukem free( nrnc.bv_val );
1717 1.1 lukem free( prnc.bv_val );
1718 1.1 lukem
1719 1.1 lukem return rc;
1720 1.1 lukem }
1721 1.1 lukem
1722 1.1 lukem static int
1723 1.1 lukem rwm_m_config(
1724 1.1 lukem BackendDB *be,
1725 1.1 lukem const char *fname,
1726 1.1 lukem int lineno,
1727 1.1 lukem int argc,
1728 1.1 lukem char **argv )
1729 1.1 lukem {
1730 1.1 lukem slap_overinst *on = (slap_overinst *) be->bd_info;
1731 1.1 lukem struct ldaprwmap *rwmap =
1732 1.1 lukem (struct ldaprwmap *)on->on_bi.bi_private;
1733 1.1 lukem
1734 1.1 lukem /* objectclass/attribute mapping */
1735 1.1 lukem return rwm_map_config( &rwmap->rwm_oc,
1736 1.1 lukem &rwmap->rwm_at,
1737 1.1 lukem fname, lineno, argc, argv );
1738 1.1 lukem }
1739 1.1 lukem
1740 1.1 lukem static int
1741 1.1 lukem rwm_response( Operation *op, SlapReply *rs )
1742 1.1 lukem {
1743 1.1 lukem slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
1744 1.1 lukem struct ldaprwmap *rwmap =
1745 1.1 lukem (struct ldaprwmap *)on->on_bi.bi_private;
1746 1.1 lukem
1747 1.1 lukem int rc;
1748 1.1 lukem
1749 1.1 lukem if ( op->o_tag == LDAP_REQ_SEARCH && rs->sr_type == REP_SEARCH ) {
1750 1.1 lukem return rwm_send_entry( op, rs );
1751 1.1 lukem }
1752 1.1 lukem
1753 1.1 lukem switch( op->o_tag ) {
1754 1.1 lukem case LDAP_REQ_SEARCH:
1755 1.1 lukem case LDAP_REQ_BIND:
1756 1.1 lukem case LDAP_REQ_ADD:
1757 1.1 lukem case LDAP_REQ_DELETE:
1758 1.1 lukem case LDAP_REQ_MODRDN:
1759 1.1 lukem case LDAP_REQ_MODIFY:
1760 1.1 lukem case LDAP_REQ_COMPARE:
1761 1.1 lukem case LDAP_REQ_EXTENDED:
1762 1.1 lukem if ( rs->sr_ref ) {
1763 1.1 lukem dncookie dc;
1764 1.1 lukem
1765 1.1 lukem /*
1766 1.1 lukem * Rewrite the dn of the referrals, if needed
1767 1.1 lukem */
1768 1.1 lukem dc.rwmap = rwmap;
1769 1.1 lukem dc.conn = op->o_conn;
1770 1.1 lukem dc.rs = NULL;
1771 1.1 lukem dc.ctx = "referralDN";
1772 1.1 lukem rc = rwm_referral_result_rewrite( &dc, rs->sr_ref );
1773 1.1.1.4 tron /* FIXME: impossible, so far */
1774 1.1 lukem if ( rc != LDAP_SUCCESS ) {
1775 1.1.1.4 tron rs->sr_err = rc;
1776 1.1 lukem break;
1777 1.1 lukem }
1778 1.1 lukem }
1779 1.1 lukem
1780 1.1.1.4 tron rwm_matched( op, rs );
1781 1.1 lukem break;
1782 1.1 lukem }
1783 1.1 lukem
1784 1.1.1.4 tron return SLAP_CB_CONTINUE;
1785 1.1 lukem }
1786 1.1 lukem
1787 1.1 lukem static int
1788 1.1 lukem rwm_db_config(
1789 1.1 lukem BackendDB *be,
1790 1.1 lukem const char *fname,
1791 1.1 lukem int lineno,
1792 1.1 lukem int argc,
1793 1.1 lukem char **argv )
1794 1.1 lukem {
1795 1.1 lukem slap_overinst *on = (slap_overinst *) be->bd_info;
1796 1.1 lukem struct ldaprwmap *rwmap =
1797 1.1 lukem (struct ldaprwmap *)on->on_bi.bi_private;
1798 1.1 lukem
1799 1.1 lukem int rc = 0;
1800 1.1 lukem char *argv0 = NULL;
1801 1.1 lukem
1802 1.1 lukem if ( strncasecmp( argv[ 0 ], "rwm-", STRLENOF( "rwm-" ) ) == 0 ) {
1803 1.1 lukem argv0 = argv[ 0 ];
1804 1.1 lukem argv[ 0 ] = &argv0[ STRLENOF( "rwm-" ) ];
1805 1.1 lukem }
1806 1.1 lukem
1807 1.1 lukem if ( strncasecmp( argv[0], "rewrite", STRLENOF("rewrite") ) == 0 ) {
1808 1.1 lukem rc = rwm_rw_config( be, fname, lineno, argc, argv );
1809 1.1 lukem
1810 1.1 lukem } else if ( strcasecmp( argv[0], "map" ) == 0 ) {
1811 1.1 lukem rc = rwm_m_config( be, fname, lineno, argc, argv );
1812 1.1 lukem
1813 1.1 lukem } else if ( strcasecmp( argv[0], "suffixmassage" ) == 0 ) {
1814 1.1 lukem rc = rwm_suffixmassage_config( be, fname, lineno, argc, argv );
1815 1.1 lukem
1816 1.1 lukem } else if ( strcasecmp( argv[0], "t-f-support" ) == 0 ) {
1817 1.1 lukem if ( argc != 2 ) {
1818 1.1.1.3 adam Debug( LDAP_DEBUG_ANY,
1819 1.1 lukem "%s: line %d: \"t-f-support {no|yes|discover}\" needs 1 argument.\n",
1820 1.1.1.3 adam fname, lineno, 0 );
1821 1.1 lukem return( 1 );
1822 1.1 lukem }
1823 1.1 lukem
1824 1.1 lukem if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
1825 1.1 lukem rwmap->rwm_flags &= ~(RWM_F_SUPPORT_T_F_MASK2);
1826 1.1 lukem
1827 1.1 lukem } else if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
1828 1.1 lukem rwmap->rwm_flags |= RWM_F_SUPPORT_T_F;
1829 1.1 lukem
1830 1.1 lukem /* TODO: not implemented yet */
1831 1.1 lukem } else if ( strcasecmp( argv[ 1 ], "discover" ) == 0 ) {
1832 1.1.1.3 adam Debug( LDAP_DEBUG_ANY,
1833 1.1 lukem "%s: line %d: \"discover\" not supported yet "
1834 1.1 lukem "in \"t-f-support {no|yes|discover}\".\n",
1835 1.1.1.3 adam fname, lineno, 0 );
1836 1.1 lukem return( 1 );
1837 1.1 lukem #if 0
1838 1.1 lukem rwmap->rwm_flags |= RWM_F_SUPPORT_T_F_DISCOVER;
1839 1.1 lukem #endif
1840 1.1 lukem
1841 1.1 lukem } else {
1842 1.1.1.3 adam Debug( LDAP_DEBUG_ANY,
1843 1.1 lukem "%s: line %d: unknown value \"%s\" for \"t-f-support {no|yes|discover}\".\n",
1844 1.1 lukem fname, lineno, argv[ 1 ] );
1845 1.1 lukem return 1;
1846 1.1 lukem }
1847 1.1 lukem
1848 1.1 lukem } else if ( strcasecmp( argv[0], "normalize-mapped-attrs" ) == 0 ) {
1849 1.1 lukem if ( argc !=2 ) {
1850 1.1.1.3 adam Debug( LDAP_DEBUG_ANY,
1851 1.1 lukem "%s: line %d: \"normalize-mapped-attrs {no|yes}\" needs 1 argument.\n",
1852 1.1.1.3 adam fname, lineno, 0 );
1853 1.1 lukem return( 1 );
1854 1.1 lukem }
1855 1.1 lukem
1856 1.1 lukem if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
1857 1.1 lukem rwmap->rwm_flags &= ~(RWM_F_NORMALIZE_MAPPED_ATTRS);
1858 1.1 lukem
1859 1.1 lukem } else if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
1860 1.1 lukem rwmap->rwm_flags |= RWM_F_NORMALIZE_MAPPED_ATTRS;
1861 1.1 lukem }
1862 1.1 lukem
1863 1.1 lukem } else {
1864 1.1 lukem rc = SLAP_CONF_UNKNOWN;
1865 1.1 lukem }
1866 1.1 lukem
1867 1.1 lukem if ( argv0 ) {
1868 1.1 lukem argv[ 0 ] = argv0;
1869 1.1 lukem }
1870 1.1 lukem
1871 1.1 lukem return rc;
1872 1.1 lukem }
1873 1.1 lukem
1874 1.1 lukem /*
1875 1.1 lukem * dynamic configuration...
1876 1.1 lukem */
1877 1.1 lukem
1878 1.1 lukem enum {
1879 1.1 lukem /* rewrite */
1880 1.1 lukem RWM_CF_REWRITE = 1,
1881 1.1 lukem
1882 1.1 lukem /* map */
1883 1.1 lukem RWM_CF_MAP,
1884 1.1 lukem RWM_CF_T_F_SUPPORT,
1885 1.1 lukem RWM_CF_NORMALIZE_MAPPED,
1886 1.1.1.2 lukem RWM_CF_DROP_UNREQUESTED,
1887 1.1 lukem
1888 1.1 lukem RWM_CF_LAST
1889 1.1 lukem };
1890 1.1 lukem
1891 1.1 lukem static slap_verbmasks t_f_mode[] = {
1892 1.1.1.2 lukem { BER_BVC( "true" ), RWM_F_SUPPORT_T_F },
1893 1.1 lukem { BER_BVC( "yes" ), RWM_F_SUPPORT_T_F },
1894 1.1 lukem { BER_BVC( "discover" ), RWM_F_SUPPORT_T_F_DISCOVER },
1895 1.1.1.2 lukem { BER_BVC( "false" ), RWM_F_NONE },
1896 1.1 lukem { BER_BVC( "no" ), RWM_F_NONE },
1897 1.1 lukem { BER_BVNULL, 0 }
1898 1.1 lukem };
1899 1.1 lukem
1900 1.1 lukem static ConfigDriver rwm_cf_gen;
1901 1.1 lukem
1902 1.1 lukem static ConfigTable rwmcfg[] = {
1903 1.1 lukem { "rwm-rewrite", "rewrite",
1904 1.1 lukem 2, 0, STRLENOF("rwm-rewrite"),
1905 1.1.1.2 lukem ARG_MAGIC|RWM_CF_REWRITE, rwm_cf_gen,
1906 1.1 lukem "( OLcfgOvAt:16.1 NAME 'olcRwmRewrite' "
1907 1.1 lukem "DESC 'Rewrites strings' "
1908 1.1 lukem "EQUALITY caseIgnoreMatch "
1909 1.1 lukem "SYNTAX OMsDirectoryString "
1910 1.1 lukem "X-ORDERED 'VALUES' )",
1911 1.1 lukem NULL, NULL },
1912 1.1 lukem
1913 1.1 lukem { "rwm-suffixmassage", "[virtual]> <real",
1914 1.1.1.2 lukem 2, 3, 0, ARG_MAGIC|RWM_CF_REWRITE, rwm_cf_gen,
1915 1.1 lukem NULL, NULL, NULL },
1916 1.1 lukem
1917 1.1 lukem { "rwm-t-f-support", "true|false|discover",
1918 1.1 lukem 2, 2, 0, ARG_MAGIC|RWM_CF_T_F_SUPPORT, rwm_cf_gen,
1919 1.1 lukem "( OLcfgOvAt:16.2 NAME 'olcRwmTFSupport' "
1920 1.1 lukem "DESC 'Absolute filters support' "
1921 1.1 lukem "SYNTAX OMsDirectoryString "
1922 1.1 lukem "SINGLE-VALUE )",
1923 1.1 lukem NULL, NULL },
1924 1.1 lukem
1925 1.1 lukem { "rwm-map", "{objectClass|attribute}",
1926 1.1 lukem 2, 4, 0, ARG_MAGIC|RWM_CF_MAP, rwm_cf_gen,
1927 1.1 lukem "( OLcfgOvAt:16.3 NAME 'olcRwmMap' "
1928 1.1 lukem "DESC 'maps attributes/objectClasses' "
1929 1.1.1.3 adam "EQUALITY caseIgnoreMatch "
1930 1.1 lukem "SYNTAX OMsDirectoryString "
1931 1.1 lukem "X-ORDERED 'VALUES' )",
1932 1.1 lukem NULL, NULL },
1933 1.1 lukem
1934 1.1 lukem { "rwm-normalize-mapped-attrs", "true|false",
1935 1.1 lukem 2, 2, 0, ARG_MAGIC|ARG_ON_OFF|RWM_CF_NORMALIZE_MAPPED, rwm_cf_gen,
1936 1.1 lukem "( OLcfgOvAt:16.4 NAME 'olcRwmNormalizeMapped' "
1937 1.1 lukem "DESC 'Normalize mapped attributes/objectClasses' "
1938 1.1 lukem "SYNTAX OMsBoolean "
1939 1.1 lukem "SINGLE-VALUE )",
1940 1.1 lukem NULL, NULL },
1941 1.1 lukem
1942 1.1.1.2 lukem { "rwm-drop-unrequested-attrs", "true|false",
1943 1.1.1.2 lukem 2, 2, 0, ARG_MAGIC|ARG_ON_OFF|RWM_CF_DROP_UNREQUESTED, rwm_cf_gen,
1944 1.1.1.2 lukem "( OLcfgOvAt:16.5 NAME 'olcRwmDropUnrequested' "
1945 1.1.1.2 lukem "DESC 'Drop unrequested attributes' "
1946 1.1.1.2 lukem "SYNTAX OMsBoolean "
1947 1.1.1.2 lukem "SINGLE-VALUE )",
1948 1.1.1.2 lukem NULL, NULL },
1949 1.1.1.2 lukem
1950 1.1 lukem { NULL, NULL, 0, 0, 0, ARG_IGNORED }
1951 1.1 lukem };
1952 1.1 lukem
1953 1.1 lukem static ConfigOCs rwmocs[] = {
1954 1.1 lukem { "( OLcfgOvOc:16.1 "
1955 1.1 lukem "NAME 'olcRwmConfig' "
1956 1.1 lukem "DESC 'Rewrite/remap configuration' "
1957 1.1 lukem "SUP olcOverlayConfig "
1958 1.1 lukem "MAY ( "
1959 1.1 lukem "olcRwmRewrite $ "
1960 1.1 lukem "olcRwmTFSupport $ "
1961 1.1 lukem "olcRwmMap $ "
1962 1.1.1.5 christos "olcRwmNormalizeMapped $ "
1963 1.1.1.5 christos "olcRwmDropUnrequested"
1964 1.1 lukem ") )",
1965 1.1 lukem Cft_Overlay, rwmcfg, NULL, NULL },
1966 1.1 lukem { NULL, 0, NULL }
1967 1.1 lukem };
1968 1.1 lukem
1969 1.1 lukem static void
1970 1.1.1.3 adam slap_bv_x_ordered_unparse( BerVarray in, BerVarray *out )
1971 1.1 lukem {
1972 1.1 lukem int i;
1973 1.1 lukem BerVarray bva = NULL;
1974 1.1 lukem char ibuf[32], *ptr;
1975 1.1 lukem struct berval idx;
1976 1.1 lukem
1977 1.1 lukem assert( in != NULL );
1978 1.1 lukem
1979 1.1 lukem for ( i = 0; !BER_BVISNULL( &in[i] ); i++ )
1980 1.1 lukem /* count'em */ ;
1981 1.1 lukem
1982 1.1 lukem if ( i == 0 ) {
1983 1.1 lukem return;
1984 1.1 lukem }
1985 1.1 lukem
1986 1.1 lukem idx.bv_val = ibuf;
1987 1.1 lukem
1988 1.1 lukem bva = ch_malloc( ( i + 1 ) * sizeof(struct berval) );
1989 1.1 lukem BER_BVZERO( &bva[ 0 ] );
1990 1.1 lukem
1991 1.1 lukem for ( i = 0; !BER_BVISNULL( &in[i] ); i++ ) {
1992 1.1 lukem idx.bv_len = snprintf( idx.bv_val, sizeof( ibuf ), "{%d}", i );
1993 1.1 lukem if ( idx.bv_len >= sizeof( ibuf ) ) {
1994 1.1 lukem ber_bvarray_free( bva );
1995 1.1 lukem return;
1996 1.1 lukem }
1997 1.1 lukem
1998 1.1 lukem bva[i].bv_len = idx.bv_len + in[i].bv_len;
1999 1.1 lukem bva[i].bv_val = ch_malloc( bva[i].bv_len + 1 );
2000 1.1 lukem ptr = lutil_strcopy( bva[i].bv_val, ibuf );
2001 1.1 lukem ptr = lutil_strcopy( ptr, in[i].bv_val );
2002 1.1 lukem *ptr = '\0';
2003 1.1 lukem BER_BVZERO( &bva[ i + 1 ] );
2004 1.1 lukem }
2005 1.1 lukem
2006 1.1 lukem *out = bva;
2007 1.1 lukem }
2008 1.1 lukem
2009 1.1 lukem static int
2010 1.1.1.3 adam rwm_bva_add(
2011 1.1.1.3 adam BerVarray *bva,
2012 1.1.1.2 lukem int idx,
2013 1.1.1.2 lukem char **argv )
2014 1.1.1.2 lukem {
2015 1.1.1.2 lukem char *line;
2016 1.1.1.2 lukem struct berval bv;
2017 1.1.1.2 lukem
2018 1.1.1.2 lukem line = ldap_charray2str( argv, "\" \"" );
2019 1.1.1.2 lukem if ( line != NULL ) {
2020 1.1.1.2 lukem int len = strlen( argv[ 0 ] );
2021 1.1.1.2 lukem
2022 1.1.1.2 lukem ber_str2bv( line, 0, 0, &bv );
2023 1.1.1.2 lukem AC_MEMCPY( &bv.bv_val[ len ], &bv.bv_val[ len + 1 ],
2024 1.1.1.2 lukem bv.bv_len - ( len + 1 ) );
2025 1.1.1.2 lukem bv.bv_val[ bv.bv_len - 1 ] = '"';
2026 1.1.1.2 lukem
2027 1.1.1.2 lukem if ( idx == -1 ) {
2028 1.1.1.3 adam ber_bvarray_add( bva, &bv );
2029 1.1.1.2 lukem
2030 1.1.1.2 lukem } else {
2031 1.1.1.3 adam (*bva)[ idx ] = bv;
2032 1.1.1.2 lukem }
2033 1.1.1.3 adam
2034 1.1.1.3 adam return 0;
2035 1.1.1.2 lukem }
2036 1.1.1.2 lukem
2037 1.1.1.3 adam return -1;
2038 1.1.1.3 adam }
2039 1.1.1.3 adam
2040 1.1.1.3 adam static int
2041 1.1.1.3 adam rwm_bva_rewrite_add(
2042 1.1.1.3 adam struct ldaprwmap *rwmap,
2043 1.1.1.3 adam int idx,
2044 1.1.1.3 adam char **argv )
2045 1.1.1.3 adam {
2046 1.1.1.3 adam return rwm_bva_add( &rwmap->rwm_bva_rewrite, idx, argv );
2047 1.1.1.3 adam }
2048 1.1.1.3 adam
2049 1.1.1.4 tron #ifdef unused
2050 1.1.1.3 adam static int
2051 1.1.1.3 adam rwm_bva_map_add(
2052 1.1.1.3 adam struct ldaprwmap *rwmap,
2053 1.1.1.3 adam int idx,
2054 1.1.1.3 adam char **argv )
2055 1.1.1.3 adam {
2056 1.1.1.3 adam return rwm_bva_add( &rwmap->rwm_bva_map, idx, argv );
2057 1.1.1.2 lukem }
2058 1.1.1.4 tron #endif /* unused */
2059 1.1.1.2 lukem
2060 1.1.1.2 lukem static int
2061 1.1.1.2 lukem rwm_info_init( struct rewrite_info ** rwm_rw )
2062 1.1.1.2 lukem {
2063 1.1.1.2 lukem char *rargv[ 3 ];
2064 1.1.1.2 lukem
2065 1.1.1.2 lukem *rwm_rw = rewrite_info_init( REWRITE_MODE_USE_DEFAULT );
2066 1.1.1.2 lukem if ( *rwm_rw == NULL ) {
2067 1.1.1.2 lukem return -1;
2068 1.1.1.2 lukem }
2069 1.1.1.2 lukem
2070 1.1.1.2 lukem /* this rewriteContext by default must be null;
2071 1.1.1.2 lukem * rules can be added if required */
2072 1.1.1.2 lukem rargv[ 0 ] = "rewriteContext";
2073 1.1.1.2 lukem rargv[ 1 ] = "searchFilter";
2074 1.1.1.2 lukem rargv[ 2 ] = NULL;
2075 1.1.1.2 lukem rewrite_parse( *rwm_rw, "<suffix massage>", 1, 2, rargv );
2076 1.1.1.2 lukem
2077 1.1.1.2 lukem rargv[ 0 ] = "rewriteContext";
2078 1.1.1.2 lukem rargv[ 1 ] = "default";
2079 1.1.1.2 lukem rargv[ 2 ] = NULL;
2080 1.1.1.2 lukem rewrite_parse( *rwm_rw, "<suffix massage>", 2, 2, rargv );
2081 1.1.1.2 lukem
2082 1.1.1.2 lukem return 0;
2083 1.1.1.2 lukem }
2084 1.1.1.2 lukem
2085 1.1.1.2 lukem static int
2086 1.1 lukem rwm_cf_gen( ConfigArgs *c )
2087 1.1 lukem {
2088 1.1 lukem slap_overinst *on = (slap_overinst *)c->bi;
2089 1.1 lukem struct ldaprwmap *rwmap =
2090 1.1 lukem (struct ldaprwmap *)on->on_bi.bi_private;
2091 1.1 lukem
2092 1.1 lukem BackendDB db;
2093 1.1 lukem char *argv0;
2094 1.1.1.2 lukem int idx0 = 0;
2095 1.1 lukem int rc = 0;
2096 1.1 lukem
2097 1.1 lukem db = *c->be;
2098 1.1 lukem db.bd_info = c->bi;
2099 1.1 lukem
2100 1.1 lukem if ( c->op == SLAP_CONFIG_EMIT ) {
2101 1.1 lukem struct berval bv = BER_BVNULL;
2102 1.1 lukem
2103 1.1 lukem switch ( c->type ) {
2104 1.1 lukem case RWM_CF_REWRITE:
2105 1.1 lukem if ( rwmap->rwm_bva_rewrite == NULL ) {
2106 1.1 lukem rc = 1;
2107 1.1 lukem
2108 1.1 lukem } else {
2109 1.1.1.3 adam slap_bv_x_ordered_unparse( rwmap->rwm_bva_rewrite, &c->rvalue_vals );
2110 1.1 lukem if ( !c->rvalue_vals ) {
2111 1.1 lukem rc = 1;
2112 1.1 lukem }
2113 1.1 lukem }
2114 1.1 lukem break;
2115 1.1 lukem
2116 1.1 lukem case RWM_CF_T_F_SUPPORT:
2117 1.1 lukem enum_to_verb( t_f_mode, (rwmap->rwm_flags & RWM_F_SUPPORT_T_F_MASK2), &bv );
2118 1.1 lukem if ( BER_BVISNULL( &bv ) ) {
2119 1.1 lukem /* there's something wrong... */
2120 1.1 lukem assert( 0 );
2121 1.1 lukem rc = 1;
2122 1.1 lukem
2123 1.1 lukem } else {
2124 1.1 lukem value_add_one( &c->rvalue_vals, &bv );
2125 1.1 lukem }
2126 1.1 lukem break;
2127 1.1 lukem
2128 1.1 lukem case RWM_CF_MAP:
2129 1.1 lukem if ( rwmap->rwm_bva_map == NULL ) {
2130 1.1 lukem rc = 1;
2131 1.1 lukem
2132 1.1 lukem } else {
2133 1.1.1.3 adam slap_bv_x_ordered_unparse( rwmap->rwm_bva_map, &c->rvalue_vals );
2134 1.1.1.3 adam if ( !c->rvalue_vals ) {
2135 1.1.1.3 adam rc = 1;
2136 1.1.1.3 adam }
2137 1.1 lukem }
2138 1.1 lukem break;
2139 1.1 lukem
2140 1.1 lukem case RWM_CF_NORMALIZE_MAPPED:
2141 1.1 lukem c->value_int = ( rwmap->rwm_flags & RWM_F_NORMALIZE_MAPPED_ATTRS );
2142 1.1 lukem break;
2143 1.1 lukem
2144 1.1.1.2 lukem case RWM_CF_DROP_UNREQUESTED:
2145 1.1.1.2 lukem c->value_int = ( rwmap->rwm_flags & RWM_F_DROP_UNREQUESTED_ATTRS );
2146 1.1.1.2 lukem break;
2147 1.1.1.2 lukem
2148 1.1 lukem default:
2149 1.1 lukem assert( 0 );
2150 1.1 lukem rc = 1;
2151 1.1 lukem }
2152 1.1 lukem
2153 1.1 lukem return rc;
2154 1.1 lukem
2155 1.1 lukem } else if ( c->op == LDAP_MOD_DELETE ) {
2156 1.1 lukem switch ( c->type ) {
2157 1.1 lukem case RWM_CF_REWRITE:
2158 1.1 lukem if ( c->valx >= 0 ) {
2159 1.1.1.2 lukem int i;
2160 1.1.1.2 lukem
2161 1.1.1.2 lukem for ( i = 0; !BER_BVISNULL( &rwmap->rwm_bva_rewrite[ i ] ); i++ )
2162 1.1.1.2 lukem /* count'em */ ;
2163 1.1.1.2 lukem
2164 1.1.1.3 adam if ( c->valx >= i ) {
2165 1.1.1.2 lukem rc = 1;
2166 1.1.1.2 lukem break;
2167 1.1.1.2 lukem }
2168 1.1.1.2 lukem
2169 1.1.1.2 lukem ber_memfree( rwmap->rwm_bva_rewrite[ c->valx ].bv_val );
2170 1.1.1.2 lukem for ( i = c->valx; !BER_BVISNULL( &rwmap->rwm_bva_rewrite[ i + 1 ] ); i++ )
2171 1.1.1.2 lukem {
2172 1.1.1.2 lukem rwmap->rwm_bva_rewrite[ i ] = rwmap->rwm_bva_rewrite[ i + 1 ];
2173 1.1.1.2 lukem }
2174 1.1.1.2 lukem BER_BVZERO( &rwmap->rwm_bva_rewrite[ i ] );
2175 1.1.1.2 lukem
2176 1.1.1.2 lukem rewrite_info_delete( &rwmap->rwm_rw );
2177 1.1.1.2 lukem assert( rwmap->rwm_rw == NULL );
2178 1.1.1.2 lukem
2179 1.1.1.2 lukem rc = rwm_info_init( &rwmap->rwm_rw );
2180 1.1.1.2 lukem
2181 1.1.1.2 lukem for ( i = 0; !BER_BVISNULL( &rwmap->rwm_bva_rewrite[ i ] ); i++ )
2182 1.1.1.2 lukem {
2183 1.1.1.3 adam ConfigArgs ca = { 0 };
2184 1.1.1.3 adam
2185 1.1.1.2 lukem ca.line = rwmap->rwm_bva_rewrite[ i ].bv_val;
2186 1.1.1.2 lukem ca.argc = 0;
2187 1.1.1.5 christos init_config_argv( &ca );
2188 1.1.1.5 christos config_parse_ldif( &ca );
2189 1.1.1.5 christos
2190 1.1.1.5 christos argv0 = ca.argv[ 0 ];
2191 1.1.1.5 christos ca.argv[ 0 ] += STRLENOF( "rwm-" );
2192 1.1.1.5 christos
2193 1.1.1.2 lukem if ( strcasecmp( ca.argv[ 0 ], "suffixmassage" ) == 0 ) {
2194 1.1.1.2 lukem rc = rwm_suffixmassage_config( &db, c->fname, c->lineno,
2195 1.1.1.2 lukem ca.argc, ca.argv );
2196 1.1.1.2 lukem
2197 1.1.1.2 lukem } else {
2198 1.1.1.2 lukem rc = rwm_rw_config( &db, c->fname, c->lineno,
2199 1.1.1.2 lukem ca.argc, ca.argv );
2200 1.1.1.2 lukem }
2201 1.1.1.2 lukem
2202 1.1.1.5 christos ca.argv[ 0 ] = argv0;
2203 1.1.1.5 christos
2204 1.1.1.2 lukem ch_free( ca.tline );
2205 1.1.1.3 adam ch_free( ca.argv );
2206 1.1.1.2 lukem
2207 1.1.1.2 lukem assert( rc == 0 );
2208 1.1.1.2 lukem }
2209 1.1 lukem
2210 1.1 lukem } else if ( rwmap->rwm_rw != NULL ) {
2211 1.1 lukem rewrite_info_delete( &rwmap->rwm_rw );
2212 1.1 lukem assert( rwmap->rwm_rw == NULL );
2213 1.1 lukem
2214 1.1 lukem ber_bvarray_free( rwmap->rwm_bva_rewrite );
2215 1.1 lukem rwmap->rwm_bva_rewrite = NULL;
2216 1.1.1.2 lukem
2217 1.1.1.2 lukem rc = rwm_info_init( &rwmap->rwm_rw );
2218 1.1 lukem }
2219 1.1 lukem break;
2220 1.1 lukem
2221 1.1 lukem case RWM_CF_T_F_SUPPORT:
2222 1.1 lukem rwmap->rwm_flags &= ~RWM_F_SUPPORT_T_F_MASK2;
2223 1.1 lukem break;
2224 1.1 lukem
2225 1.1 lukem case RWM_CF_MAP:
2226 1.1 lukem if ( c->valx >= 0 ) {
2227 1.1.1.3 adam struct ldapmap rwm_oc = rwmap->rwm_oc;
2228 1.1.1.3 adam struct ldapmap rwm_at = rwmap->rwm_at;
2229 1.1.1.3 adam char *argv[5];
2230 1.1.1.3 adam int cnt = 0;
2231 1.1.1.3 adam
2232 1.1.1.3 adam if ( rwmap->rwm_bva_map ) {
2233 1.1.1.3 adam for ( ; !BER_BVISNULL( &rwmap->rwm_bva_map[ cnt ] ); cnt++ )
2234 1.1.1.3 adam /* count */ ;
2235 1.1.1.3 adam }
2236 1.1.1.3 adam
2237 1.1.1.3 adam if ( c->valx >= cnt ) {
2238 1.1.1.3 adam rc = 1;
2239 1.1.1.3 adam break;
2240 1.1.1.3 adam }
2241 1.1.1.3 adam
2242 1.1.1.3 adam memset( &rwmap->rwm_oc, 0, sizeof( rwmap->rwm_oc ) );
2243 1.1.1.3 adam memset( &rwmap->rwm_at, 0, sizeof( rwmap->rwm_at ) );
2244 1.1.1.3 adam
2245 1.1.1.3 adam /* re-parse all mappings except the one
2246 1.1.1.3 adam * that needs to be eliminated */
2247 1.1.1.3 adam argv[0] = "map";
2248 1.1.1.3 adam for ( cnt = 0; !BER_BVISNULL( &rwmap->rwm_bva_map[ cnt ] ); cnt++ ) {
2249 1.1.1.3 adam ConfigArgs ca = { 0 };
2250 1.1.1.3 adam
2251 1.1.1.3 adam if ( cnt == c->valx ) {
2252 1.1.1.3 adam continue;
2253 1.1.1.3 adam }
2254 1.1.1.3 adam
2255 1.1.1.3 adam ca.line = rwmap->rwm_bva_map[ cnt ].bv_val;
2256 1.1.1.3 adam ca.argc = 0;
2257 1.1.1.5 christos init_config_argv( &ca );
2258 1.1.1.5 christos config_parse_ldif( &ca );
2259 1.1.1.3 adam
2260 1.1.1.3 adam argv[1] = ca.argv[0];
2261 1.1.1.3 adam argv[2] = ca.argv[1];
2262 1.1.1.3 adam argv[3] = ca.argv[2];
2263 1.1.1.3 adam argv[4] = ca.argv[3];
2264 1.1.1.3 adam
2265 1.1.1.3 adam rc = rwm_m_config( &db, c->fname, c->lineno, ca.argc + 1, argv );
2266 1.1.1.3 adam
2267 1.1.1.3 adam ch_free( ca.tline );
2268 1.1.1.3 adam ch_free( ca.argv );
2269 1.1.1.3 adam
2270 1.1.1.3 adam /* in case of failure, restore
2271 1.1.1.3 adam * the existing mapping */
2272 1.1.1.3 adam if ( rc ) {
2273 1.1.1.3 adam avl_free( rwmap->rwm_oc.remap, rwm_mapping_dst_free );
2274 1.1.1.3 adam avl_free( rwmap->rwm_oc.map, rwm_mapping_free );
2275 1.1.1.3 adam avl_free( rwmap->rwm_at.remap, rwm_mapping_dst_free );
2276 1.1.1.3 adam avl_free( rwmap->rwm_at.map, rwm_mapping_free );
2277 1.1.1.3 adam rwmap->rwm_oc = rwm_oc;
2278 1.1.1.3 adam rwmap->rwm_at = rwm_at;
2279 1.1.1.3 adam break;
2280 1.1.1.3 adam }
2281 1.1.1.3 adam }
2282 1.1.1.3 adam
2283 1.1.1.3 adam /* in case of success, destroy the old mapping
2284 1.1.1.3 adam * and eliminate the deleted one */
2285 1.1.1.3 adam if ( rc == 0 ) {
2286 1.1.1.3 adam avl_free( rwm_oc.remap, rwm_mapping_dst_free );
2287 1.1.1.3 adam avl_free( rwm_oc.map, rwm_mapping_free );
2288 1.1.1.3 adam avl_free( rwm_at.remap, rwm_mapping_dst_free );
2289 1.1.1.3 adam avl_free( rwm_at.map, rwm_mapping_free );
2290 1.1.1.3 adam
2291 1.1.1.3 adam ber_memfree( rwmap->rwm_bva_map[ c->valx ].bv_val );
2292 1.1.1.3 adam for ( cnt = c->valx; !BER_BVISNULL( &rwmap->rwm_bva_map[ cnt ] ); cnt++ ) {
2293 1.1.1.3 adam rwmap->rwm_bva_map[ cnt ] = rwmap->rwm_bva_map[ cnt + 1 ];
2294 1.1.1.3 adam }
2295 1.1.1.3 adam }
2296 1.1 lukem
2297 1.1 lukem } else {
2298 1.1 lukem avl_free( rwmap->rwm_oc.remap, rwm_mapping_dst_free );
2299 1.1 lukem avl_free( rwmap->rwm_oc.map, rwm_mapping_free );
2300 1.1 lukem avl_free( rwmap->rwm_at.remap, rwm_mapping_dst_free );
2301 1.1 lukem avl_free( rwmap->rwm_at.map, rwm_mapping_free );
2302 1.1 lukem
2303 1.1 lukem rwmap->rwm_oc.remap = NULL;
2304 1.1 lukem rwmap->rwm_oc.map = NULL;
2305 1.1 lukem rwmap->rwm_at.remap = NULL;
2306 1.1 lukem rwmap->rwm_at.map = NULL;
2307 1.1 lukem
2308 1.1 lukem ber_bvarray_free( rwmap->rwm_bva_map );
2309 1.1 lukem rwmap->rwm_bva_map = NULL;
2310 1.1 lukem }
2311 1.1 lukem break;
2312 1.1 lukem
2313 1.1 lukem case RWM_CF_NORMALIZE_MAPPED:
2314 1.1 lukem rwmap->rwm_flags &= ~RWM_F_NORMALIZE_MAPPED_ATTRS;
2315 1.1 lukem break;
2316 1.1 lukem
2317 1.1.1.2 lukem case RWM_CF_DROP_UNREQUESTED:
2318 1.1.1.2 lukem rwmap->rwm_flags &= ~RWM_F_DROP_UNREQUESTED_ATTRS;
2319 1.1.1.2 lukem break;
2320 1.1.1.2 lukem
2321 1.1 lukem default:
2322 1.1 lukem return 1;
2323 1.1 lukem }
2324 1.1 lukem return rc;
2325 1.1 lukem }
2326 1.1 lukem
2327 1.1.1.2 lukem if ( strncasecmp( c->argv[ 0 ], "olcRwm", STRLENOF( "olcRwm" ) ) == 0 ) {
2328 1.1.1.2 lukem idx0 = 1;
2329 1.1.1.2 lukem }
2330 1.1.1.2 lukem
2331 1.1 lukem switch ( c->type ) {
2332 1.1 lukem case RWM_CF_REWRITE:
2333 1.1.1.2 lukem if ( c->valx >= 0 ) {
2334 1.1.1.2 lukem struct rewrite_info *rwm_rw = rwmap->rwm_rw;
2335 1.1.1.2 lukem int i, last;
2336 1.1.1.2 lukem
2337 1.1.1.2 lukem for ( last = 0; rwmap->rwm_bva_rewrite && !BER_BVISNULL( &rwmap->rwm_bva_rewrite[ last ] ); last++ )
2338 1.1.1.2 lukem /* count'em */ ;
2339 1.1.1.2 lukem
2340 1.1.1.2 lukem if ( c->valx > last ) {
2341 1.1.1.2 lukem c->valx = last;
2342 1.1.1.2 lukem }
2343 1.1.1.2 lukem
2344 1.1.1.2 lukem rwmap->rwm_rw = NULL;
2345 1.1.1.2 lukem rc = rwm_info_init( &rwmap->rwm_rw );
2346 1.1.1.2 lukem
2347 1.1.1.2 lukem for ( i = 0; i < c->valx; i++ ) {
2348 1.1.1.3 adam ConfigArgs ca = { 0 };
2349 1.1.1.3 adam
2350 1.1.1.2 lukem ca.line = rwmap->rwm_bva_rewrite[ i ].bv_val;
2351 1.1.1.2 lukem ca.argc = 0;
2352 1.1.1.5 christos init_config_argv( &ca );
2353 1.1.1.5 christos config_parse_ldif( &ca );
2354 1.1.1.2 lukem
2355 1.1.1.2 lukem argv0 = ca.argv[ 0 ];
2356 1.1.1.2 lukem ca.argv[ 0 ] += STRLENOF( "rwm-" );
2357 1.1.1.2 lukem
2358 1.1.1.2 lukem if ( strcasecmp( ca.argv[ 0 ], "suffixmassage" ) == 0 ) {
2359 1.1.1.2 lukem rc = rwm_suffixmassage_config( &db, c->fname, c->lineno,
2360 1.1.1.2 lukem ca.argc, ca.argv );
2361 1.1 lukem
2362 1.1.1.2 lukem } else {
2363 1.1.1.2 lukem rc = rwm_rw_config( &db, c->fname, c->lineno,
2364 1.1.1.2 lukem ca.argc, ca.argv );
2365 1.1.1.2 lukem }
2366 1.1 lukem
2367 1.1.1.2 lukem ca.argv[ 0 ] = argv0;
2368 1.1 lukem
2369 1.1.1.2 lukem ch_free( ca.tline );
2370 1.1.1.3 adam ch_free( ca.argv );
2371 1.1.1.2 lukem
2372 1.1.1.2 lukem assert( rc == 0 );
2373 1.1 lukem }
2374 1.1 lukem
2375 1.1.1.2 lukem argv0 = c->argv[ idx0 ];
2376 1.1.1.2 lukem if ( strncasecmp( argv0, "rwm-", STRLENOF( "rwm-" ) ) != 0 ) {
2377 1.1.1.2 lukem return 1;
2378 1.1.1.2 lukem }
2379 1.1.1.2 lukem c->argv[ idx0 ] += STRLENOF( "rwm-" );
2380 1.1.1.2 lukem if ( strcasecmp( c->argv[ idx0 ], "suffixmassage" ) == 0 ) {
2381 1.1.1.2 lukem rc = rwm_suffixmassage_config( &db, c->fname, c->lineno,
2382 1.1.1.2 lukem c->argc - idx0, &c->argv[ idx0 ] );
2383 1.1 lukem
2384 1.1.1.2 lukem } else {
2385 1.1.1.2 lukem rc = rwm_rw_config( &db, c->fname, c->lineno,
2386 1.1.1.2 lukem c->argc - idx0, &c->argv[ idx0 ] );
2387 1.1.1.2 lukem }
2388 1.1.1.2 lukem c->argv[ idx0 ] = argv0;
2389 1.1.1.2 lukem if ( rc != 0 ) {
2390 1.1.1.2 lukem rewrite_info_delete( &rwmap->rwm_rw );
2391 1.1.1.2 lukem assert( rwmap->rwm_rw == NULL );
2392 1.1 lukem
2393 1.1.1.2 lukem rwmap->rwm_rw = rwm_rw;
2394 1.1.1.2 lukem return 1;
2395 1.1.1.2 lukem }
2396 1.1 lukem
2397 1.1.1.2 lukem for ( i = c->valx; rwmap->rwm_bva_rewrite && !BER_BVISNULL( &rwmap->rwm_bva_rewrite[ i ] ); i++ )
2398 1.1.1.2 lukem {
2399 1.1.1.3 adam ConfigArgs ca = { 0 };
2400 1.1.1.3 adam
2401 1.1.1.2 lukem ca.line = rwmap->rwm_bva_rewrite[ i ].bv_val;
2402 1.1.1.2 lukem ca.argc = 0;
2403 1.1.1.5 christos init_config_argv( &ca );
2404 1.1.1.5 christos config_parse_ldif( &ca );
2405 1.1.1.2 lukem
2406 1.1.1.2 lukem argv0 = ca.argv[ 0 ];
2407 1.1.1.2 lukem ca.argv[ 0 ] += STRLENOF( "rwm-" );
2408 1.1.1.2 lukem
2409 1.1.1.2 lukem if ( strcasecmp( ca.argv[ 0 ], "suffixmassage" ) == 0 ) {
2410 1.1.1.2 lukem rc = rwm_suffixmassage_config( &db, c->fname, c->lineno,
2411 1.1.1.2 lukem ca.argc, ca.argv );
2412 1.1 lukem
2413 1.1.1.2 lukem } else {
2414 1.1.1.2 lukem rc = rwm_rw_config( &db, c->fname, c->lineno,
2415 1.1.1.2 lukem ca.argc, ca.argv );
2416 1.1.1.2 lukem }
2417 1.1.1.2 lukem
2418 1.1.1.2 lukem ca.argv[ 0 ] = argv0;
2419 1.1.1.2 lukem
2420 1.1.1.2 lukem ch_free( ca.tline );
2421 1.1.1.3 adam ch_free( ca.argv );
2422 1.1.1.2 lukem
2423 1.1.1.2 lukem assert( rc == 0 );
2424 1.1 lukem }
2425 1.1.1.2 lukem
2426 1.1.1.2 lukem rwmap->rwm_bva_rewrite = ch_realloc( rwmap->rwm_bva_rewrite,
2427 1.1.1.2 lukem ( last + 2 )*sizeof( struct berval ) );
2428 1.1.1.2 lukem BER_BVZERO( &rwmap->rwm_bva_rewrite[last+1] );
2429 1.1.1.2 lukem
2430 1.1.1.2 lukem for ( i = last - 1; i >= c->valx; i-- )
2431 1.1.1.2 lukem {
2432 1.1.1.2 lukem rwmap->rwm_bva_rewrite[ i + 1 ] = rwmap->rwm_bva_rewrite[ i ];
2433 1.1.1.2 lukem }
2434 1.1.1.2 lukem
2435 1.1.1.2 lukem rwm_bva_rewrite_add( rwmap, c->valx, &c->argv[ idx0 ] );
2436 1.1.1.2 lukem
2437 1.1.1.2 lukem rewrite_info_delete( &rwm_rw );
2438 1.1.1.2 lukem assert( rwm_rw == NULL );
2439 1.1.1.2 lukem
2440 1.1.1.2 lukem break;
2441 1.1.1.2 lukem }
2442 1.1.1.2 lukem
2443 1.1.1.2 lukem argv0 = c->argv[ idx0 ];
2444 1.1.1.2 lukem if ( strncasecmp( argv0, "rwm-", STRLENOF( "rwm-" ) ) != 0 ) {
2445 1.1.1.2 lukem return 1;
2446 1.1.1.2 lukem }
2447 1.1.1.2 lukem c->argv[ idx0 ] += STRLENOF( "rwm-" );
2448 1.1.1.2 lukem if ( strcasecmp( c->argv[ idx0 ], "suffixmassage" ) == 0 ) {
2449 1.1.1.2 lukem rc = rwm_suffixmassage_config( &db, c->fname, c->lineno,
2450 1.1.1.2 lukem c->argc - idx0, &c->argv[ idx0 ] );
2451 1.1.1.2 lukem
2452 1.1.1.2 lukem } else {
2453 1.1.1.2 lukem rc = rwm_rw_config( &db, c->fname, c->lineno,
2454 1.1.1.2 lukem c->argc - idx0, &c->argv[ idx0 ] );
2455 1.1.1.2 lukem }
2456 1.1.1.2 lukem c->argv[ idx0 ] = argv0;
2457 1.1.1.2 lukem if ( rc ) {
2458 1.1.1.2 lukem return 1;
2459 1.1.1.2 lukem
2460 1.1.1.2 lukem } else {
2461 1.1.1.2 lukem rwm_bva_rewrite_add( rwmap, -1, &c->argv[ idx0 ] );
2462 1.1 lukem }
2463 1.1 lukem break;
2464 1.1 lukem
2465 1.1 lukem case RWM_CF_T_F_SUPPORT:
2466 1.1 lukem rc = verb_to_mask( c->argv[ 1 ], t_f_mode );
2467 1.1 lukem if ( BER_BVISNULL( &t_f_mode[ rc ].word ) ) {
2468 1.1 lukem return 1;
2469 1.1 lukem }
2470 1.1 lukem
2471 1.1 lukem rwmap->rwm_flags &= ~RWM_F_SUPPORT_T_F_MASK2;
2472 1.1 lukem rwmap->rwm_flags |= t_f_mode[ rc ].mask;
2473 1.1 lukem rc = 0;
2474 1.1 lukem break;
2475 1.1 lukem
2476 1.1 lukem case RWM_CF_MAP:
2477 1.1.1.2 lukem if ( c->valx >= 0 ) {
2478 1.1.1.3 adam struct ldapmap rwm_oc = rwmap->rwm_oc;
2479 1.1.1.3 adam struct ldapmap rwm_at = rwmap->rwm_at;
2480 1.1.1.3 adam char *argv[5];
2481 1.1.1.3 adam int cnt = 0;
2482 1.1.1.3 adam
2483 1.1.1.3 adam if ( rwmap->rwm_bva_map ) {
2484 1.1.1.3 adam for ( ; !BER_BVISNULL( &rwmap->rwm_bva_map[ cnt ] ); cnt++ )
2485 1.1.1.3 adam /* count */ ;
2486 1.1.1.3 adam }
2487 1.1.1.3 adam
2488 1.1.1.3 adam if ( c->valx >= cnt ) {
2489 1.1.1.3 adam c->valx = cnt;
2490 1.1.1.3 adam }
2491 1.1.1.3 adam
2492 1.1.1.3 adam memset( &rwmap->rwm_oc, 0, sizeof( rwmap->rwm_oc ) );
2493 1.1.1.3 adam memset( &rwmap->rwm_at, 0, sizeof( rwmap->rwm_at ) );
2494 1.1.1.3 adam
2495 1.1.1.3 adam /* re-parse all mappings, including the one
2496 1.1.1.3 adam * that needs to be added */
2497 1.1.1.3 adam argv[0] = "map";
2498 1.1.1.3 adam for ( cnt = 0; cnt < c->valx; cnt++ ) {
2499 1.1.1.3 adam ConfigArgs ca = { 0 };
2500 1.1.1.3 adam
2501 1.1.1.3 adam ca.line = rwmap->rwm_bva_map[ cnt ].bv_val;
2502 1.1.1.3 adam ca.argc = 0;
2503 1.1.1.5 christos init_config_argv( &ca );
2504 1.1.1.5 christos config_parse_ldif( &ca );
2505 1.1.1.3 adam
2506 1.1.1.3 adam argv[1] = ca.argv[0];
2507 1.1.1.3 adam argv[2] = ca.argv[1];
2508 1.1.1.3 adam argv[3] = ca.argv[2];
2509 1.1.1.3 adam argv[4] = ca.argv[3];
2510 1.1.1.3 adam
2511 1.1.1.3 adam rc = rwm_m_config( &db, c->fname, c->lineno, ca.argc + 1, argv );
2512 1.1.1.3 adam
2513 1.1.1.3 adam ch_free( ca.tline );
2514 1.1.1.3 adam ch_free( ca.argv );
2515 1.1.1.3 adam
2516 1.1.1.3 adam /* in case of failure, restore
2517 1.1.1.3 adam * the existing mapping */
2518 1.1.1.3 adam if ( rc ) {
2519 1.1.1.3 adam goto rwmmap_fail;
2520 1.1.1.3 adam }
2521 1.1.1.3 adam }
2522 1.1.1.3 adam
2523 1.1.1.3 adam argv0 = c->argv[0];
2524 1.1.1.3 adam c->argv[0] = "map";
2525 1.1.1.3 adam rc = rwm_m_config( &db, c->fname, c->lineno, c->argc, c->argv );
2526 1.1.1.3 adam c->argv[0] = argv0;
2527 1.1.1.3 adam if ( rc ) {
2528 1.1.1.3 adam goto rwmmap_fail;
2529 1.1.1.3 adam }
2530 1.1.1.3 adam
2531 1.1.1.3 adam if ( rwmap->rwm_bva_map ) {
2532 1.1.1.3 adam for ( ; !BER_BVISNULL( &rwmap->rwm_bva_map[ cnt ] ); cnt++ ) {
2533 1.1.1.3 adam ConfigArgs ca = { 0 };
2534 1.1.1.3 adam
2535 1.1.1.3 adam ca.line = rwmap->rwm_bva_map[ cnt ].bv_val;
2536 1.1.1.3 adam ca.argc = 0;
2537 1.1.1.5 christos init_config_argv( &ca );
2538 1.1.1.5 christos config_parse_ldif( &ca );
2539 1.1.1.3 adam
2540 1.1.1.3 adam argv[1] = ca.argv[0];
2541 1.1.1.3 adam argv[2] = ca.argv[1];
2542 1.1.1.3 adam argv[3] = ca.argv[2];
2543 1.1.1.3 adam argv[4] = ca.argv[3];
2544 1.1.1.3 adam
2545 1.1.1.3 adam rc = rwm_m_config( &db, c->fname, c->lineno, ca.argc + 1, argv );
2546 1.1.1.3 adam
2547 1.1.1.3 adam ch_free( ca.tline );
2548 1.1.1.3 adam ch_free( ca.argv );
2549 1.1.1.3 adam
2550 1.1.1.3 adam /* in case of failure, restore
2551 1.1.1.3 adam * the existing mapping */
2552 1.1.1.3 adam if ( rc ) {
2553 1.1.1.3 adam goto rwmmap_fail;
2554 1.1.1.3 adam }
2555 1.1.1.3 adam }
2556 1.1.1.3 adam }
2557 1.1.1.3 adam
2558 1.1.1.3 adam /* in case of success, destroy the old mapping
2559 1.1.1.3 adam * and add the new one */
2560 1.1.1.3 adam if ( rc == 0 ) {
2561 1.1.1.3 adam BerVarray tmp;
2562 1.1.1.3 adam struct berval bv, *bvp = &bv;
2563 1.1.1.3 adam
2564 1.1.1.3 adam if ( rwm_bva_add( &bvp, 0, &c->argv[ idx0 ] ) ) {
2565 1.1.1.3 adam rc = 1;
2566 1.1.1.3 adam goto rwmmap_fail;
2567 1.1.1.3 adam }
2568 1.1.1.3 adam
2569 1.1.1.3 adam tmp = ber_memrealloc( rwmap->rwm_bva_map,
2570 1.1.1.3 adam sizeof( struct berval )*( cnt + 2 ) );
2571 1.1.1.3 adam if ( tmp == NULL ) {
2572 1.1.1.3 adam ber_memfree( bv.bv_val );
2573 1.1.1.3 adam rc = 1;
2574 1.1.1.3 adam goto rwmmap_fail;
2575 1.1.1.3 adam }
2576 1.1.1.3 adam rwmap->rwm_bva_map = tmp;
2577 1.1.1.3 adam BER_BVZERO( &rwmap->rwm_bva_map[ cnt + 1 ] );
2578 1.1.1.3 adam
2579 1.1.1.3 adam avl_free( rwm_oc.remap, rwm_mapping_dst_free );
2580 1.1.1.3 adam avl_free( rwm_oc.map, rwm_mapping_free );
2581 1.1.1.3 adam avl_free( rwm_at.remap, rwm_mapping_dst_free );
2582 1.1.1.3 adam avl_free( rwm_at.map, rwm_mapping_free );
2583 1.1.1.3 adam
2584 1.1.1.3 adam for ( ; cnt-- > c->valx; ) {
2585 1.1.1.3 adam rwmap->rwm_bva_map[ cnt + 1 ] = rwmap->rwm_bva_map[ cnt ];
2586 1.1.1.3 adam }
2587 1.1.1.3 adam rwmap->rwm_bva_map[ c->valx ] = bv;
2588 1.1.1.3 adam
2589 1.1.1.3 adam } else {
2590 1.1.1.3 adam rwmmap_fail:;
2591 1.1.1.3 adam avl_free( rwmap->rwm_oc.remap, rwm_mapping_dst_free );
2592 1.1.1.3 adam avl_free( rwmap->rwm_oc.map, rwm_mapping_free );
2593 1.1.1.3 adam avl_free( rwmap->rwm_at.remap, rwm_mapping_dst_free );
2594 1.1.1.3 adam avl_free( rwmap->rwm_at.map, rwm_mapping_free );
2595 1.1.1.3 adam rwmap->rwm_oc = rwm_oc;
2596 1.1.1.3 adam rwmap->rwm_at = rwm_at;
2597 1.1.1.3 adam }
2598 1.1.1.3 adam
2599 1.1.1.3 adam break;
2600 1.1.1.2 lukem }
2601 1.1.1.2 lukem
2602 1.1 lukem argv0 = c->argv[ 0 ];
2603 1.1 lukem c->argv[ 0 ] += STRLENOF( "rwm-" );
2604 1.1 lukem rc = rwm_m_config( &db, c->fname, c->lineno, c->argc, c->argv );
2605 1.1 lukem c->argv[ 0 ] = argv0;
2606 1.1 lukem if ( rc ) {
2607 1.1 lukem return 1;
2608 1.1 lukem
2609 1.1 lukem } else {
2610 1.1 lukem char *line;
2611 1.1 lukem struct berval bv;
2612 1.1 lukem
2613 1.1 lukem line = ldap_charray2str( &c->argv[ 1 ], " " );
2614 1.1 lukem if ( line != NULL ) {
2615 1.1 lukem ber_str2bv( line, 0, 0, &bv );
2616 1.1 lukem ber_bvarray_add( &rwmap->rwm_bva_map, &bv );
2617 1.1 lukem }
2618 1.1 lukem }
2619 1.1 lukem break;
2620 1.1 lukem
2621 1.1 lukem case RWM_CF_NORMALIZE_MAPPED:
2622 1.1 lukem if ( c->value_int ) {
2623 1.1 lukem rwmap->rwm_flags |= RWM_F_NORMALIZE_MAPPED_ATTRS;
2624 1.1 lukem } else {
2625 1.1 lukem rwmap->rwm_flags &= ~RWM_F_NORMALIZE_MAPPED_ATTRS;
2626 1.1 lukem }
2627 1.1 lukem break;
2628 1.1 lukem
2629 1.1.1.2 lukem case RWM_CF_DROP_UNREQUESTED:
2630 1.1.1.2 lukem if ( c->value_int ) {
2631 1.1.1.2 lukem rwmap->rwm_flags |= RWM_F_DROP_UNREQUESTED_ATTRS;
2632 1.1.1.2 lukem } else {
2633 1.1.1.2 lukem rwmap->rwm_flags &= ~RWM_F_DROP_UNREQUESTED_ATTRS;
2634 1.1.1.2 lukem }
2635 1.1.1.2 lukem break;
2636 1.1.1.2 lukem
2637 1.1 lukem default:
2638 1.1 lukem assert( 0 );
2639 1.1 lukem return 1;
2640 1.1 lukem }
2641 1.1 lukem
2642 1.1 lukem return rc;
2643 1.1 lukem }
2644 1.1 lukem
2645 1.1 lukem static int
2646 1.1 lukem rwm_db_init(
2647 1.1 lukem BackendDB *be,
2648 1.1 lukem ConfigReply *cr )
2649 1.1 lukem {
2650 1.1 lukem slap_overinst *on = (slap_overinst *) be->bd_info;
2651 1.1 lukem struct ldaprwmap *rwmap;
2652 1.1 lukem int rc = 0;
2653 1.1 lukem
2654 1.1 lukem rwmap = (struct ldaprwmap *)ch_calloc( 1, sizeof( struct ldaprwmap ) );
2655 1.1 lukem
2656 1.1.1.2 lukem /* default */
2657 1.1.1.2 lukem rwmap->rwm_flags = RWM_F_DROP_UNREQUESTED_ATTRS;
2658 1.1 lukem
2659 1.1.1.2 lukem rc = rwm_info_init( &rwmap->rwm_rw );
2660 1.1 lukem
2661 1.1 lukem on->on_bi.bi_private = (void *)rwmap;
2662 1.1 lukem
2663 1.1 lukem if ( rc ) {
2664 1.1 lukem (void)rwm_db_destroy( be, NULL );
2665 1.1 lukem }
2666 1.1 lukem
2667 1.1 lukem return rc;
2668 1.1 lukem }
2669 1.1 lukem
2670 1.1 lukem static int
2671 1.1 lukem rwm_db_destroy(
2672 1.1 lukem BackendDB *be,
2673 1.1 lukem ConfigReply *cr )
2674 1.1 lukem {
2675 1.1 lukem slap_overinst *on = (slap_overinst *) be->bd_info;
2676 1.1 lukem int rc = 0;
2677 1.1 lukem
2678 1.1 lukem if ( on->on_bi.bi_private ) {
2679 1.1 lukem struct ldaprwmap *rwmap =
2680 1.1 lukem (struct ldaprwmap *)on->on_bi.bi_private;
2681 1.1 lukem
2682 1.1 lukem if ( rwmap->rwm_rw ) {
2683 1.1 lukem rewrite_info_delete( &rwmap->rwm_rw );
2684 1.1.1.2 lukem if ( rwmap->rwm_bva_rewrite )
2685 1.1.1.2 lukem ber_bvarray_free( rwmap->rwm_bva_rewrite );
2686 1.1 lukem }
2687 1.1 lukem
2688 1.1 lukem avl_free( rwmap->rwm_oc.remap, rwm_mapping_dst_free );
2689 1.1 lukem avl_free( rwmap->rwm_oc.map, rwm_mapping_free );
2690 1.1 lukem avl_free( rwmap->rwm_at.remap, rwm_mapping_dst_free );
2691 1.1 lukem avl_free( rwmap->rwm_at.map, rwm_mapping_free );
2692 1.1 lukem ber_bvarray_free( rwmap->rwm_bva_map );
2693 1.1 lukem
2694 1.1 lukem ch_free( rwmap );
2695 1.1 lukem }
2696 1.1 lukem
2697 1.1 lukem return rc;
2698 1.1 lukem }
2699 1.1 lukem
2700 1.1 lukem static slap_overinst rwm = { { NULL } };
2701 1.1 lukem
2702 1.1 lukem #if SLAPD_OVER_RWM == SLAPD_MOD_DYNAMIC
2703 1.1 lukem static
2704 1.1 lukem #endif /* SLAPD_OVER_RWM == SLAPD_MOD_DYNAMIC */
2705 1.1 lukem int
2706 1.1 lukem rwm_initialize( void )
2707 1.1 lukem {
2708 1.1 lukem int rc;
2709 1.1 lukem
2710 1.1 lukem /* Make sure we don't exceed the bits reserved for userland */
2711 1.1 lukem config_check_userland( RWM_CF_LAST );
2712 1.1 lukem
2713 1.1 lukem memset( &rwm, 0, sizeof( slap_overinst ) );
2714 1.1 lukem
2715 1.1 lukem rwm.on_bi.bi_type = "rwm";
2716 1.1 lukem rwm.on_bi.bi_flags =
2717 1.1 lukem SLAPO_BFLAG_SINGLE |
2718 1.1 lukem 0;
2719 1.1 lukem
2720 1.1 lukem rwm.on_bi.bi_db_init = rwm_db_init;
2721 1.1 lukem rwm.on_bi.bi_db_config = rwm_db_config;
2722 1.1 lukem rwm.on_bi.bi_db_destroy = rwm_db_destroy;
2723 1.1 lukem
2724 1.1 lukem rwm.on_bi.bi_op_bind = rwm_op_bind;
2725 1.1 lukem rwm.on_bi.bi_op_search = rwm_op_search;
2726 1.1 lukem rwm.on_bi.bi_op_compare = rwm_op_compare;
2727 1.1 lukem rwm.on_bi.bi_op_modify = rwm_op_modify;
2728 1.1 lukem rwm.on_bi.bi_op_modrdn = rwm_op_modrdn;
2729 1.1 lukem rwm.on_bi.bi_op_add = rwm_op_add;
2730 1.1 lukem rwm.on_bi.bi_op_delete = rwm_op_delete;
2731 1.1 lukem rwm.on_bi.bi_op_unbind = rwm_op_unbind;
2732 1.1 lukem rwm.on_bi.bi_extended = rwm_extended;
2733 1.1.1.2 lukem #if 1 /* TODO */
2734 1.1.1.2 lukem rwm.on_bi.bi_entry_release_rw = rwm_entry_release_rw;
2735 1.1.1.2 lukem rwm.on_bi.bi_entry_get_rw = rwm_entry_get_rw;
2736 1.1.1.2 lukem #endif
2737 1.1 lukem
2738 1.1 lukem rwm.on_bi.bi_operational = rwm_operational;
2739 1.1 lukem rwm.on_bi.bi_chk_referrals = 0 /* rwm_chk_referrals */ ;
2740 1.1 lukem
2741 1.1 lukem rwm.on_bi.bi_connection_init = rwm_conn_init;
2742 1.1 lukem rwm.on_bi.bi_connection_destroy = rwm_conn_destroy;
2743 1.1 lukem
2744 1.1 lukem rwm.on_response = rwm_response;
2745 1.1 lukem
2746 1.1 lukem rwm.on_bi.bi_cf_ocs = rwmocs;
2747 1.1 lukem
2748 1.1 lukem rc = config_register_schema( rwmcfg, rwmocs );
2749 1.1 lukem if ( rc ) {
2750 1.1 lukem return rc;
2751 1.1 lukem }
2752 1.1 lukem
2753 1.1 lukem return overlay_register( &rwm );
2754 1.1 lukem }
2755 1.1 lukem
2756 1.1 lukem #if SLAPD_OVER_RWM == SLAPD_MOD_DYNAMIC
2757 1.1 lukem int
2758 1.1 lukem init_module( int argc, char *argv[] )
2759 1.1 lukem {
2760 1.1 lukem return rwm_initialize();
2761 1.1 lukem }
2762 1.1 lukem #endif /* SLAPD_OVER_RWM == SLAPD_MOD_DYNAMIC */
2763 1.1 lukem
2764 1.1 lukem #endif /* SLAPD_OVER_RWM */
2765