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"
114 struct exception* result
123 static struct metaconn*
128 struct berval *nbase,
129 struct exception *result
134 AttributeName** newattrs,
135 AttributeName* attrs,
136 AttributeName* filter_attrs
144 int* msgid, Backend* be,
145 AttributeName* attrs,
149 Entry*** entry_array,
152 struct exception* result
159 struct metasingleconn* lsc,
163 struct exception* result
168 struct rewrite_info* info,
169 const char* rewriteContext,
173 struct exception* result
178 AttributeName* attrs,
185 AttributeName* attrs_in,
195 struct exception* result
201 struct berval* tempstr,
219 meta_back_cache_search(
227 struct berval *nbase,
233 struct berval *filterstr,
234 AttributeName *attributes,
238 struct metainfo *li = ( struct metainfo * )op->o_bd->be_private;
240 struct metasingleconn *lsc;
241 cache_manager* cm = li->cm;
242 query_manager* qm = cm->qm;
248 int count, rc = 0, *msgid = NULL;
253 int i = -1, last = 0, candidates = 0, op_type;
255 struct berval mfilter;
256 struct berval cachebase = { 0L, NULL };
257 struct berval ncachebase = { 0L, NULL };
258 struct berval cache_suffix;
259 struct berval tempstr = { 0L, NULL };
261 AttributeName *filter_attrs = NULL;
262 AttributeName *new_attrs = NULL;
263 AttributeName *attrs = NULL;
266 Entry **entry_array = NULL;
271 int template_id = -1;
277 int oc_attr_absent = 1;
279 struct exception result[1];
281 Filter* filter = str2filter(op->ors_filterstr.bv_val);
282 slap_callback cb = {cache_back_sentry, NULL};
284 cb.sc_private = op->o_bd;
287 for ( count=0; op->ors_attrs[ count ].an_name.bv_val; count++ ) {
288 if ( op->ors_attrs[count].an_desc == slap_schema.si_ad_objectClass )
291 attrs = (AttributeName*)malloc( ( count + 1 + oc_attr_absent )
292 *sizeof(AttributeName));
293 for ( count=0; op->ors_attrs[ count ].an_name.bv_val; count++ ) {
294 ber_dupbv(&attrs[ count ].an_name,
295 &op->ors_attrs[ count ].an_name);
296 attrs[count].an_desc = op->ors_attrs[count].an_desc;
298 attrs[ count ].an_name.bv_val = NULL;
299 attrs[ count ].an_name.bv_len = 0;
302 result->type = SUCCESS;
304 ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
307 LDAP_LOG( BACK_META, DETAIL1, "Threads++ = %d\n", cm->threads, 0, 0 );
308 #else /* !NEW_LOGGING */
309 Debug( LDAP_DEBUG_ANY, "Threads++ = %d\n", cm->threads, 0, 0 );
310 #endif /* !NEW_LOGGING */
311 ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
313 ldap_pvt_thread_mutex_lock(&cm->cc_mutex);
314 if (!cm->cc_thread_started) {
315 oper = (Operation*)malloc(sizeof(Operation));
317 cm->cc_thread_started = 1;
318 ldap_pvt_thread_create(&(cm->cc_thread), 1, consistency_check, (void*)oper);
320 ldap_pvt_thread_mutex_unlock(&cm->cc_mutex);
322 filter2template(filter, &tempstr, &filter_attrs, &fattr_cnt, result);
323 if (result->type != SUCCESS)
327 LDAP_LOG( BACK_META, DETAIL1, "query template of incoming query = %s\n",
328 tempstr.bv_val, 0, 0 );
329 #else /* !NEW_LOGGING */
330 Debug( LDAP_DEBUG_ANY, "query template of incoming query = %s\n",
331 tempstr.bv_val, 0, 0 );
332 #endif /* !NEW_LOGGING */
333 curr_limit = cm->num_entries_limit ;
336 attr_set = get_attr_set(attrs, qm, cm->numattrsets);
338 query.filter = filter;
340 query.base = op->o_req_dn;
341 query.scope = op->ors_scope;
343 /* check for query containment */
345 for (i=0; i<cm->numtemplates; i++) {
346 /* find if template i can potentially answer tempstr */
347 if (!is_temp_answerable(attr_set, &tempstr, qm, i))
349 if (attr_set == qm->templates[i].attr_set_index) {
354 LDAP_LOG( BACK_META, DETAIL2,
355 "Entering QC, querystr = %s\n",
356 op->ors_filterstr.bv_val, 0, 0 );
357 #else /* !NEW_LOGGING */
358 Debug( LDAP_DEBUG_NONE, "Entering QC, querystr = %s\n",
359 op->ors_filterstr.bv_val, 0, 0 );
360 #endif /* !NEW_LOGGING */
361 answerable = (*(qm->qcfunc))(qm, &query, i);
368 if ( attrs && oc_attr_absent ) {
369 for ( count = 0; attrs[count].an_name.bv_val; count++) ;
370 attrs[ count ].an_name.bv_val = "objectClass";
371 attrs[ count ].an_name.bv_len = strlen( "objectClass" );
372 attrs[ count ].an_desc = slap_schema.si_ad_objectClass;
373 attrs[ count + 1 ].an_name.bv_val = NULL;
374 attrs[ count + 1 ].an_name.bv_len = 0;
381 LDAP_LOG( BACK_META, DETAIL1, "QUERY ANSWERABLE\n", 0, 0, 0 );
382 #else /* !NEW_LOGGING */
383 Debug( LDAP_DEBUG_ANY, "QUERY ANSWERABLE\n", 0, 0, 0 );
384 #endif /* !NEW_LOGGING */
385 rewriteSession(li->rwinfo, "cacheBase", op->o_req_dn.bv_val,
386 op->o_conn, &cbase, result);
387 if (result->type != SUCCESS) {
388 ldap_pvt_thread_rdwr_runlock(&qm->templates[i].t_rwlock);
391 if ( cbase == NULL ) {
392 cachebase = op->o_req_dn;
394 cachebase.bv_val = cbase;
395 cachebase.bv_len = strlen(cbase);
397 dnNormalize(0, NULL, NULL, &cachebase, &ncachebase,
400 /* FIXME: safe default? */
403 op_tmp.o_bd = li->glue_be;
404 op_tmp.o_req_dn = cachebase;
405 op_tmp.o_req_ndn = ncachebase;
407 op_tmp.o_caching_on = 0;
408 op_tmp.o_callback = &cb;
410 li->glue_be->be_search(&op_tmp, rs);
411 free( ncachebase.bv_val );
412 if ( cachebase.bv_val != op->o_req_dn.bv_val ) {
413 /* free only if rewritten */
414 free( cachebase.bv_val );
417 ldap_pvt_thread_rdwr_runlock(&qm->templates[i].t_rwlock);
422 LDAP_LOG( BACK_META, DETAIL1, "QUERY NOT ANSWERABLE\n",
424 #else /* !NEW_LOGGING */
425 Debug( LDAP_DEBUG_ANY, "QUERY NOT ANSWERABLE\n", 0, 0, 0 );
426 #endif /* !NEW_LOGGING */
428 if ( op->ors_scope == LDAP_SCOPE_BASE ) {
429 op_type = META_OP_REQUIRE_SINGLE;
431 op_type = META_OP_ALLOW_MULTIPLE;
434 lc = metaConnect(&op_tmp, rs, op_type,
435 &op->o_req_ndn, result);
437 if (result->type != SUCCESS)
440 ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
441 if (cm->num_cached_queries >= cm->max_queries) {
444 ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
447 add_filter_attrs(&new_attrs, attrs, filter_attrs);
455 * Array of message id of each target
457 msgid = ch_calloc( sizeof( int ), li->ntargets );
458 if ( msgid == NULL ) {
459 result->type = CONN_ERR;
464 if (slimit > 0 && (slimit <= cm->num_entries_limit))
465 slimit = cm->num_entries_limit;
472 for ( i = 0, lsc = lc->conns; !META_LAST(lsc); ++i, ++lsc ) {
473 char *realbase = ( char * )op->o_req_dn.bv_val;
474 int realscope = op->ors_scope;
476 char *mapped_filter, **mapped_attrs;
478 /* FIXME: Check for more than one targets */
479 if ( meta_back_is_candidate(
480 &li->targets[i]->suffix,
482 lsc->candidate = META_CANDIDATE;
484 if ( lsc->candidate != META_CANDIDATE )
487 if ( op->ors_deref != -1 ) {
488 ldap_set_option( lsc->ld, LDAP_OPT_DEREF,
489 ( void * )&op->ors_deref);
491 if ( op->ors_tlimit != -1 ) {
492 ldap_set_option( lsc->ld, LDAP_OPT_TIMELIMIT,
493 ( void * )&op->ors_tlimit);
495 if ( op->ors_slimit != -1 ) {
496 ldap_set_option( lsc->ld, LDAP_OPT_SIZELIMIT,
497 ( void * )&op->ors_slimit);
501 * modifies the base according to the scope, if required
503 suffixlen = li->targets[ i ]->suffix.bv_len;
504 if ( suffixlen > op->o_req_ndn.bv_len ) {
505 switch ( op->ors_scope ) {
506 case LDAP_SCOPE_SUBTREE:
508 * make the target suffix the new base
509 * FIXME: this is very forgiving,
510 * because illegal bases may be turned
511 * into the suffix of the target.
514 &li->targets[ i ]->suffix,
517 li->targets[i]->suffix.bv_val;
520 * this target is no longer
529 case LDAP_SCOPE_ONELEVEL:
530 if ( is_one_level_rdn(
531 li->targets[ i ]->suffix.bv_val,
532 suffixlen - op->o_req_ndn.bv_len - 1 )
534 &li->targets[ i ]->suffix,
537 * if there is exactly one
538 * level, make the target suffix
539 * the new base, and make scope
543 li->targets[i]->suffix.bv_val;
544 realscope = LDAP_SCOPE_BASE;
546 } /* else continue with the next case */
548 case LDAP_SCOPE_BASE:
550 * this target is no longer candidate
552 lsc->candidate = META_NOT_CANDIDATE;
558 * Rewrite the search base, if required
561 rewriteSession(li->targets[i]->rwmap.rwm_rw,
563 realbase, op->o_conn, &mbase, result);
565 if (result->type != SUCCESS)
568 if ( mbase == NULL ) {
573 * Rewrite the search filter, if required
575 rewriteSession( li->targets[i]->rwmap.rwm_rw,
577 op->ors_filterstr.bv_val, op->o_conn,
578 &mfilter.bv_val, result);
579 if (result->type != SUCCESS)
582 if ( mfilter.bv_val != NULL && mfilter.bv_val[ 0 ]
584 mfilter.bv_len = strlen( mfilter.bv_val );
586 if ( mfilter.bv_val != NULL ) {
587 free( mfilter.bv_val );
589 mfilter = op->ors_filterstr;
594 * Maps attributes in filter
596 mapped_filter = ldap_back_map_filter(
597 &li->targets[i]->rwmap.rwm_at,
598 &li->targets[i]->rwmap.rwm_oc,
600 if ( mapped_filter == NULL ) {
601 mapped_filter = ( char * )mfilter.bv_val;
603 if ( mfilter.bv_val != op->ors_filterstr.bv_val ) {
604 free( mfilter.bv_val );
607 mfilter.bv_val = NULL;
610 mapped_filter = (char *) mfilter.bv_val;
614 * Maps required attributes
616 if ( ldap_back_map_attrs(
617 &li->targets[ i ]->rwmap.rwm_at,
618 new_attrs, 0, &mapped_attrs ) ) {
625 msgid[ i ] = ldap_search( lsc->ld, mbase, realscope,
626 mapped_filter, mapped_attrs,
629 if ( msgid[ i ] == -1 ) {
630 result->type = CONN_ERR;
633 lsc->candidate = META_NOT_CANDIDATE;
638 if ( mapped_attrs ) {
639 free( mapped_attrs );
643 if ( mapped_filter != op->ors_filterstr.bv_val ) {
644 free( mapped_filter );
645 mapped_filter = NULL;
648 if ( mbase != realbase ) {
656 num_entries = handleLdapResult(lc, &op_tmp, rs, msgid,
658 op->ors_attrsonly, candidates,
659 cacheable, &entry_array,
660 curr_limit, op->ors_slimit, result);
662 if (result->type != SUCCESS)
664 if (cacheable && (num_entries <= curr_limit)) {
667 LDAP_LOG( BACK_META, DETAIL1,
668 "QUERY CACHEABLE\n", 0, 0, 0 );
669 #else /* !NEW_LOGGING */
670 Debug( LDAP_DEBUG_ANY, "QUERY CACHEABLE\n", 0, 0, 0 );
671 #endif /* !NEW_LOGGING */
672 op_tmp.o_bd = li->glue_be;
673 uuid = cache_entries(&op_tmp, rs, entry_array, cm, result);
675 LDAP_LOG( BACK_META, DETAIL1,
676 "Added query %s UUID %s ENTRIES %d\n",
677 op->ors_filterstr.bv_val,
679 #else /* !NEW_LOGGING */
680 Debug( LDAP_DEBUG_ANY,
681 "Added query %s UUID %s ENTRIES %d\n",
682 op->ors_filterstr.bv_val,
684 #endif /* !NEW_LOGGING */
686 if (result->type != SUCCESS)
688 (*(qm->addfunc))(qm, &query, template_id, uuid, result);
689 if (result->type != SUCCESS)
694 /* FIXME : launch do_syncrepl() threads around here
696 * entryUUID and entryCSN need also to be requested by :
699 msgid[ i ] = ldap_search( lsc->ld, mbase, realscope,
700 mapped_filter, mapped_attrs, op->ors_attrsonly );
702 /* Also, mbase, realscope, mapped_filter, mapped_attrs need
703 * be managed as arrays. Each element needs to be retained by this point.
708 LDAP_LOG( BACK_META, DETAIL1,
709 "QUERY NOT CACHEABLE no\n",
711 #else /* !NEW_LOGGING */
712 Debug( LDAP_DEBUG_ANY, "QUERY NOT CACHEABLE no\n",
714 #endif /* !NEW_LOGGING */
719 switch (result->type) {
726 LDAP_LOG( BACK_META, DETAIL1,
727 "Invalid template error\n", 0, 0, 0 );
728 #else /* !NEW_LOGGING */
729 Debug( LDAP_DEBUG_ANY, "Invalid template error\n",
731 #endif /* !NEW_LOGGING */
737 LDAP_LOG( BACK_META, DETAIL1,
738 "Could not connect to a remote server\n",
740 #else /* !NEW_LOGGING */
741 Debug( LDAP_DEBUG_ANY,
742 "Could not connect to a remote server\n",
744 #endif /* !NEW_LOGGING */
745 send_ldap_error(op, rs, LDAP_OTHER,
746 "Connection error" );
752 LDAP_LOG( BACK_META, DETAIL1,
753 "Error in handling ldap_result\n", 0, 0, 0 );
754 #else /* !NEW_LOGGING */
755 Debug( LDAP_DEBUG_ANY,
756 "Error in handling ldap_result\n", 0, 0, 0 );
757 #endif /* !NEW_LOGGING */
762 if (result->rc == REWRITE_REGEXEC_UNWILLING) {
763 send_ldap_error( op, rs,
764 LDAP_UNWILLING_TO_PERFORM,
765 "Unwilling to perform" );
767 send_ldap_error( op, rs, LDAP_OTHER,
775 LDAP_LOG( BACK_META, DETAIL1,
776 "Error in merging entry \n", 0, 0, 0 );
777 #else /* !NEW_LOGGING */
778 Debug( LDAP_DEBUG_ANY,
779 "Error in merging entry \n", 0, 0, 0 );
780 #endif /* !NEW_LOGGING */
786 LDAP_LOG( BACK_META, DETAIL1,
787 "Error in removing query \n",
789 #else /* !NEW_LOGGING */
790 Debug( LDAP_DEBUG_ANY, "Error in removing query \n",
792 #endif /* !NEW_LOGGING */
805 for (i=0; (e = entry_array[i]); i++) {
814 if (new_attrs != attrs)
821 if (tempstr.bv_val ) {
822 free(tempstr.bv_val);
824 ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
827 LDAP_LOG( BACK_META, DETAIL1, "Threads-- = %d\n", cm->threads, 0, 0 );
828 #else /* !NEW_LOGGING */
829 Debug( LDAP_DEBUG_ANY, "Threads-- = %d\n", cm->threads, 0, 0 );
830 #endif /* !NEW_LOGGING */
831 ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
842 struct exception* result
845 struct metainfo *li = ( struct metainfo * )be->be_private;
846 struct berval a, mapped;
848 BerElement ber = *e->lm_ber;
849 Attribute *attr, *soc_attr, **attrp;
850 struct berval dummy = { 0, NULL };
851 struct berval *bv, bdn;
858 if ( ber_scanf( &ber, "{m{", &bdn ) == LBER_ERROR ) {
859 result->type = CREATE_ENTRY_ERR;
862 ent = (Entry*)malloc(sizeof(Entry));
865 * Rewrite the dn of the result, if needed
867 rewriteSession( li->targets[ target ]->rwmap.rwm_rw, "searchResult",
868 bdn.bv_val, lc->conn, &ent->e_name.bv_val, result );
870 if (result->type != SUCCESS) {
873 if ( ent->e_name.bv_val == NULL ) {
874 ber_dupbv(&(ent->e_name), &bdn);
877 LDAP_LOG( BACK_META, DETAIL1,
878 "[rw] searchResult[%d]: \"%s\" -> \"%s\"\n",
879 target, bdn.bv_val, ent->e_name.bv_val );
880 #else /* !NEW_LOGGING */
881 Debug( LDAP_DEBUG_ARGS, "rw> searchResult[%d]: \"%s\""
883 target, bdn.bv_val, ent->e_name.bv_val );
884 #endif /* !NEW_LOGGING */
885 ent->e_name.bv_len = strlen( ent->e_name.bv_val );
889 * Note: this may fail if the target host(s) schema differs
890 * from the one known to the meta, and a DN with unknown
891 * attributes is returned.
893 * FIXME: should we log anything, or delegate to dnNormalize?
895 dnNormalize( 0, NULL, NULL, &ent->e_name, &ent->e_nname, NULL );
898 if ( dnNormalize( 0, NULL, NULL, &ent->e_name, &ent->e_nname )
901 return LDAP_INVALID_DN_SYNTAX;
908 if ( li->cache.ttl != META_DNCACHE_DISABLED ) {
909 meta_dncache_update_entry( &li->cache, &ent->e_nname, target );
915 ent->e_bv.bv_val = 0;
917 attrp = &ent->e_attrs;
919 while ( ber_scanf( &ber, "{m", &a ) != LBER_ERROR ) {
920 ldap_back_map( &li->targets[ target ]->rwmap.rwm_at,
922 if ( mapped.bv_val == NULL ) {
925 attr = ( Attribute * )ch_malloc( sizeof( Attribute ) );
926 if ( attr == NULL ) {
932 attr->a_nvals = NULL;
933 if ( slap_bv2ad( &mapped, &attr->a_desc, &text ) != LDAP_SUCCESS) {
934 if ( slap_bv2undef_ad( &mapped, &attr->a_desc, &text )
937 LDAP_LOG( BACK_META, DETAIL1,
938 "slap_bv2undef_ad(%s): %s\n",
939 mapped.bv_val, text, 0 );
940 #else /* !NEW_LOGGING */
941 Debug( LDAP_DEBUG_ANY,
942 "slap_bv2undef_ad(%s): "
943 "%s\n%s", mapped.bv_val, text, "" );
944 #endif /* !NEW_LOGGING */
950 /* no subschemaSubentry */
951 if ( attr->a_desc == slap_schema.si_ad_subschemaSubentry ) {
956 if ( ber_scanf( &ber, "[W]", &attr->a_vals ) == LBER_ERROR
957 || attr->a_vals == NULL ) {
958 attr->a_vals = &dummy;
960 } else if ( attr->a_desc == slap_schema.si_ad_objectClass ||
962 slap_schema.si_ad_structuralObjectClass) {
964 } else if ( attr->a_desc == slap_schema.si_ad_objectClass ) {
967 for ( last = 0; attr->a_vals[ last ].bv_val; ++last )
969 for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++,i++ ) {
970 ldap_back_map( &li->targets[ target]->rwmap.rwm_oc,
972 if ( mapped.bv_val == NULL ) {
978 *bv = attr->a_vals[ last ];
979 attr->a_vals[ last ].bv_val = NULL;
981 } else if ( mapped.bv_val != bv->bv_val ) {
983 ber_dupbv( bv, &mapped );
987 structural_class( attr->a_vals, &sc, NULL, &text, textbuf, textlen );
988 soc_attr = (Attribute*) ch_malloc( sizeof( Attribute ));
989 soc_attr->a_desc = slap_schema.si_ad_structuralObjectClass;
990 soc_attr->a_vals = (BerVarray) ch_malloc( 2* sizeof( BerValue ));
991 ber_dupbv( &soc_attr->a_vals[0], &sc );
992 soc_attr->a_vals[1].bv_len = 0;
993 soc_attr->a_vals[1].bv_val = NULL;
994 soc_attr->a_nvals = (BerVarray) ch_malloc( 2* sizeof( BerValue ));
995 ber_dupbv( &soc_attr->a_nvals[0], &sc );
996 soc_attr->a_nvals[1].bv_len = 0;
997 soc_attr->a_nvals[1].bv_val = NULL;
1000 attrp = &soc_attr->a_next;
1003 * It is necessary to try to rewrite attributes with
1004 * dn syntax because they might be used in ACLs as
1005 * members of groups; since ACLs are applied to the
1006 * rewritten stuff, no dn-based subecj clause could
1007 * be used at the ldap backend side (see
1008 * http://www.OpenLDAP.org/faq/data/cache/452.html)
1009 * The problem can be overcome by moving the dn-based
1010 * ACLs to the target directory server, and letting
1011 * everything pass thru the ldap backend.
1013 } else if ( strcmp( attr->a_desc->ad_type->sat_syntax->ssyn_oid,
1014 SLAPD_DN_SYNTAX ) == 0 ) {
1016 for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++,i++ ) {
1018 rewriteSession(li->targets[ target ]->rwmap.rwm_rw,
1019 "searchResult", bv->bv_val,
1020 lc->conn, &newval, result);
1021 if (result->type != SUCCESS) {
1022 /* FIXME : Handle error */
1023 result->type = SUCCESS;
1026 if ( newval == NULL ) {
1030 LDAP_LOG( BACK_META, DETAIL1,
1031 "[rw] searchResult on "
1032 "attr=%s: \"%s\" -> \"%s\"\n",
1033 attr->a_desc->ad_type->
1035 bv->bv_val, newval );
1036 #else /* !NEW_LOGGING */
1037 Debug( LDAP_DEBUG_ARGS,
1038 "rw> searchResult on attr=%s:"
1039 " \"%s\" -> \"%s\"\n",
1040 attr->a_desc->ad_type->
1042 bv->bv_val, newval );
1043 #endif /* !NEW_LOGGING */
1045 bv->bv_val = newval;
1046 bv->bv_len = strlen( newval );
1051 attrp = &attr->a_next;
1064 if ( DN_SEPARATOR( rdn[ from ] ) ) {
1071 static struct metaconn*
1076 struct berval *nbase,
1077 struct exception *result)
1079 struct metaconn *lc;
1081 result->type = SUCCESS;
1082 lc = meta_back_getconn( op, rs, op_type, nbase, NULL );
1084 result->type = CONN_ERR;
1092 AttributeName** new_attrs,
1093 AttributeName* attrs,
1094 AttributeName* filter_attrs )
1096 struct berval all_user = { sizeof(LDAP_ALL_USER_ATTRIBUTES) -1,
1097 LDAP_ALL_USER_ATTRIBUTES };
1099 struct berval all_op = { sizeof(LDAP_ALL_OPERATIONAL_ATTRIBUTES) -1,
1100 LDAP_ALL_OPERATIONAL_ATTRIBUTES};
1107 /* duplicate attrs */
1108 if (attrs == NULL) {
1111 for (count=0; attrs[count].an_name.bv_val; count++)
1114 *new_attrs = (AttributeName*)(malloc((count+1)*sizeof(AttributeName)));
1115 if (attrs == NULL) {
1116 (*new_attrs)[0].an_name.bv_val = "*";
1117 (*new_attrs)[0].an_name.bv_len = 1;
1118 (*new_attrs)[1].an_name.bv_val = NULL;
1119 (*new_attrs)[1].an_name.bv_len = 0;
1123 for (i=0; i<count; i++) {
1124 (*new_attrs)[i].an_name = attrs[i].an_name;
1125 (*new_attrs)[i].an_desc = attrs[i].an_desc;
1127 (*new_attrs)[count].an_name.bv_val = NULL;
1128 (*new_attrs)[count].an_name.bv_len = 0;
1129 alluser = an_find(*new_attrs, &all_user);
1130 allop = an_find(*new_attrs, &all_op);
1133 for ( i=0; filter_attrs[i].an_name.bv_val; i++ ) {
1134 if ( an_find(*new_attrs, &filter_attrs[i].an_name ))
1136 if ( is_at_operational(filter_attrs[i].an_desc->ad_type) ) {
1141 *new_attrs = (AttributeName*)(realloc(*new_attrs,
1142 (count+2)*sizeof(AttributeName)));
1143 (*new_attrs)[count].an_name.bv_val =
1144 filter_attrs[i].an_name.bv_val;
1145 (*new_attrs)[count].an_name.bv_len =
1146 filter_attrs[i].an_name.bv_len;
1147 (*new_attrs)[count].an_desc = filter_attrs[i].an_desc;
1148 (*new_attrs)[count+1].an_name.bv_val = NULL;
1149 (*new_attrs)[count+1].an_name.bv_len = 0;
1156 struct metaconn* lc,
1159 int* msgid, Backend* be,
1160 AttributeName* attrs,
1164 Entry*** entry_array,
1167 struct exception* result)
1170 char *match = NULL, *err = NULL, *cache_ename = NULL;
1172 int mres = LDAP_SUCCESS;
1173 int num_entries = 0, count, i, rc;
1174 struct timeval tv = {0, 0};
1175 struct metasingleconn* lsc;
1176 struct metainfo *li = ( struct metainfo * )be->be_private;
1178 result->type = SUCCESS;
1180 for ( count = 0, rc = 0; candidates > 0; ) {
1183 /* check for abandon */
1186 for ( i = 0, lsc = lc->conns; !META_LAST(lsc); lsc++, i++ ) {
1187 if ( lsc->candidate != META_CANDIDATE ) {
1192 ldap_abandon( lsc->ld, msgid[ i ] );
1193 result->type = ABANDON_ERR;
1197 if ( slimit > 0 && num_entries == slimit ) {
1198 result->type = SLIMIT_ERR;
1202 if ((entry = get_result_entry(be, lc, lsc,
1203 msgid, i, &tv, result))) {
1204 rs->sr_entry = entry;
1205 rs->sr_attrs = op->ors_attrs;
1206 send_search_entry( op, rs );
1207 rs->sr_entry = NULL;
1208 rs->sr_attrs = NULL;
1210 (num_entries < curr_limit)) {
1211 rewriteSession( li->rwinfo,
1213 entry->e_name.bv_val,
1215 &cache_ename, result );
1216 free(entry->e_name.bv_val);
1217 if (result->type != SUCCESS) {
1220 ber_str2bv(cache_ename,
1221 strlen(cache_ename),
1223 ber_dupbv(&entry->e_nname,
1225 *entry_array = (Entry**)realloc(
1227 (( num_entries+2 ) *
1229 (*entry_array)[num_entries] = entry;
1230 (*entry_array)[num_entries+1] = NULL;
1234 } else if (result->type == REWRITING_ERR) {
1236 } else if (result->type == TIMEOUT_ERR) {
1237 result->type = SUCCESS;
1239 } else if (result->type == CREATE_ENTRY_ERR) {
1241 } else if (result->rc == -1) {
1244 rs->sr_err = result->rc;
1245 sres = ldap_back_map_result(rs);
1246 if (mres == LDAP_SUCCESS &&
1247 sres != LDAP_SUCCESS) {
1249 ldap_get_option(lsc->ld,
1250 LDAP_OPT_ERROR_STRING, &err);
1251 ldap_get_option(lsc->ld,
1252 LDAP_OPT_MATCHED_DN, &match);
1254 lsc->candidate = META_NOT_CANDIDATE;
1256 result->type = SUCCESS;
1259 switch (result->type) {
1262 LDAP_LOG( BACK_META, DETAIL1,
1263 "ldap_result error, rc = -1\n",
1265 #else /* !NEW_LOGGING */
1266 Debug( LDAP_DEBUG_ANY, "ldap_result error, rc = -1\n",
1268 #endif /* !NEW_LOGGING */
1269 rs->sr_err = LDAP_OTHER;
1270 send_ldap_result( op, rs );
1273 case CREATE_ENTRY_ERR:
1275 LDAP_LOG( BACK_META, DETAIL1,
1276 "Error in parsing result \n",
1278 #else /* !NEW_LOGGING */
1279 Debug( LDAP_DEBUG_ANY, "Error in parsing result \n",
1281 #endif /* !NEW_LOGGING */
1282 rs->sr_err = LDAP_OTHER;
1283 send_ldap_result( op, rs );
1284 result->type = RESULT_ERR;
1289 LDAP_LOG( BACK_META, DETAIL1, "Size limit exceeded \n",
1291 #else /* !NEW_LOGGING */
1292 Debug( LDAP_DEBUG_ANY, "Size limit exceeded \n",
1294 #endif /* !NEW_LOGGING */
1295 rs->sr_err = LDAP_SIZELIMIT_EXCEEDED;
1296 send_ldap_result( op, rs );
1297 result->type = RESULT_ERR;
1302 LDAP_LOG( BACK_META, DETAIL1,
1303 "search operation abandoned \n",
1305 #else /* !NEW_LOGGING */
1306 Debug( LDAP_DEBUG_ANY, "search operation abandoned \n",
1308 #endif /* !NEW_LOGGING */
1309 result->type = RESULT_ERR;
1318 tv.tv_usec = 100000;
1319 ldap_pvt_thread_yield();
1328 rs->sr_matched = match;
1330 send_ldap_result( op, rs );
1333 rs->sr_matched = NULL;
1341 result->type = (mres == LDAP_SUCCESS) ? SUCCESS : RESULT_ERR;
1348 struct metaconn* lc,
1349 struct metasingleconn* lsc,
1353 struct exception* result)
1356 LDAPMessage *res, *e;
1358 int sres = LDAP_SUCCESS;
1360 rc = ldap_result( lsc->ld, msgid[ i ],
1364 result->type = TIMEOUT_ERR;
1366 } else if ( rc == -1 ) {
1368 result->type = RESULT_ERR;
1370 } else if ( rc == LDAP_RES_SEARCH_ENTRY ) {
1371 e = ldap_first_entry( lsc->ld, res );
1372 entry = meta_create_entry(be, lc, i, e, result);
1376 ldap_msgfree( res );
1377 result->type = SUCCESS;
1380 sres = ldap_result2error( lsc->ld,
1383 result->type = RESULT_ERR;
1390 struct rewrite_info* info,
1391 const char* rewriteContext,
1395 struct exception* result)
1397 int rc = rewrite_session(info, rewriteContext, string, cookie, base);
1398 if (rc != REWRITE_REGEXEC_OK) {
1400 result->type = REWRITING_ERR;
1402 if (strcmp(rewriteContext, "searchBase") == 0)
1404 LDAP_LOG( BACK_META, DETAIL1,
1405 "Problem in rewriting search base\n", 0, 0, 0 );
1406 #else /* !NEW_LOGGING */
1407 Debug( LDAP_DEBUG_ANY,
1408 "Problem in rewriting search base\n", 0, 0, 0 );
1409 #endif /* !NEW_LOGGING */
1410 if (strcmp(rewriteContext, "searchFilter") == 0)
1412 LDAP_LOG( BACK_META, DETAIL1,
1413 "Problem in rewriting search filter\n",
1415 #else /* !NEW_LOGGING */
1416 Debug( LDAP_DEBUG_ANY,
1417 "Problem in rewriting search filter\n",
1419 #endif /* !NEW_LOGGING */
1420 if (strcmp(rewriteContext, "searchResult") == 0)
1422 LDAP_LOG( BACK_META, DETAIL1,
1423 "Problem in rewriting DN, or DN syntax "
1424 "attributes of search result\n", 0, 0, 0 );
1425 #else /* !NEW_LOGGING */
1426 Debug( LDAP_DEBUG_ANY,
1427 "Problem in rewriting DN, or DN syntax "
1428 "attributes of search result\n", 0, 0, 0 );
1429 #endif /* !NEW_LOGGING */
1430 if (strcmp(rewriteContext, "cacheBase") == 0)
1432 LDAP_LOG( BACK_META, DETAIL1,
1433 "Problem in rewriting search base with "
1434 "cache base\n", 0, 0, 0 );
1435 #else /* !NEW_LOGGING */
1436 Debug( LDAP_DEBUG_ANY,
1437 "Problem in rewriting search base with "
1438 "cache base\n", 0, 0, 0 );
1439 #endif /* !NEW_LOGGING */
1440 if (strcmp(rewriteContext, "cacheResult") == 0)
1442 LDAP_LOG( BACK_META, DETAIL1,
1443 "Problem in rewriting DN for cached entries\n",
1445 #else /* !NEW_LOGGING */
1446 Debug( LDAP_DEBUG_ANY,
1447 "Problem in rewriting DN for cached entries\n",
1449 #endif /* !NEW_LOGGING */
1450 if (strcmp(rewriteContext, "cacheReturn") == 0)
1452 LDAP_LOG( BACK_META, DETAIL1,
1453 "Problem in rewriting DN for answerable "
1454 "entries\n", 0, 0, 0 );
1455 #else /* !NEW_LOGGING */
1456 Debug( LDAP_DEBUG_ANY,
1457 "Problem in rewriting DN for answerable "
1458 "entries\n", 0, 0, 0 );
1459 #endif /* !NEW_LOGGING */
1461 result->type = SUCCESS;
1467 AttributeName* attrs,
1472 for (i=0; i<num; i++) {
1473 if (attrscmp(attrs, qm->attr_sets[i].attrs))
1481 AttributeName* attrs_in,
1482 AttributeName* attrs)
1484 int i, count1, count2;
1485 if ( attrs_in == NULL ) {
1486 return (attrs ? 0 : 1);
1488 if ( attrs == NULL )
1492 attrs_in && attrs_in[count1].an_name.bv_val != NULL;
1496 attrs && attrs[count2].an_name.bv_val != NULL;
1499 if ( count1 != count2 )
1502 for ( i=0; i<count1; i++ ) {
1503 if ( !an_find(attrs, &attrs_in[i].an_name ))
1513 Entry** entry_array,
1515 struct exception* result)
1521 struct berval query_uuid;
1522 struct berval crp_uuid;
1523 char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ], *crpid;
1525 query_manager *qm = cm->qm;
1527 result->type = SUCCESS;
1528 query_uuid.bv_len = lutil_uuidstr(uuidbuf, sizeof(uuidbuf));
1529 query_uuid.bv_val = ch_strdup(uuidbuf);
1532 LDAP_LOG( BACK_META, DETAIL1, "UUID for query being added = %s\n",
1534 #else /* !NEW_LOGGING */
1535 Debug( LDAP_DEBUG_ANY, "UUID for query being added = %s\n",
1537 #endif /* !NEW_LOGGING */
1539 for ( i=0; ( entry_array && (e=entry_array[i]) ); i++ ) {
1541 LDAP_LOG( BACK_META, DETAIL2, "LOCKING REMOVE MUTEX\n",
1543 #else /* !NEW_LOGGING */
1544 Debug( LDAP_DEBUG_NONE, "LOCKING REMOVE MUTEX\n", 0, 0, 0 );
1545 #endif /* !NEW_LOGGING */
1546 ldap_pvt_thread_mutex_lock(&cm->remove_mutex);
1548 LDAP_LOG( BACK_META, DETAIL2, "LOCKED REMOVE MUTEX\n", 0, 0, 0);
1549 #else /* !NEW_LOGGING */
1550 Debug( LDAP_DEBUG_NONE, "LOCKED REMOVE MUTEX\n", 0, 0, 0);
1551 #endif /* !NEW_LOGGING */
1552 if ( cm->cache_size > (cm->thresh_hi) ) {
1553 while(cm->cache_size > (cm->thresh_lo)) {
1554 crpid = cache_replacement(qm);
1555 if (crpid == NULL) {
1556 result->type = REMOVE_ERR;
1558 strcpy(crpuuid, crpid);
1559 crp_uuid.bv_val = crpuuid;
1560 crp_uuid.bv_len = strlen(crpuuid);
1562 LDAP_LOG( BACK_META, DETAIL1,
1563 "Removing query UUID %s\n",
1565 #else /* !NEW_LOGGING */
1566 Debug( LDAP_DEBUG_ANY,
1567 "Removing query UUID %s\n",
1569 #endif /* !NEW_LOGGING */
1570 return_val = remove_query_data(op, rs,
1573 LDAP_LOG( BACK_META, DETAIL1,
1574 "QUERY REMOVED, SIZE=%d\n",
1576 #else /* !NEW_LOGGING */
1577 Debug( LDAP_DEBUG_ANY,
1578 "QUERY REMOVED, SIZE=%d\n",
1580 #endif /* !NEW_LOGGING */
1581 ldap_pvt_thread_mutex_lock(
1583 cm->total_entries -= result->rc;
1584 cm->num_cached_queries--;
1586 LDAP_LOG( BACK_META, DETAIL1,
1587 "STORED QUERIES = %lu\n",
1588 cm->num_cached_queries, 0, 0 );
1589 #else /* !NEW_LOGGING */
1590 Debug( LDAP_DEBUG_ANY,
1591 "STORED QUERIES = %lu\n",
1592 cm->num_cached_queries, 0, 0 );
1593 #endif /* !NEW_LOGGING */
1594 ldap_pvt_thread_mutex_unlock(
1596 cm->cache_size = (return_val >
1598 0 : (cm->cache_size-return_val);
1600 LDAP_LOG( BACK_META, DETAIL1,
1601 "QUERY REMOVED, CACHE SIZE="
1602 "%lu bytes %d entries\n",
1604 cm->total_entries, 0 );
1605 #else /* !NEW_LOGGING */
1606 Debug( LDAP_DEBUG_ANY,
1607 "QUERY REMOVED, CACHE SIZE="
1608 "%lu bytes %d entries\n",
1610 cm->total_entries, 0 );
1611 #endif /* !NEW_LOGGING */
1617 return_val = merge_entry(op, rs, &query_uuid, result);
1618 rs->sr_entry = NULL;
1619 cm->cache_size += return_val;
1621 LDAP_LOG( BACK_META, DETAIL1,
1622 "ENTRY ADDED/MERGED, CACHE SIZE=%lu bytes\n",
1623 cm->cache_size, 0, 0 );
1624 #else /* !NEW_LOGGING */
1625 Debug( LDAP_DEBUG_ANY,
1626 "ENTRY ADDED/MERGED, CACHE SIZE=%lu bytes\n",
1627 cm->cache_size, 0, 0 );
1628 #endif /* !NEW_LOGGING */
1630 LDAP_LOG( BACK_META, DETAIL2, "UNLOCKING REMOVE MUTEX\n",
1632 #else /* !NEW_LOGGING */
1633 Debug( LDAP_DEBUG_NONE, "UNLOCKING REMOVE MUTEX\n", 0, 0, 0 );
1634 #endif /* !NEW_LOGGING */
1635 ldap_pvt_thread_mutex_unlock(&cm->remove_mutex);
1637 LDAP_LOG( BACK_META, DETAIL2, "UNLOCKED REMOVE MUTEX\n",
1639 #else /* !NEW_LOGGING */
1640 Debug( LDAP_DEBUG_NONE, "UNLOCKED REMOVE MUTEX\n", 0, 0, 0 );
1641 #endif /* !NEW_LOGGING */
1642 if (result->type != SUCCESS)
1644 ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
1645 cm->total_entries += result->rc;
1647 LDAP_LOG( BACK_META, DETAIL1,
1648 "ENTRY ADDED/MERGED, SIZE=%d, CACHED ENTRIES=%d\n",
1649 return_val, cm->total_entries, 0 );
1650 #else /* !NEW_LOGGING */
1651 Debug( LDAP_DEBUG_ANY,
1652 "ENTRY ADDED/MERGED, SIZE=%d, CACHED ENTRIES=%d\n",
1653 return_val, cm->total_entries, 0 );
1654 #endif /* !NEW_LOGGING */
1655 ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
1657 ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
1658 cm->num_cached_queries++;
1660 LDAP_LOG( BACK_META, DETAIL1, "STORED QUERIES = %lu\n",
1661 cm->num_cached_queries, 0, 0 );
1662 #else /* !NEW_LOGGING */
1663 Debug( LDAP_DEBUG_ANY, "STORED QUERIES = %lu\n",
1664 cm->num_cached_queries, 0, 0 );
1665 #endif /* !NEW_LOGGING */
1666 ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
1668 return query_uuid.bv_val;
1674 struct berval* tempstr,
1682 i = qm->templates[template_id].attr_set_index;
1683 str = qm->templates[template_id].querystr;
1685 if (attr_set == i) {
1688 id_array = qm->attr_sets[attr_set].ID_array;
1690 while (*id_array != -1) {
1698 if (strcasecmp(str, tempstr->bv_val) == 0)
1704 consistency_check(void* operation)
1706 Operation* op = (Operation*)operation;
1708 SlapReply rs = {REP_RESULT};
1710 struct metainfo *li = ( struct metainfo * )op->o_bd->be_private;
1711 cache_manager* cm = li->cm;
1712 query_manager* qm = cm->qm;
1713 CachedQuery* query, *query_prev;
1716 struct exception result;
1718 QueryTemplate* templ;
1721 op->o_bd = li->glue_be;
1724 ldap_pvt_thread_sleep(cm->cc_period);
1725 for (i=0; qm->templates[i].querystr; i++) {
1726 templ = qm->templates + i;
1727 query = templ->query_last;
1728 curr_time = slap_get_time();
1729 ldap_pvt_thread_mutex_lock(&cm->remove_mutex);
1730 while (query && (query->expiry_time < curr_time)) {
1731 ldap_pvt_thread_mutex_lock(&qm->lru_mutex);
1732 remove_query(qm, query);
1733 ldap_pvt_thread_mutex_unlock(&qm->lru_mutex);
1735 LDAP_LOG( BACK_META, DETAIL1, "Lock CR index = %d\n",
1737 #else /* !NEW_LOGGING */
1738 Debug( LDAP_DEBUG_ANY, "Lock CR index = %d\n",
1740 #endif /* !NEW_LOGGING */
1741 ldap_pvt_thread_rdwr_wlock(&templ->t_rwlock);
1742 remove_from_template(query, templ);
1744 LDAP_LOG( BACK_META, DETAIL1,
1745 "TEMPLATE %d QUERIES-- %d\n",
1746 i, templ->no_of_queries, 0 );
1747 #else /* !NEW_LOGGING */
1748 Debug( LDAP_DEBUG_ANY, "TEMPLATE %d QUERIES-- %d\n",
1749 i, templ->no_of_queries, 0 );
1750 #endif /* !NEW_LOGGING */
1752 LDAP_LOG( BACK_META, DETAIL1, "Unlock CR index = %d\n",
1754 #else /* !NEW_LOGGING */
1755 Debug( LDAP_DEBUG_ANY, "Unlock CR index = %d\n",
1757 #endif /* !NEW_LOGGING */
1758 ldap_pvt_thread_rdwr_wunlock(&templ->t_rwlock);
1759 uuid.bv_val = query->q_uuid;
1760 uuid.bv_len = strlen(query->q_uuid);
1761 return_val = remove_query_data(op, &rs, &uuid, &result);
1763 LDAP_LOG( BACK_META, DETAIL1,
1764 "STALE QUERY REMOVED, SIZE=%d\n",
1766 #else /* !NEW_LOGGING */
1767 Debug( LDAP_DEBUG_ANY, "STALE QUERY REMOVED, SIZE=%d\n",
1769 #endif /* !NEW_LOGGING */
1770 ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
1771 cm->total_entries -= result.rc;
1772 cm->num_cached_queries--;
1774 LDAP_LOG( BACK_META, DETAIL1, "STORED QUERIES = %lu\n",
1775 cm->num_cached_queries, 0, 0 );
1776 #else /* !NEW_LOGGING */
1777 Debug( LDAP_DEBUG_ANY, "STORED QUERIES = %lu\n",
1778 cm->num_cached_queries, 0, 0 );
1779 #endif /* !NEW_LOGGING */
1780 ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
1781 cm->cache_size = (return_val > cm->cache_size) ?
1782 0: (cm->cache_size-return_val);
1784 LDAP_LOG( BACK_META, DETAIL1,
1785 "STALE QUERY REMOVED, CACHE SIZE=%lu bytes %d "
1786 "entries\n", cm->cache_size,
1787 cm->total_entries, 0 );
1788 #else /* !NEW_LOGGING */
1789 Debug( LDAP_DEBUG_ANY,
1790 "STALE QUERY REMOVED, CACHE SIZE=%lu bytes %d "
1791 "entries\n", cm->cache_size,
1792 cm->total_entries, 0 );
1793 #endif /* !NEW_LOGGING */
1795 query = query->prev;
1796 free_query(query_prev);
1798 ldap_pvt_thread_mutex_unlock(&cm->remove_mutex);
1808 slap_callback *cb = op->o_callback;
1809 /*struct metainfo *li = ( struct metainfo * )op->o_bd->be_private;*/
1810 Backend* be = (Backend*)(cb->sc_private);
1811 struct metainfo *li = ( struct metainfo * )be->be_private;
1814 struct exception result;
1818 if (rs->sr_type == REP_SEARCH) {
1819 dn = rs->sr_entry->e_name;
1820 ndn = rs->sr_entry->e_nname;
1822 rewriteSession( li->rwinfo, "cacheReturn",
1823 rs->sr_entry->e_name.bv_val, op->o_conn,
1825 ber_str2bv(ename, strlen(ename), 0, &rs->sr_entry->e_name);
1826 /* FIXME: should we normalize this? */
1827 ber_dupbv(&rs->sr_entry->e_nname, &rs->sr_entry->e_name);
1829 op->o_callback = NULL;
1831 send_search_entry( op, rs );
1833 rs->sr_entry->e_name = dn;
1834 rs->sr_entry->e_nname = ndn;
1836 op->o_callback = cb;
1838 } else if (rs->sr_type == REP_RESULT) {
1839 op->o_callback = NULL;
1840 send_ldap_result( op, rs );