diff --git a/CHANGES b/CHANGES index e36100401d6f3ae3f01427cf0945bfaa9d8f09bb..06a1386a9349d99a199467138fa9f61ea1b94669 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,7 @@ OpenLDAP 2.4 Change Log OpenLDAP 2.4.25 Engineering Fixed slapd add objectclasses in order (ITS#6837) + Fixed slapd sortval handling (ITS#6845) Fixed slapd-ldap chain cn=config support (ITS#6837) Fixed slapd-meta deadlock (ITS#6846) Build Environment diff --git a/servers/slapd/add.c b/servers/slapd/add.c index 76bd732123bdf1160c26e2ace30b78e251ef61e5..c69ccefd6c1dadd1c5faff0f596fa1bbce40eaed 100644 --- a/servers/slapd/add.c +++ b/servers/slapd/add.c @@ -500,9 +500,6 @@ slap_mods2entry( } else { attr->a_nvals = attr->a_vals; } - /* slap_mods_check() gives us sorted results */ - if ( attr->a_desc->ad_type->sat_flags & SLAP_AT_SORTED_VAL ) - attr->a_flags |= SLAP_ATTR_SORTED_VALS; *tail = attr; tail = &attr->a_next; diff --git a/servers/slapd/attr.c b/servers/slapd/attr.c index fe2eded94ab796382ce23a1d3fced42ceae4d608..51f50758fcef64af13444d83e73127ebdaacf357 100644 --- a/servers/slapd/attr.c +++ b/servers/slapd/attr.c @@ -88,6 +88,8 @@ attr_alloc( AttributeDescription *ad ) ldap_pvt_thread_mutex_unlock( &attr_mutex ); a->a_desc = ad; + if ( ad && ( ad->ad_type->sat_flags & SLAP_AT_SORTED_VAL )) + a->a_flags |= SLAP_ATTR_SORTED_VALS; return a; } diff --git a/servers/slapd/back-bdb/modify.c b/servers/slapd/back-bdb/modify.c index b419db0af11e3cb4203ee97e65822f65b2a1dfdd..fb38f2df9fd782f303c0bf1d5a9260bf1b488d55 100644 --- a/servers/slapd/back-bdb/modify.c +++ b/servers/slapd/back-bdb/modify.c @@ -289,31 +289,23 @@ int bdb_modify_internal( if ( a2 ) { /* need to detect which values were deleted */ int i, j; - struct berval tmp; - j = ap->a_numvals; - for ( i=0; i<j; ) { + vals = op->o_tmpalloc( (ap->a_numvals + 1) * + sizeof(struct berval), op->o_tmpmemctx ); + j = 0; + for ( i=0; i < ap->a_numvals; i++ ) { rc = attr_valfind( a2, SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH, &ap->a_nvals[i], NULL, op->o_tmpmemctx ); - /* Move deleted values to end of array */ - if ( rc == LDAP_NO_SUCH_ATTRIBUTE ) { - j--; - if ( i != j ) { - tmp = ap->a_nvals[j]; - ap->a_nvals[j] = ap->a_nvals[i]; - ap->a_nvals[i] = tmp; - tmp = ap->a_vals[j]; - ap->a_vals[j] = ap->a_vals[i]; - ap->a_vals[i] = tmp; - } - continue; - } + /* Save deleted values */ + if ( rc == LDAP_NO_SUCH_ATTRIBUTE ) + vals[j++] = ap->a_nvals[i]; i++; } - vals = &ap->a_nvals[j]; + BER_BVZERO(vals+j); } else { /* attribute was completely deleted */ vals = ap->a_nvals; } + rc = 0; if ( !BER_BVISNULL( vals )) { rc = bdb_index_values( op, tid, ap->a_desc, vals, e->e_id, SLAP_INDEX_DELETE_OP ); @@ -323,9 +315,11 @@ int bdb_modify_internal( op->o_log_prefix, ap->a_desc->ad_cname.bv_val, 0 ); attrs_free( e->e_attrs ); e->e_attrs = save_attrs; - return rc; } } + if ( vals != ap->a_nvals ) + op->o_tmpfree( vals, op->o_tmpmemctx ); + if ( rc ) return rc; } }