]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/schema_init.c
add logs; fix bug in group/dn selection logic
[openldap] / servers / slapd / schema_init.c
index 0ce1a4d3c99476d4831dd5f0d5c965f7263924d2..499935beed43b870e1e0d94b28d0b5824958dd32 100644 (file)
@@ -1,8 +1,17 @@
 /* schema_init.c - init builtin schema */
 /* $OpenLDAP$ */
-/*
- * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 1998-2004 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
  */
 
 #include "portable.h"
@@ -88,7 +97,7 @@ sequenceValidate(
 static int certificateValidate( Syntax *syntax, struct berval *in )
 {
        X509 *xcert=NULL;
-       unsigned char *p = in->bv_val;
+       unsigned char *p = (unsigned char *)in->bv_val;
  
        xcert = d2i_X509(NULL, &p, in->bv_len);
        if ( !xcert ) return LDAP_INVALID_SYNTAX;
@@ -158,7 +167,7 @@ int octetStringIndexer(
        HASH_CONTEXT HASHcontext;
        unsigned char HASHdigest[HASH_BYTES];
        struct berval digest;
-       digest.bv_val = HASHdigest;
+       digest.bv_val = (char *)HASHdigest;
        digest.bv_len = sizeof(HASHdigest);
 
        for( i=0; values[i].bv_val != NULL; i++ ) {
@@ -177,14 +186,15 @@ int octetStringIndexer(
                HASH_Init( &HASHcontext );
                if( prefix != NULL && prefix->bv_len > 0 ) {
                        HASH_Update( &HASHcontext,
-                               prefix->bv_val, prefix->bv_len );
+                               (unsigned char *)prefix->bv_val,
+                               prefix->bv_len );
                }
                HASH_Update( &HASHcontext,
-                       syntax->ssyn_oid, slen );
+                       (unsigned char *)syntax->ssyn_oid, slen );
                HASH_Update( &HASHcontext,
-                       mr->smr_oid, mlen );
+                       (unsigned char *)mr->smr_oid, mlen );
                HASH_Update( &HASHcontext,
-                       values[i].bv_val, values[i].bv_len );
+                       (unsigned char *)values[i].bv_val, values[i].bv_len );
                HASH_Final( HASHdigest, &HASHcontext );
 
                ber_dupbv_x( &keys[i], &digest, ctx );
@@ -215,7 +225,7 @@ int octetStringFilter(
        unsigned char HASHdigest[HASH_BYTES];
        struct berval *value = (struct berval *) assertedValue;
        struct berval digest;
-       digest.bv_val = HASHdigest;
+       digest.bv_val = (char *)HASHdigest;
        digest.bv_len = sizeof(HASHdigest);
 
        slen = syntax->ssyn_oidlen;
@@ -226,14 +236,14 @@ int octetStringFilter(
        HASH_Init( &HASHcontext );
        if( prefix != NULL && prefix->bv_len > 0 ) {
                HASH_Update( &HASHcontext,
-                       prefix->bv_val, prefix->bv_len );
+                       (unsigned char *)prefix->bv_val, prefix->bv_len );
        }
        HASH_Update( &HASHcontext,
-               syntax->ssyn_oid, slen );
+               (unsigned char *)syntax->ssyn_oid, slen );
        HASH_Update( &HASHcontext,
-               mr->smr_oid, mlen );
+               (unsigned char *)mr->smr_oid, mlen );
        HASH_Update( &HASHcontext,
-               value->bv_val, value->bv_len );
+               (unsigned char *)value->bv_val, value->bv_len );
        HASH_Final( HASHdigest, &HASHcontext );
 
        ber_dupbv_x( keys, &digest, ctx );
