mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-06 10:46:21 +08:00
add support for CSNSIDMatch; use it to set contextCSN as appropriate when slapadd'ing -w
This commit is contained in:
parent
7c66952714
commit
2132aa3b16
@ -2431,7 +2431,7 @@ numericStringNormalize(
|
||||
}
|
||||
}
|
||||
|
||||
/* we should have copied no more then is in val */
|
||||
/* we should have copied no more than is in val */
|
||||
assert( (q - normalized->bv_val) <= (p - val->bv_val) );
|
||||
|
||||
/* null terminate */
|
||||
@ -3478,6 +3478,84 @@ done:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Normalize a SID as used inside a CSN:
|
||||
* three-digit numeric string */
|
||||
static int
|
||||
SIDNormalize(
|
||||
slap_mask_t usage,
|
||||
Syntax *syntax,
|
||||
MatchingRule *mr,
|
||||
struct berval *val,
|
||||
struct berval *normalized,
|
||||
void *ctx )
|
||||
{
|
||||
if ( val->bv_len != 3 ) {
|
||||
return LDAP_INVALID_SYNTAX;
|
||||
}
|
||||
|
||||
if ( !ASCII_DIGIT( val->bv_val[ 0 ] ) ||
|
||||
!ASCII_DIGIT( val->bv_val[ 1 ] ) ||
|
||||
!ASCII_DIGIT( val->bv_val[ 2 ] ) )
|
||||
{
|
||||
return LDAP_INVALID_SYNTAX;
|
||||
}
|
||||
|
||||
ber_dupbv_x( normalized, val, ctx );
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
/* Normalize a SID as used inside a CSN, either as-is
|
||||
* (assertion value) or extracted from the CSN
|
||||
* (attribute value) */
|
||||
static int
|
||||
csnSIDNormalize(
|
||||
slap_mask_t usage,
|
||||
Syntax *syntax,
|
||||
MatchingRule *mr,
|
||||
struct berval *val,
|
||||
struct berval *normalized,
|
||||
void *ctx )
|
||||
{
|
||||
struct berval bv;
|
||||
char *ptr;
|
||||
|
||||
if ( BER_BVISEMPTY( val ) ) {
|
||||
return LDAP_INVALID_SYNTAX;
|
||||
}
|
||||
|
||||
if ( SLAP_MR_IS_VALUE_OF_ASSERTION_SYNTAX(usage) ) {
|
||||
return SIDNormalize( 0, NULL, NULL, val, normalized, ctx );
|
||||
}
|
||||
|
||||
assert( SLAP_MR_IS_VALUE_OF_ATTRIBUTE_SYNTAX(usage) != 0 );
|
||||
|
||||
ptr = ber_bvchr( val, '#' );
|
||||
if ( ptr == NULL || ptr - val->bv_val == val->bv_len ) {
|
||||
return LDAP_INVALID_SYNTAX;
|
||||
}
|
||||
|
||||
bv.bv_val = ptr + 1;
|
||||
bv.bv_len = val->bv_len - ( ptr + 1 - val->bv_val );
|
||||
|
||||
ptr = ber_bvchr( &bv, '#' );
|
||||
if ( ptr == NULL || ptr - val->bv_val == val->bv_len ) {
|
||||
return LDAP_INVALID_SYNTAX;
|
||||
}
|
||||
|
||||
bv.bv_val = ptr + 1;
|
||||
bv.bv_len = val->bv_len - ( ptr + 1 - val->bv_val );
|
||||
|
||||
ptr = ber_bvchr( &bv, '#' );
|
||||
if ( ptr == NULL || ptr - val->bv_val == val->bv_len ) {
|
||||
return LDAP_INVALID_SYNTAX;
|
||||
}
|
||||
|
||||
bv.bv_len = ptr - bv.bv_val;
|
||||
|
||||
return SIDNormalize( 0, NULL, NULL, &bv, normalized, ctx );
|
||||
}
|
||||
|
||||
|
||||
#ifndef SUPPORT_OBSOLETE_UTC_SYNTAX
|
||||
/* slight optimization - does not need the start parameter */
|
||||
@ -4352,6 +4430,10 @@ static slap_syntax_defs_rec syntax_defs[] = {
|
||||
{NULL, 0, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
char *csnSIDMatchSyntaxes[] = {
|
||||
"1.3.6.1.4.1.4203.666.11.2.1" /* csn */,
|
||||
NULL
|
||||
};
|
||||
char *certificateExactMatchSyntaxes[] = {
|
||||
"1.3.6.1.4.1.1466.115.121.1.8" /* certificate */,
|
||||
NULL
|
||||
@ -4777,6 +4859,13 @@ static slap_mrule_defs_rec mrule_defs[] = {
|
||||
NULL, NULL,
|
||||
"CSNMatch" },
|
||||
|
||||
{"( 1.3.6.1.4.1.4203.666.11.2.4 NAME 'CSNSIDMatch' "
|
||||
"SYNTAX 1.3.6.1.4.1.4203.666.11.2.1 )",
|
||||
SLAP_MR_EQUALITY | SLAP_MR_EXT, csnSIDMatchSyntaxes,
|
||||
NULL, csnSIDNormalize, octetStringMatch,
|
||||
octetStringIndexer, octetStringFilter,
|
||||
NULL },
|
||||
|
||||
/* FIXME: OID is unused, but not registered yet */
|
||||
{"( 1.3.6.1.4.1.4203.666.4.12 NAME 'authzMatch' "
|
||||
"SYNTAX 1.3.6.1.4.1.4203.666.2.7 )",
|
||||
|
@ -39,7 +39,7 @@
|
||||
#include "slapcommon.h"
|
||||
|
||||
static char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
|
||||
static char maxcsnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
|
||||
static char maxcsnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE * ( SLAP_SYNC_SID_MAX + 1 ) ];
|
||||
|
||||
int
|
||||
slapadd( int argc, char **argv )
|
||||
@ -51,7 +51,9 @@ slapadd( int argc, char **argv )
|
||||
const char *progname = "slapadd";
|
||||
|
||||
struct berval csn;
|
||||
struct berval maxcsn;
|
||||
struct berval maxcsn[ SLAP_SYNC_SID_MAX + 1 ];
|
||||
MatchingRule *mr_csnsid;
|
||||
unsigned long sid;
|
||||
struct berval bvtext;
|
||||
Attribute *attr;
|
||||
Entry *ctxcsn_e;
|
||||
@ -102,8 +104,13 @@ slapadd( int argc, char **argv )
|
||||
}
|
||||
|
||||
if ( update_ctxcsn ) {
|
||||
maxcsn.bv_val = maxcsnbuf;
|
||||
maxcsn.bv_len = 0;
|
||||
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;
|
||||
maxcsn[ sid ].bv_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* nextline is the line number of the end of the current entry */
|
||||
@ -273,19 +280,37 @@ slapadd( int argc, char **argv )
|
||||
}
|
||||
|
||||
if ( update_ctxcsn ) {
|
||||
struct berval nsid;
|
||||
|
||||
attr = attr_find( e->e_attrs, slap_schema.si_ad_entryCSN );
|
||||
if ( maxcsn.bv_len != 0 ) {
|
||||
match = 0;
|
||||
value_match( &match, slap_schema.si_ad_entryCSN,
|
||||
slap_schema.si_ad_entryCSN->ad_type->sat_ordering,
|
||||
SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
|
||||
&maxcsn, &attr->a_nvals[0], &text );
|
||||
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 ) {
|
||||
Debug( LDAP_DEBUG_ANY, "%s: could not "
|
||||
"extract SID from entryCSN=%s\n",
|
||||
progname, attr->a_nvals[ 0 ].bv_val, 0 );
|
||||
|
||||
} else {
|
||||
match = -1;
|
||||
}
|
||||
if ( match < 0 ) {
|
||||
strcpy( maxcsn.bv_val, attr->a_nvals[0].bv_val );
|
||||
maxcsn.bv_len = attr->a_nvals[0].bv_len;
|
||||
assert( sid <= SLAP_SYNC_SID_MAX );
|
||||
|
||||
if ( maxcsn[ sid ].bv_len != 0 ) {
|
||||
match = 0;
|
||||
value_match( &match, slap_schema.si_ad_entryCSN,
|
||||
slap_schema.si_ad_entryCSN->ad_type->sat_ordering,
|
||||
SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
|
||||
&maxcsn[ sid ], &attr->a_nvals[0], &text );
|
||||
} else {
|
||||
match = -1;
|
||||
}
|
||||
if ( match < 0 ) {
|
||||
strcpy( maxcsn[ sid ].bv_val, attr->a_nvals[0].bv_val );
|
||||
maxcsn[ sid ].bv_len = attr->a_nvals[0].bv_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -317,7 +342,7 @@ slapadd( int argc, char **argv )
|
||||
bvtext.bv_val = textbuf;
|
||||
bvtext.bv_val[0] = '\0';
|
||||
|
||||
if ( rc == EXIT_SUCCESS && update_ctxcsn && !dryrun && maxcsn.bv_len ) {
|
||||
if ( rc == EXIT_SUCCESS && update_ctxcsn && !dryrun && sid != SLAP_SYNC_SID_MAX + 1 ) {
|
||||
ctxcsn_id = be->be_dn2id_get( be, be->be_nsuffix );
|
||||
if ( ctxcsn_id == NOID ) {
|
||||
fprintf( stderr, "%s: context entry is missing\n", progname );
|
||||
@ -325,33 +350,78 @@ slapadd( int argc, char **argv )
|
||||
} else {
|
||||
ctxcsn_e = be->be_entry_get( be, ctxcsn_id );
|
||||
if ( ctxcsn_e != NULL ) {
|
||||
attr = attr_find( ctxcsn_e->e_attrs,
|
||||
slap_schema.si_ad_contextCSN );
|
||||
attr = attr_find( ctxcsn_e->e_attrs, slap_schema.si_ad_contextCSN );
|
||||
if ( attr ) {
|
||||
value_match( &match, slap_schema.si_ad_entryCSN,
|
||||
slap_schema.si_ad_entryCSN->ad_type->sat_ordering,
|
||||
SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
|
||||
&maxcsn, &attr->a_nvals[0], &text );
|
||||
if ( match > 0 ) {
|
||||
AC_MEMCPY( attr->a_vals[0].bv_val, maxcsn.bv_val, maxcsn.bv_len );
|
||||
attr->a_vals[0].bv_val[maxcsn.bv_len] = '\0';
|
||||
attr->a_vals[0].bv_len = maxcsn.bv_len;
|
||||
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 );
|
||||
|
||||
rc = lutil_atoulx( &sid, nsid.bv_val, 16 );
|
||||
ber_memfree( nsid.bv_val );
|
||||
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s: unable to extract SID "
|
||||
"from #%d contextCSN=%s\n",
|
||||
progname, i,
|
||||
attr->a_nvals[ i ].bv_val );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( maxcsn[ sid ].bv_len == 0 ) {
|
||||
match = -1;
|
||||
|
||||
} else {
|
||||
value_match( &match, slap_schema.si_ad_entryCSN,
|
||||
slap_schema.si_ad_entryCSN->ad_type->sat_ordering,
|
||||
SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
|
||||
&maxcsn[ sid ], &attr->a_nvals[i], &text );
|
||||
}
|
||||
|
||||
if ( match < 0 ) {
|
||||
AC_MEMCPY( maxcsn[ sid ].bv_val,
|
||||
attr->a_nvals[ i ].bv_val,
|
||||
attr->a_nvals[ i ].bv_len );
|
||||
maxcsn[ sid ].bv_val[ attr->a_nvals[ i ].bv_len ] = '\0';
|
||||
maxcsn[ sid ].bv_len = attr->a_nvals[ i ].bv_len;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
match = 1;
|
||||
attr_merge_one( ctxcsn_e, slap_schema.si_ad_contextCSN, &maxcsn, NULL );
|
||||
|
||||
#if 0
|
||||
if ( attr->a_nvals && attr->a_nvals != attr->a_vals ) {
|
||||
ber_bvarray_free( attr->a_nvals );
|
||||
}
|
||||
ber_bvarray_free( attr->a_vals );
|
||||
#endif
|
||||
|
||||
attr->a_vals = NULL;
|
||||
attr->a_nvals = NULL;
|
||||
}
|
||||
if ( match > 0 ) {
|
||||
ctxcsn_id = be->be_entry_modify( be, ctxcsn_e, &bvtext );
|
||||
if( ctxcsn_id == NOID ) {
|
||||
fprintf( stderr, "%s: could not modify ctxcsn\n",
|
||||
progname);
|
||||
rc = EXIT_FAILURE;
|
||||
} else if ( verbose ) {
|
||||
fprintf( stderr, "modified: \"%s\" (%08lx)\n",
|
||||
ctxcsn_e->e_dn, (long) ctxcsn_id );
|
||||
|
||||
for ( sid = 0; sid <= SLAP_SYNC_SID_MAX; sid++ ) {
|
||||
if ( maxcsn[ sid ].bv_len ) {
|
||||
attr_merge_one( ctxcsn_e, slap_schema.si_ad_contextCSN,
|
||||
&maxcsn[ sid], NULL );
|
||||
}
|
||||
}
|
||||
|
||||
ctxcsn_id = be->be_entry_modify( be, ctxcsn_e, &bvtext );
|
||||
if( ctxcsn_id == NOID ) {
|
||||
fprintf( stderr, "%s: could not modify ctxcsn\n",
|
||||
progname);
|
||||
rc = EXIT_FAILURE;
|
||||
} else if ( verbose ) {
|
||||
fprintf( stderr, "modified: \"%s\" (%08lx)\n",
|
||||
ctxcsn_e->e_dn, (long) ctxcsn_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2856,11 +2856,12 @@ dn_callback(
|
||||
new = attr_find( dni->new_entry->e_attrs,
|
||||
slap_schema.si_ad_entryCSN );
|
||||
if ( new && old ) {
|
||||
int len = old->a_vals[0].bv_len;
|
||||
int rc, len = old->a_vals[0].bv_len;
|
||||
if ( len > new->a_vals[0].bv_len )
|
||||
len = new->a_vals[0].bv_len;
|
||||
if ( memcmp( old->a_vals[0].bv_val,
|
||||
new->a_vals[0].bv_val, len ) >= 0 ) {
|
||||
rc = memcmp( old->a_vals[0].bv_val,
|
||||
new->a_vals[0].bv_val, len );
|
||||
if ( rc > 0 ) {
|
||||
Debug( LDAP_DEBUG_SYNC,
|
||||
"dn_callback : new entry is older than ours "
|
||||
"%s ours %s, new %s\n",
|
||||
@ -2868,6 +2869,14 @@ dn_callback(
|
||||
old->a_vals[0].bv_val,
|
||||
new->a_vals[0].bv_val );
|
||||
return LDAP_SUCCESS;
|
||||
} else if ( rc == 0 ) {
|
||||
Debug( LDAP_DEBUG_SYNC,
|
||||
"dn_callback : entries have identical CSN "
|
||||
"%s ours %s, new %s\n",
|
||||
rs->sr_entry->e_name.bv_val,
|
||||
old->a_vals[0].bv_val,
|
||||
new->a_vals[0].bv_val );
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user