2 * Copyright (c) 2003 by International Business Machines, Inc.
4 * International Business Machines, Inc. (hereinafter called IBM) grants
5 * permission under its copyrights to use, copy, modify, and distribute this
6 * Software with or without fee, provided that the above copyright notice and
7 * all paragraphs of this notice appear in all copies, and that the name of IBM
8 * not be used in connection with the marketing of any product incorporating
9 * the Software or modifications thereof, without specific, written prior
12 * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
13 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
14 * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
15 * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
17 * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
20 * This software is based on the backends back-ldap and back-meta, implemented
21 * by Howard Chu <hyc@highlandsun.com>, Mark Valence
22 * <kurash@sassafras.com>, Pierangelo Masarati <ando@sys-net.it> and other
25 * The original copyright statements follow.
26 * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
27 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
29 * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
31 * This work has been developed to fulfill the requirements
32 * of SysNet s.n.c. <http:www.sys-net.it> and it has been donated
33 * to the OpenLDAP Foundation in the hope that it may be useful
34 * to the Open Source community, but WITHOUT ANY WARRANTY.
36 * Permission is granted to anyone to use this software for any purpose
37 * on any computer system, and to alter it and redistribute it, subject
38 * to the following restrictions:
40 * 1. The author and SysNet s.n.c. are not responsible for the consequences
41 * of use of this software, no matter how awful, even if they arise from
44 * 2. The origin of this software must not be misrepresented, either by
45 * explicit claim or by omission. Since few users ever read sources,
46 * credits should appear in the documentation.
48 * 3. Altered versions must be plainly marked as such, and must not be
49 * misrepresented as being the original software. Since few users
50 * ever read sources, credits should appear in the documentation.
51 * SysNet s.n.c. cannot be responsible for the consequences of the
54 * 4. This notice may not be removed or altered.
57 * This software is based on the backend back-ldap, implemented
58 * by Howard Chu <hyc@highlandsun.com>, and modified by Mark Valence
59 * <kurash@sassafras.com>, Pierangelo Masarati <ando@sys-net.it> and other
60 * contributors. The contribution of the original software to the present
61 * implementation is acknowledged in this copyright statement.
63 * A special acknowledgement goes to Howard for the overall architecture
64 * (and for borrowing large pieces of code), and to Mark, who implemented
65 * from scratch the attribute/objectclass mapping.
67 * The original copyright statement follows.
69 * Copyright 1999, Howard Chu, All rights reserved. <hyc@highlandsun.com>
71 * Permission is granted to anyone to use this software for any purpose
72 * on any computer system, and to alter it and redistribute it, subject
73 * to the following restrictions:
75 * 1. The author is not responsible for the consequences of use of this
76 * software, no matter how awful, even if they arise from flaws in it.
78 * 2. The origin of this software must not be misrepresented, either by
79 * explicit claim or by omission. Since few users ever read sources,
80 * credits should appear in the documentation.
82 * 3. Altered versions must be plainly marked as such, and must not be
83 * misrepresented as being the original software. Since few users
84 * ever read sources, credits should appear in the
87 * 4. This notice may not be removed or altered.
94 #include <ac/socket.h>
95 #include <ac/string.h>
101 #include "../back-ldap/back-ldap.h"
102 #include "back-meta.h"
103 #undef ldap_debug /* silence a warning in ldap-int.h */
104 #include "ldap_log.h"
105 #include "../../../libraries/libldap/ldap-int.h"
113 struct exception* result
122 static struct metaconn*
127 struct berval *nbase,
128 struct exception *result
133 AttributeName** newattrs,
134 AttributeName* attrs,
135 AttributeName* filter_attrs
143 int* msgid, Backend* be,
144 AttributeName* attrs,
148 Entry*** entry_array,
151 struct exception* result
158 struct metasingleconn* lsc,
162 struct exception* result
167 struct rewrite_info* info,
168 const char* rewriteContext,
172 struct exception* result
177 AttributeName* attrs,
184 AttributeName* attrs_in,
194 struct exception* result
200 struct berval* tempstr,
218 meta_back_cache_search(
226 struct berval *nbase,
232 struct berval *filterstr,
233 AttributeName *attributes,
237 struct metainfo *li = ( struct metainfo * )op->o_bd->be_private;
239 struct metasingleconn *lsc;
240 cache_manager* cm = li->cm;
241 query_manager* qm = cm->qm;
247 int count, rc = 0, *msgid = NULL;
252 int i = -1, last = 0, candidates = 0, op_type;
254 struct berval mfilter;
255 struct berval cachebase = { 0L, NULL };
256 struct berval ncachebase = { 0L, NULL };
257 struct berval cache_suffix;
258 struct berval tempstr = { 0L, NULL };
260 AttributeName *filter_attrs = NULL;
261 AttributeName *new_attrs = NULL;
262 AttributeName *attrs = NULL;
265 Entry **entry_array = NULL;
270 int template_id = -1;
276 int oc_attr_absent = 1;
278 struct exception result[1];
280 Filter* filter = str2filter(op->ors_filterstr.bv_val);
281 slap_callback cb = {cache_back_sentry, NULL};
283 cb.sc_private = op->o_bd;
286 for ( count=0; op->ors_attrs[ count ].an_name.bv_val; count++ ) {
287 if ( op->ors_attrs[count].an_desc == slap_schema.si_ad_objectClass )
290 attrs = (AttributeName*)malloc( ( count + 1 + oc_attr_absent )
291 *sizeof(AttributeName));
292 for ( count=0; op->ors_attrs[ count ].an_name.bv_val; count++ ) {
293 ber_dupbv(&attrs[ count ].an_name,
294 &op->ors_attrs[ count ].an_name);
295 attrs[count].an_desc = op->ors_attrs[count].an_desc;
297 attrs[ count ].an_name.bv_val = NULL;
298 attrs[ count ].an_name.bv_len = 0;
301 result->type = SUCCESS;
303 ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
306 LDAP_LOG( BACK_META, DETAIL1, "Threads++ = %d\n", cm->threads, 0, 0 );
307 #else /* !NEW_LOGGING */
308 Debug( LDAP_DEBUG_ANY, "Threads++ = %d\n", cm->threads, 0, 0 );
309 #endif /* !NEW_LOGGING */
310 ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
312 ldap_pvt_thread_mutex_lock(&cm->cc_mutex);
313 if (!cm->cc_thread_started) {
314 oper = (Operation*)malloc(sizeof(Operation));
316 cm->cc_thread_started = 1;
317 ldap_pvt_thread_create(&(cm->cc_thread), 1, consistency_check, (void*)oper);
319 ldap_pvt_thread_mutex_unlock(&cm->cc_mutex);
321 filter2template(filter, &tempstr, &filter_attrs, &fattr_cnt, result);
322 if (result->type != SUCCESS)
326 LDAP_LOG( BACK_META, DETAIL1, "query template of incoming query = %s\n",
327 tempstr.bv_val, 0, 0 );
328 #else /* !NEW_LOGGING */
329 Debug( LDAP_DEBUG_ANY, "query template of incoming query = %s\n",
330 tempstr.bv_val, 0, 0 );
331 #endif /* !NEW_LOGGING */
332 curr_limit = cm->num_entries_limit ;
335 attr_set = get_attr_set(attrs, qm, cm->numattrsets);
337 query.filter = filter;
339 query.base = op->o_req_dn;
340 query.scope = op->ors_scope;
342 /* check for query containment */
344 for (i=0; i<cm->numtemplates; i++) {
345 /* find if template i can potentially answer tempstr */
346 if (!is_temp_answerable(attr_set, &tempstr, qm, i))
348 if (attr_set == qm->templates[i].attr_set_index) {
353 LDAP_LOG( BACK_META, DETAIL2,
354 "Entering QC, querystr = %s\n",
355 op->ors_filterstr.bv_val, 0, 0 );
356 #else /* !NEW_LOGGING */
357 Debug( LDAP_DEBUG_NONE, "Entering QC, querystr = %s\n",
358 op->ors_filterstr.bv_val, 0, 0 );
359 #endif /* !NEW_LOGGING */
360 answerable = (*(qm->qcfunc))(qm, &query, i);
367 if ( attrs && oc_attr_absent ) {
368 for ( count = 0; attrs[count].an_name.bv_val; count++) ;
369 attrs[ count ].an_name.bv_val = "objectClass";
370 attrs[ count ].an_name.bv_len = strlen( "objectClass" );
371 attrs[ count ].an_desc = slap_schema.si_ad_objectClass;
372 attrs[ count + 1 ].an_name.bv_val = NULL;
373 attrs[ count + 1 ].an_name.bv_len = 0;
380 LDAP_LOG( BACK_META, DETAIL1, "QUERY ANSWERABLE\n", 0, 0, 0 );
381 #else /* !NEW_LOGGING */
382 Debug( LDAP_DEBUG_ANY, "QUERY ANSWERABLE\n", 0, 0, 0 );
383 #endif /* !NEW_LOGGING */
384 rewriteSession(li->rwinfo, "cacheBase", op->o_req_dn.bv_val,
385 op->o_conn, &cbase, result);
386 if (result->type != SUCCESS) {
387 ldap_pvt_thread_rdwr_runlock(&qm->templates[i].t_rwlock);
390 if ( cbase == NULL ) {
391 cachebase = op->o_req_dn;
393 cachebase.bv_val = cbase;
394 cachebase.bv_len = strlen(cbase);
396 dnNormalize(0, NULL, NULL, &cachebase, &ncachebase,
399 /* FIXME: safe default? */
402 op_tmp.o_bd = li->glue_be;
403 op_tmp.o_req_dn = cachebase;
404 op_tmp.o_req_ndn = ncachebase;
406 op_tmp.o_callback = &cb;
408 li->glue_be->be_search(&op_tmp, rs);
409 free( ncachebase.bv_val );
410 if ( cachebase.bv_val != op->o_req_dn.bv_val ) {
411 /* free only if rewritten */
412 free( cachebase.bv_val );
415 ldap_pvt_thread_rdwr_runlock(&qm->templates[i].t_rwlock);
420 LDAP_LOG( BACK_META, DETAIL1, "QUERY NOT ANSWERABLE\n",
422 #else /* !NEW_LOGGING */
423 Debug( LDAP_DEBUG_ANY, "QUERY NOT ANSWERABLE\n", 0, 0, 0 );
424 #endif /* !NEW_LOGGING */
426 if ( op->ors_scope == LDAP_SCOPE_BASE ) {
427 op_type = META_OP_REQUIRE_SINGLE;
429 op_type = META_OP_ALLOW_MULTIPLE;
432 lc = metaConnect(&op_tmp, rs, op_type,
433 &op->o_req_ndn, result);
435 if (result->type != SUCCESS)
438 ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
439 if (cm->num_cached_queries >= cm->max_queries) {
442 ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
445 add_filter_attrs(&new_attrs, attrs, filter_attrs);
453 * Array of message id of each target
455 msgid = ch_calloc( sizeof( int ), li->ntargets );
456 if ( msgid == NULL ) {
457 result->type = CONN_ERR;
462 if (slimit > 0 && (slimit <= cm->num_entries_limit))
463 slimit = cm->num_entries_limit;
470 for ( i = 0, lsc = lc->conns; !META_LAST(lsc); ++i, ++lsc ) {
471 char *realbase = ( char * )op->o_req_dn.bv_val;
472 int realscope = op->ors_scope;
474 char *mapped_filter, **mapped_attrs;
476 /* FIXME: Check for more than one targets */
477 if ( meta_back_is_candidate(
478 &li->targets[i]->suffix,
480 lsc->candidate = META_CANDIDATE;
482 if ( lsc->candidate != META_CANDIDATE )
485 if ( op->ors_deref != -1 ) {
486 ldap_set_option( lsc->ld, LDAP_OPT_DEREF,
487 ( void * )&op->ors_deref);
489 if ( op->ors_tlimit != -1 ) {
490 ldap_set_option( lsc->ld, LDAP_OPT_TIMELIMIT,
491 ( void * )&op->ors_tlimit);
493 if ( op->ors_slimit != -1 ) {
494 ldap_set_option( lsc->ld, LDAP_OPT_SIZELIMIT,
495 ( void * )&op->ors_slimit);
499 * modifies the base according to the scope, if required
501 suffixlen = li->targets[ i ]->suffix.bv_len;
502 if ( suffixlen > op->o_req_ndn.bv_len ) {
503 switch ( op->ors_scope ) {
504 case LDAP_SCOPE_SUBTREE:
506 * make the target suffix the new base
507 * FIXME: this is very forgiving,
508 * because illegal bases may be turned
509 * into the suffix of the target.
512 &li->targets[ i ]->suffix,
515 li->targets[i]->suffix.bv_val;
518 * this target is no longer
527 case LDAP_SCOPE_ONELEVEL:
528 if ( is_one_level_rdn(
529 li->targets[ i ]->suffix.bv_val,
530 suffixlen - op->o_req_ndn.bv_len - 1 )
532 &li->targets[ i ]->suffix,
535 * if there is exactly one
536 * level, make the target suffix
537 * the new base, and make scope
541 li->targets[i]->suffix.bv_val;
542 realscope = LDAP_SCOPE_BASE;
544 } /* else continue with the next case */
546 case LDAP_SCOPE_BASE:
548 * this target is no longer candidate
550 lsc->candidate = META_NOT_CANDIDATE;
556 * Rewrite the search base, if required
559 rewriteSession(li->targets[i]->rwmap.rwm_rw,
561 realbase, op->o_conn, &mbase, result);
563 if (result->type != SUCCESS)
566 if ( mbase == NULL ) {
571 * Rewrite the search filter, if required
573 rewriteSession( li->targets[i]->rwmap.rwm_rw,
575 op->ors_filterstr.bv_val, op->o_conn,
576 &mfilter.bv_val, result);
577 if (result->type != SUCCESS)
580 if ( mfilter.bv_val != NULL && mfilter.bv_val[ 0 ]
582 mfilter.bv_len = strlen( mfilter.bv_val );
584 if ( mfilter.bv_val != NULL ) {
585 free( mfilter.bv_val );
587 mfilter = op->ors_filterstr;
592 * Maps attributes in filter
594 mapped_filter = ldap_back_map_filter(
595 &li->targets[i]->rwmap.rwm_at,
596 &li->targets[i]->rwmap.rwm_oc,
598 if ( mapped_filter == NULL ) {
599 mapped_filter = ( char * )mfilter.bv_val;
601 if ( mfilter.bv_val != op->ors_filterstr.bv_val ) {
602 free( mfilter.bv_val );
605 mfilter.bv_val = NULL;
608 mapped_filter = (char *) mfilter.bv_val;
612 * Maps required attributes
614 if ( ldap_back_map_attrs(
615 &li->targets[ i ]->rwmap.rwm_at,
616 new_attrs, 0, &mapped_attrs ) ) {
623 msgid[ i ] = ldap_search( lsc->ld, mbase, realscope,
624 mapped_filter, mapped_attrs,
627 if ( msgid[ i ] == -1 ) {
628 result->type = CONN_ERR;
631 lsc->candidate = META_NOT_CANDIDATE;
636 if ( mapped_attrs ) {
637 free( mapped_attrs );
641 if ( mapped_filter != op->ors_filterstr.bv_val ) {
642 free( mapped_filter );
643 mapped_filter = NULL;
646 if ( mbase != realbase ) {
654 num_entries = handleLdapResult(lc, &op_tmp, rs, msgid,
656 op->ors_attrsonly, candidates,
657 cacheable, &entry_array,
658 curr_limit, op->ors_slimit, result);
660 if (result->type != SUCCESS)
662 if (cacheable && (num_entries <= curr_limit)) {
665 LDAP_LOG( BACK_META, DETAIL1,
666 "QUERY CACHEABLE\n", 0, 0, 0 );
667 #else /* !NEW_LOGGING */
668 Debug( LDAP_DEBUG_ANY, "QUERY CACHEABLE\n", 0, 0, 0 );
669 #endif /* !NEW_LOGGING */
670 op_tmp.o_bd = li->glue_be;
671 uuid = cache_entries(&op_tmp, rs, entry_array, cm, result);
673 LDAP_LOG( BACK_META, DETAIL1,
674 "Added query %s UUID %s ENTRIES %d\n",
675 op->ors_filterstr.bv_val,
677 #else /* !NEW_LOGGING */
678 Debug( LDAP_DEBUG_ANY,
679 "Added query %s UUID %s ENTRIES %d\n",
680 op->ors_filterstr.bv_val,
682 #endif /* !NEW_LOGGING */
684 if (result->type != SUCCESS)
686 (*(qm->addfunc))(qm, &query, template_id, uuid, result);
687 if (result->type != SUCCESS)
692 /* FIXME : launch do_syncrepl() threads around here
694 * entryUUID and entryCSN need also to be requested by :
697 msgid[ i ] = ldap_search( lsc->ld, mbase, realscope,
698 mapped_filter, mapped_attrs, op->ors_attrsonly );
700 /* Also, mbase, realscope, mapped_filter, mapped_attrs need
701 * be managed as arrays. Each element needs to be retained by this point.
706 LDAP_LOG( BACK_META, DETAIL1,
707 "QUERY NOT CACHEABLE no\n",
709 #else /* !NEW_LOGGING */
710 Debug( LDAP_DEBUG_ANY, "QUERY NOT CACHEABLE no\n",
712 #endif /* !NEW_LOGGING */
717 switch (result->type) {
724 LDAP_LOG( BACK_META, DETAIL1,
725 "Invalid template error\n", 0, 0, 0 );
726 #else /* !NEW_LOGGING */
727 Debug( LDAP_DEBUG_ANY, "Invalid template error\n",
729 #endif /* !NEW_LOGGING */
735 LDAP_LOG( BACK_META, DETAIL1,
736 "Could not connect to a remote server\n",
738 #else /* !NEW_LOGGING */
739 Debug( LDAP_DEBUG_ANY,
740 "Could not connect to a remote server\n",
742 #endif /* !NEW_LOGGING */
743 send_ldap_error(op, rs, LDAP_OTHER,
744 "Connection error" );
750 LDAP_LOG( BACK_META, DETAIL1,
751 "Error in handling ldap_result\n", 0, 0, 0 );
752 #else /* !NEW_LOGGING */
753 Debug( LDAP_DEBUG_ANY,
754 "Error in handling ldap_result\n", 0, 0, 0 );
755 #endif /* !NEW_LOGGING */
760 if (result->rc == REWRITE_REGEXEC_UNWILLING) {
761 send_ldap_error( op, rs,
762 LDAP_UNWILLING_TO_PERFORM,
763 "Unwilling to perform" );
765 send_ldap_error( op, rs, LDAP_OTHER,
773 LDAP_LOG( BACK_META, DETAIL1,
774 "Error in merging entry \n", 0, 0, 0 );
775 #else /* !NEW_LOGGING */
776 Debug( LDAP_DEBUG_ANY,
777 "Error in merging entry \n", 0, 0, 0 );
778 #endif /* !NEW_LOGGING */
784 LDAP_LOG( BACK_META, DETAIL1,
785 "Error in removing query \n",
787 #else /* !NEW_LOGGING */
788 Debug( LDAP_DEBUG_ANY, "Error in removing query \n",
790 #endif /* !NEW_LOGGING */
803 for (i=0; (e = entry_array[i]); i++) {
812 if (new_attrs != attrs)
819 if (tempstr.bv_val ) {
820 free(tempstr.bv_val);
822 ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
825 LDAP_LOG( BACK_META, DETAIL1, "Threads-- = %d\n", cm->threads, 0, 0 );
826 #else /* !NEW_LOGGING */
827 Debug( LDAP_DEBUG_ANY, "Threads-- = %d\n", cm->threads, 0, 0 );
828 #endif /* !NEW_LOGGING */
829 ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
840 struct exception* result
843 struct metainfo *li = ( struct metainfo * )be->be_private;
844 struct berval a, mapped;
846 BerElement ber = *e->lm_ber;
847 Attribute *attr, *soc_attr, **attrp;
848 struct berval dummy = { 0, NULL };
849 struct berval *bv, bdn;
852 struct berval sc = { 0, NULL };
856 if ( ber_scanf( &ber, "{m{", &bdn ) == LBER_ERROR ) {
857 result->type = CREATE_ENTRY_ERR;
860 ent = (Entry*)malloc(sizeof(Entry));
863 * Rewrite the dn of the result, if needed
865 rewriteSession( li->targets[ target ]->rwmap.rwm_rw, "searchResult",
866 bdn.bv_val, lc->conn, &ent->e_name.bv_val, result );
868 if (result->type != SUCCESS) {
871 if ( ent->e_name.bv_val == NULL ) {
872 ber_dupbv(&(ent->e_name), &bdn);
875 LDAP_LOG( BACK_META, DETAIL1,
876 "[rw] searchResult[%d]: \"%s\" -> \"%s\"\n",
877 target, bdn.bv_val, ent->e_name.bv_val );
878 #else /* !NEW_LOGGING */
879 Debug( LDAP_DEBUG_ARGS, "rw> searchResult[%d]: \"%s\""
881 target, bdn.bv_val, ent->e_name.bv_val );
882 #endif /* !NEW_LOGGING */
883 ent->e_name.bv_len = strlen( ent->e_name.bv_val );
887 * Note: this may fail if the target host(s) schema differs
888 * from the one known to the meta, and a DN with unknown
889 * attributes is returned.
891 * FIXME: should we log anything, or delegate to dnNormalize?
893 dnNormalize( 0, NULL, NULL, &ent->e_name, &ent->e_nname, NULL );
896 if ( dnNormalize( 0, NULL, NULL, &ent->e_name, &ent->e_nname )
899 return LDAP_INVALID_DN_SYNTAX;
906 if ( li->cache.ttl != META_DNCACHE_DISABLED ) {
907 meta_dncache_update_entry( &li->cache, &ent->e_nname, target );
913 ent->e_bv.bv_val = 0;
915 attrp = &ent->e_attrs;
917 while ( ber_scanf( &ber, "{m", &a ) != LBER_ERROR ) {
918 ldap_back_map( &li->targets[ target ]->rwmap.rwm_at,
920 if ( mapped.bv_val == NULL ) {
923 attr = ( Attribute * )ch_malloc( sizeof( Attribute ) );
924 if ( attr == NULL ) {
930 attr->a_nvals = NULL;
931 if ( slap_bv2ad( &mapped, &attr->a_desc, &text ) != LDAP_SUCCESS) {
932 if ( slap_bv2undef_ad( &mapped, &attr->a_desc, &text )
935 LDAP_LOG( BACK_META, DETAIL1,
936 "slap_bv2undef_ad(%s): %s\n",
937 mapped.bv_val, text, 0 );
938 #else /* !NEW_LOGGING */
939 Debug( LDAP_DEBUG_ANY,
940 "slap_bv2undef_ad(%s): "
941 "%s\n%s", mapped.bv_val, text, "" );
942 #endif /* !NEW_LOGGING */
948 /* no subschemaSubentry */
949 if ( attr->a_desc == slap_schema.si_ad_subschemaSubentry ) {
954 if ( ber_scanf( &ber, "[W]", &attr->a_vals ) == LBER_ERROR
955 || attr->a_vals == NULL ) {
956 attr->a_vals = &dummy;
958 } else if ( attr->a_desc == slap_schema.si_ad_objectClass ||
960 slap_schema.si_ad_structuralObjectClass) {
962 } else if ( attr->a_desc == slap_schema.si_ad_objectClass ) {
965 for ( last = 0; attr->a_vals[ last ].bv_val; ++last )
967 for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++,i++ ) {
968 ldap_back_map( &li->targets[ target]->rwmap.rwm_oc,
970 if ( mapped.bv_val == NULL ) {
976 *bv = attr->a_vals[ last ];
977 attr->a_vals[ last ].bv_val = NULL;
979 } else if ( mapped.bv_val != bv->bv_val ) {
981 ber_dupbv( bv, &mapped );
985 structural_class( attr->a_vals, &sc, NULL, &text, textbuf, textlen );
986 soc_attr = (Attribute*) ch_malloc( sizeof( Attribute ));
987 soc_attr->a_desc = slap_schema.si_ad_structuralObjectClass;
988 soc_attr->a_vals = (BerVarray) ch_malloc( 2* sizeof( BerValue ));
989 ber_dupbv( &soc_attr->a_vals[0], &sc );
990 soc_attr->a_vals[1].bv_len = 0;
991 soc_attr->a_vals[1].bv_val = NULL;
992 soc_attr->a_nvals = (BerVarray) ch_malloc( 2* sizeof( BerValue ));
993 ber_dupbv( &soc_attr->a_nvals[0], &sc );
994 soc_attr->a_nvals[1].bv_len = 0;
995 soc_attr->a_nvals[1].bv_val = NULL;
998 attrp = &soc_attr->a_next;
1001 * It is necessary to try to rewrite attributes with
1002 * dn syntax because they might be used in ACLs as
1003 * members of groups; since ACLs are applied to the
1004 * rewritten stuff, no dn-based subecj clause could
1005 * be used at the ldap backend side (see
1006 * http://www.OpenLDAP.org/faq/data/cache/452.html)
1007 * The problem can be overcome by moving the dn-based
1008 * ACLs to the target directory server, and letting
1009 * everything pass thru the ldap backend.
1011 } else if ( strcmp( attr->a_desc->ad_type->sat_syntax->ssyn_oid,
1012 SLAPD_DN_SYNTAX ) == 0 ) {
1014 for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++,i++ ) {
1016 rewriteSession(li->targets[ target ]->rwmap.rwm_rw,
1017 "searchResult", bv->bv_val,
1018 lc->conn, &newval, result);
1019 if (result->type != SUCCESS) {
1020 /* FIXME : Handle error */
1021 result->type = SUCCESS;
1024 if ( newval == NULL ) {
1028 LDAP_LOG( BACK_META, DETAIL1,
1029 "[rw] searchResult on "
1030 "attr=%s: \"%s\" -> \"%s\"\n",
1031 attr->a_desc->ad_type->
1033 bv->bv_val, newval );
1034 #else /* !NEW_LOGGING */
1035 Debug( LDAP_DEBUG_ARGS,
1036 "rw> searchResult on attr=%s:"
1037 " \"%s\" -> \"%s\"\n",
1038 attr->a_desc->ad_type->
1040 bv->bv_val, newval );
1041 #endif /* !NEW_LOGGING */
1043 bv->bv_val = newval;
1044 bv->bv_len = strlen( newval );
1049 attrp = &attr->a_next;
1062 if ( DN_SEPARATOR( rdn[ from ] ) ) {
1069 static struct metaconn*
1074 struct berval *nbase,
1075 struct exception *result)
1077 struct metaconn *lc;
1079 result->type = SUCCESS;
1080 lc = meta_back_getconn( op, rs, op_type, nbase, NULL );
1082 result->type = CONN_ERR;
1090 AttributeName** new_attrs,
1091 AttributeName* attrs,
1092 AttributeName* filter_attrs )
1094 struct berval all_user = { sizeof(LDAP_ALL_USER_ATTRIBUTES) -1,
1095 LDAP_ALL_USER_ATTRIBUTES };
1097 struct berval all_op = { sizeof(LDAP_ALL_OPERATIONAL_ATTRIBUTES) -1,
1098 LDAP_ALL_OPERATIONAL_ATTRIBUTES};
1105 /* duplicate attrs */
1106 if (attrs == NULL) {
1109 for (count=0; attrs[count].an_name.bv_val; count++)
1112 *new_attrs = (AttributeName*)(malloc((count+1)*sizeof(AttributeName)));
1113 if (attrs == NULL) {
1114 (*new_attrs)[0].an_name.bv_val = "*";
1115 (*new_attrs)[0].an_name.bv_len = 1;
1116 (*new_attrs)[1].an_name.bv_val = NULL;
1117 (*new_attrs)[1].an_name.bv_len = 0;
1121 for (i=0; i<count; i++) {
1122 (*new_attrs)[i].an_name = attrs[i].an_name;
1123 (*new_attrs)[i].an_desc = attrs[i].an_desc;
1125 (*new_attrs)[count].an_name.bv_val = NULL;
1126 (*new_attrs)[count].an_name.bv_len = 0;
1127 alluser = an_find(*new_attrs, &all_user);
1128 allop = an_find(*new_attrs, &all_op);
1131 for ( i=0; filter_attrs[i].an_name.bv_val; i++ ) {
1132 if ( an_find(*new_attrs, &filter_attrs[i].an_name ))
1134 if ( is_at_operational(filter_attrs[i].an_desc->ad_type) ) {
1139 *new_attrs = (AttributeName*)(realloc(*new_attrs,
1140 (count+2)*sizeof(AttributeName)));
1141 (*new_attrs)[count].an_name.bv_val =
1142 filter_attrs[i].an_name.bv_val;
1143 (*new_attrs)[count].an_name.bv_len =
1144 filter_attrs[i].an_name.bv_len;
1145 (*new_attrs)[count].an_desc = filter_attrs[i].an_desc;
1146 (*new_attrs)[count+1].an_name.bv_val = NULL;
1147 (*new_attrs)[count+1].an_name.bv_len = 0;
1154 struct metaconn* lc,
1157 int* msgid, Backend* be,
1158 AttributeName* attrs,
1162 Entry*** entry_array,
1165 struct exception* result)
1168 char *match = NULL, *err = NULL, *cache_ename = NULL;
1170 int mres = LDAP_SUCCESS;
1171 int num_entries = 0, count, i, rc;
1172 struct timeval tv = {0, 0};
1173 struct metasingleconn* lsc;
1174 struct metainfo *li = ( struct metainfo * )be->be_private;
1176 result->type = SUCCESS;
1178 for ( count = 0, rc = 0; candidates > 0; ) {
1181 /* check for abandon */
1184 for ( i = 0, lsc = lc->conns; !META_LAST(lsc); lsc++, i++ ) {
1185 if ( lsc->candidate != META_CANDIDATE ) {
1190 ldap_abandon( lsc->ld, msgid[ i ] );
1191 result->type = ABANDON_ERR;
1195 if ( slimit > 0 && num_entries == slimit ) {
1196 result->type = SLIMIT_ERR;
1200 if ((entry = get_result_entry(be, lc, lsc,
1201 msgid, i, &tv, result))) {
1202 rs->sr_entry = entry;
1203 rs->sr_attrs = op->ors_attrs;
1204 send_search_entry( op, rs );
1205 rs->sr_entry = NULL;
1206 rs->sr_attrs = NULL;
1208 (num_entries < curr_limit)) {
1209 rewriteSession( li->rwinfo,
1211 entry->e_name.bv_val,
1213 &cache_ename, result );
1214 free(entry->e_name.bv_val);
1215 if (result->type != SUCCESS) {
1218 ber_str2bv(cache_ename,
1219 strlen(cache_ename),
1221 ber_dupbv(&entry->e_nname,
1223 *entry_array = (Entry**)realloc(
1225 (( num_entries+2 ) *
1227 (*entry_array)[num_entries] = entry;
1228 (*entry_array)[num_entries+1] = NULL;
1232 } else if (result->type == REWRITING_ERR) {
1234 } else if (result->type == TIMEOUT_ERR) {
1235 result->type = SUCCESS;
1237 } else if (result->type == CREATE_ENTRY_ERR) {
1239 } else if (result->rc == -1) {
1242 rs->sr_err = result->rc;
1243 sres = ldap_back_map_result(rs);
1244 if (mres == LDAP_SUCCESS &&
1245 sres != LDAP_SUCCESS) {
1247 ldap_get_option(lsc->ld,
1248 LDAP_OPT_ERROR_STRING, &err);
1249 ldap_get_option(lsc->ld,
1250 LDAP_OPT_MATCHED_DN, &match);
1252 lsc->candidate = META_NOT_CANDIDATE;
1254 result->type = SUCCESS;
1257 switch (result->type) {
1260 LDAP_LOG( BACK_META, DETAIL1,
1261 "ldap_result error, rc = -1\n",
1263 #else /* !NEW_LOGGING */
1264 Debug( LDAP_DEBUG_ANY, "ldap_result error, rc = -1\n",
1266 #endif /* !NEW_LOGGING */
1267 rs->sr_err = LDAP_OTHER;
1268 send_ldap_result( op, rs );
1271 case CREATE_ENTRY_ERR:
1273 LDAP_LOG( BACK_META, DETAIL1,
1274 "Error in parsing result \n",
1276 #else /* !NEW_LOGGING */
1277 Debug( LDAP_DEBUG_ANY, "Error in parsing result \n",
1279 #endif /* !NEW_LOGGING */
1280 rs->sr_err = LDAP_OTHER;
1281 send_ldap_result( op, rs );
1282 result->type = RESULT_ERR;
1287 LDAP_LOG( BACK_META, DETAIL1, "Size limit exceeded \n",
1289 #else /* !NEW_LOGGING */
1290 Debug( LDAP_DEBUG_ANY, "Size limit exceeded \n",
1292 #endif /* !NEW_LOGGING */
1293 rs->sr_err = LDAP_SIZELIMIT_EXCEEDED;
1294 send_ldap_result( op, rs );
1295 result->type = RESULT_ERR;
1300 LDAP_LOG( BACK_META, DETAIL1,
1301 "search operation abandoned \n",
1303 #else /* !NEW_LOGGING */
1304 Debug( LDAP_DEBUG_ANY, "search operation abandoned \n",
1306 #endif /* !NEW_LOGGING */
1307 result->type = RESULT_ERR;
1316 tv.tv_usec = 100000;
1317 ldap_pvt_thread_yield();
1326 rs->sr_matched = match;
1328 send_ldap_result( op, rs );
1331 rs->sr_matched = NULL;
1339 result->type = (mres == LDAP_SUCCESS) ? SUCCESS : RESULT_ERR;
1346 struct metaconn* lc,
1347 struct metasingleconn* lsc,
1351 struct exception* result)
1354 LDAPMessage *res, *e;
1356 int sres = LDAP_SUCCESS;
1358 rc = ldap_result( lsc->ld, msgid[ i ],
1362 result->type = TIMEOUT_ERR;
1364 } else if ( rc == -1 ) {
1366 result->type = RESULT_ERR;
1368 } else if ( rc == LDAP_RES_SEARCH_ENTRY ) {
1369 e = ldap_first_entry( lsc->ld, res );
1370 entry = meta_create_entry(be, lc, i, e, result);
1374 ldap_msgfree( res );
1375 result->type = SUCCESS;
1378 sres = ldap_result2error( lsc->ld,
1381 result->type = RESULT_ERR;
1388 struct rewrite_info* info,
1389 const char* rewriteContext,
1393 struct exception* result)
1395 int rc = rewrite_session(info, rewriteContext, string, cookie, base);
1396 if (rc != REWRITE_REGEXEC_OK) {
1398 result->type = REWRITING_ERR;
1400 if (strcmp(rewriteContext, "searchBase") == 0)
1402 LDAP_LOG( BACK_META, DETAIL1,
1403 "Problem in rewriting search base\n", 0, 0, 0 );
1404 #else /* !NEW_LOGGING */
1405 Debug( LDAP_DEBUG_ANY,
1406 "Problem in rewriting search base\n", 0, 0, 0 );
1407 #endif /* !NEW_LOGGING */
1408 if (strcmp(rewriteContext, "searchFilter") == 0)
1410 LDAP_LOG( BACK_META, DETAIL1,
1411 "Problem in rewriting search filter\n",
1413 #else /* !NEW_LOGGING */
1414 Debug( LDAP_DEBUG_ANY,
1415 "Problem in rewriting search filter\n",
1417 #endif /* !NEW_LOGGING */
1418 if (strcmp(rewriteContext, "searchResult") == 0)
1420 LDAP_LOG( BACK_META, DETAIL1,
1421 "Problem in rewriting DN, or DN syntax "
1422 "attributes of search result\n", 0, 0, 0 );
1423 #else /* !NEW_LOGGING */
1424 Debug( LDAP_DEBUG_ANY,
1425 "Problem in rewriting DN, or DN syntax "
1426 "attributes of search result\n", 0, 0, 0 );
1427 #endif /* !NEW_LOGGING */
1428 if (strcmp(rewriteContext, "cacheBase") == 0)
1430 LDAP_LOG( BACK_META, DETAIL1,
1431 "Problem in rewriting search base with "
1432 "cache base\n", 0, 0, 0 );
1433 #else /* !NEW_LOGGING */
1434 Debug( LDAP_DEBUG_ANY,
1435 "Problem in rewriting search base with "
1436 "cache base\n", 0, 0, 0 );
1437 #endif /* !NEW_LOGGING */
1438 if (strcmp(rewriteContext, "cacheResult") == 0)
1440 LDAP_LOG( BACK_META, DETAIL1,
1441 "Problem in rewriting DN for cached entries\n",
1443 #else /* !NEW_LOGGING */
1444 Debug( LDAP_DEBUG_ANY,
1445 "Problem in rewriting DN for cached entries\n",
1447 #endif /* !NEW_LOGGING */
1448 if (strcmp(rewriteContext, "cacheReturn") == 0)
1450 LDAP_LOG( BACK_META, DETAIL1,
1451 "Problem in rewriting DN for answerable "
1452 "entries\n", 0, 0, 0 );
1453 #else /* !NEW_LOGGING */
1454 Debug( LDAP_DEBUG_ANY,
1455 "Problem in rewriting DN for answerable "
1456 "entries\n", 0, 0, 0 );
1457 #endif /* !NEW_LOGGING */
1459 result->type = SUCCESS;
1465 AttributeName* attrs,
1470 for (i=0; i<num; i++) {
1471 if (attrscmp(attrs, qm->attr_sets[i].attrs))
1479 AttributeName* attrs_in,
1480 AttributeName* attrs)
1482 int i, count1, count2;
1483 if ( attrs_in == NULL ) {
1484 return (attrs ? 0 : 1);
1486 if ( attrs == NULL )
1490 attrs_in && attrs_in[count1].an_name.bv_val != NULL;
1494 attrs && attrs[count2].an_name.bv_val != NULL;
1497 if ( count1 != count2 )
1500 for ( i=0; i<count1; i++ ) {
1501 if ( !an_find(attrs, &attrs_in[i].an_name ))
1511 Entry** entry_array,
1513 struct exception* result)
1519 struct berval query_uuid;
1520 struct berval crp_uuid;
1521 char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ], *crpid;
1523 query_manager *qm = cm->qm;
1525 result->type = SUCCESS;
1526 query_uuid.bv_len = lutil_uuidstr(uuidbuf, sizeof(uuidbuf));
1527 query_uuid.bv_val = ch_strdup(uuidbuf);
1530 LDAP_LOG( BACK_META, DETAIL1, "UUID for query being added = %s\n",
1532 #else /* !NEW_LOGGING */
1533 Debug( LDAP_DEBUG_ANY, "UUID for query being added = %s\n",
1535 #endif /* !NEW_LOGGING */
1537 for ( i=0; ( entry_array && (e=entry_array[i]) ); i++ ) {
1539 LDAP_LOG( BACK_META, DETAIL2, "LOCKING REMOVE MUTEX\n",
1541 #else /* !NEW_LOGGING */
1542 Debug( LDAP_DEBUG_NONE, "LOCKING REMOVE MUTEX\n", 0, 0, 0 );
1543 #endif /* !NEW_LOGGING */
1544 ldap_pvt_thread_mutex_lock(&cm->remove_mutex);
1546 LDAP_LOG( BACK_META, DETAIL2, "LOCKED REMOVE MUTEX\n", 0, 0, 0);
1547 #else /* !NEW_LOGGING */
1548 Debug( LDAP_DEBUG_NONE, "LOCKED REMOVE MUTEX\n", 0, 0, 0);
1549 #endif /* !NEW_LOGGING */
1550 if ( cm->cache_size > (cm->thresh_hi) ) {
1551 while(cm->cache_size > (cm->thresh_lo)) {
1552 crpid = cache_replacement(qm);
1553 if (crpid == NULL) {
1554 result->type = REMOVE_ERR;
1556 strcpy(crpuuid, crpid);
1557 crp_uuid.bv_val = crpuuid;
1558 crp_uuid.bv_len = strlen(crpuuid);
1560 LDAP_LOG( BACK_META, DETAIL1,
1561 "Removing query UUID %s\n",
1563 #else /* !NEW_LOGGING */
1564 Debug( LDAP_DEBUG_ANY,
1565 "Removing query UUID %s\n",
1567 #endif /* !NEW_LOGGING */
1568 return_val = remove_query_data(op, rs,
1571 LDAP_LOG( BACK_META, DETAIL1,
1572 "QUERY REMOVED, SIZE=%d\n",
1574 #else /* !NEW_LOGGING */
1575 Debug( LDAP_DEBUG_ANY,
1576 "QUERY REMOVED, SIZE=%d\n",
1578 #endif /* !NEW_LOGGING */
1579 ldap_pvt_thread_mutex_lock(
1581 cm->total_entries -= result->rc;
1582 cm->num_cached_queries--;
1584 LDAP_LOG( BACK_META, DETAIL1,
1585 "STORED QUERIES = %lu\n",
1586 cm->num_cached_queries, 0, 0 );
1587 #else /* !NEW_LOGGING */
1588 Debug( LDAP_DEBUG_ANY,
1589 "STORED QUERIES = %lu\n",
1590 cm->num_cached_queries, 0, 0 );
1591 #endif /* !NEW_LOGGING */
1592 ldap_pvt_thread_mutex_unlock(
1594 cm->cache_size = (return_val >
1596 0 : (cm->cache_size-return_val);
1598 LDAP_LOG( BACK_META, DETAIL1,
1599 "QUERY REMOVED, CACHE SIZE="
1600 "%lu bytes %d entries\n",
1602 cm->total_entries, 0 );
1603 #else /* !NEW_LOGGING */
1604 Debug( LDAP_DEBUG_ANY,
1605 "QUERY REMOVED, CACHE SIZE="
1606 "%lu bytes %d entries\n",
1608 cm->total_entries, 0 );
1609 #endif /* !NEW_LOGGING */
1615 return_val = merge_entry(op, rs, &query_uuid, result);
1616 rs->sr_entry = NULL;
1617 cm->cache_size += return_val;
1619 LDAP_LOG( BACK_META, DETAIL1,
1620 "ENTRY ADDED/MERGED, CACHE SIZE=%lu bytes\n",
1621 cm->cache_size, 0, 0 );
1622 #else /* !NEW_LOGGING */
1623 Debug( LDAP_DEBUG_ANY,
1624 "ENTRY ADDED/MERGED, CACHE SIZE=%lu bytes\n",
1625 cm->cache_size, 0, 0 );
1626 #endif /* !NEW_LOGGING */
1628 LDAP_LOG( BACK_META, DETAIL2, "UNLOCKING REMOVE MUTEX\n",
1630 #else /* !NEW_LOGGING */
1631 Debug( LDAP_DEBUG_NONE, "UNLOCKING REMOVE MUTEX\n", 0, 0, 0 );
1632 #endif /* !NEW_LOGGING */
1633 ldap_pvt_thread_mutex_unlock(&cm->remove_mutex);
1635 LDAP_LOG( BACK_META, DETAIL2, "UNLOCKED REMOVE MUTEX\n",
1637 #else /* !NEW_LOGGING */
1638 Debug( LDAP_DEBUG_NONE, "UNLOCKED REMOVE MUTEX\n", 0, 0, 0 );
1639 #endif /* !NEW_LOGGING */
1640 if (result->type != SUCCESS)
1642 ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
1643 cm->total_entries += result->rc;
1645 LDAP_LOG( BACK_META, DETAIL1,
1646 "ENTRY ADDED/MERGED, SIZE=%d, CACHED ENTRIES=%d\n",
1647 return_val, cm->total_entries, 0 );
1648 #else /* !NEW_LOGGING */
1649 Debug( LDAP_DEBUG_ANY,
1650 "ENTRY ADDED/MERGED, SIZE=%d, CACHED ENTRIES=%d\n",
1651 return_val, cm->total_entries, 0 );
1652 #endif /* !NEW_LOGGING */
1653 ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
1655 ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
1656 cm->num_cached_queries++;
1658 LDAP_LOG( BACK_META, DETAIL1, "STORED QUERIES = %lu\n",
1659 cm->num_cached_queries, 0, 0 );
1660 #else /* !NEW_LOGGING */
1661 Debug( LDAP_DEBUG_ANY, "STORED QUERIES = %lu\n",
1662 cm->num_cached_queries, 0, 0 );
1663 #endif /* !NEW_LOGGING */
1664 ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
1666 return query_uuid.bv_val;
1672 struct berval* tempstr,
1680 i = qm->templates[template_id].attr_set_index;
1681 str = qm->templates[template_id].querystr;
1683 if (attr_set == i) {
1686 id_array = qm->attr_sets[attr_set].ID_array;
1688 while (*id_array != -1) {
1696 if (strcasecmp(str, tempstr->bv_val) == 0)
1702 consistency_check(void* operation)
1704 Operation* op = (Operation*)operation;
1706 SlapReply rs = {REP_RESULT};
1708 struct metainfo *li = ( struct metainfo * )op->o_bd->be_private;
1709 cache_manager* cm = li->cm;
1710 query_manager* qm = cm->qm;
1711 CachedQuery* query, *query_prev;
1714 struct exception result;
1716 QueryTemplate* templ;
1719 op->o_bd = li->glue_be;
1722 ldap_pvt_thread_sleep(cm->cc_period);
1723 for (i=0; qm->templates[i].querystr; i++) {
1724 templ = qm->templates + i;
1725 query = templ->query_last;
1726 curr_time = slap_get_time();
1727 ldap_pvt_thread_mutex_lock(&cm->remove_mutex);
1728 while (query && (query->expiry_time < curr_time)) {
1729 ldap_pvt_thread_mutex_lock(&qm->lru_mutex);
1730 remove_query(qm, query);
1731 ldap_pvt_thread_mutex_unlock(&qm->lru_mutex);
1733 LDAP_LOG( BACK_META, DETAIL1, "Lock CR index = %d\n",
1735 #else /* !NEW_LOGGING */
1736 Debug( LDAP_DEBUG_ANY, "Lock CR index = %d\n",
1738 #endif /* !NEW_LOGGING */
1739 ldap_pvt_thread_rdwr_wlock(&templ->t_rwlock);
1740 remove_from_template(query, templ);
1742 LDAP_LOG( BACK_META, DETAIL1,
1743 "TEMPLATE %d QUERIES-- %d\n",
1744 i, templ->no_of_queries, 0 );
1745 #else /* !NEW_LOGGING */
1746 Debug( LDAP_DEBUG_ANY, "TEMPLATE %d QUERIES-- %d\n",
1747 i, templ->no_of_queries, 0 );
1748 #endif /* !NEW_LOGGING */
1750 LDAP_LOG( BACK_META, DETAIL1, "Unlock CR index = %d\n",
1752 #else /* !NEW_LOGGING */
1753 Debug( LDAP_DEBUG_ANY, "Unlock CR index = %d\n",
1755 #endif /* !NEW_LOGGING */
1756 ldap_pvt_thread_rdwr_wunlock(&templ->t_rwlock);
1757 uuid.bv_val = query->q_uuid;
1758 uuid.bv_len = strlen(query->q_uuid);
1759 return_val = remove_query_data(op, &rs, &uuid, &result);
1761 LDAP_LOG( BACK_META, DETAIL1,
1762 "STALE QUERY REMOVED, SIZE=%d\n",
1764 #else /* !NEW_LOGGING */
1765 Debug( LDAP_DEBUG_ANY, "STALE QUERY REMOVED, SIZE=%d\n",
1767 #endif /* !NEW_LOGGING */
1768 ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
1769 cm->total_entries -= result.rc;
1770 cm->num_cached_queries--;
1772 LDAP_LOG( BACK_META, DETAIL1, "STORED QUERIES = %lu\n",
1773 cm->num_cached_queries, 0, 0 );
1774 #else /* !NEW_LOGGING */
1775 Debug( LDAP_DEBUG_ANY, "STORED QUERIES = %lu\n",
1776 cm->num_cached_queries, 0, 0 );
1777 #endif /* !NEW_LOGGING */
1778 ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
1779 cm->cache_size = (return_val > cm->cache_size) ?
1780 0: (cm->cache_size-return_val);
1782 LDAP_LOG( BACK_META, DETAIL1,
1783 "STALE QUERY REMOVED, CACHE SIZE=%lu bytes %d "
1784 "entries\n", cm->cache_size,
1785 cm->total_entries, 0 );
1786 #else /* !NEW_LOGGING */
1787 Debug( LDAP_DEBUG_ANY,
1788 "STALE QUERY REMOVED, CACHE SIZE=%lu bytes %d "
1789 "entries\n", cm->cache_size,
1790 cm->total_entries, 0 );
1791 #endif /* !NEW_LOGGING */
1793 query = query->prev;
1794 free_query(query_prev);
1796 ldap_pvt_thread_mutex_unlock(&cm->remove_mutex);
1806 slap_callback *cb = op->o_callback;
1807 /*struct metainfo *li = ( struct metainfo * )op->o_bd->be_private;*/
1808 Backend* be = (Backend*)(cb->sc_private);
1809 struct metainfo *li = ( struct metainfo * )be->be_private;
1812 struct exception result;
1816 if (rs->sr_type == REP_SEARCH) {
1817 dn = rs->sr_entry->e_name;
1818 ndn = rs->sr_entry->e_nname;
1820 rewriteSession( li->rwinfo, "cacheReturn",
1821 rs->sr_entry->e_name.bv_val, op->o_conn,
1823 ber_str2bv(ename, strlen(ename), 0, &rs->sr_entry->e_name);
1824 /* FIXME: should we normalize this? */
1825 ber_dupbv(&rs->sr_entry->e_nname, &rs->sr_entry->e_name);
1827 op->o_callback = NULL;
1829 send_search_entry( op, rs );
1831 rs->sr_entry->e_name = dn;
1832 rs->sr_entry->e_nname = ndn;
1834 op->o_callback = cb;
1836 } else if (rs->sr_type == REP_RESULT) {
1837 op->o_callback = NULL;
1838 send_ldap_result( op, rs );