+int
+send_search_reference(
+ Backend *be,
+ Connection *conn,
+ Operation *op,
+ Entry *e,
+ struct berval **refs,
+ int scope,
+ LDAPControl **ctrls,
+ struct berval ***v2refs
+)
+{
+ BerElement *ber;
+ int rc;
+ int bytes;
+
+ Debug( LDAP_DEBUG_TRACE, "=> send_search_reference (%s)\n", e->e_dn, 0, 0 );
+
+ if ( ! access_allowed( be, conn, op, e,
+ "entry", NULL, ACL_READ ) )
+ {
+ Debug( LDAP_DEBUG_ACL,
+ "send_search_reference: access to entry not allowed\n",
+ 0, 0, 0 );
+ return( 1 );
+ }
+
+ if ( ! access_allowed( be, conn, op, e,
+ "ref", NULL, ACL_READ ) )
+ {
+ Debug( LDAP_DEBUG_ACL,
+ "send_search_reference: access to reference not allowed\n",
+ 0, 0, 0 );
+ return( 1 );
+ }
+
+ if( refs == NULL ) {
+ Debug( LDAP_DEBUG_ANY,
+ "send_search_reference: null ref in (%s)\n",
+ e->e_dn, 0, 0 );
+ return( 1 );
+ }
+
+ if( op->o_protocol < LDAP_VERSION3 ) {
+ /* save the references for the result */
+ if( *refs == NULL ) {
+ value_add( v2refs, refs );
+ }
+ return 0;
+ }
+
+ ber = ber_alloc_t( LBER_USE_DER );
+
+ if ( ber == NULL ) {
+ Debug( LDAP_DEBUG_ANY,
+ "send_search_reference: ber_alloc failed\n", 0, 0, 0 );
+ send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
+ NULL, "alloc BER error", NULL, NULL );
+ return -1;
+ }
+
+ rc = ber_printf( ber, "{it{V}}", op->o_msgid,
+ LDAP_RES_SEARCH_REFERENCE, refs );
+
+ if ( rc == -1 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "send_search_reference: ber_printf failed\n", 0, 0, 0 );
+ ber_free( ber, 1 );
+ send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
+ NULL, "encode dn error", NULL, NULL );
+ return -1;
+ }
+
+ bytes = send_ldap_ber( conn, ber );
+
+ ldap_pvt_thread_mutex_lock( &num_sent_mutex );
+ num_bytes_sent += bytes;
+ num_refs_sent++;
+ num_pdu_sent++;
+ ldap_pvt_thread_mutex_unlock( &num_sent_mutex );
+
+ Statslog( LDAP_DEBUG_STATS2, "conn=%ld op=%ld ENTRY dn=\"%s\"\n",
+ (long) conn->c_connid, (long) op->o_opid, e->e_dn, 0, 0 );
+
+ Debug( LDAP_DEBUG_TRACE, "<= send_search_reference\n", 0, 0, 0 );
+
+ return 0;
+}
+
+