@@ -388,7 +398,7 @@ octetStringSubstringsIndexer(
        HASH_CONTEXT HASHcontext;
        unsigned char HASHdigest[HASH_BYTES];
        struct berval digest;
-       digest.bv_val = HASHdigest;
+       digest.bv_val = (char *)HASHdigest;
        digest.bv_len = sizeof(HASHdigest);
 
        nkeys=0;
@@ -451,17 +461,17 @@ octetStringSubstringsIndexer(
                                HASH_Init( &HASHcontext );
                                if( prefix != NULL && prefix->bv_len > 0 ) {
                                        HASH_Update( &HASHcontext,
-                                               prefix->bv_val, prefix->bv_len );
+                                               (unsigned char *)prefix->bv_val, prefix->bv_len );
                                }
 
                                HASH_Update( &HASHcontext,
-                                       &pre, sizeof( pre ) );
+                                       (unsigned char *)&pre, sizeof( pre ) );
                                HASH_Update( &HASHcontext,
-                                       syntax->ssyn_oid, slen );
+                                       (unsigned char *)syntax->ssyn_oid, slen );
                                HASH_Update( &HASHcontext,
-                                       mr->smr_oid, mlen );
+                                       (unsigned char *)mr->smr_oid, mlen );
                                HASH_Update( &HASHcontext,
-                                       &values[i].bv_val[j],
+                                       (unsigned char *)&values[i].bv_val[j],
                                        SLAP_INDEX_SUBSTR_MAXLEN );
                                HASH_Final( HASHdigest, &HASHcontext );
 
@@ -480,16 +490,16 @@ octetStringSubstringsIndexer(
                                HASH_Init( &HASHcontext );
                                if( prefix != NULL && prefix->bv_len > 0 ) {
                                        HASH_Update( &HASHcontext,
-                                               prefix->bv_val, prefix->bv_len );
+                                               (unsigned char *)prefix->bv_val, prefix->bv_len );
                                }
                                HASH_Update( &HASHcontext,
-                                       &pre, sizeof( pre ) );
+                                       (unsigned char *)&pre, sizeof( pre ) );
                                HASH_Update( &HASHcontext,
-                                       syntax->ssyn_oid, slen );
+                                       (unsigned char *)syntax->ssyn_oid, slen );
                                HASH_Update( &HASHcontext,
-                                       mr->smr_oid, mlen );
+                                       (unsigned char *)mr->smr_oid, mlen );
                                HASH_Update( &HASHcontext,
-                                       values[i].bv_val, j );
+                                       (unsigned char *)values[i].bv_val, j );
                                HASH_Final( HASHdigest, &HASHcontext );
 
                                ber_dupbv_x( &keys[nkeys++], &digest, ctx );
@@ -500,16 +510,16 @@ octetStringSubstringsIndexer(
                                HASH_Init( &HASHcontext );
                                if( prefix != NULL && prefix->bv_len > 0 ) {
                                        HASH_Update( &HASHcontext,
-                                               prefix->bv_val, prefix->bv_len );
+                                               (unsigned char *)prefix->bv_val, prefix->bv_len );
                                }
                                HASH_Update( &HASHcontext,
-                                       &pre, sizeof( pre ) );
+                                       (unsigned char *)&pre, sizeof( pre ) );
                                HASH_Update( &HASHcontext,
-                                       syntax->ssyn_oid, slen );
+                                       (unsigned char *)syntax->ssyn_oid, slen );
                                HASH_Update( &HASHcontext,
-                                       mr->smr_oid, mlen );
+                                       (unsigned char *)mr->smr_oid, mlen );
                                HASH_Update( &HASHcontext,
-                                       &values[i].bv_val[values[i].bv_len-j], j );
+                                       (unsigned char *)&values[i].bv_val[values[i].bv_len-j], j );
                                HASH_Final( HASHdigest, &HASHcontext );
 
                                ber_dupbv_x( &keys[nkeys++], &digest, ctx );
@@ -581,7 +591,7 @@ octetStringSubstringsFilter (
                return LDAP_SUCCESS;
        }
 
-       digest.bv_val = HASHdigest;
+       digest.bv_val = (char *)HASHdigest;
        digest.bv_len = sizeof(HASHdigest);
 
        slen = syntax->ssyn_oidlen;
@@ -602,16 +612,16 @@ octetStringSubstringsFilter (
                HASH_Init( &HASHcontext );
                if( prefix != NULL && prefix->bv_len > 0 ) {
                        HASH_Update( &HASHcontext,
-                               prefix->bv_val, prefix->bv_len );
+                               (unsigned char *)prefix->bv_val, prefix->bv_len );
                }
                HASH_Update( &HASHcontext,
-                       &pre, sizeof( pre ) );
+                       (unsigned char *)&pre, sizeof( pre ) );
                HASH_Update( &HASHcontext,
-                       syntax->ssyn_oid, slen );
+                       (unsigned char *)syntax->ssyn_oid, slen );
                HASH_Update( &HASHcontext,
-                       mr->smr_oid, mlen );
+                       (unsigned char *)mr->smr_oid, mlen );
                HASH_Update( &HASHcontext,
-                       value->bv_val, klen );
+                       (unsigned char *)value->bv_val, klen );
                HASH_Final( HASHdigest, &HASHcontext );
 
                ber_dupbv_x( &keys[nkeys++], &digest, ctx );
