]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/overlays/pcache.c
More #5728 fallout
[openldap] / servers / slapd / overlays / pcache.c
index 6c3af99175aeb8c6834b63d111d8634f52d3ab14..450290fcc3ecbaa9eda4eae7257a14fefb0ae179 100644 (file)
@@ -182,6 +182,7 @@ typedef struct cache_manager_s {
        unsigned long   num_cached_queries;             /* total number of cached queries */
        unsigned long   max_queries;                    /* upper bound on # of cached queries */
        int             save_queries;                   /* save cached queries across restarts */
+       int     check_cacheability;             /* check whether a query is cacheable */
        int     numattrsets;                    /* number of attribute sets */
        int     cur_entries;                    /* current number of entries cached */
        int     max_entries;                    /* max number of entries cached */
@@ -1593,6 +1594,7 @@ struct search_info {
        Query query;
        QueryTemplate *qtemp;
        AttributeName*  save_attrs;     /* original attributes, saved for response */
+       int swap_saved_attrs;
        int max;
        int over;
        int count;
@@ -1960,6 +1962,14 @@ pcache_op_cleanup( Operation *op, SlapReply *rs ) {
                 * limit, empty the chain and ignore the rest.
                 */
                if ( !si->over ) {
+                       /* check if the entry contains undefined
+                        * attributes/objectClasses (ITS#5680) */
+                       if ( cm->check_cacheability && test_filter( op, rs->sr_entry, si->query.filter ) != LDAP_COMPARE_TRUE ) {
+                               Debug( pcache_debug, "%s: query not cacheable because of schema issues in DN \"%s\"\n",
+                                       op->o_log_prefix, rs->sr_entry->e_name.bv_val, 0 );
+                               goto over;
+                       }
+
                        if ( si->count < si->max ) {
                                si->count++;
                                e = entry_dup( rs->sr_entry );
@@ -1968,6 +1978,7 @@ pcache_op_cleanup( Operation *op, SlapReply *rs ) {
                                si->tail = e;
 
                        } else {
+over:;
                                si->over = 1;
                                si->count = 0;
                                for (;si->head; si->head=e) {
@@ -1984,7 +1995,7 @@ pcache_op_cleanup( Operation *op, SlapReply *rs ) {
        if ( rs->sr_type == REP_RESULT || 
                op->o_abandon || rs->sr_err == SLAPD_ABANDON )
        {
-               if ( si->save_attrs != NULL ) {
+               if ( si->swap_saved_attrs ) {
                        rs->sr_attrs = si->save_attrs;
                        op->ors_attrs = si->save_attrs;
                }
@@ -2067,7 +2078,7 @@ pcache_response(
 {
        struct search_info *si = op->o_callback->sc_private;
 
-       if ( si->save_attrs != NULL ) {
+       if ( si->swap_saved_attrs ) {
                rs->sr_attrs = si->save_attrs;
                op->ors_attrs = si->save_attrs;
        }
@@ -2164,7 +2175,7 @@ add_filter_attrs(
        }
        BER_BVZERO( &(*new_attrs)[j].an_name );
 
-       return count;
+       return j;
 }
 
 /* NOTE: this is a quick workaround to let pcache minimally interact
@@ -2416,6 +2427,7 @@ pcache_op_search(
                }
                si->head = NULL;
                si->tail = NULL;
+               si->swap_saved_attrs = 1;
                si->save_attrs = op->ors_attrs;
 
                op->ors_attrs = qtemp->t_attrs.attrs;
@@ -2634,6 +2646,11 @@ static ConfigTable pccfg[] = {
                "( OLcfgOvAt:2.6 NAME 'olcProxySaveQueries' "
                        "DESC 'Save cached queries for hot restart' "
                        "SYNTAX OMsBoolean )", NULL, NULL },
+       { "proxyCheckCacheability", "TRUE|FALSE",
+               2, 2, 0, ARG_ON_OFF|ARG_OFFSET, (void *)offsetof(cache_manager, check_cacheability),
+               "( OLcfgOvAt:2.7 NAME 'olcProxyCheckCacheability' "
+                       "DESC 'Check whether the results of a query are cacheable, e.g. for schema issues' "
+                       "SYNTAX OMsBoolean )", NULL, NULL },
 
        { NULL, NULL, 0, 0, 0, ARG_IGNORED }
 };
@@ -2653,7 +2670,7 @@ static ConfigOCs pcocs[] = {
                "DESC 'ProxyCache configuration' "
                "SUP olcOverlayConfig "
                "MUST ( olcProxyCache $ olcProxyAttrset $ olcProxyTemplate ) "
-               "MAY ( olcProxyResponseCB $ olcProxyCacheQueries $ olcProxySaveQueries ) )",
+               "MAY ( olcProxyResponseCB $ olcProxyCacheQueries $ olcProxySaveQueries $ olcProxyCheckCacheability ) )",
                Cft_Overlay, pccfg, NULL, pc_cfadd },
        { "( OLcfgOvOc:2.2 "
                "NAME 'olcPcacheDatabase' "
@@ -3146,6 +3163,7 @@ pcache_db_init(
        cm->cur_entries = 0;
        cm->max_queries = 10000;
        cm->save_queries = 0;
+       cm->check_cacheability = 0;
        cm->response_cb = PCACHE_RESPONSE_CB_TAIL;
        cm->defer_db_open = 1;
        cm->cc_period = 1000;