Commit 1e35a2f9 authored by Ralf Haferkamp's avatar Ralf Haferkamp
Browse files

/tmp/msg

parent 9f5dafbe
......@@ -2078,7 +2078,6 @@ acl_set_gather( SetCookie *cookie, struct berval *name, AttributeDescription *de
slap_callback cb = { NULL, acl_set_cb_gather, NULL, NULL };
acl_set_gather_t p = { 0 };
const char *text = NULL;
static struct berval defaultFilter_bv = BER_BVC( "(objectClass=*)" );
/* this routine needs to return the bervals instead of
* plain strings, since syntax is not known. It should
......@@ -2121,16 +2120,17 @@ acl_set_gather( SetCookie *cookie, struct berval *name, AttributeDescription *de
if ( ludp->lud_filter ) {
ber_str2bv_x( ludp->lud_filter, 0, 0, &op2.ors_filterstr,
cp->asc_op->o_tmpmemctx );
op2.ors_filter = str2filter_x( cp->asc_op, op2.ors_filterstr.bv_val );
if ( op2.ors_filter == NULL ) {
rc = LDAP_PROTOCOL_ERROR;
goto url_done;
}
} else {
op2.ors_filterstr = defaultFilter_bv;
op2.ors_filterstr = *slap_filterstr_objectClass_pres;
op2.ors_filter = slap_filter_objectClass_pres;
}
op2.ors_filter = str2filter_x( cp->asc_op, op2.ors_filterstr.bv_val );
if ( op2.ors_filter == NULL ) {
rc = LDAP_PROTOCOL_ERROR;
goto url_done;
}
/* Grab the scope */
op2.ors_scope = ludp->lud_scope;
......@@ -2186,7 +2186,7 @@ acl_set_gather( SetCookie *cookie, struct berval *name, AttributeDescription *de
}
url_done:;
if ( op2.ors_filter ) {
if ( op2.ors_filter && op2.ors_filter != slap_filter_objectClass_pres ) {
filter_free_x( cp->asc_op, op2.ors_filter );
}
if ( !BER_BVISNULL( &op2.o_req_ndn ) ) {
......
......@@ -154,11 +154,7 @@ static int search_aliases(
Entry *matched, *a;
EntryInfo *ei;
struct berval bv_alias = BER_BVC( "alias" );
#ifdef LDAP_COMP_MATCH
AttributeAssertion aa_alias = { NULL, BER_BVNULL, NULL };
#else
AttributeAssertion aa_alias = { NULL, BER_BVNULL };
#endif
AttributeAssertion aa_alias = ATTRIBUTEASSERTION_INIT;
Filter af;
DB_LOCK locka, lockr;
int first = 1;
......@@ -1028,17 +1024,9 @@ static int search_candidates(
int rc, depth = 1;
Filter f, rf, xf, nf;
ID *stack;
#ifdef LDAP_COMP_MATCH
AttributeAssertion aa_ref = { NULL, BER_BVNULL, NULL };
#else
AttributeAssertion aa_ref = { NULL, BER_BVNULL };
#endif
AttributeAssertion aa_ref = ATTRIBUTEASSERTION_INIT;
Filter sf;
#ifdef LDAP_COMP_MATCH
AttributeAssertion aa_subentry = { NULL, BER_BVNULL, NULL };
#else
AttributeAssertion aa_subentry = { NULL, BER_BVNULL };
#endif
AttributeAssertion aa_subentry = ATTRIBUTEASSERTION_INIT;
/*
* This routine takes as input a filter (user-filter)
......
......@@ -849,7 +849,6 @@ meta_back_get_candidate(
rs->sr_text = "No suitable candidate target found";
} else if ( candidate == META_TARGET_MULTIPLE ) {
Filter f = { 0 };
Operation op2 = *op;
SlapReply rs2 = { 0 };
slap_callback cb2 = { 0 };
......@@ -868,10 +867,8 @@ meta_back_get_candidate(
op2.ors_slimit = 1;
op2.ors_tlimit = SLAP_NO_LIMIT;
f.f_choice = LDAP_FILTER_PRESENT;
f.f_desc = slap_schema.si_ad_objectClass;
op2.ors_filter = &f;
BER_BVSTR( &op2.ors_filterstr, "(objectClass=*)" );
op2.ors_filter = slap_filter_objectClass_pres;
op2.ors_filterstr = *slap_filterstr_objectClass_pres;
op2.o_callback = &cb2;
cb2.sc_response = meta_back_conn_cb;
......
......@@ -336,7 +336,6 @@ backsql_tree_delete(
Operation op2 = *op;
slap_callback sc = { 0 };
SlapReply rs2 = { 0 };
Filter f = { 0 };
backsql_tree_delete_t btd = { 0 };
int rc;
......@@ -368,10 +367,8 @@ backsql_tree_delete(
op2.ors_deref = LDAP_DEREF_NEVER;
op2.ors_slimit = SLAP_NO_LIMIT;
op2.ors_tlimit = SLAP_NO_LIMIT;
op2.ors_filter = &f;
f.f_choice = LDAP_FILTER_PRESENT;
f.f_desc = slap_schema.si_ad_objectClass;
BER_BVSTR( &op2.ors_filterstr, "(objectClass=*)" );
op2.ors_filter = slap_filter_objectClass_pres;
op2.ors_filterstr = *slap_filterstr_objectClass_pres;
op2.ors_attrs = slap_anlist_all_attributes;
op2.ors_attrsonly = 0;
......
......@@ -44,7 +44,7 @@ do_compare(
struct berval dn = BER_BVNULL;
struct berval desc = BER_BVNULL;
struct berval value = BER_BVNULL;
AttributeAssertion ava = { 0 };
AttributeAssertion ava = ATTRIBUTEASSERTION_INIT;
Debug( LDAP_DEBUG_TRACE, "%s do_compare\n",
op->o_log_prefix, 0, 0 );
......
......@@ -33,6 +33,9 @@
#include "slap.h"
const Filter *slap_filter_objectClass_pres;
const struct berval *slap_filterstr_objectClass_pres;
static int get_filter_list(
Operation *op,
BerElement *ber,
......@@ -56,6 +59,26 @@ static int get_simple_vrFilter(
ValuesReturnFilter **f,
const char **text );
int
filter_init( void )
{
static Filter filter_objectClass_pres = { LDAP_FILTER_PRESENT };
static struct berval filterstr_objectClass_pres = BER_BVC("(objectClass=*)");
filter_objectClass_pres.f_desc = slap_schema.si_ad_objectClass;
slap_filter_objectClass_pres = &filter_objectClass_pres;
slap_filterstr_objectClass_pres = &filterstr_objectClass_pres;
return 0;
}
void
filter_destroy( void )
{
return;
}
int
get_filter(
Operation *op,
......
......@@ -112,6 +112,14 @@ slap_init( int mode, const char *name )
return 1;
}
if ( filter_init() != 0 ) {
slap_debug |= LDAP_DEBUG_NONE;
Debug( LDAP_DEBUG_ANY,
"%s: filter_init failed\n",
name, 0, 0 );
return 1;
}
if ( entry_init() != 0 ) {
slap_debug |= LDAP_DEBUG_NONE;
Debug( LDAP_DEBUG_ANY,
......
......@@ -984,6 +984,8 @@ stop:
controls_destroy();
filter_destroy();
schema_destroy();
lutil_passwd_destroy();
......
......@@ -596,7 +596,7 @@ accesslog_purge( void *ctx, void *arg )
SlapReply rs = {REP_RESULT};
slap_callback cb = { NULL, log_old_lookup, NULL, NULL };
Filter f;
AttributeAssertion ava = {0};
AttributeAssertion ava = ATTRIBUTEASSERTION_INIT;
purge_data pd = {0};
char timebuf[LDAP_LUTIL_GENTIME_BUFSIZE];
char csnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];
......
......@@ -629,12 +629,8 @@ dynlist_compare( Operation *op, SlapReply *rs )
goto release;
}
BER_BVSTR( &o.ors_filterstr, "(objectClass=*)" );
o.ors_filter = str2filter_x( op, o.ors_filterstr.bv_val );
if ( o.ors_filter == NULL ) {
/* FIXME: error? */
goto release;
}
o.ors_filterstr = *slap_filterstr_objectClass_pres;
o.ors_filter = slap_filter_objectClass_pres;
o.ors_scope = LDAP_SCOPE_BASE;
o.ors_deref = LDAP_DEREF_NEVER;
......@@ -647,7 +643,6 @@ dynlist_compare( Operation *op, SlapReply *rs )
o.o_acl_priv = ACL_COMPARE;
rc = o.o_bd->be_search( &o, &r );
filter_free_x( &o, o.ors_filter );
if ( o.o_dn.bv_val != op->o_dn.bv_val ) {
slap_op_groups_free( &o );
......
......@@ -72,12 +72,14 @@ typedef struct cached_query_s {
Qbase *qbase;
int scope;
struct berval q_uuid; /* query identifier */
int q_sizelimit;
struct query_template_s *qtemp; /* template of the query */
time_t expiry_time; /* time till the query is considered valid */
time_t expiry_time; /* time till the query is considered valid */
struct cached_query_s *next; /* next query in the template */
struct cached_query_s *prev; /* previous query in the template */
struct cached_query_s *lru_up; /* previous query in the LRU list */
struct cached_query_s *lru_down; /* next query in the LRU list */
struct cached_query_s *lru_up; /* previous query in the LRU list */
struct cached_query_s *lru_down; /* next query in the LRU list */
ldap_pvt_thread_rdwr_t rwlock;
} CachedQuery;
/*
......@@ -127,17 +129,36 @@ typedef struct query_template_s {
int no_of_queries; /* Total number of queries in the template */
time_t ttl; /* TTL for the queries of this template */
time_t negttl; /* TTL for negative results */
time_t limitttl; /* TTL for sizelimit exceeding results */
struct attr_set t_attrs; /* filter attrs + attr_set */
} QueryTemplate;
typedef enum {
PC_IGNORE = 0,
PC_POSITIVE,
PC_NEGATIVE,
PC_SIZELIMIT
} pc_caching_reason_t;
static const char *pc_caching_reason_str[] = {
"IGNORE",
"POSITIVE",
"NEGATIVE",
"SIZELIMIT",
NULL
};
struct query_manager_s;
/* prototypes for functions for 1) query containment
* 2) query addition, 3) cache replacement
*/
typedef CachedQuery * (QCfunc)(Operation *op, struct query_manager_s*, Query*, QueryTemplate*);
typedef CachedQuery * (AddQueryfunc)(Operation *op, struct query_manager_s*, Query*, QueryTemplate*, int positive);
typedef void (CRfunc)(struct query_manager_s*, struct berval * );
typedef CachedQuery *(QCfunc)(Operation *op, struct query_manager_s*,
Query*, QueryTemplate*);
typedef CachedQuery *(AddQueryfunc)(Operation *op, struct query_manager_s*,
Query*, QueryTemplate*, pc_caching_reason_t, int wlock);
typedef void (CRfunc)(struct query_manager_s*, struct berval*);
/* LDAP query cache */
typedef struct query_manager_s {
......@@ -225,7 +246,8 @@ add_query(
query_manager* qm,
Query* query,
QueryTemplate *templ,
int positive);
pc_caching_reason_t why,
int wlock);
static int
remove_query_data(
......@@ -452,7 +474,7 @@ url2query(
goto error;
}
cq = add_query( op, qm, &query, qt, 1 );
cq = add_query( op, qm, &query, qt, PC_POSITIVE, 0 );
if ( cq != NULL ) {
cq->expiry_time = expiry_time;
cq->q_uuid = uuid;
......@@ -1093,6 +1115,10 @@ query_containment(Operation *op, query_manager *qm,
qc = find_filter( op, qbptr->scopes[tscope],
query->filter, first );
if ( qc ) {
if ( qc->q_sizelimit ) {
ldap_pvt_thread_rdwr_runlock(&templa->t_rwlock);
return NULL;
}
ldap_pvt_thread_mutex_lock(&qm->lru_mutex);
if (qm->lru_top != qc) {
remove_query(qm, qc);
......@@ -1128,35 +1154,57 @@ free_query (CachedQuery* qc)
}
/* Add query to query cache */
/* Add query to query cache, the returned Query is locked for writing */
static CachedQuery *
add_query(
Operation *op,
query_manager* qm,
Query* query,
QueryTemplate *templ,
int positive)
pc_caching_reason_t why,
int wlock)
{
CachedQuery* new_cached_query = (CachedQuery*) ch_malloc(sizeof(CachedQuery));
Qbase *qbase, qb;
Filter *first;
int rc;
time_t ttl = 0;;
new_cached_query->qtemp = templ;
BER_BVZERO( &new_cached_query->q_uuid );
if ( positive ) {
new_cached_query->expiry_time = slap_get_time() + templ->ttl;
} else {
new_cached_query->expiry_time = slap_get_time() + templ->negttl;
new_cached_query->q_sizelimit = 0;
switch ( why ) {
case PC_POSITIVE:
ttl = templ->ttl;
break;
case PC_NEGATIVE:
ttl = templ->negttl;
break;
case PC_SIZELIMIT:
ttl = templ->limitttl;
break;
default:
assert( 0 );
break;
}
new_cached_query->expiry_time = slap_get_time() + ttl;
new_cached_query->lru_up = NULL;
new_cached_query->lru_down = NULL;
Debug( pcache_debug, "Added query expires at %ld\n",
(long) new_cached_query->expiry_time, 0, 0 );
Debug( pcache_debug, "Added query expires at %ld (%s)\n",
(long) new_cached_query->expiry_time,
pc_caching_reason_str[ why ], 0 );
new_cached_query->scope = query->scope;
new_cached_query->filter = query->filter;
new_cached_query->first = first = filter_first( query->filter );
ldap_pvt_thread_rdwr_init(&new_cached_query->rwlock);
if (wlock)
ldap_pvt_thread_rdwr_wlock(&new_cached_query->rwlock);
qb.base = query->base;
......@@ -1286,7 +1334,7 @@ cache_replacement(query_manager* qm, struct berval *result)
ldap_pvt_thread_mutex_unlock(&qm->lru_mutex);
*result = bottom->q_uuid;
bottom->q_uuid.bv_val = NULL;
BER_BVZERO( &bottom->q_uuid );
Debug( pcache_debug, "Lock CR index = %p\n", (void *) temp, 0, 0 );
ldap_pvt_thread_rdwr_wlock(&temp->t_rwlock);
......@@ -1339,11 +1387,7 @@ remove_query_data(
{
struct query_info *qi, *qnext;
char filter_str[ LDAP_LUTIL_UUIDSTR_BUFSIZE + STRLENOF( "(queryId=)" ) ];
#ifdef LDAP_COMP_MATCH
AttributeAssertion ava = { NULL, BER_BVNULL, NULL };
#else
AttributeAssertion ava = { NULL, BER_BVNULL };
#endif
AttributeAssertion ava = ATTRIBUTEASSERTION_INIT;
Filter filter = {LDAP_FILTER_EQUALITY};
SlapReply sreply = {REP_RESULT};
slap_callback cb = { NULL, remove_func, NULL, NULL };
......@@ -1527,6 +1571,9 @@ struct search_info {
int max;
int over;
int count;
int slimit;
int slimit_exceeded;
pc_caching_reason_t caching_reason;
Entry *head, *tail;
};
......@@ -1622,11 +1669,7 @@ pcache_remove_entries_from_cache(
SlapReply rs = { REP_RESULT };
Filter f = { 0 };
char filtbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE + STRLENOF( "(entryUUID=)" ) ];
#ifdef LDAP_COMP_MATCH
AttributeAssertion ava = { NULL, BER_BVNULL, NULL };
#else
AttributeAssertion ava = { NULL, BER_BVNULL };
#endif
AttributeAssertion ava = ATTRIBUTEASSERTION_INIT;
AttributeName attrs[ 2 ] = { 0 };
int s, rc;
......@@ -1741,11 +1784,7 @@ pcache_remove_entry_queries_from_cache(
SlapReply rs = { REP_RESULT };
Filter f = { 0 };
char filter_str[ LDAP_LUTIL_UUIDSTR_BUFSIZE + STRLENOF( "(queryId=)" ) ];
#ifdef LDAP_COMP_MATCH
AttributeAssertion ava = { NULL, BER_BVNULL, NULL };
#else
AttributeAssertion ava = { NULL, BER_BVNULL };
#endif
AttributeAssertion ava = ATTRIBUTEASSERTION_INIT;
AttributeName attrs[ 2 ] = { 0 };
int rc;
......@@ -1874,35 +1913,18 @@ static int
pcache_op_cleanup( Operation *op, SlapReply *rs ) {
slap_callback *cb = op->o_callback;
struct search_info *si = cb->sc_private;
if ( rs->sr_type == REP_RESULT || op->o_abandon ||
rs->sr_err == SLAPD_ABANDON ) {
if ( si->save_attrs != NULL ) {
rs->sr_attrs = si->save_attrs;
op->ors_attrs = si->save_attrs;
}
op->o_callback = op->o_callback->sc_next;
op->o_tmpfree( cb, op->o_tmpmemctx );
}
return SLAP_CB_CONTINUE;
}
static int
pcache_response(
Operation *op,
SlapReply *rs )
{
struct search_info *si = op->o_callback->sc_private;
slap_overinst *on = si->on;
cache_manager *cm = on->on_bi.bi_private;
query_manager* qm = cm->qm;
if ( si->save_attrs != NULL ) {
rs->sr_attrs = si->save_attrs;
op->ors_attrs = si->save_attrs;
}
if ( rs->sr_type == REP_SEARCH ) {
Entry *e;
/* don't return more entries than requested by the client */
if ( si->slimit && rs->sr_nentries >= si->slimit ) {
si->slimit_exceeded = 1;
}
/* If we haven't exceeded the limit for this query,
* build a chain of answers to store. If we hit the
* limit, empty the chain and ignore the rest.
......@@ -1914,6 +1936,7 @@ pcache_response(
if ( !si->head ) si->head = e;
if ( si->tail ) si->tail->e_private = e;
si->tail = e;
} else {
si->over = 1;
si->count = 0;
......@@ -1926,16 +1949,43 @@ pcache_response(
}
}
} else if ( rs->sr_type == REP_RESULT ) {
if ( si->count ||
( si->qtemp->negttl && !si->count && !si->over &&
rs->sr_err == LDAP_SUCCESS )) {
CachedQuery *qc = qm->addfunc(op, qm, &si->query, si->qtemp,
si->count);
}
if ( rs->sr_type == REP_RESULT ||
op->o_abandon || rs->sr_err == SLAPD_ABANDON )
{
if ( si->save_attrs != NULL ) {
rs->sr_attrs = si->save_attrs;
op->ors_attrs = si->save_attrs;
}
if ( op->o_abandon || rs->sr_err == SLAPD_ABANDON ) {
filter_free( si->query.filter );
if ( si->count ) {
/* duplicate query, free it */
Entry *e;
for (;si->head; si->head=e) {
e = si->head->e_private;
si->head->e_private = NULL;
entry_free(si->head);
}
}
op->o_callback = op->o_callback->sc_next;
op->o_tmpfree( cb, op->o_tmpmemctx );
} else if ( si->caching_reason != PC_IGNORE ) {
CachedQuery *qc = qm->addfunc(op, qm, &si->query,
si->qtemp, si->caching_reason, 1 );
if ( qc != NULL ) {
if ( si->count )
switch ( si->caching_reason ) {
case PC_POSITIVE:
cache_entries( op, rs, &qc->q_uuid );
break;
case PC_SIZELIMIT:
qc->q_sizelimit = rs->sr_nentries;
break;
}
ldap_pvt_thread_rdwr_wunlock(&qc->rwlock);
ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
cm->num_cached_queries++;
Debug( pcache_debug, "STORED QUERIES = %lu\n",
......@@ -1953,6 +2003,7 @@ pcache_response(
}
ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
}
} else if ( si->count ) {
/* duplicate query, free it */
Entry *e;
......@@ -1962,10 +2013,57 @@ pcache_response(
entry_free(si->head);
}
}
} else {
filter_free( si->query.filter );
}
}
return SLAP_CB_CONTINUE;
}
static int
pcache_response(
Operation *op,
SlapReply *rs )
{
struct search_info *si = op->o_callback->sc_private;
if ( si->save_attrs != NULL ) {
rs->sr_attrs = si->save_attrs;
op->ors_attrs = si->save_attrs;
}
if ( rs->sr_type == REP_SEARCH ) {
/* don't return more entries than requested by the client */
if ( si->slimit_exceeded ) {
return 0;
}
} else if ( rs->sr_type == REP_RESULT ) {
if ( si->count ) {
if ( rs->sr_err == LDAP_SUCCESS ) {
si->caching_reason = PC_POSITIVE;
} else if ( rs->sr_err == LDAP_SIZELIMIT_EXCEEDED
&& si->qtemp->limitttl )
{
si->caching_reason = PC_SIZELIMIT;
}
} else if ( si->qtemp->negttl && !si->count && !si->over &&
rs->sr_err == LDAP_SUCCESS )
{
si->caching_reason = PC_NEGATIVE;
}
if ( si->slimit_exceeded ) {
rs->sr_err = LDAP_SIZELIMIT_EXCEEDED;
}
}
return SLAP_CB_CONTINUE;
}
......@@ -2203,6 +2301,7 @@ pcache_op_search(
Debug( pcache_debug, "QUERY ANSWERABLE\n", 0, 0, 0 );
op->o_tmpfree( filter_attrs, op->o_tmpmemctx );
ldap_pvt_thread_rdwr_rlock(&answerable->rwlock);
if ( BER_BVISNULL( &answerable->q_uuid )) {
/* No entries cached, just an empty result set */
i = rs->sr_err = 0;
......@@ -2212,6 +2311,7 @@ pcache_op_search(
op->o_callback = NULL;
i = cm->db.bd_info->bi_op_search( op, rs );
}
ldap_pvt_thread_rdwr_runlock(&answerable->rwlock);
ldap_pvt_thread_rdwr_runlock(&qtemp->t_rwlock);
op->o_bd = save_bd;
op->o_callback = save_cb;
......@@ -2255,6 +2355,13 @@ pcache_op_search(
si->max = cm->num_entries_limit ;
si->over<