abs(si->si_type), rhint );
}
- if ( (rc = ber_flatten2( ber, &c[0].ldctl_value, 0 ) ) == LBER_ERROR ) {
+ if ( (rc = ber_flatten2( ber, &c[0].ldctl_value, 0 ) ) == -1 ) {
ber_free_buf( ber );
return rc;
}
for ( i=0; i<num; i++ ) {
if ( ber_bvcmp( &a.a_nvals[i],
&si->si_cookieState->cs_vals[i] )) {
- changed =1;
+ changed = 1;
break;
}
}
OperationBuffer opbuf;
Operation *op;
int rc = LDAP_SUCCESS;
- int dostop = 0, do_setup = 0;
+ int dostop = 0;
ber_socket_t s;
int i, defer = 1, fail = 0;
Backend *be;
if ( rc == LDAP_SUCCESS ) {
if ( si->si_conn ) {
connection_client_enable( si->si_conn );
- goto success;
} else {
- do_setup = 1;
+ si->si_conn = connection_client_setup( s, do_syncrepl, arg );
}
} else if ( si->si_conn ) {
dostop = 1;
if ( rc == SYNC_PAUSED ) {
rtask->interval.tv_sec = 0;
ldap_pvt_runqueue_resched( &slapd_rq, rtask, 0 );
+ rtask->interval.tv_sec = si->si_interval;
rc = 0;
} else if ( rc == LDAP_SUCCESS ) {
if ( si->si_type == LDAP_SYNC_REFRESH_ONLY ) {
}
ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
-
- if ( do_setup )
- si->si_conn = connection_client_setup( s, do_syncrepl, arg );
-
-success:
ldap_pvt_thread_mutex_unlock( &si->si_mutex );
if ( rc ) {
struct berval dn;
struct berval ndn;
int renamed; /* Was an existing entry renamed? */
- int delOldRDN; /* Was old RDN deleted? */
Modifications **modlist; /* the modlist we received */
Modifications *mods; /* the modlist we compared */
} dninfo;
op->orr_newSup = NULL;
op->orr_nnewSup = NULL;
}
- op->orr_deleteoldrdn = dni.delOldRDN;
+ /* Let the modify handler take care of deleting old RDNs */
+ op->orr_deleteoldrdn = 0;
op->orr_modlist = NULL;
if ( ( rc = slap_modrdn2mods( op, &rs_modify ) ) ) {
goto done;
noldp = op->orr_nnewrdn;
ber_dupbv_x( &op->orr_nnewrdn, &noldp, op->o_tmpmemctx );
- /* Setup opattrs too */
- {
- static AttributeDescription *nullattr = NULL;
- static AttributeDescription **const opattrs[] = {
- &slap_schema.si_ad_entryCSN,
- &slap_schema.si_ad_modifiersName,
- &slap_schema.si_ad_modifyTimestamp,
- &nullattr
- };
- AttributeDescription *opattr;
- Modifications *mod, **modtail, **ml;
- int i;
-
- for ( mod = op->orr_modlist;
- mod->sml_next;
- mod = mod->sml_next )
- ;
- modtail = &mod->sml_next;
-
- /* pull mod off incoming modlist, append to orr_modlist */
- for ( i = 0; (opattr = *opattrs[i]) != NULL; i++ ) {
- for ( ml = modlist; *ml; ml = &(*ml)->sml_next )
- {
- if ( (*ml)->sml_desc == opattr ) {
- mod = *ml;
- *ml = mod->sml_next;
- mod->sml_next = NULL;
- *modtail = mod;
- modtail = &mod->sml_next;
- break;
- }
- }
- }
+ /* Remove the CSN for now, only propagate the Modify */
+ if ( syncCSN ) {
+ slap_graduate_commit_csn( op );
}
op->o_bd = si->si_wbe;
rc = op->o_bd->be_modrdn( op, &rs_modify );
"syncrepl_entry: %s be_modrdn (%d)\n",
si->si_ridtxt, rc, 0 );
op->o_bd = be;
- goto done;
+ /* Renamed entries still have other mods so just fallthru */
+ op->o_req_dn = entry->e_name;
+ op->o_req_ndn = entry->e_nname;
+ if ( syncCSN ) {
+ slap_queue_csn( op, syncCSN );
+ }
}
if ( dni.mods ) {
op->o_tag = LDAP_REQ_MODIFY;
op->o_tmpfree( cf, op->o_tmpmemctx );
op->ors_filter = of;
}
- if ( op->ors_filter ) filter_free_x( op, op->ors_filter );
+ if ( op->ors_filter ) filter_free_x( op, op->ors_filter, 1 );
}
Modifications mod;
struct berval first = BER_BVNULL;
- int rc, i, j, len;
+ int rc, i, j;
+ ber_len_t len;
slap_callback cb = { NULL };
SlapReply rs_modify = {REP_RESULT};
if ( memcmp( syncCookie->ctxcsn[i].bv_val,
si->si_cookieState->cs_vals[j].bv_val, len ) > 0 ) {
mod.sml_values[j] = syncCookie->ctxcsn[i];
- if ( BER_BVISNULL( &first ))
+ if ( BER_BVISNULL( &first ) ) {
first = syncCookie->ctxcsn[i];
+
+ } else if ( memcmp( syncCookie->ctxcsn[i].bv_val, first.bv_val, first.bv_len ) > 0 )
+ {
+ first = syncCookie->ctxcsn[i];
+ }
}
break;
}
( mod.sml_numvals+2 )*sizeof(struct berval), op->o_tmpmemctx );
mod.sml_values[mod.sml_numvals++] = syncCookie->ctxcsn[i];
BER_BVZERO( &mod.sml_values[mod.sml_numvals] );
- if ( BER_BVISNULL( &first ))
+ if ( BER_BVISNULL( &first ) ) {
first = syncCookie->ctxcsn[i];
+ } else if ( memcmp( syncCookie->ctxcsn[i].bv_val, first.bv_val, first.bv_len ) > 0 )
+ {
+ first = syncCookie->ctxcsn[i];
+ }
}
}
/* Should never happen, ITS#5065 */
op->o_req_ndn = op->o_bd->be_nsuffix[0];
/* update contextCSN */
- op->o_msgid = SLAP_SYNC_UPDATE_MSGID;
+ op->o_dont_replicate = 1;
op->orm_modlist = &mod;
op->orm_no_opattrs = 1;
rc = op->o_bd->be_modify( op, &rs_modify );
op->orm_no_opattrs = 0;
- op->o_msgid = 0;
+ op->o_dont_replicate = 0;
if ( rs_modify.sr_err == LDAP_SUCCESS ) {
slap_sync_cookie_free( &si->si_syncCookie, 0 );
* Modify would fail if provider has replaced entry with a new,
* and the new explicitly includes a superior of a class that was
* only included implicitly in the old entry. Ref ITS#5517.
+ *
+ * Also use replace op if attr has no equality matching rule.
+ * (ITS#5781)
*/
- if ( nn && no < o && old->a_desc == slap_schema.si_ad_objectClass )
+ if ( nn && no < o &&
+ ( old->a_desc == slap_schema.si_ad_objectClass ||
+ !old->a_desc->ad_type->sat_equality ))
no = o;
i = j;
if ( dni->new_entry ) {
Modifications **modtail, **ml;
Attribute *old, *new;
+ struct berval old_rdn, new_rdn;
+ struct berval old_p, new_p;
int is_ctx;
is_ctx = dn_match( &rs->sr_entry->e_nname,
&op->o_bd->be_nsuffix[0] );
/* Did the DN change?
+ * case changes in the parent are ignored,
+ * we only want to know if the RDN was
+ * actually changed.
*/
- if ( !dn_match( &rs->sr_entry->e_name,
- &dni->new_entry->e_name ) )
- {
- struct berval oldRDN, oldVal;
- AttributeDescription *ad = NULL;
- Attribute *a;
+ dnRdn( &rs->sr_entry->e_name, &old_rdn );
+ dnRdn( &dni->new_entry->e_name, &new_rdn );
+ dnParent( &rs->sr_entry->e_nname, &old_p );
+ dnParent( &dni->new_entry->e_nname, &new_p );
+ if ( !dn_match( &old_rdn, &new_rdn ) ||
+ ber_bvstrcasecmp( &old_p, &new_p ))
+ {
dni->renamed = 1;
- /* See if the oldRDN was deleted */
- dnRdn( &rs->sr_entry->e_nname, &oldRDN );
- oldVal.bv_val = strchr(oldRDN.bv_val, '=') + 1;
- oldVal.bv_len = oldRDN.bv_len - ( oldVal.bv_val -
- oldRDN.bv_val );
- oldRDN.bv_len -= oldVal.bv_len + 2;
- slap_bv2ad( &oldRDN, &ad, &rs->sr_text );
- a = attr_find( dni->new_entry->e_attrs, ad );
- if ( !a || attr_valfind( a,
- SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH |
- SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
- SLAP_MR_VALUE_OF_SYNTAX,
- &oldVal, NULL, op->o_tmpmemctx ) != LDAP_SUCCESS )
- {
- dni->delOldRDN = 1;
- }
- /* OK, this was just a modDN, we're done */
- return LDAP_SUCCESS;
+
+ /* A ModDN has happened, but other changes may have
+ * occurred before we picked it up. So fallthru to
+ * regular Modify processing.
+ */
}
modtail = &dni->mods;
new = attr_find( dni->new_entry->e_attrs,
slap_schema.si_ad_entryCSN );
if ( new && old ) {
- int rc, len = old->a_vals[0].bv_len;
+ int rc;
+ ber_len_t len = old->a_vals[0].bv_len;
if ( len > new->a_vals[0].bv_len )
len = new->a_vals[0].bv_len;
rc = memcmp( old->a_vals[0].bv_val,
}
if ( LogTest( LDAP_DEBUG_SYNC ) ) {
- char buf[sizeof("rid=999 not")];
+ char buf[sizeof("rid=999 non")];
snprintf( buf, sizeof(buf), "%s %s", si->si_ridtxt,
- present_uuid ? "got" : "not" );
+ present_uuid ? "" : "non" );
- Debug( LDAP_DEBUG_SYNC, "nonpresent_callback: %s UUID %s, dn %s\n",
+ Debug( LDAP_DEBUG_SYNC, "nonpresent_callback: %spresent UUID %s, dn %s\n",
buf, a ? a->a_vals[0].bv_val : "<missing>", rs->sr_entry->e_name.bv_val );
}
"Config: ** successfully added syncrepl \"%s\"\n",
BER_BVISNULL( &si->si_bindconf.sb_uri ) ?
"(null)" : si->si_bindconf.sb_uri.bv_val, 0, 0 );
- if ( !si->si_schemachecking ) {
- SLAP_DBFLAGS(c->be) |= SLAP_DBFLAG_NO_SCHEMA_CHECK;
- }
if ( c->be->be_syncinfo ) {
si->si_cookieState = c->be->be_syncinfo->si_cookieState;
} else {
{
struct berval bc, uri;
char buf[BUFSIZ*2], *ptr;
+ ber_len_t len;
int i;
-
-#define WHATSLEFT ( sizeof( buf ) - ( ptr - buf ) )
+# define WHATSLEFT ((ber_len_t) (&buf[sizeof( buf )] - ptr))
BER_BVZERO( bv );
ptr = buf;
assert( si->si_rid >= 0 && si->si_rid <= SLAP_SYNC_SID_MAX );
- ptr += snprintf( ptr, WHATSLEFT, IDSTR "=%03d " PROVIDERSTR "=%s",
+ len = snprintf( ptr, WHATSLEFT, IDSTR "=%03d " PROVIDERSTR "=%s",
si->si_rid, si->si_bindconf.sb_uri.bv_val );
- if ( ptr - buf >= sizeof( buf ) ) return;
+ if ( len >= sizeof( buf ) ) return;
+ ptr += len;
if ( !BER_BVISNULL( &bc ) ) {
if ( WHATSLEFT <= bc.bv_len ) {
free( bc.bv_val );
if ( WHATSLEFT <= STRLENOF( " " ATTRSONLYSTR "=\"" "\"" ) ) return;
ptr = lutil_strcopy( ptr, " " ATTRSSTR "=\"" );
old = ptr;
- /* FIXME: add check for overflow */
ptr = anlist_unparse( si->si_anlist, ptr, WHATSLEFT );
+ if ( ptr == NULL ) return;
if ( si->si_allattrs ) {
if ( WHATSLEFT <= STRLENOF( ",*\"" ) ) return;
if ( old != ptr ) *ptr++ = ',';
if ( si->si_exanlist && !BER_BVISNULL(&si->si_exanlist[0].an_name) ) {
if ( WHATSLEFT <= STRLENOF( " " EXATTRSSTR "=" ) ) return;
ptr = lutil_strcopy( ptr, " " EXATTRSSTR "=" );
- /* FIXME: add check for overflow */
ptr = anlist_unparse( si->si_exanlist, ptr, WHATSLEFT );
+ if ( ptr == NULL ) return;
}
if ( WHATSLEFT <= STRLENOF( " " SCHEMASTR "=" ) + STRLENOF( "off" ) ) return;
ptr = lutil_strcopy( ptr, " " SCHEMASTR "=" );
dd /= 60;
hh = dd % 24;
dd /= 24;
- ptr = lutil_strcopy( ptr, " " INTERVALSTR "=" );
- ptr += snprintf( ptr, WHATSLEFT, "%02d:%02d:%02d:%02d", dd, hh, mm, ss );
- if ( ptr - buf >= sizeof( buf ) ) return;
+ len = snprintf( ptr, WHATSLEFT, " %s=%02d:%02d:%02d:%02d",
+ INTERVALSTR, dd, hh, mm, ss );
+ if ( len >= WHATSLEFT ) return;
+ ptr += len;
} else if ( si->si_retryinterval ) {
- int space=0;
+ const char *space = "";
if ( WHATSLEFT <= STRLENOF( " " RETRYSTR "=\"" "\"" ) ) return;
ptr = lutil_strcopy( ptr, " " RETRYSTR "=\"" );
for (i=0; si->si_retryinterval[i]; i++) {
- if ( space ) *ptr++ = ' ';
- space = 1;
- ptr += snprintf( ptr, WHATSLEFT, "%ld ", (long) si->si_retryinterval[i] );
+ len = snprintf( ptr, WHATSLEFT, "%s%ld ", space,
+ (long) si->si_retryinterval[i] );
+ space = " ";
+ if ( WHATSLEFT - 1 <= len ) return;
+ ptr += len;
if ( si->si_retrynum_init[i] == RETRYNUM_FOREVER )
*ptr++ = '+';
- else
- ptr += snprintf( ptr, WHATSLEFT, "%d", si->si_retrynum_init[i] );
+ else {
+ len = snprintf( ptr, WHATSLEFT, "%d", si->si_retrynum_init[i] );
+ if ( WHATSLEFT <= len ) return;
+ ptr += len;
+ }
}
if ( WHATSLEFT <= STRLENOF( "\"" ) ) return;
*ptr++ = '"';
}
if ( si->si_slimit ) {
- if ( WHATSLEFT <= STRLENOF( " " SLIMITSTR "=" ) ) return;
- ptr = lutil_strcopy( ptr, " " SLIMITSTR "=" );
- ptr += snprintf( ptr, WHATSLEFT, "%d", si->si_slimit );
+ len = snprintf( ptr, WHATSLEFT, " " SLIMITSTR "=%d", si->si_slimit );
+ if ( WHATSLEFT <= len ) return;
+ ptr += len;
}
if ( si->si_tlimit ) {
- if ( WHATSLEFT <= STRLENOF( " " TLIMITSTR "=" ) ) return;
- ptr = lutil_strcopy( ptr, " " TLIMITSTR "=" );
- ptr += snprintf( ptr, WHATSLEFT, "%d", si->si_tlimit );
+ len = snprintf( ptr, WHATSLEFT, " " TLIMITSTR "=%d", si->si_tlimit );
+ if ( WHATSLEFT <= len ) return;
+ ptr += len;
}
if ( si->si_syncdata ) {