1 /* op.c - relay backend operations */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 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_add_cb( slap_callback *cb, struct slap_op *op )
43 cb->sc_next = op->o_callback;
44 cb->sc_response = relay_back_swap_bd;
45 cb->sc_cleanup = relay_back_swap_bd;
46 cb->sc_private = op->o_bd;
51 relay_back_select_backend( struct slap_op *op, struct slap_rep *rs, int err )
53 relay_back_info *ri = (relay_back_info *)op->o_bd->be_private;
54 BackendDB *bd = ri->ri_bd;
57 bd = select_backend( &op->o_req_ndn, 0, 1 );
58 if ( bd == op->o_bd ) {
59 if ( err != LDAP_SUCCESS ) {
60 send_ldap_error( op, rs,
61 LDAP_UNWILLING_TO_PERFORM,
69 if ( SLAPD_GLOBAL(default_referral) ) {
70 rs->sr_ref = referral_rewrite( SLAPD_GLOBAL(default_referral),
71 NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT );
73 rs->sr_ref = SLAPD_GLOBAL(default_referral);
76 rs->sr_err = LDAP_REFERRAL;
77 send_ldap_result( op, rs );
79 if ( rs->sr_ref != SLAPD_GLOBAL(default_referral) ) {
80 ber_bvarray_free( rs->sr_ref );
84 /* NOTE: err is LDAP_INVALID_CREDENTIALS for bind,
85 * LDAP_NO_SUCH_OBJECT for other operations.
86 * noSuchObject is not allowed to be returned by bind */
88 send_ldap_result( op, rs );
96 relay_back_op_bind( struct slap_op *op, struct slap_rep *rs )
101 bd = relay_back_select_backend( op, rs, LDAP_INVALID_CREDENTIALS );
107 BackendDB *be = op->o_bd;
110 relay_back_add_cb( &cb, op );
113 rc = ( bd->be_bind )( op, rs );
116 if ( op->o_callback == &cb ) {
117 op->o_callback = op->o_callback->sc_next;
121 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
122 "operation not supported "
123 "within naming context" );
130 relay_back_op_unbind( struct slap_op *op, struct slap_rep *rs )
132 relay_back_info *ri = (relay_back_info *)op->o_bd->be_private;
138 bd = select_backend( &op->o_req_ndn, 0, 1 );
141 if ( bd && bd->be_unbind ) {
142 BackendDB *be = op->o_bd;
145 relay_back_add_cb( &cb, op );
148 rc = ( bd->be_unbind )( op, rs );
151 if ( op->o_callback == &cb ) {
152 op->o_callback = op->o_callback->sc_next;
161 relay_back_op_search( struct slap_op *op, struct slap_rep *rs )
166 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
171 if ( bd->be_search ) {
172 BackendDB *be = op->o_bd;
175 relay_back_add_cb( &cb, op );
178 rc = ( bd->be_search )( op, rs );
181 if ( op->o_callback == &cb ) {
182 op->o_callback = op->o_callback->sc_next;
186 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
187 "operation not supported "
188 "within naming context" );
196 relay_back_op_compare( struct slap_op *op, struct slap_rep *rs )
201 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
206 if ( bd->be_compare ) {
207 BackendDB *be = op->o_bd;
210 relay_back_add_cb( &cb, op );
213 rc = ( bd->be_compare )( op, rs );
216 if ( op->o_callback == &cb ) {
217 op->o_callback = op->o_callback->sc_next;
221 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
222 "operation not supported "
223 "within naming context" );
231 relay_back_op_modify( struct slap_op *op, struct slap_rep *rs )
236 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
241 if ( bd->be_modify ) {
242 BackendDB *be = op->o_bd;
245 relay_back_add_cb( &cb, op );
248 rc = ( bd->be_modify )( op, rs );
251 if ( op->o_callback == &cb ) {
252 op->o_callback = op->o_callback->sc_next;
256 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
257 "operation not supported "
258 "within naming context" );
266 relay_back_op_modrdn( struct slap_op *op, struct slap_rep *rs )
271 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
276 if ( bd->be_modrdn ) {
277 BackendDB *be = op->o_bd;
280 relay_back_add_cb( &cb, op );
283 rc = ( bd->be_modrdn )( op, rs );
286 if ( op->o_callback == &cb ) {
287 op->o_callback = op->o_callback->sc_next;
291 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
292 "operation not supported "
293 "within naming context" );
301 relay_back_op_add( struct slap_op *op, struct slap_rep *rs )
306 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
312 BackendDB *be = op->o_bd;
315 relay_back_add_cb( &cb, op );
318 rc = ( bd->be_add )( op, rs );
321 if ( op->o_callback == &cb ) {
322 op->o_callback = op->o_callback->sc_next;
326 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
327 "operation not supported "
328 "within naming context" );
336 relay_back_op_delete( struct slap_op *op, struct slap_rep *rs )
341 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
346 if ( bd->be_delete ) {
347 BackendDB *be = op->o_bd;
350 relay_back_add_cb( &cb, op );
353 rc = ( bd->be_delete )( op, rs );
356 if ( op->o_callback == &cb ) {
357 op->o_callback = op->o_callback->sc_next;
366 relay_back_op_abandon( struct slap_op *op, struct slap_rep *rs )
371 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
376 if ( bd->be_abandon ) {
377 BackendDB *be = op->o_bd;
380 relay_back_add_cb( &cb, op );
383 rc = ( bd->be_abandon )( op, rs );
386 if ( op->o_callback == &cb ) {
387 op->o_callback = op->o_callback->sc_next;
391 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
392 "operation not supported "
393 "within naming context" );
401 relay_back_op_cancel( struct slap_op *op, struct slap_rep *rs )
406 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
411 if ( bd->be_cancel ) {
412 BackendDB *be = op->o_bd;
415 relay_back_add_cb( &cb, op );
418 rc = ( bd->be_cancel )( op, rs );
421 if ( op->o_callback == &cb ) {
422 op->o_callback = op->o_callback->sc_next;
426 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
427 "operation not supported "
428 "within naming context" );
436 relay_back_op_extended( struct slap_op *op, struct slap_rep *rs )
441 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
446 if ( bd->be_extended ) {
447 BackendDB *be = op->o_bd;
450 relay_back_add_cb( &cb, op );
453 rc = ( bd->be_extended )( op, rs );
456 if ( op->o_callback == &cb ) {
457 op->o_callback = op->o_callback->sc_next;
461 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
462 "operation not supported "
463 "within naming context" );
471 relay_back_entry_release_rw( struct slap_op *op, Entry *e, int rw )
473 relay_back_info *ri = (relay_back_info *)op->o_bd->be_private;
479 bd = select_backend( &op->o_req_ndn, 0, 1 );
485 if ( bd->be_release ) {
486 BackendDB *be = op->o_bd;
489 rc = ( bd->be_release )( op, e, rw );
498 relay_back_entry_get_rw( struct slap_op *op, struct berval *ndn,
499 ObjectClass *oc, AttributeDescription *at, int rw, Entry **e )
501 relay_back_info *ri = (relay_back_info *)op->o_bd->be_private;
507 bd = select_backend( &op->o_req_ndn, 0, 1 );
513 if ( bd->be_fetch ) {
514 BackendDB *be = op->o_bd;
517 rc = ( bd->be_fetch )( op, ndn, oc, at, rw, e );
526 relay_back_chk_referrals( struct slap_op *op, struct slap_rep *rs )
531 bd = relay_back_select_backend( op, rs, LDAP_SUCCESS );
532 if ( bd == NULL || bd == op->o_bd ) {
536 if ( bd->be_chk_referrals ) {
537 BackendDB *be = op->o_bd;
540 relay_back_add_cb( &cb, op );
543 rc = ( bd->be_chk_referrals )( op, rs );
546 if ( op->o_callback == &cb ) {
547 op->o_callback = op->o_callback->sc_next;
556 relay_back_operational( struct slap_op *op, struct slap_rep *rs )
558 relay_back_info *ri = (relay_back_info *)op->o_bd->be_private;
564 bd = select_backend( &op->o_req_ndn, 0, 1 );
570 if ( bd->be_operational ) {
571 BackendDB *be = op->o_bd;
574 relay_back_add_cb( &cb, op );
577 rc = ( bd->be_operational )( op, rs );
580 if ( op->o_callback == &cb ) {
581 op->o_callback = op->o_callback->sc_next;
590 relay_back_has_subordinates( struct slap_op *op, Entry *e, int *hasSubs )
592 relay_back_info *ri = (relay_back_info *)op->o_bd->be_private;
598 bd = select_backend( &op->o_req_ndn, 0, 1 );
604 if ( bd->be_has_subordinates ) {
605 BackendDB *be = op->o_bd;
608 rc = ( bd->be_has_subordinates )( op, e, hasSubs );
617 relay_back_connection_init( BackendDB *bd, struct slap_conn *c )
619 relay_back_info *ri = (relay_back_info *)bd->be_private;
626 if ( bd->be_connection_init ) {
627 return ( bd->be_connection_init )( bd, c );
634 relay_back_connection_destroy( BackendDB *bd, struct slap_conn *c )
636 relay_back_info *ri = (relay_back_info *)bd->be_private;
643 if ( bd->be_connection_destroy ) {
644 return ( bd->be_connection_destroy )( bd, c );
652 * FIXME: must implement tools as well