X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fresult.c;h=07b8d2d904e85903dcf497ac7bcc51e908ee5efb;hb=49b0985c88ea6836a24c314aea2cb2dd0d129544;hp=41e5eed0f0ecbd7f1ee8de9ec5ac7ba66201dc55;hpb=5094d6abda4a30b1cb42b1242260d2748de6159a;p=openldap diff --git a/servers/slapd/result.c b/servers/slapd/result.c index 41e5eed0f0..07b8d2d904 100644 --- a/servers/slapd/result.c +++ b/servers/slapd/result.c @@ -1,8 +1,27 @@ /* result.c - routines to send ldap results, errors, and referrals */ /* $OpenLDAP$ */ -/* - * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. - * COPYING RESTRICTIONS APPLY, see COPYRIGHT file +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2003 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ +/* Portions Copyright (c) 1995 Regents of the University of Michigan. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and that due credit is given + * to the University of Michigan at Ann Arbor. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. This software + * is provided ``as is'' without express or implied warranty. */ #include "portable.h" @@ -22,6 +41,11 @@ #include "slapi.h" #endif +int slap_null_cb( Operation *op, SlapReply *rs ) +{ + return 0; +} + static char *v2ref( BerVarray ref, const char *text ) { size_t len = 0, i = 0; @@ -218,19 +242,19 @@ send_ldap_controls( BerElement *ber, LDAPControl **c ) return rc; } -static void +void send_ldap_response( Operation *op, SlapReply *rs ) { - char berbuf[LBER_ELEMENT_SIZEOF]; - BerElement *ber = (BerElement *)berbuf; + BerElementBuffer berbuf; + BerElement *ber = (BerElement *) &berbuf; int rc; long bytes; if (op->o_callback && op->o_callback->sc_response) { - op->o_callback->sc_response( op, rs ); - return; + rc = op->o_callback->sc_response( op, rs ); + if ( rc != SLAP_CB_CONTINUE ) return; } #ifdef LDAP_CONNECTIONLESS @@ -240,7 +264,7 @@ send_ldap_response( #endif { ber_init_w_nullc( ber, LBER_USE_DER ); - ber_set_option( ber, LBER_OPT_BER_MEMCTX, op->o_tmpmemctx ); + ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); } #ifdef NEW_LOGGING @@ -267,14 +291,20 @@ send_ldap_response( } #ifdef LDAP_CONNECTIONLESS - if (op->o_conn && op->o_conn->c_is_udp && op->o_protocol == LDAP_VERSION2) { + if (op->o_conn && op->o_conn->c_is_udp && + op->o_protocol == LDAP_VERSION2 ) + { rc = ber_printf( ber, "t{ess" /*"}}"*/, rs->sr_tag, rs->sr_err, rs->sr_matched == NULL ? "" : rs->sr_matched, rs->sr_text == NULL ? "" : rs->sr_text ); } else #endif - { + if ( rs->sr_type == REP_INTERMEDIATE ) { + rc = ber_printf( ber, "{it{" /*"}}"*/, + rs->sr_msgid, rs->sr_tag ); + + } else { rc = ber_printf( ber, "{it{ess" /*"}}"*/, rs->sr_msgid, rs->sr_tag, rs->sr_err, rs->sr_matched == NULL ? "" : rs->sr_matched, @@ -296,7 +326,9 @@ send_ldap_response( LDAP_TAG_SASL_RES_CREDS, rs->sr_sasldata ); } - if( rc != -1 && rs->sr_type == REP_EXTENDED ) { + if( rc != -1 && + ( rs->sr_type == REP_EXTENDED || rs->sr_type == REP_INTERMEDIATE )) + { if ( rs->sr_rspoid != NULL ) { rc = ber_printf( ber, "ts", LDAP_TAG_EXOP_RES_OID, rs->sr_rspoid ); @@ -363,9 +395,11 @@ send_ldap_response( } #ifdef LDAP_SLAPI - slapi_pblock_set( op->o_pb, SLAPI_RESULT_CODE, (void *)rs->sr_err ); - slapi_pblock_set( op->o_pb, SLAPI_RESULT_MATCHED, ( rs->sr_matched != NULL ) ? (void *)ch_strdup( rs->sr_matched ) : NULL ); - slapi_pblock_set( op->o_pb, SLAPI_RESULT_TEXT, ( rs->sr_text != NULL ) ? (void *)ch_strdup( rs->sr_text ) : NULL ); + if ( op->o_pb ) { + slapi_pblock_set( op->o_pb, SLAPI_RESULT_CODE, (void *)rs->sr_err ); + slapi_pblock_set( op->o_pb, SLAPI_RESULT_MATCHED, (void *)rs->sr_matched ); + slapi_pblock_set( op->o_pb, SLAPI_RESULT_TEXT, (void *)rs->sr_text ); + } #endif /* LDAP_SLAPI */ ldap_pvt_thread_mutex_lock( &num_sent_mutex ); @@ -441,11 +475,13 @@ slap_send_ldap_result( Operation *op, SlapReply *rs ) #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ARGS, "send_ldap_result: err=%d matched=\"%s\" text=\"%s\"\n", - rs->sr_err, rs->sr_matched ? rs->sr_matched : "", rs->sr_text ? rs->sr_text : "" ); + rs->sr_err, rs->sr_matched ? rs->sr_matched : "", + rs->sr_text ? rs->sr_text : "" ); #else Debug( LDAP_DEBUG_ARGS, "send_ldap_result: err=%d matched=\"%s\" text=\"%s\"\n", - rs->sr_err, rs->sr_matched ? rs->sr_matched : "", rs->sr_text ? rs->sr_text : "" ); + rs->sr_err, rs->sr_matched ? rs->sr_matched : "", + rs->sr_text ? rs->sr_text : "" ); #endif @@ -477,6 +513,22 @@ slap_send_ldap_result( Operation *op, SlapReply *rs ) } } +#ifdef LDAP_SLAPI + /* + * Call pre-result plugins. To avoid infinite recursion plugins + * should just set SLAPI_RESULT_CODE rather than sending a + * result if they wish to change the result. + */ + if ( op->o_pb ) { + slapi_x_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 ); + + (void) doPluginFNs( op->o_bd, SLAPI_PLUGIN_PRE_RESULT_FN, op->o_pb ); + } +#endif /* LDAP_SLAPI */ + if ( op->o_protocol < LDAP_VERSION3 ) { tmp = v2ref( rs->sr_ref, rs->sr_text ); rs->sr_text = tmp; @@ -490,20 +542,21 @@ slap_send_ldap_result( Operation *op, SlapReply *rs ) if ( op->o_tag == LDAP_REQ_SEARCH ) { char nbuf[64]; - snprintf( nbuf, sizeof nbuf, "%d nentries=%d", rs->sr_err, rs->sr_nentries ); + snprintf( nbuf, sizeof nbuf, "%d nentries=%d", + rs->sr_err, rs->sr_nentries ); Statslog( LDAP_DEBUG_STATS, - "conn=%lu op=%lu SEARCH RESULT tag=%lu err=%s text=%s\n", - op->o_connid, op->o_opid, rs->sr_tag, nbuf, rs->sr_text ? rs->sr_text : "" ); + "conn=%lu op=%lu SEARCH RESULT tag=%lu err=%s text=%s\n", + op->o_connid, op->o_opid, rs->sr_tag, nbuf, + rs->sr_text ? rs->sr_text : "" ); } else { Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu RESULT tag=%lu err=%d text=%s\n", - op->o_connid, op->o_opid, rs->sr_tag, rs->sr_err, rs->sr_text ? rs->sr_text : "" ); + op->o_connid, op->o_opid, rs->sr_tag, rs->sr_err, + rs->sr_text ? rs->sr_text : "" ); } - if( tmp != NULL ) { - ch_free(tmp); - } + if( tmp != NULL ) ch_free(tmp); rs->sr_text = otext; rs->sr_ref = oref; } @@ -515,10 +568,12 @@ send_ldap_sasl( Operation *op, SlapReply *rs ) #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ENTRY, "send_ldap_sasl: conn %lu err=%d len=%lu\n", - op->o_connid, rs->sr_err, rs->sr_sasldata ? rs->sr_sasldata->bv_len : -1 ); + op->o_connid, rs->sr_err, + rs->sr_sasldata ? rs->sr_sasldata->bv_len : -1 ); #else Debug( LDAP_DEBUG_TRACE, "send_ldap_sasl: err=%d len=%ld\n", - rs->sr_err, rs->sr_sasldata ? (long) rs->sr_sasldata->bv_len : -1, NULL ); + rs->sr_err, + rs->sr_sasldata ? (long) rs->sr_sasldata->bv_len : -1, NULL ); #endif rs->sr_tag = req2res( op->o_tag ); @@ -551,11 +606,10 @@ slap_send_ldap_extended( Operation *op, SlapReply *rs ) send_ldap_response( op, rs ); } -#ifdef LDAP_RES_INTERMEDIATE_RESP void -slap_send_ldap_intermediate_resp( Operation *op, SlapReply *rs ) +slap_send_ldap_intermediate( Operation *op, SlapReply *rs ) { - rs->sr_type = REP_EXTENDED; + rs->sr_type = REP_INTERMEDIATE; #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ENTRY, "send_ldap_intermediate: err=%d oid=%s len=%ld\n", @@ -568,17 +622,16 @@ slap_send_ldap_intermediate_resp( Operation *op, SlapReply *rs ) rs->sr_rspoid ? rs->sr_rspoid : "", rs->sr_rspdata != NULL ? rs->sr_rspdata->bv_len : 0 ); #endif - rs->sr_tag = LDAP_RES_INTERMEDIATE_RESP; + rs->sr_tag = LDAP_RES_INTERMEDIATE; rs->sr_msgid = op->o_msgid; send_ldap_response( op, rs ); } -#endif int slap_send_search_entry( Operation *op, SlapReply *rs ) { - char berbuf[LBER_ELEMENT_SIZEOF]; - BerElement *ber = (BerElement *)berbuf; + BerElementBuffer berbuf; + BerElement *ber = (BerElement *) &berbuf; Attribute *a, *aa; int i, j, rc=-1, bytes; char *edn; @@ -602,23 +655,23 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) rs->sr_type = REP_SEARCH; if (op->o_callback && op->o_callback->sc_response) { - return op->o_callback->sc_response( op, rs ); + rc = op->o_callback->sc_response( op, rs ); + if ( rc != SLAP_CB_CONTINUE ) return rc; } #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ENTRY, - "send_search_entry: conn %lu dn=\"%s\"%s\n", - op->o_connid, rs->sr_entry->e_name.bv_val, op->ors_attrsonly ? " (attrsOnly)" : "" ); + LDAP_LOG( OPERATION, ENTRY, "send_search_entry: conn %lu dn=\"%s\"%s\n", + op->o_connid, rs->sr_entry->e_name.bv_val, + op->ors_attrsonly ? " (attrsOnly)" : "" ); #else - Debug( LDAP_DEBUG_TRACE, - "=> send_search_entry: dn=\"%s\"%s\n", - rs->sr_entry->e_name.bv_val, op->ors_attrsonly ? " (attrsOnly)" : "", 0 ); + Debug( LDAP_DEBUG_TRACE, "=> send_search_entry: dn=\"%s\"%s\n", + rs->sr_entry->e_name.bv_val, + 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 ) ) - { + if ( !access_allowed( op, rs->sr_entry, ad_entry, NULL, ACL_READ, NULL )) { #ifdef NEW_LOGGING LDAP_LOG( ACL, INFO, "send_search_entry: conn %lu access to entry (%s) not allowed\n", @@ -635,12 +688,10 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) edn = rs->sr_entry->e_nname.bv_val; -#ifdef LDAP_CONNECTIONLESS - if (op->o_conn && op->o_conn->c_is_udp) + if ( op->o_res_ber ) { + /* read back control or LDAP_CONNECTIONLESS */ ber = op->o_res_ber; - else -#endif - { + } else { ber_len_t siz, len; struct berval bv; @@ -649,18 +700,27 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) bv.bv_val = op->o_tmpalloc(bv.bv_len, op->o_tmpmemctx ); ber_init2( ber, &bv, LBER_USE_DER ); - ber_set_option( ber, LBER_OPT_BER_MEMCTX, op->o_tmpmemctx ); + ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); } #ifdef LDAP_CONNECTIONLESS - if (op->o_conn && op->o_conn->c_is_udp && op->o_protocol == LDAP_VERSION2) { - rc = ber_printf(ber, "t{O{" /*}}*/, - LDAP_RES_SEARCH_ENTRY, &rs->sr_entry->e_name); + if ( op->o_conn && op->o_conn->c_is_udp ) { + /* CONNECTIONLESS */ + if ( op->o_protocol == LDAP_VERSION2 ) { + rc = ber_printf(ber, "t{O{" /*}}*/, + LDAP_RES_SEARCH_ENTRY, &rs->sr_entry->e_name ); + } else { + rc = ber_printf( ber, "{it{O{" /*}}}*/, op->o_msgid, + LDAP_RES_SEARCH_ENTRY, &rs->sr_entry->e_name ); + } } else #endif - { + if ( op->o_res_ber ) { + /* read back control */ + rc = ber_printf( ber, "{O{" /*}}*/, &rs->sr_entry->e_name ); + } else { rc = ber_printf( ber, "{it{O{" /*}}}*/, op->o_msgid, - LDAP_RES_SEARCH_ENTRY, &rs->sr_entry->e_name ); + LDAP_RES_SEARCH_ENTRY, &rs->sr_entry->e_name ); } if ( rc == -1 ) { @@ -672,10 +732,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 ); #endif -#ifdef LDAP_CONNECTIONLESS - if (!op->o_conn || op->o_conn->c_is_udp == 0) -#endif - ber_free_buf( ber ); + if ( op->o_res_ber == NULL ) ber_free_buf( ber ); send_ldap_error( op, rs, LDAP_OTHER, "encoding DN error" ); goto error_return; } @@ -692,7 +749,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) * to particular value of attribute and equals 1 if value matches * to ValuesReturnFilter or 0 if not */ - if ( op->vrFilter != NULL ) { + if ( op->o_vrFilter != NULL ) { int k = 0; size_t size; @@ -720,7 +777,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) } a_flags = (char *)(e_flags + i); memset( a_flags, 0, k ); - for ( a = rs->sr_entry->e_attrs, i=0; a != NULL; a = a->a_next, i++ ) { + for ( a=rs->sr_entry->e_attrs, i=0; a != NULL; a=a->a_next, i++ ) { for ( j = 0; a->a_vals[j].bv_val != NULL; j++ ); e_flags[i] = a_flags; a_flags += j; @@ -729,18 +786,16 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) rc = filter_matched_values(op, rs->sr_entry->e_attrs, &e_flags) ; if ( rc == -1 ) { #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "send_search_entry: conn %lu matched values filtering failed\n", + LDAP_LOG( OPERATION, ERR, "send_search_entry: " + "conn %lu matched values filtering failed\n", op->o_connid ? op->o_connid : 0, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "matched values filtering failed\n", 0, 0, 0 ); #endif -#ifdef LDAP_CONNECTIONLESS - if (!op->o_conn || op->o_conn->c_is_udp == 0) -#endif - ber_free( ber, 1 ); - send_ldap_error( op, rs, LDAP_OTHER, "matched values filtering error" ); + if ( op->o_res_ber == NULL ) ber_free_buf( ber ); + send_ldap_error( op, rs, LDAP_OTHER, + "matched values filtering error" ); goto error_return; } } @@ -793,10 +848,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 ); #endif -#ifdef LDAP_CONNECTIONLESS - if (!op->o_conn || op->o_conn->c_is_udp == 0) -#endif - ber_free_buf( ber ); + if ( op->o_res_ber == NULL ) ber_free_buf( ber ); send_ldap_error( op, rs, LDAP_OTHER, "encoding description error"); goto error_return; } @@ -821,7 +873,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) continue; } - if ( op->vrFilter && e_flags[j][i] == 0 ){ + if ( op->o_vrFilter && e_flags[j][i] == 0 ){ continue; } @@ -835,11 +887,9 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) "ber_printf failed\n", 0, 0, 0 ); #endif -#ifdef LDAP_CONNECTIONLESS - if (!op->o_conn || op->o_conn->c_is_udp == 0) -#endif - ber_free_buf( ber ); - send_ldap_error( op, rs, LDAP_OTHER, "encoding values error" ); + if ( op->o_res_ber == NULL ) ber_free_buf( ber ); + send_ldap_error( op, rs, LDAP_OTHER, + "encoding values error" ); goto error_return; } } @@ -854,20 +904,17 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 ); #endif -#ifdef LDAP_CONNECTIONLESS - if (!op->o_conn || op->o_conn->c_is_udp == 0) -#endif - ber_free_buf( ber ); + if ( op->o_res_ber == NULL ) ber_free_buf( ber ); send_ldap_error( op, rs, LDAP_OTHER, "encode end error" ); goto error_return; } } /* eventually will loop through generated operational attributes */ - /* only have subschemaSubentry implemented */ + /* only have subschemaSubentry and numSubordinates are implemented */ aa = backend_operational( op, rs, opattrs ); - if ( aa != NULL && op->vrFilter != NULL ) { + if ( aa != NULL && op->o_vrFilter != NULL ) { int k = 0; size_t size; @@ -883,7 +930,8 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) * Reuse previous memory - we likely need less space * for operational attributes */ - tmp = sl_realloc( e_flags, i * sizeof(char *) + k, op->o_tmpmemctx ); + tmp = sl_realloc( e_flags, i * sizeof(char *) + k, + op->o_tmpmemctx ); if ( tmp == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, @@ -898,9 +946,9 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) "for matched values filtering\n", op->o_connid, 0, 0 ); #endif - ber_free( ber, 1 ); - - send_ldap_error( op, rs, LDAP_OTHER, "not enough memory for matched values filtering" ); + if ( op->o_res_ber == NULL ) ber_free_buf( ber ); + send_ldap_error( op, rs, LDAP_OTHER, + "not enough memory for matched values filtering" ); goto error_return; } e_flags = tmp; @@ -923,12 +971,9 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) Debug( LDAP_DEBUG_ANY, "matched values filtering failed\n", 0, 0, 0 ); #endif -#ifdef LDAP_CONNECTIONLESS - if (!op->o_conn || op->o_conn->c_is_udp == 0) -#endif - ber_free( ber, 1 ); - - send_ldap_error( op, rs, LDAP_OTHER, "matched values filtering error" ); + if ( op->o_res_ber == NULL ) ber_free_buf( ber ); + send_ldap_error( op, rs, LDAP_OTHER, + "matched values filtering error" ); goto error_return; } } @@ -950,8 +995,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) continue; } } else { - if (!userattrs && !ad_inlist( desc, rs->sr_attrs ) ) - { + if (!userattrs && !ad_inlist( desc, rs->sr_attrs ) ) { continue; } } @@ -967,8 +1011,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) op->o_connid, desc->ad_cname.bv_val, 0 ); #else Debug( LDAP_DEBUG_ACL, "send_search_entry: access to attribute %s " - "not allowed\n", - desc->ad_cname.bv_val, 0, 0 ); + "not allowed\n", desc->ad_cname.bv_val, 0, 0 ); #endif continue; @@ -984,12 +1027,8 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 ); #endif -#ifdef LDAP_CONNECTIONLESS - if (!op->o_conn || op->o_conn->c_is_udp == 0) -#endif - ber_free_buf( ber ); + if ( op->o_res_ber == NULL ) ber_free_buf( ber ); send_ldap_error( op, rs, LDAP_OTHER, "encoding description error" ); - attrs_free( aa ); goto error_return; } @@ -1014,7 +1053,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) continue; } - if ( op->vrFilter && e_flags[j][i] == 0 ){ + if ( op->o_vrFilter && e_flags[j][i] == 0 ){ continue; } @@ -1028,11 +1067,9 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) "ber_printf failed\n", 0, 0, 0 ); #endif -#ifdef LDAP_CONNECTIONLESS - if (!op->o_conn || op->o_conn->c_is_udp == 0) -#endif - ber_free_buf( ber ); - send_ldap_error( op, rs, LDAP_OTHER, "encoding values error" ); + if ( op->o_res_ber == NULL ) ber_free_buf( ber ); + send_ldap_error( op, rs, LDAP_OTHER, + "encoding values error" ); attrs_free( aa ); goto error_return; } @@ -1048,12 +1085,8 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 ); #endif -#ifdef LDAP_CONNECTIONLESS - if (!op->o_conn || op->o_conn->c_is_udp == 0) -#endif - ber_free_buf( ber ); + if ( op->o_res_ber == NULL ) ber_free_buf( ber ); send_ldap_error( op, rs, LDAP_OTHER, "encode end error" ); - attrs_free( aa ); goto error_return; } @@ -1064,36 +1097,40 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) * First, setup the computed attribute context that is * passed to all plugins. */ - ctx.cac_pb = op->o_pb; - ctx.cac_attrs = rs->sr_attrs; - ctx.cac_attrsonly = op->ors_attrsonly; - ctx.cac_userattrs = userattrs; - ctx.cac_opattrs = opattrs; - ctx.cac_acl_state = acl_state; - ctx.cac_private = (void *)ber; + if ( op->o_pb ) { + ctx.cac_pb = op->o_pb; + ctx.cac_attrs = rs->sr_attrs; + ctx.cac_attrsonly = op->ors_attrsonly; + ctx.cac_userattrs = userattrs; + ctx.cac_opattrs = opattrs; + ctx.cac_acl_state = acl_state; + ctx.cac_private = (void *)ber; - /* - * For each client requested attribute, call the plugins. - */ - 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 ); - if ( rc == 1 ) { - break; - } - } - } else { /* - * Technically we shouldn't be returning operational attributes - * when the user requested only user attributes. We'll let the - * plugin decide whether to be naughty or not. + * For each client requested attribute, call the plugins. */ - rc = compute_evaluator( &ctx, "*", rs->sr_entry, slapi_x_compute_output_ber ); - } - if ( rc == 1 ) { - ber_free_buf( ber ); - send_ldap_error( op, rs, LDAP_OTHER, "computed attribute error" ); - goto error_return; + 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 ); + if ( rc == 1 ) { + break; + } + } + } else { + /* + * Technically we shouldn't be returning operational attributes + * when the user requested only user attributes. We'll let the + * plugin decide whether to be naughty or not. + */ + rc = compute_evaluator( &ctx, "*", + rs->sr_entry, slapi_x_compute_output_ber ); + } + if ( rc == 1 ) { + if ( op->o_res_ber == NULL ) ber_free_buf( ber ); + send_ldap_error( op, rs, LDAP_OTHER, "computed attribute error" ); + goto error_return; + } } #endif /* LDAP_SLAPI */ @@ -1110,13 +1147,17 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) rc = send_ldap_controls( ber, rs->sr_ctrls ); } + if( rc != -1 ) { #ifdef LDAP_CONNECTIONLESS - if( op->o_conn && op->o_conn->c_is_udp && op->o_protocol == LDAP_VERSION2 ) { - ; /* empty, skip following if */ - } else + if( op->o_conn && op->o_conn->c_is_udp ) { + if ( op->o_protocol != LDAP_VERSION2 ) { + rc = ber_printf( ber, /*{*/ "N}" ); + } + } else #endif - if( rc != -1 ) { - rc = ber_printf( ber, /*{*/ "N}" ); + if ( op->o_res_ber == NULL ) { + rc = ber_printf( ber, /*{*/ "N}" ); + } } if ( rc == -1 ) { @@ -1128,46 +1169,38 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 ); #endif -#ifdef LDAP_CONNECTIONLESS - if (!op->o_conn || op->o_conn->c_is_udp == 0) -#endif - ber_free_buf( ber ); + 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 ); } -#ifdef LDAP_CONNECTIONLESS - if (!op->o_conn || op->o_conn->c_is_udp == 0) { -#endif - bytes = op->o_noop ? 0 : send_ldap_ber( op->o_conn, ber ); - ber_free_buf( ber ); + if ( op->o_res_ber == NULL ) { + bytes = op->o_noop ? 0 : send_ldap_ber( op->o_conn, ber ); + ber_free_buf( ber ); - if ( bytes < 0 ) { + if ( bytes < 0 ) { #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "send_search_entry: conn %lu ber write failed.\n", - op->o_connid, 0, 0 ); + LDAP_LOG( OPERATION, ERR, + "send_search_entry: conn %lu ber write failed.\n", + op->o_connid, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, - "send_search_entry: ber write failed\n", - 0, 0, 0 ); + Debug( LDAP_DEBUG_ANY, + "send_search_entry: ber write failed\n", + 0, 0, 0 ); #endif - sl_release( mark, op->o_tmpmemctx ); - return -1; - } - rs->sr_nentries++; - - ldap_pvt_thread_mutex_lock( &num_sent_mutex ); - num_bytes_sent += bytes; - num_entries_sent++; - num_pdu_sent++; - ldap_pvt_thread_mutex_unlock( &num_sent_mutex ); + sl_release( mark, op->o_tmpmemctx ); + return -1; + } + rs->sr_nentries++; -#ifdef LDAP_CONNECTIONLESS + ldap_pvt_thread_mutex_lock( &num_sent_mutex ); + num_bytes_sent += bytes; + num_entries_sent++; + num_pdu_sent++; + ldap_pvt_thread_mutex_unlock( &num_sent_mutex ); } -#endif Statslog( LDAP_DEBUG_STATS2, "conn=%lu op=%lu ENTRY dn=\"%s\"\n", op->o_connid, op->o_opid, rs->sr_entry->e_dn, 0, 0 ); @@ -1190,8 +1223,8 @@ error_return:; int slap_send_search_reference( Operation *op, SlapReply *rs ) { - char berbuf[LBER_ELEMENT_SIZEOF]; - BerElement *ber = (BerElement *)berbuf; + BerElementBuffer berbuf; + BerElement *ber = (BerElement *) &berbuf; int rc = 0; int bytes; void *mark; @@ -1201,7 +1234,8 @@ slap_send_search_reference( Operation *op, SlapReply *rs ) rs->sr_type = REP_SEARCHREF; if (op->o_callback && op->o_callback->sc_response) { - return op->o_callback->sc_response( op, rs ); + rc = op->o_callback->sc_response( op, rs ); + if ( rc != SLAP_CB_CONTINUE ) return rc; } mark = sl_mark( op->o_tmpmemctx ); @@ -1209,7 +1243,8 @@ slap_send_search_reference( Operation *op, SlapReply *rs ) #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ENTRY, "send_search_reference: conn %lu dn=\"%s\"\n", - op->o_connid, rs->sr_entry ? rs->sr_entry->e_name.bv_val : "(null)", 0 ); + op->o_connid, + rs->sr_entry ? rs->sr_entry->e_name.bv_val : "(null)", 0 ); #else Debug( LDAP_DEBUG_TRACE, "=> send_search_reference: dn=\"%s\"\n", @@ -1291,13 +1326,13 @@ slap_send_search_reference( Operation *op, SlapReply *rs ) } #ifdef LDAP_CONNECTIONLESS - if (op->o_conn && op->o_conn->c_is_udp) + if( op->o_conn && op->o_conn->c_is_udp ) { ber = op->o_res_ber; - else + } else #endif { ber_init_w_nullc( ber, LBER_USE_DER ); - ber_set_option( ber, LBER_OPT_BER_MEMCTX, op->o_tmpmemctx ); + ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); } rc = ber_printf( ber, "{it{W}" /*"}"*/ , op->o_msgid, @@ -1422,3 +1457,57 @@ str2result( return( rc ); } + +int slap_read_controls( + Operation *op, + SlapReply *rs, + Entry *e, + const struct berval *oid, + LDAPControl **ctrl ) +{ + int rc; + struct berval bv; + BerElementBuffer berbuf; + BerElement *ber = (BerElement *) &berbuf; + LDAPControl c; + ber_len_t siz, len; + Operation myop; + +#ifdef NEW_LOGGING + LDAP_LOG( OPERATION, INFO, "slap_read_controls: (%s) %s\n", + oid->bv_val, e->e_dn, 0 ); +#else + Debug( LDAP_DEBUG_ANY, "slap_read_controls: (%s) %s\n", + oid->bv_val, e->e_dn, 0 ); +#endif + + rs->sr_entry = e; + rs->sr_attrs = ( oid == &slap_pre_read_bv ) ? + op->o_preread_attrs : op->o_postread_attrs; + + entry_flatsize( rs->sr_entry, &siz, &len, 0 ); + bv.bv_len = siz + len; + bv.bv_val = op->o_tmpalloc(bv.bv_len, op->o_tmpmemctx ); + + ber_init2( ber, &bv, LBER_USE_DER ); + ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); + + /* create new operation */ + myop = *op; + myop.o_bd = NULL; + myop.o_res_ber = ber; + + rc = slap_send_search_entry( &myop, rs ); + if( rc ) return rc; + + rc = ber_flatten2( ber, &c.ldctl_value, 0 ); + + if( rc == LBER_ERROR ) return LDAP_OTHER; + + c.ldctl_oid = oid->bv_val; + c.ldctl_iscritical = 0; + + *ctrl = sl_calloc( 1, sizeof(LDAPControl), NULL ); + **ctrl = c; + return LDAP_SUCCESS; +}