mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-06 10:46:21 +08:00
ITS#5470 ignore presentlist on partial multimaster refreshes
This commit is contained in:
parent
f8a012cc83
commit
26c3fd67b8
@ -432,6 +432,112 @@ ldap_sync_search(
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
check_syncprov(
|
||||
Operation *op,
|
||||
syncinfo_t *si )
|
||||
{
|
||||
AttributeName at[2];
|
||||
Attribute a = {0};
|
||||
Entry e = {0};
|
||||
SlapReply rs = {0};
|
||||
int i, j, changed = 0;
|
||||
|
||||
/* Look for contextCSN from syncprov overlay. If
|
||||
* there's no overlay, this will be a no-op. That means
|
||||
* this is a pure consumer, so local changes will not be
|
||||
* allowed, and all changes will already be reflected in
|
||||
* the cookieState.
|
||||
*/
|
||||
a.a_desc = slap_schema.si_ad_contextCSN;
|
||||
e.e_attrs = &a;
|
||||
e.e_name = op->o_bd->be_suffix[0];
|
||||
e.e_nname = op->o_bd->be_nsuffix[0];
|
||||
at[0].an_name = a.a_desc->ad_cname;
|
||||
at[0].an_desc = a.a_desc;
|
||||
BER_BVZERO( &at[1].an_name );
|
||||
rs.sr_entry = &e;
|
||||
rs.sr_flags = REP_ENTRY_MODIFIABLE;
|
||||
rs.sr_attrs = at;
|
||||
op->o_req_dn = e.e_name;
|
||||
op->o_req_ndn = e.e_nname;
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &si->si_cookieState->cs_mutex );
|
||||
i = backend_operational( op, &rs );
|
||||
if ( i == LDAP_SUCCESS && a.a_nvals ) {
|
||||
int num = a.a_numvals;
|
||||
/* check for differences */
|
||||
if ( num != si->si_cookieState->cs_num ) {
|
||||
changed = 1;
|
||||
} else {
|
||||
for ( i=0; i<num; i++ ) {
|
||||
if ( ber_bvcmp( &a.a_nvals[i],
|
||||
&si->si_cookieState->cs_vals[i] )) {
|
||||
changed =1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( changed ) {
|
||||
ber_bvarray_free( si->si_cookieState->cs_vals );
|
||||
ch_free( si->si_cookieState->cs_sids );
|
||||
si->si_cookieState->cs_num = num;
|
||||
si->si_cookieState->cs_vals = a.a_nvals;
|
||||
si->si_cookieState->cs_sids = slap_parse_csn_sids( a.a_nvals,
|
||||
num, NULL );
|
||||
si->si_cookieState->cs_age++;
|
||||
} else {
|
||||
ber_bvarray_free( a.a_nvals );
|
||||
}
|
||||
ber_bvarray_free( a.a_vals );
|
||||
}
|
||||
/* See if the cookieState has changed due to anything outside
|
||||
* this particular consumer. That includes other consumers in
|
||||
* the same context, or local changes detected above.
|
||||
*/
|
||||
if ( si->si_cookieState->cs_num > 0 && si->si_cookieAge !=
|
||||
si->si_cookieState->cs_age ) {
|
||||
if ( !si->si_syncCookie.numcsns ) {
|
||||
ber_bvarray_free( si->si_syncCookie.ctxcsn );
|
||||
ber_bvarray_dup_x( &si->si_syncCookie.ctxcsn,
|
||||
si->si_cookieState->cs_vals, NULL );
|
||||
changed = 1;
|
||||
} else {
|
||||
for (i=0; !BER_BVISNULL( &si->si_syncCookie.ctxcsn[i] ); i++) {
|
||||
/* bogus, just dup everything */
|
||||
if ( si->si_syncCookie.sids[i] == -1 ) {
|
||||
ber_bvarray_free( si->si_syncCookie.ctxcsn );
|
||||
ber_bvarray_dup_x( &si->si_syncCookie.ctxcsn,
|
||||
si->si_cookieState->cs_vals, NULL );
|
||||
changed = 1;
|
||||
break;
|
||||
}
|
||||
for (j=0; j<si->si_cookieState->cs_num; j++) {
|
||||
if ( si->si_syncCookie.sids[i] !=
|
||||
si->si_cookieState->cs_sids[j] )
|
||||
continue;
|
||||
if ( bvmatch( &si->si_syncCookie.ctxcsn[i],
|
||||
&si->si_cookieState->cs_vals[j] ))
|
||||
break;
|
||||
ber_bvreplace( &si->si_syncCookie.ctxcsn[i],
|
||||
&si->si_cookieState->cs_vals[j] );
|
||||
changed = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( changed ) {
|
||||
si->si_cookieAge = si->si_cookieState->cs_age;
|
||||
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 );
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_mutex );
|
||||
return changed;
|
||||
}
|
||||
|
||||
static int
|
||||
do_syncrep1(
|
||||
Operation *op,
|
||||
@ -538,104 +644,8 @@ do_syncrep1(
|
||||
si->si_syncCookie.ctxcsn, si->si_syncCookie.rid,
|
||||
si->si_syncCookie.sid );
|
||||
} else {
|
||||
AttributeName at[2];
|
||||
Attribute a = {0};
|
||||
Entry e = {0};
|
||||
SlapReply rs = {0};
|
||||
int i, j, changed = 0;
|
||||
|
||||
/* Look for contextCSN from syncprov overlay. If
|
||||
* there's no overlay, this will be a no-op. That means
|
||||
* this is a pure consumer, so local changes will not be
|
||||
* allowed, and all changes will already be reflected in
|
||||
* the cookieState.
|
||||
*/
|
||||
a.a_desc = slap_schema.si_ad_contextCSN;
|
||||
e.e_attrs = &a;
|
||||
e.e_name = op->o_bd->be_suffix[0];
|
||||
e.e_nname = op->o_bd->be_nsuffix[0];
|
||||
at[0].an_name = a.a_desc->ad_cname;
|
||||
at[0].an_desc = a.a_desc;
|
||||
BER_BVZERO( &at[1].an_name );
|
||||
rs.sr_entry = &e;
|
||||
rs.sr_flags = REP_ENTRY_MODIFIABLE;
|
||||
rs.sr_attrs = at;
|
||||
op->o_req_dn = e.e_name;
|
||||
op->o_req_ndn = e.e_nname;
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &si->si_cookieState->cs_mutex );
|
||||
rc = backend_operational( op, &rs );
|
||||
if ( rc == LDAP_SUCCESS && a.a_nvals ) {
|
||||
int num = a.a_numvals;
|
||||
/* check for differences */
|
||||
if ( num != si->si_cookieState->cs_num ) {
|
||||
changed = 1;
|
||||
} else {
|
||||
for ( i=0; i<num; i++ ) {
|
||||
if ( ber_bvcmp( &a.a_nvals[i],
|
||||
&si->si_cookieState->cs_vals[i] )) {
|
||||
changed =1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( changed ) {
|
||||
ber_bvarray_free( si->si_cookieState->cs_vals );
|
||||
ch_free( si->si_cookieState->cs_sids );
|
||||
si->si_cookieState->cs_num = num;
|
||||
si->si_cookieState->cs_vals = a.a_nvals;
|
||||
si->si_cookieState->cs_sids = slap_parse_csn_sids( a.a_nvals,
|
||||
num, NULL );
|
||||
si->si_cookieState->cs_age++;
|
||||
} else {
|
||||
ber_bvarray_free( a.a_nvals );
|
||||
}
|
||||
ber_bvarray_free( a.a_vals );
|
||||
}
|
||||
/* See if the cookieState has changed due to anything outside
|
||||
* this particular consumer. That includes other consumers in
|
||||
* the same context, or local changes detected above.
|
||||
*/
|
||||
if ( si->si_cookieState->cs_num > 0 && si->si_cookieAge !=
|
||||
si->si_cookieState->cs_age ) {
|
||||
if ( !si->si_syncCookie.numcsns ) {
|
||||
ber_bvarray_free( si->si_syncCookie.ctxcsn );
|
||||
ber_bvarray_dup_x( &si->si_syncCookie.ctxcsn,
|
||||
si->si_cookieState->cs_vals, NULL );
|
||||
changed = 1;
|
||||
} else {
|
||||
for (i=0; !BER_BVISNULL( &si->si_syncCookie.ctxcsn[i] ); i++) {
|
||||
/* bogus, just dup everything */
|
||||
if ( si->si_syncCookie.sids[i] == -1 ) {
|
||||
ber_bvarray_free( si->si_syncCookie.ctxcsn );
|
||||
ber_bvarray_dup_x( &si->si_syncCookie.ctxcsn,
|
||||
si->si_cookieState->cs_vals, NULL );
|
||||
changed = 1;
|
||||
break;
|
||||
}
|
||||
for (j=0; j<si->si_cookieState->cs_num; j++) {
|
||||
if ( si->si_syncCookie.sids[i] !=
|
||||
si->si_cookieState->cs_sids[j] )
|
||||
continue;
|
||||
if ( bvmatch( &si->si_syncCookie.ctxcsn[i],
|
||||
&si->si_cookieState->cs_vals[j] ))
|
||||
break;
|
||||
ber_bvreplace( &si->si_syncCookie.ctxcsn[i],
|
||||
&si->si_cookieState->cs_vals[j] );
|
||||
changed = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( changed ) {
|
||||
si->si_cookieAge = si->si_cookieState->cs_age;
|
||||
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 );
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_mutex );
|
||||
/* Look for contextCSN from syncprov overlay. */
|
||||
check_syncprov( op, si );
|
||||
}
|
||||
|
||||
si->si_refreshDone = 0;
|
||||
@ -915,6 +925,10 @@ do_syncrep2(
|
||||
}
|
||||
ber_scanf( ber, /*"{"*/ "}" );
|
||||
}
|
||||
if ( SLAP_MULTIMASTER( op->o_bd ) && check_syncprov( op, si )) {
|
||||
slap_sync_cookie_free( &syncCookie_req, 0 );
|
||||
slap_dup_sync_cookie( &syncCookie_req, &si->si_syncCookie );
|
||||
}
|
||||
if ( !syncCookie.ctxcsn ) {
|
||||
match = 1;
|
||||
} else if ( !syncCookie_req.ctxcsn ) {
|
||||
@ -1067,6 +1081,10 @@ do_syncrep2(
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( SLAP_MULTIMASTER( op->o_bd ) && check_syncprov( op, si )) {
|
||||
slap_sync_cookie_free( &syncCookie_req, 0 );
|
||||
slap_dup_sync_cookie( &syncCookie_req, &si->si_syncCookie );
|
||||
}
|
||||
if ( !syncCookie.ctxcsn ) {
|
||||
match = 1;
|
||||
} else if ( !syncCookie_req.ctxcsn ) {
|
||||
|
Loading…
Reference in New Issue
Block a user