]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/schema_init.c
slapi-plugin.h goes in include
[openldap] / servers / slapd / schema_init.c
index 5e41856b58be662ae11b99203aea83b7a4756192..2455a2a1f33bba4d788f8e469e405a268ba254df 100644 (file)
@@ -1,7 +1,7 @@
 /* schema_init.c - init builtin schema */
 /* $OpenLDAP$ */
 /*
 /* schema_init.c - init builtin schema */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -37,7 +37,7 @@
 /* recycled matching routines */
 #define bitStringMatch                                 octetStringMatch
 #define numericStringMatch                             caseIgnoreIA5Match
 /* recycled matching routines */
 #define bitStringMatch                                 octetStringMatch
 #define numericStringMatch                             caseIgnoreIA5Match
-#define objectIdentifierMatch                  caseIgnoreIA5Match
+#define objectIdentifierMatch                  octetStringMatch
 #define telephoneNumberMatch                   caseIgnoreIA5Match
 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
 #define generalizedTimeMatch                   caseIgnoreIA5Match
 #define telephoneNumberMatch                   caseIgnoreIA5Match
 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
 #define generalizedTimeMatch                   caseIgnoreIA5Match
@@ -137,8 +137,28 @@ octetStringMatch(
        return LDAP_SUCCESS;
 }
 
        return LDAP_SUCCESS;
 }
 
+static int
+octetStringOrderingMatch(
+       int *matchp,
+       slap_mask_t flags,
+       Syntax *syntax,
+       MatchingRule *mr,
+       struct berval *value,
+       void *assertedValue )
+{
+       ber_len_t v_len  = value->bv_len;
+       ber_len_t av_len = ((struct berval *) assertedValue)->bv_len;
+       int match = memcmp( value->bv_val,
+               ((struct berval *) assertedValue)->bv_val,
+               (v_len < av_len ? v_len : av_len) );
+       if( match == 0 )
+               match = v_len - av_len;
+       *matchp = match;
+       return LDAP_SUCCESS;
+}
+
 /* Index generation function */
 /* Index generation function */
-static int octetStringIndexer(
+int octetStringIndexer(
        slap_mask_t use,
        slap_mask_t flags,
        Syntax *syntax,
        slap_mask_t use,
        slap_mask_t flags,
        Syntax *syntax,
@@ -186,6 +206,7 @@ static int octetStringIndexer(
        }
 
        keys[i].bv_val = NULL;
        }
 
        keys[i].bv_val = NULL;
+       keys[i].bv_len = 0;
 
        *keysp = keys;
 
 
        *keysp = keys;
 
@@ -193,20 +214,20 @@ static int octetStringIndexer(
 }
 
 /* Index generation function */
 }
 
 /* Index generation function */
