]> git.sur5r.net Git - openldap/commitdiff
disable pagedResults or reject
authorPierangelo Masarati <ando@openldap.org>
Sun, 4 Sep 2005 20:08:35 +0000 (20:08 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sun, 4 Sep 2005 20:08:35 +0000 (20:08 +0000)
servers/slapd/controls.c
servers/slapd/overlays/pcache.c
servers/slapd/proto-slap.h

index 5e249595602f463b53acb1853c6be5b16dc52480..4eddc8310b4bbbffdeb00b1ca033cf407177003f 100644 (file)
@@ -694,6 +694,74 @@ return_results:
        return rs->sr_err;
 }
 
+int
+slap_remove_control(
+       Operation       *op,
+       SlapReply       *rs,
+       int             ctrl,
+       BI_chk_controls fnc )
+{
+       int             i, j;
+
+       switch ( op->o_ctrlflag[ ctrl ] ) {
+       case SLAP_CONTROL_NONCRITICAL:
+               for ( i = 0, j = -1; op->o_ctrls[ i ] != NULL; i++ ) {
+                       if ( strcmp( op->o_ctrls[ i ]->ldctl_oid, slap_known_controls[ ctrl - 1 ] ) == 0 )
+                       {
+                               j = i;
+                       }
+               }
+
+               if ( j == -1 ) {
+                       rs->sr_err = LDAP_OTHER;
+                       break;
+               }
+
+               if ( fnc ) {
+                       (void)fnc( op, rs );
+               }
+
+               op->o_tmpfree( op->o_ctrls[ j ], op->o_tmpmemctx );
+
+               if ( i > 1 ) {
+                       AC_MEMCPY( &op->o_ctrls[ j ], &op->o_ctrls[ j + 1 ],
+                               ( i - j ) * sizeof( LDAPControl * ) );
+
+               } else {
+                       op->o_tmpfree( op->o_ctrls, op->o_tmpmemctx );
+                       op->o_ctrls = NULL;
+               }
+
+               op->o_ctrlflag[ ctrl ] = SLAP_CONTROL_IGNORED;
+
+               Debug( LDAP_DEBUG_ANY, "%s: "
+                       "non-critical control \"%s\" not supported; stripped.\n",
+                       op->o_log_prefix, slap_known_controls[ ctrl ], 0 );
+               /* fall thru */
+
+       case SLAP_CONTROL_IGNORED:
+       case SLAP_CONTROL_NONE:
+               rs->sr_err = SLAP_CB_CONTINUE;
+               break;
+
+       case SLAP_CONTROL_CRITICAL:
+               rs->sr_err = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
+               if ( fnc ) {
+                       (void)fnc( op, rs );
+               }
+               Debug( LDAP_DEBUG_ANY, "%s: "
+                       "critical control \"%s\" not supported.\n",
+                       op->o_log_prefix, slap_known_controls[ ctrl ], 0 );
+               break;
+
+       default:
+               /* handle all cases! */
+               assert( 0 );
+       }
+
+       return rs->sr_err;
+}
+
 #ifdef LDAP_DEVEL
 static int parseManageDIT (
        Operation *op,
@@ -892,48 +960,6 @@ static int parsePagedResults (
                goto done;
        }
 
-#if 0
-       /* defer cookie decoding/checks to backend... */
-       if ( cookie.bv_len ) {
-               PagedResultsCookie reqcookie;
-               if( cookie.bv_len != sizeof( reqcookie ) ) {
-                       /* bad cookie */
-                       rs->sr_text = "paged results cookie is invalid";
-                       rc = LDAP_PROTOCOL_ERROR;
-                       goto done;
-               }
-
-               AC_MEMCPY( &reqcookie, cookie.bv_val, sizeof( reqcookie ));
-
-               if ( reqcookie > op->o_pagedresults_state.ps_cookie ) {
-                       /* bad cookie */
-                       rs->sr_text = "paged results cookie is invalid";
-                       rc = LDAP_PROTOCOL_ERROR;
-                       goto done;
-
-               } else if ( reqcookie < op->o_pagedresults_state.ps_cookie ) {
-                       rs->sr_text = "paged results cookie is invalid or old";
-                       rc = LDAP_UNWILLING_TO_PERFORM;
-                       goto done;
-               }
-
-       } else {
-               /* Initial request.  Initialize state. */
-#if 0
-               if ( op->o_conn->c_pagedresults_state.ps_cookie != 0 ) {
-                       /* There's another pagedResults control on the
-                        * same connection; reject new pagedResults controls 
-                        * (allowed by RFC2696) */
-                       rs->sr_text = "paged results cookie unavailable; try later";
-                       rc = LDAP_UNWILLING_TO_PERFORM;
-                       goto done;
-               }
-#endif
-               op->o_pagedresults_state.ps_cookie = 0;
-               op->o_pagedresults_state.ps_count = 0;
-       }
-#endif
-
        ps = op->o_tmpalloc( sizeof(PagedResultsState), op->o_tmpmemctx );
        *ps = op->o_conn->c_pagedresults_state;
        ps->ps_size = size;
index 78549fbe26a80b00badb47ff69c219aeed8ea32d..d383f7614d61b1048ba2b28e664cc44b0efa5895 100644 (file)
@@ -1205,6 +1205,56 @@ add_filter_attrs(
        }
 }
 
