2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1999-2003 The OpenLDAP Foundation.
5 * Portions Copyright 2003 IBM Corporation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
17 * This work was initially developed by the Howard Chu for inclusion
18 * in OpenLDAP Software and subsequently enhanced by Pierangelo
19 * Masarati and Apurva Kumar.
21 /* This is an altered version */
23 * This software is based on the backends back-ldap and back-meta, implemented
24 * by Howard Chu <hyc@highlandsun.com>, Mark Valence
25 * <kurash@sassafras.com>, Pierangelo Masarati <ando@sys-net.it> and other
28 * The original copyright statements follow.
29 * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
30 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
32 * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
34 * This work has been developed to fulfill the requirements
35 * of SysNet s.n.c. <http:www.sys-net.it> and it has been donated
36 * to the OpenLDAP Foundation in the hope that it may be useful
37 * to the Open Source community, but WITHOUT ANY WARRANTY.
39 * Permission is granted to anyone to use this software for any purpose
40 * on any computer system, and to alter it and redistribute it, subject
41 * to the following restrictions:
43 * 1. The author and SysNet s.n.c. are not responsible for the consequences
44 * of use of this software, no matter how awful, even if they arise from
47 * 2. The origin of this software must not be misrepresented, either by
48 * explicit claim or by omission. Since few users ever read sources,
49 * credits should appear in the documentation.
51 * 3. Altered versions must be plainly marked as such, and must not be
52 * misrepresented as being the original software. Since few users
53 * ever read sources, credits should appear in the documentation.
54 * SysNet s.n.c. cannot be responsible for the consequences of the
57 * 4. This notice may not be removed or altered.
60 * This software is based on the backend back-ldap, implemented
61 * by Howard Chu <hyc@highlandsun.com>, and modified by Mark Valence
62 * <kurash@sassafras.com>, Pierangelo Masarati <ando@sys-net.it> and other
63 * contributors. The contribution of the original software to the present
64 * implementation is acknowledged in this copyright statement.
66 * A special acknowledgement goes to Howard for the overall architecture
67 * (and for borrowing large pieces of code), and to Mark, who implemented
68 * from scratch the attribute/objectclass mapping.
70 * The original copyright statement follows.
72 * Copyright 1999, Howard Chu, All rights reserved. <hyc@highlandsun.com>
74 * Permission is granted to anyone to use this software for any purpose
75 * on any computer system, and to alter it and redistribute it, subject
76 * to the following restrictions:
78 * 1. The author is not responsible for the consequences of use of this
79 * software, no matter how awful, even if they arise from flaws in it.
81 * 2. The origin of this software must not be misrepresented, either by
82 * explicit claim or by omission. Since few users ever read sources,
83 * credits should appear in the documentation.
85 * 3. Altered versions must be plainly marked as such, and must not be
86 * misrepresented as being the original software. Since few users
87 * ever read sources, credits should appear in the
90 * 4. This notice may not be removed or altered.
97 #include <ac/socket.h>
98 #include <ac/string.h>
101 #include "ldap_pvt.h"
104 #include "../back-ldap/back-ldap.h"
105 #include "back-meta.h"
106 #undef ldap_debug /* silence a warning in ldap-int.h */
107 #include "ldap_log.h"
108 #include "../../../libraries/libldap/ldap-int.h"
116 struct exception* result
125 static struct metaconn*
130 struct berval *nbase,
131 struct exception *result
136 AttributeName** newattrs,
137 AttributeName* attrs,
138 AttributeName* filter_attrs
146 int* msgid, Backend* be,
147 AttributeName* attrs,
151 Entry*** entry_array,
154 struct exception* result
161 struct metasingleconn* lsc,
165 struct exception* result
170 struct rewrite_info* info,
171 const char* rewriteContext,
175 struct exception* result
180 AttributeName* attrs,
187 AttributeName* attrs_in,
197 struct exception* result
203 struct berval* tempstr,
221 meta_back_cache_search(
229 struct berval *nbase,
235 struct berval *filterstr,
236 AttributeName *attributes,
240 struct metainfo *li = ( struct metainfo * )op->o_bd->be_private;
242 struct metasingleconn *lsc;
243 cache_manager* cm = li->cm;
244 query_manager* qm = cm->qm;
250 int count, rc = 0, *msgid = NULL;
255 int i = -1, last = 0, candidates = 0, op_type;
257 struct berval mfilter;
258 struct berval cachebase = { 0L, NULL };
259 struct berval ncachebase = { 0L, NULL };
260 struct berval cache_suffix;
261 struct berval tempstr = { 0L, NULL };
263 AttributeName *filter_attrs = NULL;
264 AttributeName *new_attrs = NULL;
265 AttributeName *attrs = NULL;
268 Entry **entry_array = NULL;
273 int template_id = -1;
279 int oc_attr_absent = 1;
281 struct exception result[1];
283 Filter* filter = str2filter(op->ors_filterstr.bv_val);
284 slap_callback cb = {cache_back_sentry, NULL};
286 cb.sc_private = op->o_bd;
289 for ( count=0; op->ors_attrs[ count ].an_name.bv_val; count++ ) {
290 if ( op->ors_attrs[count].an_desc == slap_schema.si_ad_objectClass )
293 attrs = (AttributeName*)malloc( ( count + 1 + oc_attr_absent )
294 *sizeof(AttributeName));
295 for ( count=0; op->ors_attrs[ count ].an_name.bv_val; count++ ) {
296 ber_dupbv(&attrs[ count ].an_name,
297 &op->ors_attrs[ count ].an_name);
298 attrs[count].an_desc = op->ors_attrs[count].an_desc;
300 attrs[ count ].an_name.bv_val = NULL;
301 attrs[ count ].an_name.bv_len = 0;
304 result->type = SUCCESS;
306 ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
309 LDAP_LOG( BACK_META, DETAIL1, "Threads++ = %d\n", cm->threads, 0, 0 );
310 #else /* !NEW_LOGGING */
311 Debug( LDAP_DEBUG_ANY, "Threads++ = %d\n", cm->threads, 0, 0 );
312 #endif /* !NEW_LOGGING */
313 ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
315 ldap_pvt_thread_mutex_lock(&cm->cc_mutex);
316 if (!cm->cc_thread_started) {
317 oper = (Operation*)malloc(sizeof(Operation));
319 cm->cc_thread_started = 1;
320 ldap_pvt_thread_create(&(cm->cc_thread), 1, consistency_check, (void*)oper);
322 ldap_pvt_thread_mutex_unlock(&cm->cc_mutex);
324 filter2template(filter, &tempstr, &filter_attrs, &fattr_cnt, result);
325 if (result->type != SUCCESS)
329 LDAP_LOG( BACK_META, DETAIL1, "query template of incoming query = %s\n",
330 tempstr.bv_val, 0, 0 );
331 #else /* !NEW_LOGGING */
332 Debug( LDAP_DEBUG_ANY, "query template of incoming query = %s\n",
333 tempstr.bv_val, 0, 0 );
334 #endif /* !NEW_LOGGING */
335 curr_limit = cm->num_entries_limit ;
338 attr_set = get_attr_set(attrs, qm, cm->numattrsets);
340 query.filter = filter;
342 query.base = op->o_req_dn;
343 query.scope = op->ors_scope;
345 /* check for query containment */
347 for (i=0; i<cm->numtemplates; i++) {
348 /* find if template i can potentially answer tempstr */
349 if (!is_temp_answerable(attr_set, &tempstr, qm, i))
351 if (attr_set == qm->templates[i].attr_set_index) {
356 LDAP_LOG( BACK_META, DETAIL2,
357 "Entering QC, querystr = %s\n",
358 op->ors_filterstr.bv_val, 0, 0 );
359 #else /* !NEW_LOGGING */
360 Debug( LDAP_DEBUG_NONE, "Entering QC, querystr = %s\n",
361 op->ors_filterstr.bv_val, 0, 0 );
362 #endif /* !NEW_LOGGING */
363 answerable = (*(qm->qcfunc))(qm, &query, i);
370 if ( attrs && oc_attr_absent ) {
371 for ( count = 0; attrs[count].an_name.bv_val; count++) ;
372 attrs[ count ].an_name.bv_val = "objectClass";
373 attrs[ count ].an_name.bv_len = strlen( "objectClass" );
374 attrs[ count ].an_desc = slap_schema.si_ad_objectClass;
375 attrs[ count + 1 ].an_name.bv_val = NULL;
376 attrs[ count + 1 ].an_name.bv_len = 0;
383 LDAP_LOG( BACK_META, DETAIL1, "QUERY ANSWERABLE\n", 0, 0, 0 );
384 #else /* !NEW_LOGGING */
385 Debug( LDAP_DEBUG_ANY, "QUERY ANSWERABLE\n", 0, 0, 0 );
386 #endif /* !NEW_LOGGING */
387 rewriteSession(li->rwinfo, "cacheBase", op->o_req_dn.bv_val,
388 op->o_conn, &cbase, result);
389 if (result->type != SUCCESS) {
390 ldap_pvt_thread_rdwr_runlock(&qm->templates[i].t_rwlock);
393 if ( cbase == NULL ) {
394 cachebase = op->o_req_dn;
396 cachebase.bv_val = cbase;
397 cachebase.bv_len = strlen(cbase);
399 dnNormalize(0, NULL, NULL, &cachebase, &ncachebase,
402 /* FIXME: safe default? */
405 op_tmp.o_bd = li->glue_be;
406 op_tmp.o_req_dn = cachebase;
407 op_tmp.o_req_ndn = ncachebase;
409 op_tmp.o_callback = &cb;
411 li->glue_be->be_search(&op_tmp, rs);
412 free( ncachebase.bv_val );
413 if ( cachebase.bv_val != op->o_req_dn.bv_val ) {
414 /* free only if rewritten */
415 free( cachebase.bv_val );
418 ldap_pvt_thread_rdwr_runlock(&qm->templates[i].t_rwlock);
423 LDAP_LOG( BACK_META, DETAIL1, "QUERY NOT ANSWERABLE\n",
425 #else /* !NEW_LOGGING */
426 Debug( LDAP_DEBUG_ANY, "QUERY NOT ANSWERABLE\n", 0, 0, 0 );
427 #endif /* !NEW_LOGGING */
429 if ( op->ors_scope == LDAP_SCOPE_BASE ) {
430 op_type = META_OP_REQUIRE_SINGLE;
432 op_type = META_OP_ALLOW_MULTIPLE;
435 lc = metaConnect(&op_tmp, rs, op_type,
436 &op->o_req_ndn, result);
438 if (result->type != SUCCESS)
441 ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
442 if (cm->num_cached_queries >= cm->max_queries) {
445 ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
448 add_filter_attrs(&new_attrs, attrs, filter_attrs);
456 * Array of message id of each target
458 msgid = ch_calloc( sizeof( int ), li->ntargets );
459 if ( msgid == NULL ) {
460 result->type = CONN_ERR;
465 if (slimit > 0 && (slimit <= cm->num_entries_limit))
466 slimit = cm->num_entries_limit;
473 for ( i = 0, lsc = lc->conns; !META_LAST(lsc); ++i, ++lsc ) {
474 char *realbase = ( char * )op->o_req_dn.bv_val;
475 int realscope = op->ors_scope;
477 char *mapped_filter, **mapped_attrs;
479 /* FIXME: Check for more than one targets */
480 if ( meta_back_is_candidate(
481 &li->targets[i]->suffix,
483 lsc->candidate = META_CANDIDATE;
485 if ( lsc->candidate != META_CANDIDATE )
488 if ( op->ors_deref != -1 ) {
489 ldap_set_option( lsc->ld, LDAP_OPT_DEREF,
490 ( void * )&op->ors_deref);
492 if ( op->ors_tlimit != -1 ) {
493 ldap_set_option( lsc->ld, LDAP_OPT_TIMELIMIT,
494 ( void * )&op->ors_tlimit);
496 if ( op->ors_slimit != -1 ) {
497 ldap_set_option( lsc->ld, LDAP_OPT_SIZELIMIT,
498 ( void * )&op->ors_slimit);
502 * modifies the base according to the scope, if required
504 suffixlen = li->targets[ i ]->suffix.bv_len;
505 if ( suffixlen > op->o_req_ndn.bv_len ) {
506 switch ( op->ors_scope ) {
507 case LDAP_SCOPE_SUBTREE:
509 * make the target suffix the new base
510 * FIXME: this is very forgiving,
511 * because illegal bases may be turned
512 * into the suffix of the target.
515 &li->targets[ i ]->suffix,
518 li->targets[i]->suffix.bv_val;
521 * this target is no longer
530 case LDAP_SCOPE_ONELEVEL:
531 if ( is_one_level_rdn(
532 li->targets[ i ]->suffix.bv_val,
533 suffixlen - op->o_req_ndn.bv_len - 1 )
535 &li->targets[ i ]->suffix,
538 * if there is exactly one
539 * level, make the target suffix
540 * the new base, and make scope
544 li->targets[i]->suffix.bv_val;
545 realscope = LDAP_SCOPE_BASE;
547 } /* else continue with the next case */
549 case LDAP_SCOPE_BASE:
551 * this target is no longer candidate
553 lsc->candidate = META_NOT_CANDIDATE;
559 * Rewrite the search base, if required
562 rewriteSession(li->targets[i]->rwmap.rwm_rw,
564 realbase, op->o_conn, &mbase, result);
566 if (result->type != SUCCESS)
569 if ( mbase == NULL ) {
574 * Rewrite the search filter, if required
576 rewriteSession( li->targets[i]->rwmap.rwm_rw,
578 op->ors_filterstr.bv_val, op->o_conn,
579 &mfilter.bv_val, result);
580 if (result->type != SUCCESS)
583 if ( mfilter.bv_val != NULL && mfilter.bv_val[ 0 ]
585 mfilter.bv_len = strlen( mfilter.bv_val );
587 if ( mfilter.bv_val != NULL ) {
588 free( mfilter.bv_val );
590 mfilter = op->ors_filterstr;
595 * Maps attributes in filter
597 mapped_filter = ldap_back_map_filter(
598 &li->targets[i]->rwmap.rwm_at,
599 &li->targets[i]->rwmap.rwm_oc,
601 if ( mapped_filter == NULL ) {
602 mapped_filter = ( char * )mfilter.bv_val;
604 if ( mfilter.bv_val != op->ors_filterstr.bv_val ) {
605 free( mfilter.bv_val );
608 mfilter.bv_val = NULL;
611 mapped_filter = (char *) mfilter.bv_val;
615 * Maps required attributes
617 if ( ldap_back_map_attrs(
618 &li->targets[ i ]->rwmap.rwm_at,
619 new_attrs, 0, &mapped_attrs ) ) {
626 msgid[ i ] = ldap_search( lsc->ld, mbase, realscope,
627 mapped_filter, mapped_attrs,
630 if ( msgid[ i ] == -1 ) {
631 result->type = CONN_ERR;
634 lsc->candidate = META_NOT_CANDIDATE;
639 if ( mapped_attrs ) {
640 free( mapped_attrs );
644 if ( mapped_filter != op->ors_filterstr.bv_val ) {
645 free( mapped_filter );
646 mapped_filter = NULL;
649 if ( mbase != realbase ) {
657 num_entries = handleLdapResult(lc, &op_tmp, rs, msgid,
659 op->ors_attrsonly, candidates,
660 cacheable, &entry_array,
661 curr_limit, op->ors_slimit, result);
663 if (result->type != SUCCESS)
665 if (cacheable && (num_entries <= curr_limit)) {
668 LDAP_LOG( BACK_META, DETAIL1,
669 "QUERY CACHEABLE\n", 0, 0, 0 );
670 #else /* !NEW_LOGGING */
671 Debug( LDAP_DEBUG_ANY, "QUERY CACHEABLE\n", 0, 0, 0 );
672 #endif /* !NEW_LOGGING */
673 op_tmp.o_bd = li->glue_be;
674 uuid = cache_entries(&op_tmp, rs, entry_array, cm, result);
676 LDAP_LOG( BACK_META, DETAIL1,
677 "Added query %s UUID %s ENTRIES %d\n",
678 op->ors_filterstr.bv_val,
680 #else /* !NEW_LOGGING */
681 Debug( LDAP_DEBUG_ANY,
682 "Added query %s UUID %s ENTRIES %d\n",
683 op->ors_filterstr.bv_val,
685 #endif /* !NEW_LOGGING */
687 if (result->type != SUCCESS)
689 (*(qm->addfunc))(qm, &query, template_id, uuid, result);
690 if (result->type != SUCCESS)
695 /* FIXME : launch do_syncrepl() threads around here
697 * entryUUID and entryCSN need also to be requested by :
700 msgid[ i ] = ldap_search( lsc->ld, mbase, realscope,
701 mapped_filter, mapped_attrs, op->ors_attrsonly );
703 /* Also, mbase, realscope, mapped_filter, mapped_attrs need
704 * be managed as arrays. Each element needs to be retained by this point.
709 LDAP_LOG( BACK_META, DETAIL1,
710 "QUERY NOT CACHEABLE no\n",
712 #else /* !NEW_LOGGING */
713 Debug( LDAP_DEBUG_ANY, "QUERY NOT CACHEABLE no\n",
715 #endif /* !NEW_LOGGING */
720 switch (result->type) {
727 LDAP_LOG( BACK_META, DETAIL1,
728 "Invalid template error\n", 0, 0, 0 );
729 #else /* !NEW_LOGGING */
730 Debug( LDAP_DEBUG_ANY, "Invalid template error\n",
732 #endif /* !NEW_LOGGING */
738 LDAP_LOG( BACK_META, DETAIL1,
739 "Could not connect to a remote server\n",
741 #else /* !NEW_LOGGING */
742 Debug( LDAP_DEBUG_ANY,
743 "Could not connect to a remote server\n",
745 #endif /* !NEW_LOGGING */
746 send_ldap_error(op, rs, LDAP_OTHER,
747 "Connection error" );
753 LDAP_LOG( BACK_META, DETAIL1,
754 "Error in handling ldap_result\n", 0, 0, 0 );
755 #else /* !NEW_LOGGING */
756 Debug( LDAP_DEBUG_ANY,
757 "Error in handling ldap_result\n", 0, 0, 0 );
758 #endif /* !NEW_LOGGING */
763 if (result->rc == REWRITE_REGEXEC_UNWILLING) {
764 send_ldap_error( op, rs,
765 LDAP_UNWILLING_TO_PERFORM,
766 "Unwilling to perform" );
768 send_ldap_error( op, rs, LDAP_OTHER,
776 LDAP_LOG( BACK_META, DETAIL1,
777 "Error in merging entry \n", 0, 0, 0 );
778 #else /* !NEW_LOGGING */
779 Debug( LDAP_DEBUG_ANY,
780 "Error in merging entry \n", 0, 0, 0 );
781 #endif /* !NEW_LOGGING */
787 LDAP_LOG( BACK_META, DETAIL1,
788 "Error in removing query \n",
790 #else /* !NEW_LOGGING */
791 Debug( LDAP_DEBUG_ANY, "Error in removing query \n",
793 #endif /* !NEW_LOGGING */
806 for (i=0; (e = entry_array[i]); i++) {
815 if (new_attrs != attrs)
822 if (tempstr.bv_val ) {
823 free(tempstr.bv_val);
825 ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
828 LDAP_LOG( BACK_META, DETAIL1, "Threads-- = %d\n", cm->threads, 0, 0 );
829 #else /* !NEW_LOGGING */
830 Debug( LDAP_DEBUG_ANY, "Threads-- = %d\n", cm->threads, 0, 0 );
831 #endif /* !NEW_LOGGING */
832 ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
843 struct exception* result
846 struct metainfo *li = ( struct metainfo * )be->be_private;
847 struct berval a, mapped;
849 BerElement ber = *e->lm_ber;
850 Attribute *attr, *soc_attr, **attrp;
851 struct berval dummy = { 0, NULL };
852 struct berval *bv, bdn;
853 const char *text = NULL;
855 struct berval sc = { 0, NULL };
856 char textbuf[SLAP_TEXT_BUFLEN];
857 size_t textlen = sizeof(textbuf);
859 if ( ber_scanf( &ber, "{m{", &bdn ) == LBER_ERROR ) {
860 result->type = CREATE_ENTRY_ERR;
863 ent = (Entry*)malloc(sizeof(Entry));
866 * Rewrite the dn of the result, if needed
868 rewriteSession( li->targets[ target ]->rwmap.rwm_rw, "searchResult",
869 bdn.bv_val, lc->conn, &ent->e_name.bv_val, result );
871 if (result->type != SUCCESS) {
874 if ( ent->e_name.bv_val == NULL ) {
875 ber_dupbv(&(ent->e_name), &bdn);
878 LDAP_LOG( BACK_META, DETAIL1,
879 "[rw] searchResult[%d]: \"%s\" -> \"%s\"\n",
880 target, bdn.bv_val, ent->e_name.bv_val );
881 #else /* !NEW_LOGGING */
882 Debug( LDAP_DEBUG_ARGS, "rw> searchResult[%d]: \"%s\""
884 target, bdn.bv_val, ent->e_name.bv_val );
885 #endif /* !NEW_LOGGING */
886 ent->e_name.bv_len = strlen( ent->e_name.bv_val );
890 * Note: this may fail if the target host(s) schema differs
891 * from the one known to the meta, and a DN with unknown
892 * attributes is returned.
894 * FIXME: should we log anything, or delegate to dnNormalize?
896 dnNormalize( 0, NULL, NULL, &ent->e_name, &ent->e_nname, NULL );
899 if ( dnNormalize( 0, NULL, NULL, &ent->e_name, &ent->e_nname )
902 return LDAP_INVALID_DN_SYNTAX;
909 if ( li->cache.ttl != META_DNCACHE_DISABLED ) {
910 meta_dncache_update_entry( &li->cache, &ent->e_nname, target );
916 ent->e_bv.bv_val = 0;
918 attrp = &ent->e_attrs;
920 while ( ber_scanf( &ber, "{m", &a ) != LBER_ERROR ) {
921 ldap_back_map( &li->targets[ target ]->rwmap.rwm_at,
923 if ( mapped.bv_val == NULL ) {
926 attr = ( Attribute * )ch_malloc( sizeof( Attribute ) );
927 if ( attr == NULL ) {
933 attr->a_nvals = NULL;
934 if ( slap_bv2ad( &mapped, &attr->a_desc, &text ) != LDAP_SUCCESS) {
935 if ( slap_bv2undef_ad( &mapped, &attr->a_desc, &text )
938 LDAP_LOG( BACK_META, DETAIL1,
939 "slap_bv2undef_ad(%s): %s\n",
940 mapped.bv_val, text, 0 );
941 #else /* !NEW_LOGGING */
942 Debug( LDAP_DEBUG_ANY,
943 "slap_bv2undef_ad(%s): "
944 "%s\n%s", mapped.bv_val, text, "" );
945 #endif /* !NEW_LOGGING */
951 /* no subschemaSubentry */
952 if ( attr->a_desc == slap_schema.si_ad_subschemaSubentry ) {
957 if ( ber_scanf( &ber, "[W]", &attr->a_vals ) == LBER_ERROR
958 || attr->a_vals == NULL ) {
959 attr->a_vals = &dummy;
961 } else if ( attr->a_desc == slap_schema.si_ad_objectClass ||
963 slap_schema.si_ad_structuralObjectClass) {
965 } else if ( attr->a_desc == slap_schema.si_ad_objectClass ) {
968 for ( last = 0; attr->a_vals[ last ].bv_val; ++last )
970 for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++,i++ ) {
971 ldap_back_map( &li->targets[ target]->rwmap.rwm_oc,
973 if ( mapped.bv_val == NULL ) {
979 *bv = attr->a_vals[ last ];
980 attr->a_vals[ last ].bv_val = NULL;
982 } else if ( mapped.bv_val != bv->bv_val ) {
984 ber_dupbv( bv, &mapped );
988 structural_class( attr->a_vals, &sc, NULL, &text, textbuf, textlen );
989 soc_attr = (Attribute*) ch_malloc( sizeof( Attribute ));
990 soc_attr->a_desc = slap_schema.si_ad_structuralObjectClass;
991 soc_attr->a_vals = (BerVarray) ch_malloc( 2* sizeof( BerValue ));
992 ber_dupbv( &soc_attr->a_vals[0], &sc );
993 soc_attr->a_vals[1].bv_len = 0;
994 soc_attr->a_vals[1].bv_val = NULL;
995 soc_attr->a_nvals = (BerVarray) ch_malloc( 2* sizeof( BerValue ));
996 ber_dupbv( &soc_attr->a_nvals[0], &sc );
997 soc_attr->a_nvals[1].bv_len = 0;
998 soc_attr->a_nvals[1].bv_val = NULL;
1001 attrp = &soc_attr->a_next;
1004 * It is necessary to try to rewrite attributes with
1005 * dn syntax because they might be used in ACLs as
1006 * members of groups; since ACLs are applied to the
1007 * rewritten stuff, no dn-based subecj clause could
1008 * be used at the ldap backend side (see
1009 * http://www.OpenLDAP.org/faq/data/cache/452.html)
1010 * The problem can be overcome by moving the dn-based
1011 * ACLs to the target directory server, and letting
1012 * everything pass thru the ldap backend.
1014 } else if ( strcmp( attr->a_desc->ad_type->sat_syntax->ssyn_oid,
1015 SLAPD_DN_SYNTAX ) == 0 ) {
1017 for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++,i++ ) {
1019 rewriteSession(li->targets[ target ]->rwmap.rwm_rw,
1020 "searchResult", bv->bv_val,
1021 lc->conn, &newval, result);
1022 if (result->type != SUCCESS) {
1023 /* FIXME : Handle error */
1024 result->type = SUCCESS;
1027 if ( newval == NULL ) {
1031 LDAP_LOG( BACK_META, DETAIL1,
1032 "[rw] searchResult on "
1033 "attr=%s: \"%s\" -> \"%s\"\n",
1034 attr->a_desc->ad_type->
1036 bv->bv_val, newval );
1037 #else /* !NEW_LOGGING */
1038 Debug( LDAP_DEBUG_ARGS,
1039 "rw> searchResult on attr=%s:"
1040 " \"%s\" -> \"%s\"\n",
1041 attr->a_desc->ad_type->
1043 bv->bv_val, newval );
1044 #endif /* !NEW_LOGGING */
1046 bv->bv_val = newval;
1047 bv->bv_len = strlen( newval );
1052 attrp = &attr->a_next;
1065 if ( DN_SEPARATOR( rdn[ from ] ) ) {
1072 static struct metaconn*
1077 struct berval *nbase,
1078 struct exception *result)
1080 struct metaconn *lc;
1082 result->type = SUCCESS;
1083 lc = meta_back_getconn( op, rs, op_type, nbase, NULL );
1085 result->type = CONN_ERR;
1093 AttributeName** new_attrs,
1094 AttributeName* attrs,
1095 AttributeName* filter_attrs )
1097 struct berval all_user = { sizeof(LDAP_ALL_USER_ATTRIBUTES) -1,
1098 LDAP_ALL_USER_ATTRIBUTES };
1100 struct berval all_op = { sizeof(LDAP_ALL_OPERATIONAL_ATTRIBUTES) -1,
1101 LDAP_ALL_OPERATIONAL_ATTRIBUTES};
1108 /* duplicate attrs */
1109 if (attrs == NULL) {
1112 for (count=0; attrs[count].an_name.bv_val; count++)
1115 *new_attrs = (AttributeName*)(malloc((count+1)*sizeof(AttributeName)));
1116 if (attrs == NULL) {
1117 (*new_attrs)[0].an_name.bv_val = "*";
1118 (*new_attrs)[0].an_name.bv_len = 1;
1119 (*new_attrs)[1].an_name.bv_val = NULL;
1120 (*new_attrs)[1].an_name.bv_len = 0;
1124 for (i=0; i<count; i++) {
1125 (*new_attrs)[i].an_name = attrs[i].an_name;
1126 (*new_attrs)[i].an_desc = attrs[i].an_desc;
1128 (*new_attrs)[count].an_name.bv_val = NULL;
1129 (*new_attrs)[count].an_name.bv_len = 0;
1130 alluser = an_find(*new_attrs, &all_user);
1131 allop = an_find(*new_attrs, &all_op);
1134 for ( i=0; filter_attrs[i].an_name.bv_val; i++ ) {
1135 if ( an_find(*new_attrs, &filter_attrs[i].an_name ))
1137 if ( is_at_operational(filter_attrs[i].an_desc->ad_type) ) {
1142 *new_attrs = (AttributeName*)(realloc(*new_attrs,
1143 (count+2)*sizeof(AttributeName)));
1144 (*new_attrs)[count].an_name.bv_val =
1145 filter_attrs[i].an_name.bv_val;
1146 (*new_attrs)[count].an_name.bv_len =
1147 filter_attrs[i].an_name.bv_len;
1148 (*new_attrs)[count].an_desc = filter_attrs[i].an_desc;
1149 (*new_attrs)[count+1].an_name.bv_val = NULL;
1150 (*new_attrs)[count+1].an_name.bv_len = 0;
1157 struct metaconn* lc,
1160 int* msgid, Backend* be,
1161 AttributeName* attrs,
1165 Entry*** entry_array,
1168 struct exception* result)
1171 char *match = NULL, *err = NULL, *cache_ename = NULL;
1173 int mres = LDAP_SUCCESS;
1174 int num_entries = 0, count, i, rc;
1175 struct timeval tv = {0, 0};
1176 struct metasingleconn* lsc;
1177 struct metainfo *li = ( struct metainfo * )be->be_private;
1179 result->type = SUCCESS;
1181 for ( count = 0, rc = 0; candidates > 0; ) {
1184 /* check for abandon */
1187 for ( i = 0, lsc = lc->conns; !META_LAST(lsc); lsc++, i++ ) {
1188 if ( lsc->candidate != META_CANDIDATE ) {
1193 ldap_abandon( lsc->ld, msgid[ i ] );
1194 result->type = ABANDON_ERR;
1198 if ( slimit > 0 && num_entries == slimit ) {
1199 result->type = SLIMIT_ERR;
1203 if ((entry = get_result_entry(be, lc, lsc,
1204 msgid, i, &tv, result))) {
1205 rs->sr_entry = entry;
1206 rs->sr_attrs = op->ors_attrs;
1207 send_search_entry( op, rs );
1208 rs->sr_entry = NULL;
1209 rs->sr_attrs = NULL;
1211 (num_entries < curr_limit)) {
1212 rewriteSession( li->rwinfo,
1214 entry->e_name.bv_val,
1216 &cache_ename, result );
1217 free(entry->e_name.bv_val);
1218 if (result->type != SUCCESS) {
1221 ber_str2bv(cache_ename,
1222 strlen(cache_ename),
1224 ber_dupbv(&entry->e_nname,
1226 *entry_array = (Entry**)realloc(
1228 (( num_entries+2 ) *
1230 (*entry_array)[num_entries] = entry;
1231 (*entry_array)[num_entries+1] = NULL;
1235 } else if (result->type == REWRITING_ERR) {
1237 } else if (result->type == TIMEOUT_ERR) {
1238 result->type = SUCCESS;
1240 } else if (result->type == CREATE_ENTRY_ERR) {
1242 } else if (result->rc == -1) {
1245 rs->sr_err = result->rc;
1246 sres = ldap_back_map_result(rs);
1247 if (mres == LDAP_SUCCESS &&
1248 sres != LDAP_SUCCESS) {
1250 ldap_get_option(lsc->ld,
1251 LDAP_OPT_ERROR_STRING, &err);
1252 ldap_get_option(lsc->ld,
1253 LDAP_OPT_MATCHED_DN, &match);
1255 lsc->candidate = META_NOT_CANDIDATE;
1257 result->type = SUCCESS;
1260 switch (result->type) {
1263 LDAP_LOG( BACK_META, DETAIL1,
1264 "ldap_result error, rc = -1\n",
1266 #else /* !NEW_LOGGING */
1267 Debug( LDAP_DEBUG_ANY, "ldap_result error, rc = -1\n",
1269 #endif /* !NEW_LOGGING */
1270 rs->sr_err = LDAP_OTHER;
1271 send_ldap_result( op, rs );
1274 case CREATE_ENTRY_ERR:
1276 LDAP_LOG( BACK_META, DETAIL1,
1277 "Error in parsing result \n",
1279 #else /* !NEW_LOGGING */
1280 Debug( LDAP_DEBUG_ANY, "Error in parsing result \n",
1282 #endif /* !NEW_LOGGING */
1283 rs->sr_err = LDAP_OTHER;
1284 send_ldap_result( op, rs );
1285 result->type = RESULT_ERR;
1290 LDAP_LOG( BACK_META, DETAIL1, "Size limit exceeded \n",
1292 #else /* !NEW_LOGGING */
1293 Debug( LDAP_DEBUG_ANY, "Size limit exceeded \n",
1295 #endif /* !NEW_LOGGING */
1296 rs->sr_err = LDAP_SIZELIMIT_EXCEEDED;
1297 send_ldap_result( op, rs );
1298 result->type = RESULT_ERR;
1303 LDAP_LOG( BACK_META, DETAIL1,
1304 "search operation abandoned \n",
1306 #else /* !NEW_LOGGING */
1307 Debug( LDAP_DEBUG_ANY, "search operation abandoned \n",
1309 #endif /* !NEW_LOGGING */
1310 result->type = RESULT_ERR;
1319 tv.tv_usec = 100000;
1320 ldap_pvt_thread_yield();
1329 rs->sr_matched = match;
1331 send_ldap_result( op, rs );
1334 rs->sr_matched = NULL;
1342 result->type = (mres == LDAP_SUCCESS) ? SUCCESS : RESULT_ERR;
1349 struct metaconn* lc,
1350 struct metasingleconn* lsc,
1354 struct exception* result)
1357 LDAPMessage *res, *e;
1359 int sres = LDAP_SUCCESS;
1361 rc = ldap_result( lsc->ld, msgid[ i ],
1365 result->type = TIMEOUT_ERR;
1367 } else if ( rc == -1 ) {
1369 result->type = RESULT_ERR;
1371 } else if ( rc == LDAP_RES_SEARCH_ENTRY ) {
1372 e = ldap_first_entry( lsc->ld, res );
1373 entry = meta_create_entry(be, lc, i, e, result);
1377 ldap_msgfree( res );
1378 result->type = SUCCESS;
1381 sres = ldap_result2error( lsc->ld,
1384 result->type = RESULT_ERR;
1391 struct rewrite_info* info,
1392 const char* rewriteContext,
1396 struct exception* result)
1398 int rc = rewrite_session(info, rewriteContext, string, cookie, base);
1399 if (rc != REWRITE_REGEXEC_OK) {
1401 result->type = REWRITING_ERR;
1403 if (strcmp(rewriteContext, "searchBase") == 0)
1405 LDAP_LOG( BACK_META, DETAIL1,
1406 "Problem in rewriting search base\n", 0, 0, 0 );
1407 #else /* !NEW_LOGGING */
1408 Debug( LDAP_DEBUG_ANY,
1409 "Problem in rewriting search base\n", 0, 0, 0 );
1410 #endif /* !NEW_LOGGING */
1411 if (strcmp(rewriteContext, "searchFilter") == 0)
1413 LDAP_LOG( BACK_META, DETAIL1,
1414 "Problem in rewriting search filter\n",
1416 #else /* !NEW_LOGGING */
1417 Debug( LDAP_DEBUG_ANY,
1418 "Problem in rewriting search filter\n",
1420 #endif /* !NEW_LOGGING */
1421 if (strcmp(rewriteContext, "searchResult") == 0)
1423 LDAP_LOG( BACK_META, DETAIL1,
1424 "Problem in rewriting DN, or DN syntax "
1425 "attributes of search result\n", 0, 0, 0 );
1426 #else /* !NEW_LOGGING */
1427 Debug( LDAP_DEBUG_ANY,
1428 "Problem in rewriting DN, or DN syntax "
1429 "attributes of search result\n", 0, 0, 0 );
1430 #endif /* !NEW_LOGGING */
1431 if (strcmp(rewriteContext, "cacheBase") == 0)
1433 LDAP_LOG( BACK_META, DETAIL1,
1434 "Problem in rewriting search base with "
1435 "cache base\n", 0, 0, 0 );
1436 #else /* !NEW_LOGGING */
1437 Debug( LDAP_DEBUG_ANY,
1438 "Problem in rewriting search base with "
1439 "cache base\n", 0, 0, 0 );
1440 #endif /* !NEW_LOGGING */
1441 if (strcmp(rewriteContext, "cacheResult") == 0)
1443 LDAP_LOG( BACK_META, DETAIL1,
1444 "Problem in rewriting DN for cached entries\n",
1446 #else /* !NEW_LOGGING */
1447 Debug( LDAP_DEBUG_ANY,
1448 "Problem in rewriting DN for cached entries\n",
1450 #endif /* !NEW_LOGGING */
1451 if (strcmp(rewriteContext, "cacheReturn") == 0)
1453 LDAP_LOG( BACK_META, DETAIL1,
1454 "Problem in rewriting DN for answerable "
1455 "entries\n", 0, 0, 0 );
1456 #else /* !NEW_LOGGING */
1457 Debug( LDAP_DEBUG_ANY,
1458 "Problem in rewriting DN for answerable "
1459 "entries\n", 0, 0, 0 );
1460 #endif /* !NEW_LOGGING */
1462 result->type = SUCCESS;
1468 AttributeName* attrs,
1473 for (i=0; i<num; i++) {
1474 if (attrscmp(attrs, qm->attr_sets[i].attrs))
1482 AttributeName* attrs_in,
1483 AttributeName* attrs)
1485 int i, count1, count2;
1486 if ( attrs_in == NULL ) {
1487 return (attrs ? 0 : 1);
1489 if ( attrs == NULL )
1493 attrs_in && attrs_in[count1].an_name.bv_val != NULL;
1497 attrs && attrs[count2].an_name.bv_val != NULL;
1500 if ( count1 != count2 )
1503 for ( i=0; i<count1; i++ ) {
1504 if ( !an_find(attrs, &attrs_in[i].an_name ))
1514 Entry** entry_array,
1516 struct exception* result)
1522 struct berval query_uuid;
1523 struct berval crp_uuid;
1524 char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ], *crpid;
1526 query_manager *qm = cm->qm;
1528 result->type = SUCCESS;
1529 query_uuid.bv_len = lutil_uuidstr(uuidbuf, sizeof(uuidbuf));
1530 query_uuid.bv_val = ch_strdup(uuidbuf);
1533 LDAP_LOG( BACK_META, DETAIL1, "UUID for query being added = %s\n",
1535 #else /* !NEW_LOGGING */
1536 Debug( LDAP_DEBUG_ANY, "UUID for query being added = %s\n",
1538 #endif /* !NEW_LOGGING */
1540 for ( i=0; ( entry_array && (e=entry_array[i]) ); i++ ) {
1542 LDAP_LOG( BACK_META, DETAIL2, "LOCKING REMOVE MUTEX\n",
1544 #else /* !NEW_LOGGING */
1545 Debug( LDAP_DEBUG_NONE, "LOCKING REMOVE MUTEX\n", 0, 0, 0 );
1546 #endif /* !NEW_LOGGING */
1547 ldap_pvt_thread_mutex_lock(&cm->remove_mutex);
1549 LDAP_LOG( BACK_META, DETAIL2, "LOCKED REMOVE MUTEX\n", 0, 0, 0);
1550 #else /* !NEW_LOGGING */
1551 Debug( LDAP_DEBUG_NONE, "LOCKED REMOVE MUTEX\n", 0, 0, 0);
1552 #endif /* !NEW_LOGGING */
1553 if ( cm->cache_size > (cm->thresh_hi) ) {
1554 while(cm->cache_size > (cm->thresh_lo)) {
1555 crpid = cache_replacement(qm);
1556 if (crpid == NULL) {
1557 result->type = REMOVE_ERR;
1559 strcpy(crpuuid, crpid);
1560 crp_uuid.bv_val = crpuuid;
1561 crp_uuid.bv_len = strlen(crpuuid);
1563 LDAP_LOG( BACK_META, DETAIL1,
1564 "Removing query UUID %s\n",
1566 #else /* !NEW_LOGGING */
1567 Debug( LDAP_DEBUG_ANY,
1568 "Removing query UUID %s\n",
1570 #endif /* !NEW_LOGGING */
1571 return_val = remove_query_data(op, rs,
1574 LDAP_LOG( BACK_META, DETAIL1,
1575 "QUERY REMOVED, SIZE=%d\n",
1577 #else /* !NEW_LOGGING */
1578 Debug( LDAP_DEBUG_ANY,
1579 "QUERY REMOVED, SIZE=%d\n",
1581 #endif /* !NEW_LOGGING */
1582 ldap_pvt_thread_mutex_lock(
1584 cm->total_entries -= result->rc;
1585 cm->num_cached_queries--;
1587 LDAP_LOG( BACK_META, DETAIL1,
1588 "STORED QUERIES = %lu\n",
1589 cm->num_cached_queries, 0, 0 );
1590 #else /* !NEW_LOGGING */
1591 Debug( LDAP_DEBUG_ANY,
1592 "STORED QUERIES = %lu\n",
1593 cm->num_cached_queries, 0, 0 );
1594 #endif /* !NEW_LOGGING */
1595 ldap_pvt_thread_mutex_unlock(
1597 cm->cache_size = (return_val >
1599 0 : (cm->cache_size-return_val);
1601 LDAP_LOG( BACK_META, DETAIL1,
1602 "QUERY REMOVED, CACHE SIZE="
1603 "%lu bytes %d entries\n",
1605 cm->total_entries, 0 );
1606 #else /* !NEW_LOGGING */
1607 Debug( LDAP_DEBUG_ANY,
1608 "QUERY REMOVED, CACHE SIZE="
1609 "%lu bytes %d entries\n",
1611 cm->total_entries, 0 );
1612 #endif /* !NEW_LOGGING */
1618 return_val = merge_entry(op, rs, &query_uuid, result);
1619 rs->sr_entry = NULL;
1620 cm->cache_size += return_val;
1622 LDAP_LOG( BACK_META, DETAIL1,
1623 "ENTRY ADDED/MERGED, CACHE SIZE=%lu bytes\n",
1624 cm->cache_size, 0, 0 );
1625 #else /* !NEW_LOGGING */
1626 Debug( LDAP_DEBUG_ANY,
1627 "ENTRY ADDED/MERGED, CACHE SIZE=%lu bytes\n",
1628 cm->cache_size, 0, 0 );
1629 #endif /* !NEW_LOGGING */
1631 LDAP_LOG( BACK_META, DETAIL2, "UNLOCKING REMOVE MUTEX\n",
1633 #else /* !NEW_LOGGING */
1634 Debug( LDAP_DEBUG_NONE, "UNLOCKING REMOVE MUTEX\n", 0, 0, 0 );
1635 #endif /* !NEW_LOGGING */
1636 ldap_pvt_thread_mutex_unlock(&cm->remove_mutex);
1638 LDAP_LOG( BACK_META, DETAIL2, "UNLOCKED REMOVE MUTEX\n",
1640 #else /* !NEW_LOGGING */
1641 Debug( LDAP_DEBUG_NONE, "UNLOCKED REMOVE MUTEX\n", 0, 0, 0 );
1642 #endif /* !NEW_LOGGING */
1643 if (result->type != SUCCESS)
1645 ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
1646 cm->total_entries += result->rc;
1648 LDAP_LOG( BACK_META, DETAIL1,
1649 "ENTRY ADDED/MERGED, SIZE=%d, CACHED ENTRIES=%d\n",
1650 return_val, cm->total_entries, 0 );
1651 #else /* !NEW_LOGGING */
1652 Debug( LDAP_DEBUG_ANY,
1653 "ENTRY ADDED/MERGED, SIZE=%d, CACHED ENTRIES=%d\n",
1654 return_val, cm->total_entries, 0 );
1655 #endif /* !NEW_LOGGING */
1656 ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
1658 ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
1659 cm->num_cached_queries++;
1661 LDAP_LOG( BACK_META, DETAIL1, "STORED QUERIES = %lu\n",
1662 cm->num_cached_queries, 0, 0 );
1663 #else /* !NEW_LOGGING */
1664 Debug( LDAP_DEBUG_ANY, "STORED QUERIES = %lu\n",
1665 cm->num_cached_queries, 0, 0 );
1666 #endif /* !NEW_LOGGING */
1667 ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
1669 return query_uuid.bv_val;
1675 struct berval* tempstr,
1683 i = qm->templates[template_id].attr_set_index;
1684 str = qm->templates[template_id].querystr;
1686 if (attr_set == i) {
1689 id_array = qm->attr_sets[attr_set].ID_array;
1691 while (*id_array != -1) {
1699 if (strcasecmp(str, tempstr->bv_val) == 0)
1705 consistency_check(void* operation)
1707 Operation* op = (Operation*)operation;
1709 SlapReply rs = {REP_RESULT};
1711 struct metainfo *li = ( struct metainfo * )op->o_bd->be_private;
1712 cache_manager* cm = li->cm;
1713 query_manager* qm = cm->qm;
1714 CachedQuery* query, *query_prev;
1717 struct exception result;
1719 QueryTemplate* templ;
1722 op->o_bd = li->glue_be;
1725 ldap_pvt_thread_sleep(cm->cc_period);
1726 for (i=0; qm->templates[i].querystr; i++) {
1727 templ = qm->templates + i;
1728 query = templ->query_last;
1729 curr_time = slap_get_time();
1730 ldap_pvt_thread_mutex_lock(&cm->remove_mutex);
1731 while (query && (query->expiry_time < curr_time)) {
1732 ldap_pvt_thread_mutex_lock(&qm->lru_mutex);
1733 remove_query(qm, query);
1734 ldap_pvt_thread_mutex_unlock(&qm->lru_mutex);
1736 LDAP_LOG( BACK_META, DETAIL1, "Lock CR index = %d\n",
1738 #else /* !NEW_LOGGING */
1739 Debug( LDAP_DEBUG_ANY, "Lock CR index = %d\n",
1741 #endif /* !NEW_LOGGING */
1742 ldap_pvt_thread_rdwr_wlock(&templ->t_rwlock);
1743 remove_from_template(query, templ);
1745 LDAP_LOG( BACK_META, DETAIL1,
1746 "TEMPLATE %d QUERIES-- %d\n",
1747 i, templ->no_of_queries, 0 );
1748 #else /* !NEW_LOGGING */
1749 Debug( LDAP_DEBUG_ANY, "TEMPLATE %d QUERIES-- %d\n",
1750 i, templ->no_of_queries, 0 );
1751 #endif /* !NEW_LOGGING */
1753 LDAP_LOG( BACK_META, DETAIL1, "Unlock CR index = %d\n",
1755 #else /* !NEW_LOGGING */
1756 Debug( LDAP_DEBUG_ANY, "Unlock CR index = %d\n",
1758 #endif /* !NEW_LOGGING */
1759 ldap_pvt_thread_rdwr_wunlock(&templ->t_rwlock);
1760 uuid.bv_val = query->q_uuid;
1761 uuid.bv_len = strlen(query->q_uuid);
1762 return_val = remove_query_data(op, &rs, &uuid, &result);
1764 LDAP_LOG( BACK_META, DETAIL1,
1765 "STALE QUERY REMOVED, SIZE=%d\n",
1767 #else /* !NEW_LOGGING */
1768 Debug( LDAP_DEBUG_ANY, "STALE QUERY REMOVED, SIZE=%d\n",
1770 #endif /* !NEW_LOGGING */
1771 ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
1772 cm->total_entries -= result.rc;
1773 cm->num_cached_queries--;
1775 LDAP_LOG( BACK_META, DETAIL1, "STORED QUERIES = %lu\n",
1776 cm->num_cached_queries, 0, 0 );
1777 #else /* !NEW_LOGGING */
1778 Debug( LDAP_DEBUG_ANY, "STORED QUERIES = %lu\n",
1779 cm->num_cached_queries, 0, 0 );
1780 #endif /* !NEW_LOGGING */
1781 ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
1782 cm->cache_size = (return_val > cm->cache_size) ?
1783 0: (cm->cache_size-return_val);
1785 LDAP_LOG( BACK_META, DETAIL1,
1786 "STALE QUERY REMOVED, CACHE SIZE=%lu bytes %d "
1787 "entries\n", cm->cache_size,
1788 cm->total_entries, 0 );
1789 #else /* !NEW_LOGGING */
1790 Debug( LDAP_DEBUG_ANY,
1791 "STALE QUERY REMOVED, CACHE SIZE=%lu bytes %d "
1792 "entries\n", cm->cache_size,
1793 cm->total_entries, 0 );
1794 #endif /* !NEW_LOGGING */
1796 query = query->prev;
1797 free_query(query_prev);
1799 ldap_pvt_thread_mutex_unlock(&cm->remove_mutex);
1809 slap_callback *cb = op->o_callback;
1810 /*struct metainfo *li = ( struct metainfo * )op->o_bd->be_private;*/
1811 Backend* be = (Backend*)(cb->sc_private);
1812 struct metainfo *li = ( struct metainfo * )be->be_private;
1815 struct exception result;
1819 if (rs->sr_type == REP_SEARCH) {
1820 dn = rs->sr_entry->e_name;
1821 ndn = rs->sr_entry->e_nname;
1823 rewriteSession( li->rwinfo, "cacheReturn",
1824 rs->sr_entry->e_name.bv_val, op->o_conn,
1826 ber_str2bv(ename, strlen(ename), 0, &rs->sr_entry->e_name);
1827 /* FIXME: should we normalize this? */
1828 ber_dupbv(&rs->sr_entry->e_nname, &rs->sr_entry->e_name);
1830 op->o_callback = NULL;
1832 send_search_entry( op, rs );
1834 rs->sr_entry->e_name = dn;
1835 rs->sr_entry->e_nname = ndn;
1837 op->o_callback = cb;
1838 return LDAP_SUCCESS;
1840 } else if (rs->sr_type == REP_RESULT) {
1841 op->o_callback = NULL;
1842 send_ldap_result( op, rs );
1843 return LDAP_SUCCESS;
1846 return LDAP_SUCCESS;