/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 2003-2007 The OpenLDAP Foundation.
+ * Copyright 2003-2008 The OpenLDAP Foundation.
* Portions Copyright 2003 Pierangelo Masarati.
* All rights reserved.
*
} rwm_op_state;
static int
-rwm_db_destroy( BackendDB *be );
+rwm_db_destroy( BackendDB *be, ConfigReply *cr );
typedef struct rwm_op_cb {
slap_callback cb;
{
int j, last;
- for ( last = 0; !BER_BVISNULL( &(*ap)->a_vals[ last ] ); last++ )
- /* count values */ ;
- last--;
+ last = (*ap)->a_numvals - 1;
for ( j = 0; !BER_BVISNULL( &(*ap)->a_vals[ j ] ); j++ ) {
struct ldapmapping *mapping = NULL;
(*ap)->a_vals[ j ] = (*ap)->a_vals[ last ];
}
BER_BVZERO( &(*ap)->a_vals[ last ] );
+ (*ap)->a_numvals--;
last--;
j--;
}
}
isupdate = be_shadow_update( op );
- for ( mlp = &op->oq_modify.rs_modlist; *mlp; ) {
+ for ( mlp = &op->orm_modlist; *mlp; ) {
int is_oc = 0;
- Modifications *ml;
+ Modifications *ml = *mlp;
struct ldapmapping *mapping = NULL;
- /* duplicate the modlist */
- ml = ch_malloc( sizeof( Modifications ));
- *ml = **mlp;
- *mlp = ml;
-
+ /* ml points to a temporary mod until needs duplication */
if ( ml->sml_desc == slap_schema.si_ad_objectClass
|| ml->sml_desc == slap_schema.si_ad_structuralObjectClass )
{
} else if ( !isupdate && !get_relax( op ) && ml->sml_desc->ad_type->sat_no_user_mod )
{
+ ml = ch_malloc( sizeof( Modifications ) );
+ *ml = **mlp;
+ if ( (*mlp)->sml_values ) {
+ ber_bvarray_dup_x( &ml->sml_values, (*mlp)->sml_values, NULL );
+ if ( (*mlp)->sml_nvalues ) {
+ ber_bvarray_dup_x( &ml->sml_nvalues, (*mlp)->sml_nvalues, NULL );
+ }
+ }
+ *mlp = ml;
goto next_mod;
} else {
}
}
+ /* duplicate the modlist */
+ ml = ch_malloc( sizeof( Modifications ));
+ *ml = **mlp;
+ *mlp = ml;
+
if ( ml->sml_values != NULL ) {
int i, num;
struct berval *bva;
}
if ( !BER_BVISNULL( &id ) ) {
+ char idNul = id.bv_val[id.bv_len];
+ id.bv_val[id.bv_len] = '\0';
rs->sr_err = dnPrettyNormal( NULL, &id, &op->o_req_dn,
&op->o_req_ndn, op->o_tmpmemctx );
+ id.bv_val[id.bv_len] = idNul;
if ( rs->sr_err != LDAP_SUCCESS ) {
rs->sr_text = "Invalid DN";
return rs->sr_err;
int rc;
Attribute **ap;
int isupdate;
+ int check_duplicate_attrs = 0;
/*
* Rewrite the dn attrs, if needed
for ( ap = a_first; *ap; ) {
struct ldapmapping *mapping = NULL;
int drop_missing;
- int last=-1;
+ int last = -1;
Attribute *a;
if ( SLAP_OPATTRS( rs->sr_attr_flags ) && is_at_operational( (*ap)->a_desc->ad_type ) )
mapping->m_dst_ad->ad_type->sat_equality &&
mapping->m_dst_ad->ad_type->sat_equality->smr_normalize )
{
- int i=0;
- for ( last = 0; !BER_BVISNULL( &(*ap)->a_vals[last] ); last++ )
- /* just count */ ;
+ int i = 0;
+ last = (*ap)->a_numvals;
if ( last )
{
(*ap)->a_nvals = ch_malloc( (last+1) * sizeof(struct berval) );
BER_BVZERO( &(*ap)->a_nvals[i] );
}
}
+
/* rewrite the attribute description */
(*ap)->a_desc = mapping->m_dst_ad;
+
+ /* will need to check for duplicate attrs */
+ check_duplicate_attrs++;
}
}
}
if ( last == -1 ) { /* not yet counted */
- for ( last = 0; !BER_BVISNULL( &(*ap)->a_vals[last] ); last++ )
- /* just count */ ;
+ last = (*ap)->a_numvals;
}
if ( last == 0 ) {
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] ) {
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 */
}
}
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_numvals = (*tap)->a_numvals;
+ mod.sm_values = (*tap)->a_vals;
+ if ( (*tap)->a_nvals != (*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;
}
fname, lineno, argv[ 1 ] );
return 1;
}
+
} else if ( strcasecmp( argv[0], "normalize-mapped-attrs" ) == 0 ) {
if ( argc !=2 ) {
fprintf( stderr,
/* rewrite */
RWM_CF_REWRITE = 1,
RWM_CF_SUFFIXMASSAGE,
- RWM_CF_T_F_SUPPORT,
/* map */
RWM_CF_MAP,
+ RWM_CF_T_F_SUPPORT,
RWM_CF_NORMALIZE_MAPPED,
RWM_CF_LAST
switch ( c->type ) {
case RWM_CF_REWRITE:
- slap_rewrite_unparse( rwmap->rwm_bva_rewrite, &c->rvalue_vals );
- if ( !c->rvalue_vals ) rc = 1;
+ if ( rwmap->rwm_bva_rewrite == NULL ) {
+ rc = 1;
+
+ } else {
+ slap_rewrite_unparse( rwmap->rwm_bva_rewrite, &c->rvalue_vals );
+ if ( !c->rvalue_vals ) {
+ rc = 1;
+ }
+ }
break;
case RWM_CF_T_F_SUPPORT:
/* single modification is not allowed */
rc = 1;
- } else {
+ } else if ( rwmap->rwm_rw != NULL ) {
rewrite_info_delete( &rwmap->rwm_rw );
+ assert( rwmap->rwm_rw == NULL );
ber_bvarray_free( rwmap->rwm_bva_rewrite );
rwmap->rwm_bva_rewrite = NULL;
return rc;
}
-
-
-
-
-
-
static int
rwm_db_init(
- BackendDB *be )
+ BackendDB *be,
+ ConfigReply *cr )
{
slap_overinst *on = (slap_overinst *) be->bd_info;
struct ldaprwmap *rwmap;
on->on_bi.bi_private = (void *)rwmap;
if ( rc ) {
- (void)rwm_db_destroy( be );
+ (void)rwm_db_destroy( be, NULL );
}
return rc;
static int
rwm_db_destroy(
- BackendDB *be )
+ BackendDB *be,
+ ConfigReply *cr )
{
slap_overinst *on = (slap_overinst *) be->bd_info;
int rc = 0;