From 30ffa33d7e949ae21802a865e806d699dbe13281 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Mon, 14 Jul 2008 22:14:49 +0000 Subject: [PATCH] do not propagate undefined or otherwise broken search filters (ITS#5614) --- servers/slapd/back-ldap/back-ldap.h | 2 ++ servers/slapd/back-ldap/config.c | 31 ++++++++++++++++++-- servers/slapd/back-ldap/search.c | 44 +++++++++++++++++------------ servers/slapd/back-meta/back-meta.h | 13 +++++---- servers/slapd/back-meta/config.c | 30 ++++++++++++++++++++ servers/slapd/back-meta/map.c | 4 +++ 6 files changed, 98 insertions(+), 26 deletions(-) diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h index dedbe9da92..a5242e0a88 100644 --- a/servers/slapd/back-ldap/back-ldap.h +++ b/servers/slapd/back-ldap/back-ldap.h @@ -316,6 +316,7 @@ typedef struct ldapinfo_t { #endif /* SLAP_CONTROL_X_SESSION_TRACKING */ #define LDAP_BACK_F_NOREFS (0x00080000U) +#define LDAP_BACK_F_NOUNDEFFILTER (0x00100000U) #define LDAP_BACK_ISSET_F(ff,f) ( ( (ff) & (f) ) == (f) ) #define LDAP_BACK_ISMASK_F(ff,m,f) ( ( (ff) & (m) ) == (f) ) @@ -356,6 +357,7 @@ typedef struct ldapinfo_t { #endif /* SLAP_CONTROL_X_SESSION_TRACKING */ #define LDAP_BACK_NOREFS(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_NOREFS) +#define LDAP_BACK_NOUNDEFFILTER(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_NOUNDEFFILTER) int li_version; diff --git a/servers/slapd/back-ldap/config.c b/servers/slapd/back-ldap/config.c index bf8a8ff253..ca89cf97f0 100644 --- a/servers/slapd/back-ldap/config.c +++ b/servers/slapd/back-ldap/config.c @@ -71,6 +71,7 @@ enum { LDAP_BACK_CFG_QUARANTINE, LDAP_BACK_CFG_ST_REQUEST, LDAP_BACK_CFG_NOREFS, + LDAP_BACK_CFG_NOUNDEFFILTER, LDAP_BACK_CFG_REWRITE, @@ -311,11 +312,19 @@ static ConfigTable ldapcfg[] = { { "norefs", "true|FALSE", 2, 2, 0, ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_NOREFS, ldap_back_cf_gen, "( OLcfgDbAt:3.25 " - "NAME 'olcDbNorefs' " + "NAME 'olcDbNoRefs' " "DESC 'Do not return search reference responses' " "SYNTAX OMsBoolean " "SINGLE-VALUE )", NULL, NULL }, + { "noundeffilter", "true|FALSE", 2, 2, 0, + ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_NOUNDEFFILTER, + ldap_back_cf_gen, "( OLcfgDbAt:3.26 " + "NAME 'olcDbNoUndefFilter' " + "DESC 'Do not propagate undefined search filters' " + "SYNTAX OMsBoolean " + "SINGLE-VALUE )", + NULL, NULL }, { "suffixmassage", "[virtual]> value_int = LDAP_BACK_NOREFS( li ); break; + case LDAP_BACK_CFG_NOUNDEFFILTER: + c->value_int = LDAP_BACK_NOUNDEFFILTER( li ); + break; + default: /* FIXME: we need to handle all... */ assert( 0 ); @@ -1278,6 +1292,10 @@ ldap_back_cf_gen( ConfigArgs *c ) li->li_flags &= ~LDAP_BACK_F_NOREFS; break; + case LDAP_BACK_CFG_NOUNDEFFILTER: + li->li_flags &= ~LDAP_BACK_F_NOUNDEFFILTER; + break; + default: /* FIXME: we need to handle all... */ assert( 0 ); @@ -1931,6 +1949,15 @@ done_url:; } break; + case LDAP_BACK_CFG_NOUNDEFFILTER: + if ( c->value_int ) { + li->li_flags |= LDAP_BACK_F_NOUNDEFFILTER; + + } else { + li->li_flags &= ~LDAP_BACK_F_NOUNDEFFILTER; + } + break; + case LDAP_BACK_CFG_REWRITE: snprintf( c->cr_msg, sizeof( c->cr_msg ), "rewrite/remap capabilities have been moved " diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index 79549b22aa..4167e99721 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -102,24 +102,28 @@ ldap_back_munge_filter( goto done; } - oldfilter = *filter; - if ( newbv->bv_len > oldbv->bv_len ) { - filter->bv_len += newbv->bv_len - oldbv->bv_len; - if ( filter->bv_val == op->ors_filterstr.bv_val ) { - filter->bv_val = op->o_tmpalloc( filter->bv_len + 1, - op->o_tmpmemctx ); + /* if undef or invalid filter is not allowed, + * don't rewrite filter */ + if ( LDAP_BACK_NOUNDEFFILTER( li ) ) { + return -1; + } - AC_MEMCPY( filter->bv_val, op->ors_filterstr.bv_val, - op->ors_filterstr.bv_len + 1 ); + oldfilter = *filter; + filter->bv_len += newbv->bv_len - oldbv->bv_len; + if ( filter->bv_val == op->ors_filterstr.bv_val ) { + filter->bv_val = op->o_tmpalloc( filter->bv_len + 1, + op->o_tmpmemctx ); - } else { - filter->bv_val = op->o_tmprealloc( filter->bv_val, - filter->bv_len + 1, op->o_tmpmemctx ); - } + AC_MEMCPY( filter->bv_val, op->ors_filterstr.bv_val, + op->ors_filterstr.bv_len + 1 ); - ptr = filter->bv_val + ( ptr - oldfilter.bv_val ); + } else { + filter->bv_val = op->o_tmprealloc( filter->bv_val, + filter->bv_len + 1, op->o_tmpmemctx ); } + ptr = filter->bv_val + ( ptr - oldfilter.bv_val ); + AC_MEMCPY( &ptr[ newbv->bv_len ], &ptr[ oldbv->bv_len ], oldfilter.bv_len - ( ptr - filter->bv_val ) - oldbv->bv_len + 1 ); @@ -240,14 +244,18 @@ retry: goto finish; case LDAP_FILTER_ERROR: - if ( ldap_back_munge_filter( op, &filter ) ) { + switch (ldap_back_munge_filter( op, &filter ) ) { + case 0: + case -1: + /* invalid filters return success with no data */ + rs->sr_err = LDAP_SUCCESS; + rs->sr_text = NULL; + break; + + case 1: free_filter = 1; goto retry; } - - /* invalid filters return success with no data */ - rs->sr_err = LDAP_SUCCESS; - rs->sr_text = NULL; goto finish; default: diff --git a/servers/slapd/back-meta/back-meta.h b/servers/slapd/back-meta/back-meta.h index 8e73c1f272..62339568a6 100644 --- a/servers/slapd/back-meta/back-meta.h +++ b/servers/slapd/back-meta/back-meta.h @@ -316,6 +316,7 @@ typedef struct metatarget_t { #endif /* SLAP_CONTROL_X_SESSION_TRACKING */ #define META_BACK_TGT_NOREFS(mt) META_BACK_TGT_ISSET( (mt), LDAP_BACK_F_NOREFS ) +#define META_BACK_TGT_NOUNDEFFILTER(mt) META_BACK_TGT_ISSET( (mt), LDAP_BACK_F_NOUNDEFFILTER ) int mt_version; time_t mt_network_timeout; @@ -374,13 +375,13 @@ typedef struct metainfo_t { unsigned mi_flags; #define li_flags mi_flags /* uses flags as defined in */ -#define META_BACK_F_ONERR_STOP (0x00100000U) -#define META_BACK_F_ONERR_REPORT (0x00200000U) +#define META_BACK_F_ONERR_STOP (0x01000000U) +#define META_BACK_F_ONERR_REPORT (0x02000000U) #define META_BACK_F_ONERR_MASK (META_BACK_F_ONERR_STOP|META_BACK_F_ONERR_REPORT) -#define META_BACK_F_DEFER_ROOTDN_BIND (0x00400000U) -#define META_BACK_F_PROXYAUTHZ_ALWAYS (0x00800000U) /* users always proxyauthz */ -#define META_BACK_F_PROXYAUTHZ_ANON (0x01000000U) /* anonymous always proxyauthz */ -#define META_BACK_F_PROXYAUTHZ_NOANON (0x02000000U) /* anonymous remains anonymous */ +#define META_BACK_F_DEFER_ROOTDN_BIND (0x04000000U) +#define META_BACK_F_PROXYAUTHZ_ALWAYS (0x08000000U) /* users always proxyauthz */ +#define META_BACK_F_PROXYAUTHZ_ANON (0x10000000U) /* anonymous always proxyauthz */ +#define META_BACK_F_PROXYAUTHZ_NOANON (0x20000000U) /* anonymous remains anonymous */ #define META_BACK_ONERR_STOP(mi) LDAP_BACK_ISSET( (mi), META_BACK_F_ONERR_STOP ) #define META_BACK_ONERR_REPORT(mi) LDAP_BACK_ISSET( (mi), META_BACK_F_ONERR_REPORT ) diff --git a/servers/slapd/back-meta/config.c b/servers/slapd/back-meta/config.c index 52795400ef..c3424438e6 100644 --- a/servers/slapd/back-meta/config.c +++ b/servers/slapd/back-meta/config.c @@ -1483,6 +1483,36 @@ idassert-authzFrom "dn:" return( 1 ); } + /* do not propagate undefined search filters */ + } else if ( strcasecmp( argv[ 0 ], "noundeffilter" ) == 0 ) { + unsigned *flagsp = mi->mi_ntargets ? + &mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_flags + : &mi->mi_flags; + + if ( argc != 2 ) { + Debug( LDAP_DEBUG_ANY, + "%s: line %d: \"noundeffilter {TRUE|false}\" needs 1 argument.\n", + fname, lineno, 0 ); + return( 1 ); + } + + /* this is the default; we add it because the default might change... */ + switch ( check_true_false( argv[ 1 ] ) ) { + case 1: + *flagsp |= LDAP_BACK_F_NOUNDEFFILTER; + break; + + case 0: + *flagsp &= ~LDAP_BACK_F_NOUNDEFFILTER; + break; + + default: + Debug( LDAP_DEBUG_ANY, + "%s: line %d: \"noundeffilter {TRUE|false}\": unknown argument \"%s\".\n", + fname, lineno, argv[ 1 ] ); + return( 1 ); + } + /* anything else */ } else { return SLAP_CONF_UNKNOWN; diff --git a/servers/slapd/back-meta/map.c b/servers/slapd/back-meta/map.c index b4df6759f5..018c57f795 100644 --- a/servers/slapd/back-meta/map.c +++ b/servers/slapd/back-meta/map.c @@ -534,6 +534,10 @@ ldap_back_int_filter_map_rewrite( /* FIXME: treat UNDEFINED as FALSE */ case SLAPD_COMPARE_UNDEFINED: computed:; + if ( META_BACK_TGT_NOUNDEFFILTER( dc->target ) ) { + return LDAP_COMPARE_FALSE; + } + if ( META_BACK_TGT_T_F( dc->target ) ) { tmp = &ber_bvtf_false; break; -- 2.39.5