/* TO BE DELETED */
#define SLAP_MR_DN_FOLD (0)
+#define SLAP_MR_ASSOCIATED(mr, with) \
+ ((mr) == (with) || (mr)->smr_associated == (with))
+
#define xUTF8StringNormalize NULL
#define xIA5StringNormalize NULL
#define xtelephoneNumberNormalize NULL
#define xintegerNormalize NULL
#define xnumericStringNormalize NULL
#define xnameUIDNormalize NULL
+#define xdnNormalize NULL
+
+/* (new) normalization routines */
+#define caseExactIA5Normalize IA5StringNormalize
+#define caseIgnoreIA5Normalize IA5StringNormalize
+#define caseExactNormalize UTF8StringNormalize
+#define caseIgnoreNormalize UTF8StringNormalize
+
+#define integerNormalize NULL
+#define integerFirstComponentNormalize NULL
+#define numericStringNormalize NULL
+#define objectIdentifierNormalize NULL
+#define objectIdentifierFirstComponentNormalize NULL
+#define generalizedTimeNormalize NULL
+#define bitStringNormalize NULL
+#define telephoneNumberNormalize NULL
+#define distinguishedNameNormalize dnNormalize
#define distinguishedNameMatch dnMatch
#define distinguishedNameIndexer octetStringIndexer
#define distinguishedNameFilter octetStringFilter
-#define uniqueMemberMatch dnMatch
+#define uniqueMemberMatch dnMatch
#define objectIdentifierMatch octetStringMatch
#define objectIdentifierIndexer octetStringIndexer
#define objectIdentifierFilter octetStringFilter
+#define OpenLDAPaciMatch NULL
+
#define bitStringMatch octetStringMatch
#define bitStringIndexer octetStringIndexer
#define bitStringFilter octetStringFilter
#define caseIgnoreIndexer octetStringIndexer
#define caseIgnoreFilter octetStringFilter
-#define caseIgnoreSubstringsMatch NULL
-#define caseIgnoreSubstringsIndexer NULL
-#define caseIgnoreSubstringsFilter NULL
+#define caseIgnoreSubstringsMatch octetStringSubstringsMatch
+#define caseIgnoreSubstringsIndexer octetStringSubstringsIndexer
+#define caseIgnoreSubstringsFilter octetStringSubstringsFilter
#define caseExactMatch octetStringMatch
#define caseExactOrderingMatch octetStringOrderingMatch
#define caseExactIndexer octetStringIndexer
#define caseExactFilter octetStringFilter
-#define caseExactSubstringsMatch NULL
-#define caseExactSubstringsIndexer NULL
-#define caseExactSubstringsFilter NULL
+#define caseExactSubstringsMatch octetStringSubstringsMatch
+#define caseExactSubstringsIndexer octetStringSubstringsIndexer
+#define caseExactSubstringsFilter octetStringSubstringsFilter
#define caseExactIA5Match octetStringMatch
#define caseExactIA5Indexer octetStringIndexer
#define caseExactIA5Filter octetStringFilter
-#define caseExactIA5SubstringsMatch NULL
-#define caseExactIA5SubstringsIndexer NULL
-#define caseExactIA5SubstringsFilter NULL
+#define caseExactIA5SubstringsMatch octetStringSubstringsMatch
+#define caseExactIA5SubstringsIndexer octetStringSubstringsIndexer
+#define caseExactIA5SubstringsFilter octetStringSubstringsFilter
#define caseIgnoreIA5Match octetStringMatch
#define caseIgnoreIA5Indexer octetStringIndexer
/* validatation routines */
#define berValidate blobValidate
-/* (new) normalization routines */
-#define caseExactNormalize NULL
-#define caseExactIA5Normalize NULL
-#define caseIgnoreNormalize NULL
-#define caseIgnoreIA5Normalize NULL
-#define distinguishedNameNormalize NULL
-#define integerNormalize NULL
-#define integerFirstComponentNormalize NULL
-#define numericStringNormalize NULL
-#define objectIdentifierNormalize NULL
-#define objectIdentifierFirstComponentNormalize NULL
-#define generalizedTimeNormalize NULL
-#define uniqueMemberNormalize NULL
-#define bitStringNormalize NULL
-#define telephoneNumberNormalize NULL
-
/* approx matching rules */
#ifdef SLAP_NVALUES
#define directoryStringApproxMatchOID NULL
#ifndef SLAP_NVALUES
+#define xdnNormalize dnNormalize
+
+/* (new) normalization routines */
+#define caseExactNormalize NULL
+#define caseExactIA5Normalize NULL
+#define caseIgnoreNormalize NULL
+#define caseIgnoreIA5Normalize NULL
+#define distinguishedNameNormalize NULL
+#define integerNormalize NULL
+#define integerFirstComponentNormalize NULL
+#define numericStringNormalize NULL
+#define objectIdentifierNormalize NULL
+#define objectIdentifierFirstComponentNormalize NULL
+#define generalizedTimeNormalize NULL
+#define uniqueMemberNormalize NULL
+#define bitStringNormalize NULL
+#define telephoneNumberNormalize NULL
+
+
/* matching routines */
#define bitStringMatch octetStringMatch
#define bitStringIndexer octetStringIndexer
#define objectIdentifierIndexer caseIgnoreIA5Indexer
#define objectIdentifierFilter caseIgnoreIA5Filter
+#define octetStringSubstringsMatch NULL
+#define OpenLDAPaciMatch NULL
+
#define generalizedTimeMatch caseIgnoreIA5Match
#define generalizedTimeOrderingMatch caseIgnoreIA5Match
return rc;
}
-#ifndef SLAP_NVALUES
-
+#ifdef SLAP_NVALUES
+static int
+uniqueMemberNormalize(
+ slap_mask_t usage,
+ Syntax *syntax,
+ MatchingRule *mr,
+ struct berval *val,
+ struct berval *normalized )
+#else
static int
xnameUIDNormalize(
Syntax *syntax,
struct berval *val,
struct berval *normalized )
+#endif
{
struct berval out;
int rc;
return LDAP_SUCCESS;
}
-#endif
/*
* Handling boolean syntax and matching is quite rigid.
* A more flexible approach would be to allow a variety
comment attempts to detail how slapd(8) treats them.
Summary:
- StringSyntax X.500 LDAP Matching
+ StringSyntax X.500 LDAP Matching/Comments
DirectoryString CHOICE UTF8 i/e + ignore insignificant spaces
PrintableString subset subset i/e + ignore insignificant spaces
+ PrintableString subset subset i/e + ignore insignificant spaces
NumericString subset subset ignore all spaces
IA5String ASCII ASCII i/e + ignore insignificant spaces
TeletexString T.61 T.61 i/e + ignore insignificant spaces
must be non-empty.
In LDAPv3, a directory string is a UTF-8 encoded UCS string.
+ A directory string cannot be zero length.
For matching, there are both case ignore and exact rules. Both
also require that "insignificant" spaces be ignored.
int len;
unsigned char *u = in->bv_val;
- if( !in->bv_len ) return LDAP_INVALID_SYNTAX;
+ if( in->bv_len == 0 && syntax == slap_schema.si_syn_directoryString ) {
+ /* directory strings cannot be empty */
+ return LDAP_INVALID_SYNTAX;
+ }
for( count = in->bv_len; count > 0; count-=len, u+=len ) {
/* get the length indicated by the first byte */
if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
}
- if( count != 0 ) return LDAP_INVALID_SYNTAX;
+ if( count != 0 ) {
+ return LDAP_INVALID_SYNTAX;
+ }
return LDAP_SUCCESS;
}
-#ifndef SLAP_NVALUES
+#ifdef SLAP_NVALUES
+static int
+UTF8StringNormalize(
+ slap_mask_t use,
+ Syntax *syntax,
+ MatchingRule *mr,
+ struct berval *val,
+ struct berval *normalized )
+{
+ struct berval tmp, nvalue;
+ int flags;
+ int i, wasspace;
+
+ if( val->bv_val == NULL ) {
+ /* assume we're dealing with a syntax (e.g., UTF8String)
+ * which allows empty strings
+ */
+ normalized->bv_len = 0;
+ normalized->bv_val = NULL;
+ return LDAP_SUCCESS;
+ }
+
+ flags = SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactMatch )
+ ? LDAP_UTF8_NOCASEFOLD : LDAP_UTF8_CASEFOLD;
+ flags |= ( use & SLAP_MR_EQUALITY_APPROX == SLAP_MR_EQUALITY_APPROX )
+ ? LDAP_UTF8_APPROX : 0;
+
+ val = UTF8bvnormalize( val, &tmp, flags );
+ if( val == NULL ) {
+ return LDAP_OTHER;
+ }
+
+ /* collapse spaces (in place) */
+ nvalue.bv_len = 0;
+ nvalue.bv_val = tmp.bv_val;
+
+ wasspace=1; /* trim leading spaces */
+ for( i=0; i<tmp.bv_len; i++) {
+ if ( ASCII_SPACE( tmp.bv_val[i] )) {
+ if( wasspace++ == 0 ) {
+ /* trim repeated spaces */
+ nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
+ }
+ } else {
+ wasspace = 0;
+ nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
+ }
+ }
+
+ if( nvalue.bv_len ) {
+ if( wasspace ) {
+ /* last character was a space, trim it */
+ --nvalue.bv_len;
+ }
+ nvalue.bv_val[nvalue.bv_len] = '\0';
+
+ } else {
+ /* string of all spaces is treated as one space */
+ nvalue.bv_val[0] = ' ';
+ nvalue.bv_val[1] = '\0';
+ nvalue.bv_len = 1;
+ }
+
+ *normalized = nvalue;
+ return LDAP_SUCCESS;
+}
+#else
static int
xUTF8StringNormalize(
*keysp = keys;
return LDAP_SUCCESS;
}
+#endif
/* Substrings Index generation function */
-static int caseExactIgnoreSubstringsIndexer(
- slap_mask_t use,
+static int
+#ifdef SLAP_NVALUES
+octetStringSubstringsIndexer
+#else
+caseExactIgnoreSubstringsIndexer
+#endif
+ ( slap_mask_t use,
slap_mask_t flags,
Syntax *syntax,
MatchingRule *mr,
BerVarray values,
BerVarray *keysp )
{
- unsigned casefold, wasspace;
ber_len_t i, j, nkeys;
size_t slen, mlen;
BerVarray keys;
+#ifndef SLAP_NVALUES
BerVarray tvalues, nvalues;
+ unsigned casefold, wasspace;
+#endif
HASH_CONTEXT HASHcontext;
unsigned char HASHdigest[HASH_BYTES];
digest.bv_val = HASHdigest;
digest.bv_len = sizeof(HASHdigest);
- nkeys=0;
-
+#ifndef SLAP_NVALUES
for( i=0; values[i].bv_val != NULL; i++ ) {
/* empty - just count them */
}
tvalues[i].bv_val = NULL;
nvalues[i].bv_val = NULL;
values = nvalues;
+#endif
+
+ nkeys=0;
for( i=0; values[i].bv_val != NULL; i++ ) {
/* count number of indices to generate */
if( nkeys == 0 ) {
/* no keys to generate */
*keysp = NULL;
+#ifndef SLAP_NVALUES
ber_bvarray_free( tvalues );
ch_free( nvalues );
+#endif
return LDAP_SUCCESS;
}
*keysp = NULL;
}
+#ifndef SLAP_NVALUES
ber_bvarray_free( tvalues );
ch_free( nvalues );
+#endif
return LDAP_SUCCESS;
}
-static int caseExactIgnoreSubstringsFilter(
- slap_mask_t use,
+static int
+#ifdef SLAP_NVALUES
+octetStringSubstringsFilter
+#else
+caseExactIgnoreSubstringsFilter
+#endif
+ ( slap_mask_t use,
slap_mask_t flags,
Syntax *syntax,
MatchingRule *mr,
struct berval *value;
struct berval digest;
+#ifndef SLAP_NVALUES
casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
*keysp = NULL;
return LDAP_SUCCESS;
}
+#else
+ sa = (SubstringsAssertion *) assertedValue;
+#endif
if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
return LDAP_SUCCESS;
}
+#ifndef SLAP_NVALUES
+
static int
caseIgnoreMatch(
int *matchp,
return LDAP_SUCCESS;
}
-#ifndef SLAP_NVALUES
-
+#ifdef SLAP_NVALUES
+static int
+IA5StringNormalize(
+ slap_mask_t use,
+ Syntax *syntax,
+ MatchingRule *mr,
+ struct berval *val,
+ struct berval *normalized )
+#else
static int
xIA5StringNormalize(
Syntax *syntax,
struct berval *val,
struct berval *normalized )
+#endif
{
char *p, *q;
+#ifdef SLAP_NVALUES
+ int casefold = !SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactIA5Match);
+#endif
assert( val->bv_len );
while ( ASCII_SPACE( *p ) ) {
p++;
}
+
+#ifdef SLAP_NVALUES
+ } else if ( casefold ) {
+ /* Most IA5 rules require casefolding */
+ *q++ = TOLOWER(*p++);
+#endif
+
} else {
*q++ = *p++;
}
return LDAP_SUCCESS;
}
+#ifndef SLAP_NVALUES
+
static int
caseExactIA5Match(
int *matchp,
}
static int
-caseExactIA5SubstringsMatch(
+caseExactIA5SubstringsMatch
+#else
+static int
+octetStringSubstringsMatch
+#endif
+(
int *matchp,
slap_mask_t flags,
Syntax *syntax,
goto done;
}
- match = strncmp( sub->sa_initial.bv_val, left.bv_val,
+ match = memcmp( sub->sa_initial.bv_val, left.bv_val,
sub->sa_initial.bv_len );
if( match != 0 ) {
goto done;
}
- match = strncmp( sub->sa_final.bv_val,
+ match = memcmp( sub->sa_final.bv_val,
&left.bv_val[left.bv_len - sub->sa_final.bv_len],
sub->sa_final.bv_len );
continue;
}
- p = strchr( left.bv_val, *sub->sa_any[i].bv_val );
+ p = memchr( left.bv_val, *sub->sa_any[i].bv_val, left.bv_len );
if( p == NULL ) {
match = 1;
goto done;
}
- match = strncmp( left.bv_val,
+ match = memcmp( left.bv_val,
sub->sa_any[i].bv_val,
sub->sa_any[i].bv_len );
return LDAP_SUCCESS;
}
+#ifndef SLAP_NVALUES
+
/* Index generation function */
static int caseExactIA5Indexer(
slap_mask_t use,
{"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
0, countryStringValidate, xIA5StringNormalize, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
- 0, dnValidate, dnNormalize2, dnPretty2},
+ 0, dnValidate, xdnNormalize, dnPretty2},
{"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
0, NULL, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
* Other matching rules in X.520 that we do not use (yet):
*
* 2.5.13.9 numericStringOrderingMatch
- * 2.5.13.19 octetStringSubstringsMatch
* 2.5.13.25 uTCTimeMatch
* 2.5.13.26 uTCTimeOrderingMatch
* 2.5.13.31 directoryStringFirstComponentMatch
octetStringOrderingMatch, NULL, NULL,
NULL},
+ {"( 2.5.13.19 NAME 'octetStringSubstringsMatch' "
+ "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
+ SLAP_MR_SUBSTR, NULL,
+ NULL, NULL,
+ octetStringSubstringsMatch, NULL, NULL,
+ NULL},
+
{"( 2.5.13.20 NAME 'telephoneNumberMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
SLAP_MR_ORDERING, NULL,
NULL,
- generalizedTimeOrderingMatch, generalizedTimeOrderingMatch,
+ generalizedTimeNormalize, generalizedTimeOrderingMatch,
NULL, NULL,
NULL},