/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 1998-2006 The OpenLDAP Foundation.
+ * Copyright 1998-2007 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
int manageDSAit;
Modifications *modlist = op->orm_modlist;
int increment = op->orm_increment;
- BackendDB *op_be;
+ BackendDB *op_be, *bd = op->o_bd;
char textbuf[ SLAP_TEXT_BUFLEN ];
size_t textlen = sizeof( textbuf );
*/
op->o_bd = select_backend( &op->o_req_ndn, manageDSAit, 1 );
if ( op->o_bd == NULL ) {
+ op->o_bd = bd;
rs->sr_ref = referral_rewrite( default_referral,
NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT );
if (!rs->sr_ref) rs->sr_ref = default_referral;
if (rs->sr_ref != NULL ) {
rs->sr_err = LDAP_REFERRAL;
- op->o_bd = frontendDB;
send_ldap_result( op, rs );
- op->o_bd = NULL;
if (rs->sr_ref != default_referral) ber_bvarray_free( rs->sr_ref );
} else {
- op->o_bd = frontendDB;
send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
"no global superior knowledge" );
- op->o_bd = NULL;
}
goto cleanup;
}
}
cleanup:;
+ op->o_bd = bd;
return rs->sr_err;
}
#endif
}
-/* modify only calls this for non-replicas. modrdn always calls.
+/* Called for all modify and modrdn ops. If the current op was replicated
+ * from elsewhere, all of the attrs should already be present.
*/
void slap_mods_opattrs(
Operation *op,
char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
Modifications *mod, **modtail, *modlast;
+ int gotcsn = 0, gotmname = 0, gotmtime = 0;
if ( SLAP_LASTMOD( op->o_bd ) ) {
char *ptr;
timestamp.bv_val = timebuf;
+ for ( modtail = modsp; *modtail; modtail = &(*modtail)->sml_next ) {
+ if ( (*modtail)->sml_op != LDAP_MOD_ADD &&
+ (*modtail)->sml_op != LDAP_MOD_REPLACE ) continue;
+ if ( (*modtail)->sml_desc == slap_schema.si_ad_entryCSN ) {
+ csn = (*modtail)->sml_values[0];
+ gotcsn = 1;
+ } else
+ if ( (*modtail)->sml_desc == slap_schema.si_ad_modifiersName ) {
+ gotmname = 1;
+ } else
+ if ( (*modtail)->sml_desc == slap_schema.si_ad_modifyTimestamp ) {
+ gotmtime = 1;
+ }
+ }
if ( BER_BVISEMPTY( &op->o_csn )) {
- csn.bv_val = csnbuf;
- csn.bv_len = sizeof( csnbuf );
- slap_get_csn( op, &csn, manage_ctxcsn );
+ if ( !gotcsn ) {
+ csn.bv_val = csnbuf;
+ csn.bv_len = sizeof( csnbuf );
+ slap_get_csn( op, &csn, manage_ctxcsn );
+ } else {
+ if ( manage_ctxcsn )
+ slap_queue_csn( op, &csn );
+ }
} else {
csn = op->o_csn;
}
nname = op->o_ndn;
}
- for ( modtail = modsp; *modtail; modtail = &(*modtail)->sml_next )
- ;
-
- mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
- mod->sml_op = LDAP_MOD_REPLACE;
- mod->sml_flags = SLAP_MOD_INTERNAL;
- mod->sml_next = NULL;
- BER_BVZERO( &mod->sml_type );
- mod->sml_desc = slap_schema.si_ad_entryCSN;
- mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
- ber_dupbv( &mod->sml_values[0], &csn );
- BER_BVZERO( &mod->sml_values[1] );
- assert( !BER_BVISNULL( &mod->sml_values[0] ) );
- mod->sml_nvalues = NULL;
- *modtail = mod;
- modlast = mod;
- modtail = &mod->sml_next;
-
- if ( get_manageDIT( op ) ) {
- for ( mod = *modsp; mod != modlast; mod = mod->sml_next ) {
- if ( mod->sml_desc == slap_schema.si_ad_modifiersName ) {
- break;
- }
- }
+ if ( !gotcsn ) {
+ mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
+ mod->sml_op = LDAP_MOD_REPLACE;
+ mod->sml_flags = SLAP_MOD_INTERNAL;
+ mod->sml_next = NULL;
+ BER_BVZERO( &mod->sml_type );
+ mod->sml_desc = slap_schema.si_ad_entryCSN;
+ mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
+ ber_dupbv( &mod->sml_values[0], &csn );
+ BER_BVZERO( &mod->sml_values[1] );
+ assert( !BER_BVISNULL( &mod->sml_values[0] ) );
+ mod->sml_nvalues = NULL;
+ *modtail = mod;
+ modlast = mod;
+ modtail = &mod->sml_next;
}
- if ( mod->sml_desc != slap_schema.si_ad_modifiersName ) {
+ if ( !gotmname ) {
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
mod->sml_op = LDAP_MOD_REPLACE;
mod->sml_flags = SLAP_MOD_INTERNAL;
modtail = &mod->sml_next;
}
- if ( get_manageDIT( op ) ) {
- for ( mod = *modsp; mod != modlast; mod = mod->sml_next ) {
- if ( mod->sml_desc == slap_schema.si_ad_modifyTimestamp ) {
- break;
- }
- }
- }
-
- if ( mod->sml_desc != slap_schema.si_ad_modifyTimestamp ) {
+ if ( !gotmtime ) {
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
mod->sml_op = LDAP_MOD_REPLACE;
mod->sml_flags = SLAP_MOD_INTERNAL;