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,
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;
}
}
+/* 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,
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);
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 );