]> git.sur5r.net Git - openldap/commitdiff
implement caseIgnoreListMatch (ITS#5608)
authorPierangelo Masarati <ando@openldap.org>
Sat, 30 Aug 2008 14:30:31 +0000 (14:30 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sat, 30 Aug 2008 14:30:31 +0000 (14:30 +0000)
servers/slapd/schema_init.c
servers/slapd/schema_prep.c
servers/slapd/slap.h

index fd386a74f2e2d2b59df75b07bc113a5566bd6171..26c3ec4a5e0228410bf0009313cc9e7a4b80c114 100644 (file)
@@ -1987,6 +1987,168 @@ telephoneNumberNormalize(
        return LDAP_SUCCESS;
 }
 
+static int
+postalAddressValidate(
+       Syntax *syntax,
+       struct berval *in )
+{
+       struct berval bv = *in;
+       int c;
+
+       for ( c = 0; c < in->bv_len; c++ ) {
+               if ( in->bv_val[c] == '\\' ) {
+                       c++;
+                       if ( strncasecmp( &in->bv_val[c], "24", STRLENOF( "24" ) ) != 0
+                               && strncasecmp( &in->bv_val[c], "5C", STRLENOF( "5C" ) ) != 0 )
+                       {
+                               return LDAP_INVALID_SYNTAX;
+                       }
+                       continue;
+               }
+
+               if ( in->bv_val[c] == '$' ) {
+                       bv.bv_len = &in->bv_val[c] - bv.bv_val;
+                       if ( UTF8StringValidate( NULL, &bv ) != LDAP_SUCCESS ) {
+                               return LDAP_INVALID_SYNTAX;
+                       }
+                       bv.bv_val = &in->bv_val[c] + 1;
+               }
+       }
+
+       bv.bv_len = &in->bv_val[c] - bv.bv_val;
+       return UTF8StringValidate( NULL, &bv );
+}
+
+static int
+postalAddressNormalize(
+       slap_mask_t usage,
+       Syntax *syntax,
+       MatchingRule *mr,
+       struct berval *val,
+       struct berval *normalized,
+       void *ctx )
+{
+       BerVarray lines = NULL, nlines = NULL;
+       int l, c;
+       int nescapes = 0;
+       int rc = LDAP_SUCCESS;
+       MatchingRule *xmr = NULL;
+       struct berval bv = BER_BVNULL;
+       char *p;
+
+       if ( SLAP_MR_ASSOCIATED( mr, slap_schema.si_mr_caseIgnoreListMatch ) ) {
+               xmr = slap_schema.si_mr_caseIgnoreMatch;
+
+       } else {
+               xmr = slap_schema.si_mr_caseExactMatch;
+       }
+
+       for ( l = 0, c = 0; c < val->bv_len; c++ ) {
+               if ( val->bv_val[c] == '$' ) {
+                       l++;
+               }
+       }
+
+       lines = slap_sl_calloc( sizeof( struct berval ), 2 * ( l + 2 ), ctx );
+       nlines = &lines[l + 2];
+
+       lines[0].bv_val = val->bv_val;
+       for ( l = 0, c = 0; c < val->bv_len; c++ ) {
+               if ( val->bv_val[c] == '$' ) {
+                       lines[l].bv_len = &val->bv_val[c] - lines[l].bv_val;
+                       l++;
+                       lines[l].bv_val = &val->bv_val[c + 1];
+               }
+       }
+       lines[l].bv_len = &val->bv_val[c] - lines[l].bv_val;
+
+       normalized->bv_len = l;
+
+       for ( l = 0; !BER_BVISNULL( &lines[l] ); l++ ) {
+               int s, d;
+               ber_len_t oldlen;
+
+               ber_bvreplace_x( &bv, &lines[l], ctx );
+               oldlen = bv.bv_len;
+               for ( d = 0, s = 0; s < oldlen; d++, s++ ) {
+                       if ( bv.bv_val[s] == '\\' ) {
+                               if ( &bv.bv_val[s] - &bv.bv_val[0] + STRLENOF( "\\XX" ) > oldlen ) {
+                                       rc = LDAP_INVALID_SYNTAX;
+                                       goto done;
+
+                               } else if ( strncasecmp( &bv.bv_val[s + 1], "24", STRLENOF( "24" ) ) == 0 ) {
+                                       bv.bv_val[d] = '$';
+
+                               } else if ( strncasecmp( &bv.bv_val[s + 1], "5C", STRLENOF( "5C" ) ) == 0 ) {
+                                       bv.bv_val[d] = '\\';
+
+                               } else {
+                                       rc = LDAP_INVALID_SYNTAX;
+                                       goto done;
+                               }
+
+                               nescapes++;
+                               s += 2;
+                               bv.bv_len -= 2;
+
+                       } else {
+                               bv.bv_val[d] = bv.bv_val[s];
+                       }
+               }
+
+               rc = UTF8StringNormalize( usage, NULL, xmr, &bv, &nlines[l], ctx );
+               if ( rc != LDAP_SUCCESS ) {
+                       rc = LDAP_INVALID_SYNTAX;
+                       goto done;
+               }
+
+               normalized->bv_len += nlines[l].bv_len;
+       }
+
+       normalized->bv_len += 2*nescapes;
+
+       normalized->bv_val = slap_sl_malloc( normalized->bv_len + 1, ctx );
+
+       p = normalized->bv_val;
+       for ( l = 0; !BER_BVISNULL( &nlines[l] ); l++ ) {
+               for ( c = 0; c < nlines[l].bv_len; c++ ) {
+                       switch ( nlines[l].bv_val[c] ) {
+                       case '\\':
+                               p = lutil_strcopy( p, "\\5C" );
+                               break;
+
+                       case '$':
+                               p = lutil_strcopy( p, "\\24" );
+                               break;
+
+                       default:
+                               *p++ = nlines[l].bv_val[c];
+                               break;
+                       }
+               }
+
+               *p++ = '$';
+       }
+       *--p = '\0';
+
+       assert( p - normalized->bv_val == normalized->bv_len );
+
+done:;
+       if ( !BER_BVISNULL( &bv ) ) {
+               ber_memfree_x( bv.bv_val, ctx );
+       }
+
+       if ( nlines != NULL ) {
+               for ( l = 0; !BER_BVISNULL( &nlines[ l ] ); l++ ) {
+                       slap_sl_free( nlines[l].bv_val, ctx );
+               }
+
+               slap_sl_free( lines, ctx );
+       }
+
+       return rc;
+}
+
 int
 numericoidValidate(
        Syntax *syntax,
@@ -4688,7 +4850,7 @@ static slap_syntax_defs_rec syntax_defs[] = {
        {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
                0, NULL, blobValidate, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
-               0, NULL, UTF8StringValidate, NULL},
+               0, NULL, postalAddressValidate, 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' )",
@@ -4993,7 +5155,9 @@ static slap_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, NULL,
-               NULL, NULL, NULL, NULL, NULL, NULL },
+               NULL, postalAddressNormalize, octetStringMatch,
+               octetStringIndexer, octetStringFilter,
+               NULL },
 
        {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
index 42f9a5e94334f93f43fcb644e54276678982c7b5..28bcc96c1debd61e3f804f43783a754e1263ee83 100644 (file)
@@ -1072,6 +1072,10 @@ static struct slap_schema_mr_map {
        { "objectIdentifierFirstComponentMatch",
                offsetof(struct slap_internal_schema,
                        si_mr_objectIdentifierFirstComponentMatch) },
+       { "caseIgnoreMatch",
+               offsetof(struct slap_internal_schema, si_mr_caseIgnoreMatch) },
+       { "caseIgnoreListMatch",
+               offsetof(struct slap_internal_schema, si_mr_caseIgnoreListMatch) },
        { NULL, 0 }
 };
 
index 431a7743b76fe3fc65a31c875974eefab43fd05c..95c4e898ac109f7a92885d54341f2b928e95c37f 100644 (file)
@@ -969,6 +969,8 @@ struct slap_internal_schema {
        MatchingRule    *si_mr_integerMatch;
        MatchingRule    *si_mr_integerFirstComponentMatch;
        MatchingRule    *si_mr_objectIdentifierFirstComponentMatch;
+       MatchingRule    *si_mr_caseIgnoreMatch;
+       MatchingRule    *si_mr_caseIgnoreListMatch;
 
        /* Syntaxes */
        Syntax          *si_syn_directoryString;