]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/schema_init.c
Move backend_syncfreq code down into back-ldbm. Creates new configuration
[openldap] / servers / slapd / schema_init.c
index 1f2c29eaa4d894f59000d63c4df9139144582d70..00c4ca9955f793c1824c1aca09f178d8b1a81021 100644 (file)
 /* recycled validatation routines */
 #define berValidate                                            blobValidate
 
-/* recycled normalization routines */
-#define faxNumberNormalize                             numericStringNormalize
-#define phoneNumberNormalize                   numericStringNormalize
-#define telexNumberNormalize                   numericStringNormalize
-
 /* unimplemented pretters */
 #define dnPretty                                               NULL
 #define integerPretty                                  NULL
 /* recycled matching routines */
 #define bitStringMatch                                 octetStringMatch
 #define integerMatch                                   caseIgnoreIA5Match
-#define numericStringMatch                             caseIgnoreMatch
-#define objectIdentifierMatch                  numericStringMatch
-#define telephoneNumberMatch                   numericStringMatch
+#define numericStringMatch                             caseIgnoreIA5Match
+#define objectIdentifierMatch                  caseIgnoreIA5Match
+#define telephoneNumberMatch                   caseIgnoreIA5Match
 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
-#define generalizedTimeMatch                   numericStringMatch
-#define generalizedTimeOrderingMatch   numericStringMatch
+#define generalizedTimeMatch                   caseIgnoreIA5Match
+#define generalizedTimeOrderingMatch   caseIgnoreIA5Match
 #define uniqueMemberMatch                              dnMatch
 
 /* approx matching rules */
 #define directoryStringApproxMatchOID  "1.3.6.1.4.1.4203.666.4.4"
-#define directoryStringApproxMatch     approxMatch
-#define directoryStringApproxIndexer   approxIndexer
-#define directoryStringApproxFilter    approxFilter
+#define directoryStringApproxMatch     approxMatch
+#define directoryStringApproxIndexer   approxIndexer
+#define directoryStringApproxFilter    approxFilter
 #define IA5StringApproxMatchOID                        "1.3.6.1.4.1.4203.666.4.5"
-#define IA5StringApproxMatch                   approxMatch
+#define IA5StringApproxMatch                   approxMatch
 #define IA5StringApproxIndexer                 approxIndexer
-#define IA5StringApproxFilter                          approxFilter
+#define IA5StringApproxFilter                  approxFilter
 
 /* orderring matching rules */
 #define caseIgnoreOrderingMatch                        caseIgnoreMatch
@@ -76,7 +71,6 @@
 /* unimplemented matching routines */
 #define caseIgnoreListMatch                            NULL
 #define caseIgnoreListSubstringsMatch  NULL
-#define presentationAddressMatch               NULL
 #define protocolInformationMatch               NULL
 #define integerFirstComponentMatch             NULL
 
 #define integerIndexer                                 caseIgnoreIA5Indexer
 #define integerFilter                                  caseIgnoreIA5Filter
 
