}
static int
-send_ldap_controls( BerElement *ber, LDAPControl **c )
+send_ldap_control( BerElement *ber, LDAPControl *c )
{
int rc;
+
+ assert( c != NULL );
+
+ rc = ber_printf( ber, "{s" /*}*/, c->ldctl_oid );
+
+ if( c->ldctl_iscritical ) {
+ rc = ber_printf( ber, "b",
+ (ber_int_t) c->ldctl_iscritical ) ;
+ if( rc == -1 ) return rc;
+ }
+
+ if( c->ldctl_value.bv_val != NULL ) {
+ rc = ber_printf( ber, "O", &c->ldctl_value );
+ if( rc == -1 ) return rc;
+ }
+
+ rc = ber_printf( ber, /*{*/"N}" );
+ if( rc == -1 ) return rc;
+
+ return 0;
+}
+
+static int
+send_ldap_controls( Operation *o, BerElement *ber, LDAPControl **c )
+{
+ int rc;
+#ifdef LDAP_SLAPI
+ LDAPControl **sctrls = NULL;
+
+ /*
+ * Retrieve any additional controls that may be set by the
+ * plugin.
+ */
+
+ if ( o->o_pb && slapi_pblock_get( o->o_pb, SLAPI_RESCONTROLS, &sctrls ) != 0 ) {
+ sctrls = NULL;
+ }
+
+ if ( c == NULL && sctrls == NULL ) return 0;
+#else
if( c == NULL ) return 0;
+#endif /* LDAP_SLAPI */
rc = ber_printf( ber, "t{"/*}*/, LDAP_TAG_CONTROLS );
if( rc == -1 ) return rc;
+#ifdef LDAP_SLAPI
+ if ( c != NULL )
+#endif /* LDAP_SLAPI */
for( ; *c != NULL; c++) {
- rc = ber_printf( ber, "{s" /*}*/, (*c)->ldctl_oid );
-
- if( (*c)->ldctl_iscritical ) {
- rc = ber_printf( ber, "b",
- (ber_int_t) (*c)->ldctl_iscritical ) ;
- if( rc == -1 ) return rc;
- }
+ rc = send_ldap_control( ber, *c );
+ if( rc == -1 ) return rc;
+ }
- if( (*c)->ldctl_value.bv_val != NULL ) {
- rc = ber_printf( ber, "O", &((*c)->ldctl_value));
+#ifdef LDAP_SLAPI
+ if ( sctrls != NULL ) {
+ for ( c = sctrls; *c != NULL; c++ ) {
+ rc = send_ldap_control( ber, *c );
if( rc == -1 ) return rc;
}
-
- rc = ber_printf( ber, /*{*/"N}" );
- if( rc == -1 ) return rc;
}
+#endif /* LDAP_SLAPI */
rc = ber_printf( ber, /*{*/"N}" );
{
BerElementBuffer berbuf;
BerElement *ber = (BerElement *) &berbuf;
- int rc;
+ int rc = LDAP_SUCCESS;
long bytes;
- if (op->o_callback && op->o_callback->sc_response) {
- rc = op->o_callback->sc_response( op, rs );
- if ( rc != SLAP_CB_CONTINUE ) return;
+ if (op->o_callback) {
+ slap_callback *sc = op->o_callback;
+ rc = SLAP_CB_CONTINUE;
+ for ( ; op->o_callback; ) {
+ if ( op->o_callback->sc_response ) {
+ rc = op->o_callback->sc_response( op, rs );
+ if ( rc != SLAP_CB_CONTINUE ) break;
+ }
+ op->o_callback = op->o_callback->sc_next;
+ }
+ op->o_callback = sc;
+ if ( rc != SLAP_CB_CONTINUE ) goto cleanup;
}
-
+
#ifdef LDAP_CONNECTIONLESS
if (op->o_conn && op->o_conn->c_is_udp)
ber = op->o_res_ber;
rc = ber_printf( ber, /*"{"*/ "N}" );
}
- if( rc != -1 && rs->sr_ctrls != NULL ) {
- rc = send_ldap_controls( ber, rs->sr_ctrls );
+ if( rc != -1 ) {
+ rc = send_ldap_controls( op, ber, rs->sr_ctrls );
}
if( rc != -1 ) {
if (!op->o_conn || op->o_conn->c_is_udp == 0)
#endif
ber_free_buf( ber );
- return;
+ goto cleanup;
}
/* send BER */
0, 0, 0 );
#endif
- return;
+ goto cleanup;
}
#ifdef LDAP_SLAPI
num_bytes_sent += bytes;
num_pdu_sent++;
ldap_pvt_thread_mutex_unlock( &num_sent_mutex );
+
+cleanup:;
+ if ( rs->sr_matched && rs->sr_flags & REP_MATCHED_MUSTBEFREED ) {
+ free( (char *)rs->sr_matched );
+ rs->sr_matched = NULL;
+ }
+
+ if (op->o_callback) {
+ slap_callback *sc = op->o_callback;
+ for ( ; op->o_callback; op->o_callback = op->o_callback->sc_next ) {
+ if ( op->o_callback->sc_cleanup ) {
+ op->o_callback->sc_cleanup( op, rs );
+ }
+ }
+ op->o_callback = sc;
+ }
+
return;
}
* result if they wish to change the result.
*/
if ( op->o_pb ) {
- slapi_x_pblock_set_operation( op->o_pb, op );
+ slapi_int_pblock_set_operation( op->o_pb, op );
slapi_pblock_set( op->o_pb, SLAPI_RESULT_CODE, (void *)rs->sr_err );
slapi_pblock_set( op->o_pb, SLAPI_RESULT_TEXT, (void *)rs->sr_text );
slapi_pblock_set( op->o_pb, SLAPI_RESULT_MATCHED, (void *)rs->sr_matched );
computed_attr_context ctx;
AttributeName *anp;
#endif
- void *mark = NULL;
-
AttributeDescription *ad_entry = slap_schema.si_ad_entry;
/* a_flags: array of flags telling if the i-th element will be
char **e_flags = NULL;
rs->sr_type = REP_SEARCH;
- if (op->o_callback && op->o_callback->sc_response) {
- rc = op->o_callback->sc_response( op, rs );
- if ( rc != SLAP_CB_CONTINUE ) return rc;
+ if (op->o_callback) {
+ slap_callback *sc = op->o_callback;
+ rc = SLAP_CB_CONTINUE;
+ for ( ; op->o_callback; ) {
+ if ( op->o_callback->sc_response ) {
+ rc = op->o_callback->sc_response( op, rs );
+ if ( rc != SLAP_CB_CONTINUE ) break;
+ }
+ op->o_callback = op->o_callback->sc_next;
+ }
+ op->o_callback = sc;
+ if ( rc != SLAP_CB_CONTINUE ) goto error_return;
}
#ifdef NEW_LOGGING
op->ors_attrsonly ? " (attrsOnly)" : "", 0 );
#endif
- mark = sl_mark( op->o_tmpmemctx );
-
if ( !access_allowed( op, rs->sr_entry, ad_entry, NULL, ACL_READ, NULL )) {
#ifdef NEW_LOGGING
LDAP_LOG( ACL, INFO,
0, 0, 0 );
#endif
- sl_release( mark, op->o_tmpmemctx );
- return( 1 );
+ rc = 1;
+ goto error_return;
}
edn = rs->sr_entry->e_nname.bv_val;
if ( rs->sr_attrs != NULL ) {
for ( anp = rs->sr_attrs; anp->an_name.bv_val != NULL; anp++ ) {
rc = compute_evaluator( &ctx, anp->an_name.bv_val,
- rs->sr_entry, slapi_x_compute_output_ber );
+ rs->sr_entry, slapi_int_compute_output_ber );
if ( rc == 1 ) {
break;
}
* plugin decide whether to be naughty or not.
*/
rc = compute_evaluator( &ctx, "*",
- rs->sr_entry, slapi_x_compute_output_ber );
+ rs->sr_entry, slapi_int_compute_output_ber );
}
if ( rc == 1 ) {
if ( op->o_res_ber == NULL ) ber_free_buf( ber );
attrs_free( aa );
rc = ber_printf( ber, /*{{*/ "}N}" );
- if( rc != -1 && rs->sr_ctrls != NULL ) {
- rc = send_ldap_controls( ber, rs->sr_ctrls );
+ if( rc != -1 ) {
+ rc = send_ldap_controls( op, ber, rs->sr_ctrls );
}
if( rc != -1 ) {
if ( op->o_res_ber == NULL ) ber_free_buf( ber );
send_ldap_error( op, rs, LDAP_OTHER, "encode entry end error" );
- sl_release( mark, op->o_tmpmemctx );
- return( 1 );
+ rc = 1;
+ goto error_return;
}
if ( op->o_res_ber == NULL ) {
0, 0, 0 );
#endif
- sl_release( mark, op->o_tmpmemctx );
- return -1;
+ rc = -1;
+ goto error_return;
}
rs->sr_nentries++;
rc = 0;
error_return:;
- sl_release( mark, op->o_tmpmemctx );
+ /* FIXME: I think rs->sr_type should be explicitly set to
+ * REP_SEARCH here. That's what it was when we entered this
+ * function. send_ldap_error may have changed it, but we
+ * should set it back so that the cleanup functions know
+ * what they're doing.
+ */
+ if ( op->o_tag == LDAP_REQ_SEARCH && rs->sr_type == REP_SEARCH
+ && rs->sr_entry
+ && (rs->sr_flags & REP_ENTRY_MUSTBEFREED) )
+ {
+ entry_free( rs->sr_entry );
+ rs->sr_entry = NULL;
+ rs->sr_flags &= ~REP_ENTRY_MUSTBEFREED;
+ }
+
if ( e_flags ) sl_free( e_flags, op->o_tmpmemctx );
+
+ if (op->o_callback) {
+ slap_callback *sc = op->o_callback;
+ for ( ; op->o_callback; op->o_callback = op->o_callback->sc_next ) {
+ if ( op->o_callback->sc_cleanup ) {
+ op->o_callback->sc_cleanup( op, rs );
+ }
+ }
+ op->o_callback = sc;
+ }
return( rc );
}
BerElement *ber = (BerElement *) &berbuf;
int rc = 0;
int bytes;
- void *mark;
AttributeDescription *ad_ref = slap_schema.si_ad_ref;
AttributeDescription *ad_entry = slap_schema.si_ad_entry;
rs->sr_type = REP_SEARCHREF;
- if (op->o_callback && op->o_callback->sc_response) {
- rc = op->o_callback->sc_response( op, rs );
- if ( rc != SLAP_CB_CONTINUE ) return rc;
+ if (op->o_callback) {
+ slap_callback *sc = op->o_callback;
+ rc = SLAP_CB_CONTINUE;
+ for ( ; op->o_callback; ) {
+ if ( op->o_callback->sc_response ) {
+ rc = op->o_callback->sc_response( op, rs );
+ if ( rc != SLAP_CB_CONTINUE ) break;
+ }
+ op->o_callback = op->o_callback->sc_next;
+ }
+ op->o_callback = sc;
+ if ( rc != SLAP_CB_CONTINUE ) goto rel;
}
- mark = sl_mark( op->o_tmpmemctx );
-
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ENTRY,
"send_search_reference: conn %lu dn=\"%s\"\n",
}
if( op->o_protocol < LDAP_VERSION3 ) {
+ rc = 0;
/* save the references for the result */
if( rs->sr_ref[0].bv_val != NULL ) {
if( value_add( &rs->sr_v2ref, rs->sr_ref ) )
- return LDAP_OTHER;
+ rc = LDAP_OTHER;
}
- rc = 0;
goto rel;
}
rc = ber_printf( ber, "{it{W}" /*"}"*/ , op->o_msgid,
LDAP_RES_SEARCH_REFERENCE, rs->sr_ref );
- if( rc != -1 && rs->sr_ctrls != NULL ) {
- rc = send_ldap_controls( ber, rs->sr_ctrls );
+ if( rc != -1 ) {
+ rc = send_ldap_controls( op, ber, rs->sr_ctrls );
}
if( rc != -1 ) {
#endif
rel:
- sl_release( mark, op->o_tmpmemctx );
+ if (op->o_callback) {
+ slap_callback *sc = op->o_callback;
+ for ( ; op->o_callback; op->o_callback = op->o_callback->sc_next ) {
+ if ( op->o_callback->sc_cleanup ) {
+ op->o_callback->sc_cleanup( op, rs );
+ }
+ }
+ op->o_callback = sc;
+ }
return rc;
}