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.
25 #include <ac/string.h>
26 #include <ac/socket.h>
29 #include "back-relay.h"
32 relay_back_swap_bd( struct slap_op *op, struct slap_rep *rs )
34 slap_callback *cb = op->o_callback;
35 BackendDB *be = op->o_bd;
37 op->o_bd = cb->sc_private;
40 return SLAP_CB_CONTINUE;
44 relay_back_select_backend( struct slap_op *op, struct slap_rep *rs, int err )
46 relay_back_info *ri = (relay_back_info *)op->o_bd->be_private;
47 BackendDB *bd = ri->ri_bd;
50 bd = select_backend( &op->o_req_ndn, 0, 1 );
51 if ( bd == op->o_bd ) {
52 if ( err != LDAP_SUCCESS ) {
53 send_ldap_error( op, rs,
54 LDAP_UNWILLING_TO_PERFORM,
62 if ( default_referral ) {
63 rs->sr_ref = referral_rewrite( default_referral,
64 NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT );
66 rs->sr_ref = default_referral;
69 rs->sr_err = LDAP_REFERRAL;
70 send_ldap_result( op, rs );
72 if ( rs->sr_ref != default_referral ) {
73 ber_bvarray_free( rs->sr_ref );
77 /* NOTE: err is LDAP_INVALID_CREDENTIALS for bind,
78 * LDAP_NO_SUCH_OBJECT for other operations.
79 * noSuchObject is not allowed to be returned by bind */
81 send_ldap_result( op, rs );
89 relay_back_op_bind( struct slap_op *op, struct slap_rep *rs )
94 bd = relay_back_select_backend( op, rs, LDAP_INVALID_CREDENTIALS );
100 BackendDB *be = op->o_bd;
103 rc = ( bd->be_bind )( op, rs );
107 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
108 "operation not supported "
109 "within naming context" );
116 relay_back_op_unbind( struct slap_op *op, struct slap_rep *rs )
118 relay_back_info *ri = (relay_back_info *)op->o_bd->be_private;
124 bd = select_backend( &op->o_req_ndn, 0, 1 );
127 if ( bd && bd->be_unbind ) {
128 BackendDB *be = op->o_bd;
131 rc = ( bd->be_unbind )( op, rs );
140 relay_back_op_search( struct slap_op *op, struct slap_rep *rs )
145 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
150 if ( bd->be_search ) {
151 BackendDB *be = op->o_bd;
154 cb.sc_next = op->o_callback;
155 cb.sc_response = relay_back_swap_bd;
156 cb.sc_cleanup = relay_back_swap_bd;
157 cb.sc_private = op->o_bd;
158 op->o_callback = &cb;
161 rc = ( bd->be_search )( op, rs );
165 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
166 "operation not supported "
167 "within naming context" );
175 relay_back_op_compare( struct slap_op *op, struct slap_rep *rs )
180 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
185 if ( bd->be_compare ) {
186 BackendDB *be = op->o_bd;
189 rc = ( bd->be_compare )( op, rs );
193 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
194 "operation not supported "
195 "within naming context" );
203 relay_back_op_modify( struct slap_op *op, struct slap_rep *rs )
208 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
213 if ( bd->be_modify ) {
214 BackendDB *be = op->o_bd;
217 rc = ( bd->be_modify )( op, rs );
221 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
222 "operation not supported "
223 "within naming context" );
231 relay_back_op_modrdn( struct slap_op *op, struct slap_rep *rs )
236 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
241 if ( bd->be_modrdn ) {
242 BackendDB *be = op->o_bd;
245 rc = ( bd->be_modrdn )( op, rs );
249 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
250 "operation not supported "
251 "within naming context" );
259 relay_back_op_add( struct slap_op *op, struct slap_rep *rs )
264 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
270 BackendDB *be = op->o_bd;
273 rc = ( bd->be_add )( op, rs );
277 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
278 "operation not supported "
279 "within naming context" );
287 relay_back_op_delete( struct slap_op *op, struct slap_rep *rs )
292 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
297 if ( bd->be_delete ) {
298 BackendDB *be = op->o_bd;
301 rc = ( bd->be_delete )( op, rs );
310 relay_back_op_abandon( struct slap_op *op, struct slap_rep *rs )
315 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
320 if ( bd->be_abandon ) {
321 BackendDB *be = op->o_bd;
324 rc = ( bd->be_abandon )( op, rs );
328 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
329 "operation not supported "
330 "within naming context" );
338 relay_back_op_cancel( struct slap_op *op, struct slap_rep *rs )
343 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
348 if ( bd->be_cancel ) {
349 BackendDB *be = op->o_bd;
352 rc = ( bd->be_cancel )( op, rs );
356 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
357 "operation not supported "
358 "within naming context" );
366 relay_back_op_extended( struct slap_op *op, struct slap_rep *rs )
371 bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
376 if ( bd->be_extended ) {
377 BackendDB *be = op->o_bd;
380 rc = ( bd->be_extended )( op, rs );
384 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
385 "operation not supported "
386 "within naming context" );
394 relay_back_entry_release_rw( struct slap_op *op, Entry *e, int rw )
396 relay_back_info *ri = (relay_back_info *)op->o_bd->be_private;
402 bd = select_backend( &op->o_req_ndn, 0, 1 );
408 if ( bd->be_release ) {
409 BackendDB *be = op->o_bd;
412 rc = ( bd->be_release )( op, e, rw );
421 relay_back_entry_get_rw( struct slap_op *op, struct berval *ndn,
422 ObjectClass *oc, AttributeDescription *at, int rw, Entry **e )
424 relay_back_info *ri = (relay_back_info *)op->o_bd->be_private;
430 bd = select_backend( &op->o_req_ndn, 0, 1 );
436 if ( bd->be_fetch ) {
437 BackendDB *be = op->o_bd;
440 rc = ( bd->be_fetch )( op, ndn, oc, at, rw, e );
449 relay_back_chk_referrals( struct slap_op *op, struct slap_rep *rs )
454 bd = relay_back_select_backend( op, rs, LDAP_SUCCESS );
459 if ( bd->be_chk_referrals ) {
460 BackendDB *be = op->o_bd;
463 rc = ( bd->be_chk_referrals )( op, rs );
472 relay_back_operational( struct slap_op *op, struct slap_rep *rs,
473 int opattrs, Attribute **ap )
475 relay_back_info *ri = (relay_back_info *)op->o_bd->be_private;
481 bd = select_backend( &op->o_req_ndn, 0, 1 );
487 if ( bd->be_operational ) {
488 BackendDB *be = op->o_bd;
491 rc = ( bd->be_operational )( op, rs, opattrs, ap );
500 relay_back_has_subordinates( struct slap_op *op, Entry *e, int *hasSubs )
502 relay_back_info *ri = (relay_back_info *)op->o_bd->be_private;
508 bd = select_backend( &op->o_req_ndn, 0, 1 );
514 if ( bd->be_has_subordinates ) {
515 BackendDB *be = op->o_bd;
518 rc = ( bd->be_has_subordinates )( op, e, hasSubs );
527 relay_back_connection_init( BackendDB *bd, struct slap_conn *c )
529 relay_back_info *ri = (relay_back_info *)bd->be_private;
536 if ( bd->be_connection_init ) {
537 return ( bd->be_connection_init )( bd, c );
544 relay_back_connection_destroy( BackendDB *bd, struct slap_conn *c )
546 relay_back_info *ri = (relay_back_info *)bd->be_private;
553 if ( bd->be_connection_destroy ) {
554 return ( bd->be_connection_destroy )( bd, c );
562 * FIXME: must implement tools as well