Commit d9e9a8d4 authored by Quanah Gibson-Mount's avatar Quanah Gibson-Mount
Browse files

ITS#6373

parent 6f625b49
......@@ -9,6 +9,7 @@ OpenLDAP 2.4.20 Engineering
Fixed libldap uninitialized return value (ITS#6355)
Fixed liblutil constant (ITS#5909)
Added slapd handling of hex server IDs (ITS#6297)
Added slapd syncrepl contextCSN storing in subentry (ITS#6373)
Fixed slapd asserts in minimal environment (ITS#6361)
Fixed slapd configArgs initialization (ITS#6363)
Fixed slapd debug handling of LDAP_DEBUG_ANY (ITS#6324)
......
......@@ -1614,6 +1614,11 @@ with the inner suffix must come first in the configuration file.
You may also want to glue such databases together with the
.B olcSubordinate
attribute.
.TP
.B olcSyncUseSubentry: TRUE | FALSE
Store the syncrepl contextCSN in a subentry instead of the context entry
of the database. The subentry's RDN will be "cn=ldapsync". The default is
FALSE, meaning the contextCSN is stored in the context entry.
.HP
.hy 0
.B olcSyncrepl: rid=<replica ID>
......
......@@ -1602,6 +1602,11 @@ in order to work over all of the glued databases. E.g.
overlay syncprov
.fi
.RE
.TP
.B sync_use_subentry
Store the syncrepl contextCSN in a subentry instead of the context entry
of the database. The subentry's RDN will be "cn=ldapsync". By default
the contextCSN is stored in the context entry.
.HP
.hy 0
.B syncrepl rid=<replica ID>
......
......@@ -190,6 +190,7 @@ enum {
CFG_IX_INTLEN,
CFG_SYNTAX,
CFG_ACL_ADD,
CFG_SYNC_SUBENTRY,
CFG_LAST
};
......@@ -604,6 +605,10 @@ static ConfigTable config_back_cf_table[] = {
&config_suffix, "( OLcfgDbAt:0.10 NAME 'olcSuffix' "
"EQUALITY distinguishedNameMatch "
"SYNTAX OMsDN )", NULL, NULL },
{ "sync_use_subentry", NULL, 0, 0, 0, ARG_ON_OFF|ARG_DB|ARG_MAGIC|CFG_SYNC_SUBENTRY,
&config_generic, "( OLcfgDbAt:0.19 NAME 'olcSyncUseSubentry' "
"DESC 'Store sync context in a subentry' "
"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
{ "syncrepl", NULL, 0, 0, 0, ARG_DB|ARG_MAGIC,
&syncrepl_config, "( OLcfgDbAt:0.11 NAME 'olcSyncrepl' "
"EQUALITY caseIgnoreMatch "
......@@ -815,7 +820,7 @@ static ConfigOCs cf_ocs[] = {
"olcMaxDerefDepth $ olcPlugin $ olcReadOnly $ olcReplica $ "
"olcReplicaArgsFile $ olcReplicaPidFile $ olcReplicationInterval $ "
"olcReplogFile $ olcRequires $ olcRestrict $ olcRootDN $ olcRootPW $ "
"olcSchemaDN $ olcSecurity $ olcSizeLimit $ olcSyncrepl $ "
"olcSchemaDN $ olcSecurity $ olcSizeLimit $ olcSyncUseSubentry $ olcSyncrepl $ "
"olcTimeLimit $ olcUpdateDN $ olcUpdateRef $ olcMirrorMode $ "
"olcMonitoring ) )",
Cft_Database, NULL, cfAddDatabase },
......@@ -1085,6 +1090,9 @@ config_generic(ConfigArgs *c) {
case CFG_LASTMOD:
c->value_int = (SLAP_NOLASTMOD(c->be) == 0);
break;
case CFG_SYNC_SUBENTRY:
c->value_int = (SLAP_SYNC_SUBENTRY(c->be) != 0);
break;
case CFG_MIRRORMODE:
if ( SLAP_SHADOW(c->be))
c->value_int = (SLAP_SINGLE_SHADOW(c->be) == 0);
......@@ -1197,6 +1205,7 @@ config_generic(ConfigArgs *c) {
case CFG_SSTR_IF_MAX:
case CFG_SSTR_IF_MIN:
case CFG_ACL_ADD:
case CFG_SYNC_SUBENTRY:
break;
/* no-ops, requires slapd restart */
......@@ -1901,6 +1910,13 @@ sortval_reject:
SLAP_DBFLAGS(c->be) &= ~SLAP_DBFLAG_HIDDEN;
break;
case CFG_SYNC_SUBENTRY:
if (c->value_int)
SLAP_DBFLAGS(c->be) |= SLAP_DBFLAG_SYNC_SUBENTRY;
else
SLAP_DBFLAGS(c->be) &= ~SLAP_DBFLAG_SYNC_SUBENTRY;
break;
case CFG_SSTR_IF_MAX:
if (c->value_uint < index_substr_if_minlen) {
snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> invalid value", c->argv[0] );
......
......@@ -26,6 +26,8 @@
#include "slap.h"
#include "lutil_ldap.h"
const struct berval slap_ldapsync_bv = BER_BVC("ldapsync");
const struct berval slap_ldapsync_cn_bv = BER_BVC("cn=ldapsync");
int slap_serverID;
/* maxcsn->bv_val must point to a char buf[LDAP_LUTIL_CSNSTR_BUFSIZE] */
......@@ -133,6 +135,46 @@ slap_graduate_commit_csn( Operation *op )
return;
}
static struct berval ocbva[] = {
BER_BVC("top"),
BER_BVC("subentry"),
BER_BVC("syncProviderSubentry"),
BER_BVNULL
};
Entry *
slap_create_context_csn_entry(
Backend *be,
struct berval *context_csn )
{
Entry* e;
struct berval bv;
e = entry_alloc();
attr_merge( e, slap_schema.si_ad_objectClass,
ocbva, NULL );
attr_merge_one( e, slap_schema.si_ad_structuralObjectClass,
&ocbva[1], NULL );
attr_merge_one( e, slap_schema.si_ad_cn,
(struct berval *)&slap_ldapsync_bv, NULL );
if ( context_csn ) {
attr_merge_one( e, slap_schema.si_ad_contextCSN,
context_csn, NULL );
}
BER_BVSTR( &bv, "{}" );
attr_merge_one( e, slap_schema.si_ad_subtreeSpecification, &bv, NULL );
build_new_dn( &e->e_name, &be->be_nsuffix[0],
(struct berval *)&slap_ldapsync_cn_bv, NULL );
ber_dupbv( &e->e_nname, &e->e_name );
return e;
}
void
slap_queue_csn(
Operation *op,
......
......@@ -124,6 +124,7 @@ typedef struct sessionlog {
typedef struct syncprov_info_t {
syncops *si_ops;
BerVarray si_ctxcsn; /* ldapsync context */
struct berval si_contextdn;
int *si_sids;
int si_numcsns;
int si_chkops; /* checkpointing info */
......@@ -1361,6 +1362,7 @@ syncprov_checkpoint( Operation *op, SlapReply *rs, slap_overinst *on )
SlapReply rsm = { 0 };
slap_callback cb = {0};
BackendDB be;
#ifdef CHECK_CSN
Syntax *syn = slap_schema.si_ad_contextCSN->ad_type->sat_syntax;
......@@ -1387,12 +1389,26 @@ syncprov_checkpoint( Operation *op, SlapReply *rs, slap_overinst *on )
be = *on->on_info->oi_origdb;
opm.o_bd = &be;
}
opm.o_req_dn = opm.o_bd->be_suffix[0];
opm.o_req_ndn = opm.o_bd->be_nsuffix[0];
opm.o_req_dn = si->si_contextdn;
opm.o_req_ndn = si->si_contextdn;
opm.o_bd->bd_info = on->on_info->oi_orig;
opm.o_managedsait = SLAP_CONTROL_NONCRITICAL;
opm.o_no_schema_check = 1;
opm.o_bd->be_modify( &opm, &rsm );
if ( rsm.sr_err == LDAP_NO_SUCH_OBJECT &&
SLAP_SYNC_SUBENTRY( opm.o_bd )) {
const char *text;
char txtbuf[SLAP_TEXT_BUFLEN];
size_t textlen = sizeof txtbuf;
Entry *e = slap_create_context_csn_entry( opm.o_bd, NULL );
slap_mods2entry( &mod, &e, 0, 1, &text, txtbuf, textlen);
opm.ora_e = e;
opm.o_bd->be_add( &opm, &rsm );
if ( e == opm.ora_e )
be_entry_release_w( &opm, opm.ora_e );
}
if ( mod.sml_next != NULL ) {
slap_mods_free( mod.sml_next, 1 );
}
......@@ -1763,7 +1779,7 @@ syncprov_op_response( Operation *op, SlapReply *rs )
* it will deadlock
*/
if ( op->o_tag != LDAP_REQ_ADD ||
!dn_match( &op->o_req_ndn, &op->o_bd->be_nsuffix[0] )) {
!dn_match( &op->o_req_ndn, &si->si_contextdn )) {
if ( si->si_chkops && si->si_numops >= si->si_chkops ) {
do_check = 1;
si->si_numops = 0;
......@@ -1837,14 +1853,14 @@ syncprov_op_compare( Operation *op, SlapReply *rs )
syncprov_info_t *si = on->on_bi.bi_private;
int rc = SLAP_CB_CONTINUE;
if ( dn_match( &op->o_req_ndn, op->o_bd->be_nsuffix ) &&
if ( dn_match( &op->o_req_ndn, &si->si_contextdn ) &&
op->oq_compare.rs_ava->aa_desc == slap_schema.si_ad_contextCSN )
{
Entry e = {0};
Attribute a = {0};
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;
e.e_attrs = &a;
a.a_desc = slap_schema.si_ad_contextCSN;
......@@ -2583,7 +2599,7 @@ syncprov_operational(
return SLAP_CB_CONTINUE;
if ( rs->sr_entry &&
dn_match( &rs->sr_entry->e_nname, op->o_bd->be_nsuffix )) {
dn_match( &rs->sr_entry->e_nname, &si->si_contextdn )) {
if ( SLAP_OPATTRS( rs->sr_attr_flags ) ||
ad_inlist( slap_schema.si_ad_contextCSN, rs->sr_attrs )) {
......@@ -2876,7 +2892,13 @@ syncprov_db_open(
op->o_dn = be->be_rootdn;
op->o_ndn = be->be_rootndn;
rc = overlay_entry_get_ov( op, be->be_nsuffix, NULL,
if ( SLAP_SYNC_SUBENTRY( be )) {
build_new_dn( &si->si_contextdn, be->be_nsuffix,
(struct berval *)&slap_ldapsync_cn_bv, NULL );
} else {
si->si_contextdn = be->be_nsuffix[0];
}
rc = overlay_entry_get_ov( op, &si->si_contextdn, NULL,
slap_schema.si_ad_contextCSN, 0, &e, on );
if ( e ) {
......
......@@ -814,10 +814,13 @@ LDAP_SLAPD_F (ContentRule *) cr_bvfind LDAP_P((
*/
LDAP_SLAPD_V( int ) slap_serverID;
LDAP_SLAPD_V( const struct berval ) slap_ldapsync_bv;
LDAP_SLAPD_V( const struct berval ) slap_ldapsync_cn_bv;
LDAP_SLAPD_F (void) slap_get_commit_csn LDAP_P((
Operation *, struct berval *maxcsn, int *foundit ));
LDAP_SLAPD_F (void) slap_rewind_commit_csn LDAP_P(( Operation * ));
LDAP_SLAPD_F (void) slap_graduate_commit_csn LDAP_P(( Operation * ));
LDAP_SLAPD_F (Entry *) slap_create_context_csn_entry LDAP_P(( Backend *, struct berval *));
LDAP_SLAPD_F (int) slap_get_csn LDAP_P(( Operation *, struct berval *, int ));
LDAP_SLAPD_F (void) slap_queue_csn LDAP_P(( Operation *, struct berval * ));
......
......@@ -266,7 +266,8 @@ slap_auxprop_lookup(
const char *user,
unsigned ulen)
{
Operation op = {0};
OperationBuffer opbuf = {0};
Operation *op = (Operation *)&opbuf;
int i, doit = 0;
Connection *conn = NULL;
lookup_info sl;
......@@ -286,22 +287,22 @@ slap_auxprop_lookup(
if ( flags & SASL_AUXPROP_AUTHZID ) {
if ( !strcmp( sl.list[i].name, slap_propnames[SLAP_SASL_PROP_AUTHZLEN] )) {
if ( sl.list[i].values && sl.list[i].values[0] )
AC_MEMCPY( &op.o_req_ndn.bv_len, sl.list[i].values[0],
sizeof( op.o_req_ndn.bv_len ) );
AC_MEMCPY( &op->o_req_ndn.bv_len, sl.list[i].values[0],
sizeof( op->o_req_ndn.bv_len ) );
} else if ( !strcmp( sl.list[i].name, slap_propnames[SLAP_SASL_PROP_AUTHZ] )) {
if ( sl.list[i].values )
op.o_req_ndn.bv_val = (char *)sl.list[i].values[0];
op->o_req_ndn.bv_val = (char *)sl.list[i].values[0];
break;
}
}
if ( !strcmp( sl.list[i].name, slap_propnames[SLAP_SASL_PROP_AUTHCLEN] )) {
if ( sl.list[i].values && sl.list[i].values[0] )
AC_MEMCPY( &op.o_req_ndn.bv_len, sl.list[i].values[0],
sizeof( op.o_req_ndn.bv_len ) );
AC_MEMCPY( &op->o_req_ndn.bv_len, sl.list[i].values[0],
sizeof( op->o_req_ndn.bv_len ) );
} else if ( !strcmp( sl.list[i].name, slap_propnames[SLAP_SASL_PROP_AUTHC] ) ) {
if ( sl.list[i].values ) {
op.o_req_ndn.bv_val = (char *)sl.list[i].values[0];
op->o_req_ndn.bv_val = (char *)sl.list[i].values[0];
if ( !(flags & SASL_AUXPROP_AUTHZID) )
break;
}
......@@ -336,30 +337,30 @@ slap_auxprop_lookup(
cb.sc_private = &sl;
op.o_bd = select_backend( &op.o_req_ndn, 1 );
op->o_bd = select_backend( &op->o_req_ndn, 1 );
if ( op.o_bd ) {
if ( op->o_bd ) {
/* For rootdn, see if we can use the rootpw */
if ( be_isroot_dn( op.o_bd, &op.o_req_ndn ) &&
!BER_BVISEMPTY( &op.o_bd->be_rootpw )) {
if ( be_isroot_dn( op->o_bd, &op->o_req_ndn ) &&
!BER_BVISEMPTY( &op->o_bd->be_rootpw )) {
struct berval cbv = BER_BVNULL;
/* If there's a recognized scheme, see if it's CLEARTEXT */
if ( lutil_passwd_scheme( op.o_bd->be_rootpw.bv_val )) {
if ( !strncasecmp( op.o_bd->be_rootpw.bv_val,
if ( lutil_passwd_scheme( op->o_bd->be_rootpw.bv_val )) {
if ( !strncasecmp( op->o_bd->be_rootpw.bv_val,
sc_cleartext.bv_val, sc_cleartext.bv_len )) {
/* If it's CLEARTEXT, skip past scheme spec */
cbv.bv_len = op.o_bd->be_rootpw.bv_len -
cbv.bv_len = op->o_bd->be_rootpw.bv_len -
sc_cleartext.bv_len;
if ( cbv.bv_len ) {
cbv.bv_val = op.o_bd->be_rootpw.bv_val +
cbv.bv_val = op->o_bd->be_rootpw.bv_val +
sc_cleartext.bv_len;
}
}
/* No scheme, use the whole value */
} else {
cbv = op.o_bd->be_rootpw;
cbv = op->o_bd->be_rootpw;
}
if ( !BER_BVISEMPTY( &cbv )) {
for( i = 0; sl.list[i].name; i++ ) {
......@@ -380,27 +381,28 @@ slap_auxprop_lookup(
}
}
if ( op.o_bd->be_search ) {
if ( op->o_bd->be_search ) {
SlapReply rs = {REP_RESULT};
op.o_hdr = conn->c_sasl_bindop->o_hdr;
op.o_tag = LDAP_REQ_SEARCH;
op.o_dn = conn->c_ndn;
op.o_ndn = conn->c_ndn;
op.o_callback = &cb;
slap_op_time( &op.o_time, &op.o_tincr );
op.o_do_not_cache = 1;
op.o_is_auth_check = 1;
op.o_req_dn = op.o_req_ndn;
op.ors_scope = LDAP_SCOPE_BASE;
op.ors_deref = LDAP_DEREF_NEVER;
op.ors_tlimit = SLAP_NO_LIMIT;
op.ors_slimit = 1;
op.ors_filter = &generic_filter;
op.ors_filterstr = generic_filterstr;
op->o_hdr = conn->c_sasl_bindop->o_hdr;
op->o_controls = opbuf.ob_controls;
op->o_tag = LDAP_REQ_SEARCH;
op->o_dn = conn->c_ndn;
op->o_ndn = conn->c_ndn;
op->o_callback = &cb;
slap_op_time( &op->o_time, &op->o_tincr );
op->o_do_not_cache = 1;
op->o_is_auth_check = 1;
op->o_req_dn = op->o_req_ndn;
op->ors_scope = LDAP_SCOPE_BASE;
op->ors_deref = LDAP_DEREF_NEVER;
op->ors_tlimit = SLAP_NO_LIMIT;
op->ors_slimit = 1;
op->ors_filter = &generic_filter;
op->ors_filterstr = generic_filterstr;
/* FIXME: we want all attributes, right? */
op.ors_attrs = NULL;
op->ors_attrs = NULL;
op.o_bd->be_search( &op, &rs );
op->o_bd->be_search( op, &rs );
}
}
}
......
......@@ -1804,6 +1804,7 @@ struct BackendDB {
#define SLAP_DBFLAG_SHADOW_MASK (SLAP_DBFLAG_SHADOW|SLAP_DBFLAG_SINGLE_SHADOW|SLAP_DBFLAG_SYNC_SHADOW|SLAP_DBFLAG_SLURP_SHADOW)
#define SLAP_DBFLAG_CLEAN 0x10000U /* was cleanly shutdown */
#define SLAP_DBFLAG_ACL_ADD 0x20000U /* check attr ACLs on adds */
#define SLAP_DBFLAG_SYNC_SUBENTRY 0x40000U /* use subentry for context */
slap_mask_t be_flags;
#define SLAP_DBFLAGS(be) ((be)->be_flags)
#define SLAP_NOLASTMOD(be) (SLAP_DBFLAGS(be) & SLAP_DBFLAG_NOLASTMOD)
......@@ -1830,6 +1831,7 @@ struct BackendDB {
#define SLAP_MULTIMASTER(be) (!SLAP_SINGLE_SHADOW(be))
#define SLAP_DBCLEAN(be) (SLAP_DBFLAGS(be) & SLAP_DBFLAG_CLEAN)
#define SLAP_DBACL_ADD(be) (SLAP_DBFLAGS(be) & SLAP_DBFLAG_ACL_ADD)
#define SLAP_SYNC_SUBENTRY(be) (SLAP_DBFLAGS(be) & SLAP_DBFLAG_SYNC_SUBENTRY)
slap_mask_t be_restrictops; /* restriction operations */
#define SLAP_RESTRICT_OP_ADD 0x0001U
......
......@@ -438,10 +438,32 @@ slapadd( int argc, char **argv )
}
if ( rc == EXIT_SUCCESS && update_ctxcsn && !dryrun && sid != SLAP_SYNC_SID_MAX + 1 ) {
ctxcsn_id = be->be_dn2id_get( be, be->be_nsuffix );
struct berval ctxdn;
if ( SLAP_SYNC_SUBENTRY( be )) {
build_new_dn( &ctxdn, &be->be_nsuffix[0],
(struct berval *)&slap_ldapsync_cn_bv, NULL );
} else {
ctxdn = be->be_nsuffix[0];
}
ctxcsn_id = be->be_dn2id_get( be, &ctxdn );
if ( ctxcsn_id == NOID ) {
fprintf( stderr, "%s: context entry is missing\n", progname );
rc = EXIT_FAILURE;
if ( SLAP_SYNC_SUBENTRY( be )) {
ctxcsn_e = slap_create_context_csn_entry( be, NULL );
for ( sid = 0; sid <= SLAP_SYNC_SID_MAX; sid++ ) {
if ( maxcsn[ sid ].bv_len ) {
attr_merge_one( ctxcsn_e, slap_schema.si_ad_contextCSN,
&maxcsn[ sid ], NULL );
}
}
ctxcsn_id = be->be_entry_put( be, ctxcsn_e, &bvtext );
if ( ctxcsn_id == NOID ) {
fprintf( stderr, "%s: couldn't create context entry\n", progname );
rc = EXIT_FAILURE;
}
} else {
fprintf( stderr, "%s: context entry is missing\n", progname );
rc = EXIT_FAILURE;
}
} else {
ctxcsn_e = be->be_entry_get( be, ctxcsn_id );
if ( ctxcsn_e != NULL ) {
......
......@@ -70,6 +70,7 @@ typedef struct syncinfo_s {
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;
......@@ -119,7 +120,7 @@ static int syncrepl_entry(
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 * );
......@@ -458,8 +459,8 @@ check_syncprov(
*/
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 );
......@@ -627,7 +628,7 @@ do_syncrep1(
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 */
......@@ -753,7 +754,6 @@ do_syncrep2(
err = LDAP_SUCCESS;
ber_len_t len;
struct berval *psub;
Modifications *modlist = NULL;
int match, m;
......@@ -775,8 +775,6 @@ do_syncrep2(
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 ) {
......@@ -873,7 +871,7 @@ do_syncrep2(
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:
......@@ -893,7 +891,7 @@ do_syncrep2(
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 );
......@@ -1013,7 +1011,7 @@ do_syncrep2(
}
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 ) {
......@@ -1174,7 +1172,7 @@ do_syncrep2(
if ( syncCookie.ctxcsn )
{
rc = syncrepl_updateCookie( si, op, psub, &syncCookie);
rc = syncrepl_updateCookie( si, op, &syncCookie);
}
}
......@@ -1330,6 +1328,12 @@ do_syncrepl(
} 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;
......@@ -2957,7 +2961,6 @@ static int
syncrepl_updateCookie(
syncinfo_t *si,
Operation *op,
struct berval *pdn,
struct sync_cookie *syncCookie )
{
Backend *be = op->o_bd;
......@@ -3048,8 +3051,8 @@ syncrepl_updateCookie(
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;
......@@ -3057,6 +3060,20 @@ syncrepl_updateCookie(
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;
......@@ -3695,6 +3712,9 @@ syncinfo_free( syncinfo_t *sie, int free_all )
if ( sie->si_logbase.bv_val ) {
ch_free( sie->si_logbase.bv_val );
}
if ( 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 ) {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment