]> git.sur5r.net Git - openldap/commitdiff
ITS#5608
authorQuanah Gibson-Mount <quanah@openldap.org>
Wed, 3 Sep 2008 23:46:56 +0000 (23:46 +0000)
committerQuanah Gibson-Mount <quanah@openldap.org>
Wed, 3 Sep 2008 23:46:56 +0000 (23:46 +0000)
CHANGES
servers/slapd/schema_init.c
servers/slapd/schema_prep.c
servers/slapd/slap.h

diff --git a/CHANGES b/CHANGES
index c2e110eedd7d4f7b887168a6aa7f0344face4a28..3d3c54424e23b5d6f72a65688c5b229ad402c359 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -7,6 +7,7 @@ OpenLDAP 2.4.12 Engineering
        Fixed slapd custom attribute inheritance (ITS#5642)
        Fixed slapd dynacl mask handling (ITS#5637)
        Fixed slapd firstComponentMatch normalization (ITS#5634)
+       Added slapd caseIgnoreListMatch (ITS#5608)
        Fixed slapd overlay control registration (ITS#5649)
        Fixed slapd socket closing on Windows (ITS#5606)
        Fixed slapd syncrepl error logging (ITS#5618)
index fd386a74f2e2d2b59df75b07bc113a5566bd6171..2d8e75c34c4964604a884074d11c674b565bc3f6 100644 (file)
@@ -1987,6 +1987,119 @@ 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 rc = LDAP_SUCCESS;
+       MatchingRule *xmr = NULL;
+       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++ ) {
+               /* NOTE: we directly normalize each line,
+                * without unescaping the values, since the special
+                * values '\24' ('$') and '\5C' ('\') are not affected
+                * by normalization */
+               rc = UTF8StringNormalize( usage, NULL, xmr, &lines[l], &nlines[l], ctx );
+               if ( rc != LDAP_SUCCESS ) {
+                       rc = LDAP_INVALID_SYNTAX;
+                       goto done;
+               }
+
+               normalized->bv_len += nlines[l].bv_len;
+       }
+
+       normalized->bv_val = slap_sl_malloc( normalized->bv_len + 1, ctx );
+
+       p = normalized->bv_val;
+       for ( l = 0; !BER_BVISNULL( &nlines[l] ); l++ ) {
+               p = lutil_strncopy( p, nlines[l].bv_val, nlines[l].bv_len );
+
+               *p++ = '$';
+       }
+       *--p = '\0';
+
+       assert( p - normalized->bv_val == normalized->bv_len );
+
+done:;
+       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 +4801,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 +5106,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;