From 1157b6dc6a767f3efc76ef4ba2b732933515302e Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Wed, 12 Sep 2007 21:09:04 +0000 Subject: [PATCH] handle sizelimit in caching (in partial fulfilment of ITS#5114) --- servers/slapd/overlays/pcache.c | 186 ++++++++++++++++++----- tests/data/proxycache.out | 44 +++++- tests/data/slapd-proxycache.conf | 13 +- tests/scripts/conf.sh | 2 + tests/scripts/test020-proxycache | 253 ++++++++++++++++++++++++------- 5 files changed, 394 insertions(+), 104 deletions(-) diff --git a/servers/slapd/overlays/pcache.c b/servers/slapd/overlays/pcache.c index 58c5e1e81e..0e9b80df30 100644 --- a/servers/slapd/overlays/pcache.c +++ b/servers/slapd/overlays/pcache.c @@ -72,6 +72,7 @@ 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 */ struct cached_query_s *next; /* next query in the template */ @@ -127,17 +128,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); +typedef void (CRfunc)(struct query_manager_s*, struct berval*); /* LDAP query cache */ typedef struct query_manager_s { @@ -225,7 +245,7 @@ add_query( query_manager* qm, Query* query, QueryTemplate *templ, - int positive); + pc_caching_reason_t why ); static int remove_query_data( @@ -452,7 +472,7 @@ url2query( goto error; } - cq = add_query( op, qm, &query, qt, 1 ); + cq = add_query( op, qm, &query, qt, PC_POSITIVE ); if ( cq != NULL ) { cq->expiry_time = expiry_time; cq->q_uuid = uuid; @@ -1093,6 +1113,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); @@ -1135,24 +1159,41 @@ add_query( query_manager* qm, Query* query, QueryTemplate *templ, - int positive) + pc_caching_reason_t why ) { 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; @@ -1286,7 +1327,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); @@ -1527,6 +1568,8 @@ struct search_info { int max; int over; int count; + int slimit; + int slimit_exceeded; Entry *head, *tail; }; @@ -1874,8 +1917,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 ( rs->sr_type == REP_SEARCH ) { + /* don't return more entries than requested by the client */ + if ( si->slimit && rs->sr_nentries >= si->slimit ) { + si->slimit_exceeded = 1; + } + } + + 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; @@ -1883,6 +1936,7 @@ pcache_op_cleanup( Operation *op, SlapReply *rs ) { op->o_callback = op->o_callback->sc_next; op->o_tmpfree( cb, op->o_tmpmemctx ); } + return SLAP_CB_CONTINUE; } @@ -1914,6 +1968,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 +1981,44 @@ pcache_response( } } + /* 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 || - ( si->qtemp->negttl && !si->count && !si->over && - rs->sr_err == LDAP_SUCCESS )) { - CachedQuery *qc = qm->addfunc(op, qm, &si->query, si->qtemp, - si->count); + pc_caching_reason_t why = PC_IGNORE; + + if ( si->count ) { + if ( rs->sr_err == LDAP_SUCCESS ) { + why = PC_POSITIVE; + + } else if ( rs->sr_err == LDAP_SIZELIMIT_EXCEEDED + && si->qtemp->limitttl ) + { + why = PC_SIZELIMIT; + } + + } else if ( si->qtemp->negttl && !si->count && !si->over && + rs->sr_err == LDAP_SUCCESS ) + { + why = PC_NEGATIVE; + } + + if ( why != PC_IGNORE ) { + CachedQuery *qc = qm->addfunc(op, qm, &si->query, + si->qtemp, why ); if ( qc != NULL ) { - if ( si->count ) + switch ( why ) { + case PC_POSITIVE: cache_entries( op, rs, &qc->q_uuid ); + break; + + case PC_SIZELIMIT: + qc->q_sizelimit = rs->sr_nentries; + break; + } ldap_pvt_thread_mutex_lock(&cm->cache_mutex); cm->num_cached_queries++; Debug( pcache_debug, "STORED QUERIES = %lu\n", @@ -1953,6 +2036,7 @@ pcache_response( } ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); } + } else if ( si->count ) { /* duplicate query, free it */ Entry *e; @@ -1962,10 +2046,16 @@ pcache_response( entry_free(si->head); } } + } else { filter_free( si->query.filter ); } + + if ( si->slimit_exceeded ) { + rs->sr_err = LDAP_SIZELIMIT_EXCEEDED; + } } + return SLAP_CB_CONTINUE; } @@ -2255,6 +2345,12 @@ pcache_op_search( si->max = cm->num_entries_limit ; si->over = 0; si->count = 0; + si->slimit = 0; + si->slimit_exceeded = 0; + if ( op->ors_slimit && op->ors_slimit < cm->num_entries_limit ) { + si->slimit = op->ors_slimit; + op->ors_slimit = cm->num_entries_limit; + } si->head = NULL; si->tail = NULL; si->save_attrs = op->ors_attrs; @@ -2455,9 +2551,10 @@ static ConfigTable pccfg[] = { "DESC 'A set of attributes to cache' " "SYNTAX OMsDirectoryString )", NULL, NULL }, { "proxytemplate", "filter> templates; temp; temp=temp->qmnext) { - if ( temp->negttl ) { - bv.bv_len = snprintf( c->cr_msg, sizeof( c->cr_msg ), - " %d %ld %ld", - temp->attr_set_index, - temp->ttl, - temp->negttl ); - } else { - bv.bv_len = snprintf( c->cr_msg, sizeof( c->cr_msg ), " %d %ld", - temp->attr_set_index, - temp->ttl ); - } + /* HEADS-UP: always print all; + * if optional == 0, ignore */ + bv.bv_len = snprintf( c->cr_msg, sizeof( c->cr_msg ), + " %d %ld %ld %ld", + temp->attr_set_index, + temp->ttl, + temp->negttl, + temp->limitttl ); bv.bv_len += temp->querystr.bv_len + 2; bv.bv_val = ch_malloc( bv.bv_len+1 ); ptr = bv.bv_val; @@ -2839,23 +2933,37 @@ pc_cf_gen( ConfigArgs *c ) ldap_pvt_thread_rdwr_init( &temp->t_rwlock ); temp->query = temp->query_last = NULL; if ( lutil_parse_time( c->argv[3], &t ) != 0 ) { - snprintf( c->cr_msg, sizeof( c->cr_msg ), "unable to parse template ttl=\"%s\"", + snprintf( c->cr_msg, sizeof( c->cr_msg ), + "unable to parse template ttl=\"%s\"", c->argv[3] ); Debug( LDAP_DEBUG_CONFIG, "%s: %s.\n", c->log, c->cr_msg, 0 ); return( 1 ); } temp->ttl = (time_t)t; - if ( c->argc == 5 ) { + temp->negttl = (time_t)0; + temp->limitttl = (time_t)0; + switch ( c->argc ) { + case 6: + if ( lutil_parse_time( c->argv[5], &t ) != 0 ) { + snprintf( c->cr_msg, sizeof( c->cr_msg ), + "unable to parse template sizelimit ttl=\"%s\"", + c->argv[5] ); + Debug( LDAP_DEBUG_CONFIG, "%s: %s.\n", c->log, c->cr_msg, 0 ); + return( 1 ); + } + temp->limitttl = (time_t)t; + /* fallthru */ + + case 5: if ( lutil_parse_time( c->argv[4], &t ) != 0 ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), - "unable to parse template negttl=\"%s\"", + "unable to parse template negative ttl=\"%s\"", c->argv[4] ); Debug( LDAP_DEBUG_CONFIG, "%s: %s.\n", c->log, c->cr_msg, 0 ); return( 1 ); } temp->negttl = (time_t)t; - } else { - temp->negttl = 0; + break; } temp->no_of_queries = 0; diff --git a/tests/data/proxycache.out b/tests/data/proxycache.out index 886f2549f1..96167929e4 100644 --- a/tests/data/proxycache.out +++ b/tests/data/proxycache.out @@ -1,4 +1,4 @@ -# Query 1: filter:(sn=Jon) attrs: all +# Query 1: filter:(sn=Jon) attrs:all (expect nothing) # Query 2: filter:(|(cn=*Jon*)(sn=Jon*)) attrs:cn sn title uid dn: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com cn: James A Jones 1 @@ -24,7 +24,7 @@ sn: Doe uid: johnd title: System Administrator, Information Technology Division -# Query 3: filter:(sn=Smith*) attrs:cn sn title uid +# Query 3: filter:(sn=Smith*) attrs:cn sn uid dn: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com cn: Jennifer Smith cn: Jen Smith @@ -65,7 +65,7 @@ postalAddress: Info Tech Division $ 535 W. William St. $ Anytown, MI 48103 mail: bjorn@mailgw.example.com telephoneNumber: +1 313 555 0355 -# Query 6: filter:(mail=*@mail.alumni.example.com) cn sn title uid +# Query 6: filter:(mail=*@mail.alumni.example.com) attrs:cn sn title uid dn: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com cn: Dorothy Stevens cn: Dot Stevens @@ -101,7 +101,7 @@ sn: Hampster uid: uham title: Secretary, UM Alumni Association -# Query 7: filter:(mail=*) cn sn title uid +# Query 7: filter:(mail=*) attrs:cn sn title uid dn: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=example, dc=com cn: Barbara Jensen @@ -176,7 +176,21 @@ sn: Hampster uid: uham title: Secretary, UM Alumni Association -# Query 8: filter:(|(cn=*Jones)(sn=Jones)) attrs:cn sn title uid +# Query 8: filter:(mail=*example.com) attrs:cn sn title uid +dn: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=example, + dc=com +cn: Barbara Jensen +cn: Babs Jensen +sn:: IEplbnNlbiA= +uid: bjensen +title: Mythical Manager, Research Systems + +# Query 9: filter:(uid=b*) attrs:mail +dn: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=example, + dc=com +mail: bjensen@mailgw.example.com + +# Query 10: filter:(|(cn=*Jones)(sn=Jones)) attrs:cn sn title uid dn: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com cn: James A Jones 1 cn: James Jones @@ -194,7 +208,7 @@ sn: Doe uid: jjones title: Senior Manager, Information Technology Division -# Query 9: filter:(sn=Smith) attrs:cn sn title uid +# Query 11: filter:(sn=Smith) attrs:cn sn title uid dn: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com cn: Jennifer Smith cn: Jen Smith @@ -202,7 +216,7 @@ sn: Smith uid: jen title: Telemarketer, UM Alumni Association -# Query 10: filter:(uid=bjorn) attrs:mail postaladdress telephonenumber cn uid +# Query 12: filter:(uid=bjorn) attrs:mail postaladdress telephonenumber cn uid dn: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=example,dc =com cn: Bjorn Jensen @@ -212,7 +226,7 @@ postalAddress: Info Tech Division $ 535 W. William St. $ Anytown, MI 48103 mail: bjorn@mailgw.example.com telephoneNumber: +1 313 555 0355 -# Query 11: filter:(mail=jaj@mail.alumni.example.com) cn sn title uid +# Query 13: filter:(mail=jaj@mail.alumni.example.com) attrs:cn sn title uid dn: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com cn: James A Jones 1 cn: James Jones @@ -221,3 +235,17 @@ sn: Jones uid: jaj title: Mad Cow Researcher, UM Alumni Association +# Query 14: filter:(mail=*example.com) attrs:cn sn title uid +dn: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=example, + dc=com +cn: Barbara Jensen +cn: Babs Jensen +sn:: IEplbnNlbiA= +uid: bjensen +title: Mythical Manager, Research Systems + +# Query 15: filter:(uid=b*) attrs:mail +dn: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=example,dc + =com +mail: bjorn@mailgw.example.com + diff --git a/tests/data/slapd-proxycache.conf b/tests/data/slapd-proxycache.conf index b9257c8ff3..87bffc6700 100644 --- a/tests/data/slapd-proxycache.conf +++ b/tests/data/slapd-proxycache.conf @@ -39,17 +39,20 @@ argsfile @TESTDIR@/slapd.2.args database ldap suffix "dc=example,dc=com" rootdn "dc=example,dc=com" +rootpw "secret" uri "@URI1@" +limits dn="cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=example,dc=com" size=1 + overlay pcache proxycache @BACKEND@ 100 2 @ENTRY_LIMIT@ @CACHETTL@ proxyattrset 0 sn cn title uid proxyattrset 1 mail postaladdress telephonenumber cn uid -proxytemplate (|(cn=)(sn=)) 0 @CACHETTL@ -proxytemplate (sn=) 0 @CACHETTL@ -proxytemplate (uid=) 1 @CACHETTL@ -proxytemplate (mail=) 0 @CACHETTL@ - +proxytemplate (|(cn=)(sn=)) 0 @CACHETTL@ @NCACHETTL@ @SCACHETTL@ +proxytemplate (sn=) 0 @CACHETTL@ @NCACHETTL@ @SCACHETTL@ +proxytemplate (uid=) 1 @CACHETTL@ @NCACHETTL@ @SCACHETTL@ +proxytemplate (mail=) 0 @CACHETTL@ @NCACHETTL@ @SCACHETTL@ + #bdb#cachesize 20 #hdb#cachesize 20 diff --git a/tests/scripts/conf.sh b/tests/scripts/conf.sh index e4a73a3b41..25dd524f01 100755 --- a/tests/scripts/conf.sh +++ b/tests/scripts/conf.sh @@ -71,6 +71,8 @@ sed -e "s/@BACKEND@/${BACKEND}/" \ -e "s;@PORT6@;${PORT6};" \ -e "s/@SASL_MECH@/${SASL_MECH}/" \ -e "s/@CACHETTL@/${CACHETTL}/" \ + -e "s/@NCACHETTL@/${NCACHETTL}/" \ + -e "s/@SCACHETTL@/${SCACHETTL}/" \ -e "s/@ENTRY_LIMIT@/${CACHE_ENTRY_LIMIT}/" \ -e "s;@TESTDIR@;${TESTDIR};" \ -e "s;@DATADIR@;${DATADIR};" \ diff --git a/tests/scripts/test020-proxycache b/tests/scripts/test020-proxycache index 070970af97..44e55b6bd9 100755 --- a/tests/scripts/test020-proxycache +++ b/tests/scripts/test020-proxycache @@ -14,7 +14,9 @@ ## . CACHETTL="1m" -CACHE_ENTRY_LIMIT=10 +NCACHETTL="1m" +SCACHETTL="1m" +CACHE_ENTRY_LIMIT=6 . $SRCDIR/scripts/defines.sh @@ -109,13 +111,17 @@ if test $RC != 0 ; then exit $RC fi -cat /dev/null > $SLAVEOUT +cat /dev/null > $SEARCHOUT echo "Making queries on the proxy cache..." -echo "Query 1: filter:(sn=Jon) attrs: all" -echo "# Query 1: filter:(sn=Jon) attrs: all" >> $SLAVEOUT +CNT=0 + +CNT=`expr $CNT + 1` +FILTER="(sn=Jon)" +echo "Query $CNT: filter:$FILTER attrs:all (expect nothing)" +echo "# Query $CNT: filter:$FILTER attrs:all (expect nothing)" >> $SEARCHOUT $LDAPSEARCH -x -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \ - 'sn=Jon' >> $SLAVEOUT 2>&1 + "$FILTER" >> $SEARCHOUT 2>> $TESTOUT RC=$? if test $RC != 0 ; then echo "ldapsearch failed ($RC)!" @@ -132,10 +138,13 @@ if test $RC != 0 ; then exit 0 fi -echo "Query 2: filter:(|(cn=*Jon*)(sn=Jon*)) attrs:cn sn title uid" -echo "# Query 2: filter:(|(cn=*Jon*)(sn=Jon*)) attrs:cn sn title uid" >> $SLAVEOUT +CNT=`expr $CNT + 1` +FILTER="(|(cn=*Jon*)(sn=Jon*))" +ATTRS="cn sn title uid" +echo "Query $CNT: filter:$FILTER attrs:$ATTRS" +echo "# Query $CNT: filter:$FILTER attrs:$ATTRS" >> $SEARCHOUT $LDAPSEARCH -x -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \ - '(|(cn=*Jon*)(sn=Jon*))' cn sn title uid >> $SLAVEOUT 2>&1 + "$FILTER" $ATTRS >> $SEARCHOUT 2>> $TESTOUT RC=$? if test $RC != 0 ; then echo "ldapsearch failed ($RC)!" @@ -143,10 +152,13 @@ if test $RC != 0 ; then exit $RC fi -echo "Query 3: filter:(sn=Smith*) attrs:cn sn uid" -echo "# Query 3: filter:(sn=Smith*) attrs:cn sn uid" >> $SLAVEOUT +CNT=`expr $CNT + 1` +FILTER="(sn=Smith*)" +ATTRS="cn sn uid" +echo "Query $CNT: filter:$FILTER attrs:$ATTRS" +echo "# Query $CNT: filter:$FILTER attrs:$ATTRS" >> $SEARCHOUT $LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \ - 'sn=Smith*' cn sn uid >> $SLAVEOUT 2>&1 + "$FILTER" $ATTRS >> $SEARCHOUT 2>> $TESTOUT RC=$? if test $RC != 0 ; then echo "ldapsearch failed ($RC)!" @@ -154,21 +166,13 @@ if test $RC != 0 ; then exit $RC fi -echo "Query 4: filter:(sn=Doe*) attrs:cn sn title uid" -echo "# Query 4: filter:(sn=Doe*) attrs:cn sn title uid" >> $SLAVEOUT +CNT=`expr $CNT + 1` +FILTER="(sn=Doe*)" +ATTRS="cn sn title uid" +echo "Query $CNT: filter:$FILTER attrs:$ATTRS" +echo "# Query $CNT: filter:$FILTER attrs:$ATTRS" >> $SEARCHOUT $LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \ - 'sn=Doe' cn sn title uid >> $SLAVEOUT 2>&1 -RC=$? -if test $RC != 0 ; then - echo "ldapsearch failed ($RC)!" - test $KILLSERVERS != no && kill -HUP $KILLPIDS - exit $RC -fi - -echo "Query 5: filter:(uid=bjorn) attrs:mail postaladdress telephonenumber cn uid" -echo "# Query 5: filter:(uid=bjorn) attrs:mail postaladdress telephonenumber cn uid" >> $SLAVEOUT -$LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \ - 'uid=bjorn' mail postaladdress telephonenumber cn uid >> $SLAVEOUT 2>&1 + "$FILTER" $ATTRS >> $SEARCHOUT 2>> $TESTOUT RC=$? if test $RC != 0 ; then echo "ldapsearch failed ($RC)!" @@ -176,10 +180,13 @@ if test $RC != 0 ; then exit $RC fi -echo "Query 6: filter:(mail=*@mail.alumni.example.com) cn sn title uid" -echo "# Query 6: filter:(mail=*@mail.alumni.example.com) cn sn title uid" >> $SLAVEOUT +CNT=`expr $CNT + 1` +FILTER="(uid=bjorn)" +ATTRS="mail postaladdress telephonenumber cn uid" +echo "Query $CNT: filter:$FILTER attrs:$ATTRS" +echo "# Query $CNT: filter:$FILTER attrs:$ATTRS" >> $SEARCHOUT $LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \ - 'mail=*@mail.alumni.example.com' cn sn title uid >> $SLAVEOUT 2>&1 + "$FILTER" $ATTRS >> $SEARCHOUT 2>> $TESTOUT RC=$? if test $RC != 0 ; then echo "ldapsearch failed ($RC)!" @@ -187,10 +194,13 @@ if test $RC != 0 ; then exit $RC fi -echo "Query 7: filter:(mail=*) cn sn title uid" -echo "# Query 7: filter:(mail=*) cn sn title uid" >> $SLAVEOUT +CNT=`expr $CNT + 1` +FILTER="(mail=*@mail.alumni.example.com)" +ATTRS="cn sn title uid" +echo "Query $CNT: filter:$FILTER attrs:$ATTRS" +echo "# Query $CNT: filter:$FILTER attrs:$ATTRS" >> $SEARCHOUT $LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \ - 'mail=*' cn sn title uid >> $SLAVEOUT 2>&1 + "$FILTER" $ATTRS >> $SEARCHOUT 2>> $TESTOUT RC=$? if test $RC != 0 ; then echo "ldapsearch failed ($RC)!" @@ -198,8 +208,78 @@ if test $RC != 0 ; then exit $RC fi -# queries 2-6 are cacheable -CACHEABILITY=0111110 +CNT=`expr $CNT + 1` +FILTER="(mail=*)" +ATTRS="cn sn title uid" +echo "Query $CNT: filter:$FILTER attrs:$ATTRS" +echo "# Query $CNT: filter:$FILTER attrs:$ATTRS" >> $SEARCHOUT +$LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \ + "$FILTER" $ATTRS >> $SEARCHOUT 2>> $TESTOUT +RC=$? +if test $RC != 0 ; then + echo "ldapsearch failed ($RC)!" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit $RC +fi + +CNT=`expr $CNT + 1` +FILTER="(mail=*example.com)" +ATTRS="cn sn title uid" +USERDN="cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=example,dc=com" +PASSWD="bjorn" +echo "Query $CNT: filter:$FILTER attrs:$ATTRS" +echo "# Query $CNT: filter:$FILTER attrs:$ATTRS" >> $SEARCHOUT +$LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \ + -D "$USERDN" -w "$PASSWD" \ + "$FILTER" $ATTRS >> $SEARCHOUT 2>> $TESTOUT +RC=$? +case $RC in +0) + echo "ldapsearch should have failed!" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit $RC + ;; +4) + echo "ldapsearch failed ($RC)" + ;; +*) + echo "ldapsearch failed ($RC)!" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit $RC + ;; +esac + +CNT=`expr $CNT + 1` +FILTER="(uid=b*)" +ATTRS="mail" +USERDN="cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=example,dc=com" +PASSWD="bjorn" +echo "Query $CNT: filter:$FILTER attrs:$ATTRS" +echo "# Query $CNT: filter:$FILTER attrs:$ATTRS" >> $SEARCHOUT +$LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \ + -D "$USERDN" -w "$PASSWD" \ + "$FILTER" $ATTRS >> $SEARCHOUT 2>> $TESTOUT +RC=$? +case $RC in +0) + echo "ldapsearch should have failed!" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit $RC + ;; +4) + echo "ldapsearch failed ($RC)" + ;; +*) + echo "ldapsearch failed ($RC)!" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit $RC + ;; +esac + +FIRST=$CNT + +# queries 2-6,8-9 are cacheable +CACHEABILITY=011111011 grep CACHEABLE $LOG2 | awk '{ if ($2 == "NOT") printf "Query %d not cacheable\n",NR @@ -221,10 +301,13 @@ else exit 1 fi -echo "Query 8: filter:(|(cn=*Jones)(sn=Jones)) attrs:cn sn title uid" -echo "# Query 8: filter:(|(cn=*Jones)(sn=Jones)) attrs:cn sn title uid" >> $SLAVEOUT +CNT=`expr $CNT + 1` +FILTER="(|(cn=*Jones)(sn=Jones))" +ATTRS="cn sn title uid" +echo "Query $CNT: filter:$FILTER attrs:$ATTRS" +echo "# Query $CNT: filter:$FILTER attrs:$ATTRS" >> $SEARCHOUT $LDAPSEARCH -x -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \ - '(|(cn=*Jones)(sn=Jones))' cn sn title uid >> $SLAVEOUT 2>&1 + "$FILTER" $ATTRS >> $SEARCHOUT 2>> $TESTOUT RC=$? if test $RC != 0 ; then echo "ldapsearch failed ($RC)!" @@ -232,10 +315,13 @@ if test $RC != 0 ; then exit $RC fi -echo "Query 9: filter:(sn=Smith) attrs:cn sn title uid" -echo "# Query 9: filter:(sn=Smith) attrs:cn sn title uid" >> $SLAVEOUT +CNT=`expr $CNT + 1` +FILTER="(sn=Smith)" +ATTRS="cn sn title uid" +echo "Query $CNT: filter:$FILTER attrs:$ATTRS" +echo "# Query $CNT: filter:$FILTER attrs:$ATTRS" >> $SEARCHOUT $LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \ - 'sn=Smith' cn sn title uid >> $SLAVEOUT 2>&1 + "$FILTER" $ATTRS >> $SEARCHOUT 2>> $TESTOUT RC=$? if test $RC != 0 ; then echo "ldapsearch failed ($RC)!" @@ -243,10 +329,13 @@ if test $RC != 0 ; then exit $RC fi -echo "Query 10: filter:(uid=bjorn) attrs:mail postaladdress telephonenumber cn uid" -echo "# Query 10: filter:(uid=bjorn) attrs:mail postaladdress telephonenumber cn uid" >> $SLAVEOUT +CNT=`expr $CNT + 1` +FILTER="(uid=bjorn)" +ATTRS="mail postaladdress telephonenumber cn uid" +echo "Query $CNT: filter:$FILTER attrs:$ATTRS" +echo "# Query $CNT: filter:$FILTER attrs:$ATTRS" >> $SEARCHOUT $LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \ - 'uid=bjorn' mail postaladdress telephonenumber cn uid >> $SLAVEOUT 2>&1 + "$FILTER" $ATTRS >> $SEARCHOUT 2>> $TESTOUT RC=$? if test $RC != 0 ; then echo "ldapsearch failed ($RC)!" @@ -254,10 +343,13 @@ if test $RC != 0 ; then exit $RC fi -echo "Query 11: filter:(mail=jaj@mail.alumni.example.com) cn sn title uid" -echo "# Query 11: filter:(mail=jaj@mail.alumni.example.com) cn sn title uid" >> $SLAVEOUT +CNT=`expr $CNT + 1` +FILTER="(mail=jaj@mail.alumni.example.com)" +ATTRS="cn sn title uid" +echo "Query $CNT: filter:$FILTER attrs:$ATTRS" +echo "# Query $CNT: filter:$FILTER attrs:$ATTRS" >> $SEARCHOUT $LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \ - 'mail=jaj@mail.alumni.example.com' cn sn title uid >> $SLAVEOUT 2>&1 + "$FILTER" $ATTRS >> $SEARCHOUT 2>> $TESTOUT RC=$? if test $RC != 0 ; then @@ -266,18 +358,75 @@ if test $RC != 0 ; then exit $RC fi -#queries 8-11 are answerable -ANSWERABILITY=1111 -grep ANSWERABLE $LOG2 | awk '{ - if (NR > 7) { +CNT=`expr $CNT + 1` +FILTER="(mail=*example.com)" +ATTRS="cn sn title uid" +USERDN="cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=example,dc=com" +PASSWD="bjorn" +echo "Query $CNT: filter:$FILTER attrs:$ATTRS" +echo "# Query $CNT: filter:$FILTER attrs:$ATTRS" >> $SEARCHOUT +$LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \ + -D "$USERDN" -w "$PASSWD" \ + "$FILTER" $ATTRS >> $SEARCHOUT 2>> $TESTOUT +RC=$? +case $RC in +0) + echo "ldapsearch should have failed!" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit $RC + ;; +4) + echo "ldapsearch failed ($RC)" + ;; +*) + echo "ldapsearch failed ($RC)!" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit $RC + ;; +esac + +CNT=`expr $CNT + 1` +FILTER="(uid=b*)" +ATTRS="mail" +USERDN="cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=example,dc=com" +PASSWD="bjorn" +echo "Query $CNT: filter:$FILTER attrs:$ATTRS" +echo "# Query $CNT: filter:$FILTER attrs:$ATTRS" >> $SEARCHOUT +$LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \ + -D "$USERDN" -w "$PASSWD" \ + "$FILTER" $ATTRS >> $SEARCHOUT 2>> $TESTOUT +RC=$? +case $RC in +0) + echo "ldapsearch should have failed!" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit $RC + ;; +4) + echo "ldapsearch failed ($RC)" + ;; +*) + echo "ldapsearch failed ($RC)!" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit $RC + ;; +esac + +#queries 10-12,15 are answerable, 13-14 are not +#actually, 12 would be answerable, but since 8 made mail=*example.com +#not answerable because of sizelimit, queries contained in it are no longer +#answerable as well +ANSWERABILITY=111001 +grep ANSWERABLE $LOG2 | awk -vFIRST=$FIRST '{ + if (NR > FIRST) { if ($2 == "NOT") printf "Query %d not answerable\n",NR else printf "Query %d answerable\n",NR } }' -ANSWERED=`grep ANSWERABLE $LOG2 | awk '{ - if (NR > 7) { +ANSWERED=`grep ANSWERABLE $LOG2 | awk -vFIRST=$FIRST '{ + if (NR > FIRST) { if ($2 == "NOT") printf "0" else @@ -295,7 +444,7 @@ else fi echo "Filtering ldapsearch results..." -. $LDIFFILTER < $SLAVEOUT > $SEARCHFLT +. $LDIFFILTER < $SEARCHOUT > $SEARCHFLT echo "Filtering original ldif..." . $LDIFFILTER < $PROXYCACHEOUT > $LDIFFLT echo "Comparing filter output..."