Questions:
* relay_back_operational() sets up callbacks. Should it?
Looks harmless, but as far as I can tell, be->be_operational() functions do not use them, since they (should) send no response.
* There is no relay_back_chk_controls(). Should there be?
Though I think DNs would then be rewritten four times the same way for each operation:-( Already operational, has_subordinates and finally the operation itself does. And possibly for access controls.
I've factored op.c code out to table-driven handlers and a macro, and cleaned away those '#if 0's.
Fixed more problems:
* Search referrals should have a scope.
* relay_back_op_extended() was (still) broken. The handler should return a result which caller should send, so it must set sr->sr_ref without freeing it. Setting REP_REF_MUSTBEFREED instead, and droping the RB_SEND requirement in fail_mode.
* For readability, fixed return values from relay_back_chk_referrals() and other unused handlers. (chk_referrals may be unfixable.)
* relay_back_entry_<get/release>_rw() returned operationsError for failure. Failing with noSuchObject/unwillingToPerform instead.
* relay_back_entry_release_rw() leaked entries when bd->be_release==0. For paranoia, fixed it only when the entry's e_private == NULL.
- The handlers for Abandon, Cancel and connection-init/destroy should not exist, as far as I can tell. They forward the call to the underlying backend database, but that means it receives the call twice:
So does Unbind. Removed the handler.
- back-relay can be configured to cause infinite recursion. (...) Anyway, recursion can now be properly caught with op->o_extra. (...)
Needed a unique key per <operation type, relay database> combination. Otherwise things like backend_group() called from another operation failed when looking up a relayed DN via relay_back_entry_get_rw().
That fixed relay_back_operational() and relay_back_has_subordinates(), or at least I assume that's what their FIXMEs were about.