diff --git a/CHANGES b/CHANGES index 09cf77992932088d34d2c46aac610c9e12ea17c1..5756c73862f42fda72a32be7fa28da320b3b7cd9 100644 --- a/CHANGES +++ b/CHANGES @@ -2,12 +2,15 @@ OpenLDAP 2.4 Change Log OpenLDAP 2.4.12 Engineering Fixed slapd socket closing on Windows (ITS#5606) + Fixed slapd-ldap,slapd-meta invalid filter behavior (ITS#5614) Fixed slapd-meta quarantine behavior (ITS#5592) Fixed slapd-sql freeing of connection (ITS#5607) Fixed slapo-constraint string termination (ITS#5609) Fixed slapo-rwm callback cleanup (ITS#5601) Build Environment Fixed ODBC library detection (ITS#5602) + Documentation + Added slapd-ldap(5), slapd-meta(5) noundeffilter (ITS#5614) OpenLDAP 2.4.11 Release (2008/07/16) Fixed liblber ber_get_next length decoding (ITS#5580) diff --git a/doc/man/man5/slapd-ldap.5 b/doc/man/man5/slapd-ldap.5 index 4ce6d217951339071ea3b7f0bb18865a1dead58c..ddadfb493514aa0d279c5c1d9d7c91d1ba9edab6 100644 --- a/doc/man/man5/slapd-ldap.5 +++ b/doc/man/man5/slapd-ldap.5 @@ -391,6 +391,17 @@ If do not return search reference responses. By default, they are returned unless request is LDAPv2. +.TP +.B noundeffilter <NO|yes> +If +.BR yes , +return success instead of searching if a filter is undefined or contains +undefined portions. +By default, the search is propagated after replacing undefined portions +with +.BR (!(objectClass=*)) , +which corresponds to the empty result set. + .TP .B protocol\-version {0,2,3} This directive indicates what protocol version must be used to contact diff --git a/doc/man/man5/slapd-meta.5 b/doc/man/man5/slapd-meta.5 index 897578c22f84873a27ce87f641a24ff90273c500..e44dcd6bff8cafac65745461e1ede7af10427cbc 100644 --- a/doc/man/man5/slapd-meta.5 +++ b/doc/man/man5/slapd-meta.5 @@ -136,6 +136,19 @@ By default, they are returned unless request is LDAPv2. If set before any target specification, it affects all targets, unless overridden by any per-target directive. +.TP +.B noundeffilter <NO|yes> +If +.BR yes , +return success instead of searching if a filter is undefined or contains +undefined portions. +By default, the search is propagated after replacing undefined portions +with +.BR (!(objectClass=*)) , +which corresponds to the empty result set. +If set before any target specification, it affects all targets, unless +overridden by any per-target directive. + .TP .B protocol\-version {0,2,3} This directive indicates what protocol version must be used to contact diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h index dedbe9da92ea8c5654ad27168fae7d4847c9bf4a..a5242e0a88ebf40615cacd6a210d44c9928b03e3 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 bf8a8ff253c83fdae44d909ff6245490e6ae2485..ca89cf97f082a46f48b48f01f1148c2bb5a05384 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]> <real", 2, 3, 0, ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE, ldap_back_cf_gen, NULL, NULL, NULL }, @@ -358,7 +367,8 @@ static ConfigOCs ldapocs[] = { #ifdef SLAP_CONTROL_X_SESSION_TRACKING "$ olcDbSessionTrackingRequest " #endif /* SLAP_CONTROL_X_SESSION_TRACKING */ - "$ olcDbNorefs " + "$ olcDbNoRefs " + "$ olcDbNoUndefFilter " ") )", Cft_Database, ldapcfg}, { NULL, 0, NULL } @@ -1152,6 +1162,10 @@ ldap_back_cf_gen( ConfigArgs *c ) c->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 79549b22aa71fa466ff6346ee2f2c8588f3de35e..fb32cb0373acb404bee976057f47d0cc12152cf7 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -94,6 +94,17 @@ ldap_back_munge_filter( } else if ( strncmp( ptr, bv_undefined.bv_val, bv_undefined.bv_len ) == 0 ) { + /* if undef or invalid filter is not allowed, + * don't rewrite filter */ + if ( LDAP_BACK_NOUNDEFFILTER( li ) ) { + if ( filter->bv_val != op->ors_filterstr.bv_val ) { + op->o_tmpfree( filter->bv_val, op->o_tmpmemctx ); + } + BER_BVZERO( filter ); + gotit = -1; + goto done; + } + oldbv = &bv_undefined; newbv = &bv_F; @@ -103,23 +114,21 @@ ldap_back_munge_filter( } 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 ); - - AC_MEMCPY( filter->bv_val, op->ors_filterstr.bv_val, - op->ors_filterstr.bv_len + 1 ); + 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 ); @@ -152,7 +161,6 @@ ldap_back_search( msgid; struct berval match = BER_BVNULL, filter = BER_BVNULL; - int free_filter = 0; int i; char **attrs = NULL; int freetext = 0; @@ -240,8 +248,7 @@ retry: goto finish; case LDAP_FILTER_ERROR: - if ( ldap_back_munge_filter( op, &filter ) ) { - free_filter = 1; + if (ldap_back_munge_filter( op, &filter ) > 0 ) { goto retry; } @@ -525,6 +532,10 @@ finish:; ldap_back_quarantine( op, rs ); } + if ( filter.bv_val != op->ors_filterstr.bv_val ) { + op->o_tmpfree( filter.bv_val, op->o_tmpmemctx ); + } + #if 0 /* let send_ldap_result play cleanup handlers (ITS#4645) */ if ( rc != SLAPD_ABANDON ) @@ -550,10 +561,6 @@ finish:; rs->sr_matched = save_matched; } - if ( free_filter ) { - op->o_tmpfree( filter.bv_val, op->o_tmpmemctx ); - } - if ( rs->sr_text ) { if ( freetext ) { LDAP_FREE( (char *)rs->sr_text ); diff --git a/servers/slapd/back-meta/back-meta.h b/servers/slapd/back-meta/back-meta.h index 8e73c1f272d8f67c9dba6349d95a0b3c19bca391..62339568a6fdf317ba6ef8c90ee00097091c818b 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 <back-ldap/back-ldap.h> */ -#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 52795400efa26435b19aff9b677bcaf4c244607f..c3424438e6fd5715ae7042f059cc418ab532ae6a 100644 --- a/servers/slapd/back-meta/config.c +++ b/servers/slapd/back-meta/config.c @@ -1483,6 +1483,36 @@ idassert-authzFrom "dn:<rootdn>" 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 b4df6759f530af1a6f83a5ef7f4d79b84852e63a..962b4f05e51d3fa58e47891f8ae9e485cd208625 100644 --- a/servers/slapd/back-meta/map.c +++ b/servers/slapd/back-meta/map.c @@ -530,10 +530,15 @@ ldap_back_int_filter_map_rewrite( case SLAPD_FILTER_COMPUTED: switch ( f->f_result ) { - case LDAP_COMPARE_FALSE: /* FIXME: treat UNDEFINED as FALSE */ case SLAPD_COMPARE_UNDEFINED: computed:; + if ( META_BACK_TGT_NOUNDEFFILTER( dc->target ) ) { + return LDAP_COMPARE_FALSE; + } + /* fallthru */ + + case LDAP_COMPARE_FALSE: if ( META_BACK_TGT_T_F( dc->target ) ) { tmp = &ber_bvtf_false; break;