From 86528cfa1d8d707feb370d642ea9d1eb71326b48 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Thu, 26 Aug 2010 23:19:43 +0000 Subject: [PATCH] honor all user attrs --- contrib/slapd-modules/dupent/dupent.c | 181 +++++++++++++++----------- 1 file changed, 105 insertions(+), 76 deletions(-) diff --git a/contrib/slapd-modules/dupent/dupent.c b/contrib/slapd-modules/dupent/dupent.c index d448b9a6e1..42fc914f00 100644 --- a/contrib/slapd-modules/dupent/dupent.c +++ b/contrib/slapd-modules/dupent/dupent.c @@ -74,7 +74,7 @@ dupent_parseCtrl ( ber_len_t off = 0; ber_int_t PartialApplicationAllowed = 1; dupent_t *ds = NULL; - int i, c; + int i; if ( op->o_dupent != SLAP_CONTROL_NONE ) { rs->sr_text = "Dupent control specified multiple times"; @@ -136,75 +136,77 @@ dupent_parseCtrl ( goto done; } - /* FIXME: temporary */ - if ( cnt == 0 ) { - rs->sr_text = "Dupent control: no attrs not supported"; - rs->sr_err = LDAP_UNAVAILABLE_CRITICAL_EXTENSION; - goto done; - } - ds = (dupent_t *)op->o_tmpcalloc( 1, - sizeof(dupent_t) + sizeof(AttributeName)*(cnt + 1), + sizeof(dupent_t) + sizeof(AttributeName)*cnt, op->o_tmpmemctx ); - ds->ds_an = (AttributeName *)&ds[ 1 ]; - ds->ds_flags = 0; ds->ds_paa = PartialApplicationAllowed; - for ( i = 0, c = 0; i < cnt; i++ ) { - const char *text; - int j; - int rc; - AttributeDescription *ad = NULL; + if ( cnt == 0 ) { + ds->ds_flags |= SLAP_USERATTRS_YES; + + } else { + int c; + + ds->ds_an = (AttributeName *)&ds[ 1 ]; + + for ( i = 0, c = 0; i < cnt; i++ ) { + const char *text; + int j; + int rc; + AttributeDescription *ad = NULL; + + if ( bvmatch( &AttributeDescriptionList[i], + slap_bv_all_user_attrs ) ) + { + if ( ds->ds_flags & SLAP_USERATTRS_YES ) { + rs->sr_text = "Dupent control: AttributeDescription decoding error"; + rs->sr_err = LDAP_PROTOCOL_ERROR; + goto done; + } + + ds->ds_flags |= SLAP_USERATTRS_YES; + continue; + } - if ( bvmatch( &AttributeDescriptionList[i], - slap_bv_all_user_attrs ) ) - { - if ( ds->ds_flags & SLAP_USERATTRS_YES ) { - rs->sr_text = "Dupent control: AttributeDescription decoding error"; - rs->sr_err = LDAP_PROTOCOL_ERROR; - goto done; + rc = slap_bv2ad( &AttributeDescriptionList[i], &ad, &text ); + if ( rc != LDAP_SUCCESS ) { + continue; } - /* FIXME: temporary */ - rs->sr_text = "Dupent control: all user attrs not supported"; - rs->sr_err = LDAP_UNAVAILABLE_CRITICAL_EXTENSION; - goto done; + ds->ds_an[c].an_desc = ad; + ds->ds_an[c].an_name = ad->ad_cname; - ds->ds_flags |= SLAP_USERATTRS_YES; - continue; - } + /* FIXME: not specified; consider this an error, just in case */ + for ( j = 0; j < c; j++ ) { + if ( ds->ds_an[c].an_desc == ds->ds_an[j].an_desc ) { + rs->sr_text = "Dupent control: AttributeDescription must be unique within AttributeDescriptionList"; + rs->sr_err = LDAP_PROTOCOL_ERROR; + goto done; + } + } - rc = slap_bv2ad( &AttributeDescriptionList[i], &ad, &text ); - if ( rc != LDAP_SUCCESS ) { -#if 0 - rs->sr_text = "Dupent control: AttributeDescription decoding error"; - rs->sr_err = LDAP_PROTOCOL_ERROR; - goto done; -#endif - continue; + c++; } - ds->ds_an[c].an_desc = ad; - ds->ds_an[c].an_name = ad->ad_cname; + ds->ds_nattrs = c; + + if ( ds->ds_flags & SLAP_USERATTRS_YES ) { + /* purge user attrs */ + for ( i = 0; i < ds->ds_nattrs; ) { + if ( is_at_operational( ds->ds_an[i].an_desc->ad_type ) ) { + i++; + continue; + } - /* FIXME: not specified; we avoid it just in case */ - for ( j = 0; j < c; j++ ) { - if ( ds->ds_an[c].an_desc == ds->ds_an[j].an_desc ) { - rs->sr_text = "Dupent control: AttributeDescription must be unique within AttributeDescriptionList"; - rs->sr_err = LDAP_PROTOCOL_ERROR; - goto done; + ds->ds_nattrs--; + if ( i < ds->ds_nattrs ) { + ds->ds_an[i] = ds->ds_an[ds->ds_nattrs]; + } } } - - c++; } - ds->ds_nattrs = c; - - ber_memfree_x( AttributeDescriptionList, op->o_tmpmemctx ); - AttributeDescriptionList = NULL; - op->o_ctrldupent = (void *)ds; op->o_dupent = ctrl->ldctl_iscritical @@ -338,6 +340,32 @@ dupent_response_entry_1level( return rc; } +static int +dupent_attr_prepare( dupent_t *ds, Entry *e, valnum_t *valnum, int nattrs, int c, Attribute **app, Attribute **ap_listp ) +{ + valnum[c].ap = *app; + *app = (*app)->a_next; + + valnum[c].ap->a_next = *ap_listp; + *ap_listp = valnum[c].ap; + + valnum[c].a = *valnum[c].ap; + if ( c < nattrs - 1 ) { + valnum[c].a.a_next = &valnum[c + 1].a; + } else { + valnum[c].a.a_next = NULL; + } + valnum[c].a.a_numvals = 1; + valnum[c].a.a_vals = valnum[c].vals; + BER_BVZERO( &valnum[c].vals[1] ); + if ( valnum[c].ap->a_nvals != valnum[c].ap->a_vals ) { + valnum[c].a.a_nvals = valnum[c].nvals; + BER_BVZERO( &valnum[c].nvals[1] ); + } else { + valnum[c].a.a_nvals = valnum[c].a.a_vals; + } +} + static int dupent_response_entry( Operation *op, SlapReply *rs ) { @@ -352,15 +380,25 @@ dupent_response_entry( Operation *op, SlapReply *rs ) assert( rs->sr_type == REP_SEARCH ); for ( i = 0; i < dc->dc_ds->ds_nattrs; i++ ) { - Attribute *a; + Attribute *ap; - a = attr_find( rs->sr_entry->e_attrs, + ap = attr_find( rs->sr_entry->e_attrs, dc->dc_ds->ds_an[ i ].an_desc ); - if ( a && a->a_numvals > 1 ) { + if ( ap && ap->a_numvals > 1 ) { nattrs++; } } + if ( dc->dc_ds->ds_flags & SLAP_USERATTRS_YES ) { + Attribute *ap; + + for ( ap = rs->sr_entry->e_attrs; ap != NULL; ap = ap->a_next ) { + if ( !is_at_operational( ap->a_desc->ad_type ) && ap->a_numvals > 1 ) { + nattrs++; + } + } + } + if ( !nattrs ) { return SLAP_CB_CONTINUE; } @@ -379,28 +417,19 @@ dupent_response_entry( Operation *op, SlapReply *rs ) } if ( *app != NULL && (*app)->a_numvals > 1 ) { - valnum[c].ap = *app; - *app = (*app)->a_next; - - valnum[c].ap->a_next = ap_list; - ap_list = valnum[c].ap; + assert( c < nattrs ); + dupent_attr_prepare( dc->dc_ds, e, valnum, nattrs, c, app, &ap_list ); + c++; + } + } - valnum[c].a = *valnum[c].ap; - if ( c < nattrs - 1 ) { - valnum[c].a.a_next = &valnum[c + 1].a; - } else { - valnum[c].a.a_next = NULL; - } - valnum[c].a.a_numvals = 1; - valnum[c].a.a_vals = valnum[c].vals; - BER_BVZERO( &valnum[c].vals[1] ); - if ( valnum[c].ap->a_nvals != valnum[c].ap->a_vals ) { - valnum[c].a.a_nvals = valnum[c].nvals; - BER_BVZERO( &valnum[c].nvals[1] ); - } else { - valnum[c].a.a_nvals = valnum[c].a.a_vals; + if ( dc->dc_ds->ds_flags & SLAP_USERATTRS_YES ) { + for ( app = &e->e_attrs; *app != NULL; app = &(*app)->a_next ) { + if ( !is_at_operational( (*app)->a_desc->ad_type ) && (*app)->a_numvals > 1 ) { + assert( c < nattrs ); + dupent_attr_prepare( dc->dc_ds, e, valnum, nattrs, c, app, &ap_list ); + c++; } - c++; } } -- 2.39.5