From 00dc402f249306ad7a66a7120ae808731185f83d Mon Sep 17 00:00:00 2001 From: Quanah Gibson-Mount Date: Thu, 18 Oct 2007 03:35:12 +0000 Subject: [PATCH] ITS#5192 ITS#5072 ITS#5168 --- CHANGES | 2 + servers/slapd/back-meta/map.c | 12 +-- servers/slapd/filter.c | 23 ++--- servers/slapd/ldapsync.c | 24 +++--- servers/slapd/overlays/rwmmap.c | 13 ++- servers/slapd/overlays/syncprov.c | 80 +++++++++++------ servers/slapd/schema_init.c | 51 ++++++++--- servers/slapd/slap.h | 7 +- servers/slapd/syncrepl.c | 137 ++++++++++++++++-------------- 9 files changed, 214 insertions(+), 135 deletions(-) diff --git a/CHANGES b/CHANGES index c5df3185d0..7728c3f1d6 100644 --- a/CHANGES +++ b/CHANGES @@ -10,6 +10,8 @@ OpenLDAP 2.4.6 Engineering Added slapd attribute value sorting (ITS#5153) Added slapd checking for long-running tasks (ITS#4188) Fixed slapd syncrepl cookie propagation (ITS#5170) + Fixed slapd certificateExactAssertion (ITS#5072) + Fixed slapd Multi-Master Replication with refreshAndPersist (ITS#5192) Fixed slapd-bdb/hdb suffix logging (ITS#5128) Fixed slapd-bdb/hdb IDL LRU handling (ITS#5121) Fixed slapd-bdb/hdb cachesize config check (ITS#5122) diff --git a/servers/slapd/back-meta/map.c b/servers/slapd/back-meta/map.c index f0985af6e7..7904cfd4c7 100644 --- a/servers/slapd/back-meta/map.c +++ b/servers/slapd/back-meta/map.c @@ -213,7 +213,6 @@ map_attr_value( int remap ) { struct berval vtmp; - char uuid[ LDAP_LUTIL_UUIDSTR_BUFSIZE ]; int freeval = 0; ldap_back_map( &dc->target->mt_rwmap.rwm_at, &ad->ad_cname, mapped_attr, remap ); @@ -260,13 +259,14 @@ map_attr_value( return -1; } - } else if ( ad->ad_type->sat_syntax == slap_schema.si_ad_entryUUID->ad_type->sat_syntax ) { - vtmp.bv_len = lutil_uuidstr_from_normalized( value->bv_val, - value->bv_len, uuid, LDAP_LUTIL_UUIDSTR_BUFSIZE ); - if ( vtmp.bv_len < 0 ) { + } else if ( ad->ad_type->sat_equality->smr_usage & SLAP_MR_MUTATION_NORMALIZER ) { + if ( ad->ad_type->sat_equality->smr_normalize( + (SLAP_MR_DENORMALIZE|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX), + NULL, NULL, value, &vtmp, NULL ) ) + { return -1; } - vtmp.bv_val = uuid; + freeval = 1; } else if ( ad == slap_schema.si_ad_objectClass || ad == slap_schema.si_ad_structuralObjectClass ) { ldap_back_map( &dc->target->mt_rwmap.rwm_oc, value, &vtmp, remap ); diff --git a/servers/slapd/filter.c b/servers/slapd/filter.c index 5b6ec115b2..8c11f81f5d 100644 --- a/servers/slapd/filter.c +++ b/servers/slapd/filter.c @@ -567,7 +567,7 @@ filter2bv_x( Operation *op, Filter *f, struct berval *fstr ) { int i; Filter *p; - struct berval tmp; + struct berval tmp, value; static struct berval ber_bvfalse = BER_BVC( "(?=false)" ), ber_bvtrue = BER_BVC( "(?=true)" ), @@ -592,13 +592,6 @@ filter2bv_x( Operation *op, Filter *f, struct berval *fstr ) case LDAP_FILTER_EQUALITY: fstr->bv_len = STRLENOF("(=)"); sign = "="; - if ( f->f_av_desc->ad_type->sat_syntax == slap_schema.si_ad_entryUUID->ad_type->sat_syntax ) { - tmp.bv_val = op->o_tmpalloc( LDAP_LUTIL_UUIDSTR_BUFSIZE, op->o_tmpmemctx ); - tmp.bv_len = lutil_uuidstr_from_normalized( f->f_av_value.bv_val, - f->f_av_value.bv_len, tmp.bv_val, LDAP_LUTIL_UUIDSTR_BUFSIZE ); - assert( tmp.bv_len > 0 ); - goto escaped; - } goto simple; case LDAP_FILTER_GE: fstr->bv_len = STRLENOF("(>=)"); @@ -613,13 +606,19 @@ filter2bv_x( Operation *op, Filter *f, struct berval *fstr ) sign = "~="; simple: - filter_escape_value_x( &f->f_av_value, &tmp, op->o_tmpmemctx ); + value = f->f_av_value; + if ( f->f_av_desc->ad_type->sat_equality->smr_usage & SLAP_MR_MUTATION_NORMALIZER ) { + f->f_av_desc->ad_type->sat_equality->smr_normalize( + (SLAP_MR_DENORMALIZE|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX), + NULL, NULL, &f->f_av_value, &value, op->o_tmpmemctx ); + } + + filter_escape_value_x( &value, &tmp, op->o_tmpmemctx ); /* NOTE: tmp can legitimately be NULL (meaning empty) * since in a Filter values in AVAs are supposed * to have been normalized, meaning that an empty value * is legal for that attribute's syntax */ -escaped: fstr->bv_len += f->f_av_desc->ad_cname.bv_len + tmp.bv_len; if ( undef ) fstr->bv_len++; @@ -630,6 +629,10 @@ escaped: f->f_av_desc->ad_cname.bv_val, sign, tmp.bv_len ? tmp.bv_val : "" ); + if ( value.bv_val != f->f_av_value.bv_val ) { + ber_memfree_x( value.bv_val, op->o_tmpmemctx ); + } + ber_memfree_x( tmp.bv_val, op->o_tmpmemctx ); break; diff --git a/servers/slapd/ldapsync.c b/servers/slapd/ldapsync.c index 99905ac677..d04aa260f2 100644 --- a/servers/slapd/ldapsync.c +++ b/servers/slapd/ldapsync.c @@ -146,8 +146,8 @@ slap_parse_csn_sid( struct berval *csnp ) csn.bv_len = q - p; - i = (int)strtoul( p, &q, 16 ); - if ( p == q || q != p + csn.bv_len || i > SLAP_SYNC_SID_MAX ) { + i = strtol( p, &q, 16 ); + if ( p == q || q != p + csn.bv_len || i < 0 || i > SLAP_SYNC_SID_MAX ) { i = -1; } @@ -174,7 +174,6 @@ slap_parse_sync_cookie( { char *csn_ptr; char *csn_str; - char *rid_ptr; char *cval; char *next, *end; AttributeDescription *ad = slap_schema.si_ad_modifyTimestamp; @@ -195,11 +194,13 @@ slap_parse_sync_cookie( for ( next=cookie->octet_str.bv_val; next < end; ) { if ( !strncmp( next, "rid=", STRLENOF("rid=") )) { - rid_ptr = next; - cookie->rid = strtoul( &rid_ptr[ STRLENOF( "rid=" ) ], &next, 10 ); + char *rid_ptr = next; + cookie->rid = strtol( &rid_ptr[ STRLENOF( "rid=" ) ], &next, 10 ); if ( next == rid_ptr || next > end || - ( *next && *next != ',' ) ) + ( *next && *next != ',' ) || + cookie->rid < 0 || + cookie->rid > SLAP_SYNC_RID_MAX ) { return -1; } @@ -212,11 +213,14 @@ slap_parse_sync_cookie( continue; } if ( !strncmp( next, "sid=", STRLENOF("sid=") )) { - rid_ptr = next; - cookie->sid = strtoul( &rid_ptr[ STRLENOF( "sid=" ) ], &next, 16 ); - if ( next == rid_ptr || + char *sid_ptr = next; + sid_ptr = next; + cookie->sid = strtol( &sid_ptr[ STRLENOF( "sid=" ) ], &next, 16 ); + if ( next == sid_ptr || next > end || - ( *next && *next != ',' ) ) + ( *next && *next != ',' ) || + cookie->sid < 0 || + cookie->sid > SLAP_SYNC_SID_MAX ) { return -1; } diff --git a/servers/slapd/overlays/rwmmap.c b/servers/slapd/overlays/rwmmap.c index c5c9142090..8fa42c91ee 100644 --- a/servers/slapd/overlays/rwmmap.c +++ b/servers/slapd/overlays/rwmmap.c @@ -32,7 +32,6 @@ #include "slap.h" #include "rwm.h" -#include "lutil.h" #undef ldap_debug /* silence a warning in ldap-int.h */ #include "../../../libraries/libldap/ldap-int.h" @@ -380,7 +379,6 @@ map_attr_value( { struct berval vtmp = BER_BVNULL; int freeval = 0; - char uuid[ LDAP_LUTIL_UUIDSTR_BUFSIZE ]; AttributeDescription *ad = *adp; struct ldapmapping *mapping = NULL; @@ -422,13 +420,14 @@ map_attr_value( return -1; } - } else if ( ad->ad_type->sat_syntax == slap_schema.si_ad_entryUUID->ad_type->sat_syntax ) { - vtmp.bv_len = lutil_uuidstr_from_normalized( value->bv_val, - value->bv_len, uuid, LDAP_LUTIL_UUIDSTR_BUFSIZE ); - if ( vtmp.bv_len < 0 ) { + } else if ( ad->ad_type->sat_equality->smr_usage & SLAP_MR_MUTATION_NORMALIZER ) { + if ( ad->ad_type->sat_equality->smr_normalize( + (SLAP_MR_DENORMALIZE|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX), + NULL, NULL, value, &vtmp, NULL ) ) + { return -1; } - vtmp.bv_val = uuid; + freeval = 1; } else if ( ad == slap_schema.si_ad_objectClass || ad == slap_schema.si_ad_structuralObjectClass ) diff --git a/servers/slapd/overlays/syncprov.c b/servers/slapd/overlays/syncprov.c index 9cae2c53dc..49d0dd5db6 100644 --- a/servers/slapd/overlays/syncprov.c +++ b/servers/slapd/overlays/syncprov.c @@ -770,6 +770,8 @@ syncprov_sendresp( Operation *op, opcookie *opc, syncops *so, BER_BVZERO( &csns[1] ); slap_compose_sync_cookie( op, &cookie, csns, so->s_rid, so->s_sid ); + Debug( LDAP_DEBUG_SYNC, "syncprov_sendresp: cookie=%s\n", cookie.bv_val, 0, 0 ); + e_uuid.e_attrs = &a_uuid; a_uuid.a_desc = slap_schema.si_ad_entryUUID; a_uuid.a_nvals = &opc->suuid; @@ -974,15 +976,18 @@ static int syncprov_qresp( opcookie *opc, syncops *so, int mode ) { syncres *sr; - int sid; + int sid, srsize; /* Don't send changes back to their originator */ sid = slap_parse_csn_sid( &opc->sctxcsn ); if ( sid >= 0 && sid == so->s_sid ) return LDAP_SUCCESS; - sr = ch_malloc(sizeof(syncres) + opc->suuid.bv_len + 1 + - opc->sdn.bv_len + 1 + opc->sndn.bv_len + 1 + opc->sctxcsn.bv_len + 1 ); + srsize = sizeof(syncres) + opc->suuid.bv_len + 1 + + opc->sdn.bv_len + 1 + opc->sndn.bv_len + 1; + if ( opc->sctxcsn.bv_len ) + srsize += opc->sctxcsn.bv_len + 1; + sr = ch_malloc( srsize ); sr->s_next = NULL; sr->s_dn.bv_val = (char *)(sr + 1); sr->s_dn.bv_len = opc->sdn.bv_len; @@ -995,9 +1000,13 @@ syncprov_qresp( opcookie *opc, syncops *so, int mode ) opc->sndn.bv_val ) + 1; sr->s_uuid.bv_len = opc->suuid.bv_len; AC_MEMCPY( sr->s_uuid.bv_val, opc->suuid.bv_val, opc->suuid.bv_len ); - sr->s_csn.bv_val = sr->s_uuid.bv_val + sr->s_uuid.bv_len + 1; + if ( opc->sctxcsn.bv_len ) { + sr->s_csn.bv_val = sr->s_uuid.bv_val + sr->s_uuid.bv_len + 1; + strcpy( sr->s_csn.bv_val, opc->sctxcsn.bv_val ); + } else { + sr->s_csn.bv_val = NULL; + } sr->s_csn.bv_len = opc->sctxcsn.bv_len; - strcpy( sr->s_csn.bv_val, opc->sctxcsn.bv_val ); ldap_pvt_thread_mutex_lock( &so->s_mutex ); if ( !so->s_res ) { @@ -1527,6 +1536,9 @@ syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl, slap_compose_sync_cookie( op, &cookie, delcsn, srs->sr_state.rid, srs->sr_state.sid ); + + Debug( LDAP_DEBUG_SYNC, "syncprov_playlog: cookie=%s\n", cookie.bv_val, 0, 0 ); + uuids[ndel].bv_val = NULL; syncprov_sendinfo( op, rs, LDAP_TAG_SYNC_ID_SET, &cookie, 0, uuids, 1 ); op->o_tmpfree( cookie.bv_val, op->o_tmpmemctx ); @@ -1546,7 +1558,7 @@ syncprov_op_response( Operation *op, SlapReply *rs ) { struct berval maxcsn = BER_BVNULL; char cbuf[LDAP_LUTIL_CSNSTR_BUFSIZE]; - int do_check = 0; + int do_check = 0, have_psearches; /* Update our context CSN */ cbuf[0] = '\0'; @@ -1605,7 +1617,10 @@ syncprov_op_response( Operation *op, SlapReply *rs ) opc->sctxcsn.bv_val = cbuf; /* Handle any persistent searches */ - if ( si->si_ops ) { + ldap_pvt_thread_mutex_lock( &si->si_ops_mutex ); + have_psearches = ( si->si_ops != NULL ); + ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex ); + if ( have_psearches ) { switch(op->o_tag) { case LDAP_REQ_ADD: case LDAP_REQ_MODIFY: @@ -1708,12 +1723,19 @@ syncprov_op_mod( Operation *op, SlapReply *rs ) { slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; syncprov_info_t *si = on->on_bi.bi_private; + slap_callback *cb; + opcookie *opc; + int have_psearches, cbsize; + + ldap_pvt_thread_mutex_lock( &si->si_ops_mutex ); + have_psearches = ( si->si_ops != NULL ); + ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex ); + + cbsize = sizeof(slap_callback) + sizeof(opcookie) + + (have_psearches ? sizeof(modinst) : 0 ); - slap_callback *cb = op->o_tmpcalloc(1, sizeof(slap_callback)+ - sizeof(opcookie) + - (si->si_ops ? sizeof(modinst) : 0 ), - op->o_tmpmemctx); - opcookie *opc = (opcookie *)(cb+1); + cb = op->o_tmpcalloc(1, cbsize, op->o_tmpmemctx); + opc = (opcookie *)(cb+1); opc->son = on; cb->sc_response = syncprov_op_response; cb->sc_cleanup = syncprov_op_cleanup; @@ -1724,7 +1746,7 @@ syncprov_op_mod( Operation *op, SlapReply *rs ) /* If there are active persistent searches, lock this operation. * See seqmod.c for the locking logic on its own. */ - if ( si->si_ops ) { + if ( have_psearches ) { modtarget *mt, mtdummy; modinst *mi; @@ -1771,7 +1793,7 @@ syncprov_op_mod( Operation *op, SlapReply *rs ) } } - if (( si->si_ops || si->si_logs ) && op->o_tag != LDAP_REQ_ADD ) + if (( have_psearches || si->si_logs ) && op->o_tag != LDAP_REQ_ADD ) syncprov_matchops( op, opc, 1 ); return SLAP_CB_CONTINUE; @@ -1940,16 +1962,20 @@ syncprov_search_response( Operation *op, SlapReply *rs ) rs->sr_entry->e_name.bv_val, 0, 0 ); return LDAP_SUCCESS; } - /* Make sure entry is less than the snapshot'd contextCSN */ - for ( i=0; iss_numcsns; i++ ) { - if ( sid == ss->ss_sids[i] && ber_bvcmp( &a->a_nvals[0], - &ss->ss_ctxcsn[i] ) > 0 ) { - Debug( LDAP_DEBUG_SYNC, - "Entry %s CSN %s greater than snapshot %s\n", - rs->sr_entry->e_name.bv_val, - a->a_nvals[0].bv_val, - ss->ss_ctxcsn[i].bv_val ); - return LDAP_SUCCESS; + + /* If not a persistent search */ + if ( !ss->ss_so ) { + /* Make sure entry is less than the snapshot'd contextCSN */ + for ( i=0; iss_numcsns; i++ ) { + if ( sid == ss->ss_sids[i] && ber_bvcmp( &a->a_nvals[0], + &ss->ss_ctxcsn[i] ) > 0 ) { + Debug( LDAP_DEBUG_SYNC, + "Entry %s CSN %s greater than snapshot %s\n", + rs->sr_entry->e_name.bv_val, + a->a_nvals[0].bv_val, + ss->ss_ctxcsn[i].bv_val ); + return LDAP_SUCCESS; + } } } @@ -1980,6 +2006,8 @@ syncprov_search_response( Operation *op, SlapReply *rs ) slap_compose_sync_cookie( op, &cookie, ss->ss_ctxcsn, srs->sr_state.rid, srs->sr_state.sid ); + Debug( LDAP_DEBUG_SYNC, "syncprov_search_response: cookie=%s\n", cookie.bv_val, 0, 0 ); + /* Is this a regular refresh? */ if ( !ss->ss_so ) { rs->sr_ctrls = op->o_tmpalloc( sizeof(LDAPControl *)*2, @@ -2188,6 +2216,8 @@ no_change: nochange = 1; if ( si->si_usehint && srs->sr_rhint == 0 ) { if ( ctxcsn ) ber_bvarray_free_x( ctxcsn, op->o_tmpmemctx ); + if ( sids ) + op->o_tmpfree( sids, op->o_tmpmemctx ); send_ldap_error( op, rs, LDAP_SYNC_REFRESH_REQUIRED, "sync cookie is stale" ); return rs->sr_err; } @@ -2198,6 +2228,8 @@ no_change: nochange = 1; LDAP_SUCCESS ) { if ( ctxcsn ) ber_bvarray_free_x( ctxcsn, op->o_tmpmemctx ); + if ( sids ) + op->o_tmpfree( sids, op->o_tmpmemctx ); send_ldap_result( op, rs ); return rs->sr_err; } diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c index 34dbc86cee..f318a75564 100644 --- a/servers/slapd/schema_init.c +++ b/servers/slapd/schema_init.c @@ -2348,6 +2348,19 @@ UUIDNormalize( unsigned char octet = '\0'; int i; int j; + + if ( SLAP_MR_IS_DENORMALIZE( usage ) ) { + /* NOTE: must be a normalized UUID */ + assert( val->bv_len == 16 ); + + normalized->bv_val = slap_sl_malloc( LDAP_LUTIL_UUIDSTR_BUFSIZE, ctx ); + normalized->bv_len = lutil_uuidstr_from_normalized( val->bv_val, + val->bv_len, normalized->bv_val, LDAP_LUTIL_UUIDSTR_BUFSIZE ); + assert( normalized->bv_len == STRLENOF( "BADBADBA-DBAD-0123-4567-BADBADBADBAD" ) ); + + return LDAP_SUCCESS; + } + normalized->bv_len = 16; normalized->bv_val = slap_sl_malloc( normalized->bv_len + 1, ctx ); @@ -2585,7 +2598,13 @@ serialNumberAndIssuerCheck( for( ; (x.bv_val[0] == ' ') && x.bv_len; x.bv_val++, x.bv_len--) { /* empty */; } - + + /* For backward compatibility, this part is optional */ + if( !strncasecmp( x.bv_val, "rdnSequence:", STRLENOF("rdnSequence:"))) { + x.bv_val += STRLENOF("rdnSequence:"); + x.bv_len -= STRLENOF("rdnSequence:"); + } + if( x.bv_val[0] != '"' ) return LDAP_INVALID_SYNTAX; x.bv_val++; x.bv_len--; @@ -2697,7 +2716,13 @@ serialNumberAndIssuerCheck( for( ; (x.bv_val[0] == ' ') && x.bv_len; x.bv_val++, x.bv_len--) { /* empty */; } - + + /* For backward compatibility, this part is optional */ + if( !strncasecmp( x.bv_val, "rdnSequence:", STRLENOF("rdnSequence:"))) { + x.bv_val += STRLENOF("rdnSequence:"); + x.bv_len -= STRLENOF("rdnSequence:"); + } + if( x.bv_val[0] != '"' ) return LDAP_INVALID_SYNTAX; x.bv_val++; x.bv_len--; @@ -2849,7 +2874,7 @@ serialNumberAndIssuerPretty( if( rc ) return LDAP_INVALID_SYNTAX; /* make room from sn + "$" */ - out->bv_len = STRLENOF("{ serialNumber , issuer \"\" }") + out->bv_len = STRLENOF("{ serialNumber , issuer rdnSequence:\"\" }") + sn.bv_len + ni.bv_len; out->bv_val = slap_sl_malloc( out->bv_len + 1, ctx ); @@ -2867,8 +2892,8 @@ serialNumberAndIssuerPretty( AC_MEMCPY( &out->bv_val[n], sn.bv_val, sn.bv_len ); n += sn.bv_len; - AC_MEMCPY( &out->bv_val[n], ", issuer \"", STRLENOF(", issuer \"")); - n += STRLENOF(", issuer \""); + AC_MEMCPY( &out->bv_val[n], ", issuer rdnSequence:\"", STRLENOF(", issuer rdnSequence:\"")); + n += STRLENOF(", issuer rdnSequence:\""); AC_MEMCPY( &out->bv_val[n], ni.bv_val, ni.bv_len ); n += ni.bv_len; @@ -2939,7 +2964,7 @@ serialNumberAndIssuerNormalize( } /* make room for sn + "$" */ - out->bv_len = STRLENOF( "{ serialNumber , issuer \"\" }" ) + out->bv_len = STRLENOF( "{ serialNumber , issuer rdnSequence:\"\" }" ) + ( sn2.bv_len * 2 + 3 ) + ni.bv_len; out->bv_val = slap_sl_malloc( out->bv_len + 1, ctx ); @@ -2961,15 +2986,15 @@ serialNumberAndIssuerNormalize( unsigned char *v = sn2.bv_val; out->bv_val[n++] = '\''; for ( j = 0; j < sn2.bv_len; j++ ) { - sprintf( &out->bv_val[n], "%02x", v[j] ); + sprintf( &out->bv_val[n], "%02X", v[j] ); n += 2; } out->bv_val[n++] = '\''; out->bv_val[n++] = 'H'; } - AC_MEMCPY( &out->bv_val[n], ", issuer \"", STRLENOF( ", issuer \"" )); - n += STRLENOF( ", issuer \"" ); + AC_MEMCPY( &out->bv_val[n], ", issuer rdnSequence:\"", STRLENOF( ", issuer rdnSequence:\"" )); + n += STRLENOF( ", issuer rdnSequence:\"" ); AC_MEMCPY( &out->bv_val[n], ni.bv_val, ni.bv_len ); n += ni.bv_len; @@ -3061,7 +3086,7 @@ certificateExactNormalize( sptr = serial; *sptr++ = '\''; for ( i = 0; ibv_len = STRLENOF( "{ serialNumber , issuer \"\" }" ) + normalized->bv_len = STRLENOF( "{ serialNumber , issuer rdnSequence:\"\" }" ) + seriallen + issuer_dn.bv_len; normalized->bv_val = ch_malloc(normalized->bv_len+1); @@ -3090,8 +3115,8 @@ certificateExactNormalize( AC_MEMCPY(p, serial, seriallen); p += seriallen; - AC_MEMCPY(p, ", issuer \"", STRLENOF( ", issuer \"" )); - p += STRLENOF( ", issuer \"" ); + AC_MEMCPY(p, ", issuer rdnSequence:\"", STRLENOF( ", issuer rdnSequence:\"" )); + p += STRLENOF( ", issuer rdnSequence:\"" ); AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len); p += issuer_dn.bv_len; diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 65319e1a6e..eae710d0ce 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -556,7 +556,8 @@ struct MatchingRule { */ #define SLAP_MR_VALUE_OF_ASSERTION_SYNTAX 0x0001U #define SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX 0x0002U -#define SLAP_MR_VALUE_OF_SYNTAX 0x0003U +#define SLAP_MR_VALUE_OF_SYNTAX (SLAP_MR_VALUE_OF_ASSERTION_SYNTAX|SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX) +#define SLAP_MR_DENORMALIZE (SLAP_MR_MUTATION_NORMALIZER) #define SLAP_MR_IS_VALUE_OF_ATTRIBUTE_SYNTAX( usage ) \ ((usage) & SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX ) @@ -568,6 +569,8 @@ struct MatchingRule { #else #define SLAP_MR_IS_VALUE_OF_SYNTAX( usage ) (1) #endif +#define SLAP_MR_IS_DENORMALIZE( usage ) \ + ((usage) & SLAP_MR_DENORMALIZE ) /* either or both the asserted value or attribute value * may be provided in normalized form @@ -1675,7 +1678,7 @@ typedef BackendDB Backend; struct syncinfo_s; -#define SLAP_SYNC_RID_SIZE 3 +#define SLAP_SYNC_RID_MAX 999 #define SLAP_SYNC_SID_MAX 4095 /* based on liblutil/csn.c field width */ #define SLAP_SYNCUUID_SET_SIZE 256 diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index 2f64096553..3c7026f80b 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -63,7 +63,7 @@ typedef struct syncinfo_s { BackendDB *si_wbe; struct re_s *si_re; int si_rid; - char si_ridtxt[ STRLENOF("rid=4095") + 1 ]; + char si_ridtxt[ STRLENOF("rid=999") + 1 ]; slap_bindconf si_bindconf; struct berval si_base; struct berval si_logbase; @@ -103,7 +103,7 @@ typedef struct syncinfo_s { } syncinfo_t; static int syncuuid_cmp( const void *, const void * ); -static void avl_ber_bvfree( void * ); +static int avl_presentlist_insert( syncinfo_t* si, struct berval *syncUUID ); static void syncrepl_del_nonpresent( Operation *, syncinfo_t *, BerVarray, struct berval * ); static int syncrepl_message_to_op( syncinfo_t *, Operation *, LDAPMessage * ); @@ -797,6 +797,10 @@ do_syncrep2( } if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) { ber_scanf( ber, /*"{"*/ "m}", &cookie ); + + Debug( LDAP_DEBUG_SYNC, "do_syncrep2: cookie=%s\n", + BER_BVISNULL( &cookie ) ? "" : cookie.bv_val, 0, 0 ); + if ( !BER_BVISNULL( &cookie ) ) { ch_free( syncCookie.octet_str.bv_val ); ber_dupbv( &syncCookie.octet_str, &cookie ); @@ -864,6 +868,10 @@ do_syncrep2( ber_scanf( ber, "{" /*"}"*/); if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) { ber_scanf( ber, "m", &cookie ); + + Debug( LDAP_DEBUG_SYNC, "do_syncrep2: cookie=%s\n", + BER_BVISNULL( &cookie ) ? "" : cookie.bv_val, 0, 0 ); + if ( !BER_BVISNULL( &cookie ) ) { ch_free( syncCookie.octet_str.bv_val ); ber_dupbv( &syncCookie.octet_str, &cookie); @@ -901,7 +909,7 @@ do_syncrep2( syncrepl_del_nonpresent( op, si, NULL, &syncCookie.ctxcsn[m] ); } else { - avl_free( si->si_presentlist, avl_ber_bvfree ); + avl_free( si->si_presentlist, ch_free ); si->si_presentlist = NULL; } } @@ -952,6 +960,10 @@ do_syncrep2( if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) { ber_scanf( ber, "m", &cookie ); + + Debug( LDAP_DEBUG_SYNC, "do_syncrep2: cookie=%s\n", + BER_BVISNULL( &cookie ) ? "" : cookie.bv_val, 0, 0 ); + if ( !BER_BVISNULL( &cookie ) ) { ch_free( syncCookie.octet_str.bv_val ); ber_dupbv( &syncCookie.octet_str, &cookie ); @@ -979,6 +991,10 @@ do_syncrep2( LDAP_TAG_SYNC_COOKIE ) { ber_scanf( ber, "m", &cookie ); + + Debug( LDAP_DEBUG_SYNC, "do_syncrep2: cookie=%s\n", + BER_BVISNULL( &cookie ) ? "" : cookie.bv_val, 0, 0 ); + if ( !BER_BVISNULL( &cookie ) ) { ch_free( syncCookie.octet_str.bv_val ); ber_dupbv( &syncCookie.octet_str, &cookie ); @@ -1003,15 +1019,8 @@ do_syncrep2( } else { int i; for ( i = 0; !BER_BVISNULL( &syncUUIDs[i] ); i++ ) { - struct berval *syncuuid_bv; - syncuuid_bv = ber_dupbv( NULL, &syncUUIDs[i] ); - slap_sl_free( syncUUIDs[i].bv_val,op->o_tmpmemctx ); - if ( avl_insert( &si->si_presentlist, - (caddr_t) syncuuid_bv, - syncuuid_cmp, avl_dup_error ) ) - { - ber_bvfree( syncuuid_bv ); - } + (void)avl_presentlist_insert( si, &syncUUIDs[i] ); + slap_sl_free( syncUUIDs[i].bv_val, op->o_tmpmemctx ); } slap_sl_free( syncUUIDs, op->o_tmpmemctx ); } @@ -1278,16 +1287,16 @@ reload: if ( rc ) { if ( fail == RETRYNUM_TAIL ) { Debug( LDAP_DEBUG_ANY, - "do_syncrepl: rid %03d quitting\n", - si->si_rid, 0, 0 ); + "do_syncrepl: %s quitting\n", + si->si_ridtxt, 0, 0 ); } else if ( fail > 0 ) { Debug( LDAP_DEBUG_ANY, - "do_syncrepl: rid %03d retrying (%d retries left)\n", - si->si_rid, fail, 0 ); + "do_syncrepl: %s retrying (%d retries left)\n", + si->si_ridtxt, fail, 0 ); } else { Debug( LDAP_DEBUG_ANY, - "do_syncrepl: rid %03d retrying\n", - si->si_rid, 0, 0 ); + "do_syncrepl: %s retrying\n", + si->si_ridtxt, 0, 0 ); } } @@ -1823,6 +1832,29 @@ typedef struct dninfo { Modifications *mods; /* the modlist we compared */ } dninfo; +/* return 1 if inserted, 0 otherwise */ +static int +avl_presentlist_insert( + syncinfo_t* si, + struct berval *syncUUID ) +{ + struct berval *syncuuid_bv = ch_malloc( sizeof( struct berval ) + syncUUID->bv_len + 1 ); + + syncuuid_bv->bv_len = syncUUID->bv_len; + syncuuid_bv->bv_val = (char *)&syncuuid_bv[1]; + AC_MEMCPY( syncuuid_bv->bv_val, syncUUID->bv_val, syncUUID->bv_len ); + syncuuid_bv->bv_val[ syncuuid_bv->bv_len ] = '\0'; + + if ( avl_insert( &si->si_presentlist, (caddr_t) syncuuid_bv, + syncuuid_cmp, avl_dup_error ) ) + { + ch_free( syncuuid_bv ); + return 0; + } + + return 1; +} + static int syncrepl_entry( syncinfo_t* si, @@ -1835,7 +1867,7 @@ syncrepl_entry( { Backend *be = op->o_bd; slap_callback cb = { NULL, NULL, NULL, NULL }; - struct berval *syncuuid_bv = NULL; + int syncuuid_inserted = 0; struct berval syncUUID_strrep = BER_BVNULL; SlapReply rs_search = {REP_RESULT}; @@ -1857,13 +1889,7 @@ syncrepl_entry( if (( syncstate == LDAP_SYNC_PRESENT || syncstate == LDAP_SYNC_ADD ) ) { if ( !si->si_refreshPresent ) { - syncuuid_bv = ber_dupbv( NULL, syncUUID ); - if ( avl_insert( &si->si_presentlist, (caddr_t) syncuuid_bv, - syncuuid_cmp, avl_dup_error ) ) - { - ber_bvfree( syncuuid_bv ); - syncuuid_bv = NULL; - } + syncuuid_inserted = avl_presentlist_insert( si, syncUUID ); } } @@ -1900,7 +1926,7 @@ syncrepl_entry( ava.aa_desc = slap_schema.si_ad_entryUUID; ava.aa_value = *syncUUID; - if ( syncuuid_bv ) { + if ( syncuuid_inserted ) { Debug( LDAP_DEBUG_SYNC, "syncrepl_entry: %s inserted UUID %s\n", si->si_ridtxt, syncUUID_strrep.bv_val, 0 ); } @@ -3004,13 +3030,11 @@ nonpresent_callback( struct nonpresent_entry *np_entry; if ( rs->sr_type == REP_RESULT ) { - count = avl_free( si->si_presentlist, avl_ber_bvfree ); + count = avl_free( si->si_presentlist, ch_free ); si->si_presentlist = NULL; } else if ( rs->sr_type == REP_SEARCH ) { if ( !( si->si_refreshDelete & NP_DELETE_ONE ) ) { - char buf[sizeof("rid=000 not")]; - a = attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_entryUUID ); if ( a ) { @@ -3018,13 +3042,15 @@ nonpresent_callback( syncuuid_cmp ); } - if ( slap_debug & LDAP_DEBUG_SYNC ) { - sprintf( buf, "%s %s", si->si_ridtxt, + if ( LogTest( LDAP_DEBUG_SYNC ) ) { + char buf[sizeof("rid=999 not")]; + + snprintf( buf, sizeof(buf), "%s %s", si->si_ridtxt, present_uuid ? "got" : "not" ); - } - Debug( LDAP_DEBUG_SYNC, "nonpresent_callback: %s UUID %s, dn %s\n", - buf, a ? a->a_vals[0].bv_val : "", rs->sr_entry->e_name.bv_val ); + Debug( LDAP_DEBUG_SYNC, "nonpresent_callback: %s UUID %s, dn %s\n", + buf, a ? a->a_vals[0].bv_val : "", rs->sr_entry->e_name.bv_val ); + } if ( a == NULL ) return 0; } @@ -3038,8 +3064,7 @@ nonpresent_callback( } else { avl_delete( &si->si_presentlist, - &a->a_nvals[0], syncuuid_cmp ); - ch_free( present_uuid->bv_val ); + &a->a_nvals[0], syncuuid_cmp ); ch_free( present_uuid ); } } @@ -3177,18 +3202,6 @@ syncuuid_cmp( const void* v_uuid1, const void* v_uuid2 ) return ( memcmp( uuid1->bv_val, uuid2->bv_val, uuid1->bv_len ) ); } -static void -avl_ber_bvfree( void *v_bv ) -{ - struct berval *bv = (struct berval *)v_bv; - - if( v_bv == NULL ) return; - if ( !BER_BVISNULL( bv ) ) { - ch_free( bv->bv_val ); - } - ch_free( (char *) bv ); -} - void syncinfo_free( syncinfo_t *sie, int free_all ) { @@ -3280,7 +3293,7 @@ syncinfo_free( syncinfo_t *sie, int free_all ) } slap_sync_cookie_free( &sie->si_syncCookie, 0 ); if ( sie->si_presentlist ) { - avl_free( sie->si_presentlist, avl_ber_bvfree ); + avl_free( sie->si_presentlist, ch_free ); } while ( !LDAP_LIST_EMPTY( &sie->si_nonpresentlist ) ) { struct nonpresent_entry* npe; @@ -3390,7 +3403,7 @@ parse_syncrepl_line( return -1; } si->si_rid = tmp; - sprintf( si->si_ridtxt, IDSTR "=%d", si->si_rid ); + sprintf( si->si_ridtxt, IDSTR "=%03d", si->si_rid ); gots |= GOT_ID; } else if ( !strncasecmp( c->argv[ i ], PROVIDERSTR "=", STRLENOF( PROVIDERSTR "=" ) ) ) @@ -3577,12 +3590,10 @@ parse_syncrepl_line( si->si_interval = 0; } else if ( strchr( val, ':' ) != NULL ) { char *next, *ptr = val; - unsigned dd, hh, mm, ss; + int dd, hh, mm, ss; - /* NOTE: the test for ptr[ 0 ] == '-' - * should go before the call to strtoul() */ - dd = strtoul( ptr, &next, 10 ); - if ( ptr[ 0 ] == '-' || next == ptr || next[0] != ':' ) { + dd = strtol( ptr, &next, 10 ); + if ( next == ptr || next[0] != ':' || dd < 0 ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "Error: parse_syncrepl_line: " "invalid interval \"%s\", unable to parse days", val ); @@ -3590,8 +3601,8 @@ parse_syncrepl_line( return -1; } ptr = next + 1; - hh = strtoul( ptr, &next, 10 ); - if ( ptr[ 0 ] == '-' || next == ptr || next[0] != ':' || hh > 24 ) { + hh = strtol( ptr, &next, 10 ); + if ( next == ptr || next[0] != ':' || hh < 0 || hh > 24 ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "Error: parse_syncrepl_line: " "invalid interval \"%s\", unable to parse hours", val ); @@ -3599,8 +3610,8 @@ parse_syncrepl_line( return -1; } ptr = next + 1; - mm = strtoul( ptr, &next, 10 ); - if ( ptr[ 0 ] == '-' || next == ptr || next[0] != ':' || mm > 60 ) { + mm = strtol( ptr, &next, 10 ); + if ( next == ptr || next[0] != ':' || mm < 0 || mm > 60 ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "Error: parse_syncrepl_line: " "invalid interval \"%s\", unable to parse minutes", val ); @@ -3608,8 +3619,8 @@ parse_syncrepl_line( return -1; } ptr = next + 1; - ss = strtoul( ptr, &next, 10 ); - if ( ptr[ 0 ] == '-' || next == ptr || next[0] != '\0' || ss > 60 ) { + ss = strtol( ptr, &next, 10 ); + if ( next == ptr || next[0] != '\0' || ss < 0 || ss > 60 ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "Error: parse_syncrepl_line: " "invalid interval \"%s\", unable to parse seconds", val ); @@ -3937,7 +3948,7 @@ syncrepl_unparse( syncinfo_t *si, struct berval *bv ) ptr = buf; assert( si->si_rid >= 0 && si->si_rid <= SLAP_SYNC_SID_MAX ); - ptr += snprintf( ptr, WHATSLEFT, IDSTR "=%d " PROVIDERSTR "=%s", + ptr += snprintf( ptr, WHATSLEFT, IDSTR "=%03d " PROVIDERSTR "=%s", si->si_rid, si->si_bindconf.sb_uri.bv_val ); if ( ptr - buf >= sizeof( buf ) ) return; if ( !BER_BVISNULL( &bc ) ) { -- 2.39.5