+/* NOTE: this is a quick workaround to let pcache minimally interact
+ * with pagedResults.  A more articulated solutions would be to
+ * perform the remote query without control and cache all results,
+ * performing the pagedResults search only within the client
+ * and the proxy.  This requires pcache to understand pagedResults. */
+static int
+proxy_cache_remove_paged_results(
+       Operation       *op,
+       SlapReply       *rs )
+{
+       if ( op->o_pagedresults == SLAP_CONTROL_CRITICAL ) {
+               Debug( LDAP_DEBUG_ANY, "%s: "
+                       "critical pagedResults control disabled with proxy cache.\n",
+                       op->o_log_prefix, 0, 0 );
+
+       } else if ( op->o_pagedresults == SLAP_CONTROL_NONCRITICAL ) {
+               Debug( LDAP_DEBUG_ANY, "%s: "
+                       "non-critical pagedResults control disabled with proxy cache; stripped.\n",
+                       op->o_log_prefix, 0, 0 );
+       }
+
+       assert( op->o_pagedresults_state != NULL );
+       op->o_tmpfree( op->o_pagedresults_state, op->o_tmpmemctx );
+       op->o_pagedresults_state = NULL;
+
+       return 0;
+}
+
+static int
+proxy_cache_chk_controls(
+       Operation       *op,
+       SlapReply       *rs )
+{
+       int             rc = SLAP_CB_CONTINUE;
+
+       if ( op->o_pagedresults ) {
+               int     tmprc;
+
+               tmprc = slap_remove_control( op, rs, slap_cids.sc_pagedResults,
+                               proxy_cache_remove_paged_results );
+               if ( tmprc != SLAP_CB_CONTINUE ) {
+                       rc = tmprc;
+               }
+       }
+
+       rs->sr_err = rc;
+
+       return rc;
+}
+
 static int
 proxy_cache_search(
        Operation       *op,
@@ -1241,6 +1291,9 @@ proxy_cache_search(
        Debug( LDAP_DEBUG_ANY, "query template of incoming query = %s\n",
                                        tempstr.bv_val, 0, 0 );
 
+       /* FIXME: cannot cache/answer requests with pagedResults control */
+       
+
        /* find attr set */
        attr_set = get_attr_set(op->ors_attrs, qm, cm->numattrsets);
 
@@ -2080,6 +2133,8 @@ int pcache_init()
        proxy_cache.on_bi.bi_db_destroy = proxy_cache_destroy;
        proxy_cache.on_bi.bi_op_search = proxy_cache_search;
 
+       proxy_cache.on_bi.bi_chk_controls = proxy_cache_chk_controls;
+
        proxy_cache.on_bi.bi_cf_ocs = pcocs;
 
        code = config_register_schema( pccfg, pcocs );
index d79433ca2090c97047d99287bbf69c1baa75f806..1038da8cef72f6bc79ac4bcb40c642d7578b9fe3 100644 (file)
@@ -574,6 +574,11 @@ LDAP_SLAPD_F (int) slap_find_control_id LDAP_P ((
        const char *oid, int *cid ));
 LDAP_SLAPD_F (int) slap_global_control LDAP_P ((
        Operation *op, const char *oid, int *cid ));
+LDAP_SLAPD_F (int) slap_remove_control LDAP_P((
+       Operation       *op,
+       SlapReply       *rs,
+       int             ctrl,
+       BI_chk_controls fnc ));
 
 /*
  * config.c