-/*
- * Copyright (c) 2003 by International Business Machines, Inc.
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * International Business Machines, Inc. (hereinafter called IBM) grants
- * permission under its copyrights to use, copy, modify, and distribute this
- * Software with or without fee, provided that the above copyright notice and
- * all paragraphs of this notice appear in all copies, and that the name of IBM
- * not be used in connection with the marketing of any product incorporating
- * the Software or modifications thereof, without specific, written prior
- * permission.
+ * Copyright 1999-2003 The OpenLDAP Foundation.
+ * Portions Copyright 2003 IBM Corporation.
+ * All rights reserved.
*
- * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
- * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
- * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ * 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
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This work was initially developed by the Howard Chu for inclusion
+ * in OpenLDAP Software and subsequently enhanced by Pierangelo
+ * Masarati and Apurva Kumar.
+ */
+/* This is an altered version */
+/*
* This software is based on the backends back-ldap and back-meta, implemented
* by Howard Chu <hyc@highlandsun.com>, Mark Valence
* <kurash@sassafras.com>, Pierangelo Masarati <ando@sys-net.it> and other
#include "ldap_log.h"
#include "../../../libraries/libldap/ldap-int.h"
-#ifdef LDAP_CACHING
static Entry*
meta_create_entry(
Backend *be,
int template_id
);
-static void
+static void*
consistency_check(
- Operation *op,
- SlapReply *rs,
- Backend *glue_be
+ void *op
);
static int
SlapReply *rs
);
+
int
meta_back_cache_search(
Operation *op,
cache_manager* cm = li->cm;
query_manager* qm = cm->qm;
+ Operation *oper;
+
time_t curr_time;
int count, rc = 0, *msgid = NULL;
int num_entries = 0;
int curr_limit;
int fattr_cnt=0;
+ int oc_attr_absent = 1;
-
struct exception result[1];
Filter* filter = str2filter(op->ors_filterstr.bv_val);
cb.sc_private = op->o_bd;
if (op->ors_attrs) {
- for ( count=0; op->ors_attrs[ count ].an_name.bv_val; count++ )
- ;
- attrs = (AttributeName*)malloc( ( count + 1 ) *
- sizeof(AttributeName));
+ for ( count=0; op->ors_attrs[ count ].an_name.bv_val; count++ ) {
+ if ( op->ors_attrs[count].an_desc == slap_schema.si_ad_objectClass )
+ oc_attr_absent = 0;
+ }
+ attrs = (AttributeName*)malloc( ( count + 1 + oc_attr_absent )
+ *sizeof(AttributeName));
for ( count=0; op->ors_attrs[ count ].an_name.bv_val; count++ ) {
ber_dupbv(&attrs[ count ].an_name,
&op->ors_attrs[ count ].an_name);
Debug( LDAP_DEBUG_ANY, "Threads++ = %d\n", cm->threads, 0, 0 );
#endif /* !NEW_LOGGING */
ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
-
+
+ ldap_pvt_thread_mutex_lock(&cm->cc_mutex);
+ if (!cm->cc_thread_started) {
+ oper = (Operation*)malloc(sizeof(Operation));
+ *oper = *op;
+ cm->cc_thread_started = 1;
+ ldap_pvt_thread_create(&(cm->cc_thread), 1, consistency_check, (void*)oper);
+ }
+ ldap_pvt_thread_mutex_unlock(&cm->cc_mutex);
+
filter2template(filter, &tempstr, &filter_attrs, &fattr_cnt, result);
if (result->type != SUCCESS)
goto Catch;
}
}
+ if ( attrs && oc_attr_absent ) {
+ for ( count = 0; attrs[count].an_name.bv_val; count++) ;
+ attrs[ count ].an_name.bv_val = "objectClass";
+ attrs[ count ].an_name.bv_len = strlen( "objectClass" );
+ attrs[ count ].an_desc = slap_schema.si_ad_objectClass;
+ attrs[ count + 1 ].an_name.bv_val = NULL;
+ attrs[ count + 1 ].an_name.bv_len = 0;
+ }
+
if (answerable) {
Operation op_tmp;
op_tmp.o_req_dn = cachebase;
op_tmp.o_req_ndn = ncachebase;
- op_tmp.o_caching_on = 1;
op_tmp.o_callback = &cb;
- li->glue_be->be_search(op, rs);
- ber_memfree( ncachebase.bv_val );
+ li->glue_be->be_search(&op_tmp, rs);
+ free( ncachebase.bv_val );
if ( cachebase.bv_val != op->o_req_dn.bv_val ) {
/* free only if rewritten */
free( cachebase.bv_val );
ldap_pvt_thread_rdwr_runlock(&qm->templates[i].t_rwlock);
} else {
+ Operation op_tmp;
+ op_tmp = *op;
#ifdef NEW_LOGGING
LDAP_LOG( BACK_META, DETAIL1, "QUERY NOT ANSWERABLE\n",
0, 0, 0 );
op_type = META_OP_ALLOW_MULTIPLE;
}
- lc = metaConnect(op, rs, op_type,
+ lc = metaConnect(&op_tmp, rs, op_type,
&op->o_req_ndn, result);
if (result->type != SUCCESS)
ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
if (cacheable) {
-#ifdef NEW_LOGGING
- LDAP_LOG( BACK_META, DETAIL1,
- "QUERY TEMPLATE CACHEABLE\n",
- 0, 0, 0);
-#else /* !NEW_LOGGING */
- Debug( LDAP_DEBUG_ANY, "QUERY TEMPLATE CACHEABLE\n",
- 0, 0, 0);
-#endif /* !NEW_LOGGING */
add_filter_attrs(&new_attrs, attrs, filter_attrs);
} else {
new_attrs = attrs;
*/
msgid[ i ] = ldap_search( lsc->ld, mbase, realscope,
mapped_filter, mapped_attrs,
- op->ors_attrsonly );
+ op->ors_attrsonly );
+
if ( msgid[ i ] == -1 ) {
+ result->type = CONN_ERR;
+ goto Catch;
+ /*
lsc->candidate = META_NOT_CANDIDATE;
continue;
+ */
}
if ( mapped_attrs ) {
++candidates;
}
- num_entries = handleLdapResult(lc, op, rs, msgid,
+ num_entries = handleLdapResult(lc, &op_tmp, rs, msgid,
op->o_bd, attrs,
op->ors_attrsonly, candidates,
cacheable, &entry_array,
if (result->type != SUCCESS)
goto Catch;
if (cacheable && (num_entries <= curr_limit)) {
- Operation op_tmp = *op;
#ifdef NEW_LOGGING
LDAP_LOG( BACK_META, DETAIL1,
Debug( LDAP_DEBUG_ANY, "QUERY CACHEABLE\n", 0, 0, 0 );
#endif /* !NEW_LOGGING */
op_tmp.o_bd = li->glue_be;
- uuid = cache_entries(&op_tmp, rs, entry_array,
- cm, result);
+ uuid = cache_entries(&op_tmp, rs, entry_array, cm, result);
#ifdef NEW_LOGGING
LDAP_LOG( BACK_META, DETAIL1,
"Added query %s UUID %s ENTRIES %d\n",
goto Catch;
filter = 0;
attrs = 0;
+
+ /* FIXME : launch do_syncrepl() threads around here
+ *
+ * entryUUID and entryCSN need also to be requested by :
+ */
+ /*
+ msgid[ i ] = ldap_search( lsc->ld, mbase, realscope,
+ mapped_filter, mapped_attrs, op->ors_attrsonly );
+ */
+ /* Also, mbase, realscope, mapped_filter, mapped_attrs need
+ * be managed as arrays. Each element needs to be retained by this point.
+ */
+
+ } else {
+#ifdef NEW_LOGGING
+ LDAP_LOG( BACK_META, DETAIL1,
+ "QUERY NOT CACHEABLE no\n",
+ 0, 0, 0);
+#else /* !NEW_LOGGING */
+ Debug( LDAP_DEBUG_ANY, "QUERY NOT CACHEABLE no\n",
+ 0, 0, 0);
+#endif /* !NEW_LOGGING */
}
}
break;
}
- ldap_pvt_thread_mutex_lock(&cm->consistency_mutex);
- curr_time = slap_get_time();
- if (curr_time - cm->consistency_time > cm->consistency_cycle_time) {
- cm->consistency_time = curr_time;
- consistency_check(op, rs, li->glue_be);
- }
- ldap_pvt_thread_mutex_unlock(&cm->consistency_mutex);
if ( msgid ) {
ch_free( msgid );
struct berval a, mapped;
Entry* ent;
BerElement ber = *e->lm_ber;
- Attribute *attr, **attrp;
- struct berval dummy = { 0, NULL };
- struct berval *bv, bdn;
- const char *text;
- char* ename = NULL;
+ Attribute *attr, *soc_attr, **attrp;
+ struct berval dummy = { 0, NULL };
+ struct berval *bv, bdn;
+ const char *text = NULL;
+ char* ename = NULL;
+ struct berval sc = { 0, NULL };
+ char textbuf[SLAP_TEXT_BUFLEN];
+ size_t textlen = sizeof(textbuf);
+
if ( ber_scanf( &ber, "{m{", &bdn ) == LBER_ERROR ) {
result->type = CREATE_ENTRY_ERR;
return NULL;
attr->a_flags = 0;
attr->a_next = 0;
attr->a_desc = NULL;
+ attr->a_nvals = NULL;
if ( slap_bv2ad( &mapped, &attr->a_desc, &text ) != LDAP_SUCCESS) {
if ( slap_bv2undef_ad( &mapped, &attr->a_desc, &text )
!= LDAP_SUCCESS) {
if ( ber_scanf( &ber, "[W]", &attr->a_vals ) == LBER_ERROR
|| attr->a_vals == NULL ) {
attr->a_vals = &dummy;
+#if 0
} else if ( attr->a_desc == slap_schema.si_ad_objectClass ||
attr->a_desc ==
slap_schema.si_ad_structuralObjectClass) {
+#else
+ } else if ( attr->a_desc == slap_schema.si_ad_objectClass ) {
+#endif
int i, last;
for ( last = 0; attr->a_vals[ last ].bv_val; ++last )
;
ber_dupbv( bv, &mapped );
}
}
+
+ structural_class( attr->a_vals, &sc, NULL, &text, textbuf, textlen );
+ soc_attr = (Attribute*) ch_malloc( sizeof( Attribute ));
+ soc_attr->a_desc = slap_schema.si_ad_structuralObjectClass;
+ soc_attr->a_vals = (BerVarray) ch_malloc( 2* sizeof( BerValue ));
+ ber_dupbv( &soc_attr->a_vals[0], &sc );
+ soc_attr->a_vals[1].bv_len = 0;
+ soc_attr->a_vals[1].bv_val = NULL;
+ soc_attr->a_nvals = (BerVarray) ch_malloc( 2* sizeof( BerValue ));
+ ber_dupbv( &soc_attr->a_nvals[0], &sc );
+ soc_attr->a_nvals[1].bv_len = 0;
+ soc_attr->a_nvals[1].bv_val = NULL;
+
+ *attrp = soc_attr;
+ attrp = &soc_attr->a_next;
+
/*
* It is necessary to try to rewrite attributes with
* dn syntax because they might be used in ACLs as
*attrp = attr;
attrp = &attr->a_next;
}
+
return ent;
}
int count;
/* duplicate attrs */
- for (count=0; attrs[count].an_name.bv_val; count++)
- ;
- *new_attrs = (AttributeName*)(malloc((count+1)*sizeof(AttributeName)));
- for (i=0; i<count; i++) {
- /*
- ber_dupbv(&((*new_attrs)[i].an_name), &(attrs[i].an_name));
- */
- (*new_attrs)[i].an_name = attrs[i].an_name;
- (*new_attrs)[i].an_desc = attrs[i].an_desc;
+ if (attrs == NULL) {
+ count = 1;
+ } else {
+ for (count=0; attrs[count].an_name.bv_val; count++)
+ ;
}
- (*new_attrs)[count].an_name.bv_val = NULL;
- (*new_attrs)[count].an_name.bv_len = 0;
-
-
- if ((*new_attrs)[0].an_name.bv_val == NULL) {
- *new_attrs = (AttributeName*)(malloc(2*sizeof(AttributeName)));
+ *new_attrs = (AttributeName*)(malloc((count+1)*sizeof(AttributeName)));
+ if (attrs == NULL) {
(*new_attrs)[0].an_name.bv_val = "*";
(*new_attrs)[0].an_name.bv_len = 1;
- (*new_attrs)[1].an_name.bv_val = NULL;
+ (*new_attrs)[1].an_name.bv_val = NULL;
(*new_attrs)[1].an_name.bv_len = 0;
alluser = 1;
- count = 1;
- } else {
+ allop = 0;
+ } else {
+ for (i=0; i<count; i++) {
+ (*new_attrs)[i].an_name = attrs[i].an_name;
+ (*new_attrs)[i].an_desc = attrs[i].an_desc;
+ }
+ (*new_attrs)[count].an_name.bv_val = NULL;
+ (*new_attrs)[count].an_name.bv_len = 0;
alluser = an_find(*new_attrs, &all_user);
allop = an_find(*new_attrs, &all_op);
}
for ( i=0; filter_attrs[i].an_name.bv_val; i++ ) {
if ( an_find(*new_attrs, &filter_attrs[i].an_name ))
continue;
- if ( is_at_operational(filter_attrs[i].an_desc->ad_type)
- && allop )
- continue;
- else if (alluser)
+ if ( is_at_operational(filter_attrs[i].an_desc->ad_type) ) {
+ if (allop)
+ continue;
+ } else if (alluser)
continue;
*new_attrs = (AttributeName*)(realloc(*new_attrs,
(count+2)*sizeof(AttributeName)));
if ((entry = get_result_entry(be, lc, lsc,
msgid, i, &tv, result))) {
rs->sr_entry = entry;
+ rs->sr_attrs = op->ors_attrs;
send_search_entry( op, rs );
rs->sr_entry = NULL;
+ rs->sr_attrs = NULL;
if ((cacheable) &&
(num_entries < curr_limit)) {
rewriteSession( li->rwinfo,
AttributeName* attrs)
{
int i, count1, count2;
- if ((attrs_in==NULL) || (attrs==NULL))
- return 1;
+ if ( attrs_in == NULL ) {
+ return (attrs ? 0 : 1);
+ }
+ if ( attrs == NULL )
+ return 0;
+
for ( count1=0;
attrs_in && attrs_in[count1].an_name.bv_val != NULL;
count1++ )
return 0;
}
-static void
-consistency_check(Operation *op, SlapReply *rs, Backend* glue_be)
+static void*
+consistency_check(void* operation)
{
+ Operation* op = (Operation*)operation;
+
+ SlapReply rs = {REP_RESULT};
+
struct metainfo *li = ( struct metainfo * )op->o_bd->be_private;
cache_manager* cm = li->cm;
query_manager* qm = cm->qm;
struct exception result;
int i, return_val;
QueryTemplate* templ;
- Backend *be = op->o_bd;
- op->o_bd = glue_be;
+
+ op->o_bd = li->glue_be;
- for (i=0; qm->templates[i].querystr; i++) {
- templ = qm->templates + i;
- query = templ->query_last;
- curr_time = slap_get_time();
- ldap_pvt_thread_mutex_lock(&cm->remove_mutex);
- while (query && (query->expiry_time < curr_time)) {
- ldap_pvt_thread_mutex_lock(&qm->lru_mutex);
- remove_query(qm, query);
- ldap_pvt_thread_mutex_unlock(&qm->lru_mutex);
+ for(;;) {
+ ldap_pvt_thread_sleep(cm->cc_period);
+ for (i=0; qm->templates[i].querystr; i++) {
+ templ = qm->templates + i;
+ query = templ->query_last;
+ curr_time = slap_get_time();
+ ldap_pvt_thread_mutex_lock(&cm->remove_mutex);
+ while (query && (query->expiry_time < curr_time)) {
+ ldap_pvt_thread_mutex_lock(&qm->lru_mutex);
+ remove_query(qm, query);
+ ldap_pvt_thread_mutex_unlock(&qm->lru_mutex);
#ifdef NEW_LOGGING
- LDAP_LOG( BACK_META, DETAIL1, "Lock CR index = %d\n",
- i, 0, 0 );
+ LDAP_LOG( BACK_META, DETAIL1, "Lock CR index = %d\n",
+ i, 0, 0 );
#else /* !NEW_LOGGING */
- Debug( LDAP_DEBUG_ANY, "Lock CR index = %d\n",
- i, 0, 0 );
+ Debug( LDAP_DEBUG_ANY, "Lock CR index = %d\n",
+ i, 0, 0 );
#endif /* !NEW_LOGGING */
- ldap_pvt_thread_rdwr_wlock(&templ->t_rwlock);
- remove_from_template(query, templ);
+ ldap_pvt_thread_rdwr_wlock(&templ->t_rwlock);
+ remove_from_template(query, templ);
#ifdef NEW_LOGGING
- LDAP_LOG( BACK_META, DETAIL1,
- "TEMPLATE %d QUERIES-- %d\n",
- i, templ->no_of_queries, 0 );
+ LDAP_LOG( BACK_META, DETAIL1,
+ "TEMPLATE %d QUERIES-- %d\n",
+ i, templ->no_of_queries, 0 );
#else /* !NEW_LOGGING */
- Debug( LDAP_DEBUG_ANY, "TEMPLATE %d QUERIES-- %d\n",
- i, templ->no_of_queries, 0 );
+ Debug( LDAP_DEBUG_ANY, "TEMPLATE %d QUERIES-- %d\n",
+ i, templ->no_of_queries, 0 );
#endif /* !NEW_LOGGING */
#ifdef NEW_LOGGING
- LDAP_LOG( BACK_META, DETAIL1, "Unlock CR index = %d\n",
- i, 0, 0 );
+ LDAP_LOG( BACK_META, DETAIL1, "Unlock CR index = %d\n",
+ i, 0, 0 );
#else /* !NEW_LOGGING */
- Debug( LDAP_DEBUG_ANY, "Unlock CR index = %d\n",
- i, 0, 0 );
+ Debug( LDAP_DEBUG_ANY, "Unlock CR index = %d\n",
+ i, 0, 0 );
#endif /* !NEW_LOGGING */
- ldap_pvt_thread_rdwr_wunlock(&templ->t_rwlock);
- uuid.bv_val = query->q_uuid;
- uuid.bv_len = strlen(query->q_uuid);
- return_val = remove_query_data(op, rs, &uuid, &result);
+ ldap_pvt_thread_rdwr_wunlock(&templ->t_rwlock);
+ uuid.bv_val = query->q_uuid;
+ uuid.bv_len = strlen(query->q_uuid);
+ return_val = remove_query_data(op, &rs, &uuid, &result);
#ifdef NEW_LOGGING
- LDAP_LOG( BACK_META, DETAIL1,
- "STALE QUERY REMOVED, SIZE=%d\n",
- return_val, 0, 0 );
-#else /* !NEW_LOGGING */
- Debug( LDAP_DEBUG_ANY, "STALE QUERY REMOVED, SIZE=%d\n",
+ LDAP_LOG( BACK_META, DETAIL1,
+ "STALE QUERY REMOVED, SIZE=%d\n",
return_val, 0, 0 );
+#else /* !NEW_LOGGING */
+ Debug( LDAP_DEBUG_ANY, "STALE QUERY REMOVED, SIZE=%d\n",
+ return_val, 0, 0 );
#endif /* !NEW_LOGGING */
- ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
- cm->total_entries -= result.rc;
- cm->num_cached_queries--;
+ ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
+ cm->total_entries -= result.rc;
+ cm->num_cached_queries--;
#ifdef NEW_LOGGING
- LDAP_LOG( BACK_META, DETAIL1, "STORED QUERIES = %lu\n",
- cm->num_cached_queries, 0, 0 );
+ LDAP_LOG( BACK_META, DETAIL1, "STORED QUERIES = %lu\n",
+ cm->num_cached_queries, 0, 0 );
#else /* !NEW_LOGGING */
- Debug( LDAP_DEBUG_ANY, "STORED QUERIES = %lu\n",
- cm->num_cached_queries, 0, 0 );
+ Debug( LDAP_DEBUG_ANY, "STORED QUERIES = %lu\n",
+ cm->num_cached_queries, 0, 0 );
#endif /* !NEW_LOGGING */
- ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
- cm->cache_size = (return_val > cm->cache_size) ?
- 0: (cm->cache_size-return_val);
+ ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
+ cm->cache_size = (return_val > cm->cache_size) ?
+ 0: (cm->cache_size-return_val);
#ifdef NEW_LOGGING
- LDAP_LOG( BACK_META, DETAIL1,
- "STALE QUERY REMOVED, CACHE SIZE=%lu bytes %d "
- "entries\n", cm->cache_size,
- cm->total_entries, 0 );
+ LDAP_LOG( BACK_META, DETAIL1,
+ "STALE QUERY REMOVED, CACHE SIZE=%lu bytes %d "
+ "entries\n", cm->cache_size,
+ cm->total_entries, 0 );
#else /* !NEW_LOGGING */
- Debug( LDAP_DEBUG_ANY,
- "STALE QUERY REMOVED, CACHE SIZE=%lu bytes %d "
- "entries\n", cm->cache_size,
- cm->total_entries, 0 );
+ Debug( LDAP_DEBUG_ANY,
+ "STALE QUERY REMOVED, CACHE SIZE=%lu bytes %d "
+ "entries\n", cm->cache_size,
+ cm->total_entries, 0 );
#endif /* !NEW_LOGGING */
- query_prev = query;
- query = query->prev;
- free_query(query_prev);
+ query_prev = query;
+ query = query->prev;
+ free_query(query_prev);
+ }
+ ldap_pvt_thread_mutex_unlock(&cm->remove_mutex);
}
- ldap_pvt_thread_mutex_unlock(&cm->remove_mutex);
}
-
- op->o_bd = be;
}
static int
SlapReply *rs )
{
slap_callback *cb = op->o_callback;
- struct metainfo *li = ( struct metainfo * )op->o_bd->be_private;
+ /*struct metainfo *li = ( struct metainfo * )op->o_bd->be_private;*/
+ Backend* be = (Backend*)(cb->sc_private);
+ struct metainfo *li = ( struct metainfo * )be->be_private;
char *ename = NULL;
struct exception result;
struct berval dn;
struct berval ndn;
-
- dn = rs->sr_entry->e_name;
- ndn = rs->sr_entry->e_nname;
-
- rewriteSession( li->rwinfo, "cacheReturn",
- rs->sr_entry->e_name.bv_val, op->o_conn,
- &ename, &result );
- ber_str2bv(ename, strlen(ename), 0, &rs->sr_entry->e_name);
- /* FIXME: should we normalize this? */
- ber_dupbv(&rs->sr_entry->e_nname, &rs->sr_entry->e_name);
-
- op->o_callback = NULL;
-
- send_search_entry( op, rs );
- rs->sr_entry->e_name = dn;
- rs->sr_entry->e_nname = ndn;
-
- op->o_callback = cb;
+ if (rs->sr_type == REP_SEARCH) {
+ dn = rs->sr_entry->e_name;
+ ndn = rs->sr_entry->e_nname;
+
+ rewriteSession( li->rwinfo, "cacheReturn",
+ rs->sr_entry->e_name.bv_val, op->o_conn,
+ &ename, &result );
+ ber_str2bv(ename, strlen(ename), 0, &rs->sr_entry->e_name);
+ /* FIXME: should we normalize this? */
+ ber_dupbv(&rs->sr_entry->e_nname, &rs->sr_entry->e_name);
+
+ op->o_callback = NULL;
+
+ send_search_entry( op, rs );
+
+ rs->sr_entry->e_name = dn;
+ rs->sr_entry->e_nname = ndn;
+
+ op->o_callback = cb;
+ return LDAP_SUCCESS;
+
+ } else if (rs->sr_type == REP_RESULT) {
+ op->o_callback = NULL;
+ send_ldap_result( op, rs );
+ return LDAP_SUCCESS;
+ }
- return 0;
+ return LDAP_SUCCESS;
}
-#endif