@@ -636,16 +646,16 @@ octetStringSubstringsFilter (
                                HASH_Init( &HASHcontext );
                                if( prefix != NULL && prefix->bv_len > 0 ) {
                                        HASH_Update( &HASHcontext,
-                                               prefix->bv_val, prefix->bv_len );
+                                               (unsigned char *)prefix->bv_val, prefix->bv_len );
                                }
                                HASH_Update( &HASHcontext,
-                                       &pre, sizeof( pre ) );
+                                       (unsigned char *)&pre, sizeof( pre ) );
                                HASH_Update( &HASHcontext,
-                                       syntax->ssyn_oid, slen );
+                                       (unsigned char *)syntax->ssyn_oid, slen );
                                HASH_Update( &HASHcontext,
-                                       mr->smr_oid, mlen );
+                                       (unsigned char *)mr->smr_oid, mlen );
                                HASH_Update( &HASHcontext,
-                                       &value->bv_val[j], klen ); 
+                                       (unsigned char *)&value->bv_val[j], klen ); 
                                HASH_Final( HASHdigest, &HASHcontext );
 
                                ber_dupbv_x( &keys[nkeys++], &digest, ctx );
@@ -665,16 +675,16 @@ octetStringSubstringsFilter (
                HASH_Init( &HASHcontext );
                if( prefix != NULL && prefix->bv_len > 0 ) {
                        HASH_Update( &HASHcontext,
-                               prefix->bv_val, prefix->bv_len );
+                               (unsigned char *)prefix->bv_val, prefix->bv_len );
                }
                HASH_Update( &HASHcontext,
-                       &pre, sizeof( pre ) );
+                       (unsigned char *)&pre, sizeof( pre ) );
                HASH_Update( &HASHcontext,
-                       syntax->ssyn_oid, slen );
+                       (unsigned char *)syntax->ssyn_oid, slen );
                HASH_Update( &HASHcontext,
-                       mr->smr_oid, mlen );
+                       (unsigned char *)mr->smr_oid, mlen );
                HASH_Update( &HASHcontext,
-                       &value->bv_val[value->bv_len-klen], klen );
+                       (unsigned char *)&value->bv_val[value->bv_len-klen], klen );
                HASH_Final( HASHdigest, &HASHcontext );
 
                ber_dupbv_x( &keys[nkeys++], &digest, ctx );
