From 7dc7c60c4bee16d1fcc1a6bc71aac881bdceb866 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Sun, 26 Aug 2007 17:03:22 +0000 Subject: [PATCH] improve previous commit; fix ITS#5108 by letting both SID and RID be 0..4095, input/output in decimal, but consistently handled in hexadecimals within CSN --- doc/man/man5/slapd.conf.5 | 7 +++++-- servers/slapd/bconfig.c | 7 +++++-- servers/slapd/ldapsync.c | 29 +++++++++++++++++++++++------ servers/slapd/slapadd.c | 37 +++++++++++++------------------------ servers/slapd/syncrepl.c | 11 ++++++----- 5 files changed, 52 insertions(+), 39 deletions(-) diff --git a/doc/man/man5/slapd.conf.5 b/doc/man/man5/slapd.conf.5 index abac3c582e..e5c5a1cc2e 100644 --- a/doc/man/man5/slapd.conf.5 +++ b/doc/man/man5/slapd.conf.5 @@ -854,7 +854,9 @@ factor is measure of security provided by the underlying transport, e.g. ldapi:// (and eventually IPSEC). It is not normally used. .TP .B serverID [] -Specify an integer ID from 0 to 4095 for this server. These IDs are +Specify an integer ID from 0 to 4095 for this server (limited +to 3 hexadecimal digits). +These IDs are required when using multimaster replication and each master must have a unique ID. If the URL is provided, this directive may be specified multiple times, providing a complete list of participating servers @@ -1584,7 +1586,8 @@ replication engine. identifies the current .B syncrepl directive within the replication consumer site. -It is a non-negative integer having no more than three digits. +It is a non-negative integer not greater than 4095 (limited +to three hexadecimal digits). .B provider specifies the replication provider site containing the master content diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c index 9416a8cf29..4245048d9f 100644 --- a/servers/slapd/bconfig.c +++ b/servers/slapd/bconfig.c @@ -945,6 +945,7 @@ config_generic(ConfigArgs *c) { struct berval bv; for ( si = sid_list; si; si=si->si_next ) { + assert( si->si_num >= 0 && si->si_num <= SLAP_SYNC_SID_MAX ); if ( !BER_BVISEMPTY( &si->si_url )) { bv.bv_len = si->si_url.bv_len + 6; bv.bv_val = ch_malloc( bv.bv_len ); @@ -1460,8 +1461,10 @@ config_generic(ConfigArgs *c) { { ServerID *si, **sip; LDAPURLDesc *lud; - int num = atoi( c->argv[1] ); - if ( num < 0 || num > SLAP_SYNC_SID_MAX ) { + int num; + if ( lutil_atoi( &num, c->argv[1] ) || + num < 0 || num > SLAP_SYNC_SID_MAX ) + { snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> illegal server ID", c->argv[0] ); Debug(LDAP_DEBUG_ANY, "%s: %s %s\n", diff --git a/servers/slapd/ldapsync.c b/servers/slapd/ldapsync.c index 840a3c131d..99905ac677 100644 --- a/servers/slapd/ldapsync.c +++ b/servers/slapd/ldapsync.c @@ -120,20 +120,37 @@ slap_sync_cookie_free( } int -slap_parse_csn_sid( struct berval *csn ) +slap_parse_csn_sid( struct berval *csnp ) { char *p, *q; + struct berval csn = *csnp; int i; - p = memchr( csn->bv_val, '#', csn->bv_len ); - if ( p ) - p = strchr( p+1, '#' ); + p = ber_bvchr( &csn, '#' ); if ( !p ) return -1; p++; - i = strtoul( p, &q, 10 ); - if ( p == q || i > SLAP_SYNC_SID_MAX ) + csn.bv_len -= p - csn.bv_val; + csn.bv_val = p; + + p = ber_bvchr( &csn, '#' ); + if ( !p ) + return -1; + p++; + csn.bv_len -= p - csn.bv_val; + csn.bv_val = p; + + q = ber_bvchr( &csn, '#' ); + if ( !q ) + return -1; + + 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 = -1; + } + return i; } diff --git a/servers/slapd/slapadd.c b/servers/slapd/slapadd.c index 6701291106..7f66cad740 100644 --- a/servers/slapd/slapadd.c +++ b/servers/slapd/slapadd.c @@ -52,7 +52,6 @@ slapadd( int argc, char **argv ) struct berval csn; struct berval maxcsn[ SLAP_SYNC_SID_MAX + 1 ]; - MatchingRule *mr_csnsid; unsigned long sid; struct berval bvtext; Attribute *attr; @@ -104,8 +103,6 @@ slapadd( int argc, char **argv ) } if ( update_ctxcsn ) { - mr_csnsid = mr_find( "CSNSIDMatch" ); - assert( mr_csnsid != NULL ); maxcsn[ 0 ].bv_val = maxcsnbuf; for ( sid = 1; sid <= SLAP_SYNC_SID_MAX; sid++ ) { maxcsn[ sid ].bv_val = maxcsn[ sid - 1 ].bv_val + LDAP_LUTIL_CSNSTR_BUFSIZE; @@ -280,24 +277,21 @@ slapadd( int argc, char **argv ) } if ( update_ctxcsn ) { - struct berval nsid; + int rc_sid; attr = attr_find( e->e_attrs, slap_schema.si_ad_entryCSN ); assert( attr != NULL ); - - rc = mr_csnsid->smr_normalize( SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, - NULL, NULL, &attr->a_nvals[ 0 ], &nsid, NULL ); - assert( rc == LDAP_SUCCESS ); - rc = lutil_atoulx( &sid, nsid.bv_val, 16 ); - ber_memfree( nsid.bv_val ); - if ( rc ) { + + rc_sid = slap_parse_csn_sid( &attr->a_nvals[ 0 ] ); + if ( rc_sid < 0 ) { Debug( LDAP_DEBUG_ANY, "%s: could not " "extract SID from entryCSN=%s\n", progname, attr->a_nvals[ 0 ].bv_val, 0 ); } else { - assert( sid <= SLAP_SYNC_SID_MAX ); + assert( rc_sid <= SLAP_SYNC_SID_MAX ); + sid = (unsigned)rc_sid; if ( maxcsn[ sid ].bv_len != 0 ) { match = 0; value_match( &match, slap_schema.si_ad_entryCSN, @@ -355,19 +349,10 @@ slapadd( int argc, char **argv ) int i; for ( i = 0; !BER_BVISNULL( &attr->a_vals[ i ] ); i++ ) { - struct berval nsid; - - rc = mr_csnsid->smr_normalize( SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, - NULL, NULL, &attr->a_nvals[ i ], &nsid, NULL ); - - /* must succeed, since it passed - * validation/normalization */ - assert( rc == LDAP_SUCCESS ); + int rc_sid; - rc = lutil_atoulx( &sid, nsid.bv_val, 16 ); - ber_memfree( nsid.bv_val ); - - if ( rc ) { + rc_sid = slap_parse_csn_sid( &attr->a_nvals[ i ] ); + if ( rc_sid < 0 ) { Debug( LDAP_DEBUG_ANY, "%s: unable to extract SID " "from #%d contextCSN=%s\n", @@ -376,6 +361,10 @@ slapadd( int argc, char **argv ) continue; } + assert( rc_sid <= SLAP_SYNC_SID_MAX ); + + sid = (unsigned)rc_sid; + if ( maxcsn[ sid ].bv_len == 0 ) { match = -1; diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index 404f9579a5..d0893a3144 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[8]; + char si_ridtxt[ STRLENOF("rid=4095") + 1 ]; slap_bindconf si_bindconf; struct berval si_base; struct berval si_logbase; @@ -3351,15 +3351,15 @@ parse_syncrepl_line( Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return -1; } - if ( tmp >= 1000 || tmp < 0 ) { + if ( tmp > SLAP_SYNC_SID_MAX || tmp < 0 ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "Error: parse_syncrepl_line: " - "syncrepl id %d is out of range [0..999]", tmp ); + "syncrepl id %d is out of range [0..4095]", tmp ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return -1; } si->si_rid = tmp; - sprintf( si->si_ridtxt, IDSTR "=%03d", si->si_rid ); + sprintf( si->si_ridtxt, IDSTR "=%d", si->si_rid ); gots |= GOT_ID; } else if ( !strncasecmp( c->argv[ i ], PROVIDERSTR "=", STRLENOF( PROVIDERSTR "=" ) ) ) @@ -3905,7 +3905,8 @@ syncrepl_unparse( syncinfo_t *si, struct berval *bv ) si->si_bindconf.sb_version = LDAP_VERSION3; ptr = buf; - ptr += snprintf( ptr, WHATSLEFT, IDSTR "=%03d " PROVIDERSTR "=%s", + assert( si->si_rid >= 0 && si->si_rid <= SLAP_SYNC_SID_MAX ); + ptr += snprintf( ptr, WHATSLEFT, IDSTR "=%d " 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