]> git.sur5r.net Git - openldap/commitdiff
SLAP_NVALUES: a couple of basic normalizers... but not working yet.
authorKurt Zeilenga <kurt@openldap.org>
Fri, 28 Feb 2003 05:13:29 +0000 (05:13 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Fri, 28 Feb 2003 05:13:29 +0000 (05:13 +0000)
servers/slapd/modify.c
servers/slapd/schema_init.c
servers/slapd/schema_prep.c
servers/slapd/slap.h

index a24e250abb05eee0c7c87f8efa86e0b0db33ccf4..885066970e2a89b83c890234f1138e033ebce751 100644 (file)
@@ -607,6 +607,20 @@ int slap_mods_check(
                                }
                        }
 
+                       /*
+                        * a rough single value check... an additional check is needed
+                        * to catch add of single value to existing single valued attribute
+                        */
+                       if ((ml->sml_op == LDAP_MOD_ADD || ml->sml_op == LDAP_MOD_REPLACE)
+                               && nvals > 1 && is_at_single_value( ad->ad_type ))
+                       {
+                               snprintf( textbuf, textlen,
+                                       "%s: multiple values provided",
+                                       ml->sml_type.bv_val );
+                               *text = textbuf;
+                               return LDAP_CONSTRAINT_VIOLATION;
+                       }
+
 #ifdef SLAP_NVALUES
                        if( nvals && ad->ad_type->sat_equality &&
                                ad->ad_type->sat_equality->smr_normalize )
@@ -639,20 +653,6 @@ int slap_mods_check(
                                ml->sml_nvalues[nvals].bv_len = 0;
                        }
 #endif
-
-                       /*
-                        * a rough single value check... an additional check is needed
-                        * to catch add of single value to existing single valued attribute
-                        */
-                       if ((ml->sml_op == LDAP_MOD_ADD || ml->sml_op == LDAP_MOD_REPLACE)
-                               && nvals > 1 && is_at_single_value( ad->ad_type ))
-                       {
-                               snprintf( textbuf, textlen,
-                                       "%s: multiple value provided",
-                                       ml->sml_type.bv_val );
-                               *text = textbuf;
-                               return LDAP_CONSTRAINT_VIOLATION;
-                       }
                }
        }
 
index 16271a6a29f4efa3bd634181785af0881f819f2b..070c14cde41b6e2d62390f49b107b7d24ccc0c18 100644 (file)
@@ -32,6 +32,9 @@
 /* TO BE DELETED */
 #define SLAP_MR_DN_FOLD (0)
 
+#define SLAP_MR_ASSOCIATED(mr, with) \
+       ((mr) == (with) || (mr)->smr_associated == (with))
+
 #define xUTF8StringNormalize NULL
 #define xIA5StringNormalize NULL
 #define xtelephoneNumberNormalize NULL
 #define xnumericStringNormalize NULL
 #define xnameUIDNormalize NULL
 
+/* (new) normalization routines */
+#define caseExactIA5Normalize                                          IA5StringNormalize
+#define caseIgnoreIA5Normalize                                         IA5StringNormalize
+#define caseExactNormalize                                                     UTF8StringNormalize
+#define caseIgnoreNormalize                                                    UTF8StringNormalize
+
+#define distinguishedNameNormalize                                     NULL
+#define integerNormalize                                                       NULL
+#define integerFirstComponentNormalize                         NULL
+#define numericStringNormalize                                         NULL
+#define objectIdentifierNormalize                                      NULL
+#define objectIdentifierFirstComponentNormalize                NULL
+#define generalizedTimeNormalize                                       NULL
+#define uniqueMemberNormalize                                          NULL
+#define bitStringNormalize                                                     NULL
+#define telephoneNumberNormalize                                       NULL
+
 #define distinguishedNameMatch         dnMatch
 #define distinguishedNameIndexer       octetStringIndexer
 #define distinguishedNameFilter                octetStringFilter
 /* validatation routines */
 #define berValidate                                            blobValidate
 
-/* (new) normalization routines */
-#define caseExactNormalize                                                     NULL
-#define caseExactIA5Normalize                                          NULL
-#define caseIgnoreNormalize                                                    NULL
-#define caseIgnoreIA5Normalize                                         NULL
-#define distinguishedNameNormalize                                     NULL
-#define integerNormalize                                                       NULL
-#define integerFirstComponentNormalize                         NULL
-#define numericStringNormalize                                         NULL
-#define objectIdentifierNormalize                                      NULL
-#define objectIdentifierFirstComponentNormalize                NULL
-#define generalizedTimeNormalize                                       NULL
-#define uniqueMemberNormalize                                          NULL
-#define bitStringNormalize                                                     NULL
-#define telephoneNumberNormalize                                       NULL
-
 /* approx matching rules */
 #ifdef SLAP_NVALUES
 #define directoryStringApproxMatchOID  NULL
 
 #ifndef SLAP_NVALUES
 
