Commit d959e946 authored by Quanah Gibson-Mount's avatar Quanah Gibson-Mount
Browse files

ITS#9420 - Fix memory leak in modrdn

Fix provided by grapvar@gmail.com
parent b855258a
......@@ -382,6 +382,50 @@ cleanup:;
return rs->sr_err;
}
/* extracted from slap_modrdn2mods() */
static int
mod_op_add_val(
Operation *op,
AttributeDescription * const desc,
struct berval * const val,
short const sm_op )
{
int rv = LDAP_SUCCESS;
Modifications *mod_tmp;
mod_tmp = ( Modifications * )ch_malloc( sizeof( Modifications ) );
mod_tmp->sml_desc = desc;
BER_BVZERO( &mod_tmp->sml_type );
mod_tmp->sml_numvals = 1;
mod_tmp->sml_values = ( BerVarray )ch_malloc( 2 * sizeof( struct berval ) );
ber_dupbv( &mod_tmp->sml_values[0], val );
mod_tmp->sml_values[1].bv_val = NULL;
if( desc->ad_type->sat_equality && desc->ad_type->sat_equality->smr_normalize) {
mod_tmp->sml_nvalues = ( BerVarray )ch_malloc( 2 * sizeof( struct berval ) );
rv = desc->ad_type->sat_equality->smr_normalize(
SLAP_MR_EQUALITY|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
desc->ad_type->sat_syntax,
desc->ad_type->sat_equality,
&mod_tmp->sml_values[0],
&mod_tmp->sml_nvalues[0], NULL );
if (rv != LDAP_SUCCESS) {
ch_free(mod_tmp->sml_nvalues);
ch_free(mod_tmp->sml_values[0].bv_val);
ch_free(mod_tmp->sml_values);
ch_free(mod_tmp);
goto done;
}
mod_tmp->sml_nvalues[1].bv_val = NULL;
} else {
mod_tmp->sml_nvalues = NULL;
}
mod_tmp->sml_op = sm_op;
mod_tmp->sml_flags = 0;
mod_tmp->sml_next = op->orr_modlist;
op->orr_modlist = mod_tmp;
done:
return rv;
}
int
slap_modrdn2mods(
Operation *op,
......@@ -424,7 +468,6 @@ slap_modrdn2mods(
/* Add new attribute values to the entry */
for ( a_cnt = 0; new_rdn[a_cnt]; a_cnt++ ) {
AttributeDescription *desc = NULL;
Modifications *mod_tmp;
rs->sr_err = slap_bv2ad( &new_rdn[a_cnt]->la_attr, &desc, &rs->sr_text );
......@@ -449,43 +492,15 @@ slap_modrdn2mods(
}
/* Apply modification */
mod_tmp = ( Modifications * )ch_malloc( sizeof( Modifications ) );
mod_tmp->sml_desc = desc;
BER_BVZERO( &mod_tmp->sml_type );
mod_tmp->sml_numvals = 1;
mod_tmp->sml_values = ( BerVarray )ch_malloc( 2 * sizeof( struct berval ) );
ber_dupbv( &mod_tmp->sml_values[0], &new_rdn[a_cnt]->la_value );
mod_tmp->sml_values[1].bv_val = NULL;
if( desc->ad_type->sat_equality->smr_normalize) {
mod_tmp->sml_nvalues = ( BerVarray )ch_malloc( 2 * sizeof( struct berval ) );
rs->sr_err = desc->ad_type->sat_equality->smr_normalize(
SLAP_MR_EQUALITY|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
desc->ad_type->sat_syntax,
desc->ad_type->sat_equality,
&mod_tmp->sml_values[0],
&mod_tmp->sml_nvalues[0], NULL );
if (rs->sr_err != LDAP_SUCCESS) {
ch_free(mod_tmp->sml_nvalues);
ch_free(mod_tmp->sml_values[0].bv_val);
ch_free(mod_tmp->sml_values);
ch_free(mod_tmp);
goto done;
}
mod_tmp->sml_nvalues[1].bv_val = NULL;
} else {
mod_tmp->sml_nvalues = NULL;
}
mod_tmp->sml_op = SLAP_MOD_SOFTADD;
mod_tmp->sml_flags = 0;
mod_tmp->sml_next = op->orr_modlist;
op->orr_modlist = mod_tmp;
rs->sr_err = mod_op_add_val( op, desc, &new_rdn[a_cnt]->la_value, SLAP_MOD_SOFTADD );
if (rs->sr_err != LDAP_SUCCESS)
goto done;
}
/* Remove old rdn value if required */
if ( op->orr_deleteoldrdn ) {
for ( d_cnt = 0; old_rdn[d_cnt]; d_cnt++ ) {
AttributeDescription *desc = NULL;
Modifications *mod_tmp;
rs->sr_err = slap_bv2ad( &old_rdn[d_cnt]->la_attr, &desc, &rs->sr_text );
if ( rs->sr_err != LDAP_SUCCESS ) {
......@@ -498,29 +513,9 @@ slap_modrdn2mods(
}
/* Apply modification */
mod_tmp = ( Modifications * )ch_malloc( sizeof( Modifications ) );
mod_tmp->sml_desc = desc;
BER_BVZERO( &mod_tmp->sml_type );
mod_tmp->sml_numvals = 1;
mod_tmp->sml_values = ( BerVarray )ch_malloc( 2 * sizeof( struct berval ) );
ber_dupbv( &mod_tmp->sml_values[0], &old_rdn[d_cnt]->la_value );
mod_tmp->sml_values[1].bv_val = NULL;
if( desc->ad_type->sat_equality && desc->ad_type->sat_equality->smr_normalize) {
mod_tmp->sml_nvalues = ( BerVarray )ch_malloc( 2 * sizeof( struct berval ) );
(void) (*desc->ad_type->sat_equality->smr_normalize)(
SLAP_MR_EQUALITY|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
desc->ad_type->sat_syntax,
desc->ad_type->sat_equality,
&mod_tmp->sml_values[0],
&mod_tmp->sml_nvalues[0], NULL );
mod_tmp->sml_nvalues[1].bv_val = NULL;
} else {
mod_tmp->sml_nvalues = NULL;
}
mod_tmp->sml_op = LDAP_MOD_DELETE;
mod_tmp->sml_flags = 0;
mod_tmp->sml_next = op->orr_modlist;
op->orr_modlist = mod_tmp;
rs->sr_err = mod_op_add_val( op, desc, &old_rdn[d_cnt]->la_value, LDAP_MOD_DELETE );
if (rs->sr_err != LDAP_SUCCESS)
goto done;
}
}
......@@ -528,12 +523,8 @@ done:
/* LDAP v2 supporting correct attribute handling. */
if ( rs->sr_err != LDAP_SUCCESS && op->orr_modlist != NULL ) {
Modifications *tmp;
for ( ; op->orr_modlist != NULL; op->orr_modlist = tmp ) {
tmp = op->orr_modlist->sml_next;
ch_free( op->orr_modlist );
}
slap_mods_free( op->orr_modlist, 1 );
op->orr_modlist = NULL;
}
if ( new_rdn != NULL ) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment