1 /* op.c - relay backend operations */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 2003-2004 The OpenLDAP Foundation.
5 * Portions Copyright 2004 Pierangelo Masarati.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
17 * This work was initially developed by Pierangelo Masarati for inclusion
18 * in OpenLDAP Software.
26 #include "back-relay.h"
29 relay_back_swap_bd( struct slap_op *op, struct slap_rep *rs )
31 slap_callback *cb = op->o_callback;
32 BackendDB *be = op->o_bd;
34 op->o_bd = cb->sc_private;
37 return SLAP_CB_CONTINUE;
41 relay_back_select_backend( struct slap_op *op, struct slap_rep *rs, int err )
43 relay_back_info *ri = (relay_back_info *)op->o_bd->be_private;
44 BackendDB *bd = ri->ri_bd;
47 bd = select_backend( &op->o_req_ndn, 0, 1 );
48 if ( bd == op->o_bd ) {
49 if ( err != LDAP_SUCCESS ) {
50 send_ldap_error( op, rs,
51 LDAP_UNWILLING_TO_PERFORM,
59 if ( default_referral ) {
60 rs->sr_ref = referral_rewrite( default_referral,
61 NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT );
63 rs->sr_ref = default_referral;
66 rs->sr_err = LDAP_REFERRAL;
67 send_ldap_result( op, rs );
69 if ( rs->sr_ref != default_referral ) {
70 ber_bvarray_free( rs->sr_ref );
74 /* NOTE: err is LDAP_INVALID_CREDENTIALS for bind,
75 * LDAP_NO_SUCH_OBJECT for other operations.
76 * noSuchObject is not allowed to be returned by bind */
78 send_ldap_result( op, rs );
86 relay_back_op_bind( struct slap_op *op, struct slap_rep *rs )
91 bd = relay_back_select_backend( op, rs, LDAP_INVALID_CREDENTIALS );
97 BackendDB *be = op->o_bd;
100 rc = ( bd->be_bind )( op, rs );
104 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
105 "operation not supported "
106 "within naming context" );
113 relay_back_op_unbind( struct slap_op *op, struct slap_rep *rs )
115 relay_back_info *ri = (relay_back_info *)op->o_bd->be_private;
121 bd = select_backend( &op->o_req_ndn, 0, 1 );
124 if ( bd && bd->be_unbind ) {
125 BackendDB *be = op->o_bd;
128 cb.sc_next = op->o_callback;
129 cb.sc_response = relay_back_swap_bd;
130 cb.sc_cleanup = relay_back_swap_bd;
131 cb.sc_private = op->o_bd;
132 op->o_callback = &cb;
135 rc = ( bd->be_unbind )( op, rs );
144 relay_back_op_search( struct slap_op *op, struct slap_rep *rs )
149 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
154 if ( bd->be_search ) {
155 BackendDB *be = op->o_bd;
158 cb.sc_next = op->o_callback;
159 cb.sc_response = relay_back_swap_bd;
160 cb.sc_cleanup = relay_back_swap_bd;
161 cb.sc_private = op->o_bd;
162 op->o_callback = &cb;
165 rc = ( bd->be_search )( op, rs );
169 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
170 "operation not supported "
171 "within naming context" );
179 relay_back_op_compare( struct slap_op *op, struct slap_rep *rs )
184 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
189 if ( bd->be_compare ) {
190 BackendDB *be = op->o_bd;
193 cb.sc_next = op->o_callback;
194 cb.sc_response = relay_back_swap_bd;
195 cb.sc_cleanup = relay_back_swap_bd;
196 cb.sc_private = op->o_bd;
197 op->o_callback = &cb;
200 rc = ( bd->be_compare )( op, rs );
204 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
205 "operation not supported "
206 "within naming context" );
214 relay_back_op_modify( struct slap_op *op, struct slap_rep *rs )
219 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
224 if ( bd->be_modify ) {
225 BackendDB *be = op->o_bd;
228 cb.sc_next = op->o_callback;
229 cb.sc_response = relay_back_swap_bd;
230 cb.sc_cleanup = relay_back_swap_bd;
231 cb.sc_private = op->o_bd;
232 op->o_callback = &cb;
235 rc = ( bd->be_modify )( op, rs );
239 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
240 "operation not supported "
241 "within naming context" );
249 relay_back_op_modrdn( struct slap_op *op, struct slap_rep *rs )
254 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
259 if ( bd->be_modrdn ) {
260 BackendDB *be = op->o_bd;
263 cb.sc_next = op->o_callback;
264 cb.sc_response = relay_back_swap_bd;
265 cb.sc_cleanup = relay_back_swap_bd;
266 cb.sc_private = op->o_bd;
267 op->o_callback = &cb;
270 rc = ( bd->be_modrdn )( op, rs );
274 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
275 "operation not supported "
276 "within naming context" );
284 relay_back_op_add( struct slap_op *op, struct slap_rep *rs )
289 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
295 BackendDB *be = op->o_bd;
298 cb.sc_next = op->o_callback;
299 cb.sc_response = relay_back_swap_bd;
300 cb.sc_cleanup = relay_back_swap_bd;
301 cb.sc_private = op->o_bd;
302 op->o_callback = &cb;
305 rc = ( bd->be_add )( op, rs );
309 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
310 "operation not supported "
311 "within naming context" );
319 relay_back_op_delete( struct slap_op *op, struct slap_rep *rs )
324 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
329 if ( bd->be_delete ) {
330 BackendDB *be = op->o_bd;
333 cb.sc_next = op->o_callback;
334 cb.sc_response = relay_back_swap_bd;
335 cb.sc_cleanup = relay_back_swap_bd;
336 cb.sc_private = op->o_bd;
337 op->o_callback = &cb;
340 rc = ( bd->be_delete )( op, rs );
349 relay_back_op_abandon( struct slap_op *op, struct slap_rep *rs )
354 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
359 if ( bd->be_abandon ) {
360 BackendDB *be = op->o_bd;
363 cb.sc_next = op->o_callback;
364 cb.sc_response = relay_back_swap_bd;
365 cb.sc_cleanup = relay_back_swap_bd;
366 cb.sc_private = op->o_bd;
367 op->o_callback = &cb;
370 rc = ( bd->be_abandon )( op, rs );
374 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
375 "operation not supported "
376 "within naming context" );
384 relay_back_op_cancel( struct slap_op *op, struct slap_rep *rs )
389 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
394 if ( bd->be_cancel ) {
395 BackendDB *be = op->o_bd;
398 cb.sc_next = op->o_callback;
399 cb.sc_response = relay_back_swap_bd;
400 cb.sc_cleanup = relay_back_swap_bd;
401 cb.sc_private = op->o_bd;
402 op->o_callback = &cb;
405 rc = ( bd->be_cancel )( op, rs );
409 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
410 "operation not supported "
411 "within naming context" );
419 relay_back_op_extended( struct slap_op *op, struct slap_rep *rs )
424 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
429 if ( bd->be_extended ) {
430 BackendDB *be = op->o_bd;
433 cb.sc_next = op->o_callback;
434 cb.sc_response = relay_back_swap_bd;
435 cb.sc_cleanup = relay_back_swap_bd;
436 cb.sc_private = op->o_bd;
437 op->o_callback = &cb;
440 rc = ( bd->be_extended )( op, rs );
444 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
445 "operation not supported "
446 "within naming context" );
454 relay_back_entry_release_rw( struct slap_op *op, Entry *e, int rw )
456 relay_back_info *ri = (relay_back_info *)op->o_bd->be_private;
462 bd = select_backend( &op->o_req_ndn, 0, 1 );
468 if ( bd->be_release ) {
469 BackendDB *be = op->o_bd;
472 rc = ( bd->be_release )( op, e, rw );
481 relay_back_entry_get_rw( struct slap_op *op, struct berval *ndn,
482 ObjectClass *oc, AttributeDescription *at, int rw, Entry **e )
484 relay_back_info *ri = (relay_back_info *)op->o_bd->be_private;
490 bd = select_backend( &op->o_req_ndn, 0, 1 );
496 if ( bd->be_fetch ) {
497 BackendDB *be = op->o_bd;
500 rc = ( bd->be_fetch )( op, ndn, oc, at, rw, e );
509 relay_back_chk_referrals( struct slap_op *op, struct slap_rep *rs )
514 bd = relay_back_select_backend( op, rs, LDAP_SUCCESS );
519 if ( bd->be_chk_referrals ) {
520 BackendDB *be = op->o_bd;
523 cb.sc_next = op->o_callback;
524 cb.sc_response = relay_back_swap_bd;
525 cb.sc_cleanup = relay_back_swap_bd;
526 cb.sc_private = op->o_bd;
527 op->o_callback = &cb;
530 rc = ( bd->be_chk_referrals )( op, rs );
539 relay_back_operational( struct slap_op *op, struct slap_rep *rs,
540 int opattrs, Attribute **ap )
542 relay_back_info *ri = (relay_back_info *)op->o_bd->be_private;
548 bd = select_backend( &op->o_req_ndn, 0, 1 );
554 if ( bd->be_operational ) {
555 BackendDB *be = op->o_bd;
558 rc = ( bd->be_operational )( op, rs, opattrs, ap );
567 relay_back_has_subordinates( struct slap_op *op, Entry *e, int *hasSubs )
569 relay_back_info *ri = (relay_back_info *)op->o_bd->be_private;
575 bd = select_backend( &op->o_req_ndn, 0, 1 );
581 if ( bd->be_has_subordinates ) {
582 BackendDB *be = op->o_bd;
585 rc = ( bd->be_has_subordinates )( op, e, hasSubs );
594 relay_back_connection_init( BackendDB *bd, struct slap_conn *c )
596 relay_back_info *ri = (relay_back_info *)bd->be_private;
603 if ( bd->be_connection_init ) {
604 return ( bd->be_connection_init )( bd, c );
611 relay_back_connection_destroy( BackendDB *bd, struct slap_conn *c )
613 relay_back_info *ri = (relay_back_info *)bd->be_private;
620 if ( bd->be_connection_destroy ) {
621 return ( bd->be_connection_destroy )( bd, c );
629 * FIXME: must implement tools as well