+/* (new) normalization routines */
+#define caseExactNormalize                                                     NULL
+#define caseExactIA5Normalize                                          NULL
+#define caseIgnoreNormalize                                                    NULL
+#define caseIgnoreIA5Normalize                                         NULL
+#define distinguishedNameNormalize                                     NULL
+#define integerNormalize                                                       NULL
+#define integerFirstComponentNormalize                         NULL
+#define numericStringNormalize                                         NULL
+#define objectIdentifierNormalize                                      NULL
+#define objectIdentifierFirstComponentNormalize                NULL
+#define generalizedTimeNormalize                                       NULL
+#define uniqueMemberNormalize                                          NULL
+#define bitStringNormalize                                                     NULL
+#define telephoneNumberNormalize                                       NULL
+
+
 /* matching routines */
 #define bitStringMatch                                 octetStringMatch
 #define bitStringIndexer                               octetStringIndexer
@@ -569,9 +590,10 @@ LDAP/X.500 string syntax / matching rules have a few oddities.  This
 comment attempts to detail how slapd(8) treats them.
 
 Summary:
-  StringSyntax         X.500   LDAP    Matching
+  StringSyntax         X.500   LDAP    Matching/Comments
   DirectoryString      CHOICE  UTF8    i/e + ignore insignificant spaces
   PrintableString      subset  subset  i/e + ignore insignificant spaces
+  PrintableString      subset  subset  i/e + ignore insignificant spaces
   NumericString                subset  subset  ignore all spaces
   IA5String                    ASCII   ASCII   i/e + ignore insignificant spaces
   TeletexString                T.61    T.61    i/e + ignore insignificant spaces
@@ -588,6 +610,7 @@ Directory String -
   must be non-empty.
 
   In LDAPv3, a directory string is a UTF-8 encoded UCS string.
+  A directory string cannot be zero length.
 
   For matching, there are both case ignore and exact rules.  Both
   also require that "insignificant" spaces be ignored.
