From ec532ce88590c5454025cbc030d9df65d2df634f Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Sun, 4 Sep 2005 20:08:35 +0000 Subject: [PATCH] disable pagedResults or reject --- servers/slapd/controls.c | 110 ++++++++++++++++++++------------ servers/slapd/overlays/pcache.c | 55 ++++++++++++++++ servers/slapd/proto-slap.h | 5 ++ 3 files changed, 128 insertions(+), 42 deletions(-) diff --git a/servers/slapd/controls.c b/servers/slapd/controls.c index 5e24959560..4eddc8310b 100644 --- a/servers/slapd/controls.c +++ b/servers/slapd/controls.c @@ -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; diff --git a/servers/slapd/overlays/pcache.c b/servers/slapd/overlays/pcache.c index 78549fbe26..d383f7614d 100644 --- a/servers/slapd/overlays/pcache.c +++ b/servers/slapd/overlays/pcache.c @@ -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 ); diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index d79433ca20..1038da8cef 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -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