save old values when deleting (ITS#5258; not optimal)

This commit is contained in:
Pierangelo Masarati 2007-12-06 12:29:04 +00:00
parent 7a3f73efd8
commit 8958bcd60f

View File

@ -748,98 +748,129 @@ memberof_op_modify( Operation *op, SlapReply *rs )
save_dn = op->o_dn; save_dn = op->o_dn;
save_ndn = op->o_ndn; save_ndn = op->o_ndn;
if ( MEMBEROF_DANGLING_CHECK( mo ) if ( memberof_isGroupOrMember( op, &iswhat ) == LDAP_SUCCESS
&& !get_relax( op ) && ( iswhat & MEMBEROF_IS_GROUP ) )
&& memberof_isGroupOrMember( op, &iswhat ) == LDAP_SUCCESS
&& ( iswhat & MEMBEROF_IS_GROUP ) )
{ {
op->o_dn = op->o_bd->be_rootdn; Modifications *ml;
op->o_dn = op->o_bd->be_rootndn; int save_member = 0;
op->o_bd->bd_info = (BackendInfo *)on->on_info;
assert( op->orm_modlist != NULL ); for ( ml = op->orm_modlist; ml; ml = ml->sml_next ) {
if ( ml->sml_desc == mo->mo_ad_member ) {
for ( mlp = &op->orm_modlist; *mlp; ) { switch ( ml->sml_op ) {
Modifications *ml = *mlp; case LDAP_MOD_DELETE:
int i; case LDAP_MOD_REPLACE:
save_member = 1;
if ( !is_ad_subtype( ml->sml_desc, mo->mo_ad_member ) ) { break;
mlp = &ml->sml_next; }
continue;
} }
}
switch ( ml->sml_op ) { if ( save_member ) {
case LDAP_MOD_DELETE: BerVarray vals = NULL;
/* we don't care about cancellations: if the value
* exists, fine; if it doesn't, we let the underlying
* database fail as appropriate; */
mlp = &ml->sml_next;
break;
case LDAP_MOD_REPLACE: op->o_dn = op->o_bd->be_rootdn;
case LDAP_MOD_ADD: op->o_dn = op->o_bd->be_rootndn;
/* NOTE: right now, the attributeType we use op->o_bd->bd_info = (BackendInfo *)on->on_info;
* for member must have a normalized value */ rc = backend_attribute( op, NULL, &op->o_req_ndn,
assert( ml->sml_nvalues != NULL ); mo->mo_ad_member, &vals, ACL_READ );
op->o_bd->bd_info = (BackendInfo *)on;
if ( rc == LDAP_SUCCESS && vals != NULL ) {
memberof_saved_member_set( op, &saved_member_vals, vals );
ber_bvarray_free_x( vals, op->o_tmpmemctx );
}
}
for ( i = 0; !BER_BVISNULL( &ml->sml_nvalues[ i ] ); i++ ) { if ( MEMBEROF_DANGLING_CHECK( mo )
int rc; && !get_relax( op ) )
Entry *e; {
op->o_dn = op->o_bd->be_rootdn;
op->o_dn = op->o_bd->be_rootndn;
op->o_bd->bd_info = (BackendInfo *)on->on_info;
if ( be_entry_get_rw( op, &ml->sml_nvalues[ i ], assert( op->orm_modlist != NULL );
NULL, NULL, 0, &e ) == LDAP_SUCCESS )
{
be_entry_release_r( op, e );
continue;
}
if ( MEMBEROF_DANGLING_ERROR( mo ) ) { for ( mlp = &op->orm_modlist; *mlp; ) {
rc = rs->sr_err = LDAP_CONSTRAINT_VIOLATION; Modifications *ml = *mlp;
rs->sr_text = "adding non-existing object " int i;
"as group member";
send_ldap_result( op, rs );
goto done;
}
if ( MEMBEROF_DANGLING_DROP( mo ) ) { if ( !is_ad_subtype( ml->sml_desc, mo->mo_ad_member ) ) {
int j; mlp = &ml->sml_next;
continue;
}
Debug( LDAP_DEBUG_ANY, "%s: memberof_op_modify(\"%s\"): " switch ( ml->sml_op ) {
"member=\"%s\" does not exist (stripping...)\n", case LDAP_MOD_DELETE:
op->o_log_prefix, op->o_req_dn.bv_val, /* we don't care about cancellations: if the value
ml->sml_nvalues[ i ].bv_val ); * exists, fine; if it doesn't, we let the underlying
* database fail as appropriate; */
mlp = &ml->sml_next;
break;
for ( j = i + 1; !BER_BVISNULL( &ml->sml_nvalues[ j ] ); j++ ); case LDAP_MOD_REPLACE:
ber_memfree( ml->sml_values[ i ].bv_val ); case LDAP_MOD_ADD:
BER_BVZERO( &ml->sml_values[ i ] ); /* NOTE: right now, the attributeType we use
ber_memfree( ml->sml_nvalues[ i ].bv_val ); * for member must have a normalized value */
BER_BVZERO( &ml->sml_nvalues[ i ] ); assert( ml->sml_nvalues != NULL );
ml->sml_numvals--;
if ( j - i == 1 ) { for ( i = 0; !BER_BVISNULL( &ml->sml_nvalues[ i ] ); i++ ) {
break; int rc;
Entry *e;
if ( be_entry_get_rw( op, &ml->sml_nvalues[ i ],
NULL, NULL, 0, &e ) == LDAP_SUCCESS )
{
be_entry_release_r( op, e );
continue;
} }
AC_MEMCPY( &ml->sml_values[ i ], &ml->sml_values[ i + 1 ], if ( MEMBEROF_DANGLING_ERROR( mo ) ) {
sizeof( struct berval ) * ( j - i ) ); rc = rs->sr_err = LDAP_CONSTRAINT_VIOLATION;
AC_MEMCPY( &ml->sml_nvalues[ i ], &ml->sml_nvalues[ i + 1 ], rs->sr_text = "adding non-existing object "
sizeof( struct berval ) * ( j - i ) ); "as group member";
i--; send_ldap_result( op, rs );
goto done;
}
if ( MEMBEROF_DANGLING_DROP( mo ) ) {
int j;
Debug( LDAP_DEBUG_ANY, "%s: memberof_op_modify(\"%s\"): "
"member=\"%s\" does not exist (stripping...)\n",
op->o_log_prefix, op->o_req_dn.bv_val,
ml->sml_nvalues[ i ].bv_val );
for ( j = i + 1; !BER_BVISNULL( &ml->sml_nvalues[ j ] ); j++ );
ber_memfree( ml->sml_values[ i ].bv_val );
BER_BVZERO( &ml->sml_values[ i ] );
ber_memfree( ml->sml_nvalues[ i ].bv_val );
BER_BVZERO( &ml->sml_nvalues[ i ] );
ml->sml_numvals--;
if ( j - i == 1 ) {
break;
}
AC_MEMCPY( &ml->sml_values[ i ], &ml->sml_values[ i + 1 ],
sizeof( struct berval ) * ( j - i ) );
AC_MEMCPY( &ml->sml_nvalues[ i ], &ml->sml_nvalues[ i + 1 ],
sizeof( struct berval ) * ( j - i ) );
i--;
}
} }
if ( BER_BVISNULL( &ml->sml_nvalues[ 0 ] ) ) {
*mlp = ml->sml_next;
slap_mod_free( &ml->sml_mod, 0 );
free( ml );
} else {
mlp = &ml->sml_next;
}
break;
default:
assert( 0 );
} }
if ( BER_BVISNULL( &ml->sml_nvalues[ 0 ] ) ) {
*mlp = ml->sml_next;
slap_mod_free( &ml->sml_mod, 0 );
free( ml );
} else {
mlp = &ml->sml_next;
}
break;
default:
assert( 0 );
} }
} }
} }
@ -1280,12 +1311,10 @@ memberof_res_modify( Operation *op, SlapReply *rs )
/* fall thru */ /* fall thru */
case LDAP_MOD_REPLACE: case LDAP_MOD_REPLACE:
vals = memberof_saved_member_get( op, &saved_member_vals );
/* delete all ... */ /* delete all ... */
op->o_bd->bd_info = (BackendInfo *)on->on_info; if ( vals != NULL ) {
rc = backend_attribute( op, NULL, &op->o_req_ndn,
mo->mo_ad_member, &vals, ACL_READ );
op->o_bd->bd_info = (BackendInfo *)on;
if ( rc == LDAP_SUCCESS ) {
for ( i = 0; !BER_BVISNULL( &vals[ i ] ); i++ ) { for ( i = 0; !BER_BVISNULL( &vals[ i ] ); i++ ) {
(void)memberof_value_modify( op, rs, (void)memberof_value_modify( op, rs,
&vals[ i ], mo->mo_ad_memberof, &vals[ i ], mo->mo_ad_memberof,