From 09b92f0aeb8aba682cfa6e26363e0ff0f1e673b6 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Wed, 2 Apr 2003 22:58:02 +0000 Subject: [PATCH] more new API ... --- servers/slapd/back-sql/bind.c | 81 ++++++-------- servers/slapd/back-sql/external.h | 4 +- servers/slapd/back-sql/init.c | 9 +- servers/slapd/back-sql/other.c | 104 +++++++++++++++--- servers/slapd/back-sql/search.c | 175 ++++++++++++++++++------------ 5 files changed, 226 insertions(+), 147 deletions(-) diff --git a/servers/slapd/back-sql/bind.c b/servers/slapd/back-sql/bind.c index 30c060f5c4..b768d40dc7 100644 --- a/servers/slapd/back-sql/bind.c +++ b/servers/slapd/back-sql/bind.c @@ -20,17 +20,9 @@ #include "entry-id.h" int -backsql_bind( - BackendDB *be, - Connection *conn, - Operation *op, - struct berval *dn, - struct berval *ndn, - int method, - struct berval *cred, - struct berval *edn ) +backsql_bind( Operation *op, SlapReply *rs ) { - backsql_info *bi = (backsql_info*)be->be_private; + backsql_info *bi = (backsql_info*)op->o_bd->be_private; backsql_entryID user_id; SQLHDBC dbh; AttributeDescription *password = slap_schema.si_ad_userPassword; @@ -41,73 +33,74 @@ backsql_bind( Debug( LDAP_DEBUG_TRACE, "==>backsql_bind()\n", 0, 0, 0 ); - if ( be_isroot_pw( be, conn, ndn, cred ) ) { - ber_dupbv( edn, be_root_dn( be ) ); + if ( be_isroot_pw( op ) ) { + ber_dupbv( &op->oq_bind.rb_edn, be_root_dn( op->o_bd ) ); Debug( LDAP_DEBUG_TRACE, "<==backsql_bind() root bind\n", 0, 0, 0 ); - return LDAP_SUCCESS; + return 0; } - ber_dupbv( edn, ndn ); + ber_dupbv( &op->oq_bind.rb_edn, &op->o_req_ndn ); - if ( method != LDAP_AUTH_SIMPLE ) { - send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED, - NULL, "authentication method not supported", - NULL, NULL ); + if ( op->oq_bind.rb_method != LDAP_AUTH_SIMPLE ) { + rs->sr_err = LDAP_STRONG_AUTH_NOT_SUPPORTED; + rs->sr_text = "authentication method not supported"; + send_ldap_result( op, rs ); return 1; } /* * method = LDAP_AUTH_SIMPLE */ - rc = backsql_get_db_conn( be, conn, &dbh ); + rs->sr_err = backsql_get_db_conn( op->o_bd, op->o_conn, &dbh ); if (!dbh) { Debug( LDAP_DEBUG_TRACE, "backsql_bind(): " "could not get connection handle - exiting\n", 0, 0, 0 ); - send_ldap_result( conn, op, rc, "", - rc == LDAP_OTHER ? "SQL-backend error" : "", - NULL, NULL ); + + rs->sr_text = ( rs->sr_err == LDAP_OTHER ) + ? "SQL-backend error" : NULL; + send_ldap_result( op, rs ); return 1; } - if ( backsql_dn2id( bi, &user_id, dbh, ndn ) != LDAP_SUCCESS ) { + rc = backsql_dn2id( bi, &user_id, dbh, &op->o_req_ndn ); + if ( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_bind(): " "could not retrieve bind dn id - no such entry\n", 0, 0, 0 ); - send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS, - NULL, NULL, NULL, NULL ); + rs->sr_err = LDAP_INVALID_CREDENTIALS; + send_ldap_result( op, rs ); return 1; } - backsql_init_search( &bsi, bi, ndn, LDAP_SCOPE_BASE, -1, -1, -1, - NULL, dbh, be, conn, op, NULL ); + backsql_init_search( &bsi, bi, &op->o_req_ndn, LDAP_SCOPE_BASE, + -1, -1, -1, NULL, dbh, op->o_bd, op->o_conn, op, NULL ); e = backsql_id2entry( &bsi, &user_entry, &user_id ); if ( e == NULL ) { Debug( LDAP_DEBUG_TRACE, "backsql_bind(): " "error in backsql_id2entry() - auth failed\n", 0, 0, 0 ); - send_ldap_result( conn, op, LDAP_OTHER, - NULL, NULL, NULL, NULL ); + rs->sr_err = LDAP_OTHER; + send_ldap_result( op, rs ); return 1; } - if ( ! access_allowed( be, conn, op, e, password, NULL, - ACL_AUTH, NULL ) ) { - send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS, - NULL, NULL, NULL, NULL ); + if ( ! access_allowed( op, e, password, NULL, ACL_AUTH, NULL ) ) { + rs->sr_err = LDAP_INSUFFICIENT_ACCESS; + send_ldap_result( op, rs ); return 1; } if ( ( a = attr_find( e->e_attrs, password ) ) == NULL ) { - send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH, - NULL, NULL, NULL, NULL ); + rs->sr_err = LDAP_INAPPROPRIATE_AUTH; + send_ldap_result( op, rs ); return 1; } - if ( slap_passwd_check( conn, a, cred ) != 0 ) { - send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS, - NULL, NULL, NULL, NULL ); + if ( slap_passwd_check( op->o_conn, a, &op->oq_bind.rb_cred ) != 0 ) { + rs->sr_err = LDAP_INVALID_CREDENTIALS; + send_ldap_result( op, rs ); return 1; } @@ -115,17 +108,5 @@ backsql_bind( return 0; } -int -backsql_unbind( - BackendDB *be, - Connection *conn, - Operation *op ) -{ - Debug( LDAP_DEBUG_TRACE, "==>backsql_unbind()\n", 0, 0, 0 ); - send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL, NULL, 0 ); - Debug( LDAP_DEBUG_TRACE, "<==backsql_unbind()\n", 0, 0, 0 ); - return 0; -} - #endif /* SLAPD_SQL */ diff --git a/servers/slapd/back-sql/external.h b/servers/slapd/back-sql/external.h index a45ac6f002..ced5e61156 100644 --- a/servers/slapd/back-sql/external.h +++ b/servers/slapd/back-sql/external.h @@ -14,7 +14,7 @@ LDAP_BEGIN_DECL -extern BI_init sql_back_initialize; +extern BI_init sql_back_initialize; extern BI_destroy backsql_destroy; extern BI_db_init backsql_db_init; @@ -25,14 +25,12 @@ extern BI_db_destroy backsql_db_destroy; extern BI_db_config backsql_db_config; extern BI_op_bind backsql_bind; -extern BI_op_unbind backsql_unbind; extern BI_op_search backsql_search; extern BI_op_compare backsql_compare; extern BI_op_modify backsql_modify; extern BI_op_modrdn backsql_modrdn; extern BI_op_add backsql_add; extern BI_op_delete backsql_delete; -extern BI_op_abandon backsql_abandon; extern BI_operational backsql_operational; diff --git a/servers/slapd/back-sql/init.c b/servers/slapd/back-sql/init.c index a5402355f2..1548b7e39c 100644 --- a/servers/slapd/back-sql/init.c +++ b/servers/slapd/back-sql/init.c @@ -68,15 +68,10 @@ sql_back_initialize( bi->bi_db_close = backsql_db_close; bi->bi_db_destroy = backsql_db_destroy; -#ifdef BACKSQL_ALL_DONE - bi->bi_op_abandon = backsql_abandon; - bi->bi_op_compare = backsql_compare; -#else bi->bi_op_abandon = 0; - bi->bi_op_compare = 0; -#endif + bi->bi_op_compare = backsql_compare; bi->bi_op_bind = backsql_bind; - bi->bi_op_unbind = backsql_unbind; + bi->bi_op_unbind = 0; bi->bi_op_search = backsql_search; bi->bi_op_modify = backsql_modify; bi->bi_op_modrdn = backsql_modrdn; diff --git a/servers/slapd/back-sql/other.c b/servers/slapd/back-sql/other.c index f0d863e605..525c07a847 100644 --- a/servers/slapd/back-sql/other.c +++ b/servers/slapd/back-sql/other.c @@ -17,34 +17,106 @@ #include "back-sql.h" #include "sql-wrap.h" #include "entry-id.h" +#include "util.h" int -backsql_compare( +backsql_compare( Operation *op, SlapReply *rs ) + /* BackendDB *bd, Connection *conn, Operation *op, struct berval *dn, struct berval *ndn, - AttributeAssertion *ava ) + AttributeAssertion *ava ) */ { - Debug( LDAP_DEBUG_TRACE, "==>backsql_compare() - not implemented\n", + backsql_info *bi = (backsql_info*)op->o_bd->be_private; + backsql_entryID user_id; + SQLHDBC dbh; + Entry *e, user_entry; + Attribute *a; + backsql_srch_info bsi; + int rc; + AttributeName anlist[2]; + + Debug( LDAP_DEBUG_TRACE, "==>backsql_compare()\n", 0, 0, 0 ); + + rs->sr_err = backsql_get_db_conn( op->o_bd, op->o_conn, &dbh ); + if (!dbh) { + Debug( LDAP_DEBUG_TRACE, "backsql_compare(): " + "could not get connection handle - exiting\n", 0, 0, 0 ); - return 1; -} -int -backsql_abandon( - BackendDB *be, - Connection *conn, - Operation *op, - int msgid ) -{ - Debug( LDAP_DEBUG_TRACE, "==>backsql_abandon()\n", 0, 0, 0 ); - Debug( LDAP_DEBUG_TRACE, "<==backsql_abandon()\n", 0, 0, 0 ); - return 0; -} + rs->sr_text = ( rs->sr_err == LDAP_OTHER ) + ? "SQL-backend error" : NULL; + goto return_results; + } + + rc = backsql_dn2id( bi, &user_id, dbh, &op->o_req_ndn ); + if ( rc != LDAP_SUCCESS ) { + Debug( LDAP_DEBUG_TRACE, "backsql_compare(): " + "could not retrieve bind dn id - no such entry\n", + 0, 0, 0 ); + rs->sr_err = LDAP_INVALID_CREDENTIALS; + goto return_results; + } + anlist[0].an_name = op->oq_compare.rs_ava->aa_desc->ad_cname; + anlist[0].an_desc = op->oq_compare.rs_ava->aa_desc; + anlist[1].an_name.bv_val = NULL; + backsql_init_search( &bsi, bi, &op->o_req_ndn, LDAP_SCOPE_BASE, + -1, -1, -1, NULL, dbh, op->o_bd, op->o_conn, op, + anlist); + e = backsql_id2entry( &bsi, &user_entry, &user_id ); + if ( e == NULL ) { + Debug( LDAP_DEBUG_TRACE, "backsql_compare(): " + "error in backsql_id2entry() - auth failed\n", + 0, 0, 0 ); + rs->sr_err = LDAP_OTHER; + goto return_results; + } + if ( ! access_allowed( op, e, op->oq_compare.rs_ava->aa_desc, + &op->oq_compare.rs_ava->aa_value, + ACL_COMPARE, NULL ) ) { + rs->sr_err = LDAP_INSUFFICIENT_ACCESS; + goto return_results; + } + + + rs->sr_err = LDAP_NO_SUCH_ATTRIBUTE; + for ( a = attrs_find( e->e_attrs, op->oq_compare.rs_ava->aa_desc ); + a != NULL; + a = attrs_find( a->a_next, op->oq_compare.rs_ava->aa_desc )) + { + rs->sr_err = LDAP_COMPARE_FALSE; +#ifdef SLAP_NVALUES + if ( value_find_ex( op->oq_compare.rs_ava->aa_desc, + SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH | + SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH, + a->a_nvals, &op->oq_compare.rs_ava->aa_value ) == 0 ) +#else + if ( value_find( op->oq_compare.rs_ava->aa_desc, a->a_vals, &op->oq_compare.rs_ava->aa_value ) == 0 ) +#endif + { + rs->sr_err = LDAP_COMPARE_TRUE; + break; + } + } + +return_results:; + send_ldap_result( op, rs ); + + Debug(LDAP_DEBUG_TRACE,"<==backsql_compare()\n",0,0,0); + switch ( rs->sr_err ) { + case LDAP_COMPARE_TRUE: + case LDAP_COMPARE_FALSE: + return 0; + + default: + return 1; + } +} + /* * sets the supported operational attributes (if required) */ diff --git a/servers/slapd/back-sql/search.c b/servers/slapd/back-sql/search.c index c5f67a8bce..5947d85f8b 100644 --- a/servers/slapd/back-sql/search.c +++ b/servers/slapd/back-sql/search.c @@ -984,7 +984,8 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi ) } int -backsql_search( +backsql_search( Operation *op, SlapReply *rs ) + /* BackendDB *be, Connection *conn, Operation *op, @@ -997,50 +998,54 @@ backsql_search( Filter *filter, struct berval *filterstr, AttributeName *attrs, - int attrsonly ) + int attrsonly ) */ { - backsql_info *bi = (backsql_info *)be->be_private; + backsql_info *bi = (backsql_info *)op->o_bd->be_private; SQLHDBC dbh; int sres; - int nentries; Entry *entry, *res; - int manageDSAit = get_manageDSAit( op ); - BerVarray v2refs = NULL; + int manageDSAit; time_t stoptime = 0; backsql_srch_info srch_info; backsql_entryID *eid = NULL; struct slap_limits_set *limit = NULL; int isroot = 0; + manageDSAit = get_manageDSAit( op ); + Debug( LDAP_DEBUG_TRACE, "==>backsql_search(): " "base='%s', filter='%s', scope=%d,", - nbase->bv_val, filterstr->bv_val, scope ); + op->o_req_ndn.bv_val, + op->oq_search.rs_filterstr.bv_val, + op->oq_search.rs_scope ); Debug( LDAP_DEBUG_TRACE, " deref=%d, attrsonly=%d, " "attributes to load: %s\n", - deref, attrsonly, attrs == NULL ? "all" : "custom list" ); + op->oq_search.rs_deref, + op->oq_search.rs_attrsonly, + op->oq_search.rs_attrs == NULL ? "all" : "custom list" ); - if ( nbase->bv_len > BACKSQL_MAX_DN_LEN ) { + if ( op->o_req_ndn.bv_len > BACKSQL_MAX_DN_LEN ) { Debug( LDAP_DEBUG_TRACE, "backsql_search(): " "search base length (%ld) exceeds max length (%ld)\n", - nbase->bv_len, BACKSQL_MAX_DN_LEN, 0 ); + op->o_req_ndn.bv_len, BACKSQL_MAX_DN_LEN, 0 ); /* * FIXME: a LDAP_NO_SUCH_OBJECT could be appropriate * since it is impossible that such a long DN exists * in the backend */ - send_ldap_result( conn, op, LDAP_ADMINLIMIT_EXCEEDED, - "", NULL, NULL, NULL ); + rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED; + send_ldap_result( op, rs ); return 1; } - sres = backsql_get_db_conn( be, conn, &dbh ); + sres = backsql_get_db_conn( op->o_bd, op->o_conn, &dbh ); if ( sres != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_search(): " "could not get connection handle - exiting\n", 0, 0, 0 ); - send_ldap_result( conn, op, sres, "", - sres == LDAP_OTHER ? "SQL-backend error" : "", - NULL, NULL ); + rs->sr_err = sres; + rs->sr_text = sres == LDAP_OTHER ? "SQL-backend error" : NULL; + send_ldap_result( op, rs ); return 1; } @@ -1048,10 +1053,10 @@ backsql_search( srch_info.use_reverse_dn = BACKSQL_USE_REVERSE_DN( bi ); /* if not root, get appropriate limits */ - if ( be_isroot( be, &op->o_ndn ) ) { + if ( be_isroot( op->o_bd, &op->o_ndn ) ) { isroot = 1; } else { - ( void ) get_limits( be, &op->o_ndn, &limit ); + ( void ) get_limits( op->o_bd, &op->o_ndn, &limit ); } /* The time/size limits come first because they require very little @@ -1060,32 +1065,31 @@ backsql_search( /* if no time limit requested, use soft limit (unless root!) */ if ( isroot ) { - if ( tlimit == 0 ) { - tlimit = -1; /* allow root to set no limit */ + if ( op->oq_search.rs_tlimit == 0 ) { + op->oq_search.rs_tlimit = -1; /* allow root to set no limit */ } - if ( slimit == 0 ) { - slimit = -1; + if ( op->oq_search.rs_slimit == 0 ) { + op->oq_search.rs_slimit = -1; } } else { /* if no limit is required, use soft limit */ - if ( tlimit <= 0 ) { - tlimit = limit->lms_t_soft; + if ( op->oq_search.rs_tlimit <= 0 ) { + op->oq_search.rs_tlimit = limit->lms_t_soft; /* if requested limit higher than hard limit, abort */ - } else if ( tlimit > limit->lms_t_hard ) { + } else if ( op->oq_search.rs_tlimit > limit->lms_t_hard ) { /* no hard limit means use soft instead */ if ( limit->lms_t_hard == 0 && limit->lms_t_soft > -1 - && tlimit > limit->lms_t_soft ) { - tlimit = limit->lms_t_soft; + && op->oq_search.rs_tlimit > limit->lms_t_soft ) { + op->oq_search.rs_tlimit = limit->lms_t_soft; /* positive hard limit means abort */ } else if ( limit->lms_t_hard > 0 ) { - send_search_result( conn, op, - LDAP_ADMINLIMIT_EXCEEDED, - NULL, NULL, NULL, NULL, 0 ); + rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED; + send_ldap_result( op, rs ); return 0; } @@ -1093,22 +1097,21 @@ backsql_search( } /* if no limit is required, use soft limit */ - if ( slimit <= 0 ) { - slimit = limit->lms_s_soft; + if ( op->oq_search.rs_slimit <= 0 ) { + op->oq_search.rs_slimit = limit->lms_s_soft; /* if requested limit higher than hard limit, abort */ - } else if ( slimit > limit->lms_s_hard ) { + } else if ( op->oq_search.rs_slimit > limit->lms_s_hard ) { /* no hard limit means use soft instead */ if ( limit->lms_s_hard == 0 && limit->lms_s_soft > -1 - && slimit > limit->lms_s_soft ) { - slimit = limit->lms_s_soft; + && op->oq_search.rs_slimit > limit->lms_s_soft ) { + op->oq_search.rs_slimit = limit->lms_s_soft; /* positive hard limit means abort */ } else if ( limit->lms_s_hard > 0 ) { - send_search_result( conn, op, - LDAP_ADMINLIMIT_EXCEEDED, - NULL, NULL, NULL, NULL, 0 ); + rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED; + send_ldap_result( op, rs ); return 0; } @@ -1117,11 +1120,14 @@ backsql_search( } /* compute it anyway; root does not use it */ - stoptime = op->o_time + tlimit; + stoptime = op->o_time + op->oq_search.rs_tlimit; - backsql_init_search( &srch_info, bi, nbase, scope, - slimit, tlimit, stoptime, filter, dbh, - be, conn, op, attrs ); + backsql_init_search( &srch_info, bi, &op->o_req_dn, + op->oq_search.rs_scope, + op->oq_search.rs_slimit, op->oq_search.rs_tlimit, + stoptime, op->oq_search.rs_filter, + dbh, op->o_bd, op->o_conn, op, + op->oq_search.rs_attrs ); /* * for each objectclass we try to construct query which gets IDs @@ -1134,14 +1140,12 @@ backsql_search( &srch_info, BACKSQL_STOP, AVL_INORDER ); if ( !isroot && limit->lms_s_unchecked != -1 ) { if ( srch_info.n_candidates == -1 ) { - send_search_result( conn, op, - LDAP_ADMINLIMIT_EXCEEDED, - NULL, NULL, NULL, NULL, 0 ); + rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED; + send_ldap_result( op, rs ); goto done; } } - nentries = 0; /* * now we load candidate entries (only those attributes * mentioned in attrs and filter), test it against full filter @@ -1158,9 +1162,13 @@ backsql_search( } /* check time limit */ - if ( tlimit != -1 && slap_get_time() > stoptime ) { - send_search_result( conn, op, LDAP_TIMELIMIT_EXCEEDED, - NULL, NULL, v2refs, NULL, nentries ); + if ( op->oq_search.rs_tlimit != -1 && slap_get_time() > stoptime ) { + rs->sr_err = LDAP_TIMELIMIT_EXCEEDED; + rs->sr_ctrls = NULL; + rs->sr_ref = rs->sr_v2ref; + rs->sr_err = (rs->sr_v2ref == NULL) ? LDAP_SUCCESS + : LDAP_REFERRAL; + send_ldap_result( op, rs ); goto end_of_search; } @@ -1177,14 +1185,34 @@ backsql_search( continue; } - if ( !manageDSAit && scope != LDAP_SCOPE_BASE && - is_entry_referral( entry ) ) { - BerVarray refs = get_entry_referrals( be, conn, - op, entry ); + if ( !manageDSAit && + op->oq_search.rs_scope != LDAP_SCOPE_BASE && + is_entry_referral( entry ) ) { + BerVarray refs; + struct berval matched_dn; + + ber_dupbv( &matched_dn, &entry->e_name ); + refs = get_entry_referrals( op, entry ); + if ( refs ) { + rs->sr_ref = referral_rewrite( refs, + &matched_dn, &op->o_req_dn, + op->oq_search.rs_scope ); + ber_bvarray_free( refs ); + } + + if (!rs->sr_ref) { + rs->sr_text = "bad_referral object"; + } + + rs->sr_err = LDAP_REFERRAL; + rs->sr_matched = matched_dn.bv_val; + send_ldap_result( op, rs ); + + ber_bvarray_free( rs->sr_ref ); + rs->sr_ref = NULL; + ber_memfree( matched_dn.bv_val ); + rs->sr_matched = NULL; - send_search_reference( be, conn, op, entry, refs, - NULL, &v2refs ); - ber_bvarray_free( refs ); continue; } @@ -1226,10 +1254,10 @@ backsql_search( } } - if ( test_filter( be, conn, op, entry, filter ) + if ( test_filter( op, entry, op->oq_search.rs_filter ) == LDAP_COMPARE_TRUE ) { if ( hasSubordinate && !( srch_info.bsi_flags & BSQL_SF_ALL_OPER ) - && !ad_inlist( slap_schema.si_ad_hasSubordinates, attrs ) ) { + && !ad_inlist( slap_schema.si_ad_hasSubordinates, op->oq_search.rs_attrs ) ) { a->a_next = NULL; attr_free( hasSubordinate ); hasSubordinate = NULL; @@ -1240,15 +1268,14 @@ backsql_search( sres = 0; } else { #endif - sres = send_search_entry( be, conn, op, entry, - attrs, attrsonly, NULL ); + rs->sr_entry = entry; + sres = send_search_entry( op, rs ); #if 0 } #endif switch ( sres ) { case 0: - nentries++; break; case -1: @@ -1266,24 +1293,30 @@ backsql_search( } entry_free( entry ); - if ( slimit != -1 && nentries >= slimit ) { - send_search_result( conn, op, LDAP_SIZELIMIT_EXCEEDED, - NULL, NULL, v2refs, NULL, nentries ); + if ( op->oq_search.rs_slimit != -1 + && rs->sr_nentries >= op->oq_search.rs_slimit ) { + rs->sr_err = LDAP_SIZELIMIT_EXCEEDED; + send_ldap_result( op, rs ); goto end_of_search; } } end_of_search:; - if ( nentries > 0 ) { - send_search_result( conn, op, - v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL, - NULL, NULL, v2refs, NULL, nentries ); + if ( rs->sr_nentries > 0 ) { + rs->sr_ref = rs->sr_v2ref; + rs->sr_err = (rs->sr_v2ref == NULL) ? LDAP_SUCCESS + : LDAP_REFERRAL; } else { - send_ldap_result( conn, op, srch_info.status, - NULL, NULL, NULL, 0 ); + rs->sr_err = srch_info.status; } - + send_ldap_result( op, rs ); + + if ( rs->sr_v2ref ) { + ber_bvarray_free( rs->sr_v2ref ); + rs->sr_v2ref = NULL; + } + done:; ch_free( srch_info.attrs ); -- 2.39.5