mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-06 10:46:21 +08:00
save old values when deleting (ITS#5258; not optimal)
This commit is contained in:
parent
7a3f73efd8
commit
8958bcd60f
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user