-/*
- * Copyright (c) 2003 by International Business Machines, Inc.
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * International Business Machines, Inc. (hereinafter called IBM) grants
- * permission under its copyrights to use, copy, modify, and distribute this
- * Software with or without fee, provided that the above copyright notice and
- * all paragraphs of this notice appear in all copies, and that the name of IBM
- * not be used in connection with the marketing of any product incorporating
- * the Software or modifications thereof, without specific, written prior
- * permission.
+ * Copyright 1999-2003 The OpenLDAP Foundation.
+ * Portions Copyright 2003 IBM Corporation.
+ * All rights reserved.
*
- * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
- * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
- * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
*
- *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This work was initially developed by the Howard Chu for inclusion
+ * in OpenLDAP Software and subsequently enhanced by Pierangelo
+ * Masarati and Apurva Kumar.
+ */
+/* This is an altered version */
+/*
* This software is based on the backends back-ldap and back-meta, implemented
* by Howard Chu <hyc@highlandsun.com>, Mark Valence
* <kurash@sassafras.com>, Pierangelo Masarati <ando@sys-net.it> and other
#include <ac/string.h>
#include <ac/time.h>
+#include "ldap_pvt.h"
#include "lutil.h"
#include "slap.h"
#include "../back-ldap/back-ldap.h"
#include "back-meta.h"
-#include "ldap_pvt.h"
#undef ldap_debug /* silence a warning in ldap-int.h */
#include "ldap_log.h"
#include "../../../libraries/libldap/ldap-int.h"
-#include <sys/time.h>
-#ifdef LDAP_CACHING
static Entry*
meta_create_entry(
Backend *be,
static struct metaconn*
metaConnect(
- struct metainfo* li,
- Connection* conn,
- Operation* op,
- int op_type,
- struct berval* nbase,
- struct exception* result
+ Operation *op,
+ SlapReply *rs,
+ int op_type,
+ struct berval *nbase,
+ struct exception *result
);
static void
handleLdapResult(
struct metaconn* lc,
Operation* op,
+ SlapReply *rs,
int* msgid, Backend* be,
AttributeName* attrs,
int attrsonly,
static char*
cache_entries(
+ Operation *op,
+ SlapReply *rs,
Entry** entry_array,
cache_manager* cm,
- Backend* be,
- Connection* conn,
struct exception* result
);
int template_id
);
-static void
+static void*
consistency_check(
- Backend* be,
- Backend* glue_be,
- Connection* conn
+ void *op
);
static int
cache_back_sentry(
- Backend* be,
- Connection* conn,
Operation* op,
- Entry* e,
- AttributeName* attrs,
- int attrsonly,
- LDAPControl** ctrls
+ SlapReply *rs
);
+
int
meta_back_cache_search(
+ Operation *op,
+ SlapReply *rs )
+ /*
Backend *be,
Connection *conn,
Operation *op,
struct berval *filterstr,
AttributeName *attributes,
int attrsonly
-)
+) */
{
- struct metainfo *li = ( struct metainfo * )be->be_private;
+ struct metainfo *li = ( struct metainfo * )op->o_bd->be_private;
struct metaconn *lc;
struct metasingleconn *lsc;
cache_manager* cm = li->cm;
query_manager* qm = cm->qm;
+ Operation *oper;
+
time_t curr_time;
int count, rc = 0, *msgid = NULL;
int i = -1, last = 0, candidates = 0, op_type;
struct berval mfilter;
- struct berval *cachebase = NULL;
- struct berval *ncachebase = NULL;
+ struct berval cachebase = { 0L, NULL };
+ struct berval ncachebase = { 0L, NULL };
struct berval cache_suffix;
- struct berval tempstr = {0, 0};
+ struct berval tempstr = { 0L, NULL };
AttributeName *filter_attrs = NULL;
AttributeName *new_attrs = NULL;
int num_entries = 0;
int curr_limit;
int fattr_cnt=0;
+ int oc_attr_absent = 1;
-
struct exception result[1];
- Filter* filter = str2filter(filterstr->bv_val);
- slap_callback cb = {NULL, NULL, cache_back_sentry, NULL};
+ Filter* filter = str2filter(op->ors_filterstr.bv_val);
+ slap_callback cb = {cache_back_sentry, NULL};
- cb.sc_private = be;
+ cb.sc_private = op->o_bd;
- if (attributes) {
- for ( count=0; attributes[ count ].an_name.bv_val; count++ )
- ;
- attrs = (AttributeName*)malloc( ( count + 1 ) *
- sizeof(AttributeName));
- for ( count=0; attributes[ count ].an_name.bv_val; count++ ) {
+ if (op->ors_attrs) {
+ for ( count=0; op->ors_attrs[ count ].an_name.bv_val; count++ ) {
+ if ( op->ors_attrs[count].an_desc == slap_schema.si_ad_objectClass )
+ oc_attr_absent = 0;
+ }
+ attrs = (AttributeName*)malloc( ( count + 1 + oc_attr_absent )
+ *sizeof(AttributeName));
+ for ( count=0; op->ors_attrs[ count ].an_name.bv_val; count++ ) {
ber_dupbv(&attrs[ count ].an_name,
- &attributes[ count ].an_name);
- attrs[count].an_desc = attributes[count].an_desc;
+ &op->ors_attrs[ count ].an_name);
+ attrs[count].an_desc = op->ors_attrs[count].an_desc;
}
attrs[ count ].an_name.bv_val = NULL;
attrs[ count ].an_name.bv_len = 0;
Debug( LDAP_DEBUG_ANY, "Threads++ = %d\n", cm->threads, 0, 0 );
#endif /* !NEW_LOGGING */
ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
-
+
+ ldap_pvt_thread_mutex_lock(&cm->cc_mutex);
+ if (!cm->cc_thread_started) {
+ oper = (Operation*)malloc(sizeof(Operation));
+ *oper = *op;
+ cm->cc_thread_started = 1;
+ ldap_pvt_thread_create(&(cm->cc_thread), 1, consistency_check, (void*)oper);
+ }
+ ldap_pvt_thread_mutex_unlock(&cm->cc_mutex);
+
filter2template(filter, &tempstr, &filter_attrs, &fattr_cnt, result);
if (result->type != SUCCESS)
goto Catch;
query.filter = filter;
query.attrs = attrs;
- query.base = *base;
- query.scope = scope;
+ query.base = op->o_req_dn;
+ query.scope = op->ors_scope;
/* check for query containment */
if (attr_set > -1) {
#ifdef NEW_LOGGING
LDAP_LOG( BACK_META, DETAIL2,
"Entering QC, querystr = %s\n",
- filterstr->bv_val, 0, 0 );
+ op->ors_filterstr.bv_val, 0, 0 );
#else /* !NEW_LOGGING */
Debug( LDAP_DEBUG_NONE, "Entering QC, querystr = %s\n",
- filterstr->bv_val, 0, 0 );
+ op->ors_filterstr.bv_val, 0, 0 );
#endif /* !NEW_LOGGING */
answerable = (*(qm->qcfunc))(qm, &query, i);
}
}
+ if ( attrs && oc_attr_absent ) {
+ for ( count = 0; attrs[count].an_name.bv_val; count++) ;
+ attrs[ count ].an_name.bv_val = "objectClass";
+ attrs[ count ].an_name.bv_len = strlen( "objectClass" );
+ attrs[ count ].an_desc = slap_schema.si_ad_objectClass;
+ attrs[ count + 1 ].an_name.bv_val = NULL;
+ attrs[ count + 1 ].an_name.bv_len = 0;
+ }
+
if (answerable) {
+ Operation op_tmp;
+
#ifdef NEW_LOGGING
LDAP_LOG( BACK_META, DETAIL1, "QUERY ANSWERABLE\n", 0, 0, 0 );
#else /* !NEW_LOGGING */
Debug( LDAP_DEBUG_ANY, "QUERY ANSWERABLE\n", 0, 0, 0 );
#endif /* !NEW_LOGGING */
- rewriteSession(li->rwinfo, "cacheBase", nbase->bv_val,
- conn, &cbase, result);
+ rewriteSession(li->rwinfo, "cacheBase", op->o_req_dn.bv_val,
+ op->o_conn, &cbase, result);
if (result->type != SUCCESS) {
ldap_pvt_thread_rdwr_runlock(&qm->templates[i].t_rwlock);
goto Catch;
}
- cachebase = ber_str2bv(cbase, strlen(cbase), 0, NULL);
- dnNormalize(NULL, cachebase, &ncachebase);
-
- op->o_caching_on = 1;
- op->o_callback = &cb;
- li->glue_be->be_search(li->glue_be, conn, op, cachebase,
- ncachebase, scope, deref, slimit, tlimit,
- filter, filterstr, attrs, attrsonly);
+ if ( cbase == NULL ) {
+ cachebase = op->o_req_dn;
+ } else {
+ cachebase.bv_val = cbase;
+ cachebase.bv_len = strlen(cbase);
+ }
+ dnNormalize(0, NULL, NULL, &cachebase, &ncachebase,
+ op->o_tmpmemctx);
+
+ /* FIXME: safe default? */
+ op_tmp = *op;
+
+ op_tmp.o_bd = li->glue_be;
+ op_tmp.o_req_dn = cachebase;
+ op_tmp.o_req_ndn = ncachebase;
+
+ op_tmp.o_callback = &cb;
+
+ li->glue_be->be_search(&op_tmp, rs);
+ free( ncachebase.bv_val );
+ if ( cachebase.bv_val != op->o_req_dn.bv_val ) {
+ /* free only if rewritten */
+ free( cachebase.bv_val );
+ }
ldap_pvt_thread_rdwr_runlock(&qm->templates[i].t_rwlock);
} else {
+ Operation op_tmp;
+ op_tmp = *op;
#ifdef NEW_LOGGING
LDAP_LOG( BACK_META, DETAIL1, "QUERY NOT ANSWERABLE\n",
0, 0, 0 );
Debug( LDAP_DEBUG_ANY, "QUERY NOT ANSWERABLE\n", 0, 0, 0 );
#endif /* !NEW_LOGGING */
- if ( scope == LDAP_SCOPE_BASE ) {
+ if ( op->ors_scope == LDAP_SCOPE_BASE ) {
op_type = META_OP_REQUIRE_SINGLE;
} else {
op_type = META_OP_ALLOW_MULTIPLE;
}
- lc = metaConnect(li, conn, op, op_type, nbase, result);
+ lc = metaConnect(&op_tmp, rs, op_type,
+ &op->o_req_ndn, result);
if (result->type != SUCCESS)
goto Catch;
ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
if (cacheable) {
-#ifdef NEW_LOGGING
- LDAP_LOG( BACK_META, DETAIL1,
- "QUERY TEMPLATE CACHEABLE\n",
- 0, 0, 0);
-#else /* !NEW_LOGGING */
- Debug( LDAP_DEBUG_ANY, "QUERY TEMPLATE CACHEABLE\n",
- 0, 0, 0);
-#endif /* !NEW_LOGGING */
add_filter_attrs(&new_attrs, attrs, filter_attrs);
} else {
new_attrs = attrs;
*/
for ( i = 0, lsc = lc->conns; !META_LAST(lsc); ++i, ++lsc ) {
- char *realbase = ( char * )base->bv_val;
- int realscope = scope;
+ char *realbase = ( char * )op->o_req_dn.bv_val;
+ int realscope = op->ors_scope;
ber_len_t suffixlen;
char *mapped_filter, **mapped_attrs;
/* FIXME: Check for more than one targets */
if ( meta_back_is_candidate(
- &li->targets[i]->suffix, nbase ))
+ &li->targets[i]->suffix,
+ &op->o_req_ndn ))
lsc->candidate = META_CANDIDATE;
if ( lsc->candidate != META_CANDIDATE )
continue;
- if ( deref != -1 ) {
+ if ( op->ors_deref != -1 ) {
ldap_set_option( lsc->ld, LDAP_OPT_DEREF,
- ( void * )&deref);
+ ( void * )&op->ors_deref);
}
- if ( tlimit != -1 ) {
+ if ( op->ors_tlimit != -1 ) {
ldap_set_option( lsc->ld, LDAP_OPT_TIMELIMIT,
- ( void * )&tlimit);
+ ( void * )&op->ors_tlimit);
}
- if ( slimit != -1 ) {
+ if ( op->ors_slimit != -1 ) {
ldap_set_option( lsc->ld, LDAP_OPT_SIZELIMIT,
- ( void * )&slimit);
+ ( void * )&op->ors_slimit);
}
/*
* modifies the base according to the scope, if required
*/
suffixlen = li->targets[ i ]->suffix.bv_len;
- if ( suffixlen > nbase->bv_len ) {
- switch ( scope ) {
+ if ( suffixlen > op->o_req_ndn.bv_len ) {
+ switch ( op->ors_scope ) {
case LDAP_SCOPE_SUBTREE:
/*
* make the target suffix the new base
*/
if ( dnIsSuffix(
&li->targets[ i ]->suffix,
- nbase ) ) {
+ &op->o_req_ndn ) ) {
realbase =
li->targets[i]->suffix.bv_val;
} else {
case LDAP_SCOPE_ONELEVEL:
if ( is_one_level_rdn(
li->targets[ i ]->suffix.bv_val,
- suffixlen - nbase->bv_len - 1 )
+ suffixlen - op->o_req_ndn.bv_len - 1 )
&& dnIsSuffix(
&li->targets[ i ]->suffix,
- nbase ) ) {
+ &op->o_req_ndn ) ) {
/*
* if there is exactly one
* level, make the target suffix
realscope = LDAP_SCOPE_BASE;
break;
} /* else continue with the next case */
+
case LDAP_SCOPE_BASE:
/*
* this target is no longer candidate
* Rewrite the search base, if required
*/
- rewriteSession(li->targets[i]->rwinfo, "searchBase",
- realbase, conn, &mbase, result);
+ rewriteSession(li->targets[i]->rwmap.rwm_rw,
+ "searchBase",
+ realbase, op->o_conn, &mbase, result);
if (result->type != SUCCESS)
goto Catch;
/*
* Rewrite the search filter, if required
*/
- rewriteSession( li->targets[i]->rwinfo, "searchFilter",
- filterstr->bv_val, conn,
+ rewriteSession( li->targets[i]->rwmap.rwm_rw,
+ "searchFilter",
+ op->ors_filterstr.bv_val, op->o_conn,
&mfilter.bv_val, result);
if (result->type != SUCCESS)
goto Catch;
if ( mfilter.bv_val != NULL ) {
free( mfilter.bv_val );
}
- mfilter = *filterstr;
+ mfilter = op->ors_filterstr;
}
+#if 0
/*
* Maps attributes in filter
*/
mapped_filter = ldap_back_map_filter(
- &li->targets[i]->at_map,
- &li->targets[i]->oc_map, &mfilter, 0 );
+ &li->targets[i]->rwmap.rwm_at,
+ &li->targets[i]->rwmap.rwm_oc,
+ &mfilter, 0 );
if ( mapped_filter == NULL ) {
mapped_filter = ( char * )mfilter.bv_val;
} else {
- if ( mfilter.bv_val != filterstr->bv_val ) {
+ if ( mfilter.bv_val != op->ors_filterstr.bv_val ) {
free( mfilter.bv_val );
}
}
mfilter.bv_val = NULL;
mfilter.bv_len = 0;
+#else
+ mapped_filter = (char *) mfilter.bv_val;
+#endif
/*
* Maps required attributes
*/
- mapped_attrs = ldap_back_map_attrs(
- &li->targets[ i ]->at_map,
- new_attrs, 0 );
- if ( mapped_attrs == NULL && new_attrs) {
- for ( count=0;
- new_attrs[ count ].an_name.bv_val;
- count++)
- ;
- mapped_attrs = ch_malloc( ( count + 1 ) *
- sizeof(char *));
- for ( count=0;
- new_attrs[ count ].an_name.bv_val;
- count++ ) {
- mapped_attrs[ count ] =
- new_attrs[count].an_name.bv_val;
- }
- mapped_attrs[ count ] = NULL;
+ if ( ldap_back_map_attrs(
+ &li->targets[ i ]->rwmap.rwm_at,
+ new_attrs, 0, &mapped_attrs ) ) {
+ goto Catch;
}
/*
*/
msgid[ i ] = ldap_search( lsc->ld, mbase, realscope,
mapped_filter, mapped_attrs,
- attrsonly );
+ op->ors_attrsonly );
+
if ( msgid[ i ] == -1 ) {
+ result->type = CONN_ERR;
+ goto Catch;
+ /*
lsc->candidate = META_NOT_CANDIDATE;
continue;
+ */
}
if ( mapped_attrs ) {
mapped_attrs = NULL;
}
- if ( mapped_filter != filterstr->bv_val ) {
+ if ( mapped_filter != op->ors_filterstr.bv_val ) {
free( mapped_filter );
mapped_filter = NULL;
}
++candidates;
}
- num_entries = handleLdapResult(lc, op, msgid, be, attrs,
- attrsonly, candidates, cacheable, &entry_array,
- curr_limit, slimit, result);
+ num_entries = handleLdapResult(lc, &op_tmp, rs, msgid,
+ op->o_bd, attrs,
+ op->ors_attrsonly, candidates,
+ cacheable, &entry_array,
+ curr_limit, op->ors_slimit, result);
if (result->type != SUCCESS)
goto Catch;
if (cacheable && (num_entries <= curr_limit)) {
+
#ifdef NEW_LOGGING
LDAP_LOG( BACK_META, DETAIL1,
"QUERY CACHEABLE\n", 0, 0, 0 );
#else /* !NEW_LOGGING */
Debug( LDAP_DEBUG_ANY, "QUERY CACHEABLE\n", 0, 0, 0 );
#endif /* !NEW_LOGGING */
- uuid = cache_entries(entry_array, cm, li->glue_be,
- conn, result);
+ op_tmp.o_bd = li->glue_be;
+ uuid = cache_entries(&op_tmp, rs, entry_array, cm, result);
#ifdef NEW_LOGGING
LDAP_LOG( BACK_META, DETAIL1,
"Added query %s UUID %s ENTRIES %d\n",
- filterstr->bv_val, uuid, num_entries );
+ op->ors_filterstr.bv_val,
+ uuid, num_entries );
#else /* !NEW_LOGGING */
Debug( LDAP_DEBUG_ANY,
"Added query %s UUID %s ENTRIES %d\n",
- filterstr->bv_val, uuid, num_entries );
+ op->ors_filterstr.bv_val,
+ uuid, num_entries );
#endif /* !NEW_LOGGING */
if (result->type != SUCCESS)
goto Catch;
filter = 0;
attrs = 0;
+
+ /* FIXME : launch do_syncrepl() threads around here
+ *
+ * entryUUID and entryCSN need also to be requested by :
+ */
+ /*
+ msgid[ i ] = ldap_search( lsc->ld, mbase, realscope,
+ mapped_filter, mapped_attrs, op->ors_attrsonly );
+ */
+ /* Also, mbase, realscope, mapped_filter, mapped_attrs need
+ * be managed as arrays. Each element needs to be retained by this point.
+ */
+
+ } else {
+#ifdef NEW_LOGGING
+ LDAP_LOG( BACK_META, DETAIL1,
+ "QUERY NOT CACHEABLE no\n",
+ 0, 0, 0);
+#else /* !NEW_LOGGING */
+ Debug( LDAP_DEBUG_ANY, "QUERY NOT CACHEABLE no\n",
+ 0, 0, 0);
+#endif /* !NEW_LOGGING */
}
}
-Catch:
+Catch:;
switch (result->type) {
case SUCCESS:
- rc=0;
- break;
+ rc = 0;
+ break;
+
case FILTER_ERR:
#ifdef NEW_LOGGING
LDAP_LOG( BACK_META, DETAIL1,
0, 0, 0 );
#endif /* !NEW_LOGGING */
break;
+
case CONN_ERR:
rc = -1;
#ifdef NEW_LOGGING
"Could not connect to a remote server\n",
0, 0, 0 );
#endif /* !NEW_LOGGING */
- send_ldap_result(conn, op, LDAP_OTHER,
- NULL, "Connection error",
- NULL, NULL );
- break;
+ send_ldap_error(op, rs, LDAP_OTHER,
+ "Connection error" );
+ break;
+
case RESULT_ERR:
rc = -1;
#ifdef NEW_LOGGING
"Error in handling ldap_result\n", 0, 0, 0 );
#endif /* !NEW_LOGGING */
break;
+
case REWRITING_ERR:
rc = -1;
if (result->rc == REWRITE_REGEXEC_UNWILLING) {
- send_ldap_result( conn, op,
+ send_ldap_error( op, rs,
LDAP_UNWILLING_TO_PERFORM,
- NULL, "Unwilling to perform",
- NULL, NULL );
+ "Unwilling to perform" );
} else {
- send_ldap_result( conn, op, LDAP_OTHER,
- NULL, "Rewrite error",
- NULL, NULL );
+ send_ldap_error( op, rs, LDAP_OTHER,
+ "Rewrite error" );
}
- break;
+ break;
+
case MERGE_ERR:
rc = -1;
#ifdef NEW_LOGGING
Debug( LDAP_DEBUG_ANY,
"Error in merging entry \n", 0, 0, 0 );
#endif /* !NEW_LOGGING */
- break;
+ break;
+
case REMOVE_ERR:
rc = -1;
#ifdef NEW_LOGGING
Debug( LDAP_DEBUG_ANY, "Error in removing query \n",
0, 0, 0 );
#endif /* !NEW_LOGGING */
- break;
+ break;
+
default:
/* assert(0); */
+ break;
}
- ldap_pvt_thread_mutex_lock(&cm->consistency_mutex);
- curr_time = slap_get_time();
- if (curr_time - cm->consistency_time > cm->consistency_cycle_time) {
- cm->consistency_time = curr_time;
- consistency_check(be, li->glue_be, conn);
- }
- ldap_pvt_thread_mutex_unlock(&cm->consistency_mutex);
if ( msgid ) {
ch_free( msgid );
struct berval a, mapped;
Entry* ent;
BerElement ber = *e->lm_ber;
- Attribute *attr, **attrp;
- struct berval dummy = { 0, NULL };
- struct berval *bv, bdn;
- const char *text;
- char* ename = NULL;
+ Attribute *attr, *soc_attr, **attrp;
+ struct berval dummy = { 0, NULL };
+ struct berval *bv, bdn;
+ const char *text = NULL;
+ char* ename = NULL;
+ struct berval sc = { 0, NULL };
+ char textbuf[SLAP_TEXT_BUFLEN];
+ size_t textlen = sizeof(textbuf);
+
if ( ber_scanf( &ber, "{m{", &bdn ) == LBER_ERROR ) {
result->type = CREATE_ENTRY_ERR;
return NULL;
/*
* Rewrite the dn of the result, if needed
*/
- rewriteSession( li->targets[ target ]->rwinfo, "searchResult",
+ rewriteSession( li->targets[ target ]->rwmap.rwm_rw, "searchResult",
bdn.bv_val, lc->conn, &ent->e_name.bv_val, result );
if (result->type != SUCCESS) {
* from the one known to the meta, and a DN with unknown
* attributes is returned.
*
- * FIXME: should we log anything, or delegate to dnNormalize2?
+ * FIXME: should we log anything, or delegate to dnNormalize?
*/
- dnNormalize2( NULL, &ent->e_name, &ent->e_nname );
+ dnNormalize( 0, NULL, NULL, &ent->e_name, &ent->e_nname, NULL );
/*
- if ( dnNormalize2( NULL, &ent->e_name, &ent->e_nname ) != LDAP_SUCCESS ) {
+ if ( dnNormalize( 0, NULL, NULL, &ent->e_name, &ent->e_nname )
+ != LDAP_SUCCESS )
+ {
return LDAP_INVALID_DN_SYNTAX;
}
*/
attrp = &ent->e_attrs;
while ( ber_scanf( &ber, "{m", &a ) != LBER_ERROR ) {
- ldap_back_map( &li->targets[ target ]->at_map, &a, &mapped, 1 );
+ ldap_back_map( &li->targets[ target ]->rwmap.rwm_at,
+ &a, &mapped, 1 );
if ( mapped.bv_val == NULL ) {
continue;
}
attr->a_flags = 0;
attr->a_next = 0;
attr->a_desc = NULL;
+ attr->a_nvals = NULL;
if ( slap_bv2ad( &mapped, &attr->a_desc, &text ) != LDAP_SUCCESS) {
if ( slap_bv2undef_ad( &mapped, &attr->a_desc, &text )
!= LDAP_SUCCESS) {
if ( ber_scanf( &ber, "[W]", &attr->a_vals ) == LBER_ERROR
|| attr->a_vals == NULL ) {
attr->a_vals = &dummy;
+#if 0
} else if ( attr->a_desc == slap_schema.si_ad_objectClass ||
attr->a_desc ==
slap_schema.si_ad_structuralObjectClass) {
+#else
+ } else if ( attr->a_desc == slap_schema.si_ad_objectClass ) {
+#endif
int i, last;
for ( last = 0; attr->a_vals[ last ].bv_val; ++last )
;
for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++,i++ ) {
- ldap_back_map( &li->targets[ target]->oc_map,
+ ldap_back_map( &li->targets[ target]->rwmap.rwm_oc,
bv, &mapped, 1 );
if ( mapped.bv_val == NULL ) {
free( bv->bv_val );
ber_dupbv( bv, &mapped );
}
}
+
+ structural_class( attr->a_vals, &sc, NULL, &text, textbuf, textlen );
+ soc_attr = (Attribute*) ch_malloc( sizeof( Attribute ));
+ soc_attr->a_desc = slap_schema.si_ad_structuralObjectClass;
+ soc_attr->a_vals = (BerVarray) ch_malloc( 2* sizeof( BerValue ));
+ ber_dupbv( &soc_attr->a_vals[0], &sc );
+ soc_attr->a_vals[1].bv_len = 0;
+ soc_attr->a_vals[1].bv_val = NULL;
+ soc_attr->a_nvals = (BerVarray) ch_malloc( 2* sizeof( BerValue ));
+ ber_dupbv( &soc_attr->a_nvals[0], &sc );
+ soc_attr->a_nvals[1].bv_len = 0;
+ soc_attr->a_nvals[1].bv_val = NULL;
+
+ *attrp = soc_attr;
+ attrp = &soc_attr->a_next;
+
/*
* It is necessary to try to rewrite attributes with
* dn syntax because they might be used in ACLs as
int i;
for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++,i++ ) {
char *newval;
- rewriteSession(li->targets[ target ]->rwinfo,
+ rewriteSession(li->targets[ target ]->rwmap.rwm_rw,
"searchResult", bv->bv_val,
lc->conn, &newval, result);
if (result->type != SUCCESS) {
*attrp = attr;
attrp = &attr->a_next;
}
+
return ent;
}
static struct metaconn*
metaConnect(
- struct metainfo* li,
- Connection* conn,
- Operation* op,
- int op_type,
- struct berval* nbase,
- struct exception* result)
+ Operation* op,
+ SlapReply *rs,
+ int op_type,
+ struct berval *nbase,
+ struct exception *result)
{
- struct metaconn* lc;
+ struct metaconn *lc;
+
result->type = SUCCESS;
- lc = meta_back_getconn( li, conn, op, op_type, nbase, NULL );
+ lc = meta_back_getconn( op, rs, op_type, nbase, NULL );
if (!lc) {
result->type = CONN_ERR;
return 0;
int count;
/* duplicate attrs */
- for (count=0; attrs[count].an_name.bv_val; count++)
- ;
- *new_attrs = (AttributeName*)(malloc((count+1)*sizeof(AttributeName)));
- for (i=0; i<count; i++) {
- /*
- ber_dupbv(&((*new_attrs)[i].an_name), &(attrs[i].an_name));
- */
- (*new_attrs)[i].an_name = attrs[i].an_name;
- (*new_attrs)[i].an_desc = attrs[i].an_desc;
+ if (attrs == NULL) {
+ count = 1;
+ } else {
+ for (count=0; attrs[count].an_name.bv_val; count++)
+ ;
}
- (*new_attrs)[count].an_name.bv_val = NULL;
- (*new_attrs)[count].an_name.bv_len = 0;
-
-
- if ((*new_attrs)[0].an_name.bv_val == NULL) {
- *new_attrs = (AttributeName*)(malloc(2*sizeof(AttributeName)));
+ *new_attrs = (AttributeName*)(malloc((count+1)*sizeof(AttributeName)));
+ if (attrs == NULL) {
(*new_attrs)[0].an_name.bv_val = "*";
(*new_attrs)[0].an_name.bv_len = 1;
- (*new_attrs)[1].an_name.bv_val = NULL;
+ (*new_attrs)[1].an_name.bv_val = NULL;
(*new_attrs)[1].an_name.bv_len = 0;
alluser = 1;
- count = 1;
- } else {
+ allop = 0;
+ } else {
+ for (i=0; i<count; i++) {
+ (*new_attrs)[i].an_name = attrs[i].an_name;
+ (*new_attrs)[i].an_desc = attrs[i].an_desc;
+ }
+ (*new_attrs)[count].an_name.bv_val = NULL;
+ (*new_attrs)[count].an_name.bv_len = 0;
alluser = an_find(*new_attrs, &all_user);
allop = an_find(*new_attrs, &all_op);
}
for ( i=0; filter_attrs[i].an_name.bv_val; i++ ) {
if ( an_find(*new_attrs, &filter_attrs[i].an_name ))
continue;
- if ( is_at_operational(filter_attrs[i].an_desc->ad_type)
- && allop )
- continue;
- else if (alluser)
+ if ( is_at_operational(filter_attrs[i].an_desc->ad_type) ) {
+ if (allop)
+ continue;
+ } else if (alluser)
continue;
*new_attrs = (AttributeName*)(realloc(*new_attrs,
(count+2)*sizeof(AttributeName)));
handleLdapResult(
struct metaconn* lc,
Operation* op,
+ SlapReply *rs,
int* msgid, Backend* be,
AttributeName* attrs,
int attrsonly,
}
if ((entry = get_result_entry(be, lc, lsc,
- msgid, i, &tv, result))) {
- send_search_entry( be, lc->conn, op, entry,
- attrs, attrsonly, NULL );
+ msgid, i, &tv, result))) {
+ rs->sr_entry = entry;
+ rs->sr_attrs = op->ors_attrs;
+ send_search_entry( op, rs );
+ rs->sr_entry = NULL;
+ rs->sr_attrs = NULL;
if ((cacheable) &&
(num_entries < curr_limit)) {
rewriteSession( li->rwinfo,
} else if (result->rc == -1) {
break;
} else {
- sres = ldap_back_map_result(result->rc);
+ rs->sr_err = result->rc;
+ sres = ldap_back_map_result(rs);
if (mres == LDAP_SUCCESS &&
sres != LDAP_SUCCESS) {
mres = sres;
Debug( LDAP_DEBUG_ANY, "ldap_result error, rc = -1\n",
0, 0, 0 );
#endif /* !NEW_LOGGING */
- send_search_result( lc->conn, op, LDAP_OTHER, NULL,
- NULL, NULL, NULL, num_entries );
+ rs->sr_err = LDAP_OTHER;
+ send_ldap_result( op, rs );
return 0;
+
case CREATE_ENTRY_ERR:
#ifdef NEW_LOGGING
LDAP_LOG( BACK_META, DETAIL1,
Debug( LDAP_DEBUG_ANY, "Error in parsing result \n",
0, 0, 0 );
#endif /* !NEW_LOGGING */
- send_search_result( lc->conn, op, LDAP_OTHER, NULL,
- NULL, NULL, NULL, num_entries );
+ rs->sr_err = LDAP_OTHER;
+ send_ldap_result( op, rs );
result->type = RESULT_ERR;
return 0;
+
case SLIMIT_ERR:
#ifdef NEW_LOGGING
LDAP_LOG( BACK_META, DETAIL1, "Size limit exceeded \n",
Debug( LDAP_DEBUG_ANY, "Size limit exceeded \n",
0, 0, 0 );
#endif /* !NEW_LOGGING */
- send_search_result( lc->conn, op,
- LDAP_SIZELIMIT_EXCEEDED,
- NULL, NULL, NULL, NULL, num_entries );
+ rs->sr_err = LDAP_SIZELIMIT_EXCEEDED;
+ send_ldap_result( op, rs );
result->type = RESULT_ERR;
- return 0;
+ return 0;
+
case ABANDON_ERR:
#ifdef NEW_LOGGING
LDAP_LOG( BACK_META, DETAIL1,
#endif /* !NEW_LOGGING */
result->type = RESULT_ERR;
return 0;
+
default:
/* assert( 0 ); */
+ break;
}
if ( gotit == 0 ) {
tv.tv_sec = 0;
}
}
- send_search_result( lc->conn, op, mres, match, err,
- NULL, NULL, num_entries );
+ rs->sr_err = mres;
+ rs->sr_text = err;
+ rs->sr_matched = match;
+
+ send_ldap_result( op, rs );
+
+ rs->sr_text = NULL;
+ rs->sr_matched = NULL;
if (err)
free(err);
AttributeName* attrs)
{
int i, count1, count2;
- if ((attrs_in==NULL) || (attrs==NULL))
- return 1;
+ if ( attrs_in == NULL ) {
+ return (attrs ? 0 : 1);
+ }
+ if ( attrs == NULL )
+ return 0;
+
for ( count1=0;
attrs_in && attrs_in[count1].an_name.bv_val != NULL;
count1++ )
static char*
cache_entries(
+ Operation *op,
+ SlapReply *rs,
Entry** entry_array,
cache_manager* cm,
- Backend* be,
- Connection* conn,
struct exception* result)
{
- int i;
- int return_val;
- int cache_size;
- Entry* e;
- struct berval query_uuid;
- struct berval crp_uuid;
- char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ], *crpid;
- char crpuuid[40];
- query_manager* qm = cm->qm;
+ int i;
+ int return_val;
+ int cache_size;
+ Entry *e;
+ struct berval query_uuid;
+ struct berval crp_uuid;
+ char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ], *crpid;
+ char crpuuid[40];
+ query_manager *qm = cm->qm;
result->type = SUCCESS;
query_uuid.bv_len = lutil_uuidstr(uuidbuf, sizeof(uuidbuf));
"Removing query UUID %s\n",
crpuuid, 0, 0 );
#endif /* !NEW_LOGGING */
- return_val = remove_query_data(be, conn,
+ return_val = remove_query_data(op, rs,
&crp_uuid, result);
#ifdef NEW_LOGGING
LDAP_LOG( BACK_META, DETAIL1,
cm->num_cached_queries--;
#ifdef NEW_LOGGING
LDAP_LOG( BACK_META, DETAIL1,
- "STORED QUERIES = %d\n",
+ "STORED QUERIES = %lu\n",
cm->num_cached_queries, 0, 0 );
#else /* !NEW_LOGGING */
Debug( LDAP_DEBUG_ANY,
- "STORED QUERIES = %d\n",
+ "STORED QUERIES = %lu\n",
cm->num_cached_queries, 0, 0 );
#endif /* !NEW_LOGGING */
ldap_pvt_thread_mutex_unlock(
#ifdef NEW_LOGGING
LDAP_LOG( BACK_META, DETAIL1,
"QUERY REMOVED, CACHE SIZE="
- "%d bytes %d entries\n",
+ "%lu bytes %d entries\n",
cm->cache_size,
cm->total_entries, 0 );
#else /* !NEW_LOGGING */
Debug( LDAP_DEBUG_ANY,
"QUERY REMOVED, CACHE SIZE="
- "%d bytes %d entries\n",
+ "%lu bytes %d entries\n",
cm->cache_size,
cm->total_entries, 0 );
#endif /* !NEW_LOGGING */
}
}
}
- return_val = merge_entry(be, conn, e, &query_uuid, result);
+
+ rs->sr_entry = e;
+ return_val = merge_entry(op, rs, &query_uuid, result);
+ rs->sr_entry = NULL;
cm->cache_size += return_val;
#ifdef NEW_LOGGING
LDAP_LOG( BACK_META, DETAIL1,
- "ENTRY ADDED/MERGED, CACHE SIZE=%d bytes\n",
+ "ENTRY ADDED/MERGED, CACHE SIZE=%lu bytes\n",
cm->cache_size, 0, 0 );
#else /* !NEW_LOGGING */
Debug( LDAP_DEBUG_ANY,
- "ENTRY ADDED/MERGED, CACHE SIZE=%d bytes\n",
+ "ENTRY ADDED/MERGED, CACHE SIZE=%lu bytes\n",
cm->cache_size, 0, 0 );
#endif /* !NEW_LOGGING */
#ifdef NEW_LOGGING
ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
cm->num_cached_queries++;
#ifdef NEW_LOGGING
- LDAP_LOG( BACK_META, DETAIL1, "STORED QUERIES = %d\n",
+ LDAP_LOG( BACK_META, DETAIL1, "STORED QUERIES = %lu\n",
cm->num_cached_queries, 0, 0 );
#else /* !NEW_LOGGING */
- Debug( LDAP_DEBUG_ANY, "STORED QUERIES = %d\n",
+ Debug( LDAP_DEBUG_ANY, "STORED QUERIES = %lu\n",
cm->num_cached_queries, 0, 0 );
#endif /* !NEW_LOGGING */
ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
return 0;
}
-static void
-consistency_check(Backend* be, Backend* glue_be, Connection* conn)
+static void*
+consistency_check(void* operation)
{
- struct metainfo *li = ( struct metainfo * )be->be_private;
+ Operation* op = (Operation*)operation;
+
+ SlapReply rs = {REP_RESULT};
+
+ struct metainfo *li = ( struct metainfo * )op->o_bd->be_private;
cache_manager* cm = li->cm;
query_manager* qm = cm->qm;
CachedQuery* query, *query_prev;
struct berval uuid;
struct exception result;
int i, return_val;
- QueryTemplate* templ;
-
+ QueryTemplate* templ;
+
+
+ op->o_bd = li->glue_be;
- for (i=0; qm->templates[i].querystr; i++) {
- templ = qm->templates + i;
- query = templ->query_last;
- curr_time = slap_get_time();
- ldap_pvt_thread_mutex_lock(&cm->remove_mutex);
- while (query && (query->expiry_time < curr_time)) {
- ldap_pvt_thread_mutex_lock(&qm->lru_mutex);
- remove_query(qm, query);
- ldap_pvt_thread_mutex_unlock(&qm->lru_mutex);
+ for(;;) {
+ ldap_pvt_thread_sleep(cm->cc_period);
+ for (i=0; qm->templates[i].querystr; i++) {
+ templ = qm->templates + i;
+ query = templ->query_last;
+ curr_time = slap_get_time();
+ ldap_pvt_thread_mutex_lock(&cm->remove_mutex);
+ while (query && (query->expiry_time < curr_time)) {
+ ldap_pvt_thread_mutex_lock(&qm->lru_mutex);
+ remove_query(qm, query);
+ ldap_pvt_thread_mutex_unlock(&qm->lru_mutex);
#ifdef NEW_LOGGING
- LDAP_LOG( BACK_META, DETAIL1, "Lock CR index = %d\n",
- i, 0, 0 );
+ LDAP_LOG( BACK_META, DETAIL1, "Lock CR index = %d\n",
+ i, 0, 0 );
#else /* !NEW_LOGGING */
- Debug( LDAP_DEBUG_ANY, "Lock CR index = %d\n",
- i, 0, 0 );
+ Debug( LDAP_DEBUG_ANY, "Lock CR index = %d\n",
+ i, 0, 0 );
#endif /* !NEW_LOGGING */
- ldap_pvt_thread_rdwr_wlock(&templ->t_rwlock);
- remove_from_template(query, templ);
+ ldap_pvt_thread_rdwr_wlock(&templ->t_rwlock);
+ remove_from_template(query, templ);
#ifdef NEW_LOGGING
- LDAP_LOG( BACK_META, DETAIL1,
- "TEMPLATE %d QUERIES-- %d\n",
- i, templ->no_of_queries, 0 );
+ LDAP_LOG( BACK_META, DETAIL1,
+ "TEMPLATE %d QUERIES-- %d\n",
+ i, templ->no_of_queries, 0 );
#else /* !NEW_LOGGING */
- Debug( LDAP_DEBUG_ANY, "TEMPLATE %d QUERIES-- %d\n",
- i, templ->no_of_queries, 0 );
+ Debug( LDAP_DEBUG_ANY, "TEMPLATE %d QUERIES-- %d\n",
+ i, templ->no_of_queries, 0 );
#endif /* !NEW_LOGGING */
#ifdef NEW_LOGGING
- LDAP_LOG( BACK_META, DETAIL1, "Unlock CR index = %d\n",
- i, 0, 0 );
+ LDAP_LOG( BACK_META, DETAIL1, "Unlock CR index = %d\n",
+ i, 0, 0 );
#else /* !NEW_LOGGING */
- Debug( LDAP_DEBUG_ANY, "Unlock CR index = %d\n",
- i, 0, 0 );
+ Debug( LDAP_DEBUG_ANY, "Unlock CR index = %d\n",
+ i, 0, 0 );
#endif /* !NEW_LOGGING */
- ldap_pvt_thread_rdwr_wunlock(&templ->t_rwlock);
- uuid.bv_val = query->q_uuid;
- uuid.bv_len = strlen(query->q_uuid);
- return_val = remove_query_data(glue_be, conn,
- &uuid, &result);
+ ldap_pvt_thread_rdwr_wunlock(&templ->t_rwlock);
+ uuid.bv_val = query->q_uuid;
+ uuid.bv_len = strlen(query->q_uuid);
+ return_val = remove_query_data(op, &rs, &uuid, &result);
#ifdef NEW_LOGGING
- LDAP_LOG( BACK_META, DETAIL1,
- "STALE QUERY REMOVED, SIZE=%d\n",
- return_val, 0, 0 );
-#else /* !NEW_LOGGING */
- Debug( LDAP_DEBUG_ANY, "STALE QUERY REMOVED, SIZE=%d\n",
+ LDAP_LOG( BACK_META, DETAIL1,
+ "STALE QUERY REMOVED, SIZE=%d\n",
return_val, 0, 0 );
+#else /* !NEW_LOGGING */
+ Debug( LDAP_DEBUG_ANY, "STALE QUERY REMOVED, SIZE=%d\n",
+ return_val, 0, 0 );
#endif /* !NEW_LOGGING */
- ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
- cm->total_entries -= result.rc;
- cm->num_cached_queries--;
+ ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
+ cm->total_entries -= result.rc;
+ cm->num_cached_queries--;
#ifdef NEW_LOGGING
- LDAP_LOG( BACK_META, DETAIL1, "STORED QUERIES = %d\n",
- cm->num_cached_queries, 0, 0 );
+ LDAP_LOG( BACK_META, DETAIL1, "STORED QUERIES = %lu\n",
+ cm->num_cached_queries, 0, 0 );
#else /* !NEW_LOGGING */
- Debug( LDAP_DEBUG_ANY, "STORED QUERIES = %d\n",
- cm->num_cached_queries, 0, 0 );
+ Debug( LDAP_DEBUG_ANY, "STORED QUERIES = %lu\n",
+ cm->num_cached_queries, 0, 0 );
#endif /* !NEW_LOGGING */
- ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
- cm->cache_size = (return_val > cm->cache_size) ?
- 0: (cm->cache_size-return_val);
+ ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);
+ cm->cache_size = (return_val > cm->cache_size) ?
+ 0: (cm->cache_size-return_val);
#ifdef NEW_LOGGING
- LDAP_LOG( BACK_META, DETAIL1,
- "STALE QUERY REMOVED, CACHE SIZE=%d bytes %d "
- "entries\n", cm->cache_size,
- cm->total_entries, 0 );
+ LDAP_LOG( BACK_META, DETAIL1,
+ "STALE QUERY REMOVED, CACHE SIZE=%lu bytes %d "
+ "entries\n", cm->cache_size,
+ cm->total_entries, 0 );
#else /* !NEW_LOGGING */
- Debug( LDAP_DEBUG_ANY,
- "STALE QUERY REMOVED, CACHE SIZE=%d bytes %d "
- "entries\n", cm->cache_size,
- cm->total_entries, 0 );
+ Debug( LDAP_DEBUG_ANY,
+ "STALE QUERY REMOVED, CACHE SIZE=%lu bytes %d "
+ "entries\n", cm->cache_size,
+ cm->total_entries, 0 );
#endif /* !NEW_LOGGING */
- query_prev = query;
- query = query->prev;
- free_query(query_prev);
+ query_prev = query;
+ query = query->prev;
+ free_query(query_prev);
+ }
+ ldap_pvt_thread_mutex_unlock(&cm->remove_mutex);
}
- ldap_pvt_thread_mutex_unlock(&cm->remove_mutex);
}
}
static int
cache_back_sentry(
- Backend* glue_be,
- Connection* conn,
Operation* op,
- Entry* e,
- AttributeName* attrs,
- int attrsonly,
- LDAPControl** ctrls )
+ SlapReply *rs )
{
- slap_callback* cb = op->o_callback;
- Backend* be = (Backend*)(cb->sc_private);
- struct metainfo *li = ( struct metainfo * )be->be_private;
+ slap_callback *cb = op->o_callback;
+ /*struct metainfo *li = ( struct metainfo * )op->o_bd->be_private;*/
+ Backend* be = (Backend*)(cb->sc_private);
+ struct metainfo *li = ( struct metainfo * )be->be_private;
- char* ename = NULL;
- struct exception result;
- struct berval dn;
- struct berval ndn;
-
- dn = e->e_name;
- ndn = e->e_nname;
-
- rewriteSession( li->rwinfo,
- "cacheReturn", e->e_name.bv_val, conn, &ename, &result );
- ber_str2bv(ename, strlen(ename), 0, &e->e_name);
- ber_dupbv(&e->e_nname, &e->e_name);
-
- op->o_callback = NULL;
- send_search_entry(be, conn, op, e, attrs, attrsonly, ctrls);
+ char *ename = NULL;
+ struct exception result;
+ struct berval dn;
+ struct berval ndn;
- e->e_name = dn;
- e->e_nname = ndn;
+ if (rs->sr_type == REP_SEARCH) {
+ dn = rs->sr_entry->e_name;
+ ndn = rs->sr_entry->e_nname;
+
+ rewriteSession( li->rwinfo, "cacheReturn",
+ rs->sr_entry->e_name.bv_val, op->o_conn,
+ &ename, &result );
+ ber_str2bv(ename, strlen(ename), 0, &rs->sr_entry->e_name);
+ /* FIXME: should we normalize this? */
+ ber_dupbv(&rs->sr_entry->e_nname, &rs->sr_entry->e_name);
+
+ op->o_callback = NULL;
+
+ send_search_entry( op, rs );
+
+ rs->sr_entry->e_name = dn;
+ rs->sr_entry->e_nname = ndn;
+
+ op->o_callback = cb;
+ return LDAP_SUCCESS;
+
+ } else if (rs->sr_type == REP_RESULT) {
+ op->o_callback = NULL;
+ send_ldap_result( op, rs );
+ return LDAP_SUCCESS;
+ }
- op->o_callback = cb;
- return 0;
+ return LDAP_SUCCESS;
}
-#endif