@@ -794,7 +804,7 @@ nameUIDPretty(
        } else {
                int rc;
                struct berval dnval = *val;
-               struct berval uidval = { 0, NULL };
+               struct berval uidval = BER_BVNULL;
 
                if( val->bv_val[val->bv_len-1] == 'B'
                        && val->bv_val[val->bv_len-2] == '\'' )
@@ -861,9 +871,11 @@ uniqueMemberNormalize(
        struct berval out;
        int rc;
 
+       assert( SLAP_MR_IS_VALUE_OF_SYNTAX( usage ));
+
        ber_dupbv( &out, val );
        if( out.bv_len != 0 ) {
-               struct berval uid = { 0, NULL };
+               struct berval uid = BER_BVNULL;
 
                if( out.bv_val[out.bv_len-1] == 'B'
                        && out.bv_val[out.bv_len-2] == '\'' )
@@ -923,10 +935,10 @@ uniqueMemberMatch(
 {
        int match;
        struct berval *asserted = (struct berval *) assertedValue;
-       struct berval assertedDN = { 0, NULL };
-       struct berval assertedUID = { 0, NULL };
-       struct berval valueDN = { 0, NULL };
-       struct berval valueUID = { 0, NULL };
+       struct berval assertedDN = BER_BVNULL;
+       struct berval assertedUID = BER_BVNULL;
+       struct berval valueDN = BER_BVNULL;
+       struct berval valueUID = BER_BVNULL;
 
        if( asserted->bv_len != 0 ) {
                assertedDN = *asserted;
@@ -1105,7 +1117,7 @@ UTF8StringValidate(
 {
        ber_len_t count;
        int len;
-       unsigned char *u = in->bv_val;
+       unsigned char *u = (unsigned char *)in->bv_val;
 
        if( in->bv_len == 0 && syntax == slap_schema.si_syn_directoryString ) {
                /* directory strings cannot be empty */
@@ -1147,7 +1159,7 @@ UTF8StringValidate(
 
                /* make sure len corresponds with the offset
                        to the next character */
-               if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
+               if( LDAP_UTF8_OFFSET( (char *)u ) != len ) return LDAP_INVALID_SYNTAX;
        }
 
        if( count != 0 ) {
@@ -1170,6 +1182,8 @@ UTF8StringNormalize(
        int flags;
        int i, wasspace;
 
+       assert( SLAP_MR_IS_VALUE_OF_SYNTAX( use ));
+
        if( val->bv_val == NULL ) {
                /* assume we're dealing with a syntax (e.g., UTF8String)
                 * which allows empty strings
@@ -1358,7 +1372,7 @@ approxIndexer(
        BerVarray keys=NULL;
 
        for( j=0; values[j].bv_val != NULL; j++ ) {
-               struct berval val = { 0, NULL };
+               struct berval val = BER_BVNULL;
                /* Yes, this is necessary */
                UTF8bvnormalize( &values[j], &val, LDAP_UTF8_APPROX, NULL );
                assert( val.bv_val != NULL );
@@ -1463,6 +1477,8 @@ telephoneNumberNormalize(
 {
        char *p, *q;
 
+       assert( SLAP_MR_IS_VALUE_OF_SYNTAX( usage ));
+
        /* validator should have refused an empty string */
        assert( val->bv_len );
 
@@ -1708,10 +1724,12 @@ IA5StringNormalize(
        void *ctx )
 {
        char *p, *q;
-       int casefold = SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactIA5Match);
+       int casefold = !SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactIA5Match);
 
        assert( val->bv_len );
 
+       assert( SLAP_MR_IS_VALUE_OF_SYNTAX( use ));
+
        p = val->bv_val;
 
        /* Ignore initial whitespace */
@@ -1762,6 +1780,86 @@ IA5StringNormalize(
        return LDAP_SUCCESS;
 }
 
+static int
+UUIDValidate(
+       Syntax *syntax,
+       struct berval *in )
+{
+       int i;
+       if( in->bv_len != 36 ) {
+               assert(0);
+               return LDAP_INVALID_SYNTAX;
+       }
+
+       for( i=0; i<36; i++ ) {
+               switch(i) {
+                       case 8:
+                       case 13:
+                       case 18:
+                       case 23:
+                               if( in->bv_val[i] != '-' ) {
+                                       return LDAP_INVALID_SYNTAX;
+                               }
+                               break;
+                       default:
+                               if( !ASCII_HEX( in->bv_val[i]) ) {
+                                       return LDAP_INVALID_SYNTAX;
+                               }
+               }
+       }
+       
+       return LDAP_SUCCESS;
+}
+
+static int
+UUIDNormalize(
+       slap_mask_t usage,
+       Syntax *syntax,
+       MatchingRule *mr,
+       struct berval *val,
+       struct berval *normalized,
+       void *ctx )
+{
+       unsigned char octet = '\0';
+       int i;
+       int j;
+       normalized->bv_len = 16;
+       normalized->bv_val = sl_malloc( normalized->bv_len+1, ctx );
+
+       for( i=0, j=0; i<36; i++ ) {
+               unsigned char nibble;
+               if( val->bv_val[i] == '-' ) {
+                       continue;
+
+               } else if( ASCII_DIGIT( val->bv_val[i] ) ) {
+                       nibble = val->bv_val[i] - '0';
+
+               } else if( ASCII_HEXLOWER( val->bv_val[i] ) ) {
+                       nibble = val->bv_val[i] - ('a'-10);
+
+               } else if( ASCII_HEXUPPER( val->bv_val[i] ) ) {
+                       nibble = val->bv_val[i] - ('A'-10);
+
+               } else {
+                       sl_free( normalized->bv_val, ctx );
+                       return LDAP_INVALID_SYNTAX;
+               }
+
+               if( j & 1 ) {
+                       octet |= nibble;
+                       normalized->bv_val[j>>1] = octet;
+               } else {
+                       octet = nibble << 4;
+               }
+               j++;
+       }
+
+       normalized->bv_val[normalized->bv_len] = 0;
+       return LDAP_SUCCESS;
+}
+
+
+
 static int
 numericStringValidate(
        Syntax *syntax,
@@ -2112,19 +2210,20 @@ certificateExactNormalize(
        unsigned char *p;
        char *serial = NULL;
        ber_len_t seriallen;
-       struct berval issuer_dn = { 0, NULL };
+       struct berval issuer_dn = BER_BVNULL;
        X509_NAME *name = NULL;
        ASN1_INTEGER *sn = NULL;
        X509 *xcert = NULL;
 
        if( val->bv_len == 0 ) goto done;
 
-       if( val->bv_val[0] != LBER_SEQUENCE ) {
-               /* assume serialNumberAndIssuer */
-               return serialNumberAndIssuerNormalize(0,NULL,NULL,val,normalized,NULL);
+       if( SLAP_MR_IS_VALUE_OF_ASSERTION_SYNTAX(usage) ) {
+               return serialNumberAndIssuerNormalize(0,NULL,NULL,val,normalized,ctx);
        }
 
-       p = val->bv_val;
+       assert( SLAP_MR_IS_VALUE_OF_ATTRIBUTE_SYNTAX(usage) );
+
+       p = (unsigned char *)val->bv_val;
        xcert = d2i_X509( NULL, &p, val->bv_len);
        if( xcert == NULL ) goto done;
 
@@ -2140,7 +2239,8 @@ certificateExactNormalize(
        if( rc != LDAP_SUCCESS ) goto done;
 
        normalized->bv_len = seriallen + issuer_dn.bv_len + 1;
-       p = normalized->bv_val = ch_malloc(normalized->bv_len+1);
+       normalized->bv_val = ch_malloc(normalized->bv_len+1);
+       p = (unsigned char *)normalized->bv_val;
        AC_MEMCPY(p, serial, seriallen);
        p += seriallen;
        *p++ = '$';
@@ -2457,6 +2557,139 @@ generalizedTimeOrderingMatch(
        return LDAP_SUCCESS;
 }
 
+static int
+deliveryMethodValidate(
+       Syntax *syntax,
+       struct berval *val )
+{
+#undef LENOF
+#define LENOF(s) (sizeof(s)-1)
+       struct berval tmp = *val;
+       /*
+     * DeliveryMethod = pdm *( WSP DOLLAR WSP DeliveryMethod )
+        *      pdm = "any" / "mhs" / "physical" / "telex" / "teletex" /
+        *              "g3fax" / "g4fax" / "ia5" / "videotex" / "telephone"
+        */
+again:
+       if( tmp.bv_len < 3 ) return LDAP_INVALID_SYNTAX;
+
+       switch( tmp.bv_val[0] ) {
+       case 'a':
+       case 'A':
+               if(( tmp.bv_len >= LENOF("any") ) &&
+                       ( strncasecmp(tmp.bv_val, "any", LENOF("any")) == 0 ))
+               {
+                       tmp.bv_len -= LENOF("any");
+                       tmp.bv_val += LENOF("any");
+                       break;
+               }
+               return LDAP_INVALID_SYNTAX;
+
+       case 'm':
+       case 'M':
+               if(( tmp.bv_len >= LENOF("mhs") ) &&
+                       ( strncasecmp(tmp.bv_val, "mhs", LENOF("mhs")) == 0 ))
+               {
+                       tmp.bv_len -= LENOF("mhs");
+                       tmp.bv_val += LENOF("mhs");
+                       break;
+               }
+               return LDAP_INVALID_SYNTAX;
+
+       case 'p':
+       case 'P':
+               if(( tmp.bv_len >= LENOF("physical") ) &&
+                       ( strncasecmp(tmp.bv_val, "physical", LENOF("physical")) == 0 ))
+               {
+                       tmp.bv_len -= LENOF("physical");
+                       tmp.bv_val += LENOF("physical");
+                       break;
+               }
+               return LDAP_INVALID_SYNTAX;
+
+       case 't':
+       case 'T': /* telex or teletex or telephone */
+               if(( tmp.bv_len >= LENOF("telex") ) &&
+                       ( strncasecmp(tmp.bv_val, "telex", LENOF("telex")) == 0 ))
+               {
+                       tmp.bv_len -= LENOF("telex");
+                       tmp.bv_val += LENOF("telex");
+                       break;
+               }
+               if(( tmp.bv_len >= LENOF("teletex") ) &&
+                       ( strncasecmp(tmp.bv_val, "teletex", LENOF("teletex")) == 0 ))
+               {
+                       tmp.bv_len -= LENOF("teletex");
+                       tmp.bv_val += LENOF("teletex");
+                       break;
+               }
+               if(( tmp.bv_len >= LENOF("telephone") ) &&
+                       ( strncasecmp(tmp.bv_val, "telephone", LENOF("telephone")) == 0 ))
+               {
+                       tmp.bv_len -= LENOF("telephone");
+                       tmp.bv_val += LENOF("telephone");
+                       break;
+               }
+               return LDAP_INVALID_SYNTAX;
+
+       case 'g':
+       case 'G': /* g3fax or g4fax */
+               if(( tmp.bv_len >= LENOF("g3fax") ) && (
+                       ( strncasecmp(tmp.bv_val, "g3fax", LENOF("g3fax")) == 0 ) ||
+                       ( strncasecmp(tmp.bv_val, "g4fax", LENOF("g4fax")) == 0 )))
+               {
+                       tmp.bv_len -= LENOF("g3fax");
+                       tmp.bv_val += LENOF("g3fax");
+                       break;
+               }
+               return LDAP_INVALID_SYNTAX;
+
+       case 'i':
+       case 'I':
+               if(( tmp.bv_len >= LENOF("ia5") ) &&
+                       ( strncasecmp(tmp.bv_val, "ia5", LENOF("ia5")) == 0 ))
+               {
+                       tmp.bv_len -= LENOF("ia5");
+                       tmp.bv_val += LENOF("ia5");
+                       break;
+               }
+               return LDAP_INVALID_SYNTAX;
+
+       case 'v':
+       case 'V':
+               if(( tmp.bv_len >= LENOF("videotex") ) &&
+                       ( strncasecmp(tmp.bv_val, "videotex", LENOF("videotex")) == 0 ))
+               {
+                       tmp.bv_len -= LENOF("videotex");
+                       tmp.bv_val += LENOF("videotex");
+                       break;
+               }
+               return LDAP_INVALID_SYNTAX;
+
+       default:
+               return LDAP_INVALID_SYNTAX;
+       }
+
+       if( tmp.bv_len == 0 ) return LDAP_SUCCESS;
+
+       while( tmp.bv_len && ( tmp.bv_val[0] == ' ' )) {
+               tmp.bv_len++;
+               tmp.bv_val--;
+       }
+       if( tmp.bv_len && ( tmp.bv_val[0] == '$' )) {
+               tmp.bv_len++;
+               tmp.bv_val--;
+       } else {
+               return LDAP_INVALID_SYNTAX;
+       }
+       while( tmp.bv_len && ( tmp.bv_val[0] == ' ' )) {
+               tmp.bv_len++;
+               tmp.bv_val--;
+       }
+
+       goto again;
+}
+
 static int
 nisNetgroupTripleValidate(
        Syntax *syntax,
@@ -2640,7 +2873,7 @@ static slap_syntax_defs_rec syntax_defs[] = {
        {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
                0, NULL, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
-               0, NULL, NULL},
+               0, deliveryMethodValidate, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
                0, UTF8StringValidate, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
@@ -2752,6 +2985,9 @@ static slap_syntax_defs_rec syntax_defs[] = {
                SLAP_SYNTAX_HIDE, NULL, NULL},
 #endif
 
+       {"( 1.3.6.1.4.1.4203.666.2.6 DESC 'UUID' )",
+               SLAP_SYNTAX_HIDE, UUIDValidate, NULL},
+
        /* OpenLDAP Void Syntax */
        {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
                SLAP_SYNTAX_HIDE, inValidate, NULL},
@@ -2786,22 +3022,22 @@ char *objectIdentifierFirstComponentMatchSyntaxes[] = {
 /*
  * Other matching rules in X.520 that we do not use (yet):
  *
- * 2.5.13.9            numericStringOrderingMatch
  * 2.5.13.25   uTCTimeMatch
  * 2.5.13.26   uTCTimeOrderingMatch
- * 2.5.13.31   directoryStringFirstComponentMatch
- * 2.5.13.32   wordMatch
- * 2.5.13.33   keywordMatch
- * 2.5.13.35   certificateMatch
+ * 2.5.13.31*  directoryStringFirstComponentMatch
+ * 2.5.13.32*  wordMatch
+ * 2.5.13.33*  keywordMatch
  * 2.5.13.36   certificatePairExactMatch
  * 2.5.13.37   certificatePairMatch
  * 2.5.13.38   certificateListExactMatch
  * 2.5.13.39   certificateListMatch
  * 2.5.13.40   algorithmIdentifierMatch
- * 2.5.13.41   storedPrefixMatch
+ * 2.5.13.41*  storedPrefixMatch
  * 2.5.13.42   attributeCertificateMatch
  * 2.5.13.43   readerAndKeyIDMatch
  * 2.5.13.44   attributeIntegrityMatch
+ *
+ * (*) described in RFC 3698 (LDAP: Additional Matching Rules)
  */
 static slap_mrule_defs_rec mrule_defs[] = {
        /*
@@ -2856,7 +3092,7 @@ static slap_mrule_defs_rec mrule_defs[] = {
 
        {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
-               SLAP_MR_SUBSTR, NULL,
+               SLAP_MR_SUBSTR, directoryStringSyntaxes,
                NULL, UTF8StringNormalize, octetStringSubstringsMatch,
                octetStringSubstringsIndexer, octetStringSubstringsFilter,
                "caseIgnoreMatch" },
@@ -2885,10 +3121,17 @@ static slap_mrule_defs_rec mrule_defs[] = {
        {"( 2.5.13.8 NAME 'numericStringMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
                SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
-               NULL, numericStringNormalize, octetStringSubstringsMatch,
-               octetStringSubstringsIndexer, octetStringSubstringsFilter,
+               NULL, numericStringNormalize, octetStringMatch,
+               octetStringIndexer, octetStringFilter,
                NULL },
 
+       {"( 2.5.13.9 NAME 'numericStringOrderingMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
+               SLAP_MR_ORDERING, NULL,
+               NULL, numericStringNormalize, octetStringOrderingMatch,
+               NULL, NULL,
+               "numericStringMatch" },
+
        {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
                SLAP_MR_SUBSTR, NULL,
@@ -3029,6 +3272,17 @@ static slap_mrule_defs_rec mrule_defs[] = {
 #endif
                NULL },
 
+       {"( 2.5.13.35 NAME 'certificateMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 )",
+               SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
+#ifdef HAVE_TLS
+               NULL, NULL, octetStringMatch,
+               octetStringIndexer, octetStringFilter,
+#else
+               NULL, NULL, NULL, NULL, NULL,
+#endif
+               NULL },
+
        {"( 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, NULL,
@@ -3090,6 +3344,20 @@ static slap_mrule_defs_rec mrule_defs[] = {
                NULL, NULL,
                "integerMatch" },
 
+       {"( 1.3.6.1.4.1.4203.666.4.6 NAME 'UUIDMatch' "
+               "SYNTAX 1.3.6.1.4.1.4203.666.2.6 )",
+               SLAP_MR_HIDE | SLAP_MR_EQUALITY, NULL,
+               NULL, UUIDNormalize, octetStringMatch,
+               octetStringIndexer, octetStringFilter,
+               NULL},
+
+       {"( 1.3.6.1.4.1.4203.666.4.7 NAME 'UUIDOrderingMatch' "
+               "SYNTAX 1.3.6.1.4.1.4203.666.2.6 )",
+               SLAP_MR_HIDE | SLAP_MR_ORDERING, NULL,
+               NULL, UUIDNormalize, octetStringOrderingMatch,
+               octetStringIndexer, octetStringFilter,
+               "UUIDMatch"},
+
        {NULL, SLAP_MR_NONE, NULL,
                NULL, NULL, NULL, NULL, NULL,
                NULL }