mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-20 22:59:34 -05:00
ITS#8966 add changelog support to syncrepl consumer
Tested against DSEE7. The DSEE binaries must be in your path to run the test script.
This commit is contained in:
parent
7b587018ec
commit
e8c62bf8b4
8 changed files with 955 additions and 64 deletions
|
|
@ -2685,6 +2685,8 @@ ldap_parse_deref_control LDAP_P((
|
||||||
#define LDIF_DEFAULT_ADD 0x01 /* if changetype missing, assume LDAP_ADD */
|
#define LDIF_DEFAULT_ADD 0x01 /* if changetype missing, assume LDAP_ADD */
|
||||||
#define LDIF_ENTRIES_ONLY 0x02 /* ignore changetypes other than add */
|
#define LDIF_ENTRIES_ONLY 0x02 /* ignore changetypes other than add */
|
||||||
#define LDIF_NO_CONTROLS 0x04 /* ignore control specifications */
|
#define LDIF_NO_CONTROLS 0x04 /* ignore control specifications */
|
||||||
|
#define LDIF_MODS_ONLY 0x08 /* no changetypes, assume LDAP_MODIFY */
|
||||||
|
#define LDIF_NO_DN 0x10 /* dn is not present */
|
||||||
|
|
||||||
typedef struct ldifrecord {
|
typedef struct ldifrecord {
|
||||||
ber_tag_t lr_op; /* type of operation - LDAP_REQ_MODIFY, LDAP_REQ_ADD, etc. */
|
ber_tag_t lr_op; /* type of operation - LDAP_REQ_MODIFY, LDAP_REQ_ADD, etc. */
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ ldap_parse_ldif_record_x(
|
||||||
char *line, *dn;
|
char *line, *dn;
|
||||||
int rc, modop;
|
int rc, modop;
|
||||||
int expect_modop, expect_sep;
|
int expect_modop, expect_sep;
|
||||||
int ldapadd, new_entry, delete_entry, got_all;
|
int ldapadd, new_entry, delete_entry, got_all, no_dn;
|
||||||
LDAPMod **pmods;
|
LDAPMod **pmods;
|
||||||
int version;
|
int version;
|
||||||
LDAPControl **pctrls;
|
LDAPControl **pctrls;
|
||||||
|
|
@ -121,9 +121,11 @@ ldap_parse_ldif_record_x(
|
||||||
memset( lr, 0, sizeof(LDIFRecord) );
|
memset( lr, 0, sizeof(LDIFRecord) );
|
||||||
lr->lr_ctx = ctx; /* save memory context for later */
|
lr->lr_ctx = ctx; /* save memory context for later */
|
||||||
ldapadd = flags & LDIF_DEFAULT_ADD;
|
ldapadd = flags & LDIF_DEFAULT_ADD;
|
||||||
|
no_dn = flags & LDIF_NO_DN;
|
||||||
|
expect_modop = flags & LDIF_MODS_ONLY;
|
||||||
new_entry = ldapadd;
|
new_entry = ldapadd;
|
||||||
|
|
||||||
rc = got_all = delete_entry = modop = expect_modop = 0;
|
rc = got_all = delete_entry = modop = 0;
|
||||||
expect_sep = 0;
|
expect_sep = 0;
|
||||||
version = 0;
|
version = 0;
|
||||||
pmods = NULL;
|
pmods = NULL;
|
||||||
|
|
@ -162,7 +164,7 @@ ldap_parse_ldif_record_x(
|
||||||
}
|
}
|
||||||
lr->lr_freeval[i] = freev;
|
lr->lr_freeval[i] = freev;
|
||||||
|
|
||||||
if ( dn == NULL ) {
|
if ( dn == NULL && !no_dn ) {
|
||||||
if ( linenum+i == 1 && BV_CASEMATCH( lr->lr_btype+i, &BV_VERSION )) {
|
if ( linenum+i == 1 && BV_CASEMATCH( lr->lr_btype+i, &BV_VERSION )) {
|
||||||
/* lutil_atoi() introduces a dependence of libldap
|
/* lutil_atoi() introduces a dependence of libldap
|
||||||
* on liblutil; we only allow version 1 by now (ITS#6654)
|
* on liblutil; we only allow version 1 by now (ITS#6654)
|
||||||
|
|
@ -190,7 +192,7 @@ ldap_parse_ldif_record_x(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check to make sure there was a dn: line */
|
/* check to make sure there was a dn: line */
|
||||||
if ( !dn ) {
|
if ( !dn && !no_dn ) {
|
||||||
rc = 0;
|
rc = 0;
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
@ -207,6 +209,9 @@ ldap_parse_ldif_record_x(
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( no_dn ) {
|
||||||
|
i = 0;
|
||||||
|
} else {
|
||||||
i = idn+1;
|
i = idn+1;
|
||||||
/* Check for "control" tag after dn and before changetype. */
|
/* Check for "control" tag after dn and before changetype. */
|
||||||
if ( BV_CASEMATCH( lr->lr_btype+i, &BV_CONTROL )) {
|
if ( BV_CASEMATCH( lr->lr_btype+i, &BV_CONTROL )) {
|
||||||
|
|
@ -230,6 +235,7 @@ short_input:
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Check for changetype */
|
/* Check for changetype */
|
||||||
if ( BV_CASEMATCH( lr->lr_btype+i, &BV_CHANGETYPE )) {
|
if ( BV_CASEMATCH( lr->lr_btype+i, &BV_CHANGETYPE )) {
|
||||||
|
|
@ -421,6 +427,7 @@ short_input:
|
||||||
|
|
||||||
lr->lr_mops = ber_memalloc_x( lr->lr_lines+1, ctx );
|
lr->lr_mops = ber_memalloc_x( lr->lr_lines+1, ctx );
|
||||||
lr->lr_mops[lr->lr_lines] = M_SEP;
|
lr->lr_mops[lr->lr_lines] = M_SEP;
|
||||||
|
if ( i > 0 )
|
||||||
lr->lr_mops[i-1] = M_SEP;
|
lr->lr_mops[i-1] = M_SEP;
|
||||||
|
|
||||||
for ( ; i<lr->lr_lines; i++ ) {
|
for ( ; i<lr->lr_lines; i++ ) {
|
||||||
|
|
@ -510,6 +517,7 @@ short_input:
|
||||||
j = 0;
|
j = 0;
|
||||||
k = -1;
|
k = -1;
|
||||||
BER_BVZERO(&bv);
|
BER_BVZERO(&bv);
|
||||||
|
if ( idn > 0 )
|
||||||
lr->lr_mops[idn-1] = M_SEP;
|
lr->lr_mops[idn-1] = M_SEP;
|
||||||
for (i=idn; i<lr->lr_lines; i++) {
|
for (i=idn; i<lr->lr_lines; i++) {
|
||||||
if ( lr->lr_mops[i] == M_SEP )
|
if ( lr->lr_mops[i] == M_SEP )
|
||||||
|
|
|
||||||
109
servers/slapd/schema/dsee.schema
Normal file
109
servers/slapd/schema/dsee.schema
Normal file
|
|
@ -0,0 +1,109 @@
|
||||||
|
# $OpenLDAP$
|
||||||
|
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||||
|
##
|
||||||
|
## Copyright 2019 The OpenLDAP Foundation.
|
||||||
|
## All rights reserved.
|
||||||
|
##
|
||||||
|
## Redistribution and use in source and binary forms, with or without
|
||||||
|
## modification, are permitted only as authorized by the OpenLDAP
|
||||||
|
## Public License.
|
||||||
|
##
|
||||||
|
## A copy of this license is available in the file LICENSE in the
|
||||||
|
## top-level directory of the distribution or, alternatively, at
|
||||||
|
## <http://www.OpenLDAP.org/license.html>.
|
||||||
|
|
||||||
|
# This file is provided for informational purposes only.
|
||||||
|
|
||||||
|
# These definitions are from Sun DSEE 7's cn=schema subentry.
|
||||||
|
# None of the attributes had matching rules defined; we've
|
||||||
|
# inserted usable ones as needed.
|
||||||
|
|
||||||
|
# Some of these attributes are defined with NO-USER-MODIFICATION,
|
||||||
|
# but slapd won't load such definitions from user-modifiable schema
|
||||||
|
# files. So that designation has been removed, and commented accordingly.
|
||||||
|
|
||||||
|
objectidentifier NetscapeRoot 2.16.840.1.113730
|
||||||
|
objectidentifier NetscapeDS NetscapeRoot:3
|
||||||
|
objectidentifier NSDSat NetscapeDS:1
|
||||||
|
objectidentifier NSDSoc NetscapeDS:2
|
||||||
|
objectidentifier SunRoot 1.3.6.1.4.1.42
|
||||||
|
objectidentifier SunDS SunRoot:2.27
|
||||||
|
|
||||||
|
attributetype ( NSDSat:5
|
||||||
|
NAME 'changeNumber'
|
||||||
|
DESC 'Changelog attribute type'
|
||||||
|
EQUALITY integerMatch
|
||||||
|
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
|
||||||
|
X-ORIGIN 'Changelog Internet Draft' )
|
||||||
|
|
||||||
|
attributetype ( NSDSat:6
|
||||||
|
NAME 'targetDn'
|
||||||
|
DESC 'Changelog attribute type'
|
||||||
|
EQUALITY distinguishedNameMatch
|
||||||
|
SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
|
||||||
|
X-ORIGIN 'Changelog Internet Draft' )
|
||||||
|
|
||||||
|
attributetype ( NSDSat:7
|
||||||
|
NAME 'changeType'
|
||||||
|
DESC 'Changelog attribute type'
|
||||||
|
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
|
||||||
|
X-ORIGIN 'Changelog Internet Draft' )
|
||||||
|
|
||||||
|
# They claim Binary syntax but it's really octetString
|
||||||
|
attributetype ( NSDSat:8
|
||||||
|
NAME 'changes'
|
||||||
|
DESC 'Changelog attribute type'
|
||||||
|
SYNTAX 1.3.6.1.4.1.1466.115.121.1.5
|
||||||
|
X-ORIGIN 'Changelog Internet Draft' )
|
||||||
|
|
||||||
|
attributetype ( NSDSat:9
|
||||||
|
NAME 'newRdn'
|
||||||
|
DESC 'Changelog attribute type'
|
||||||
|
EQUALITY distinguishedNameMatch
|
||||||
|
SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
|
||||||
|
X-ORIGIN 'Changelog Internet Draft' )
|
||||||
|
|
||||||
|
attributetype ( NSDSat:10
|
||||||
|
NAME 'deleteOldRdn'
|
||||||
|
DESC 'Changelog attribute type'
|
||||||
|
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
|
||||||
|
X-ORIGIN 'Changelog Internet Draft' )
|
||||||
|
|
||||||
|
attributetype ( NSDSat:11
|
||||||
|
NAME 'newSuperior'
|
||||||
|
DESC 'Changelog attribute type'
|
||||||
|
EQUALITY distinguishedNameMatch
|
||||||
|
SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
|
||||||
|
X-ORIGIN 'Changelog Internet Draft' )
|
||||||
|
|
||||||
|
# should be generalizedTime, but they used directoryString instead...
|
||||||
|
attributeType ( NSDSat:77
|
||||||
|
NAME 'changeTime'
|
||||||
|
DESC 'Sun ONE defined attribute type'
|
||||||
|
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
|
||||||
|
X-ORIGIN 'Sun ONE Directory Server' )
|
||||||
|
|
||||||
|
# These are UUIDs, but (of course) hyphenated differently than ours.
|
||||||
|
# NO-USER-MODIFICATION
|
||||||
|
attributetype ( NSDSat:542
|
||||||
|
NAME 'nsUniqueId'
|
||||||
|
DESC 'Sun ONE defined attribute type'
|
||||||
|
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
|
||||||
|
SINGLE-VALUE
|
||||||
|
X-ORIGIN 'Sun ONE Directory Server' )
|
||||||
|
|
||||||
|
# NO-USER-MODIFICATION
|
||||||
|
attributeype ( SunDS:9.1.596
|
||||||
|
NAME 'targetUniqueId'
|
||||||
|
DESC 'RetroChangelog attribute type'
|
||||||
|
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
|
||||||
|
SINGLE-VALUE
|
||||||
|
X-ORIGIN 'Sun Directory Server' )
|
||||||
|
|
||||||
|
objectclass ( NSDSoc:1
|
||||||
|
NAME 'changeLogEntry'
|
||||||
|
DESC 'LDAP changelog objectclass'
|
||||||
|
SUP top STRUCTURAL
|
||||||
|
MUST ( targetDn $ changeTime $ changeNumber $ changeType )
|
||||||
|
MAY ( changes $ newRdn $ deleteOldRdn $ newSuperior )
|
||||||
|
X-ORIGIN 'Changelog Internet Draft' )
|
||||||
|
|
@ -50,6 +50,17 @@ static struct berval msad_addval = BER_BVC("range=1-1");
|
||||||
static struct berval msad_delval = BER_BVC("range=0-0");
|
static struct berval msad_delval = BER_BVC("range=0-0");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef LDAP_DEVEL
|
||||||
|
#define DO_DSEE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DO_DSEE
|
||||||
|
static AttributeDescription *sy_ad_nsUniqueId;
|
||||||
|
static AttributeDescription *sy_ad_dseeLastChange;
|
||||||
|
|
||||||
|
#define DSEE_SYNC_ADD 0x20
|
||||||
|
#endif
|
||||||
|
|
||||||
#define UUIDLEN 16
|
#define UUIDLEN 16
|
||||||
|
|
||||||
struct nonpresent_entry {
|
struct nonpresent_entry {
|
||||||
|
|
@ -144,6 +155,10 @@ typedef struct syncinfo_s {
|
||||||
#endif
|
#endif
|
||||||
#ifdef LDAP_CONTROL_X_DIRSYNC
|
#ifdef LDAP_CONTROL_X_DIRSYNC
|
||||||
struct berval si_dirSyncCookie;
|
struct berval si_dirSyncCookie;
|
||||||
|
#endif
|
||||||
|
#ifdef DO_DSEE
|
||||||
|
unsigned long si_prevchange;;
|
||||||
|
unsigned long si_lastchange;
|
||||||
#endif
|
#endif
|
||||||
ldap_pvt_thread_mutex_t si_mutex;
|
ldap_pvt_thread_mutex_t si_mutex;
|
||||||
} syncinfo_t;
|
} syncinfo_t;
|
||||||
|
|
@ -179,6 +194,10 @@ static int syncrepl_dirsync_cookie(
|
||||||
syncinfo_t *, Operation *, LDAPControl ** );
|
syncinfo_t *, Operation *, LDAPControl ** );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef DO_DSEE
|
||||||
|
static int syncrepl_dsee_update( syncinfo_t *si, Operation *op ) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* delta-mmr overlay handler */
|
/* delta-mmr overlay handler */
|
||||||
static int syncrepl_op_modify( Operation *op, SlapReply *rs );
|
static int syncrepl_op_modify( Operation *op, SlapReply *rs );
|
||||||
|
|
||||||
|
|
@ -188,6 +207,8 @@ static int nonpresent_callback( Operation *, SlapReply * );
|
||||||
|
|
||||||
static AttributeDescription *sync_descs[4];
|
static AttributeDescription *sync_descs[4];
|
||||||
|
|
||||||
|
static AttributeDescription *dsee_descs[7];
|
||||||
|
|
||||||
/* delta-mmr */
|
/* delta-mmr */
|
||||||
static AttributeDescription *ad_reqMod, *ad_reqDN;
|
static AttributeDescription *ad_reqMod, *ad_reqDN;
|
||||||
|
|
||||||
|
|
@ -199,6 +220,8 @@ typedef struct logschema {
|
||||||
struct berval ls_delRdn;
|
struct berval ls_delRdn;
|
||||||
struct berval ls_newSup;
|
struct berval ls_newSup;
|
||||||
struct berval ls_controls;
|
struct berval ls_controls;
|
||||||
|
struct berval ls_uuid;
|
||||||
|
struct berval ls_changenum;
|
||||||
} logschema;
|
} logschema;
|
||||||
|
|
||||||
static logschema changelog_sc = {
|
static logschema changelog_sc = {
|
||||||
|
|
@ -208,7 +231,9 @@ static logschema changelog_sc = {
|
||||||
BER_BVC("newRDN"),
|
BER_BVC("newRDN"),
|
||||||
BER_BVC("deleteOldRDN"),
|
BER_BVC("deleteOldRDN"),
|
||||||
BER_BVC("newSuperior"),
|
BER_BVC("newSuperior"),
|
||||||
BER_BVC("controls")
|
BER_BVNULL,
|
||||||
|
BER_BVC("targetUniqueId"),
|
||||||
|
BER_BVC("changeNumber")
|
||||||
};
|
};
|
||||||
|
|
||||||
static logschema accesslog_sc = {
|
static logschema accesslog_sc = {
|
||||||
|
|
@ -239,6 +264,10 @@ syncrepl_state2str( int state )
|
||||||
#ifdef LDAP_CONTROL_X_DIRSYNC
|
#ifdef LDAP_CONTROL_X_DIRSYNC
|
||||||
case MSAD_DIRSYNC_MODIFY:
|
case MSAD_DIRSYNC_MODIFY:
|
||||||
return "DIRSYNC_MOD";
|
return "DIRSYNC_MOD";
|
||||||
|
#endif
|
||||||
|
#ifdef DO_DSEE
|
||||||
|
case DSEE_SYNC_ADD:
|
||||||
|
return "DSEE_ADD";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -281,6 +310,20 @@ init_syncrepl(syncinfo_t *si)
|
||||||
sync_descs[3] = NULL;
|
sync_descs[3] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( si->si_syncdata == SYNCDATA_CHANGELOG ) {
|
||||||
|
/* DSEE doesn't support allopattrs */
|
||||||
|
si->si_allopattrs = 0;
|
||||||
|
if ( !dsee_descs[0] ) {
|
||||||
|
dsee_descs[0] = slap_schema.si_ad_objectClass;
|
||||||
|
dsee_descs[1] = slap_schema.si_ad_creatorsName;
|
||||||
|
dsee_descs[2] = slap_schema.si_ad_createTimestamp;
|
||||||
|
dsee_descs[3] = slap_schema.si_ad_modifiersName;
|
||||||
|
dsee_descs[4] = slap_schema.si_ad_modifyTimestamp;
|
||||||
|
dsee_descs[5] = sy_ad_nsUniqueId;
|
||||||
|
dsee_descs[6] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( si->si_allattrs && si->si_allopattrs )
|
if ( si->si_allattrs && si->si_allopattrs )
|
||||||
attrs = NULL;
|
attrs = NULL;
|
||||||
else
|
else
|
||||||
|
|
@ -349,10 +392,12 @@ init_syncrepl(syncinfo_t *si)
|
||||||
if ( si->si_allopattrs ) {
|
if ( si->si_allopattrs ) {
|
||||||
attrs[n++] = ch_strdup( sync_descs[0]->ad_cname.bv_val );
|
attrs[n++] = ch_strdup( sync_descs[0]->ad_cname.bv_val );
|
||||||
} else {
|
} else {
|
||||||
|
if ( si->si_syncdata != SYNCDATA_CHANGELOG ) {
|
||||||
for ( i = 0; sync_descs[ i ] != NULL; i++ ) {
|
for ( i = 0; sync_descs[ i ] != NULL; i++ ) {
|
||||||
attrs[ n++ ] = ch_strdup ( sync_descs[i]->ad_cname.bv_val );
|
attrs[ n++ ] = ch_strdup ( sync_descs[i]->ad_cname.bv_val );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
attrs[ n ] = NULL;
|
attrs[ n ] = NULL;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -377,6 +422,14 @@ init_syncrepl(syncinfo_t *si)
|
||||||
attrs[i] = NULL;
|
attrs[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( si->si_syncdata == SYNCDATA_CHANGELOG ) {
|
||||||
|
for ( n = 0; attrs[ n ] != NULL; n++ ) /* empty */;
|
||||||
|
attrs = ( char ** ) ch_realloc( attrs, (n + 6)*sizeof( char * ) );
|
||||||
|
for ( i = 0; dsee_descs[ i ] != NULL; i++ ) {
|
||||||
|
attrs[ n++ ] = ch_strdup ( dsee_descs[i]->ad_cname.bv_val );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
si->si_attrs = attrs;
|
si->si_attrs = attrs;
|
||||||
|
|
||||||
exattrs = anlist2attrs( si->si_exanlist );
|
exattrs = anlist2attrs( si->si_exanlist );
|
||||||
|
|
@ -427,6 +480,8 @@ init_syncrepl(syncinfo_t *si)
|
||||||
si->si_exattrs = exattrs;
|
si->si_exattrs = exattrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct berval generic_filterstr = BER_BVC("(objectclass=*)");
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ldap_sync_search(
|
ldap_sync_search(
|
||||||
syncinfo_t *si,
|
syncinfo_t *si,
|
||||||
|
|
@ -442,6 +497,7 @@ ldap_sync_search(
|
||||||
char *filter;
|
char *filter;
|
||||||
int attrsonly;
|
int attrsonly;
|
||||||
int scope;
|
int scope;
|
||||||
|
char filterbuf[sizeof("(changeNumber>=18446744073709551615)")];
|
||||||
|
|
||||||
/* setup LDAP SYNC control */
|
/* setup LDAP SYNC control */
|
||||||
ber_init2( ber, NULL, LBER_USE_DER );
|
ber_init2( ber, NULL, LBER_USE_DER );
|
||||||
|
|
@ -450,8 +506,55 @@ ldap_sync_search(
|
||||||
/* If we're using a log but we have no state, then fallback to
|
/* If we're using a log but we have no state, then fallback to
|
||||||
* normal mode for a full refresh.
|
* normal mode for a full refresh.
|
||||||
*/
|
*/
|
||||||
if ( si->si_syncdata && !si->si_syncCookie.numcsns ) {
|
if ( si->si_syncdata ) {
|
||||||
|
#ifdef DO_DSEE
|
||||||
|
if ( si->si_syncdata == SYNCDATA_CHANGELOG ) {
|
||||||
|
LDAPMessage *res, *msg;
|
||||||
|
unsigned long first = 0, last = 0;
|
||||||
|
int gotfirst = 0, gotlast = 0;
|
||||||
|
/* See if we're new enough for the remote server */
|
||||||
|
lattrs[0] = "firstchangenumber";
|
||||||
|
lattrs[1] = "lastchangenumber";
|
||||||
|
lattrs[2] = NULL;
|
||||||
|
rc = ldap_search_ext_s( si->si_ld, "", LDAP_SCOPE_BASE, generic_filterstr.bv_val, lattrs, 0,
|
||||||
|
NULL, NULL, NULL, si->si_slimit, &res );
|
||||||
|
if ( rc )
|
||||||
|
return rc;
|
||||||
|
msg = ldap_first_message( si->si_ld, res );
|
||||||
|
if ( msg && ldap_msgtype( msg ) == LDAP_RES_SEARCH_ENTRY ) {
|
||||||
|
BerElement *ber = NULL;
|
||||||
|
struct berval bv, *bvals, **bvp = &bvals;;
|
||||||
|
rc = ldap_get_dn_ber( si->si_ld, msg, &ber, &bv );
|
||||||
|
for ( rc = ldap_get_attribute_ber( si->si_ld, msg, ber, &bv, bvp );
|
||||||
|
rc == LDAP_SUCCESS;
|
||||||
|
rc = ldap_get_attribute_ber( si->si_ld, msg, ber, &bv, bvp ) ) {
|
||||||
|
if ( bv.bv_val == NULL )
|
||||||
|
break;
|
||||||
|
if ( !strcasecmp( bv.bv_val, "firstchangenumber" )) {
|
||||||
|
first = strtoul( bvals[0].bv_val, NULL, 0 );
|
||||||
|
gotfirst = 1;
|
||||||
|
} else if ( !strcasecmp( bv.bv_val, "lastchangenumber" )) {
|
||||||
|
last = strtoul( bvals[0].bv_val, NULL, 0 );
|
||||||
|
gotlast = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ldap_msgfree( res );
|
||||||
|
if ( gotfirst && gotlast ) {
|
||||||
|
if ( !si->si_lastchange || si->si_lastchange < first )
|
||||||
si->si_logstate = SYNCLOG_FALLBACK;
|
si->si_logstate = SYNCLOG_FALLBACK;
|
||||||
|
/* if we're in logging mode, it will update si_lastchange itself */
|
||||||
|
if ( si->si_logstate == SYNCLOG_FALLBACK )
|
||||||
|
si->si_lastchange = last;
|
||||||
|
} else {
|
||||||
|
/* should be an error; changelog plugin not enabled on provider */
|
||||||
|
si->si_logstate = SYNCLOG_FALLBACK;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
if ( si->si_logstate == SYNCLOG_LOGGING && !si->si_syncCookie.numcsns ) {
|
||||||
|
si->si_logstate = SYNCLOG_FALLBACK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use the log parameters if we're in log mode */
|
/* Use the log parameters if we're in log mode */
|
||||||
|
|
@ -467,16 +570,25 @@ ldap_sync_search(
|
||||||
lattrs[3] = ls->ls_newRdn.bv_val;
|
lattrs[3] = ls->ls_newRdn.bv_val;
|
||||||
lattrs[4] = ls->ls_delRdn.bv_val;
|
lattrs[4] = ls->ls_delRdn.bv_val;
|
||||||
lattrs[5] = ls->ls_newSup.bv_val;
|
lattrs[5] = ls->ls_newSup.bv_val;
|
||||||
|
if ( si->si_syncdata == SYNCDATA_ACCESSLOG ) {
|
||||||
lattrs[6] = ls->ls_controls.bv_val;
|
lattrs[6] = ls->ls_controls.bv_val;
|
||||||
lattrs[7] = slap_schema.si_ad_entryCSN->ad_cname.bv_val;
|
lattrs[7] = slap_schema.si_ad_entryCSN->ad_cname.bv_val;
|
||||||
lattrs[8] = NULL;
|
lattrs[8] = NULL;
|
||||||
|
filter = si->si_logfilterstr.bv_val;
|
||||||
|
scope = LDAP_SCOPE_SUBTREE;
|
||||||
|
} else {
|
||||||
|
lattrs[6] = ls->ls_uuid.bv_val;
|
||||||
|
lattrs[7] = ls->ls_changenum.bv_val;
|
||||||
|
lattrs[8] = NULL;
|
||||||
|
sprintf( filterbuf, "(changeNumber>=%lu)", si->si_lastchange+1 );
|
||||||
|
filter = filterbuf;
|
||||||
|
scope = LDAP_SCOPE_ONELEVEL;
|
||||||
|
}
|
||||||
|
|
||||||
rhint = 0;
|
rhint = 0;
|
||||||
base = si->si_logbase.bv_val;
|
base = si->si_logbase.bv_val;
|
||||||
filter = si->si_logfilterstr.bv_val;
|
|
||||||
attrs = lattrs;
|
attrs = lattrs;
|
||||||
attrsonly = 0;
|
attrsonly = 0;
|
||||||
scope = LDAP_SCOPE_SUBTREE;
|
|
||||||
} else {
|
} else {
|
||||||
rhint = 1;
|
rhint = 1;
|
||||||
base = si->si_base.bv_val;
|
base = si->si_base.bv_val;
|
||||||
|
|
@ -513,6 +625,11 @@ ldap_sync_search(
|
||||||
ctrls[1] = NULL;
|
ctrls[1] = NULL;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
#endif
|
||||||
|
#ifdef DO_DSEE
|
||||||
|
if ( si->si_syncdata == SYNCDATA_CHANGELOG ) {
|
||||||
|
ctrls[0] = NULL;
|
||||||
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if ( !BER_BVISNULL( &si->si_syncCookie.octet_str ) )
|
if ( !BER_BVISNULL( &si->si_syncCookie.octet_str ) )
|
||||||
|
|
@ -734,6 +851,23 @@ do_syncrep1(
|
||||||
si->si_dirSyncCookie = cookies[0];
|
si->si_dirSyncCookie = cookies[0];
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
#endif
|
||||||
|
#ifdef DO_DSEE
|
||||||
|
if ( si->si_syncdata == SYNCDATA_CHANGELOG ) {
|
||||||
|
if ( !si->si_lastchange ) {
|
||||||
|
BerVarray vals = NULL;
|
||||||
|
|
||||||
|
op->o_req_ndn = si->si_contextdn;
|
||||||
|
op->o_req_dn = op->o_req_ndn;
|
||||||
|
/* try to read last change number */
|
||||||
|
backend_attribute( op, NULL, &op->o_req_ndn,
|
||||||
|
sy_ad_dseeLastChange, &vals, ACL_READ );
|
||||||
|
if ( vals ) {
|
||||||
|
si->si_lastchange = strtoul( vals[0].bv_val, NULL, 0 );
|
||||||
|
si->si_prevchange = si->si_lastchange;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -955,6 +1089,27 @@ do_syncrep2(
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef DO_DSEE
|
||||||
|
if ( si->si_syncdata == SYNCDATA_CHANGELOG ) {
|
||||||
|
if ( si->si_logstate == SYNCLOG_LOGGING ) {
|
||||||
|
rc = syncrepl_message_to_op( si, op, msg );
|
||||||
|
if ( rc )
|
||||||
|
si->si_logstate = SYNCLOG_FALLBACK;
|
||||||
|
} else {
|
||||||
|
syncstate = DSEE_SYNC_ADD;
|
||||||
|
rc = syncrepl_message_to_entry( si, op, msg,
|
||||||
|
&modlist, &entry, syncstate, syncUUID );
|
||||||
|
if ( rc == 0 )
|
||||||
|
rc = syncrepl_entry( si, op, entry, &modlist, syncstate, syncUUID, NULL );
|
||||||
|
op->o_tmpfree( syncUUID[0].bv_val, op->o_tmpmemctx );
|
||||||
|
if ( modlist )
|
||||||
|
slap_mods_free( modlist, 1);
|
||||||
|
}
|
||||||
|
if ( rc )
|
||||||
|
goto done;
|
||||||
|
break;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
ldap_get_entry_controls( si->si_ld, msg, &rctrls );
|
ldap_get_entry_controls( si->si_ld, msg, &rctrls );
|
||||||
ldap_get_dn_ber( si->si_ld, msg, NULL, &bdn );
|
ldap_get_dn_ber( si->si_ld, msg, NULL, &bdn );
|
||||||
|
|
@ -1207,6 +1362,14 @@ do_syncrep2(
|
||||||
"do_syncrep2: %s LDAP_RES_SEARCH_RESULT (%d) %s\n",
|
"do_syncrep2: %s LDAP_RES_SEARCH_RESULT (%d) %s\n",
|
||||||
si->si_ridtxt, err, ldap_err2string( err ) );
|
si->si_ridtxt, err, ldap_err2string( err ) );
|
||||||
}
|
}
|
||||||
|
if ( si->si_syncdata == SYNCDATA_CHANGELOG && err == LDAP_SUCCESS ) {
|
||||||
|
rc = syncrepl_dsee_update( si, op );
|
||||||
|
if ( rc == LDAP_SUCCESS ) {
|
||||||
|
rc = -2; /* schedule a re-poll */
|
||||||
|
si->si_logstate = SYNCLOG_LOGGING;
|
||||||
|
}
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
if ( rctrls ) {
|
if ( rctrls ) {
|
||||||
LDAPControl **next = NULL;
|
LDAPControl **next = NULL;
|
||||||
#ifdef LDAP_CONTROL_X_DIRSYNC
|
#ifdef LDAP_CONTROL_X_DIRSYNC
|
||||||
|
|
@ -1945,13 +2108,109 @@ syncrepl_accesslog_mods(
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
syncrepl_changelog_mods(
|
syncrepl_dsee_uuid(
|
||||||
syncinfo_t *si,
|
struct berval *dseestr,
|
||||||
struct berval *vals,
|
struct berval *syncUUID,
|
||||||
struct Modifications **modres
|
void *ctx
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return -1; /* FIXME */
|
slap_mr_normalize_func *normf;
|
||||||
|
/* DSEE UUID is of form 12345678-12345678-12345678-12345678 */
|
||||||
|
if ( dseestr->bv_len != 35 )
|
||||||
|
return -1;
|
||||||
|
dseestr->bv_len++;
|
||||||
|
dseestr->bv_val[35] = '-';
|
||||||
|
normf = slap_schema.si_ad_entryUUID->ad_type->sat_equality->smr_normalize;
|
||||||
|
if ( normf( SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, NULL, NULL,
|
||||||
|
dseestr, &syncUUID[0], ctx ))
|
||||||
|
return -1;
|
||||||
|
(void)slap_uuidstr_from_normalized( &syncUUID[1], &syncUUID[0], ctx );
|
||||||
|
return LDAP_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
syncrepl_changelog_mods(
|
||||||
|
syncinfo_t *si,
|
||||||
|
ber_tag_t req,
|
||||||
|
struct berval *vals,
|
||||||
|
struct Modifications **modres,
|
||||||
|
struct berval *uuid,
|
||||||
|
void *ctx
|
||||||
|
)
|
||||||
|
{
|
||||||
|
LDIFRecord lr;
|
||||||
|
struct berval rbuf = vals[0];
|
||||||
|
int i, rc;
|
||||||
|
int lrflags = LDIF_NO_DN;
|
||||||
|
Modifications *mod = NULL, *modlist = NULL, **modtail = &modlist;
|
||||||
|
|
||||||
|
if ( req == LDAP_REQ_ADD )
|
||||||
|
lrflags |= LDIF_ENTRIES_ONLY|LDIF_DEFAULT_ADD;
|
||||||
|
else
|
||||||
|
lrflags |= LDIF_MODS_ONLY;
|
||||||
|
|
||||||
|
rc = ldap_parse_ldif_record_x( &rbuf, 0, &lr, "syncrepl", lrflags, ctx );
|
||||||
|
for (i = 0; lr.lrop_mods[i] != NULL; i++) {
|
||||||
|
AttributeDescription *ad = NULL;
|
||||||
|
const char *text;
|
||||||
|
int j;
|
||||||
|
if ( slap_str2ad( lr.lrop_mods[i]->mod_type, &ad, &text ) ) {
|
||||||
|
/* Invalid */
|
||||||
|
Debug( LDAP_DEBUG_ANY, "syncrepl_changelog_mods: %s "
|
||||||
|
"Invalid attribute %s, %s\n",
|
||||||
|
si->si_ridtxt, lr.lrop_mods[i]->mod_type, text );
|
||||||
|
slap_mods_free( modlist, 1 );
|
||||||
|
modlist = NULL;
|
||||||
|
rc = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
|
||||||
|
mod->sml_flags = 0;
|
||||||
|
mod->sml_op = lr.lrop_mods[i]->mod_op ^ LDAP_MOD_BVALUES;
|
||||||
|
mod->sml_next = NULL;
|
||||||
|
mod->sml_desc = ad;
|
||||||
|
mod->sml_type = ad->ad_cname;
|
||||||
|
mod->sml_values = NULL;
|
||||||
|
mod->sml_nvalues = NULL;
|
||||||
|
j = 0;
|
||||||
|
if ( lr.lrop_mods[i]->mod_bvalues != NULL ) {
|
||||||
|
for (; lr.lrop_mods[i]->mod_bvalues[j] != NULL; j++ ) {
|
||||||
|
struct berval bv, bv2;
|
||||||
|
bv = *(lr.lrop_mods[i]->mod_bvalues[j]);
|
||||||
|
REWRITE_VAL( si, ad, bv, bv2 );
|
||||||
|
ber_bvarray_add( &mod->sml_values, &bv2 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mod->sml_numvals = j;
|
||||||
|
|
||||||
|
*modtail = mod;
|
||||||
|
modtail = &mod->sml_next;
|
||||||
|
}
|
||||||
|
ldap_ldif_record_done( &lr );
|
||||||
|
|
||||||
|
if ( req == LDAP_REQ_ADD && !BER_BVISNULL( uuid )) {
|
||||||
|
struct berval uuids[2];
|
||||||
|
if ( !syncrepl_dsee_uuid( uuid, uuids, ctx )) {
|
||||||
|
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
|
||||||
|
mod->sml_flags = 0;
|
||||||
|
mod->sml_op = LDAP_MOD_ADD;
|
||||||
|
mod->sml_next = NULL;
|
||||||
|
mod->sml_desc = slap_schema.si_ad_entryUUID;
|
||||||
|
mod->sml_type = slap_schema.si_ad_entryUUID->ad_cname;
|
||||||
|
mod->sml_values = ch_malloc( 2 * sizeof(struct berval));
|
||||||
|
mod->sml_nvalues = NULL;
|
||||||
|
ber_dupbv( &mod->sml_values[0], &uuids[1] );
|
||||||
|
BER_BVZERO( &mod->sml_values[1] );
|
||||||
|
slap_sl_free( uuids[0].bv_val, ctx );
|
||||||
|
slap_sl_free( uuids[1].bv_val, ctx );
|
||||||
|
mod->sml_numvals = 1;
|
||||||
|
*modtail = mod;
|
||||||
|
modtail = &mod->sml_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*modres = modlist;
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct OpExtraSync {
|
typedef struct OpExtraSync {
|
||||||
|
|
@ -2411,8 +2670,10 @@ syncrepl_message_to_op(
|
||||||
struct berval rdn = BER_BVNULL, sup = BER_BVNULL,
|
struct berval rdn = BER_BVNULL, sup = BER_BVNULL,
|
||||||
prdn = BER_BVNULL, nrdn = BER_BVNULL,
|
prdn = BER_BVNULL, nrdn = BER_BVNULL,
|
||||||
psup = BER_BVNULL, nsup = BER_BVNULL;
|
psup = BER_BVNULL, nsup = BER_BVNULL;
|
||||||
|
struct berval dsee_uuid = BER_BVNULL, dsee_mods = BER_BVNULL;
|
||||||
int rc, deleteOldRdn = 0, freeReqDn = 0;
|
int rc, deleteOldRdn = 0, freeReqDn = 0;
|
||||||
int do_graduate = 0;
|
int do_graduate = 0;
|
||||||
|
unsigned long changenum = 0;
|
||||||
|
|
||||||
if ( ldap_msgtype( msg ) != LDAP_RES_SEARCH_ENTRY ) {
|
if ( ldap_msgtype( msg ) != LDAP_RES_SEARCH_ENTRY ) {
|
||||||
Debug( LDAP_DEBUG_ANY, "syncrepl_message_to_op: %s "
|
Debug( LDAP_DEBUG_ANY, "syncrepl_message_to_op: %s "
|
||||||
|
|
@ -2483,7 +2744,7 @@ syncrepl_message_to_op(
|
||||||
if ( si->si_syncdata == SYNCDATA_ACCESSLOG ) {
|
if ( si->si_syncdata == SYNCDATA_ACCESSLOG ) {
|
||||||
rc = syncrepl_accesslog_mods( si, bvals, &modlist );
|
rc = syncrepl_accesslog_mods( si, bvals, &modlist );
|
||||||
} else {
|
} else {
|
||||||
rc = syncrepl_changelog_mods( si, bvals, &modlist );
|
dsee_mods = bvals[0];
|
||||||
}
|
}
|
||||||
if ( rc ) goto done;
|
if ( rc ) goto done;
|
||||||
} else if ( !ber_bvstrcasecmp( &bv, &ls->ls_newRdn ) ) {
|
} else if ( !ber_bvstrcasecmp( &bv, &ls->ls_newRdn ) ) {
|
||||||
|
|
@ -2510,6 +2771,10 @@ syncrepl_message_to_op(
|
||||||
if ( !ber_bvcmp( &cbv, &rel_ctrl_bv ) )
|
if ( !ber_bvcmp( &cbv, &rel_ctrl_bv ) )
|
||||||
op->o_relax = SLAP_CONTROL_CRITICAL;
|
op->o_relax = SLAP_CONTROL_CRITICAL;
|
||||||
}
|
}
|
||||||
|
} else if ( !ber_bvstrcasecmp( &bv, &ls->ls_uuid ) ) {
|
||||||
|
dsee_uuid = bvals[0];
|
||||||
|
} else if ( !ber_bvstrcasecmp( &bv, &ls->ls_changenum ) ) {
|
||||||
|
changenum = strtoul( bvals->bv_val, NULL, 0 );
|
||||||
} else if ( !ber_bvstrcasecmp( &bv,
|
} else if ( !ber_bvstrcasecmp( &bv,
|
||||||
&slap_schema.si_ad_entryCSN->ad_cname ) )
|
&slap_schema.si_ad_entryCSN->ad_cname ) )
|
||||||
{
|
{
|
||||||
|
|
@ -2519,6 +2784,14 @@ syncrepl_message_to_op(
|
||||||
ch_free( bvals );
|
ch_free( bvals );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* don't parse mods until we've gotten the uuid */
|
||||||
|
if ( si->si_syncdata == SYNCDATA_CHANGELOG && !BER_BVISNULL( &dsee_mods )) {
|
||||||
|
rc = syncrepl_changelog_mods( si, op->o_tag,
|
||||||
|
&dsee_mods, &modlist, &dsee_uuid, op->o_tmpmemctx );
|
||||||
|
if ( rc )
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
/* If we didn't get a mod type or a target DN, bail out */
|
/* If we didn't get a mod type or a target DN, bail out */
|
||||||
if ( op->o_tag == LBER_DEFAULT || BER_BVISNULL( &dn ) ) {
|
if ( op->o_tag == LBER_DEFAULT || BER_BVISNULL( &dn ) ) {
|
||||||
rc = -1;
|
rc = -1;
|
||||||
|
|
@ -2640,6 +2913,9 @@ syncrepl_message_to_op(
|
||||||
do_graduate = 0;
|
do_graduate = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if ( si->si_syncdata == SYNCDATA_CHANGELOG && !rc )
|
||||||
|
si->si_lastchange = changenum;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if ( do_graduate )
|
if ( do_graduate )
|
||||||
slap_graduate_commit_csn( op );
|
slap_graduate_commit_csn( op );
|
||||||
|
|
@ -2721,6 +2997,7 @@ syncrepl_message_to_entry(
|
||||||
return LDAP_OTHER;
|
return LDAP_OTHER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( si->si_syncdata != SYNCDATA_CHANGELOG ) {
|
||||||
/* syncUUID[0] is normalized UUID received over the wire
|
/* syncUUID[0] is normalized UUID received over the wire
|
||||||
* syncUUID[1] is denormalized UUID, generated here
|
* syncUUID[1] is denormalized UUID, generated here
|
||||||
*/
|
*/
|
||||||
|
|
@ -2728,6 +3005,7 @@ syncrepl_message_to_entry(
|
||||||
Debug( LDAP_DEBUG_SYNC,
|
Debug( LDAP_DEBUG_SYNC,
|
||||||
"syncrepl_message_to_entry: %s DN: %s, UUID: %s\n",
|
"syncrepl_message_to_entry: %s DN: %s, UUID: %s\n",
|
||||||
si->si_ridtxt, bdn.bv_val, syncUUID[1].bv_val );
|
si->si_ridtxt, bdn.bv_val, syncUUID[1].bv_val );
|
||||||
|
}
|
||||||
|
|
||||||
if ( syncstate == LDAP_SYNC_PRESENT || syncstate == LDAP_SYNC_DELETE ) {
|
if ( syncstate == LDAP_SYNC_PRESENT || syncstate == LDAP_SYNC_DELETE ) {
|
||||||
/* NOTE: this could be done even before decoding the DN,
|
/* NOTE: this could be done even before decoding the DN,
|
||||||
|
|
@ -2782,6 +3060,16 @@ syncrepl_message_to_entry(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* map nsUniqueId to entryUUID, drop nsUniqueId */
|
||||||
|
if ( si->si_syncdata == SYNCDATA_CHANGELOG &&
|
||||||
|
!strcasecmp( tmp.sml_type.bv_val, sy_ad_nsUniqueId->ad_cname.bv_val )) {
|
||||||
|
rc = syncrepl_dsee_uuid( &tmp.sml_values[0], syncUUID, op->o_tmpmemctx );
|
||||||
|
ber_bvarray_free( tmp.sml_values );
|
||||||
|
if ( rc )
|
||||||
|
goto done;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
|
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
|
||||||
|
|
||||||
mod->sml_op = LDAP_MOD_REPLACE;
|
mod->sml_op = LDAP_MOD_REPLACE;
|
||||||
|
|
@ -2928,7 +3216,6 @@ syncrepl_dirsync_message(
|
||||||
return LDAP_OTHER;
|
return LDAP_OTHER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
while ( ber_remaining( ber ) ) {
|
while ( ber_remaining( ber ) ) {
|
||||||
AttributeDescription *ad = NULL;
|
AttributeDescription *ad = NULL;
|
||||||
|
|
||||||
|
|
@ -3228,7 +3515,22 @@ static int syncrepl_dirsync_schema()
|
||||||
}
|
}
|
||||||
#endif /* LDAP_CONTROL_X_DIRSYNC */
|
#endif /* LDAP_CONTROL_X_DIRSYNC */
|
||||||
|
|
||||||
static struct berval generic_filterstr = BER_BVC("(objectclass=*)");
|
#ifdef DO_DSEE
|
||||||
|
static int syncrepl_dsee_schema()
|
||||||
|
{
|
||||||
|
const char *text;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = slap_str2ad( "nsUniqueId", &sy_ad_nsUniqueId, &text );
|
||||||
|
if ( rc )
|
||||||
|
return rc;
|
||||||
|
return register_at( "( 1.3.6.1.4.1.4203.666.1.28 " /* OpenLDAP-specific */
|
||||||
|
"NAME 'lastChangeNumber' "
|
||||||
|
"DESC 'RetroChangelog latest change record' "
|
||||||
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 "
|
||||||
|
"SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", &sy_ad_dseeLastChange, 0);
|
||||||
|
}
|
||||||
|
#endif /* DO_DSEE */
|
||||||
|
|
||||||
/* During a refresh, we may get an LDAP_SYNC_ADD for an already existing
|
/* During a refresh, we may get an LDAP_SYNC_ADD for an already existing
|
||||||
* entry if a previous refresh was interrupted before sending us a new
|
* entry if a previous refresh was interrupted before sending us a new
|
||||||
|
|
@ -3511,6 +3813,7 @@ syncrepl_entry(
|
||||||
switch ( syncstate ) {
|
switch ( syncstate ) {
|
||||||
case LDAP_SYNC_ADD:
|
case LDAP_SYNC_ADD:
|
||||||
case LDAP_SYNC_MODIFY:
|
case LDAP_SYNC_MODIFY:
|
||||||
|
case DSEE_SYNC_ADD:
|
||||||
if ( BER_BVISNULL( &op->o_csn ))
|
if ( BER_BVISNULL( &op->o_csn ))
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -4352,6 +4655,63 @@ syncrepl_add_glue(
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
syncrepl_dsee_update(
|
||||||
|
syncinfo_t *si,
|
||||||
|
Operation *op
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Backend *be = op->o_bd;
|
||||||
|
Modifications mod;
|
||||||
|
struct berval first = BER_BVNULL;
|
||||||
|
slap_callback cb = { NULL };
|
||||||
|
SlapReply rs_modify = {REP_RESULT};
|
||||||
|
char valbuf[sizeof("18446744073709551615")];
|
||||||
|
struct berval bvals[2];
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if ( si->si_lastchange == si->si_prevchange )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
mod.sml_op = LDAP_MOD_REPLACE;
|
||||||
|
mod.sml_desc = sy_ad_dseeLastChange;
|
||||||
|
mod.sml_type = mod.sml_desc->ad_cname;
|
||||||
|
mod.sml_flags = SLAP_MOD_INTERNAL;
|
||||||
|
mod.sml_nvalues = NULL;
|
||||||
|
mod.sml_values = bvals;
|
||||||
|
mod.sml_numvals = 1;
|
||||||
|
mod.sml_next = NULL;
|
||||||
|
bvals[0].bv_val = valbuf;
|
||||||
|
bvals[0].bv_len = sprintf( valbuf, "%lu", si->si_lastchange );
|
||||||
|
BER_BVZERO( &bvals[1] );
|
||||||
|
|
||||||
|
op->o_bd = si->si_wbe;
|
||||||
|
|
||||||
|
op->o_tag = LDAP_REQ_MODIFY;
|
||||||
|
|
||||||
|
cb.sc_response = syncrepl_null_callback;
|
||||||
|
cb.sc_private = si;
|
||||||
|
|
||||||
|
op->o_callback = &cb;
|
||||||
|
op->o_req_dn = si->si_contextdn;
|
||||||
|
op->o_req_ndn = si->si_contextdn;
|
||||||
|
|
||||||
|
/* update contextCSN */
|
||||||
|
op->o_dont_replicate = 1;
|
||||||
|
|
||||||
|
/* avoid timestamp collisions */
|
||||||
|
slap_op_time( &op->o_time, &op->o_tincr );
|
||||||
|
|
||||||
|
op->orm_modlist = &mod;
|
||||||
|
op->orm_no_opattrs = 1;
|
||||||
|
rc = op->o_bd->be_modify( op, &rs_modify );
|
||||||
|
|
||||||
|
op->o_bd = be;
|
||||||
|
si->si_prevchange = si->si_lastchange;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
syncrepl_updateCookie(
|
syncrepl_updateCookie(
|
||||||
syncinfo_t *si,
|
syncinfo_t *si,
|
||||||
|
|
@ -5805,6 +6165,24 @@ parse_syncrepl_line(
|
||||||
val = c->argv[ i ] + STRLENOF( SYNCDATASTR "=" );
|
val = c->argv[ i ] + STRLENOF( SYNCDATASTR "=" );
|
||||||
si->si_syncdata = verb_to_mask( val, datamodes );
|
si->si_syncdata = verb_to_mask( val, datamodes );
|
||||||
si->si_got |= GOT_SYNCDATA;
|
si->si_got |= GOT_SYNCDATA;
|
||||||
|
if ( si->si_syncdata == SYNCDATA_CHANGELOG ) {
|
||||||
|
#ifdef DO_DSEE
|
||||||
|
if ( sy_ad_nsUniqueId == NULL ) {
|
||||||
|
int rc = syncrepl_dsee_schema();
|
||||||
|
if ( rc ) {
|
||||||
|
snprintf( c->cr_msg, sizeof( c->cr_msg ),
|
||||||
|
"changelog schema problem (%d)\n", rc );
|
||||||
|
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
snprintf( c->cr_msg, sizeof( c->cr_msg ),
|
||||||
|
"changelog not yet supported\n" );
|
||||||
|
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
} else if ( !strncasecmp( c->argv[ i ], STRICT_REFRESH,
|
} else if ( !strncasecmp( c->argv[ i ], STRICT_REFRESH,
|
||||||
STRLENOF( STRICT_REFRESH ) ) )
|
STRLENOF( STRICT_REFRESH ) ) )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
63
tests/data/slapd-dsee-slave1.conf
Normal file
63
tests/data/slapd-dsee-slave1.conf
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
# slave slapd config -- for testing of SYNC replication
|
||||||
|
# $OpenLDAP$
|
||||||
|
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||||
|
##
|
||||||
|
## Copyright 1998-2018 The OpenLDAP Foundation.
|
||||||
|
## All rights reserved.
|
||||||
|
##
|
||||||
|
## Redistribution and use in source and binary forms, with or without
|
||||||
|
## modification, are permitted only as authorized by the OpenLDAP
|
||||||
|
## Public License.
|
||||||
|
##
|
||||||
|
## A copy of this license is available in the file LICENSE in the
|
||||||
|
## top-level directory of the distribution or, alternatively, at
|
||||||
|
## <http://www.OpenLDAP.org/license.html>.
|
||||||
|
|
||||||
|
include @SCHEMADIR@/core.schema
|
||||||
|
include @SCHEMADIR@/cosine.schema
|
||||||
|
include @SCHEMADIR@/inetorgperson.schema
|
||||||
|
include @SCHEMADIR@/openldap.schema
|
||||||
|
include @SCHEMADIR@/nis.schema
|
||||||
|
include @SCHEMADIR@/dsee.schema
|
||||||
|
#
|
||||||
|
pidfile @TESTDIR@/slapd.2.pid
|
||||||
|
argsfile @TESTDIR@/slapd.2.args
|
||||||
|
|
||||||
|
#mod#modulepath ../servers/slapd/back-@BACKEND@/
|
||||||
|
#mod#moduleload back_@BACKEND@.la
|
||||||
|
#monitormod#modulepath ../servers/slapd/back-monitor/
|
||||||
|
#monitormod#moduleload back_monitor.la
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
# consumer database definitions
|
||||||
|
#######################################################################
|
||||||
|
|
||||||
|
database @BACKEND@
|
||||||
|
suffix "dc=example,dc=com"
|
||||||
|
rootdn "cn=Replica,dc=example,dc=com"
|
||||||
|
rootpw secret
|
||||||
|
#null#bind on
|
||||||
|
#~null~#directory @TESTDIR@/db.2.a
|
||||||
|
#indexdb#index objectClass eq
|
||||||
|
#indexdb#index cn,sn,uid pres,eq,sub
|
||||||
|
#indexdb#index entryUUID,entryCSN eq
|
||||||
|
#ndb#dbname db_2
|
||||||
|
#ndb#include @DATADIR@/ndb.conf
|
||||||
|
|
||||||
|
# Don't change syncrepl spec yet
|
||||||
|
syncrepl rid=1
|
||||||
|
provider=@URI1@
|
||||||
|
binddn="cn=Directory Manager"
|
||||||
|
bindmethod=simple
|
||||||
|
credentials=secret21
|
||||||
|
searchbase="dc=example,dc=com"
|
||||||
|
filter="(objectClass=*)"
|
||||||
|
schemachecking=off
|
||||||
|
scope=sub
|
||||||
|
type=refreshOnly
|
||||||
|
logbase="cn=changelog"
|
||||||
|
syncdata=changelog
|
||||||
|
retry="3 +" interval=00:00:00:03
|
||||||
|
updateref @URI1@
|
||||||
|
|
||||||
|
#monitor#database monitor
|
||||||
|
|
@ -27,7 +27,7 @@ description: MSAD doesn't like long descriptions
|
||||||
description: 5K and 3K are too big
|
description: 5K and 3K are too big
|
||||||
|
|
||||||
dn: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=example,dc=com
|
dn: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=example,dc=com
|
||||||
objectclass: inetorgperson
|
objectclass: inetOrgPerson
|
||||||
objectclass: domainRelatedObject
|
objectclass: domainRelatedObject
|
||||||
cn: Barbara Jensen
|
cn: Barbara Jensen
|
||||||
sn:: IEplbnNlbiA=
|
sn:: IEplbnNlbiA=
|
||||||
|
|
@ -47,7 +47,7 @@ telephonenumber: +1 313 555 9022
|
||||||
associatedDomain: test.openldap.org
|
associatedDomain: test.openldap.org
|
||||||
|
|
||||||
dn: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=example,dc=com
|
dn: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=example,dc=com
|
||||||
objectclass: inetorgperson
|
objectclass: inetOrgPerson
|
||||||
objectclass: domainRelatedObject
|
objectclass: domainRelatedObject
|
||||||
cn: Bjorn Jensen
|
cn: Bjorn Jensen
|
||||||
sn: Jensen
|
sn: Jensen
|
||||||
|
|
@ -66,7 +66,7 @@ telephonenumber: +1 313 555 0355
|
||||||
associatedDomain: test.openldap.org
|
associatedDomain: test.openldap.org
|
||||||
|
|
||||||
dn: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
|
dn: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||||
objectclass: inetorgperson
|
objectclass: inetOrgPerson
|
||||||
objectclass: domainRelatedObject
|
objectclass: domainRelatedObject
|
||||||
cn: Dorothy Stevens
|
cn: Dorothy Stevens
|
||||||
sn: Stevens
|
sn: Stevens
|
||||||
|
|
@ -83,7 +83,7 @@ homephone: +1 313 555 0454
|
||||||
associatedDomain: test.openldap.org
|
associatedDomain: test.openldap.org
|
||||||
|
|
||||||
dn: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com
|
dn: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||||
objectclass: inetorgperson
|
objectclass: inetOrgPerson
|
||||||
objectclass: domainRelatedObject
|
objectclass: domainRelatedObject
|
||||||
cn: James A Jones 1
|
cn: James A Jones 1
|
||||||
sn: Jones
|
sn: Jones
|
||||||
|
|
@ -101,7 +101,7 @@ telephonenumber: +1 313 555 0895
|
||||||
associatedDomain: test.openldap.org
|
associatedDomain: test.openldap.org
|
||||||
|
|
||||||
dn: cn=James A Jones 2,ou=Information Technology Division,ou=People,dc=example,dc=com
|
dn: cn=James A Jones 2,ou=Information Technology Division,ou=People,dc=example,dc=com
|
||||||
objectclass: inetorgperson
|
objectclass: inetOrgPerson
|
||||||
objectclass: domainRelatedObject
|
objectclass: domainRelatedObject
|
||||||
cn: James A Jones 2
|
cn: James A Jones 2
|
||||||
sn: Doe
|
sn: Doe
|
||||||
|
|
@ -118,7 +118,7 @@ telephonenumber: +1 313 555 7334
|
||||||
associatedDomain: test.openldap.org
|
associatedDomain: test.openldap.org
|
||||||
|
|
||||||
dn: cn=Jane Doe,ou=Alumni Association,ou=People,dc=example,dc=com
|
dn: cn=Jane Doe,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||||
objectclass: inetorgperson
|
objectclass: inetOrgPerson
|
||||||
objectclass: domainRelatedObject
|
objectclass: domainRelatedObject
|
||||||
cn: Jane Doe
|
cn: Jane Doe
|
||||||
sn: Doe
|
sn: Doe
|
||||||
|
|
@ -136,7 +136,7 @@ telephonenumber: +1 313 555 4774
|
||||||
associatedDomain: test.openldap.org
|
associatedDomain: test.openldap.org
|
||||||
|
|
||||||
dn: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
|
dn: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||||
objectclass: inetorgperson
|
objectclass: inetOrgPerson
|
||||||
objectclass: domainRelatedObject
|
objectclass: domainRelatedObject
|
||||||
cn: Jennifer Smith
|
cn: Jennifer Smith
|
||||||
sn: Smith
|
sn: Smith
|
||||||
|
|
@ -153,7 +153,7 @@ telephonenumber: +1 313 555 8232
|
||||||
associatedDomain: test.openldap.org
|
associatedDomain: test.openldap.org
|
||||||
|
|
||||||
dn: cn=John Doe,ou=Information Technology Division,ou=People,dc=example,dc=com
|
dn: cn=John Doe,ou=Information Technology Division,ou=People,dc=example,dc=com
|
||||||
objectclass: inetorgperson
|
objectclass: inetOrgPerson
|
||||||
objectclass: domainRelatedObject
|
objectclass: domainRelatedObject
|
||||||
cn: John Doe
|
cn: John Doe
|
||||||
sn: Doe
|
sn: Doe
|
||||||
|
|
@ -170,7 +170,7 @@ telephonenumber: +1 313 555 9394
|
||||||
associatedDomain: test.openldap.org
|
associatedDomain: test.openldap.org
|
||||||
|
|
||||||
dn: cn=Manager,dc=example,dc=com
|
dn: cn=Manager,dc=example,dc=com
|
||||||
objectclass: inetorgperson
|
objectclass: inetOrgPerson
|
||||||
objectclass: domainRelatedObject
|
objectclass: domainRelatedObject
|
||||||
cn: Manager
|
cn: Manager
|
||||||
sn: Manager
|
sn: Manager
|
||||||
|
|
@ -179,7 +179,7 @@ userpassword:: c2VjcmV0
|
||||||
associatedDomain: test.openldap.org
|
associatedDomain: test.openldap.org
|
||||||
|
|
||||||
dn: cn=Mark Elliot,ou=Alumni Association,ou=People,dc=example,dc=com
|
dn: cn=Mark Elliot,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||||
objectclass: inetorgperson
|
objectclass: inetOrgPerson
|
||||||
objectclass: domainRelatedObject
|
objectclass: domainRelatedObject
|
||||||
cn: Mark Elliot
|
cn: Mark Elliot
|
||||||
sn: Elliot
|
sn: Elliot
|
||||||
|
|
@ -196,7 +196,7 @@ telephonenumber: +1 313 555 4177
|
||||||
associatedDomain: test.openldap.org
|
associatedDomain: test.openldap.org
|
||||||
|
|
||||||
dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
|
dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||||
objectclass: inetorgperson
|
objectclass: inetOrgPerson
|
||||||
objectclass: domainRelatedObject
|
objectclass: domainRelatedObject
|
||||||
cn: Ursula Hampster
|
cn: Ursula Hampster
|
||||||
sn: Hampster
|
sn: Hampster
|
||||||
|
|
@ -226,7 +226,7 @@ member: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=example,
|
||||||
owner: cn=Manager,dc=example,dc=com
|
owner: cn=Manager,dc=example,dc=com
|
||||||
cn: All Staff
|
cn: All Staff
|
||||||
description: Everyone in the sample data
|
description: Everyone in the sample data
|
||||||
objectclass: groupofnames
|
objectclass: groupOfNames
|
||||||
objectclass: domainRelatedObject
|
objectclass: domainRelatedObject
|
||||||
associatedDomain: test.openldap.org
|
associatedDomain: test.openldap.org
|
||||||
|
|
||||||
|
|
@ -234,7 +234,7 @@ dn: cn=ITD Staff,ou=Groups,dc=example,dc=com
|
||||||
owner: cn=Manager,dc=example,dc=com
|
owner: cn=Manager,dc=example,dc=com
|
||||||
description: All ITD Staff
|
description: All ITD Staff
|
||||||
cn: ITD Staff
|
cn: ITD Staff
|
||||||
objectclass: groupofuniquenames
|
objectclass: groupOfUniqueNames
|
||||||
objectclass: domainRelatedObject
|
objectclass: domainRelatedObject
|
||||||
uniquemember: cn=Manager,dc=example,dc=com
|
uniquemember: cn=Manager,dc=example,dc=com
|
||||||
uniquemember: cn=Bjorn Jensen,OU=Information Technology Division,ou=People,dc=example,dc=com
|
uniquemember: cn=Bjorn Jensen,OU=Information Technology Division,ou=People,dc=example,dc=com
|
||||||
|
|
@ -253,7 +253,7 @@ member: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||||
owner: cn=Manager,dc=example,dc=com
|
owner: cn=Manager,dc=example,dc=com
|
||||||
description: All Alumni Assoc Staff
|
description: All Alumni Assoc Staff
|
||||||
cn: Alumni Assoc Staff
|
cn: Alumni Assoc Staff
|
||||||
objectclass: groupofnames
|
objectclass: groupOfNames
|
||||||
objectclass: domainRelatedObject
|
objectclass: domainRelatedObject
|
||||||
associatedDomain: test.openldap.org
|
associatedDomain: test.openldap.org
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,7 @@ P1SRSLAVECONF=$DATADIR/slapd-syncrepl-slave-persist1.conf
|
||||||
P2SRSLAVECONF=$DATADIR/slapd-syncrepl-slave-persist2.conf
|
P2SRSLAVECONF=$DATADIR/slapd-syncrepl-slave-persist2.conf
|
||||||
P3SRSLAVECONF=$DATADIR/slapd-syncrepl-slave-persist3.conf
|
P3SRSLAVECONF=$DATADIR/slapd-syncrepl-slave-persist3.conf
|
||||||
DIRSYNC1CONF=$DATADIR/slapd-dirsync1.conf
|
DIRSYNC1CONF=$DATADIR/slapd-dirsync1.conf
|
||||||
|
DSEESYNC1CONF=$DATADIR/slapd-dsee-slave1.conf
|
||||||
REFSLAVECONF=$DATADIR/slapd-ref-slave.conf
|
REFSLAVECONF=$DATADIR/slapd-ref-slave.conf
|
||||||
SCHEMACONF=$DATADIR/slapd-schema.conf
|
SCHEMACONF=$DATADIR/slapd-schema.conf
|
||||||
TLSCONF=$DATADIR/slapd-tls.conf
|
TLSCONF=$DATADIR/slapd-tls.conf
|
||||||
|
|
|
||||||
330
tests/scripts/test072-dsee-sync
Executable file
330
tests/scripts/test072-dsee-sync
Executable file
|
|
@ -0,0 +1,330 @@
|
||||||
|
#! /bin/sh
|
||||||
|
# $OpenLDAP$
|
||||||
|
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||||
|
##
|
||||||
|
## Copyright 1998-2018 The OpenLDAP Foundation.
|
||||||
|
## All rights reserved.
|
||||||
|
##
|
||||||
|
## Redistribution and use in source and binary forms, with or without
|
||||||
|
## modification, are permitted only as authorized by the OpenLDAP
|
||||||
|
## Public License.
|
||||||
|
##
|
||||||
|
## A copy of this license is available in the file LICENSE in the
|
||||||
|
## top-level directory of the distribution or, alternatively, at
|
||||||
|
## <http://www.OpenLDAP.org/license.html>.
|
||||||
|
|
||||||
|
echo "running defines.sh"
|
||||||
|
. $SRCDIR/scripts/defines.sh
|
||||||
|
|
||||||
|
if test -z `which dsadm`; then
|
||||||
|
echo "DSEE dsadm not in path, test skipped"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p $TESTDIR $DBDIR2
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test replication:
|
||||||
|
# - start provider
|
||||||
|
# - start consumer
|
||||||
|
# - populate over ldap
|
||||||
|
# - perform some modifies and deleted
|
||||||
|
# - attempt to modify the consumer (referral)
|
||||||
|
# - retrieve database over ldap and compare against expected results
|
||||||
|
#
|
||||||
|
|
||||||
|
DSEEPW=secret21
|
||||||
|
DSEEDN="cn=Directory Manager"
|
||||||
|
DSEEPWF=$TESTDIR/dseepw
|
||||||
|
|
||||||
|
echo "secret21" > $DSEEPWF
|
||||||
|
|
||||||
|
echo "Setting up DSEE provider slapd on TCP/IP port $PORT1..."
|
||||||
|
dsadm create -p $PORT1 -w $DSEEPWF $DBDIR1
|
||||||
|
dsadm start $DBDIR1
|
||||||
|
dsconf create-suffix -c -p $PORT1 -w $DSEEPWF $BASEDN
|
||||||
|
dsconf set-server-prop -p $PORT1 -w $DSEEPWF moddn-enabled:on
|
||||||
|
dsconf set-server-prop -p $PORT1 -w $DSEEPWF retro-cl-enabled:on
|
||||||
|
dsadm restart $DBDIR1
|
||||||
|
KILLPIDS=`basename $DBDIR1/locks/server/*`
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
echo "Using ldapsearch to check that provider slapd is running..."
|
||||||
|
for i in 0 1 2 3 4 5; do
|
||||||
|
$LDAPSEARCH -s base -b "$BASEDN" -h $LOCALHOST -p $PORT1 \
|
||||||
|
'objectclass=*' > /dev/null 2>&1
|
||||||
|
RC=$?
|
||||||
|
if test $RC = 0 ; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
echo "Waiting 5 seconds for slapd to start..."
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
|
||||||
|
if test $RC != 0 ; then
|
||||||
|
echo "ldapsearch failed ($RC)!"
|
||||||
|
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||||
|
exit $RC
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Starting consumer slapd on TCP/IP port $PORT2..."
|
||||||
|
. $CONFFILTER $BACKEND $MONITORDB < $DSEESYNC1CONF > $CONF2
|
||||||
|
$SLAPD -f $CONF2 -h $URI2 -d $LVL $TIMING > $LOG2 2>&1 &
|
||||||
|
SLAVEPID=$!
|
||||||
|
if test $WAIT != 0 ; then
|
||||||
|
echo SLAVEPID $SLAVEPID
|
||||||
|
read foo
|
||||||
|
fi
|
||||||
|
KILLPIDS="$KILLPIDS $SLAVEPID"
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
echo "Using ldapsearch to check that consumer slapd is running..."
|
||||||
|
for i in 0 1 2 3 4 5; do
|
||||||
|
$LDAPSEARCH -s base -b "$MONITOR" -h $LOCALHOST -p $PORT2 \
|
||||||
|
'objectclass=*' > /dev/null 2>&1
|
||||||
|
RC=$?
|
||||||
|
if test $RC = 0 ; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
echo "Waiting 5 seconds for slapd to start..."
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
|
||||||
|
if test $RC != 0 ; then
|
||||||
|
echo "ldapsearch failed ($RC)!"
|
||||||
|
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||||
|
exit $RC
|
||||||
|
fi
|
||||||
|
|
||||||
|
# using LDIFDIRSYNCNOCP to avoid custom OpenLDAP schema
|
||||||
|
echo "Using ldapadd to populate the provider directory..."
|
||||||
|
$LDAPADD -D "$DSEEDN" -h $LOCALHOST -p $PORT1 -w $DSEEPW < \
|
||||||
|
$LDIFDIRSYNCNOCP > /dev/null 2>&1
|
||||||
|
RC=$?
|
||||||
|
if test $RC != 0 ; then
|
||||||
|
echo "ldapadd failed ($RC)!"
|
||||||
|
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||||
|
exit $RC
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..."
|
||||||
|
sleep $SLEEP1
|
||||||
|
|
||||||
|
echo "Using ldapmodify to modify provider directory..."
|
||||||
|
|
||||||
|
#
|
||||||
|
# Do some modifications
|
||||||
|
#
|
||||||
|
|
||||||
|
$LDAPMODIFY -v -D "$DSEEDN" -h $LOCALHOST -p $PORT1 -w $DSEEPW > \
|
||||||
|
$TESTOUT 2>&1 << EOMODS
|
||||||
|
dn: cn=James A Jones 1, ou=Alumni Association, ou=People, dc=example,dc=com
|
||||||
|
changetype: modify
|
||||||
|
add: carLicense
|
||||||
|
carLicense: Orange Juice
|
||||||
|
-
|
||||||
|
delete: sn
|
||||||
|
sn: Jones
|
||||||
|
-
|
||||||
|
add: sn
|
||||||
|
sn: Jones
|
||||||
|
|
||||||
|
dn: cn=Bjorn Jensen, ou=Information Technology Division, ou=People, dc=example,dc=com
|
||||||
|
changetype: modify
|
||||||
|
replace: carLicense
|
||||||
|
carLicense: Iced Tea
|
||||||
|
carLicense: Mad Dog 20/20
|
||||||
|
|
||||||
|
dn: cn=ITD Staff,ou=Groups,dc=example,dc=com
|
||||||
|
changetype: modify
|
||||||
|
delete: uniquemember
|
||||||
|
uniquemember: cn=James A Jones 2, ou=Information Technology Division, ou=People, dc=example,dc=com
|
||||||
|
uniquemember: cn=Bjorn Jensen, ou=Information Technology Division, ou=People, dc=example,dc=com
|
||||||
|
-
|
||||||
|
add: uniquemember
|
||||||
|
uniquemember: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||||
|
uniquemember: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||||
|
|
||||||
|
dn: cn=All Staff,ou=Groups,dc=example,dc=com
|
||||||
|
changetype: modify
|
||||||
|
delete: description
|
||||||
|
|
||||||
|
dn: cn=Gern Jensen,ou=Information Technology Division,ou=People,dc=example,dc=com
|
||||||
|
changetype: add
|
||||||
|
objectclass: inetOrgPerson
|
||||||
|
cn: Gern Jensen
|
||||||
|
sn: Jensen
|
||||||
|
uid: gjensen
|
||||||
|
title: Chief Investigator, ITD
|
||||||
|
postaladdress: ITD $ 535 W. William St $ Ann Arbor, MI 48103
|
||||||
|
seealso: cn=All Staff,ou=Groups,dc=example,dc=com
|
||||||
|
carLicense: Coffee
|
||||||
|
homepostaladdress: 844 Brown St. Apt. 4 $ Ann Arbor, MI 48104
|
||||||
|
description: Very odd
|
||||||
|
facsimiletelephonenumber: +1 313 555 7557
|
||||||
|
telephonenumber: +1 313 555 8343
|
||||||
|
mail: gjensen@mailgw.example.com
|
||||||
|
homephone: +1 313 555 8844
|
||||||
|
|
||||||
|
dn: ou=Retired,ou=People,dc=example,dc=com
|
||||||
|
changetype: add
|
||||||
|
objectclass: organizationalUnit
|
||||||
|
ou: Retired
|
||||||
|
|
||||||
|
dn: cn=Rosco P. Coltrane, ou=Information Technology Division, ou=People, dc=example,dc=com
|
||||||
|
changetype: add
|
||||||
|
objectclass: inetOrgPerson
|
||||||
|
cn: Rosco P. Coltrane
|
||||||
|
sn: Coltrane
|
||||||
|
uid: rosco
|
||||||
|
|
||||||
|
dn: cn=Rosco P. Coltrane, ou=Information Technology Division, ou=People, dc=example,dc=com
|
||||||
|
changetype: modrdn
|
||||||
|
newrdn: cn=Rosco P. Coltrane
|
||||||
|
deleteoldrdn: 1
|
||||||
|
newsuperior: ou=Retired,ou=People,dc=example,dc=com
|
||||||
|
|
||||||
|
dn: cn=James A Jones 2, ou=Information Technology Division, ou=People, dc=example,dc=com
|
||||||
|
changetype: delete
|
||||||
|
|
||||||
|
dn: ou=testdomain1,dc=example,dc=com
|
||||||
|
changetype: modrdn
|
||||||
|
newrdn: ou=itsdomain1
|
||||||
|
deleteoldrdn: 1
|
||||||
|
|
||||||
|
dn: ou=itsdomain1,dc=example,dc=com
|
||||||
|
changetype: modify
|
||||||
|
replace: description
|
||||||
|
description: Example, Inc. ITS test domain
|
||||||
|
|
||||||
|
EOMODS
|
||||||
|
|
||||||
|
RC=$?
|
||||||
|
if test $RC != 0 ; then
|
||||||
|
echo "ldapmodify failed ($RC)!"
|
||||||
|
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||||
|
exit $RC
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..."
|
||||||
|
sleep $SLEEP1
|
||||||
|
|
||||||
|
echo "Performing modrdn alone on the provider..."
|
||||||
|
$LDAPMODIFY -v -D "$DSEEDN" -h $LOCALHOST -p $PORT1 -w $DSEEPW > \
|
||||||
|
$TESTOUT 2>&1 << EOMODS
|
||||||
|
dn: ou=testdomain2,dc=example,dc=com
|
||||||
|
changetype: modrdn
|
||||||
|
newrdn: ou=itsdomain2
|
||||||
|
deleteoldrdn: 1
|
||||||
|
|
||||||
|
EOMODS
|
||||||
|
|
||||||
|
RC=$?
|
||||||
|
if test $RC != 0 ; then
|
||||||
|
echo "ldapmodify failed ($RC)!"
|
||||||
|
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||||
|
exit $RC
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..."
|
||||||
|
sleep $SLEEP1
|
||||||
|
|
||||||
|
echo "Performing modify alone on the provider..."
|
||||||
|
$LDAPMODIFY -v -D "$DSEEDN" -h $LOCALHOST -p $PORT1 -w $DSEEPW > \
|
||||||
|
$TESTOUT 2>&1 << EOMODS
|
||||||
|
dn: ou=itsdomain2,dc=example,dc=com
|
||||||
|
changetype: modify
|
||||||
|
replace: description
|
||||||
|
description: Example, Inc. itsdomain2 test domain
|
||||||
|
|
||||||
|
EOMODS
|
||||||
|
|
||||||
|
RC=$?
|
||||||
|
if test $RC != 0 ; then
|
||||||
|
echo "ldapmodify failed ($RC)!"
|
||||||
|
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||||
|
exit $RC
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..."
|
||||||
|
sleep $SLEEP1
|
||||||
|
|
||||||
|
echo "Performing larger modify on the provider..."
|
||||||
|
$LDAPMODIFY -v -D "$DSEEDN" -h $LOCALHOST -p $PORT1 -w $DSEEPW > \
|
||||||
|
$TESTOUT 2>&1 << EOMODS
|
||||||
|
dn: cn=Alumni Assoc Staff,ou=Groups,dc=example,dc=com
|
||||||
|
changetype: modify
|
||||||
|
replace: cn
|
||||||
|
cn: Alumni Assoc Staff
|
||||||
|
-
|
||||||
|
replace: description
|
||||||
|
description: blablabla
|
||||||
|
-
|
||||||
|
replace: member
|
||||||
|
member: cn=Manager,dc=example,dc=com
|
||||||
|
member: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||||
|
member: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||||
|
member: cn=Jane Doe,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||||
|
member: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||||
|
member: cn=Mark Elliot,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||||
|
member: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||||
|
|
||||||
|
EOMODS
|
||||||
|
|
||||||
|
RC=$?
|
||||||
|
if test $RC != 0 ; then
|
||||||
|
echo "ldapmodify failed ($RC)!"
|
||||||
|
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||||
|
exit $RC
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..."
|
||||||
|
sleep $SLEEP1
|
||||||
|
|
||||||
|
OPATTRS="creatorsName createTimestamp modifiersName modifyTimestamp"
|
||||||
|
|
||||||
|
echo "Using ldapsearch to read all the entries from the provider..."
|
||||||
|
$LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT1 \
|
||||||
|
-D "$DSEEDN" -w $DSEEPW \
|
||||||
|
'(objectclass=*)' '*' $OPATTRS > $MASTEROUT 2>&1
|
||||||
|
RC=$?
|
||||||
|
|
||||||
|
if test $RC != 0 ; then
|
||||||
|
echo "ldapsearch failed at provider ($RC)!"
|
||||||
|
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||||
|
exit $RC
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Using ldapsearch to read all the entries from the consumer..."
|
||||||
|
$LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \
|
||||||
|
'(objectclass=*)' '*' $OPATTRS > $SLAVEOUT 2>&1
|
||||||
|
RC=$?
|
||||||
|
|
||||||
|
if test $RC != 0 ; then
|
||||||
|
echo "ldapsearch failed at consumer ($RC)!"
|
||||||
|
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||||
|
exit $RC
|
||||||
|
fi
|
||||||
|
|
||||||
|
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||||
|
|
||||||
|
echo "Filtering provider results..."
|
||||||
|
$LDIFFILTER -s a < $MASTEROUT > $MASTERFLT
|
||||||
|
echo "Filtering consumer results..."
|
||||||
|
$LDIFFILTER -s a < $SLAVEOUT > $SLAVEFLT
|
||||||
|
|
||||||
|
echo "Comparing retrieved entries from provider and consumer..."
|
||||||
|
$CMP $MASTERFLT $SLAVEFLT > $CMPOUT
|
||||||
|
|
||||||
|
if test $? != 0 ; then
|
||||||
|
echo "test failed - provider and consumer databases differ"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ">>>>> Test succeeded"
|
||||||
|
|
||||||
|
test $KILLSERVERS != no && wait
|
||||||
|
|
||||||
|
exit 0
|
||||||
Loading…
Reference in a new issue