......@@ -535,7 +535,7 @@ static ConfigTable config_back_cf_table[] = {
#endif
"( OLcfgGlAt:38 NAME 'olcPlugin' "
"EQUALITY caseIgnoreMatch "
"SYNTAX OMsDirectoryString )", NULL, NULL },
"SYNTAX OMsDirectoryString X-ORDERED 'VALUES' )", NULL, NULL },
{ "pluginlog", "filename", 2, 2, 0,
#ifdef LDAP_SLAPI
ARG_STRING, &slapi_log_file,
......@@ -1418,8 +1418,13 @@ config_generic(ConfigArgs *c) {
case CFG_SYNC_SUBENTRY:
break;
/* no-ops, requires slapd restart */
#ifdef LDAP_SLAPI
case CFG_PLUGIN:
slapi_int_unregister_plugins(c->be, c->valx);
break;
#endif
/* no-op, requires slapd restart */
case CFG_MODLOAD:
snprintf(c->log, sizeof( c->log ), "change requires slapd restart");
break;
......@@ -2409,7 +2414,7 @@ sortval_reject:
#ifdef LDAP_SLAPI
case CFG_PLUGIN:
if(slapi_int_read_config(c->be, c->fname, c->lineno, c->argc, c->argv) != LDAP_SUCCESS)
if(slapi_int_read_config(c->be, c->fname, c->lineno, c->argc, c->argv, c->valx) != LDAP_SUCCESS)
return(1);
slapi_plugins_used++;
break;
......@@ -5676,6 +5681,8 @@ done:
overlay_destroy_one( ca->be, (slap_overinst *)ca->bi );
} else if ( coptr->co_type == Cft_Schema ) {
schema_destroy_one( ca, colst, nocs, last );
} else if ( ca->cleanup ) {
ca->cleanup( ca );
}
}
done_noop:
......
......@@ -60,8 +60,8 @@ do_bind(
if ( !BER_BVISEMPTY( &op->o_conn->c_dn ) ) {
/* log authorization identity demotion */
Debug( LDAP_DEBUG_STATS,
"%s BIND anonymous mech=implicit ssf=0\n",
op->o_log_prefix );
"%s BIND anonymous mech=implicit bind_ssf=0 ssf=%d\n",
op->o_log_prefix, op->o_conn->c_ssf );
}
connection2anonymous( op->o_conn );
if ( op->o_conn->c_sasl_bind_in_progress ) {
......@@ -534,9 +534,9 @@ fe_op_bind_success( Operation *op, SlapReply *rs )
/* log authorization identity */
Debug( LDAP_DEBUG_STATS,
"%s BIND dn=\"%s\" mech=%s ssf=0\n",
"%s BIND dn=\"%s\" mech=%s bind_ssf=0 ssf=%d\n",
op->o_log_prefix,
op->o_conn->c_dn.bv_val, op->orb_mech.bv_val );
op->o_conn->c_dn.bv_val, op->orb_mech.bv_val, op->o_conn->c_ssf );
Debug( LDAP_DEBUG_TRACE,
"do_bind: v%d bind: \"%s\" to \"%s\"\n",
......
......@@ -1872,14 +1872,14 @@ static int connection_bind_cb( Operation *op, SlapReply *rs )
/* log authorization identity */
Debug( LDAP_DEBUG_STATS,
"%s BIND dn=\"%s\" mech=%s sasl_ssf=%d ssf=%d\n",
"%s BIND dn=\"%s\" mech=%s bind_ssf=%d ssf=%d\n",
op->o_log_prefix,
BER_BVISNULL( &op->o_conn->c_dn ) ? "<empty>" : op->o_conn->c_dn.bv_val,
op->o_conn->c_authmech.bv_val,
op->orb_ssf, op->o_conn->c_ssf );
Debug( LDAP_DEBUG_TRACE,
"do_bind: SASL/%s bind: dn=\"%s\" sasl_ssf=%d\n",
"do_bind: SASL/%s bind: dn=\"%s\" bind_ssf=%d\n",
op->o_conn->c_authmech.bv_val,
BER_BVISNULL( &op->o_conn->c_dn ) ? "<empty>" : op->o_conn->c_dn.bv_val,
op->orb_ssf );
......
......@@ -36,7 +36,8 @@ slap_compose_sync_cookie(
struct berval *cookie,
BerVarray csn,
int rid,
int sid )
int sid,
struct berval *delcsn )
{
int len, numcsn = 0;
......@@ -65,6 +66,8 @@ slap_compose_sync_cookie(
len = 0;
for ( i=0; i<numcsn; i++)
len += csn[i].bv_len + 1;
if ( delcsn && !BER_BVISEMPTY(delcsn) )
len += STRLENOF(",delcsn=") + delcsn->bv_len;
len += STRLENOF("rid=123,csn=");
if ( sid >= 0 )
......@@ -83,6 +86,10 @@ slap_compose_sync_cookie(
*ptr++ = ';';
}
ptr--;
if ( delcsn && !BER_BVISEMPTY(delcsn) ) {
ptr = lutil_strcopy( ptr, ",delcsn=" );
ptr = lutil_strncopy( ptr, delcsn->bv_val, delcsn->bv_len );
}
*ptr = '\0';
cookie->bv_len = ptr - cookie->bv_val;
}
......@@ -112,6 +119,11 @@ slap_sync_cookie_free(
BER_BVZERO( &cookie->octet_str );
}
if ( !BER_BVISNULL( &cookie->delcsn )) {
ch_free( cookie->delcsn.bv_val );
BER_BVZERO( &cookie->delcsn );
}
if ( free_cookie ) {
ch_free( cookie );
}
......@@ -273,6 +285,7 @@ slap_parse_sync_cookie(
cookie->ctxcsn = NULL;
cookie->sids = NULL;
cookie->numcsns = 0;
BER_BVZERO( &cookie->delcsn );
end = cookie->octet_str.bv_val + cookie->octet_str.bv_len;
......@@ -359,6 +372,49 @@ slap_parse_sync_cookie(
}
continue;
}
if ( !strncmp( next, "delcsn=", STRLENOF("delcsn=") )) {
struct berval stamp;
next += STRLENOF("delcsn=");
while ( next < end ) {
csn_str = next;
csn_ptr = strchr( csn_str, '#' );
if ( !csn_ptr || csn_ptr > end )
break;
/* ad will be NULL when called from main. we just
* want to parse the rid then. But we still iterate
* through the string to find the end.
*/
cval = strchr( csn_ptr, ';' );
if ( !cval )
cval = strchr(csn_ptr, ',' );
if ( cval )
stamp.bv_len = cval - csn_str;
else
stamp.bv_len = end - csn_str;
if ( ad ) {
struct berval bv;
stamp.bv_val = csn_str;
if ( ad->ad_type->sat_syntax->ssyn_validate(
ad->ad_type->sat_syntax, &stamp ) != LDAP_SUCCESS )
break;
if ( ad->ad_type->sat_equality->smr_normalize(
SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
ad->ad_type->sat_syntax,
ad->ad_type->sat_equality,
&stamp, &bv, memctx ) != LDAP_SUCCESS )
break;
cookie->delcsn = bv;
}
if ( cval ) {
next = cval + 1;
} else {
next = end;
}
break;
}
continue;
}
next++;
}
if ( cookie->numcsns ) {
......@@ -411,6 +467,7 @@ slap_init_sync_cookie_ctxcsn(
value_add_one( &cookie->ctxcsn, &ctxcsn );
cookie->numcsns = 1;
cookie->sid = -1;
BER_BVZERO( &cookie->delcsn );
return 0;
}
......@@ -455,6 +512,10 @@ slap_dup_sync_cookie(
new->sids[i] = src->sids[i];
}
if ( !BER_BVISNULL( &src->delcsn )) {
ber_dupbv( &new->delcsn, &src->delcsn );
}
if ( !BER_BVISNULL( &src->octet_str )) {
ber_dupbv( &new->octet_str, &src->octet_str );
}
......
......@@ -724,55 +724,55 @@ static int autoca_cf( ConfigArgs *c )
static ConfigTable autoca_cfg[] = {
{ "userClass", "objectclass", 2, 2, 0,
ARG_STRING|ARG_MAGIC|ACA_USRCLASS, autoca_cf,
"( OLcfgOvAt:22.1 NAME 'olcACAuserClass' "
"( OLcfgOvAt:22.1 NAME 'olcAutoCAuserClass' "
"DESC 'ObjectClass of user entries' "
"EQUALITY caseIgnoreMatch "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
{ "serverClass", "objectclass", 2, 2, 0,
ARG_STRING|ARG_MAGIC|ACA_SRVCLASS, autoca_cf,
"( OLcfgOvAt:22.2 NAME 'olcACAserverClass' "
"( OLcfgOvAt:22.2 NAME 'olcAutoCAserverClass' "
"DESC 'ObjectClass of server entries' "
"EQUALITY caseIgnoreMatch "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
{ "userKeybits", "integer", 2, 2, 0,
ARG_INT|ARG_MAGIC|ACA_USRKEYBITS, autoca_cf,
"( OLcfgOvAt:22.3 NAME 'olcACAuserKeybits' "
"( OLcfgOvAt:22.3 NAME 'olcAutoCAuserKeybits' "
"DESC 'Size of PrivateKey for user entries' "
"EQUALITY integerMatch "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
{ "serverKeybits", "integer", 2, 2, 0,
ARG_INT|ARG_MAGIC|ACA_SRVKEYBITS, autoca_cf,
"( OLcfgOvAt:22.4 NAME 'olcACAserverKeybits' "
"( OLcfgOvAt:22.4 NAME 'olcAutoCAserverKeybits' "
"DESC 'Size of PrivateKey for server entries' "
"EQUALITY integerMatch "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
{ "caKeybits", "integer", 2, 2, 0,
ARG_INT|ARG_MAGIC|ACA_CAKEYBITS, autoca_cf,
"( OLcfgOvAt:22.5 NAME 'olcACAKeybits' "
"( OLcfgOvAt:22.5 NAME 'olcAutoCAKeybits' "
"DESC 'Size of PrivateKey for CA certificate' "
"EQUALITY integerMatch "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
{ "userDays", "integer", 2, 2, 0,
ARG_INT|ARG_MAGIC|ACA_USRDAYS, autoca_cf,
"( OLcfgOvAt:22.6 NAME 'olcACAuserDays' "
"( OLcfgOvAt:22.6 NAME 'olcAutoCAuserDays' "
"DESC 'Lifetime of user certificates in days' "
"EQUALITY integerMatch "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
{ "serverDays", "integer", 2, 2, 0,
ARG_INT|ARG_MAGIC|ACA_SRVDAYS, autoca_cf,
"( OLcfgOvAt:22.7 NAME 'olcACAserverDays' "
"( OLcfgOvAt:22.7 NAME 'olcAutoCAserverDays' "
"DESC 'Lifetime of server certificates in days' "
"EQUALITY integerMatch "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
{ "caDays", "integer", 2, 2, 0,
ARG_INT|ARG_MAGIC|ACA_CADAYS, autoca_cf,
"( OLcfgOvAt:22.8 NAME 'olcACADays' "
"( OLcfgOvAt:22.8 NAME 'olcAutoCADays' "
"DESC 'Lifetime of CA certificate in days' "
"EQUALITY integerMatch "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
{ "localdn", "dn", 2, 2, 0,
ARG_DN|ARG_MAGIC|ACA_LOCALDN, autoca_cf,
"( OLcfgOvAt:22.9 NAME 'olcACAlocalDN' "
"( OLcfgOvAt:22.9 NAME 'olcAutoCAlocalDN' "
"DESC 'DN of local server cert' "
"EQUALITY distinguishedNameMatch "
"SYNTAX OMsDN SINGLE-VALUE )", NULL, NULL },
......@@ -781,13 +781,13 @@ static ConfigTable autoca_cfg[] = {
static ConfigOCs autoca_ocs[] = {
{ "( OLcfgOvOc:22.1 "
"NAME 'olcACAConfig' "
"NAME 'olcAutoCAConfig' "
"DESC 'AutoCA configuration' "
"SUP olcOverlayConfig "
"MAY ( olcACAuserClass $ olcACAserverClass $ "
"olcACAuserKeybits $ olcACAserverKeybits $ olcACAKeyBits $ "
"olcACAuserDays $ olcACAserverDays $ olcACADays $ "
"olcACAlocalDN ) )",
"MAY ( olcAutoCAuserClass $ olcAutoCAserverClass $ "
"olcAutoCAuserKeybits $ olcAutoCAserverKeybits $ olcAutoCAKeyBits $ "
"olcAutoCAuserDays $ olcAutoCAserverDays $ olcAutoCADays $ "
"olcAutoCAlocalDN ) )",
Cft_Overlay, autoca_cfg },
{ NULL, 0, NULL }
};
......
......@@ -123,7 +123,7 @@ static int dgroup_cf( ConfigArgs *c )
static ConfigTable dgroupcfg[] = {
{ "attrpair", "member-attribute> <URL-attribute", 3, 3, 0,
ARG_MAGIC, dgroup_cf,
"( OLcfgOvAt:17.1 NAME 'olcDGAttrPair' "
"( OLcfgOvAt:17.1 NAME ( 'olcDynGroupAttrPair' 'olcDGAttrPair' ) "
"EQUALITY caseIgnoreMatch "
"DESC 'Member and MemberURL attribute pair' "
"SYNTAX OMsDirectoryString )", NULL, NULL },
......@@ -132,10 +132,10 @@ static ConfigTable dgroupcfg[] = {
static ConfigOCs dgroupocs[] = {
{ "( OLcfgOvOc:17.1 "
"NAME 'olcDGConfig' "
"NAME ( 'olcDynGroupConfig' 'olcDGConfig' ) "
"DESC 'Dynamic Group configuration' "
"SUP olcOverlayConfig "
"MAY olcDGAttrPair )",
"MAY olcDynGroupAttrPair)",
Cft_Overlay, dgroupcfg },
{ NULL, 0, NULL }
};
......
......@@ -1398,7 +1398,7 @@ static ConfigDriver dl_cfgen;
static ConfigTable dlcfg[] = {
{ "dynlist-attrset", "group-oc> [uri] <URL-ad> <[mapped:]member-ad> [...]",
3, 0, 0, ARG_MAGIC|DL_ATTRSET, dl_cfgen,
"( OLcfgOvAt:8.1 NAME 'olcDlAttrSet' "
"( OLcfgOvAt:8.1 NAME ( 'olcDynListAttrSet' 'olcDlAttrSet' ) "
"DESC 'Dynamic list: <group objectClass>, <URL attributeDescription>, <member attributeDescription>' "
"EQUALITY caseIgnoreMatch "
"SYNTAX OMsDirectoryString "
......@@ -1417,10 +1417,10 @@ static ConfigTable dlcfg[] = {
static ConfigOCs dlocs[] = {
{ "( OLcfgOvOc:8.1 "
"NAME 'olcDynamicList' "
"NAME ( 'olcDynListConfig' 'olcDynamicList' ) "
"DESC 'Dynamic list configuration' "
"SUP olcOverlayConfig "
"MAY olcDLattrSet )",
"MAY olcDynListAttrSet )",
Cft_Overlay, dlcfg, NULL, NULL },
{ NULL, 0, NULL }
};
......
......@@ -1759,7 +1759,7 @@ static ConfigTable mo_cfg[] = {
static ConfigOCs mo_ocs[] = {
{ "( OLcfgOvOc:18.1 "
"NAME 'olcMemberOf' "
"NAME ( 'olcMemberOfConfig' 'olcMemberOf' ) "
"DESC 'Member-of configuration' "
"SUP olcOverlayConfig "
"MAY ( "
......
......@@ -55,6 +55,7 @@ typedef struct pp_info {
int use_lockout; /* send AccountLocked result? */
int hash_passwords; /* transparently hash cleartext pwds */
int forward_updates; /* use frontend for policy state updates */
int disable_write;
} pp_info;
/* Our per-connection info - note, it is not per-instance, it is
......@@ -415,7 +416,8 @@ static ldap_pvt_thread_mutex_t chk_syntax_mutex;
enum {
PPOLICY_DEFAULT = 1,
PPOLICY_HASH_CLEARTEXT,
PPOLICY_USE_LOCKOUT
PPOLICY_USE_LOCKOUT,
PPOLICY_DISABLE_WRITE,
};
static ConfigDriver ppolicy_cf_default;
......@@ -448,6 +450,12 @@ static ConfigTable ppolicycfg[] = {
"DESC 'Warn clients with AccountLocked' "
"EQUALITY booleanMatch "
"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
{ "ppolicy_disable_write", "on|off", 1, 2, 0,
ARG_ON_OFF|ARG_OFFSET|PPOLICY_DISABLE_WRITE,
(void *)offsetof(pp_info,disable_write),
"( OLcfgOvAt:12.5 NAME 'olcPPolicyDisableWrite' "
"DESC 'Prevent all policy overlay writes' "
"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
{ NULL, NULL, 0, 0, 0, ARG_IGNORED }
};
......@@ -1571,7 +1579,7 @@ done:
be_entry_release_r( op, e );
locked:
if ( mod ) {
if ( mod && !pi->disable_write ) {
Operation op2 = *op;
SlapReply r2 = { REP_RESULT };
slap_callback cb = { NULL, slap_null_cb, NULL, NULL };
......@@ -1610,6 +1618,8 @@ locked:
op2.o_bd->bd_info = (BackendInfo *)on->on_info;
}
rc = op2.o_bd->be_modify( &op2, &r2 );
}
if ( mod ) {
slap_mods_free( mod, 1 );
}
......@@ -1984,6 +1994,7 @@ ppolicy_modify( Operation *op, SlapReply *rs )
op->o_bd->bd_info = (BackendInfo *)on;
if ( rc != LDAP_SUCCESS ) return SLAP_CB_CONTINUE;
if ( pi->disable_write ) return SLAP_CB_CONTINUE;
/* If this is a replica, we may need to tweak some of the
* master's modifications. Otherwise, just pass it through.
......
......@@ -887,7 +887,8 @@ syncprov_sendresp( Operation *op, resinfo *ri, syncops *so, int mode )
rs.sr_flags = REP_CTRLS_MUSTBEFREED;
csns[0] = ri->ri_csn;
BER_BVZERO( &csns[1] );
slap_compose_sync_cookie( op, &cookie, csns, so->s_rid, slap_serverID ? slap_serverID : -1 );
slap_compose_sync_cookie( op, &cookie, csns, so->s_rid,
slap_serverID ? slap_serverID : -1, NULL );
#ifdef LDAP_DEBUG
if ( so->s_sid > 0 ) {
......@@ -1139,7 +1140,7 @@ syncprov_qresp( opcookie *opc, syncops *so, int mode )
syncprov_info_t *si = opc->son->on_bi.bi_private;
slap_compose_sync_cookie( NULL, &ri->ri_cookie, si->si_ctxcsn,
so->s_rid, slap_serverID ? slap_serverID : -1);
so->s_rid, slap_serverID ? slap_serverID : -1, NULL );
}
Debug( LDAP_DEBUG_SYNC, "%s syncprov_qresp: "
"set up a new syncres mode=%d csn=%s\n",
......@@ -1317,15 +1318,17 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit )
/* Don't send ops back to the originator */
if ( opc->osid > 0 && opc->osid == ss->s_sid ) {
Debug( LDAP_DEBUG_SYNC, "syncprov_matchops: skipping original sid %03x\n",
opc->osid );
Debug( LDAP_DEBUG_SYNC, "%s syncprov_matchops: "
"skipping original sid %03x\n",
ss->s_op->o_log_prefix, opc->osid );
continue;
}
/* Don't send ops back to the messenger */
if ( opc->rsid > 0 && opc->rsid == ss->s_sid ) {
Debug( LDAP_DEBUG_SYNC, "syncprov_matchops: skipping relayed sid %03x\n",
opc->rsid );
Debug( LDAP_DEBUG_SYNC, "%s syncprov_matchops: "
"skipping relayed sid %03x\n",
ss->s_op->o_log_prefix, opc->rsid );
continue;
}
......@@ -1389,8 +1392,9 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit )
ldap_pvt_thread_mutex_unlock( &ss->s_mutex );
}
Debug( LDAP_DEBUG_TRACE, "syncprov_matchops: sid %03x fscope %d rc %d\n",
ss->s_sid, fc.fscope, rc );
Debug( LDAP_DEBUG_TRACE, "%s syncprov_matchops: "
"sid %03x fscope %d rc %d\n",
ss->s_op->o_log_prefix, ss->s_sid, fc.fscope, rc );
/* check if current o_req_dn is in scope and matches filter */
if ( fc.fscope && rc == LDAP_COMPARE_TRUE ) {
......@@ -1710,21 +1714,114 @@ playlog_cb( Operation *op, SlapReply *rs )
return rs->sr_err;
}
/* enter with sl->sl_mutex locked, release before returning */
static void
syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl,
sync_control *srs, BerVarray ctxcsn, int numcsns, int *sids )
/*
* Check whether the last nmods UUIDs in the uuids list exist in the database
* and (still) match the op filter, zero out the bv_len of any that still exist
* and return the number of UUIDs we have confirmed are gone now.
*/
static int
check_uuidlist_presence(
Operation *op,
struct berval *uuids,
int len,
int nmods )
{
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
Operation fop = *op;
SlapReply frs = { REP_RESULT };
Filter mf, af;
AttributeAssertion eq = ATTRIBUTEASSERTION_INIT;
slap_callback cb = {0};
int i, mods = nmods;
fop.o_sync_mode = 0;
fop.o_callback = &cb;
fop.ors_limit = NULL;
fop.ors_tlimit = SLAP_NO_LIMIT;
fop.ors_attrs = slap_anlist_all_attributes;
fop.ors_attrsonly = 0;
fop.o_managedsait = SLAP_CONTROL_CRITICAL;
af.f_choice = LDAP_FILTER_AND;
af.f_next = NULL;
af.f_and = &mf;
mf.f_choice = LDAP_FILTER_EQUALITY;
mf.f_ava = &eq;
mf.f_av_desc = slap_schema.si_ad_entryUUID;
mf.f_next = fop.ors_filter;
fop.ors_filter = &af;
cb.sc_response = playlog_cb;
fop.o_bd->bd_info = (BackendInfo *)on->on_info;
for ( i=0; i<nmods; i++ ) {
mf.f_av_value = uuids[ len - 1 - i ];
cb.sc_private = NULL;
fop.ors_slimit = 1;
if ( BER_BVISEMPTY( &mf.f_av_value ) ) {
mods--;
continue;
}
rs_reinit( &frs, REP_RESULT );
fop.o_bd->be_search( &fop, &frs );
if ( cb.sc_private ) {
uuids[ len - 1 - i ].bv_len = 0;
mods--;
}
}
fop.o_bd->bd_info = (BackendInfo *)on;
return mods;
}
static int
syncprov_play_sessionlog( Operation *op, SlapReply *rs, sync_control *srs,
BerVarray ctxcsn, int numcsns, int *sids,
struct berval *mincsn, int minsid )
{
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
syncprov_info_t *si = (syncprov_info_t *)on->on_bi.bi_private;
sessionlog *sl = si->si_logs;
int i, j, ndel, num, nmods, mmods, do_play = 0, rc = -1;
BerVarray uuids, csns;
struct berval uuid[2] = {}, csn[2] = {};
slog_entry *se;
int i, j, ndel, num, nmods, mmods;
char cbuf[LDAP_PVT_CSNSTR_BUFSIZE];
BerVarray uuids;
struct berval delcsn[2];
TAvlnode *entry;
ldap_pvt_thread_mutex_lock( &sl->sl_mutex );
/* Are there any log entries, and is the consumer state
* present in the session log?
*/
if ( !sl->sl_num ) {
ldap_pvt_thread_mutex_unlock( &sl->sl_mutex );
return;
return rc;
}
assert( sl->sl_num > 0 );
for ( i=0; i<sl->sl_numcsns; i++ ) {
/* SID not present == new enough */
if ( minsid < sl->sl_sids[i] ) {
do_play = 1;
break;
}
/* SID present */
if ( minsid == sl->sl_sids[i] ) {
/* new enough? */
if ( ber_bvcmp( mincsn, &sl->sl_mincsn[i] ) >= 0 )
do_play = 1;
break;
}
}
/* SID not present == new enough */
if ( i == sl->sl_numcsns )
do_play = 1;
if ( !do_play ) {
ldap_pvt_thread_mutex_unlock( &sl->sl_mutex );
return rc;
}
num = sl->sl_num;
......@@ -1733,20 +1830,20 @@ syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl,
sl->sl_playing++;
ldap_pvt_thread_mutex_unlock( &sl->sl_mutex );
uuids = op->o_tmpalloc( (num+1) * sizeof( struct berval ) +
uuids = op->o_tmpalloc( (num) * sizeof( struct berval ) +
num * UUID_LEN, op->o_tmpmemctx );
uuids[0].bv_val = (char *)(uuids + num + 1);
delcsn[0].bv_len = 0;
delcsn[0].bv_val = cbuf;
BER_BVZERO(&delcsn[1]);
uuids[0].bv_val = (char *)(uuids + num);
csns = op->o_tmpalloc( (num) * sizeof( struct berval ) +
num * LDAP_PVT_CSNSTR_BUFSIZE, op->o_tmpmemctx );
csns[0].bv_val = (char *)(csns + num);
/* Make a copy of the relevant UUIDs. Put the Deletes up front
* and everything else at the end. Do this first so we can
* unlock the list mutex.
*/
Debug( LDAP_DEBUG_SYNC, "srs csn %s\n",
srs->sr_state.ctxcsn[0].bv_val );
Debug( LDAP_DEBUG_SYNC, "%s syncprov_play_sessionlog: "
"sync control csn %s\n",
op->o_log_prefix, srs->sr_state.ctxcsn[0].bv_val );
for ( se=sl->sl_head; se; se=se->se_next ) {
int k;
......@@ -1754,10 +1851,11 @@ syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl,
char uuidstr[40];
lutil_uuidstr_from_normalized( se->se_uuid.bv_val, se->se_uuid.bv_len,
uuidstr, 40 );
Debug( LDAP_DEBUG_SYNC, "%s syncprov_playlog: "
Debug( LDAP_DEBUG_SYNC, "%s syncprov_play_sessionlog: "
"log entry tag=%lu uuid=%s cookie=%s\n",
op->o_log_prefix, se->se_tag, uuidstr, se->se_csn.bv_val );
}
ndel = 1;
for ( k=0; k<srs->sr_state.numcsns; k++ ) {
if ( se->se_sid == srs->sr_state.sids[k] ) {
......@@ -1766,8 +1864,9 @@ syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl,
}
}
if ( ndel <= 0 ) {
Debug( LDAP_DEBUG_SYNC, "%s syncprov_playlog: "
"cmp %d, too old\n", op->o_log_prefix, ndel );
Debug( LDAP_DEBUG_SYNC, "%s syncprov_play_sessionlog: "
"cmp %d, csn %s too old, skipping\n",
op->o_log_prefix, ndel, se->se_csn.bv_val );
continue;
}
ndel = 0;
......@@ -1778,16 +1877,14 @@ syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl,
}
}
if ( ndel > 0 ) {
Debug( LDAP_DEBUG_SYNC, "%s syncprov_playlog: "
"cmp %d, too new\n", op->o_log_prefix, ndel );
Debug( LDAP_DEBUG_SYNC, "%s syncprov_play_sessionlog: "
"cmp %d, csn %s too new, we're finished\n",
op->o_log_prefix, ndel, se->se_csn.bv_val );
break;
}
if ( se->se_tag == LDAP_REQ_DELETE ) {
j = i;
i++;
AC_MEMCPY( cbuf, se->se_csn.bv_val, se->se_csn.bv_len );
delcsn[0].bv_len = se->se_csn.bv_len;
delcsn[0].bv_val[delcsn[0].bv_len] = '\0';
} else {
if ( se->se_tag == LDAP_REQ_ADD )
continue;
......@@ -1798,14 +1895,18 @@ syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl,
AC_MEMCPY(uuids[j].bv_val, se->se_uuid.bv_val, UUID_LEN);
uuids[j].bv_len = UUID_LEN;
csns[j].bv_val = csns[0].bv_val + (j * LDAP_PVT_CSNSTR_BUFSIZE);
AC_MEMCPY(csns[j].bv_val, se->se_csn.bv_val, se->se_csn.bv_len);
csns[j].bv_len = se->se_csn.bv_len;
if ( LogTest( LDAP_DEBUG_SYNC ) ) {
char uuidstr[40];
lutil_uuidstr_from_normalized( uuids[j].bv_val, uuids[j].bv_len,
uuidstr, 40 );
Debug( LDAP_DEBUG_SYNC, "%s syncprov_playlog: "
Debug( LDAP_DEBUG_SYNC, "%s syncprov_play_sessionlog: "
"picking a %s entry uuid=%s cookie=%s\n",
op->o_log_prefix, se->se_tag == LDAP_REQ_DELETE ? "deleted" : "modified",
uuidstr, delcsn[0].bv_len ? delcsn[0].bv_val : "(null)" );
uuidstr, csns[j].bv_len ? csns[j].bv_val : "(null)" );
}
}
ldap_pvt_thread_mutex_lock( &sl->sl_mutex );
......@@ -1841,72 +1942,57 @@ syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl,
}
}
/* Check mods now */
if ( mmods ) {
Operation fop;
int rc;
Filter mf, af;
AttributeAssertion eq = ATTRIBUTEASSERTION_INIT;
slap_callback cb = {0};
fop = *op;
fop.o_sync_mode = 0;
fop.o_callback = &cb;
fop.ors_limit = NULL;
fop.ors_tlimit = SLAP_NO_LIMIT;
fop.ors_attrs = slap_anlist_all_attributes;
fop.ors_attrsonly = 0;
fop.o_managedsait = SLAP_CONTROL_CRITICAL;
af.f_choice = LDAP_FILTER_AND;
af.f_next = NULL;
af.f_and = &mf;
mf.f_choice = LDAP_FILTER_EQUALITY;
mf.f_ava = &eq;
mf.f_av_desc = slap_schema.si_ad_entryUUID;
mf.f_next = fop.ors_filter;
fop.ors_filter = &af;
cb.sc_response = playlog_cb;
fop.o_bd->bd_info = (BackendInfo *)on->on_info;
for ( i=ndel; i<num; i++ ) {
if ( uuids[i].bv_len != 0 ) {
SlapReply frs = { REP_RESULT };
check_uuidlist_presence( op, uuids, num, nmods );
}
mf.f_av_value = uuids[i];
cb.sc_private = NULL;
fop.ors_slimit = 1;
rc = fop.o_bd->be_search( &fop, &frs );
/* ITS#8768 Send entries sorted by CSN order */
i = j = 0;
while ( i < ndel || j < nmods ) {
struct berval cookie;
int index;
/* If entry was not found, add to delete list */
if ( !cb.sc_private ) {
uuids[ndel++] = uuids[i];
}
}
/* Skip over duplicate mods */
if ( j < nmods && BER_BVISEMPTY( &uuids[ num - 1 - j ] ) ) {
j++;
continue;
}
fop.o_bd->bd_info = (BackendInfo *)on;
index = num - 1 - j;
if ( i >= ndel ) {
j++;
} else if ( j >= nmods ) {
index = i++;
/* Take the oldest by CSN order */
} else if ( ber_bvcmp( &csns[index], &csns[i] ) < 0 ) {
j++;
} else {
index = i++;
}
if ( ndel ) {
struct berval cookie;
if ( delcsn[0].bv_len ) {
slap_compose_sync_cookie( op, &cookie, delcsn, srs->sr_state.rid,
slap_serverID ? slap_serverID : -1 );
uuid[0] = uuids[index];
csn[0] = csns[index];
Debug( LDAP_DEBUG_SYNC, "%s syncprov_playlog: cookie=%s\n",
op->o_log_prefix, cookie.bv_val );
slap_compose_sync_cookie( op, &cookie, srs->sr_state.ctxcsn,
srs->sr_state.rid, slap_serverID ? slap_serverID : -1, csn );
if ( LogTest( LDAP_DEBUG_SYNC ) ) {
char uuidstr[40];
lutil_uuidstr_from_normalized( uuid[0].bv_val, uuid[0].bv_len,
uuidstr, 40 );
Debug( LDAP_DEBUG_SYNC, "%s syncprov_play_sessionlog: "
"sending a new disappearing entry uuid=%s cookie=%s\n",
op->o_log_prefix, uuidstr, cookie.bv_val );
}
uuids[ndel].bv_val = NULL;
syncprov_sendinfo( op, rs, LDAP_TAG_SYNC_ID_SET,
delcsn[0].bv_len ? &cookie : NULL, 0, uuids, 1 );
if ( delcsn[0].bv_len ) {
op->o_tmpfree( cookie.bv_val, op->o_tmpmemctx );
}
/* TODO: we might batch those that share the same CSN (think present
* phase), but would have to limit how many we send out at once */
syncprov_sendinfo( op, rs, LDAP_TAG_SYNC_ID_SET, &cookie, 0, uuid, 1 );
}
op->o_tmpfree( uuids, op->o_tmpmemctx );
op->o_tmpfree( csns, op->o_tmpmemctx );
return LDAP_SUCCESS;
}
static int
......@@ -2531,7 +2617,8 @@ syncprov_search_response( Operation *op, SlapReply *rs )
/* If we're in delta-sync mode, always send a cookie */
if ( si->si_nopres && si->si_usehint && a ) {
struct berval cookie;
slap_compose_sync_cookie( op, &cookie, a->a_nvals, srs->sr_state.rid, slap_serverID ? slap_serverID : -1 );
slap_compose_sync_cookie( op, &cookie, a->a_nvals, srs->sr_state.rid,
slap_serverID ? slap_serverID : -1, NULL );
rs->sr_err = syncprov_state_ctrl( op, rs, rs->sr_entry,
LDAP_SYNC_ADD, rs->sr_ctrls, 0, 1, &cookie );
op->o_tmpfree( cookie.bv_val, op->o_tmpmemctx );
......@@ -2545,7 +2632,8 @@ syncprov_search_response( Operation *op, SlapReply *rs )
if ( ( ss->ss_flags & SS_CHANGED ) &&
ss->ss_ctxcsn && !BER_BVISNULL( &ss->ss_ctxcsn[0] )) {
slap_compose_sync_cookie( op, &cookie, ss->ss_ctxcsn,
srs->sr_state.rid, slap_serverID ? slap_serverID : -1 );
srs->sr_state.rid,
slap_serverID ? slap_serverID : -1, NULL );
Debug( LDAP_DEBUG_SYNC, "%s syncprov_search_response: cookie=%s\n",
op->o_log_prefix, cookie.bv_val );
......@@ -2846,40 +2934,11 @@ no_change: if ( !(op->o_sync_mode & SLAP_SYNC_PERSIST) ) {
goto shortcut;
}
/* Do we have a sessionlog for this search? */
sl=si->si_logs;
if ( sl ) {
int do_play = 0;
ldap_pvt_thread_mutex_lock( &sl->sl_mutex );
/* Are there any log entries, and is the consumer state
* present in the session log?
*/
if ( sl->sl_num > 0 ) {
int i;
for ( i=0; i<sl->sl_numcsns; i++ ) {
/* SID not present == new enough */
if ( minsid < sl->sl_sids[i] ) {
do_play = 1;
break;
}
/* SID present */
if ( minsid == sl->sl_sids[i] ) {
/* new enough? */
if ( ber_bvcmp( &mincsn, &sl->sl_mincsn[i] ) >= 0 )
do_play = 1;
break;
}
}
/* SID not present == new enough */
if ( i == sl->sl_numcsns )
do_play = 1;
}
if ( do_play ) {
if ( si->si_logs ) {
do_present = 0;
/* mutex is unlocked in playlog */
syncprov_playlog( op, rs, sl, srs, ctxcsn, numcsns, sids );
} else {
ldap_pvt_thread_mutex_unlock( &sl->sl_mutex );
if ( syncprov_play_sessionlog( op, rs, srs, ctxcsn,
numcsns, sids, &mincsn, minsid ) ) {
do_present = SS_PRESENT;
}
}
/*
......
......@@ -1188,7 +1188,7 @@ LDAP_SLAPD_V (char *) slap_known_controls[];
* ldapsync.c
*/
LDAP_SLAPD_F (void) slap_compose_sync_cookie LDAP_P((
Operation *, struct berval *, BerVarray, int, int ));
Operation *, struct berval *, BerVarray, int, int, struct berval * ));
LDAP_SLAPD_F (void) slap_sync_cookie_free LDAP_P((
struct sync_cookie *, int free_cookie ));
LDAP_SLAPD_F (int) slap_parse_csn_sid LDAP_P((
......
......@@ -513,7 +513,7 @@ oc_check_required(
Debug( LDAP_DEBUG_TRACE,
"oc_check_required entry (%s), objectClass \"%s\"\n",
e->e_dn, ocname->bv_val );
e->e_dn?e->e_dn:"(null)", ocname->bv_val );
/* check for empty oc_required */
......
......@@ -1769,6 +1769,7 @@ struct sync_cookie {
int numcsns;
int rid;
struct berval octet_str;
struct berval delcsn;
int sid;
LDAP_STAILQ_ENTRY(sync_cookie) sc_next;
};
......
......@@ -129,7 +129,7 @@ done:
/*********************************************************************
* Function Name: slapi_int_register_plugin
*
* Description: insert the slapi_pblock structure to the end of the plugin
* Description: insert the slapi_pblock structure to a given position the end of the plugin
* list
*
* Input: a pointer to a plugin slapi_pblock structure to be added to
......@@ -143,21 +143,23 @@ done:
* Messages: None
*********************************************************************/
int
slapi_int_register_plugin(
slapi_int_register_plugin_index(
Backend *be,
Slapi_PBlock *pPB )
Slapi_PBlock *pPB,
int index )
{
Slapi_PBlock *pTmpPB;
Slapi_PBlock *pSavePB;
int rc = LDAP_SUCCESS;
int pos = 0, rc = LDAP_SUCCESS;
assert( be != NULL );
pTmpPB = SLAPI_BACKEND_PBLOCK( be );
if ( pTmpPB == NULL ) {
if ( pTmpPB == NULL || index == 0 ) {
SLAPI_BACKEND_PBLOCK( be ) = pPB;
} else {
while ( pTmpPB != NULL && rc == LDAP_SUCCESS ) {
while ( pTmpPB != NULL && rc == LDAP_SUCCESS &&
( index < 0 || pos++ < index ) ) {
pSavePB = pTmpPB;
rc = slapi_pblock_get( pTmpPB, SLAPI_IBM_PBLOCK, &pTmpPB );
}
......@@ -167,9 +169,21 @@ slapi_int_register_plugin(
}
}
if ( index >= 0 && rc == LDAP_SUCCESS ) {
rc = slapi_pblock_set( pPB, SLAPI_IBM_PBLOCK, (void *)pTmpPB );
}
return ( rc != LDAP_SUCCESS ) ? LDAP_OTHER : LDAP_SUCCESS;
}
int
slapi_int_register_plugin(
Backend *be,
Slapi_PBlock *pPB )
{
return slapi_int_register_plugin_index( be, pPB, -1 );
}
/*********************************************************************
* Function Name: slapi_int_get_plugins
*
......@@ -630,7 +644,8 @@ slapi_int_read_config(
const char *fname,
int lineno,
int argc,
char **argv )
char **argv,
int index )
{
int iType = -1;
int numPluginArgc = 0;
......@@ -690,7 +705,7 @@ slapi_int_read_config(
}
}
rc = slapi_int_register_plugin( be, pPlugin );
rc = slapi_int_register_plugin_index( be, pPlugin, index );
if ( rc != LDAP_SUCCESS ) {
if ( iType == SLAPI_PLUGIN_EXTENDEDOP ) {
slapi_int_unregister_extop( be, &pGExtendedOps, pPlugin );
......@@ -703,6 +718,74 @@ slapi_int_read_config(
return 0;
}
int
slapi_int_unregister_plugin(
Backend *be,
Slapi_PBlock *pPlugin,
Slapi_PBlock *pPrev
)
{
int type;
assert( pPlugin != NULL );
slapi_pblock_get( pPlugin, SLAPI_PLUGIN_TYPE, (void *)&type );
if ( type == SLAPI_PLUGIN_EXTENDEDOP ) {
slapi_int_unregister_extop( be, &pGExtendedOps, pPlugin );
}
if ( pPrev != NULL ) {
Slapi_PBlock *pNext = NULL;
slapi_pblock_get( pPlugin, SLAPI_IBM_PBLOCK, &pNext );
slapi_pblock_set( pPrev, SLAPI_IBM_PBLOCK, &pNext );
}
slapi_pblock_destroy( pPlugin );
return LDAP_SUCCESS;
}
int
slapi_int_unregister_plugins(
Backend *be,
int index
)
{
Slapi_PBlock *pTmpPB = NULL;
Slapi_PBlock *pSavePB = NULL;
int rc = LDAP_SUCCESS;
pTmpPB = SLAPI_BACKEND_PBLOCK( be );
if ( pTmpPB == NULL ) {
return ( index < 0 ) ? LDAP_SUCCESS : LDAP_OTHER;
}
if ( index < 0 ) {
/* All plugins must go */
while ( pTmpPB != NULL && rc == LDAP_SUCCESS ) {
pSavePB = pTmpPB;
rc = slapi_pblock_get( pTmpPB, SLAPI_IBM_PBLOCK, &pTmpPB );
if ( pSavePB != NULL ) {
slapi_int_unregister_plugin( be, pSavePB, NULL );
}
}
} else if ( index == 0 ) {
slapi_pblock_get( pTmpPB, SLAPI_IBM_PBLOCK, &pSavePB );
SLAPI_BACKEND_PBLOCK( be ) = pSavePB;
slapi_int_unregister_plugin( be, pTmpPB, NULL );
} else {
int pos = -1;
while ( pTmpPB != NULL && rc == LDAP_SUCCESS && ++pos < index ) {
pSavePB = pTmpPB;
rc = slapi_pblock_get( pTmpPB, SLAPI_IBM_PBLOCK, &pTmpPB );
}
if ( pos == index ) {
slapi_int_unregister_plugin( be, pTmpPB, pSavePB );
}
}
return rc;
}
void
slapi_int_plugin_unparse(
Backend *be,
......
......@@ -65,13 +65,15 @@ LDAP_SLAPI_F (int) slapi_int_pblock_get_next LDAP_P(( Slapi_PBlock **pb ));
/* plugin.c */
LDAP_SLAPI_F (int) slapi_int_register_plugin LDAP_P((Backend *be, Slapi_PBlock *pPB));
LDAP_SLAPI_F (int) slapi_int_register_plugin_index LDAP_P((Backend *be, Slapi_PBlock *pPB, int index));
LDAP_SLAPI_F (int) slapi_int_call_plugins LDAP_P((Backend *be, int funcType, Slapi_PBlock * pPB));
LDAP_SLAPI_F (int) slapi_int_get_plugins LDAP_P((Backend *be, int functype, SLAPI_FUNC **ppFuncPtrs));
LDAP_SLAPI_F (int) slapi_int_register_extop LDAP_P((Backend *pBE, ExtendedOp **opList, Slapi_PBlock *pPB));
LDAP_SLAPI_F (int) slapi_int_get_extop_plugin LDAP_P((struct berval *reqoid, SLAPI_FUNC *pFuncAddr ));
LDAP_SLAPI_F (struct berval *) slapi_int_get_supported_extop LDAP_P(( int ));
LDAP_SLAPI_F (int) slapi_int_unregister_plugins LDAP_P((Backend *be, int index));
LDAP_SLAPI_F (int) slapi_int_read_config LDAP_P((Backend *be, const char *fname, int lineno,
int argc, char **argv ));
int argc, char **argv, int index ));
LDAP_SLAPI_F (void) slapi_int_plugin_unparse LDAP_P((Backend *be, BerVarray *out ));
LDAP_SLAPI_F (int) slapi_int_initialize LDAP_P((void));
......
......@@ -295,7 +295,7 @@ int slapi_int_free_object_extensions(int objecttype, void *object)
eblock = (struct slapi_extension_block *)*peblock;
if ( eblock->extensions != NULL ) {
if ( eblock != NULL && eblock->extensions != NULL ) {
for ( i = registered_extensions.extensions[objecttype].count - 1; i >= 0; --i ) {
free_extension( eblock, objecttype, object, parent, i );
}
......
......@@ -764,7 +764,7 @@ check_syncprov(
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 );
si->si_syncCookie.sid, NULL );
ch_free( si->si_syncCookie.sids );
slap_reparse_sync_cookie( &si->si_syncCookie, op->o_tmpmemctx );
}
......@@ -927,7 +927,7 @@ do_syncrep1(
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 );
si->si_syncCookie.sid, NULL );
} else {
/* ITS#6367: recreate the cookie so it has our SID, not our peer's */
ch_free( si->si_syncCookie.octet_str.bv_val );
......@@ -937,7 +937,7 @@ do_syncrep1(
if ( BER_BVISNULL( &si->si_syncCookie.octet_str ))
slap_compose_sync_cookie( NULL, &si->si_syncCookie.octet_str,
si->si_syncCookie.ctxcsn, si->si_syncCookie.rid,
si->si_syncCookie.sid );
si->si_syncCookie.sid, NULL );
}
}
......@@ -1852,7 +1852,7 @@ reload:
if ( BER_BVISNULL( &si->si_syncCookie.octet_str ))
slap_compose_sync_cookie( NULL, &si->si_syncCookie.octet_str,
si->si_syncCookie.ctxcsn, si->si_syncCookie.rid,
si->si_syncCookie.sid );
si->si_syncCookie.sid, NULL );
rc = ldap_sync_search( si, op->o_tmpmemctx );
goto reload;
}
......@@ -4381,7 +4381,12 @@ syncrepl_del_nonpresent(
if ( !LDAP_LIST_EMPTY( &si->si_nonpresentlist ) ) {
if ( sc->ctxcsn && !BER_BVISNULL( &sc->ctxcsn[m] ) ) {
if ( !BER_BVISNULL( &sc->delcsn ) ) {
Debug( LDAP_DEBUG_SYNC, "syncrepl_del_nonpresent: %s "
"using delcsn=%s\n",
si->si_ridtxt, sc->delcsn.bv_val );
csn = sc->delcsn;
} else if ( sc->ctxcsn && !BER_BVISNULL( &sc->ctxcsn[m] ) ) {
csn = sc->ctxcsn[m];
} else {
csn = si->si_syncCookie.ctxcsn[0];
......
......@@ -39,7 +39,7 @@ if test $BACKEND = ldif ; then
fi
echo "This test tracks a case where changes are incorrectly skipped"
echo "See http://www.openldap.org/its/index.cgi/?findid=8444 for more information."
echo "See https://bugs.openldap.org/show_bug.cgi?id=8444 for more information."
MMR=4
XDIR=$TESTDIR/srv
......
......@@ -101,13 +101,13 @@ olcSyncrepl: {2}rid=102 provider=@URI4@ binddn="cn=manager,dc=example,dc=com
dn: olcOverlay={0}dynlist,olcDatabase={1}@BACKEND@,cn=config
objectClass: olcOverlayConfig
objectClass: olcDynamicList
objectClass: olcDynListConfig
olcOverlay: {0}dynlist
olcDlAttrSet: {0}groupOfURLs memberURL
olcDynListAttrSet: {0}groupOfURLs memberURL
dn: olcOverlay={1}memberof,olcDatabase={1}@BACKEND@,cn=config
objectClass: olcOverlayConfig
objectClass: olcMemberOf
objectClass: olcMemberOfConfig
olcOverlay: {1}memberof
olcMemberOfDangling: ignore
olcMemberOfRefInt: TRUE
......
......@@ -101,13 +101,13 @@ olcSyncrepl: {2}rid=102 provider=@URI4@ binddn="cn=manager,dc=example,dc=com
dn: olcOverlay={0}dynlist,olcDatabase={1}@BACKEND@,cn=config
objectClass: olcOverlayConfig
objectClass: olcDynamicList
objectClass: olcDynListConfig
olcOverlay: {0}dynlist
olcDlAttrSet: {0}groupOfURLs memberURL
olcDynListAttrSet: {0}groupOfURLs memberURL
dn: olcOverlay={1}memberof,olcDatabase={1}@BACKEND@,cn=config
objectClass: olcOverlayConfig
objectClass: olcMemberOf
objectClass: olcMemberOfConfig
olcOverlay: {1}memberof
olcMemberOfDangling: ignore
olcMemberOfRefInt: TRUE
......