diff --git a/CHANGES b/CHANGES index 09326c49840ed11523b0bbe0e3a229418cac2918..a79108bb1462677a03fd7198a572bc74fb1cfde1 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,8 @@ OpenLDAP 2.4 Change Log OpenLDAP 2.4.16 Engineering Fixed libldap segfault in checking cert/DN (ITS#5976) + Fixed slapd-ldap/meta with broken AD results (ITS#5977) + Fixed slapd-ldap/meta with invalid attrs again (ITS#5959) OpenLDAP 2.4.15 Release (2009/02/24) Fixed libldap alias dereferencing in C API again (ITS#5916) diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index 389278cb11321e5145729c81e3651e80cad6806d..b3a68b31411e21f23fe4793354cf1e228e3138b6 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -47,7 +47,8 @@ ldap_build_entry( Operation *op, LDAPMessage *e, Entry *ent, static int ldap_back_munge_filter( Operation *op, - struct berval *filter ) + struct berval *filter, + int *freeit ) { ldapinfo_t *li = (ldapinfo_t *) op->o_bd->be_private; @@ -122,6 +123,7 @@ ldap_back_munge_filter( AC_MEMCPY( filter->bv_val, op->ors_filterstr.bv_val, op->ors_filterstr.bv_len + 1 ); + *freeit = 1; } else { filter->bv_val = op->o_tmprealloc( filter->bv_val, filter->bv_len + 1, op->o_tmpmemctx ); @@ -163,7 +165,7 @@ ldap_back_search( filter = BER_BVNULL; int i; char **attrs = NULL; - int freetext = 0; + int freetext = 0, freefilter = 0; int do_retry = 1, dont_retry = 0; LDAPControl **ctrls = NULL; char **references = NULL; @@ -242,7 +244,7 @@ retry: goto finish; case LDAP_FILTER_ERROR: - if (ldap_back_munge_filter( op, &filter ) > 0 ) { + if (ldap_back_munge_filter( op, &filter, &freefilter ) > 0 ) { goto retry; } @@ -561,7 +563,7 @@ finish:; ldap_back_quarantine( op, rs ); } - if ( filter.bv_val != op->ors_filterstr.bv_val ) { + if ( freefilter && filter.bv_val != op->ors_filterstr.bv_val ) { op->o_tmpfree( filter.bv_val, op->o_tmpmemctx ); } @@ -732,6 +734,10 @@ ldap_build_entry( for ( i = 0; !BER_BVISNULL( &attr->a_vals[i] ); i++ ) ; last = i; + /* + * check that each value is valid per syntax + * and pretty if appropriate + */ for ( i = 0; i<last; i++ ) { struct berval pval; int rc; @@ -762,7 +768,9 @@ ldap_build_entry( } attr->a_vals[i] = attr->a_vals[last]; BER_BVZERO( &attr->a_vals[last] ); + i--; } + } else if ( pretty ) { LBER_FREE( attr->a_vals[i].bv_val ); attr->a_vals[i] = pval; @@ -782,10 +790,6 @@ ldap_build_entry( for ( i = 0; i < last; i++ ) { int rc; - /* - * check that each value is valid per syntax - * and pretty if appropriate - */ rc = attr->a_desc->ad_type->sat_equality->smr_normalize( SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, attr->a_desc->ad_type->sat_syntax, @@ -801,6 +805,7 @@ ldap_build_entry( } attr->a_vals[i] = attr->a_vals[last]; BER_BVZERO( &attr->a_vals[last] ); + i--; } } BER_BVZERO( &attr->a_nvals[i] ); @@ -814,6 +819,31 @@ ldap_build_entry( } attr->a_numvals = last; + + /* Handle sorted vals, strip dups but keep the attr */ + if ( attr->a_desc->ad_type->sat_flags & SLAP_AT_SORTED_VAL ) { + while ( attr->a_numvals > 1 ) { + int rc = slap_sort_vals( (Modifications *)attr, &text, &i, op->o_tmpmemctx ); + if ( rc != LDAP_TYPE_OR_VALUE_EXISTS ) + break; + + /* Strip duplicate values */ + if ( attr->a_nvals != attr->a_vals ) + LBER_FREE( attr->a_nvals[i].bv_val ); + LBER_FREE( attr->a_vals[i].bv_val ); + attr->a_numvals--; + if ( i < attr->a_numvals ) { + attr->a_vals[i] = attr->a_vals[attr->a_numvals]; + if ( attr->a_nvals != attr->a_vals ) + attr->a_nvals[i] = attr->a_nvals[attr->a_numvals]; + } + BER_BVZERO(&attr->a_vals[attr->a_numvals]); + if ( attr->a_nvals != attr->a_vals ) + BER_BVZERO(&attr->a_nvals[attr->a_numvals]); + } + attr->a_flags |= SLAP_ATTR_SORTED_VALS; + } + *attrp = attr; attrp = &attr->a_next; diff --git a/servers/slapd/back-meta/search.c b/servers/slapd/back-meta/search.c index a094de66edd0d774d5cc49958bd9fc6b20b45ecd..171221421df2c7f5271f00914c72b2ea9e971c4c 100644 --- a/servers/slapd/back-meta/search.c +++ b/servers/slapd/back-meta/search.c @@ -1801,6 +1801,7 @@ meta_send_entry( metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private; struct berval a, mapped; int check_duplicate_attrs = 0; + int check_sorted_attrs = 0; Entry ent = { 0 }; BerElement ber = *e->lm_ber; Attribute *attr, **attrp; @@ -1925,6 +1926,9 @@ meta_send_entry( } } + if ( attr->a_desc->ad_type->sat_flags & SLAP_AT_SORTED_VAL ) + check_sorted_attrs = 1; + /* no subschemaSubentry */ if ( attr->a_desc == slap_schema.si_ad_subschemaSubentry || attr->a_desc == slap_schema.si_ad_entryDN ) @@ -2157,6 +2161,35 @@ next_attr:; } } + /* Check for sorted attributes */ + if ( check_sorted_attrs ) { + for ( attr = ent.e_attrs; attr; attr = attr->a_next ) { + if ( attr->a_desc->ad_type->sat_flags & SLAP_AT_SORTED_VAL ) { + while ( attr->a_numvals > 1 ) { + int i; + int rc = slap_sort_vals( (Modifications *)attr, &text, &i, op->o_tmpmemctx ); + if ( rc != LDAP_TYPE_OR_VALUE_EXISTS ) + break; + + /* Strip duplicate values */ + if ( attr->a_nvals != attr->a_vals ) + LBER_FREE( attr->a_nvals[i].bv_val ); + LBER_FREE( attr->a_vals[i].bv_val ); + attr->a_numvals--; + if ( i < attr->a_numvals ) { + attr->a_vals[i] = attr->a_vals[attr->a_numvals]; + if ( attr->a_nvals != attr->a_vals ) + attr->a_nvals[i] = attr->a_nvals[attr->a_numvals]; + } + BER_BVZERO(&attr->a_vals[attr->a_numvals]); + if ( attr->a_nvals != attr->a_vals ) + BER_BVZERO(&attr->a_nvals[attr->a_numvals]); + } + attr->a_flags |= SLAP_ATTR_SORTED_VALS; + } + } + } + ldap_get_entry_controls( mc->mc_conns[target].msc_ld, e, &rs->sr_ctrls ); rs->sr_entry = &ent;