From 1b1fa920ce5a0255c024b3e4469603ecf15ed666 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Tue, 14 Aug 2007 11:59:44 +0000 Subject: [PATCH] import fix for ITS#5091 --- CHANGES | 1 + servers/slapd/back-meta/search.c | 67 +++++++++++++++++++++++++++++++- servers/slapd/overlays/rwm.c | 64 ++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 9975e9e33e..7f9df92668 100644 --- a/CHANGES +++ b/CHANGES @@ -13,6 +13,7 @@ OpenLDAP 2.3.38 Engineering Fixed slapd-hdb slapacl behavior (ITS#5087) Fixed slapd-relay configuration (ITS#4322,ITS#4340) Fixed slapd-sql structuralObjectClass issue (ITS#5088) + Fixed slapo-rwm/slapd-meta dup attrs after mapping (ITS#5091) Fixed slapo-syncprov uninit'd vars (ITS#5048,#5049) Fixed libldap ldap_add_result_entry (ITS#5056) Added client tools support for ppolicy response (ITS#5061) diff --git a/servers/slapd/back-meta/search.c b/servers/slapd/back-meta/search.c index 242d5a9576..f5828f11a3 100644 --- a/servers/slapd/back-meta/search.c +++ b/servers/slapd/back-meta/search.c @@ -1720,6 +1720,7 @@ meta_send_entry( { metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private; struct berval a, mapped; + int check_duplicate_attrs = 0; Entry ent = { 0 }; BerElement ber = *e->lm_ber; Attribute *attr, **attrp; @@ -1786,6 +1787,10 @@ meta_send_entry( ( void )ber_scanf( &ber, "x" /* [W] */ ); continue; } + if ( mapped.bv_val != a.bv_val ) { + /* will need to check for duplicate attrs */ + check_duplicate_attrs++; + } attr = ( Attribute * )ch_calloc( 1, sizeof( Attribute ) ); if ( attr == NULL ) { continue; @@ -1858,6 +1863,7 @@ meta_send_entry( ldap_back_map( &mi->mi_targets[ target ]->mt_rwmap.rwm_oc, bv, &mapped, BACKLDAP_REMAP ); if ( BER_BVISNULL( &mapped ) || mapped.bv_val[0] == '\0') { +remove_oc:; free( bv->bv_val ); BER_BVZERO( bv ); if ( --last < 0 ) { @@ -1868,8 +1874,23 @@ meta_send_entry( bv--; } else if ( mapped.bv_val != bv->bv_val ) { - free( bv->bv_val ); - ber_dupbv( bv, &mapped ); + int i; + + for ( i = 0; !BER_BVISNULL( &attr->a_vals[ i ] ); i++ ) { + if ( &attr->a_vals[ i ] == bv ) { + continue; + } + + if ( ber_bvstrcasecmp( &mapped, &attr->a_vals[ i ] ) == 0 ) { + break; + } + } + + if ( !BER_BVISNULL( &attr->a_vals[ i ] ) ) { + goto remove_oc; + } + + ber_bvreplace( bv, &mapped ); } } /* @@ -1957,6 +1978,48 @@ meta_send_entry( attrp = &attr->a_next; next_attr:; } + + /* only check if some mapping occurred */ + if ( check_duplicate_attrs ) { + Attribute **ap; + + for ( ap = &ent.e_attrs; *ap != NULL; ap = &(*ap)->a_next ) { + Attribute **tap; + + for ( tap = &(*ap)->a_next; *tap != NULL; ) { + if ( (*tap)->a_desc == (*ap)->a_desc ) { + Entry e = { 0 }; + Modification mod = { 0 }; + const char *text = NULL; + char textbuf[ SLAP_TEXT_BUFLEN ]; + Attribute *next = (*tap)->a_next; + + BER_BVSTR( &e.e_name, "" ); + BER_BVSTR( &e.e_nname, "" ); + e.e_attrs = *ap; + mod.sm_op = LDAP_MOD_ADD; + mod.sm_desc = (*ap)->a_desc; + mod.sm_type = mod.sm_desc->ad_cname; + mod.sm_values = (*tap)->a_vals; + mod.sm_nvalues = (*tap)->a_nvals; + + (void)modify_add_values( &e, &mod, + /* permissive */ 1, + &text, textbuf, sizeof( textbuf ) ); + + /* should not insert new attrs! */ + assert( e.e_attrs == *ap ); + + attr_free( *tap ); + *tap = next; + + } else { + tap = &(*tap)->a_next; + } + } + } + } + rs->sr_entry = &ent; rs->sr_attrs = op->ors_attrs; rs->sr_flags = 0; diff --git a/servers/slapd/overlays/rwm.c b/servers/slapd/overlays/rwm.c index f65e75a393..b836b5da1c 100644 --- a/servers/slapd/overlays/rwm.c +++ b/servers/slapd/overlays/rwm.c @@ -1075,6 +1075,7 @@ rwm_attrs( Operation *op, SlapReply *rs, Attribute** a_first, int stripEntryDN ) int rc; Attribute **ap; int isupdate; + int check_duplicate_attrs = 0; /* * Rewrite the dn attrs, if needed @@ -1128,6 +1129,9 @@ rwm_attrs( Operation *op, SlapReply *rs, Attribute** a_first, int stripEntryDN ) if ( mapping != NULL ) { (*ap)->a_desc = mapping->m_dst_ad; + + /* will need to check for duplicate attrs */ + check_duplicate_attrs++; } } @@ -1164,6 +1168,7 @@ rwm_attrs( Operation *op, SlapReply *rs, Attribute** a_first, int stripEntryDN ) rwm_map( &rwmap->rwm_oc, &bv[0], &mapped, RWM_REMAP ); if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) ) { +remove_oc:; ch_free( bv[0].bv_val ); BER_BVZERO( &bv[0] ); if ( &(*ap)->a_vals[last] > &bv[0] ) { @@ -1174,12 +1179,32 @@ rwm_attrs( Operation *op, SlapReply *rs, Attribute** a_first, int stripEntryDN ) bv--; } else if ( mapped.bv_val != bv[0].bv_val ) { + int i; + + for ( i = 0; !BER_BVISNULL( &(*ap)->a_vals[ i ] ); i++ ) { + if ( &(*ap)->a_vals[ i ] == bv ) { + continue; + } + + if ( ber_bvstrcasecmp( &mapped, &(*ap)->a_vals[ i ] ) == 0 ) { + break; + } + } + + if ( !BER_BVISNULL( &(*ap)->a_vals[ i ] ) ) { + goto remove_oc; + } + /* * FIXME: after LBER_FREEing * the value is replaced by * ch_alloc'ed memory */ ber_bvreplace( &bv[0], &mapped ); + + /* FIXME: will need to check + * if the structuralObjectClass + * changed */ } } @@ -1233,6 +1258,45 @@ cleanup_attr:; attr_free( a ); } + /* only check if some mapping occurred */ + if ( check_duplicate_attrs ) { + for ( ap = a_first; *ap != NULL; ap = &(*ap)->a_next ) { + Attribute **tap; + + for ( tap = &(*ap)->a_next; *tap != NULL; ) { + if ( (*tap)->a_desc == (*ap)->a_desc ) { + Entry e = { 0 }; + Modification mod = { 0 }; + const char *text = NULL; + char textbuf[ SLAP_TEXT_BUFLEN ]; + Attribute *next = (*tap)->a_next; + + BER_BVSTR( &e.e_name, "" ); + BER_BVSTR( &e.e_nname, "" ); + e.e_attrs = *ap; + mod.sm_op = LDAP_MOD_ADD; + mod.sm_desc = (*ap)->a_desc; + mod.sm_type = mod.sm_desc->ad_cname; + mod.sm_values = (*tap)->a_vals; + mod.sm_nvalues = (*tap)->a_nvals; + + (void)modify_add_values( &e, &mod, + /* permissive */ 1, + &text, textbuf, sizeof( textbuf ) ); + + /* should not insert new attrs! */ + assert( e.e_attrs == *ap ); + + attr_free( *tap ); + *tap = next; + + } else { + tap = &(*tap)->a_next; + } + } + } + } + return 0; } -- 2.47.2