]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/schema_init.c
liberally accept many LDAPv2/LDAPv3 stuff in DN (quoted parts, ';' as rdn separator...
[openldap] / servers / slapd / schema_init.c
index cfb9494b077b1322569c39c21e336651be65c970..8437777e12722ed44d77784a3079b37862fca325 100644 (file)
 #define berValidate                                            blobValidate
 
 /* unimplemented pretters */
-#define dnPretty                                               NULL
 #define integerPretty                                  NULL
+#ifndef USE_LDAP_DN_PARSING
+#      define dnPretty                                         NULL
+#else
+#      define SLAP_LDAPDN_PRETTY 0x1
+#endif /* !USE_LDAP_DN_PARSING */
 
 /* recycled matching routines */
 #define bitStringMatch                                 octetStringMatch
@@ -71,6 +75,8 @@
 /* recycled indexing/filtering routines */
 #define dnIndexer                              caseExactIgnoreIndexer
 #define dnFilter                               caseExactIgnoreFilter
+#define bitStringFilter                        octetStringFilter
+#define bitStringIndexer               octetStringIndexer
 
 #define telephoneNumberIndexer                 caseIgnoreIA5Indexer
 #define telephoneNumberFilter                  caseIgnoreIA5Filter
@@ -216,6 +222,310 @@ int octetStringFilter(
        return LDAP_SUCCESS;
 }
 
+#ifdef USE_LDAP_DN_PARSING
+static int
+dnValidate(
+       Syntax *syntax,
+       struct berval *in )
+{
+       int             rc;
+       LDAPDN          *dn = NULL;
+
+       if ( in->bv_len == 0 ) {
+               return( LDAP_SUCCESS );
+       }
+
+       rc = ldap_str2dn( in->bv_val, &dn, LDAP_DN_FORMAT_LDAP );
+
+       /*
+        * Fixme: should we also validate each DN component?
+        */
+       ldapava_free_dn( dn );
+       
+       if ( rc != LDAP_SUCCESS ) {
+               return( LDAP_INVALID_SYNTAX );
+       }
+
+       return( LDAP_SUCCESS );
+}
+
+static void
+AVA_Sort( LDAPRDN *rdn, int iAVA )
+{
+       int             i;
+       LDAPAVA         *ava_in = rdn[ iAVA ][ 0 ];
+       
+       for ( i = 0; i < iAVA; i++ ) {
+               LDAPAVA         *ava = rdn[ i ][ 0 ];
+               int             a, j;
+
+               a = strcmp( ava_in->la_attr->bv_val, ava->la_attr->bv_val );
+
+               if ( a > 0 ) {
+                       break;
+               }
+
+               while ( a == 0 ) {
+                       int             v, d;
+
+                       d = ava_in->la_value->bv_len - ava->la_value->bv_len;
+
+                       v = memcmp( ava_in->la_value->bv_val, 
+                                       ava->la_value->bv_val,
+                                       d <= 0 ? ava_in->la_value->bv_len 
+                                               : ava->la_value->bv_len );
+
+                       if ( v == 0 && d != 0 ) {
+                               v = d;
+                       }
+
+                       if ( v <= 0 ) {
+                               /* 
+                                * got it!
+                                */
+                               break;
+                       }
+
+                       if ( ++i == iAVA ) {
+                               /*
+                                * already sorted
+                                */
+                               return;
+                       }
+
+                       ava = rdn[ i ][ 0 ];
+                       a = strcmp( ava_in->la_value->bv_val, 
+                                       ava->la_value->bv_val );
+               }
+
+               /*
+                * move ahead
+                */
+               for ( j = iAVA; j > i; j-- ) {
+                       rdn[ j ][ 0 ] = rdn[ j - 1 ][ 0 ];
+               }
+               rdn[ i ][ 0 ] = ava_in;
+
+               return;
+       }
+}
+
+/*
+ * In-place, schema-aware normalization / "pretty"ing of the
+ * structural representation of a distinguished name.
+ */
+static int
+LDAPDN_rewrite( LDAPDN *dn, unsigned flags )
+{
+       int             iRDN;
+       int             rc;
+
+       assert( dn );
+
+       for ( iRDN = 0; dn[ iRDN ]; iRDN++ ) {
+               LDAPRDN         *rdn = dn[ iRDN ][ 0 ];
+               int             iAVA;
+
+               for ( iAVA = 0; rdn[ iAVA ]; iAVA++ ) {
+                       LDAPAVA                 *ava = rdn[ iAVA ][ 0 ];
+                       AttributeDescription    *ad = NULL;
+                       const char              *text = NULL;
+                       slap_syntax_transform_func *transf = NULL;
+                       MatchingRule *mr;
+                       struct berval           *bv = NULL;
+
+                       rc = slap_bv2ad( ava->la_attr, &ad, &text );
+                       if ( rc != LDAP_SUCCESS ) {
+                               return LDAP_INVALID_SYNTAX;
+                       }
+
+                       /* 
+                        * Replace attr oid/name with the canonical name
+                        */
+                       ber_bvfree( ava->la_attr );
+                       ava->la_attr = ber_bvdup( &ad->ad_cname );
+
+                       if( flags & SLAP_LDAPDN_PRETTY ) {
+                               transf = ad->ad_type->sat_syntax->ssyn_pretty;
+                               mr = NULL;
+                       } else {
+                               transf = ad->ad_type->sat_syntax->ssyn_normalize;
+                               mr = ad->ad_type->sat_equality;
+                       }
+
+                       if ( transf ) {
+                               /*
+                                * transform value by normalize/pretty function
+                                */
+                               rc = ( *transf )( ad->ad_type->sat_syntax,
+                                       ava->la_value, &bv );
+                       
+                               if ( rc != LDAP_SUCCESS ) {
+                                       return LDAP_INVALID_SYNTAX;
+                               }
+                       }
+
+                       if( mr && ( mr->smr_usage & SLAP_MR_DN_FOLD ) ) {
+                               struct berval *s = bv;
+
+                               bv = ber_bvstr( UTF8normalize( bv ? bv : ava->la_value, 
+                                       UTF8_CASEFOLD ) );
+
+                               ber_bvfree( s );
+                       }
+
+                       if( bv ) {
+                               ber_bvfree( ava->la_value );
+                               ava->la_value = bv;
+                       }
+
+                       AVA_Sort( rdn, iAVA );
+               }
+       }
+
+       return LDAP_SUCCESS;
+}
+
+int
+dnNormalize(
+       Syntax *syntax,
+       struct berval *val,
+       struct berval **normalized )
+{
+       struct berval *out = NULL;
+
+       Debug( LDAP_DEBUG_TRACE, ">>> dnNormalize: <%s>\n", val->bv_val, 0, 0 );
+
+       if ( val->bv_len != 0 ) {
+               LDAPDN          *dn = NULL;
+               char            *dn_out = NULL;
+               int             rc;
+
+               /*
+                * Go to structural representation
+                */
+               rc = ldap_str2dn( val->bv_val, &dn, LDAP_DN_FORMAT_LDAP );
+               if ( rc != LDAP_SUCCESS ) {
+                       return LDAP_INVALID_SYNTAX;
+               }
+
+               /*
+                * Schema-aware rewrite
+                */
+               if ( LDAPDN_rewrite( dn, 0 ) != LDAP_SUCCESS ) {
+                       ldapava_free_dn( dn );
+                       return LDAP_INVALID_SYNTAX;
+               }
+
+               /*
+                * Back to string representation
+                */
+               rc = ldap_dn2str( dn, &dn_out, LDAP_DN_FORMAT_LDAPV3 );
+
+               ldapava_free_dn( dn );
+
+               if ( rc != LDAP_SUCCESS ) {
+                       return LDAP_INVALID_SYNTAX;
+               }
+
+               out = ber_bvstr( dn_out );
+
+       } else {
+               out = ber_bvdup( val );
+       }
+
+       Debug( LDAP_DEBUG_TRACE, "<<< dnNormalize: <%s>\n", out->bv_val, 0, 0 );
+
+       *normalized = out;
+
+       return LDAP_SUCCESS;
+}
+
+int
+dnPretty(
+       Syntax *syntax,
+       struct berval *val,
+       struct berval **pretty)
+{
+       struct berval *out = NULL;
+
+       Debug( LDAP_DEBUG_TRACE, ">>> dnPretty: <%s>\n", val->bv_val, 0, 0 );
+
+       if ( val->bv_len != 0 ) {
+               LDAPDN          *dn = NULL;
+               char            *dn_out = NULL;
+               int             rc;
+
+               /* FIXME: should be liberal in what we accept */
+               rc = ldap_str2dn( val->bv_val, &dn, LDAP_DN_FORMAT_LDAP );
+               if ( rc != LDAP_SUCCESS ) {
+                       return LDAP_INVALID_SYNTAX;
+               }
+
+               /*
+                * Schema-aware rewrite
+                */
+               if ( LDAPDN_rewrite( dn, SLAP_LDAPDN_PRETTY ) != LDAP_SUCCESS ) {
+                       ldapava_free_dn( dn );
+                       return LDAP_INVALID_SYNTAX;
+               }
+
+               /* FIXME: not sure why the default isn't pretty */
+               rc = ldap_dn2str( dn, &dn_out,
+                       LDAP_DN_FORMAT_LDAPV3 | LDAP_DN_PRETTY );
+
+               ldapava_free_dn( dn );
+
+               if ( rc != LDAP_SUCCESS ) {
+                       return LDAP_INVALID_SYNTAX;
+               }
+
+               out = ber_bvstr( dn_out );
+
+       } else {
+               out = ber_bvdup( val );
+       }
+
+       Debug( LDAP_DEBUG_TRACE, "<<< dnPretty: <%s>\n", out->bv_val, 0, 0 );
+
+       *pretty = out;
+
+       return LDAP_SUCCESS;
+}
+
+int
+dnMatch(
+       int *matchp,
+       slap_mask_t flags,
+       Syntax *syntax,
+       MatchingRule *mr,
+       struct berval *value,
+       void *assertedValue )
+{
+       int match;
+       struct berval *asserted = (struct berval *) assertedValue;
+       
+       match = value->bv_len - asserted->bv_len;
+
+       if ( match == 0 ) {
+               match = strcmp( value->bv_val, asserted->bv_val );
+       }
+
+#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 );
+}
+
+#else /* !USE_LDAP_DN_PARSING */
+
 static int
 dnValidate(
        Syntax *syntax,
@@ -255,7 +565,7 @@ dnNormalize(
 
        if ( val->bv_len != 0 ) {
                char *dn;
-               out = ber_bvstr( UTF8normalize( val->bv_val, UTF8_CASEFOLD ) );
+               out = ber_bvstr( UTF8normalize( val, UTF8_CASEFOLD ) );
 
                dn = dn_validate( out->bv_val );
 
@@ -274,7 +584,7 @@ dnNormalize(
        return LDAP_SUCCESS;
 }
 
-static int
+int
 dnMatch(
        int *matchp,
        slap_mask_t flags,
@@ -310,6 +620,8 @@ dnMatch(
        return LDAP_SUCCESS;
 }
 
+#endif /* !USE_LDAP_DN_PARSING */
+
 static int
 nameUIDValidate(
        Syntax *syntax,
@@ -331,13 +643,10 @@ nameUIDValidate(
                                break;
                        }
                }
-               if( dn->bv_val[i] != '\'' ) {
-                       return LDAP_INVALID_SYNTAX;
-               }
-               if( dn->bv_val[i-1] != 'B' ) {
-                       return LDAP_INVALID_SYNTAX;
-               }
-               if( dn->bv_val[i-2] != '#' ) {
+               if( dn->bv_val[i] != '\'' ||
+                   dn->bv_val[i-1] != 'B' ||
+                   dn->bv_val[i-2] != '#' ) {
+                       ber_bvfree( dn );
                        return LDAP_INVALID_SYNTAX;
                }
 
@@ -440,14 +749,21 @@ bitStringValidate(
                return LDAP_INVALID_SYNTAX;
        }
 
-       if( in->bv_val[0] != 'B' ||
-               in->bv_val[1] != '\'' ||
-               in->bv_val[in->bv_len-1] != '\'' )
+       /*
+        * rfc 2252 section 6.3 Bit String
+        * bitstring = "'" *binary-digit "'"
+        * binary-digit = "0" / "1"
+        * example: '0101111101'B
+        */
+       
+       if( in->bv_val[0] != '\'' ||
+               in->bv_val[in->bv_len-2] != '\'' ||
+               in->bv_val[in->bv_len-1] != 'B' )
        {
                return LDAP_INVALID_SYNTAX;
        }
 
-       for( i=in->bv_len-2; i>1; i-- ) {
+       for( i=in->bv_len-3; i>0; i-- ) {
                if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
                        return LDAP_INVALID_SYNTAX;
                }
@@ -456,6 +772,51 @@ bitStringValidate(
        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.
+     */
+       struct berval *newval;
+       char *p;
+
+       /* start at the first bit */
+       p = &val->bv_val[1];
+
+       /* Find the first non-zero bit */
+       while ( *p == '0' ) p++;
+
+       newval = (struct berval *) ch_malloc( sizeof(struct berval) );
+
+       if( *p == '\'' ) {
+               /* no non-zero bits */
+               newval->bv_val = ch_strdup("\'0\'B");
+               newval->bv_len = sizeof("\'0\'B") - 1;
+               goto done;
+       }
+
+       newval->bv_val = ch_malloc( val->bv_len + 1 );
+
+       newval->bv_val[0] = '\'';
+       newval->bv_len = 1;
+
+       for( ; *p != '\0'; p++ ) {
+               newval->bv_val[newval->bv_len++] = *p;
+       }
+
+       newval->bv_val[newval->bv_len] = '\0';
+
+done:
+       *normalized = newval;
+       return LDAP_SUCCESS;
+}
+
 /*
  * Handling boolean syntax and matching is quite rigid.
  * A more flexible approach would be to allow a variety
@@ -620,7 +981,7 @@ UTF8SubstringsassertionNormalize(
        }
 
        if( sa->sa_initial != NULL ) {
-               nsa->sa_initial = ber_bvstr( UTF8normalize( sa->sa_initial->bv_val, casefold ) );
+               nsa->sa_initial = ber_bvstr( UTF8normalize( sa->sa_initial, casefold ) );
                if( nsa->sa_initial == NULL ) {
                        goto err;
                }
@@ -632,7 +993,7 @@ UTF8SubstringsassertionNormalize(
                }
                nsa->sa_any = (struct berval **)ch_malloc( (i + 1) * sizeof(struct berval *) );
                for( i=0; sa->sa_any[i] != NULL; i++ ) {
-                       nsa->sa_any[i] = ber_bvstr( UTF8normalize( sa->sa_any[i]->bv_val, casefold ) );
+                       nsa->sa_any[i] = ber_bvstr( UTF8normalize( sa->sa_any[i], casefold ) );
                        if( nsa->sa_any[i] == NULL ) {
                                goto err;
                        }
@@ -641,7 +1002,7 @@ UTF8SubstringsassertionNormalize(
        }
 
        if( sa->sa_final != NULL ) {
-               nsa->sa_final = ber_bvstr( UTF8normalize( sa->sa_final->bv_val, casefold ) );
+               nsa->sa_final = ber_bvstr( UTF8normalize( sa->sa_final, casefold ) );
                if( nsa->sa_final == NULL ) {
                        goto err;
                }
@@ -650,9 +1011,9 @@ UTF8SubstringsassertionNormalize(
        return nsa;
 
 err:
-       ch_free( nsa->sa_final );
+       ber_bvfree( nsa->sa_final );
        ber_bvecfree( nsa->sa_any );
-       ch_free( nsa->sa_initial );
+       ber_bvfree( nsa->sa_initial );
        ch_free( nsa );
        return NULL;
 }
@@ -700,23 +1061,23 @@ approxMatch(
        struct berval *value,
        void *assertedValue )
 {
-       char *val, *assertv, **values, **words, *c;
+       char *val, *nval, *assertv, **values, **words, *c;
        int i, count, len, nextchunk=0, nextavail=0;
        size_t avlen;
 
        /* Yes, this is necessary */
-       val = UTF8normalize( value->bv_val, UTF8_NOCASEFOLD );
-       if( val == NULL ) {
+       nval = UTF8normalize( value, UTF8_NOCASEFOLD );
+       if( nval == NULL ) {
                *matchp = 1;
                return LDAP_SUCCESS;
        }
-       strip8bitChars( val );
+       strip8bitChars( nval );
 
        /* Yes, this is necessary */
-       assertv = UTF8normalize( ((struct berval *)assertedValue)->bv_val,
+       assertv = UTF8normalize( ((struct berval *)assertedValue),
                                 UTF8_NOCASEFOLD );
        if( assertv == NULL ) {
-               free( val );
+               ch_free( nval );
                *matchp = 1;
                return LDAP_SUCCESS;
        }
@@ -724,7 +1085,7 @@ approxMatch(
        avlen = strlen( assertv );
 
        /* Isolate how many words there are */
-       for( c=val,count=1; *c; c++ ) {
+       for( c=nval,count=1; *c; c++ ) {
                c = strpbrk( c, SLAPD_APPROX_DELIMITER );
                if ( c == NULL ) break;
                *c = '\0';
@@ -734,7 +1095,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=nval,i=0;  i<count;  i++,c+=strlen(c)+1 ) {
                words[i] = c;
                values[i] = phonetic(c);
        }
@@ -770,6 +1131,7 @@ approxMatch(
                                        break;
                                }
                        }
+                       ch_free( val );
                }
 
                /* This chunk in the asserted value was NOT within the *value. */
@@ -797,7 +1159,7 @@ approxMatch(
        }
        ch_free( values );
        ch_free( words );
-       free( val );
+       ch_free( nval );
 
        return LDAP_SUCCESS;
 }
@@ -818,7 +1180,7 @@ approxIndexer(
 
        for( j=0; values[j] != NULL; j++ ) {
                /* Yes, this is necessary */
-               val = UTF8normalize( values[j]->bv_val, UTF8_NOCASEFOLD );
+               val = UTF8normalize( values[j], UTF8_NOCASEFOLD );
                strip8bitChars( val );
 
                /* Isolate how many words there are. There will be a key for each */
@@ -871,7 +1233,7 @@ approxFilter(
        struct berval **keys;
 
        /* Yes, this is necessary */
-       val = UTF8normalize( ((struct berval *)assertValue)->bv_val,
+       val = UTF8normalize( ((struct berval *)assertValue),
                             UTF8_NOCASEFOLD );
        if( val == NULL ) {
                keys = (struct berval **)ch_malloc( sizeof(struct berval *) );
@@ -926,14 +1288,14 @@ approxMatch(
        char *s, *t;
 
        /* Yes, this is necessary */
-       s = UTF8normalize( value->bv_val, UTF8_NOCASEFOLD );
+       s = UTF8normalize( value, UTF8_NOCASEFOLD );
        if( s == NULL ) {
                *matchp = 1;
                return LDAP_SUCCESS;
        }
 
        /* Yes, this is necessary */
-       t = UTF8normalize( ((struct berval *)assertedValue)->bv_val,
+       t = UTF8normalize( ((struct berval *)assertedValue),
                           UTF8_NOCASEFOLD );
        if( t == NULL ) {
                free( s );
@@ -981,7 +1343,7 @@ approxIndexer(
        /* Copy each value and run it through phonetic() */
        for( i=0; values[i] != NULL; i++ ) {
                /* Yes, this is necessary */
-               s = UTF8normalize( values[i]->bv_val, UTF8_NOCASEFOLD );
+               s = UTF8normalize( values[i], UTF8_NOCASEFOLD );
 
                /* strip 8-bit chars and run through phonetic() */
                keys[i] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
@@ -1010,7 +1372,7 @@ approxFilter(
        keys = (struct berval **)ch_malloc( sizeof( struct berval * ) * 2 );
 
        /* Yes, this is necessary */
-       s = UTF8normalize( ((struct berval *)assertValue)->bv_val,
+       s = UTF8normalize( ((struct berval *)assertValue),
                             UTF8_NOCASEFOLD );
        if( s == NULL ) {
                keys[0] = NULL;
@@ -1052,7 +1414,7 @@ caseExactIgnoreSubstringsMatch(
        void *assertedValue )
 {
        int match = 0;
-       SubstringsAssertion *sub;
+       SubstringsAssertion *sub = NULL;
        struct berval left;
        int i;
        ber_len_t inlen=0;
@@ -1061,7 +1423,7 @@ caseExactIgnoreSubstringsMatch(
        casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
                ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
 
-       nav = UTF8normalize( value->bv_val, casefold );
+       nav = UTF8normalize( value, casefold );
        if( nav == NULL ) {
                match = 1;
                goto done;
@@ -1152,6 +1514,11 @@ retry:
 
                        if( idx >= left.bv_len ) {
                                /* this shouldn't happen */
+                               free( nav );
+                               ch_free( sub->sa_final );
+                               ber_bvecfree( sub->sa_any );
+                               ch_free( sub->sa_initial );
+                               ch_free( sub );
                                return LDAP_OTHER;
                        }
 
@@ -1183,9 +1550,9 @@ retry:
 done:
        free( nav );
        if( sub != NULL ) {
-               ch_free( sub->sa_final );
+               ber_bvfree( sub->sa_final );
                ber_bvecfree( sub->sa_any );
-               ch_free( sub->sa_initial );
+               ber_bvfree( sub->sa_initial );
                ch_free( sub );
        }
        *matchp = match;
@@ -1229,7 +1596,7 @@ int caseExactIgnoreIndexer(
 
        for( i=0; values[i] != NULL; i++ ) {
                struct berval *value;
-               value = ber_bvstr( UTF8normalize( values[i]->bv_val,
+               value = ber_bvstr( UTF8normalize( values[i],
                        casefold ) );
 
                HASH_Init( &HASHcontext );
@@ -1281,7 +1648,7 @@ int caseExactIgnoreFilter(
        casefold = strcmp( mr->smr_oid, caseExactMatchOID )
                ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
 
-       value = ber_bvstr( UTF8normalize( ((struct berval *) assertValue)->bv_val,
+       value = ber_bvstr( UTF8normalize( ((struct berval *) assertValue),
                casefold ) );
        /* This usually happens if filter contains bad UTF8 */
        if( value == NULL ) {
@@ -1350,7 +1717,7 @@ int caseExactIgnoreSubstringsIndexer(
 
        nvalues = ch_malloc( sizeof( struct berval * ) * (i+1) );
        for( i=0; values[i] != NULL; i++ ) {
-               nvalues[i] = ber_bvstr( UTF8normalize( values[i]->bv_val,
+               nvalues[i] = ber_bvstr( UTF8normalize( values[i],
                        casefold ) );
        }
        nvalues[i] = NULL;
@@ -1390,6 +1757,7 @@ int caseExactIgnoreSubstringsIndexer(
        if( nkeys == 0 ) {
                /* no keys to generate */
                *keysp = NULL;
+               ber_bvecfree( nvalues );
                return LDAP_SUCCESS;
        }
 
@@ -1550,9 +1918,9 @@ int caseExactIgnoreSubstringsFilter(
        }
 
        if( nkeys == 0 ) {
-               ch_free( sa->sa_final );
+               ber_bvfree( sa->sa_final );
                ber_bvecfree( sa->sa_any );
-               ch_free( sa->sa_initial );
+               ber_bvfree( sa->sa_initial );
                ch_free( sa );
                *keysp = NULL;
                return LDAP_SUCCESS;
@@ -1665,9 +2033,9 @@ int caseExactIgnoreSubstringsFilter(
                ch_free( keys );
                *keysp = NULL;
        }
-       ch_free( sa->sa_final );
+       ber_bvfree( sa->sa_final );
        ber_bvecfree( sa->sa_any );
-       ch_free( sa->sa_initial );
+       ber_bvfree( sa->sa_initial );
        ch_free( sa );
 
        return LDAP_SUCCESS;
@@ -3472,7 +3840,6 @@ asn1_integer2str(ASN1_INTEGER *a)
                 */
                while (base < n) {
                        unsigned int carry;
-                       unsigned int temp;
 
                        carry = 0;
                        for (i = base; i<n; i++ ) {
@@ -3485,7 +3852,8 @@ asn1_integer2str(ASN1_INTEGER *a)
                                 * Way too large, we need to leave
                                 * room for sign if negative
                                 */
-                         return NULL;
+                               free(copy);
+                               return NULL;
                        }
                        *--p = digit[carry];
                        if (copy[base] == 0)
@@ -3543,7 +3911,6 @@ certificateExactConvert(
        struct berval *serial;
        struct berval *issuer_dn;
        struct berval *bv_tmp;
-       int ret;
 
        xcert = d2i_X509(NULL, &p, in->bv_len);
        if ( !xcert ) {
@@ -4031,7 +4398,7 @@ utcTimeNormalize(
                return LBER_ERROR_MEMORY;
        }
 
-       sprintf( out->bv_val, "%02ld%02ld%02ld%02ld%02ld%02ldZ",
+       sprintf( out->bv_val, "%02d%02d%02d%02d%02d%02dZ",
                parts[1], parts[2] + 1, parts[3] + 1,
                parts[4], parts[5], parts[6] );
        out->bv_len = 13;
@@ -4086,7 +4453,7 @@ generalizedTimeNormalize(
                return LBER_ERROR_MEMORY;
        }
 
-       sprintf( out->bv_val, "%02ld%02ld%02ld%02ld%02ld%02ld%02ldZ",
+       sprintf( out->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
                parts[0], parts[1], parts[2] + 1, parts[3] + 1,
                parts[4], parts[5], parts[6] );
        out->bv_len = 15;
@@ -4212,7 +4579,7 @@ struct syntax_defs_rec syntax_defs[] = {
        {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' " 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, NULL, NULL },
+               0, bitStringValidate, bitStringNormalize, 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' "
@@ -4330,10 +4697,13 @@ struct syntax_defs_rec syntax_defs[] = {
 
        /* OpenLDAP Experimental Syntaxes */
        {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
-               0, UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
+               SLAP_SYNTAX_HIDE,
+               UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
                NULL, NULL},
+
+       /* needs updating */
        {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
-               0, NULL, NULL, NULL},
+               SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
 
        /* OpenLDAP Void Syntax */
        {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
@@ -4420,7 +4790,7 @@ struct mrule_defs_rec mrule_defs[] = {
 
        {"( 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_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
                NULL, NULL,
                caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
                directoryStringApproxMatchOID },
@@ -4466,7 +4836,7 @@ struct 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,
+               SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
                NULL, NULL,
                caseIgnoreIA5Match,
                caseIgnoreIA5Indexer,
@@ -4484,7 +4854,7 @@ struct mrule_defs_rec mrule_defs[] = {
 
        {"( 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_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
                NULL, NULL,
                caseIgnoreListMatch, NULL, NULL,
                NULL},
@@ -4514,7 +4884,7 @@ struct mrule_defs_rec mrule_defs[] = {
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
                SLAP_MR_EQUALITY | SLAP_MR_EXT,
                NULL, NULL,
-               bitStringMatch, NULL, NULL,
+               bitStringMatch, bitStringIndexer, bitStringFilter,
                NULL},
 
        {"( 2.5.13.17 NAME 'octetStringMatch' "
@@ -4526,7 +4896,7 @@ struct mrule_defs_rec mrule_defs[] = {
 
        {"( 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_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
                NULL, NULL,
                telephoneNumberMatch,
                telephoneNumberIndexer,
@@ -4610,7 +4980,7 @@ struct mrule_defs_rec mrule_defs[] = {
 
        {"( 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_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
                NULL, NULL,
                caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
                IA5StringApproxMatchOID },
@@ -4633,6 +5003,7 @@ struct mrule_defs_rec mrule_defs[] = {
                caseExactIA5SubstringsFilter,
                NULL},
 
+       /* 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,
@@ -4721,3 +5092,12 @@ schema_init( void )
        schema_init_done = 1;
        return LDAP_SUCCESS;
 }
+
+void
+schema_destroy( void )
+{
+       oc_destroy();
+       at_destroy();
+       mr_destroy();
+       syn_destroy();
+}