h.b.furuseth@usit.uio.no wrote:
Full_Name: Hallvard B Furuseth Version: HEAD OS: Linux URL: Submission from: (NULL) (129.240.6.233) Submitted by: hallvard
back-relay's be_extended could send a result, but be_extended should only set/return it and leave it to the frontend to send it. Just fixed by Pierangelo.
Looking at the code, some overlays also send results when used as be_extended: pcache:pcache_op_privdb(), retcode, rwm, slapi_overlay.
More about back-relay:
it fails to send anything if the Delete operation is not supported.
be_abandon, be_chk_referrals and be_operational can return either an LDAP result code, or 0 or 1 (which become success and operationError if they get used as result codes). I don't know if that matters.
Back-relay operations can be factored out to something like this:
int relay_back_op( Operation *op, SlapReply *rs, BackendDB *bd, BI_op_func *func, Fail_Type fail_mode ) { int rc = fail_mode;
if ( func ) { BackendDB *be = op->o_bd; slap_callback cb;
relay_back_add_cb( &cb, op ); op->o_bd = bd; rc = func( op, rs ); op->o_bd = be; if ( op->o_callback == &cb ) { op->o_callback = op->o_callback->sc_next; }
} else if ( fail_mode > Fail_1 ) { rc = rs->sr_err = LDAP_UNWILLING_TO_PERFORM; rs->sr_text = "operation not supported within naming context"; if ( fail_mode == Fail_send ) { send_ldap_result( op, rs ); rc = 1; } }
return rc; }
... return relay_back_op( op, rs, bd, bd->be_bind, Fail_send ); (void) relay_back_op( op, rs, bd, bd->be_unbind, Fail_0 ); return 0; return relay_back_op( op, rs, bd, bd->be_search, Fail_send ); return relay_back_op( op, rs, bd, bd->be_compare, Fail_send ); return relay_back_op( op, rs, bd, bd->be_modify, Fail_send ); return relay_back_op( op, rs, bd, bd->be_modrdn, Fail_send ); return relay_back_op( op, rs, bd, bd->be_add, Fail_send ); return relay_back_op( op, rs, bd, bd->be_delete, Fail_send ); return relay_back_op( op, rs, bd, bd->be_abandon, Fail_1 ); return relay_back_op( op, rs, bd, bd->be_cancel, Fail_send );
^^^ cancel should __NOT__ send response, since it's an extended operation. On the contrary, it should set op->o_cancel if it couldn't relay the operation, otherwise the cancel thread would yield forever.
return relay_back_op( op, rs, bd, bd->be_extended, Fail_unwilling ); return relay_back_op( op, rs, bd, bd->be_chk_referrals, Fail_0 ); return relay_back_op( op, rs, bd, bd->be_operational, Fail_1 );
I like the idea, but that's slightly too simple. The reason I didn't try to synthesize calls like that was the need to also handle more complex combinations. For this reason, I'm actually considering the use of a mask to fine-grain drive the behavior of the helper.
p.
Ing. Pierangelo Masarati OpenLDAP Core Team
SysNet s.r.l. via Dossi, 8 - 27100 Pavia - ITALIA http://www.sys-net.it --------------------------------------- Office: +39 02 23998309 Mobile: +39 333 4963172 Email: pierangelo.masarati@sys-net.it ---------------------------------------