]> git.sur5r.net Git - openldap/commitdiff
more new API ...
authorPierangelo Masarati <ando@openldap.org>
Wed, 2 Apr 2003 22:58:02 +0000 (22:58 +0000)
committerPierangelo Masarati <ando@openldap.org>
Wed, 2 Apr 2003 22:58:02 +0000 (22:58 +0000)
servers/slapd/back-sql/bind.c
servers/slapd/back-sql/external.h
servers/slapd/back-sql/init.c
servers/slapd/back-sql/other.c
servers/slapd/back-sql/search.c

index 30c060f5c483ae022a9829ff82d685292272f2b7..b768d40dc7fe4ac494e6e68e814198a9924cfe25 100644 (file)
 #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 */
 
index a45ac6f0022340fd2447b5cd65f2c42477b63355..ced5e61156e7fb431e6bbf8a62feec26c9724c4a 100644 (file)
@@ -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;
 
index a5402355f26dd6ba349e58f08d5336f34ef617ed..1548b7e39ca4d1e9afaad238dcf2a324039e3846 100644 (file)
@@ -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;
index f0d863e6055eed015f5fbf398bdedfa7e5063ace..525c07a847aeddc4fcfcfc7b6b06155d4e0dc2dd 100644 (file)
 #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)
  */
index c5f67a8bcef411bbbe711808a276a61d84ea9640..5947d85f8bf9ba497627e6bd95e032948aa324b7 100644 (file)
@@ -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 );