+#define telephoneNumberIndexer                 caseIgnoreIA5Indexer
+#define telephoneNumberFilter                  caseIgnoreIA5Filter
+#define telephoneNumberSubstringsIndexer       caseIgnoreIA5SubstringsIndexer
+#define telephoneNumberSubstringsFilter                caseIgnoreIA5SubstringsFilter
+
 static char *strcasechr( const char *str, int c )
 {
        char *lower = strchr( str, TOLOWER(c) );
@@ -138,7 +137,7 @@ int octetStringIndexer(
        size_t slen, mlen;
        struct berval **keys;
        HASH_CONTEXT   HASHcontext;
-       unsigned char   HASHdigest[HASH_BYTES];
+       unsigned char   HASHdigest[HASH_BYTES];
        struct berval digest;
        digest.bv_val = HASHdigest;
        digest.bv_len = sizeof(HASHdigest);
@@ -192,7 +191,7 @@ int octetStringFilter(
        size_t slen, mlen;
        struct berval **keys;
        HASH_CONTEXT   HASHcontext;
-       unsigned char   HASHdigest[HASH_BYTES];
+       unsigned char   HASHdigest[HASH_BYTES];
        struct berval *value = (struct berval *) assertValue;
        struct berval digest;
        digest.bv_val = HASHdigest;
@@ -243,21 +242,23 @@ dnValidate(
        return rc;
 }
 
-static int
+int
 dnNormalize(
        Syntax *syntax,
        struct berval *val,
        struct berval **normalized )
 {
-       struct berval *out = ber_bvdup( val );
+       struct berval *out;
 
-       if( out->bv_len != 0 ) {
+       if ( val->bv_len != 0 ) {
                char *dn;
 #ifdef USE_DN_NORMALIZE
-               dn = dn_normalize( out->bv_val );
+               out = ber_bvstr( UTF8normalize( val->bv_val, UTF8_CASEFOLD ) );
 #else
-               dn = dn_validate( out->bv_val );
+               out = ber_bvdup( val );
+               ldap_pvt_str2upper( out->bv_val );
 #endif
+               dn = dn_validate( out->bv_val );
 
                if( dn == NULL ) {
                        ber_bvfree( out );
@@ -266,6 +267,8 @@ dnNormalize(
 
                out->bv_val = dn;
                out->bv_len = strlen( dn );
+       } else {
+               out = ber_bvdup( val );
        }
 
        *normalized = out;
@@ -294,8 +297,15 @@ dnMatch(
 #endif
        }
 
+#ifdef NEW_LOGGING
+       LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
+                  "dnMatch: %d\n    %s\n    %s\n", match,
+                  value->bv_val, asserted->bv_val ));
+#else
        Debug( LDAP_DEBUG_ARGS, "dnMatch %d\n\t\"%s\"\n\t\"%s\"\n",
            match, value->bv_val, asserted->bv_val );
+#endif
+
 
        *matchp = match;
        return LDAP_SUCCESS;
@@ -430,6 +440,7 @@ bitStringValidate(
        if( in->bv_len < 3 ) {
                return LDAP_INVALID_SYNTAX;
        }
+
        if( in->bv_val[0] != 'B' ||
                in->bv_val[1] != '\'' ||
                in->bv_val[in->bv_len-1] != '\'' )
@@ -490,60 +501,6 @@ booleanMatch(
 }
 
 #if UTF8MATCH
-static int
-UTF8casecmp(
-       struct berval *right,
-       struct berval *left )
-{
-       ber_len_t r, l;
-       int rlen, llen;
-       ldap_unicode_t ru, lu;
-       ldap_unicode_t ruu, luu;
-
-       for( r=0, l=0;
-               r < right->bv_len && l < left->bv_len;
-               r+=rlen, l+=llen )
-       {
-               /*
-                * XXYYZ: we convert to ucs4 even though -llunicode
-                * expects ucs2 in an unsigned long
-                */
-               ru = ldap_utf8_to_ucs4( &right->bv_val[r] );
-               if( ru == LDAP_UCS4_INVALID ) {
-                       return 1;
-               }
-
-               lu = ldap_utf8_to_ucs4( &left->bv_val[l] );
-               if( lu == LDAP_UCS4_INVALID ) {
-                       return -1;
-               }
-
-               ruu = uctoupper( ru );
-               luu = uctoupper( lu );
-
-               if( ruu > luu ) {
-                       return 1;
-               } else if( luu > ruu ) {
-                       return -1;
-               }
-
-               rlen = LDAP_UTF8_CHARLEN( &right->bv_val[r] );
-               llen = LDAP_UTF8_CHARLEN( &left->bv_val[l] );
-       }
-
-       if( r < right->bv_len ) {
-               /* less left */
-               return -1;
-       }
-
-       if( l < left->bv_len ) {
-               /* less right */
-               return 1;
-       }
-
-       return 0;
-}
-
 /* case insensitive UTF8 strncmp with offset for second string */
 static int
 UTF8oncasecmp(
@@ -553,8 +510,8 @@ UTF8oncasecmp(
        ber_len_t offset )
 {
        ber_len_t r, l;
-       int rlen, llen;
-       int rslen, lslen;
+       ber_len_t rlen, llen;
+       ber_len_t rslen, lslen;
        ldap_unicode_t ru, lu;
        ldap_unicode_t ruu, luu;
 
@@ -776,7 +733,7 @@ approxMatch(
        /* Get a phonetic copy of each word */
        words = (char **)ch_malloc( count * sizeof(char *) );
        values = (char **)ch_malloc( count * sizeof(char *) );
-       for( c=val,i=0;  i<count;  i++,c+=strlen(c)+1 ) {
+       for( c=val,i=0;  i<count;  i++,c+=strlen(c)+1 ) {
                words[i] = c;
                values[i] = phonetic(c);
        }
@@ -788,17 +745,21 @@ approxMatch(
        len = 0;
        while ( nextchunk < ((struct berval *)assertedValue)->bv_len ) {
                len = strcspn( assertv + nextchunk, SLAPD_APPROX_DELIMITER);
+               if( len == 0 ) {
+                       nextchunk++;
+                       continue;
+               }
 #if defined(SLAPD_APPROX_INITIALS)
-               if( len <= 1 ) {
+               else if( len == 1 ) {
                        /* Single letter words need to at least match one word's initial */
                        for( i=nextavail; i<count; i++ )
-                               if( !strncasecmp( assertv+nextchunk, words[i], 1 ))
+                               if( !strncasecmp( assertv+nextchunk, words[i], 1 )) {
+                                       nextavail=i+1;
                                        break;
+                               }
                }
-
-               else
 #endif
-               {
+               else {
                        /* Isolate the next word in the asserted value and phonetic it */
                        assertv[nextchunk+len] = '\0';
                        val = phonetic( assertv + nextchunk );
@@ -862,7 +823,7 @@ approxIndexer(
 
                /* Isolate how many words there are. There will be a key for each */
                val = ch_strdup( values[j]->bv_val );
-               for( wordcount=0,c=val;  *c;  c++) {
+               for( wordcount=0,c=val;  *c;  c++) {
                        len = strcspn(c, SLAPD_APPROX_DELIMITER);
                        if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
                        c+= len;
@@ -878,7 +839,7 @@ approxIndexer(
                keys = newkeys;
 
                /* Get a phonetic copy of each word */
-               for( c=val,i=0;  i<wordcount;  c+=len+1  ) {
+               for( c=val,i=0;  i<wordcount;  c+=len+1  ) {
                        len = strlen( c );
                        if( len < SLAPD_APPROX_WORDLEN ) continue;
                        keys[keycount] = (struct berval *)ch_malloc( sizeof(struct berval) );
@@ -926,7 +887,7 @@ approxFilter(
        keys = (struct berval **)ch_malloc( (count + 1) * sizeof(struct berval *) );
 
        /* Get a phonetic copy of each word */
-       for( c=val,i=0;  i<count; c+=len+1 ) {
+       for( c=val,i=0;  i<count; c+=len+1 ) {
                len = strlen(c);
                if( len < SLAPD_APPROX_WORDLEN ) continue;
                keys[i] = (struct berval *)ch_malloc( sizeof(struct berval) );
@@ -1190,7 +1151,7 @@ int caseExactIndexer(
        size_t slen, mlen;
        struct berval **keys;
        HASH_CONTEXT   HASHcontext;
-       unsigned char   HASHdigest[HASH_BYTES];
+       unsigned char   HASHdigest[HASH_BYTES];
        struct berval digest;
        digest.bv_val = HASHdigest;
        digest.bv_len = sizeof(HASHdigest);
@@ -1208,7 +1169,12 @@ int caseExactIndexer(
        mlen = strlen( mr->smr_oid );
 
        for( i=0; values[i] != NULL; i++ ) {
-               struct berval *value = values[i];
+               struct berval *value;
+#if UTF8MATCH
+               value = ber_bvstr( UTF8normalize( values[i]->bv_val, UTF8_NOCASEFOLD ) );
+#else
+               value = values[i];
+#endif
 
                HASH_Init( &HASHcontext );
                if( prefix != NULL && prefix->bv_len > 0 ) {
@@ -1223,6 +1189,10 @@ int caseExactIndexer(
                        value->bv_val, value->bv_len );
                HASH_Final( HASHdigest, &HASHcontext );
 
+#if UTF8MATCH
+               ber_bvfree( value );
+#endif
+
                keys[i] = ber_bvdup( &digest );
        }
 
@@ -1244,7 +1214,7 @@ int caseExactFilter(
        size_t slen, mlen;
        struct berval **keys;
        HASH_CONTEXT   HASHcontext;
-       unsigned char   HASHdigest[HASH_BYTES];
+       unsigned char   HASHdigest[HASH_BYTES];
        struct berval *value;
        struct berval digest;
        digest.bv_val = HASHdigest;
@@ -1253,7 +1223,11 @@ int caseExactFilter(
        slen = strlen( syntax->ssyn_oid );
        mlen = strlen( mr->smr_oid );
 
+#if UTF8MATCH
+        value = ber_bvstr( UTF8normalize( ((struct berval *) assertValue)->bv_val, UTF8_NOCASEFOLD ) );
+#else
        value = (struct berval *) assertValue;
+#endif 
 
        keys = ch_malloc( sizeof( struct berval * ) * 2 );
 
@@ -1273,6 +1247,10 @@ int caseExactFilter(
        keys[0] = ber_bvdup( &digest );
        keys[1] = NULL;
 
+#if UTF8MATCH
+       ber_bvfree( value );
+#endif
+
        *keysp = keys;
        return LDAP_SUCCESS;
 }
@@ -1291,7 +1269,7 @@ int caseExactSubstringsIndexer(
        size_t slen, mlen;
        struct berval **keys;
        HASH_CONTEXT   HASHcontext;
-       unsigned char   HASHdigest[HASH_BYTES];
+       unsigned char   HASHdigest[HASH_BYTES];
        struct berval digest;
        digest.bv_val = HASHdigest;
        digest.bv_len = sizeof(HASHdigest);
@@ -1347,8 +1325,13 @@ int caseExactSubstringsIndexer(
                ber_len_t j,max;
                struct berval *value;
 
+               if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
+
+#if UTF8MATCH
+                value = ber_bvstr( UTF8normalize( values[i]->bv_val, UTF8_NOCASEFOLD ) );
+#else
                value = values[i];
-               if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
+#endif
 
                if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
                        ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
@@ -1425,6 +1408,11 @@ int caseExactSubstringsIndexer(
                        }
 
                }
+
+#if UTF8MATCH
+               ber_bvfree( value );
+#endif
+
        }
 
        if( nkeys > 0 ) {
@@ -1453,7 +1441,7 @@ int caseExactSubstringsFilter(
        size_t slen, mlen, klen;
        struct berval **keys;
        HASH_CONTEXT   HASHcontext;
-       unsigned char   HASHdigest[HASH_BYTES];
+       unsigned char   HASHdigest[HASH_BYTES];
        struct berval *value;
        struct berval digest;
 
@@ -1498,7 +1486,11 @@ int caseExactSubstringsFilter(
                sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
        {
                pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
+#if UTF8MATCH
+                value = ber_bvstr( UTF8normalize( sa->sa_initial->bv_val, UTF8_NOCASEFOLD ) );
+#else
                value = sa->sa_initial;
+#endif
 
                klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
                        ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
@@ -1518,6 +1510,9 @@ int caseExactSubstringsFilter(
                        value->bv_val, klen );
                HASH_Final( HASHdigest, &HASHcontext );
 
+#if UTF8MATCH
+               ber_bvfree( value );
+#endif
                keys[nkeys++] = ber_bvdup( &digest );
        }
 
@@ -1531,7 +1526,11 @@ int caseExactSubstringsFilter(
                                continue;
                        }
 
+#if UTF8MATCH
+                        value = ber_bvstr( UTF8normalize( sa->sa_any[i]->bv_val, UTF8_NOCASEFOLD ) );
+#else
                        value = sa->sa_any[i];
+#endif
 
                        for(j=0;
                                j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
@@ -1554,6 +1553,10 @@ int caseExactSubstringsFilter(
 
                                keys[nkeys++] = ber_bvdup( &digest );
                        }
+
+#if UTF8MATCH
+                       ber_bvfree( value );
+#endif
                }
        }
 
@@ -1561,7 +1564,11 @@ int caseExactSubstringsFilter(
                sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
        {
                pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
+#if UTF8MATCH
+                value = ber_bvstr( UTF8normalize( sa->sa_final->bv_val, UTF8_NOCASEFOLD ) );
+#else
                value = sa->sa_final;
+#endif
 
                klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
                        ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
@@ -1581,6 +1588,9 @@ int caseExactSubstringsFilter(
                        &value->bv_val[value->bv_len-klen], klen );
                HASH_Final( HASHdigest, &HASHcontext );
 
+#if UTF8MATCH
+               ber_bvfree( value );
+#endif
                keys[nkeys++] = ber_bvdup( &digest );
        }
 
@@ -1605,7 +1615,9 @@ caseIgnoreMatch(
        void *assertedValue )
 {
 #if UTF8MATCH
-       *matchp = UTF8casecmp( value, (struct berval *) assertedValue );
+       *matchp = UTF8normcmp( value->bv_val,
+                              ((struct berval *) assertedValue)->bv_val,
+                              UTF8_CASEFOLD );
 #else
        int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
 
@@ -1787,7 +1799,7 @@ int caseIgnoreIndexer(
        size_t slen, mlen;
        struct berval **keys;
        HASH_CONTEXT   HASHcontext;
-       unsigned char   HASHdigest[HASH_BYTES];
+       unsigned char   HASHdigest[HASH_BYTES];
        struct berval digest;
        digest.bv_val = HASHdigest;
        digest.bv_len = sizeof(HASHdigest);
@@ -1805,9 +1817,13 @@ int caseIgnoreIndexer(
        mlen = strlen( mr->smr_oid );
 
        for( i=0; values[i] != NULL; i++ ) {
-               struct berval *value = ber_bvdup( values[i] );
+               struct berval *value;
+#if UTF8MATCH
+               value = ber_bvstr( UTF8normalize( values[i]->bv_val, UTF8_CASEFOLD ) );
+#else
+               value = ber_bvdup( values[i] );
                ldap_pvt_str2upper( value->bv_val );
-
+#endif
                HASH_Init( &HASHcontext );
                if( prefix != NULL && prefix->bv_len > 0 ) {
                        HASH_Update( &HASHcontext,
@@ -1844,7 +1860,7 @@ int caseIgnoreFilter(
        size_t slen, mlen;
        struct berval **keys;
        HASH_CONTEXT   HASHcontext;
-       unsigned char   HASHdigest[HASH_BYTES];
+       unsigned char   HASHdigest[HASH_BYTES];
        struct berval *value;
        struct berval digest;
        digest.bv_val = HASHdigest;
@@ -1853,8 +1869,12 @@ int caseIgnoreFilter(
        slen = strlen( syntax->ssyn_oid );
        mlen = strlen( mr->smr_oid );
 
+#if UTF8MATCH
+       value = ber_bvstr( UTF8normalize( ((struct berval *) assertValue)->bv_val, UTF8_CASEFOLD ) );
+#else
        value = ber_bvdup( (struct berval *) assertValue );
        ldap_pvt_str2upper( value->bv_val );
+#endif
 
        keys = ch_malloc( sizeof( struct berval * ) * 2 );
 
@@ -1895,7 +1915,7 @@ int caseIgnoreSubstringsIndexer(
        size_t slen, mlen;
        struct berval **keys;
        HASH_CONTEXT   HASHcontext;
-       unsigned char   HASHdigest[HASH_BYTES];
+       unsigned char   HASHdigest[HASH_BYTES];
        struct berval digest;
        digest.bv_val = HASHdigest;
        digest.bv_len = sizeof(HASHdigest);
@@ -1953,8 +1973,12 @@ int caseIgnoreSubstringsIndexer(
 
                if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
 
+#if UTF8MATCH
+               value = ber_bvstr( UTF8normalize( values[i]->bv_val, UTF8_CASEFOLD ) );
+#else
                value = ber_bvdup( values[i] );
                ldap_pvt_str2upper( value->bv_val );
+#endif
 
                if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
                        ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
@@ -2061,7 +2085,7 @@ int caseIgnoreSubstringsFilter(
        size_t slen, mlen, klen;
        struct berval **keys;
        HASH_CONTEXT   HASHcontext;
-       unsigned char   HASHdigest[HASH_BYTES];
+       unsigned char   HASHdigest[HASH_BYTES];
        struct berval *value;
        struct berval digest;
 
@@ -2106,8 +2130,12 @@ int caseIgnoreSubstringsFilter(
                sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
        {
                pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
+#if UTF8MATCH
+               value = ber_bvstr( UTF8normalize( sa->sa_initial->bv_val, UTF8_CASEFOLD ) );
+#else
                value = ber_bvdup( sa->sa_initial );
                ldap_pvt_str2upper( value->bv_val );
+#endif
 
                klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
                        ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
@@ -2141,8 +2169,12 @@ int caseIgnoreSubstringsFilter(
                                continue;
                        }
 
+#if UTF8MATCH
+                       value = ber_bvstr( UTF8normalize( sa->sa_any[i]->bv_val, UTF8_CASEFOLD ) );
+#else
                        value = ber_bvdup( sa->sa_any[i] );
                        ldap_pvt_str2upper( value->bv_val );
+#endif
 
                        for(j=0;
                                j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
@@ -2174,8 +2206,12 @@ int caseIgnoreSubstringsFilter(
                sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
        {
                pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
+#if UTF8MATCH
+               value = ber_bvstr( UTF8normalize( sa->sa_final->bv_val, UTF8_CASEFOLD ) );
+#else
                value = ber_bvdup( sa->sa_final );
                ldap_pvt_str2upper( value->bv_val );
+#endif
 
                klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
                        ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
@@ -2217,7 +2253,10 @@ oidValidate(
 {
        ber_len_t i;
 
-       if( val->bv_len == 0 ) return 0;
+       if( val->bv_len == 0 ) {
+               /* disallow empty strings */
+               return LDAP_INVALID_SYNTAX;
+       }
 
        if( OID_LEADCHAR(val->bv_val[0]) ) {
                int dot = 0;
@@ -2311,6 +2350,23 @@ done:
        return LDAP_SUCCESS;
 }
 
+static int
+countryStringValidate(
+       Syntax *syntax,
+       struct berval *val )
+{
+       if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
+
+       if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
+               return LDAP_INVALID_SYNTAX;
+       }
+       if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
+               return LDAP_INVALID_SYNTAX;
+       }
+
+       return LDAP_SUCCESS;
+}
+
 static int
 printableStringValidate(
        Syntax *syntax,
@@ -2321,7 +2377,27 @@ printableStringValidate(
        if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
 
        for(i=0; i < val->bv_len; i++) {
-               if( !isprint(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
+               if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
+                       return LDAP_INVALID_SYNTAX;
+               }
+       }
+
+       return LDAP_SUCCESS;
+}
+
+static int
+printablesStringValidate(
+       Syntax *syntax,
+       struct berval *val )
+{
+       ber_len_t i;
+
+       if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
+
+       for(i=0; i < val->bv_len; i++) {
+               if( !SLAP_PRINTABLES(val->bv_val[i]) ) {
+                       return LDAP_INVALID_SYNTAX;
+               }
        }
 
        return LDAP_SUCCESS;
@@ -2571,7 +2647,7 @@ int caseExactIA5Indexer(
        size_t slen, mlen;
        struct berval **keys;
        HASH_CONTEXT   HASHcontext;
-       unsigned char   HASHdigest[HASH_BYTES];
+       unsigned char   HASHdigest[HASH_BYTES];
        struct berval digest;
        digest.bv_val = HASHdigest;
        digest.bv_len = sizeof(HASHdigest);
@@ -2625,7 +2701,7 @@ int caseExactIA5Filter(
        size_t slen, mlen;
        struct berval **keys;
        HASH_CONTEXT   HASHcontext;
-       unsigned char   HASHdigest[HASH_BYTES];
+       unsigned char   HASHdigest[HASH_BYTES];
        struct berval *value;
        struct berval digest;
        digest.bv_val = HASHdigest;
@@ -2672,7 +2748,7 @@ int caseExactIA5SubstringsIndexer(
        size_t slen, mlen;
        struct berval **keys;
        HASH_CONTEXT   HASHcontext;
-       unsigned char   HASHdigest[HASH_BYTES];
+       unsigned char   HASHdigest[HASH_BYTES];
        struct berval digest;
        digest.bv_val = HASHdigest;
        digest.bv_len = sizeof(HASHdigest);
@@ -2834,7 +2910,7 @@ int caseExactIA5SubstringsFilter(
        size_t slen, mlen, klen;
        struct berval **keys;
        HASH_CONTEXT   HASHcontext;
-       unsigned char   HASHdigest[HASH_BYTES];
+       unsigned char   HASHdigest[HASH_BYTES];
        struct berval *value;
        struct berval digest;
 
@@ -2987,7 +3063,7 @@ caseIgnoreIA5Match(
 {
        int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
 
-       if( match == 0 ) {
+       if( match == 0 && value->bv_len ) {
                match = strncasecmp( value->bv_val,
                        ((struct berval *) assertedValue)->bv_val,
                        value->bv_len );
@@ -3137,7 +3213,7 @@ int caseIgnoreIA5Indexer(
        size_t slen, mlen;
        struct berval **keys;
        HASH_CONTEXT   HASHcontext;
-       unsigned char   HASHdigest[HASH_BYTES];
+       unsigned char   HASHdigest[HASH_BYTES];
        struct berval digest;
        digest.bv_val = HASHdigest;
        digest.bv_len = sizeof(HASHdigest);
@@ -3194,7 +3270,7 @@ int caseIgnoreIA5Filter(
        size_t slen, mlen;
        struct berval **keys;
        HASH_CONTEXT   HASHcontext;
-       unsigned char   HASHdigest[HASH_BYTES];
+       unsigned char   HASHdigest[HASH_BYTES];
        struct berval *value;
        struct berval digest;
        digest.bv_val = HASHdigest;
@@ -3245,7 +3321,7 @@ int caseIgnoreIA5SubstringsIndexer(
        size_t slen, mlen;
        struct berval **keys;
        HASH_CONTEXT   HASHcontext;
-       unsigned char   HASHdigest[HASH_BYTES];
+       unsigned char   HASHdigest[HASH_BYTES];
        struct berval digest;
        digest.bv_val = HASHdigest;
        digest.bv_len = sizeof(HASHdigest);
@@ -3411,7 +3487,7 @@ int caseIgnoreIA5SubstringsFilter(
        size_t slen, mlen, klen;
        struct berval **keys;
        HASH_CONTEXT   HASHcontext;
-       unsigned char   HASHdigest[HASH_BYTES];
+       unsigned char   HASHdigest[HASH_BYTES];
        struct berval *value;
        struct berval digest;
 
@@ -3560,32 +3636,37 @@ int caseIgnoreIA5SubstringsFilter(
        return LDAP_SUCCESS;
 }
        
+static int
+numericStringValidate(
+       Syntax *syntax,
+       struct berval *in )
+{
+       ber_len_t i;
+
+       for(i=0; i < in->bv_len; i++) {
+               if( !SLAP_NUMERIC(in->bv_val[i]) ) {
+                       return LDAP_INVALID_SYNTAX;
+               }
+       }
+
+       return LDAP_SUCCESS;
+}
+
 static int
 numericStringNormalize(
        Syntax *syntax,
        struct berval *val,
        struct berval **normalized )
 {
-       /* similiar to IA5StringNormalize except removes all spaces */
+       /* removal all spaces */
        struct berval *newval;
        char *p, *q;
 
        newval = ch_malloc( sizeof( struct berval ) );
+       newval->bv_val = ch_malloc( val->bv_len + 1 );
 
        p = val->bv_val;
-
-       /* Ignore initial whitespace */
-       while ( ASCII_SPACE( *p ) ) {
-               p++;
-       }
-
-       if( *p == '\0' ) {
-               ch_free( newval );
-               return LDAP_INVALID_SYNTAX;
-       }
-
-       newval->bv_val = ch_strdup( p );
-       p = q = newval->bv_val;
+       q = newval->bv_val;
 
        while ( *p ) {
                if ( ASCII_SPACE( *p ) ) {
@@ -3596,16 +3677,9 @@ numericStringNormalize(
                }
        }
 
-       assert( *newval->bv_val );
-       assert( newval->bv_val < p );
+       assert( newval->bv_val <= p );
        assert( q <= p );
 
-       /* cannot start with a space */
-       assert( !ASCII_SPACE(*newval->bv_val) );
-
-       /* cannot end with a space */
-       assert( !ASCII_SPACE( q[-1] ) );
-
        /* null terminate */
        *q = '\0';
 
@@ -3694,9 +3768,16 @@ objectIdentifierFirstComponentMatch(
                ch_free( stored );
        }
 
+#ifdef NEW_LOGGING
+       LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
+                  "objectIdentifierFirstComponentMatch: %d\n    %s\n    %s\n",
+                  match, value->bv_val, asserted->bv_val ));
+#else
        Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
                "%d\n\t\"%s\"\n\t\"%s\"\n",
            match, value->bv_val, asserted->bv_val );
+#endif
+
 
        if( rc == LDAP_SUCCESS ) *matchp = match;
        return rc;
@@ -3829,7 +3910,7 @@ check_time_syntax (struct berval *val,
        }
 
        switch ( tzoffset ) {
-       case -1: /* negativ offset to UTC, ie west of Greenwich  */
+       case -1: /* negativ offset to UTC, ie west of Greenwich  */
                parts[4] += parts[7];
                parts[5] += parts[8];
                for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
@@ -4103,7 +4184,7 @@ struct syntax_defs_rec syntax_defs[] = {
                X_BINARY X_NOT_H_R ")",
                SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
-               0, NULL, NULL, NULL},
+               0, countryStringValidate, IA5StringNormalize, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
                0, dnValidate, dnNormalize, dnPretty},
        {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
@@ -4123,7 +4204,7 @@ struct syntax_defs_rec syntax_defs[] = {
        {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
                0, NULL, NULL, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
-               0, IA5StringValidate, faxNumberNormalize, NULL},
+               0, printablesStringValidate, IA5StringNormalize, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
                SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
@@ -4151,32 +4232,32 @@ struct syntax_defs_rec syntax_defs[] = {
        {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
                0, NULL, NULL, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
-               0, IA5StringValidate, numericStringNormalize, NULL},
+               0, numericStringValidate, numericStringNormalize, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
                0, NULL, NULL, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
                0, oidValidate, NULL, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
-               0, NULL, NULL, NULL},
+               0, IA5StringValidate, IA5StringNormalize, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
                0, blobValidate, NULL, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
-               0, blobValidate, NULL, NULL},
+               0, UTF8StringValidate, UTF8StringNormalize, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
                0, NULL, NULL, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
                0, NULL, NULL, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
-               0, printableStringValidate, NULL, NULL},
+               0, printableStringValidate, IA5StringNormalize, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
                X_BINARY X_NOT_H_R ")",
                SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
-               0, IA5StringValidate, phoneNumberNormalize, NULL},
+               0, printableStringValidate, IA5StringNormalize, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
                0, NULL, NULL, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
-               0, IA5StringValidate, telexNumberNormalize, NULL},
+               0, printableStringValidate, IA5StringNormalize, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
                0, utcTimeValidate, utcTimeNormalize, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
@@ -4198,7 +4279,7 @@ struct syntax_defs_rec syntax_defs[] = {
 
        /* OpenLDAP Experimental Syntaxes */
        {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
-               0, IA5StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
+               0, UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
                NULL, NULL},
        {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
                0, NULL, NULL, NULL},
@@ -4255,7 +4336,8 @@ struct mrule_defs_rec mrule_defs[] = {
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
                SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
                NULL, NULL,
-               directoryStringApproxMatch, directoryStringApproxIndexer, 
+               directoryStringApproxMatch,
+               directoryStringApproxIndexer, 
                directoryStringApproxFilter,
                NULL},
 
@@ -4263,7 +4345,8 @@ struct mrule_defs_rec mrule_defs[] = {
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
                SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
                NULL, NULL,
-               IA5StringApproxMatch, IA5StringApproxIndexer, 
+               IA5StringApproxMatch,
+               IA5StringApproxIndexer, 
                IA5StringApproxFilter,
                NULL},
 
@@ -4395,21 +4478,25 @@ struct mrule_defs_rec mrule_defs[] = {
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
                SLAP_MR_EQUALITY | SLAP_MR_EXT,
                NULL, NULL,
-               telephoneNumberMatch, NULL, NULL,
+               telephoneNumberMatch,
+               telephoneNumberIndexer,
+               telephoneNumberFilter,
                NULL},
 
        {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
                SLAP_MR_SUBSTR | SLAP_MR_EXT,
                NULL, NULL,
-               telephoneNumberSubstringsMatch, NULL, NULL,
+               telephoneNumberSubstringsMatch,
+               telephoneNumberSubstringsIndexer,
+               telephoneNumberSubstringsFilter,
                NULL},
 
        {"( 2.5.13.22 NAME 'presentationAddressMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
                SLAP_MR_EQUALITY | SLAP_MR_EXT,
                NULL, NULL,
-               presentationAddressMatch, NULL, NULL,
+               NULL, NULL, NULL,
                NULL},
 
        {"( 2.5.13.23 NAME 'uniqueMemberMatch' "