-static int octetStringFilter(
+int octetStringFilter(
        slap_mask_t use,
        slap_mask_t flags,
        Syntax *syntax,
        MatchingRule *mr,
        struct berval *prefix,
        slap_mask_t use,
        slap_mask_t flags,
        Syntax *syntax,
        MatchingRule *mr,
        struct berval *prefix,
-       void * assertValue,
+       void * assertedValue,
        BerVarray *keysp )
 {
        size_t slen, mlen;
        BerVarray keys;
        HASH_CONTEXT   HASHcontext;
        unsigned char   HASHdigest[HASH_BYTES];
        BerVarray *keysp )
 {
        size_t slen, mlen;
        BerVarray keys;
        HASH_CONTEXT   HASHcontext;
        unsigned char   HASHdigest[HASH_BYTES];
-       struct berval *value = (struct berval *) assertValue;
+       struct berval *value = (struct berval *) assertedValue;
        struct berval digest;
        digest.bv_val = HASHdigest;
        digest.bv_len = sizeof(HASHdigest);
        struct berval digest;
        digest.bv_val = HASHdigest;
        digest.bv_len = sizeof(HASHdigest);
@@ -231,6 +252,7 @@ static int octetStringFilter(
 
        ber_dupbv( keys, &digest );
        keys[1].bv_val = NULL;
 
        ber_dupbv( keys, &digest );
        keys[1].bv_val = NULL;
+       keys[1].bv_len = 0;
 
        *keysp = keys;
 
 
        *keysp = keys;
 
@@ -292,46 +314,6 @@ bitStringValidate(
        return LDAP_SUCCESS;
 }
 
        return LDAP_SUCCESS;
 }
 
-static int
-bitStringNormalize(
-       Syntax *syntax,
-       struct berval *val,
-       struct berval *normalized )
-{
-       /*
-        * A normalized bitString is has no extaneous (leading) zero bits.
-        * That is, '00010'B is normalized to '10'B
-        * However, as a special case, '0'B requires no normalization.
-        */
-       char *p;
-
-       /* start at the first bit */
-       p = &val->bv_val[1];
-
-       /* Find the first non-zero bit */
-       while ( *p == '0' ) p++;
-
-       if( *p == '\'' ) {
-               /* no non-zero bits */
-               ber_str2bv( "\'0\'B", sizeof("\'0\'B") - 1, 1, normalized );
-               goto done;
-       }
-
-       normalized->bv_val = ch_malloc( val->bv_len + 1 );
-
-       normalized->bv_val[0] = '\'';
-       normalized->bv_len = 1;
-
-       for( ; *p != '\0'; p++ ) {
-               normalized->bv_val[normalized->bv_len++] = *p;
-       }
-
-       normalized->bv_val[normalized->bv_len] = '\0';
-
-done:
-       return LDAP_SUCCESS;
-}
-
 static int
 nameUIDValidate(
        Syntax *syntax,
 static int
 nameUIDValidate(
        Syntax *syntax,
@@ -383,57 +365,44 @@ nameUIDNormalize(
 
        ber_dupbv( &out, val );
        if( out.bv_len != 0 ) {
 
        ber_dupbv( &out, val );
        if( out.bv_len != 0 ) {
-               struct berval uidin = { 0, NULL };
-               struct berval uidout = { 0, NULL };
+               struct berval uid = { 0, NULL };
 
                if( out.bv_val[out.bv_len-1] == 'B'
                        && out.bv_val[out.bv_len-2] == '\'' )
                {
                        /* assume presence of optional UID */
 
                if( out.bv_val[out.bv_len-1] == 'B'
                        && out.bv_val[out.bv_len-2] == '\'' )
                {
                        /* assume presence of optional UID */
-                       uidin.bv_val = strrchr( out.bv_val, '#' );
+                       uid.bv_val = strrchr( out.bv_val, '#' );
 
 
-                       if( uidin.bv_val == NULL ) {
+                       if( uid.bv_val == NULL ) {
                                free( out.bv_val );
                                return LDAP_INVALID_SYNTAX;
                        }
 
                                free( out.bv_val );
                                return LDAP_INVALID_SYNTAX;
                        }
 
-                       uidin.bv_len = out.bv_len - (uidin.bv_val - out.bv_val);
-                       out.bv_len -= uidin.bv_len--;
+                       uid.bv_len = out.bv_len - (uid.bv_val - out.bv_val);
+                       out.bv_len -= uid.bv_len--;
 
                        /* temporarily trim the UID */
 
                        /* temporarily trim the UID */
-                       *(uidin.bv_val++) = '\0';
-
-                       rc = bitStringNormalize( syntax, &uidin, &uidout );
-
-                       if( rc != LDAP_SUCCESS ) {
-                               free( out.bv_val );
-                               return LDAP_INVALID_SYNTAX;
-                       }
+                       *(uid.bv_val++) = '\0';
                }
 
                }
 
-#ifdef USE_DN_NORMALIZE
                rc = dnNormalize2( NULL, &out, normalized );
                rc = dnNormalize2( NULL, &out, normalized );
-#else
-               rc = dnPretty2( NULL, &out, normalized );
-#endif
 
                if( rc != LDAP_SUCCESS ) {
                        free( out.bv_val );
 
                if( rc != LDAP_SUCCESS ) {
                        free( out.bv_val );
-                       free( uidout.bv_val );
                        return LDAP_INVALID_SYNTAX;
                }
 
                        return LDAP_INVALID_SYNTAX;
                }
 
-               if( uidout.bv_len ) {
+               if( uid.bv_len ) {
                        normalized->bv_val = ch_realloc( normalized->bv_val,
                        normalized->bv_val = ch_realloc( normalized->bv_val,
-                               normalized->bv_len + uidout.bv_len + sizeof("#") );
+                               normalized->bv_len + uid.bv_len + sizeof("#") );
 
                        /* insert the separator */
                        normalized->bv_val[normalized->bv_len++] = '#';
 
                        /* append the UID */
                        AC_MEMCPY( &normalized->bv_val[normalized->bv_len],
 
                        /* insert the separator */
                        normalized->bv_val[normalized->bv_len++] = '#';
 
                        /* append the UID */
                        AC_MEMCPY( &normalized->bv_val[normalized->bv_len],
-                               uidout.bv_val, uidout.bv_len );
-                       normalized->bv_len += uidout.bv_len;
+                               uid.bv_val, uid.bv_len );
+                       normalized->bv_len += uid.bv_len;
 
                        /* terminate */
                        normalized->bv_val[normalized->bv_len] = '\0';
 
                        /* terminate */
                        normalized->bv_val[normalized->bv_len] = '\0';
@@ -511,7 +480,7 @@ Directory String -
   In later versions, more CHOICEs were added.  In all cases the string
   must be non-empty.
 
   In later versions, more CHOICEs were added.  In all cases the string
   must be non-empty.
 
-  In LDPAv3, a directory string is a UTF-8 encoded UCS string.
+  In LDAPv3, a directory string is a UTF-8 encoded UCS string.
 
   For matching, there are both case ignore and exact rules.  Both
   also require that "insignificant" spaces be ignored.
 
   For matching, there are both case ignore and exact rules.  Both
   also require that "insignificant" spaces be ignored.
@@ -703,7 +672,7 @@ UTF8SubstringsassertionNormalize(
        SubstringsAssertion *nsa;
        int i;
 
        SubstringsAssertion *nsa;
        int i;
 
-       nsa = (SubstringsAssertion *)ch_calloc( 1, sizeof(SubstringsAssertion) );
+       nsa = (SubstringsAssertion *)SLAP_CALLOC( 1, sizeof(SubstringsAssertion) );
        if( nsa == NULL ) {
                return NULL;
        }
        if( nsa == NULL ) {
                return NULL;
        }
@@ -720,7 +689,10 @@ UTF8SubstringsassertionNormalize(
                        /* empty */
                }
                nsa->sa_any = (struct berval *)
                        /* empty */
                }
                nsa->sa_any = (struct berval *)
-                       ch_malloc( (i + 1) * sizeof(struct berval) );
+                       SLAP_MALLOC( (i + 1) * sizeof(struct berval) );
+               if( nsa->sa_any == NULL ) {
+                               goto err;
+               }
 
                for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
                        UTF8bvnormalize( &sa->sa_any[i], &nsa->sa_any[i], 
 
                for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
                        UTF8bvnormalize( &sa->sa_any[i], &nsa->sa_any[i], 
@@ -929,7 +901,7 @@ approxFilter(
        Syntax *syntax,
        MatchingRule *mr,
        struct berval *prefix,
        Syntax *syntax,
        MatchingRule *mr,
        struct berval *prefix,
-       void * assertValue,
+       void * assertedValue,
        BerVarray *keysp )
 {
        char *c;
        BerVarray *keysp )
 {
        char *c;
@@ -938,7 +910,7 @@ approxFilter(
        BerVarray keys;
 
        /* Yes, this is necessary */
        BerVarray keys;
 
        /* Yes, this is necessary */
-       val = UTF8bvnormalize( ((struct berval *)assertValue),
+       val = UTF8bvnormalize( ((struct berval *)assertedValue),
                NULL, LDAP_UTF8_APPROX );
        if( val == NULL || val->bv_val == NULL ) {
                keys = (struct berval *)ch_malloc( sizeof(struct berval) );
                NULL, LDAP_UTF8_APPROX );
        if( val == NULL || val->bv_val == NULL ) {
                keys = (struct berval *)ch_malloc( sizeof(struct berval) );
@@ -1068,7 +1040,7 @@ approxFilter(
        Syntax *syntax,
        MatchingRule *mr,
        struct berval *prefix,
        Syntax *syntax,
        MatchingRule *mr,
        struct berval *prefix,
-       void * assertValue,
+       void * assertedValue,
        BerVarray *keysp )
 {
        BerVarray keys;
        BerVarray *keysp )
 {
        BerVarray keys;
@@ -1077,7 +1049,7 @@ approxFilter(
        keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 );
 
        /* Yes, this is necessary */
        keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 );
 
        /* Yes, this is necessary */
-       s = UTF8normalize( ((struct berval *)assertValue),
+       s = UTF8normalize( ((struct berval *)assertedValue),
                             UTF8_NOCASEFOLD );
        if( s == NULL ) {
                keys[0] = NULL;
                             UTF8_NOCASEFOLD );
        if( s == NULL ) {
                keys[0] = NULL;
@@ -1333,7 +1305,7 @@ static int caseExactIgnoreFilter(
        Syntax *syntax,
        MatchingRule *mr,
        struct berval *prefix,
        Syntax *syntax,
        MatchingRule *mr,
        struct berval *prefix,
-       void * assertValue,
+       void * assertedValue,
        BerVarray *keysp )
 {
        unsigned casefold;
        BerVarray *keysp )
 {
        unsigned casefold;
@@ -1353,7 +1325,7 @@ static int caseExactIgnoreFilter(
        casefold = ( mr != caseExactMatchingRule )
                ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
 
        casefold = ( mr != caseExactMatchingRule )
                ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
 
-       UTF8bvnormalize( (struct berval *) assertValue, &value, casefold );
+       UTF8bvnormalize( (struct berval *) assertedValue, &value, casefold );
        /* This usually happens if filter contains bad UTF8 */
        if( value.bv_val == NULL ) {
                keys = ch_malloc( sizeof( struct berval ) );
        /* This usually happens if filter contains bad UTF8 */
        if( value.bv_val == NULL ) {
                keys = ch_malloc( sizeof( struct berval ) );
@@ -1572,7 +1544,7 @@ static int caseExactIgnoreSubstringsFilter(
        Syntax *syntax,
        MatchingRule *mr,
        struct berval *prefix,
        Syntax *syntax,
        MatchingRule *mr,
        struct berval *prefix,
-       void * assertValue,
+       void * assertedValue,
        BerVarray *keysp )
 {
        SubstringsAssertion *sa;
        BerVarray *keysp )
 {
        SubstringsAssertion *sa;
@@ -1589,7 +1561,7 @@ static int caseExactIgnoreSubstringsFilter(
        casefold = ( mr != caseExactSubstringsMatchingRule )
                ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
 
        casefold = ( mr != caseExactSubstringsMatchingRule )
                ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
 
-       sa = UTF8SubstringsassertionNormalize( assertValue, casefold );
+       sa = UTF8SubstringsassertionNormalize( assertedValue, casefold );
        if( sa == NULL ) {
                *keysp = NULL;
                return LDAP_SUCCESS;
        if( sa == NULL ) {
                *keysp = NULL;
                return LDAP_SUCCESS;
@@ -2021,7 +1993,7 @@ static int integerFilter(
        Syntax *syntax,
        MatchingRule *mr,
        struct berval *prefix,
        Syntax *syntax,
        MatchingRule *mr,
        struct berval *prefix,
-       void * assertValue,
+       void * assertedValue,
        BerVarray *keysp )
 {
        size_t slen, mlen;
        BerVarray *keysp )
 {
        size_t slen, mlen;
@@ -2036,7 +2008,7 @@ static int integerFilter(
        slen = syntax->ssyn_oidlen;
        mlen = mr->smr_oidlen;
 
        slen = syntax->ssyn_oidlen;
        mlen = mr->smr_oidlen;
 
-       integerNormalize( syntax, assertValue, &norm );
+       integerNormalize( syntax, assertedValue, &norm );
 
        keys = ch_malloc( sizeof( struct berval ) * 2 );
 
 
        keys = ch_malloc( sizeof( struct berval ) * 2 );
 
@@ -2415,7 +2387,7 @@ static int caseExactIA5Filter(
        Syntax *syntax,
        MatchingRule *mr,
        struct berval *prefix,
        Syntax *syntax,
        MatchingRule *mr,
        struct berval *prefix,
-       void * assertValue,
+       void * assertedValue,
        BerVarray *keysp )
 {
        size_t slen, mlen;
        BerVarray *keysp )
 {
        size_t slen, mlen;
@@ -2430,7 +2402,7 @@ static int caseExactIA5Filter(
        slen = syntax->ssyn_oidlen;
        mlen = mr->smr_oidlen;
 
        slen = syntax->ssyn_oidlen;
        mlen = mr->smr_oidlen;
 
-       value = (struct berval *) assertValue;
+       value = (struct berval *) assertedValue;
 
        keys = ch_malloc( sizeof( struct berval ) * 2 );
 
 
        keys = ch_malloc( sizeof( struct berval ) * 2 );
 
@@ -2621,10 +2593,10 @@ static int caseExactIA5SubstringsFilter(
        Syntax *syntax,
        MatchingRule *mr,
        struct berval *prefix,
        Syntax *syntax,
        MatchingRule *mr,
        struct berval *prefix,
-       void * assertValue,
+       void * assertedValue,
        BerVarray *keysp )
 {
        BerVarray *keysp )
 {
-       SubstringsAssertion *sa = assertValue;
+       SubstringsAssertion *sa = assertedValue;
        char pre;
        ber_len_t nkeys = 0;
        size_t slen, mlen, klen;
        char pre;
        ber_len_t nkeys = 0;
        size_t slen, mlen, klen;
@@ -3002,7 +2974,7 @@ static int caseIgnoreIA5Filter(
        Syntax *syntax,
        MatchingRule *mr,
        struct berval *prefix,
        Syntax *syntax,
        MatchingRule *mr,
        struct berval *prefix,
-       void * assertValue,
+       void * assertedValue,
        BerVarray *keysp )
 {
        size_t slen, mlen;
        BerVarray *keysp )
 {
        size_t slen, mlen;
@@ -3017,7 +2989,7 @@ static int caseIgnoreIA5Filter(
        slen = syntax->ssyn_oidlen;
        mlen = mr->smr_oidlen;
 
        slen = syntax->ssyn_oidlen;
        mlen = mr->smr_oidlen;
 
-       ber_dupbv( &value, (struct berval *) assertValue );
+       ber_dupbv( &value, (struct berval *) assertedValue );
        ldap_pvt_str2lower( value.bv_val );
 
        keys = ch_malloc( sizeof( struct berval ) * 2 );
        ldap_pvt_str2lower( value.bv_val );
 
        keys = ch_malloc( sizeof( struct berval ) * 2 );
@@ -3216,10 +3188,10 @@ static int caseIgnoreIA5SubstringsFilter(
        Syntax *syntax,
        MatchingRule *mr,
        struct berval *prefix,
        Syntax *syntax,
        MatchingRule *mr,
        struct berval *prefix,
-       void * assertValue,
+       void * assertedValue,
        BerVarray *keysp )
 {
        BerVarray *keysp )
 {
-       SubstringsAssertion *sa = assertValue;
+       SubstringsAssertion *sa = assertedValue;
        char pre;
        ber_len_t nkeys = 0;
        size_t slen, mlen, klen;
        char pre;
        ber_len_t nkeys = 0;
        size_t slen, mlen, klen;
@@ -3447,7 +3419,7 @@ objectIdentifierFirstComponentMatch(
        int rc = LDAP_SUCCESS;
        int match;
        struct berval *asserted = (struct berval *) assertedValue;
        int rc = LDAP_SUCCESS;
        int match;
        struct berval *asserted = (struct berval *) assertedValue;
-       ber_len_t i;
+       ber_len_t i, j;
        struct berval oid;
 
        if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
        struct berval oid;
 
        if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
@@ -3461,8 +3433,8 @@ objectIdentifierFirstComponentMatch(
 
        /* grab next word */
        oid.bv_val = &value->bv_val[i];
 
        /* grab next word */
        oid.bv_val = &value->bv_val[i];
-       oid.bv_len = value->bv_len - i;
-       for( i=1; ASCII_SPACE(value->bv_val[i]) && i < oid.bv_len; i++ ) {
+       j = value->bv_len - i;
+       for( i=0; !ASCII_SPACE(oid.bv_val[i]) && i < j; i++ ) {
                /* empty */
        }
        oid.bv_len = i;
                /* empty */
        }
        oid.bv_len = i;
@@ -3518,7 +3490,6 @@ objectIdentifierFirstComponentMatch(
                match, value->bv_val, asserted->bv_val );
 #endif
 
                match, value->bv_val, asserted->bv_val );
 #endif
 
-
        if( rc == LDAP_SUCCESS ) *matchp = match;
        return rc;
 }
        if( rc == LDAP_SUCCESS ) *matchp = match;
        return rc;
 }
@@ -3536,14 +3507,18 @@ integerBitAndMatch(
 
        /* safe to assume integers are NUL terminated? */
        lValue = strtoul(value->bv_val, NULL, 10);
 
        /* safe to assume integers are NUL terminated? */
        lValue = strtoul(value->bv_val, NULL, 10);
-       if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
+       if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
                return LDAP_CONSTRAINT_VIOLATION;
                return LDAP_CONSTRAINT_VIOLATION;
+       }
 
        lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
 
        lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
-       if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
+       if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
+               && errno == ERANGE )
+       {
                return LDAP_CONSTRAINT_VIOLATION;
                return LDAP_CONSTRAINT_VIOLATION;
+       }
 
 
-       *matchp = (lValue & lAssertedValue);
+       *matchp = (lValue & lAssertedValue) ? 0 : 1;
        return LDAP_SUCCESS;
 }
 
        return LDAP_SUCCESS;
 }
 
@@ -3560,21 +3535,24 @@ integerBitOrMatch(
 
        /* safe to assume integers are NUL terminated? */
        lValue = strtoul(value->bv_val, NULL, 10);
 
        /* safe to assume integers are NUL terminated? */
        lValue = strtoul(value->bv_val, NULL, 10);
-       if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
+       if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
                return LDAP_CONSTRAINT_VIOLATION;
                return LDAP_CONSTRAINT_VIOLATION;
+       }
 
        lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
 
        lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
-       if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
+       if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
+               && errno == ERANGE )
+       {
                return LDAP_CONSTRAINT_VIOLATION;
                return LDAP_CONSTRAINT_VIOLATION;
+       }
 
 
-       *matchp = (lValue | lAssertedValue);
+       *matchp = (lValue | lAssertedValue) ? 0 : -1;
        return LDAP_SUCCESS;
 }
 
 #ifdef HAVE_TLS
 #include <openssl/x509.h>
 #include <openssl/err.h>
        return LDAP_SUCCESS;
 }
 
 #ifdef HAVE_TLS
 #include <openssl/x509.h>
 #include <openssl/err.h>
-char digit[] = "0123456789";
 
 /*
  * Next function returns a string representation of a ASN1_INTEGER.
 
 /*
  * Next function returns a string representation of a ASN1_INTEGER.
@@ -3586,6 +3564,7 @@ asn1_integer2str(ASN1_INTEGER *a, struct berval *bv)
 {
        char buf[256];
        char *p;
 {
        char buf[256];
        char *p;
+       static char digit[] = "0123456789";
   
        /* We work backwards, make it fill from the end of buf */
        p = buf + sizeof(buf) - 1;
   
        /* We work backwards, make it fill from the end of buf */
        p = buf + sizeof(buf) - 1;
@@ -3628,8 +3607,8 @@ asn1_integer2str(ASN1_INTEGER *a, struct berval *bv)
                                return NULL;
                        }
                        *--p = digit[carry];
                                return NULL;
                        }
                        *--p = digit[carry];
-                       if (copy[base] == 0)
-                               base++;
+
+                       if (copy[base] == 0) base++;
                }
                free(copy);
        }
                }
                free(copy);
        }
@@ -3673,7 +3652,9 @@ certificateExactConvert(
                X509_free(xcert);
                return LDAP_INVALID_SYNTAX;
        }
                X509_free(xcert);
                return LDAP_INVALID_SYNTAX;
        }
-       if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn ) != LDAP_SUCCESS ) {
+       if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn )
+               != LDAP_SUCCESS )
+       {
                X509_free(xcert);
                ber_memfree(serial.bv_val);
                return LDAP_INVALID_SYNTAX;
                X509_free(xcert);
                ber_memfree(serial.bv_val);
                return LDAP_INVALID_SYNTAX;
@@ -3721,33 +3702,34 @@ serial_and_issuer_parse(
 
        begin = assertion->bv_val;
        end = assertion->bv_val+assertion->bv_len-1;
 
        begin = assertion->bv_val;
        end = assertion->bv_val+assertion->bv_len-1;
-       for (p=begin; p<=end && *p != '$'; p++)
-               ;
-       if ( p > end )
-               return LDAP_INVALID_SYNTAX;
+       for (p=begin; p<=end && *p != '$'; p++) /* empty */ ;
+       if ( p > end ) return LDAP_INVALID_SYNTAX;
 
 
-       /* p now points at the $ sign, now use begin and end to delimit the
-          serial number */
-       while (ASCII_SPACE(*begin))
-               begin++;
+       /* p now points at the $ sign, now use
+        * begin and end to delimit the serial number
+        */
+       while (ASCII_SPACE(*begin)) begin++;
        end = p-1;
        end = p-1;
-       while (ASCII_SPACE(*end))
-               end--;
+       while (ASCII_SPACE(*end)) end--;
+
+       if( end <= begin ) return LDAP_INVALID_SYNTAX;
 
        bv.bv_len = end-begin+1;
        bv.bv_val = begin;
        ber_dupbv(serial, &bv);
 
        /* now extract the issuer, remember p was at the dollar sign */
 
        bv.bv_len = end-begin+1;
        bv.bv_val = begin;
        ber_dupbv(serial, &bv);
 
        /* now extract the issuer, remember p was at the dollar sign */
-       if ( issuer_dn ) {
-               begin = p+1;
-               end = assertion->bv_val+assertion->bv_len-1;
-               while (ASCII_SPACE(*begin))
-                       begin++;
-               /* should we trim spaces at the end too? is it safe always? */
+       begin = p+1;
+       end = assertion->bv_val+assertion->bv_len-1;
+       while (ASCII_SPACE(*begin)) begin++;
+       /* should we trim spaces at the end too? is it safe always? no, no */
+
+       if( end <= begin ) return LDAP_INVALID_SYNTAX;
 
 
+       if ( issuer_dn ) {
                bv.bv_len = end-begin+1;
                bv.bv_val = begin;
                bv.bv_len = end-begin+1;
                bv.bv_val = begin;
+
                dnNormalize2( NULL, &bv, issuer_dn );
        }
 
                dnNormalize2( NULL, &bv, issuer_dn );
        }
 
@@ -3791,8 +3773,7 @@ certificateExactMatch(
        X509_free(xcert);
 
        serial_and_issuer_parse(assertedValue,
        X509_free(xcert);
 
        serial_and_issuer_parse(assertedValue,
-                               &asserted_serial,
-                               &asserted_issuer_dn);
+               &asserted_serial, &asserted_issuer_dn);
 
        ret = integerMatch(
                matchp,
 
        ret = integerMatch(
                matchp,
@@ -3888,8 +3869,7 @@ static int certificateExactIndexer(
                asn1_integer2str(xcert->cert_info->serialNumber, &serial);
                X509_free(xcert);
                integerNormalize( slap_schema.si_syn_integer,
                asn1_integer2str(xcert->cert_info->serialNumber, &serial);
                X509_free(xcert);
                integerNormalize( slap_schema.si_syn_integer,
-                                 &serial,
-                                 &keys[i] );
+                       &serial, &keys[i] );
                ber_memfree(serial.bv_val);
 #ifdef NEW_LOGGING
                LDAP_LOG( CONFIG, ENTRY, 
                ber_memfree(serial.bv_val);
 #ifdef NEW_LOGGING
                LDAP_LOG( CONFIG, ENTRY, 
@@ -3915,15 +3895,15 @@ static int certificateExactFilter(
        Syntax *syntax,
        MatchingRule *mr,
        struct berval *prefix,
        Syntax *syntax,
        MatchingRule *mr,
        struct berval *prefix,
-       void * assertValue,
+       void * assertedValue,
        BerVarray *keysp )
 {
        BerVarray keys;
        struct berval asserted_serial;
        BerVarray *keysp )
 {
        BerVarray keys;
        struct berval asserted_serial;
+       int ret;
 
 
-       serial_and_issuer_parse(assertValue,
-                               &asserted_serial,
-                               NULL);
+       ret = serial_and_issuer_parse( assertedValue, &asserted_serial, NULL );
+       if( ret != LDAP_SUCCESS ) return ret;
 
        keys = ch_malloc( sizeof( struct berval ) * 2 );
        integerNormalize( syntax, &asserted_serial, &keys[0] );
 
        keys = ch_malloc( sizeof( struct berval ) * 2 );
        integerNormalize( syntax, &asserted_serial, &keys[0] );
@@ -4266,19 +4246,10 @@ bootParameterValidate(
        return LDAP_SUCCESS;
 }
 
        return LDAP_SUCCESS;
 }
 
-static struct syntax_defs_rec {
-       char *sd_desc;
 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
-       int sd_flags;
-       slap_syntax_validate_func *sd_validate;
-       slap_syntax_transform_func *sd_normalize;
-       slap_syntax_transform_func *sd_pretty;
-#ifdef SLAPD_BINARY_CONVERSION
-       slap_syntax_transform_func *sd_ber2str;
-       slap_syntax_transform_func *sd_str2ber;
-#endif
-} syntax_defs[] = {
+
+static slap_syntax_defs_rec syntax_defs[] = {
        {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
                X_BINARY X_NOT_H_R ")",
                SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
                X_BINARY X_NOT_H_R ")",
                SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
@@ -4293,7 +4264,7 @@ static struct syntax_defs_rec {
                X_NOT_H_R ")",
                SLAP_SYNTAX_BER, berValidate, NULL, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
                X_NOT_H_R ")",
                SLAP_SYNTAX_BER, berValidate, NULL, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
-               0, bitStringValidate, bitStringNormalize, NULL },
+               0, bitStringValidate, NULL, NULL },
        {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
                0, booleanValidate, NULL, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
        {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
                0, booleanValidate, NULL, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
@@ -4411,7 +4382,7 @@ static struct syntax_defs_rec {
         * Chadwick in private mail.
         */
        {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
         * Chadwick in private mail.
         */
        {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
-               0, NULL, NULL, NULL},
+               0, UTF8StringValidate, NULL, NULL},
 #endif
 
        /* OpenLDAP Experimental Syntaxes */
 #endif
 
        /* OpenLDAP Experimental Syntaxes */
@@ -4434,11 +4405,37 @@ static struct syntax_defs_rec {
        {NULL, 0, NULL, NULL, NULL}
 };
 
        {NULL, 0, NULL, NULL, NULL}
 };
 
+#ifdef HAVE_TLS
+char *certificateExactMatchSyntaxes[] = {
+       "1.3.6.1.4.1.1466.115.121.1.8" /* certificate */,
+       NULL
+};
+#endif
+char *directoryStringSyntaxes[] = {
+       "1.3.6.1.4.1.1466.115.121.1.44" /* printableString */,
+       NULL
+};
+char *integerFirstComponentMatchSyntaxes[] = {
+       "1.3.6.1.4.1.1466.115.121.1.27" /* INTEGER */,
+       "1.3.6.1.4.1.1466.115.121.1.17" /* ditStructureRuleDescription */,
+       NULL
+};
+char *objectIdentifierFirstComponentMatchSyntaxes[] = {
+       "1.3.6.1.4.1.1466.115.121.1.38" /* OID */,
+       "1.3.6.1.4.1.1466.115.121.1.3"  /* attributeTypeDescription */,
+       "1.3.6.1.4.1.1466.115.121.1.16" /* ditContentRuleDescription */,
+       "1.3.6.1.4.1.1466.115.121.1.54" /* ldapSyntaxDescription */,
+       "1.3.6.1.4.1.1466.115.121.1.30" /* matchingRuleDescription */,
+       "1.3.6.1.4.1.1466.115.121.1.31" /* matchingRuleUseDescription */,
+       "1.3.6.1.4.1.1466.115.121.1.35" /* nameFormDescription */,
+       "1.3.6.1.4.1.1466.115.121.1.37" /* objectClassDescription */,
+       NULL
+};
+
 /*
  * Other matching rules in X.520 that we do not use (yet):
  *
  * 2.5.13.9            numericStringOrderingMatch
 /*
  * Other matching rules in X.520 that we do not use (yet):
  *
  * 2.5.13.9            numericStringOrderingMatch
- * 2.5.13.18   octetStringOrderingMatch
  * 2.5.13.19   octetStringSubstringsMatch
  * 2.5.13.25   uTCTimeMatch
  * 2.5.13.26   uTCTimeOrderingMatch
  * 2.5.13.19   octetStringSubstringsMatch
  * 2.5.13.25   uTCTimeMatch
  * 2.5.13.26   uTCTimeOrderingMatch
@@ -4456,24 +4453,14 @@ static struct syntax_defs_rec {
  * 2.5.13.43   readerAndKeyIDMatch
  * 2.5.13.44   attributeIntegrityMatch
  */
  * 2.5.13.43   readerAndKeyIDMatch
  * 2.5.13.44   attributeIntegrityMatch
  */
-static struct mrule_defs_rec {
-       char *                                          mrd_desc;
-       slap_mask_t                                     mrd_usage;
-       slap_mr_convert_func *          mrd_convert;
-       slap_mr_normalize_func *        mrd_normalize;
-       slap_mr_match_func *            mrd_match;
-       slap_mr_indexer_func *          mrd_indexer;
-       slap_mr_filter_func *           mrd_filter;
-
-       char *                                          mrd_associated;
-} mrule_defs[] = {
+static slap_mrule_defs_rec mrule_defs[] = {
        /*
         * EQUALITY matching rules must be listed after associated APPROX
         * matching rules.  So, we list all APPROX matching rules first.
         */
        {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
        /*
         * EQUALITY matching rules must be listed after associated APPROX
         * matching rules.  So, we list all APPROX matching rules first.
         */
        {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
-               SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
+               SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
                NULL, NULL,
                directoryStringApproxMatch,
                directoryStringApproxIndexer, 
                NULL, NULL,
                directoryStringApproxMatch,
                directoryStringApproxIndexer, 
@@ -4482,7 +4469,7 @@ static struct mrule_defs_rec {
 
        {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
 
        {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
-               SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
+               SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
                NULL, NULL,
                IA5StringApproxMatch,
                IA5StringApproxIndexer, 
                NULL, NULL,
                IA5StringApproxMatch,
                IA5StringApproxIndexer, 
@@ -4495,14 +4482,14 @@ static struct mrule_defs_rec {
        
        {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
        
        {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
-               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
                NULL, NULL,
                objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
                NULL},
 
        {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
                NULL, NULL,
                objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
                NULL},
 
        {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
-               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
                NULL, NULL,
                dnMatch, dnIndexer, dnFilter,
                NULL},
                NULL, NULL,
                dnMatch, dnIndexer, dnFilter,
                NULL},
@@ -4510,20 +4497,21 @@ static struct mrule_defs_rec {
        {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
                SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
        {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
                SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
+                       directoryStringSyntaxes,
                NULL, NULL,
                caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
                directoryStringApproxMatchOID },
 
        {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
                NULL, NULL,
                caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
                directoryStringApproxMatchOID },
 
        {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
-               SLAP_MR_ORDERING,
+               SLAP_MR_ORDERING, directoryStringSyntaxes,
                NULL, NULL,
                caseIgnoreOrderingMatch, NULL, NULL,
                NULL},
 
        {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
                NULL, NULL,
                caseIgnoreOrderingMatch, NULL, NULL,
                NULL},
 
        {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
-               SLAP_MR_SUBSTR | SLAP_MR_EXT,
+               SLAP_MR_SUBSTR, NULL,
                NULL, NULL,
                caseExactIgnoreSubstringsMatch,
                caseExactIgnoreSubstringsIndexer,
                NULL, NULL,
                caseExactIgnoreSubstringsMatch,
                caseExactIgnoreSubstringsIndexer,
@@ -4532,21 +4520,21 @@ static struct mrule_defs_rec {
 
        {"( 2.5.13.5 NAME 'caseExactMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
 
        {"( 2.5.13.5 NAME 'caseExactMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
-               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes,
                NULL, NULL,
                caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
                directoryStringApproxMatchOID },
 
        {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
                NULL, NULL,
                caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
                directoryStringApproxMatchOID },
 
        {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
-               SLAP_MR_ORDERING,
+               SLAP_MR_ORDERING, directoryStringSyntaxes,
                NULL, NULL,
                caseExactOrderingMatch, NULL, NULL,
                NULL},
 
        {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
                NULL, NULL,
                caseExactOrderingMatch, NULL, NULL,
                NULL},
 
        {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
-               SLAP_MR_SUBSTR | SLAP_MR_EXT,
+               SLAP_MR_SUBSTR, directoryStringSyntaxes,
                NULL, NULL,
                caseExactIgnoreSubstringsMatch,
                caseExactIgnoreSubstringsIndexer,
                NULL, NULL,
                caseExactIgnoreSubstringsMatch,
                caseExactIgnoreSubstringsIndexer,
@@ -4555,7 +4543,7 @@ static struct mrule_defs_rec {
 
        {"( 2.5.13.8 NAME 'numericStringMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
 
        {"( 2.5.13.8 NAME 'numericStringMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
-               SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
+               SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
                NULL, NULL,
                caseIgnoreIA5Match,
                caseIgnoreIA5Indexer,
                NULL, NULL,
                caseIgnoreIA5Match,
                caseIgnoreIA5Indexer,
@@ -4564,7 +4552,7 @@ static struct mrule_defs_rec {
 
        {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
 
        {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
-               SLAP_MR_SUBSTR | SLAP_MR_EXT,
+               SLAP_MR_SUBSTR, NULL,
                NULL, NULL,
                caseIgnoreIA5SubstringsMatch,
                caseIgnoreIA5SubstringsIndexer,
                NULL, NULL,
                caseIgnoreIA5SubstringsMatch,
                caseIgnoreIA5SubstringsIndexer,
@@ -4573,56 +4561,63 @@ static struct mrule_defs_rec {
 
        {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
 
        {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
-               SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
+               SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
                NULL, NULL,
                caseIgnoreListMatch, NULL, NULL,
                NULL},
 
        {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
                NULL, NULL,
                caseIgnoreListMatch, NULL, NULL,
                NULL},
 
        {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
-               SLAP_MR_SUBSTR | SLAP_MR_EXT,
+               SLAP_MR_SUBSTR, NULL,
                NULL, NULL,
                caseIgnoreListSubstringsMatch, NULL, NULL,
                NULL},
 
        {"( 2.5.13.13 NAME 'booleanMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
                NULL, NULL,
                caseIgnoreListSubstringsMatch, NULL, NULL,
                NULL},
 
        {"( 2.5.13.13 NAME 'booleanMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
-               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
                NULL, NULL,
                booleanMatch, NULL, NULL,
                NULL},
 
        {"( 2.5.13.14 NAME 'integerMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
                NULL, NULL,
                booleanMatch, NULL, NULL,
                NULL},
 
        {"( 2.5.13.14 NAME 'integerMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
-               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
                NULL, NULL,
                integerMatch, integerIndexer, integerFilter,
                NULL},
 
        {"( 2.5.13.15 NAME 'integerOrderingMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
                NULL, NULL,
                integerMatch, integerIndexer, integerFilter,
                NULL},
 
        {"( 2.5.13.15 NAME 'integerOrderingMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
-               SLAP_MR_ORDERING,
+               SLAP_MR_ORDERING, NULL,
                NULL, NULL,
                integerOrderingMatch, NULL, NULL,
                NULL},
 
        {"( 2.5.13.16 NAME 'bitStringMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
                NULL, NULL,
                integerOrderingMatch, NULL, NULL,
                NULL},
 
        {"( 2.5.13.16 NAME 'bitStringMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
-               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
                NULL, NULL,
                bitStringMatch, bitStringIndexer, bitStringFilter,
                NULL},
 
        {"( 2.5.13.17 NAME 'octetStringMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
                NULL, NULL,
                bitStringMatch, bitStringIndexer, bitStringFilter,
                NULL},
 
        {"( 2.5.13.17 NAME 'octetStringMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
-               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
                NULL, NULL,
                octetStringMatch, octetStringIndexer, octetStringFilter,
                NULL},
 
                NULL, NULL,
                octetStringMatch, octetStringIndexer, octetStringFilter,
                NULL},
 
+       {"( 2.5.13.18 NAME 'octetStringOrderingMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
+               SLAP_MR_ORDERING, NULL,
+               NULL, NULL,
+               octetStringOrderingMatch, NULL, NULL,
+               NULL},
+
        {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
        {"( 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,
+               SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
                NULL, NULL,
                telephoneNumberMatch,
                telephoneNumberIndexer,
                NULL, NULL,
                telephoneNumberMatch,
                telephoneNumberIndexer,
@@ -4631,7 +4626,7 @@ static struct mrule_defs_rec {
 
        {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
 
        {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
-               SLAP_MR_SUBSTR | SLAP_MR_EXT,
+               SLAP_MR_SUBSTR, NULL,
                NULL, NULL,
                telephoneNumberSubstringsMatch,
                telephoneNumberSubstringsIndexer,
                NULL, NULL,
                telephoneNumberSubstringsMatch,
                telephoneNumberSubstringsIndexer,
@@ -4640,42 +4635,42 @@ static struct mrule_defs_rec {
 
        {"( 2.5.13.22 NAME 'presentationAddressMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
 
        {"( 2.5.13.22 NAME 'presentationAddressMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
-               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
                NULL, NULL,
                NULL, NULL, NULL,
                NULL},
 
        {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
                NULL, NULL,
                NULL, NULL, NULL,
                NULL},
 
        {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
-               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
                NULL, NULL,
                uniqueMemberMatch, NULL, NULL,
                NULL},
 
        {"( 2.5.13.24 NAME 'protocolInformationMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
                NULL, NULL,
                uniqueMemberMatch, NULL, NULL,
                NULL},
 
        {"( 2.5.13.24 NAME 'protocolInformationMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
-               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
                NULL, NULL,
                protocolInformationMatch, NULL, NULL,
                NULL},
 
        {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
                NULL, NULL,
                protocolInformationMatch, NULL, NULL,
                NULL},
 
        {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
-               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
                NULL, NULL,
                generalizedTimeMatch, NULL, NULL,
                NULL},
 
        {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
                NULL, NULL,
                generalizedTimeMatch, NULL, NULL,
                NULL},
 
        {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
-               SLAP_MR_ORDERING,
+               SLAP_MR_ORDERING, NULL,
                NULL, NULL,
                generalizedTimeOrderingMatch, NULL, NULL,
                NULL},
 
        {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
                NULL, NULL,
                generalizedTimeOrderingMatch, NULL, NULL,
                NULL},
 
        {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
-               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               SLAP_MR_EQUALITY | SLAP_MR_EXT, integerFirstComponentMatchSyntaxes,
                NULL, NULL,
                integerFirstComponentMatch, NULL, NULL,
                NULL},
                NULL, NULL,
                integerFirstComponentMatch, NULL, NULL,
                NULL},
@@ -4683,6 +4678,7 @@ static struct mrule_defs_rec {
        {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
                SLAP_MR_EQUALITY | SLAP_MR_EXT,
        {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
                SLAP_MR_EQUALITY | SLAP_MR_EXT,
+                       objectIdentifierFirstComponentMatchSyntaxes,
                NULL, NULL,
                objectIdentifierFirstComponentMatch, NULL, NULL,
                NULL},
                NULL, NULL,
                objectIdentifierFirstComponentMatch, NULL, NULL,
                NULL},
@@ -4690,7 +4686,7 @@ static struct mrule_defs_rec {
 #ifdef HAVE_TLS
        {"( 2.5.13.34 NAME 'certificateExactMatch' "
                "SYNTAX 1.2.826.0.1.3344810.7.1 )",
 #ifdef HAVE_TLS
        {"( 2.5.13.34 NAME 'certificateExactMatch' "
                "SYNTAX 1.2.826.0.1.3344810.7.1 )",
-               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes,
                certificateExactConvert, NULL,
                certificateExactMatch,
                certificateExactIndexer, certificateExactFilter,
                certificateExactConvert, NULL,
                certificateExactMatch,
                certificateExactIndexer, certificateExactFilter,
@@ -4699,21 +4695,21 @@ static struct mrule_defs_rec {
 
        {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
 
        {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
-               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
                NULL, NULL,
                caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter,
                IA5StringApproxMatchOID },
 
        {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
                NULL, NULL,
                caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter,
                IA5StringApproxMatchOID },
 
        {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
-               SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
+               SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
                NULL, NULL,
                caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
                IA5StringApproxMatchOID },
 
        {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
                NULL, NULL,
                caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
                IA5StringApproxMatchOID },
 
        {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
-               SLAP_MR_SUBSTR,
+               SLAP_MR_SUBSTR, NULL,
                NULL, NULL,
                caseIgnoreIA5SubstringsMatch,
                caseIgnoreIA5SubstringsIndexer,
                NULL, NULL,
                caseIgnoreIA5SubstringsMatch,
                caseIgnoreIA5SubstringsIndexer,
@@ -4722,7 +4718,7 @@ static struct mrule_defs_rec {
 
        {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
 
        {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
-               SLAP_MR_SUBSTR,
+               SLAP_MR_SUBSTR, NULL,
                NULL, NULL,
                caseExactIA5SubstringsMatch,
                caseExactIA5SubstringsIndexer,
                NULL, NULL,
                caseExactIA5SubstringsMatch,
                caseExactIA5SubstringsIndexer,
@@ -4733,7 +4729,7 @@ static struct mrule_defs_rec {
        /* needs updating */
        {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
        /* needs updating */
        {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
-               SLAP_MR_EQUALITY,
+               SLAP_MR_EQUALITY, NULL,
                NULL, NULL,
                authPasswordMatch, NULL, NULL,
                NULL},
                NULL, NULL,
                authPasswordMatch, NULL, NULL,
                NULL},
@@ -4742,7 +4738,7 @@ static struct mrule_defs_rec {
 #ifdef SLAPD_ACI_ENABLED
        {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
                "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
 #ifdef SLAPD_ACI_ENABLED
        {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
                "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
-               SLAP_MR_EQUALITY,
+               SLAP_MR_EQUALITY, NULL,
                NULL, NULL,
                OpenLDAPaciMatch, NULL, NULL,
                NULL},
                NULL, NULL,
                OpenLDAPaciMatch, NULL, NULL,
                NULL},
@@ -4750,19 +4746,21 @@ static struct mrule_defs_rec {
 
        {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
 
        {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
-               SLAP_MR_EXT,
+               SLAP_MR_EXT, NULL,
                NULL, NULL,
                integerBitAndMatch, NULL, NULL,
                NULL},
 
        {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
                NULL, NULL,
                integerBitAndMatch, NULL, NULL,
                NULL},
 
        {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
-               SLAP_MR_EXT,
+               SLAP_MR_EXT, NULL,
                NULL, NULL,
                integerBitOrMatch, NULL, NULL,
                NULL},
 
                NULL, NULL,
                integerBitOrMatch, NULL, NULL,
                NULL},
 
-       {NULL, SLAP_MR_NONE, NULL, NULL, NULL, NULL}
+       {NULL, SLAP_MR_NONE, NULL,
+               NULL, NULL, NULL, NULL, NULL,
+               NULL }
 };
 
 int
 };
 
 int
@@ -4775,17 +4773,7 @@ slap_schema_init( void )
        assert( schema_init_done == 0 );
 
        for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
        assert( schema_init_done == 0 );
 
        for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
-               res = register_syntax( syntax_defs[i].sd_desc,
-                       syntax_defs[i].sd_flags,
-                       syntax_defs[i].sd_validate,
-                       syntax_defs[i].sd_normalize,
-                       syntax_defs[i].sd_pretty
-#ifdef SLAPD_BINARY_CONVERSION
-                       ,
-                       syntax_defs[i].sd_ber2str,
-                       syntax_defs[i].sd_str2ber
-#endif
-               );
+               res = register_syntax( &syntax_defs[i] );
 
                if ( res ) {
                        fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
 
                if ( res ) {
                        fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
@@ -4795,22 +4783,16 @@ slap_schema_init( void )
        }
 
        for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
        }
 
        for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
-               if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) {
+               if( mrule_defs[i].mrd_usage == SLAP_MR_NONE &&
+                       mrule_defs[i].mrd_compat_syntaxes == NULL )
+               {
                        fprintf( stderr,
                                "slap_schema_init: Ingoring unusable matching rule %s\n",
                                 mrule_defs[i].mrd_desc );
                        continue;
                }
 
                        fprintf( stderr,
                                "slap_schema_init: Ingoring unusable matching rule %s\n",
                                 mrule_defs[i].mrd_desc );
                        continue;
                }
 
-               res = register_matching_rule(
-                       mrule_defs[i].mrd_desc,
-                       mrule_defs[i].mrd_usage,
-                       mrule_defs[i].mrd_convert,
-                       mrule_defs[i].mrd_normalize,
-                       mrule_defs[i].mrd_match,
-                       mrule_defs[i].mrd_indexer,
-                       mrule_defs[i].mrd_filter,
-                       mrule_defs[i].mrd_associated );
+               res = register_matching_rule( &mrule_defs[i] );
 
                if ( res ) {
                        fprintf( stderr,
 
                if ( res ) {
                        fprintf( stderr,
@@ -4838,5 +4820,6 @@ schema_destroy( void )
        for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ )
                *mr_ptr[i].mr = NULL;
        mr_destroy();
        for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ )
                *mr_ptr[i].mr = NULL;
        mr_destroy();
+       mru_destroy();
        syn_destroy();
 }
        syn_destroy();
 }