@@ -643,7 +666,10 @@ UTF8StringValidate(
        int len;
        unsigned char *u = in->bv_val;
 
-       if( !in->bv_len ) return LDAP_INVALID_SYNTAX;
+       if( in->bv_len == 0 && syntax == slap_schema.si_syn_directoryString ) {
+               /* directory strings cannot be empty */
+               return LDAP_INVALID_SYNTAX;
+       }
 
        for( count = in->bv_len; count > 0; count-=len, u+=len ) {
                /* get the length indicated by the first byte */
@@ -683,12 +709,79 @@ UTF8StringValidate(
                if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
        }
 
-       if( count != 0 ) return LDAP_INVALID_SYNTAX;
+       if( count != 0 ) {
+               return LDAP_INVALID_SYNTAX;
+       }
 
        return LDAP_SUCCESS;
 }
 
-#ifndef SLAP_NVALUES
+#ifdef SLAP_NVALUES
+static int
+UTF8StringNormalize(
+       slap_mask_t use,
+       Syntax *syntax,
+       MatchingRule *mr,
+       struct berval *val,
+       struct berval *normalized )
+{
+       struct berval tmp, nvalue;
+       int flags;
+       int i, wasspace;
+
+       if( val->bv_val == NULL ) {
+               /* assume we're dealing with a syntax (e.g., UTF8String)
+                * which allows empty strings
+                */
+               normalized->bv_len = 0;
+               normalized->bv_val = NULL;
+               return LDAP_SUCCESS;
+       }
+
+       flags = SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactMatch )
+               ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
+       flags |= ( use & SLAP_MR_EQUALITY_APPROX == SLAP_MR_EQUALITY_APPROX )
+               ? LDAP_UTF8_APPROX : 0;
+
+       val = UTF8bvnormalize( val, &tmp, flags );
+       if( val == NULL ) {
+               return LDAP_OTHER;
+       }
+       
+       /* collapse spaces (in place) */
+       nvalue.bv_len = 0;
+       nvalue.bv_val = tmp.bv_val;
+
+       wasspace=1; /* trim leading spaces */
+       for( i=0; i<tmp.bv_len; i++) {
+               if ( ASCII_SPACE( tmp.bv_val[i] )) {
+                       if( wasspace++ == 0 ) {
+                               /* trim repeated spaces */
+                               nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
+                       }
+               } else {
+                       wasspace = 0;
+                       nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
+               }
+       }
+
+       if( nvalue.bv_len ) {
+               if( wasspace ) {
+                       /* last character was a space, trim it */
+                       --nvalue.bv_len;
+               }
+               nvalue.bv_val[nvalue.bv_len] = '\0';
+
+       } else {
+               /* string of all spaces is treated as one space */
+               nvalue.bv_val[0] = ' ';
+               nvalue.bv_val[1] = '\0';
+               nvalue.bv_len = 1;
+       }
+
+       return LDAP_SUCCESS;
+}
+#else
 
 static int
 xUTF8StringNormalize(
@@ -2288,15 +2381,26 @@ IA5StringValidate(
        return LDAP_SUCCESS;
 }
 
-#ifndef SLAP_NVALUES
-
+#ifdef SLAP_NVALUES
+static int
+IA5StringNormalize(
+       slap_mask_t use,
+       Syntax *syntax,
+       MatchingRule *mr,
+       struct berval *val,
+       struct berval *normalized )
+#else
 static int
 xIA5StringNormalize(
        Syntax *syntax,
        struct berval *val,
        struct berval *normalized )
+#endif
 {
        char *p, *q;
+#ifdef SLAP_NVALUES
+       int casefold = !SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactIA5Match);
+#endif
 
        assert( val->bv_len );
 
@@ -2318,6 +2422,13 @@ xIA5StringNormalize(
                        while ( ASCII_SPACE( *p ) ) {
                                p++;
                        }
+
+#ifdef SLAP_NVALUES
+               } else if ( casefold ) {
+                       /* Most IA5 rules require casefolding */
+                       *q++ = TOLOWER(*p++);
+#endif
+
                } else {
                        *q++ = *p++;
                }
@@ -2351,6 +2462,8 @@ xIA5StringNormalize(
        return LDAP_SUCCESS;
 }
 
+#ifndef SLAP_NVALUES
+
 static int
 caseExactIA5Match(
        int *matchp,
@@ -4839,7 +4952,7 @@ static slap_mrule_defs_rec mrule_defs[] = {
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
                SLAP_MR_ORDERING, NULL,
                NULL,
-               generalizedTimeOrderingMatch, generalizedTimeOrderingMatch,
+               generalizedTimeNormalize, generalizedTimeOrderingMatch,
                NULL, NULL,
                NULL},
 
index abb2b2217a04f597ccad3f261ec4ecc4ffc33358..5905bb61c84aead02a687efdd8b859a521aeb27f 100644 (file)
@@ -796,6 +796,8 @@ static struct slap_schema_mr_map {
        char *ssmm_name;
        size_t ssmm_offset;
 } mr_map[] = {
+       { "caseExactIA5Match",
+               offsetof(struct slap_internal_schema, si_mr_caseExactIA5Match) },
        { "caseExactMatch",
                offsetof(struct slap_internal_schema, si_mr_caseExactMatch) },
        { "caseExactSubstringsMatch",
@@ -814,12 +816,14 @@ static struct slap_schema_syn_map {
        char *sssm_name;
        size_t sssm_offset;
 } syn_map[] = {
-       { "1.3.6.1.4.1.1466.115.121.1.40",
-               offsetof(struct slap_internal_schema, si_syn_octetString) },
+       { "1.3.6.1.4.1.1466.115.121.1.15",
+               offsetof(struct slap_internal_schema, si_syn_directoryString) },
        { "1.3.6.1.4.1.1466.115.121.1.12",
                offsetof(struct slap_internal_schema, si_syn_distinguishedName) },
        { "1.3.6.1.4.1.1466.115.121.1.27",
                offsetof(struct slap_internal_schema, si_syn_integer) },
+       { "1.3.6.1.4.1.1466.115.121.1.40",
+               offsetof(struct slap_internal_schema, si_syn_octetString) },
        { NULL, 0 }
 };
 
index 8d033a96a2161776b132591dcebe02fc07080539..340e46538f3226dce717612293c9ebccf2dc4262 100644 (file)
@@ -792,13 +792,15 @@ struct slap_internal_schema {
        MatchingRule    *si_mr_distinguishedNameMatch;
        MatchingRule    *si_mr_caseExactMatch;
        MatchingRule    *si_mr_caseExactSubstringsMatch;
+       MatchingRule    *si_mr_caseExactIA5Match;
        MatchingRule    *si_mr_integerMatch;
        MatchingRule    *si_mr_integerFirstComponentMatch;
 
        /* Syntaxes */
-       Syntax          *si_syn_octetString;
+       Syntax          *si_syn_directoryString;
        Syntax          *si_syn_distinguishedName;
        Syntax          *si_syn_integer;
+       Syntax          *si_syn_octetString;
 };
 
 typedef struct slap_attr_assertion {