struct berval si_logbase;
struct berval si_filterstr;
struct berval si_logfilterstr;
+ struct berval si_contextdn;
int si_scope;
int si_attrsonly;
char *si_anfile;
Modifications**,int, struct berval*,
struct berval *cookieCSN );
static int syncrepl_updateCookie(
- syncinfo_t *, Operation *, struct berval *,
+ syncinfo_t *, Operation *,
struct sync_cookie * );
static struct berval * slap_uuidstr_from_normalized(
struct berval *, struct berval *, void * );
*/
a.a_desc = slap_schema.si_ad_contextCSN;
e.e_attrs = &a;
- e.e_name = op->o_bd->be_suffix[0];
- e.e_nname = op->o_bd->be_nsuffix[0];
+ e.e_name = si->si_contextdn;
+ e.e_nname = si->si_contextdn;
at[0].an_name = a.a_desc->ad_cname;
at[0].an_desc = a.a_desc;
BER_BVZERO( &at[1].an_name );
{
ber_len_t ssf; /* ITS#5403, 3864 LDAP_OPT_X_SASL_SSF probably ought
to use sasl_ssf_t but currently uses ber_len_t */
- ldap_get_option( si->si_ld, LDAP_OPT_X_SASL_SSF, &ssf );
- op->o_sasl_ssf = ssf;
+ if ( ldap_get_option( si->si_ld, LDAP_OPT_X_SASL_SSF, &ssf )
+ == LDAP_SUCCESS )
+ op->o_sasl_ssf = ssf;
}
op->o_ssf = ( op->o_sasl_ssf > op->o_tls_ssf )
? op->o_sasl_ssf : op->o_tls_ssf;
BerVarray csn = NULL;
void *ctx = op->o_tmpmemctx;
- op->o_req_ndn = op->o_bd->be_nsuffix[0];
+ op->o_req_ndn = si->si_contextdn;
op->o_req_dn = op->o_req_ndn;
/* try to read stored contextCSN */
si->si_syncCookie.ctxcsn, si->si_syncCookie.rid,
si->si_syncCookie.sid );
} else {
+ /* ITS#6367: recreate the cookie so it has our SID, not our peer's */
+ ch_free( si->si_syncCookie.octet_str.bv_val );
+ slap_compose_sync_cookie( NULL, &si->si_syncCookie.octet_str,
+ si->si_syncCookie.ctxcsn, si->si_syncCookie.rid,
+ si->si_syncCookie.sid );
/* Look for contextCSN from syncprov overlay. */
check_syncprov( op, si );
}
err = LDAP_SUCCESS;
ber_len_t len;
- struct berval *psub;
Modifications *modlist = NULL;
int match, m;
Debug( LDAP_DEBUG_TRACE, "=>do_syncrep2 %s\n", si->si_ridtxt, 0, 0 );
- psub = &si->si_be->be_nsuffix[0];
-
slap_dup_sync_cookie( &syncCookie_req, &si->si_syncCookie );
if ( abs(si->si_type) == LDAP_SYNC_REFRESH_AND_PERSIST ) {
slap_parse_sync_cookie( &syncCookie, NULL );
if ( syncCookie.ctxcsn ) {
int i, sid = slap_parse_csn_sid( syncCookie.ctxcsn );
+ check_syncprov( op, si );
for ( i =0; i<si->si_cookieState->cs_num; i++ ) {
if ( si->si_cookieState->cs_sids[i] == sid &&
ber_bvcmp( syncCookie.ctxcsn, &si->si_cookieState->cs_vals[i] ) <= 0 ) {
if ( ( rc = syncrepl_message_to_op( si, op, msg ) ) == LDAP_SUCCESS &&
syncCookie.ctxcsn )
{
- rc = syncrepl_updateCookie( si, op, psub, &syncCookie );
+ rc = syncrepl_updateCookie( si, op, &syncCookie );
} else switch ( rc ) {
case LDAP_ALREADY_EXISTS:
case LDAP_NO_SUCH_OBJECT:
syncstate, &syncUUID, syncCookie.ctxcsn ) ) == LDAP_SUCCESS &&
syncCookie.ctxcsn )
{
- rc = syncrepl_updateCookie( si, op, psub, &syncCookie );
+ rc = syncrepl_updateCookie( si, op, &syncCookie );
}
}
ldap_controls_free( rctrls );
}
if ( syncCookie.ctxcsn && match < 0 && err == LDAP_SUCCESS )
{
- rc = syncrepl_updateCookie( si, op, psub, &syncCookie );
+ rc = syncrepl_updateCookie( si, op, &syncCookie );
}
if ( err == LDAP_SUCCESS
&& si->si_logstate == SYNCLOG_FALLBACK ) {
if ( syncCookie.ctxcsn )
{
- rc = syncrepl_updateCookie( si, op, psub, &syncCookie);
+ rc = syncrepl_updateCookie( si, op, &syncCookie);
}
}
if ( SLAP_GLUE_SUBORDINATE( be ) && !overlay_is_inst( be, "syncprov" )) {
BackendDB * top_be = select_backend( &be->be_nsuffix[0], 1 );
if ( overlay_is_inst( top_be, "syncprov" ))
- si->si_wbe = select_backend( &be->be_nsuffix[0], 1 );
+ si->si_wbe = top_be;
else
si->si_wbe = be;
} else {
si->si_wbe = be;
}
+ if ( SLAP_SYNC_SUBENTRY( si->si_wbe )) {
+ build_new_dn( &si->si_contextdn, &si->si_wbe->be_nsuffix[0],
+ (struct berval *)&slap_ldapsync_cn_bv, NULL );
+ } else {
+ si->si_contextdn = si->si_wbe->be_nsuffix[0];
+ }
}
if ( !si->si_schemachecking )
op->o_no_schema_check = 1;
op->o_tag = LBER_DEFAULT;
op->o_bd = si->si_wbe;
+ if ( BER_BVISEMPTY( &bdn ) && !BER_BVISEMPTY( &op->o_bd->be_nsuffix[0] ) ) {
+ Debug( LDAP_DEBUG_ANY,
+ "syncrepl_message_to_op: %s got empty dn",
+ si->si_ridtxt, 0, 0 );
+ return LDAP_OTHER;
+ }
+
while (( rc = ldap_get_attribute_ber( si->si_ld, msg, ber, &bv, &bvals ) )
== LDAP_SUCCESS ) {
if ( bv.bv_val == NULL )
return rc;
}
+ if ( BER_BVISEMPTY( &bdn ) && !BER_BVISEMPTY( &op->o_bd->be_nsuffix[0] ) ) {
+ Debug( LDAP_DEBUG_ANY,
+ "syncrepl_message_to_entry: %s got empty dn",
+ si->si_ridtxt, 0, 0 );
+ return LDAP_OTHER;
+ }
+
if ( syncstate == LDAP_SYNC_PRESENT || syncstate == LDAP_SYNC_DELETE ) {
/* NOTE: this could be done even before decoding the DN,
* although encoding errors wouldn't be detected */
syncrepl_updateCookie(
syncinfo_t *si,
Operation *op,
- struct berval *pdn,
struct sync_cookie *syncCookie )
{
Backend *be = op->o_bd;
cb.sc_private = si;
op->o_callback = &cb;
- op->o_req_dn = op->o_bd->be_suffix[0];
- op->o_req_ndn = op->o_bd->be_nsuffix[0];
+ op->o_req_dn = si->si_contextdn;
+ op->o_req_ndn = si->si_contextdn;
/* update contextCSN */
op->o_dont_replicate = 1;
op->orm_modlist = &mod;
op->orm_no_opattrs = 1;
rc = op->o_bd->be_modify( op, &rs_modify );
+
+ if ( rs_modify.sr_err == LDAP_NO_SUCH_OBJECT &&
+ SLAP_SYNC_SUBENTRY( op->o_bd )) {
+ const char *text;
+ char txtbuf[SLAP_TEXT_BUFLEN];
+ size_t textlen = sizeof txtbuf;
+ Entry *e = slap_create_context_csn_entry( op->o_bd, NULL );
+ rc = slap_mods2entry( &mod, &e, 0, 1, &text, txtbuf, textlen);
+ op->ora_e = e;
+ rc = op->o_bd->be_add( op, &rs_modify );
+ if ( e == op->ora_e )
+ be_entry_release_w( op, op->ora_e );
+ }
+
op->orm_no_opattrs = 0;
op->o_dont_replicate = 0;
if ( sie->si_logbase.bv_val ) {
ch_free( sie->si_logbase.bv_val );
}
+ if ( sie->si_be && SLAP_SYNC_SUBENTRY( sie->si_be )) {
+ ch_free( sie->si_contextdn.bv_val );
+ }
if ( sie->si_attrs ) {
int i = 0;
while ( sie->si_attrs[i] != NULL ) {
}
}
}
+ if ( j < 1 || si->si_retrynum_init[j-1] != RETRYNUM_FOREVER ) {
+ Debug( LDAP_DEBUG_CONFIG,
+ "%s: syncrepl will eventually stop retrying; the \"retry\" parameter should end with a '+'.\n",
+ c->log, 0, 0 );
+ }
+
si->si_retrynum_init[j] = RETRYNUM_TAIL;
si->si_retrynum[j] = RETRYNUM_TAIL;
si->si_retryinterval[j] = 0;