]> git.sur5r.net Git - openldap/commitdiff
Modify slapd syntax struct to have both a validation and normalization
authorKurt Zeilenga <kurt@openldap.org>
Mon, 24 Jan 2000 23:31:26 +0000 (23:31 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Mon, 24 Jan 2000 23:31:26 +0000 (23:31 +0000)
routine.  Could be combined into one routine.
Modify slapd matching rule struct to only have match function.
Modify old attribute such that 'bin' implies octetString, not 'binary'.
Add compatibility for IA5 strings.  Only directoryStrings were handled
before.
Treat attribute types without syntax as incomplete, not default.
Add OctetStringValidate (always returns okay).
Add {UTF8,IA5}StringValidate/Normalize  (IA5 based loosely on
case_exact_normalize).  Need case{Exact,Ignore}UTFMatch, using IA5 versions
for now.
Removed default of syntax/mr handlders, should just skip
registration of syntax/mr's without handlers.
Added comments to slap.h about types versus descriptions.

servers/slapd/attr.c
servers/slapd/proto-slap.h
servers/slapd/schema.c
servers/slapd/slap.h

index 1c4067c7498cc369bfbe9fef937e8870806cb054..4d94aced307ccb7f85d5bbaa55b8048afd9cbb41 100644 (file)
@@ -282,31 +282,45 @@ attr_syntax_config(
        at = (LDAP_ATTRIBUTE_TYPE *)
                ch_calloc( 1, sizeof(LDAP_ATTRIBUTE_TYPE) );
 
+#define SYNTAX_DS_OID  "1.3.6.1.4.1.1466.115.121.1.15"
+#define SYNTAX_DSCE_OID        "2.5.13.5"
+#define SYNTAX_IA5_OID "1.3.6.1.4.1.1466.115.121.1.26"
+#define SYNTAX_IA5CE_OID       "1.3.6.1.4.1.1466.109.114.1"
+#define SYNTAX_DN_OID  "1.3.6.1.4.1.1466.115.121.1.12"
+#define SYNTAX_TEL_OID "1.3.6.1.4.1.1466.115.121.1.50"
+#define SYNTAX_BIN_OID "1.3.6.1.4.1.1466.115.121.1.40" /* octetString */
+
        lasti = argc - 1;
        if ( strcasecmp( argv[lasti], "caseignorestring" ) == 0 ||
            strcasecmp( argv[lasti], "cis" ) == 0 ) {
-               at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.15";
+               at->at_syntax_oid = SYNTAX_DS_OID;
                at->at_equality_oid = "2.5.13.2";
                at->at_ordering_oid = "2.5.13.3";
                at->at_substr_oid = "2.5.13.4";
+
        } else if ( strcasecmp( argv[lasti], "telephone" ) == 0 ||
            strcasecmp( argv[lasti], "tel" ) == 0 ) {
-               at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.50";
+               at->at_syntax_oid = SYNTAX_TEL_OID;
                at->at_equality_oid = "2.5.13.20";
                at->at_substr_oid = "2.5.13.21";
+
        } else if ( strcasecmp( argv[lasti], "dn" ) == 0 ) {
-               at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.12";
+               at->at_syntax_oid = SYNTAX_DN_OID;
                at->at_equality_oid = "2.5.13.1";
+
        } else if ( strcasecmp( argv[lasti], "caseexactstring" ) == 0 ||
            strcasecmp( argv[lasti], "ces" ) == 0 ) {
-               at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.15";
-               at->at_equality_oid = "2.5.13.5";
+               at->at_syntax_oid = SYNTAX_DS_OID;
+               at->at_equality_oid = SYNTAX_DSCE_OID;
                at->at_ordering_oid = "2.5.13.6";
                at->at_substr_oid = "2.5.13.7";
+
        } else if ( strcasecmp( argv[lasti], "binary" ) == 0 ||
            strcasecmp( argv[lasti], "bin" ) == 0 ) {
-               at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.5";
-               /* There is no match for binary syntax. Really */
+               /* bin -> octetString, not binary! */
+               at->at_syntax_oid = SYNTAX_BIN_OID;
+               at->at_equality_oid = "2.5.13.17";
+
        } else {
                Debug( LDAP_DEBUG_ANY,
            "%s: line %d: unknown syntax \"%s\" in attribute line (ignored)\n",
@@ -572,6 +586,7 @@ at_add(
        }
        sat = (AttributeType *) ch_calloc( 1, sizeof(AttributeType) );
        memcpy( &sat->sat_atype, at, sizeof(LDAP_ATTRIBUTE_TYPE));
+
        if ( at->at_sup_oid ) {
                if ( (sat1 = at_find(at->at_sup_oid)) ) {
                        sat->sat_sup = sat1;
@@ -585,6 +600,19 @@ at_add(
                }
        }
 
+       /*
+        * Inherit definitions from superiors.  We only check the
+        * direct superior since that one has already inherited from
+        * its own superiorss
+        */
+       if ( sat->sat_sup ) {
+               sat->sat_syntax = sat->sat_sup->sat_syntax;
+
+               sat->sat_equality = sat->sat_sup->sat_equality;
+               sat->sat_ordering = sat->sat_sup->sat_ordering;
+               sat->sat_substr = sat->sat_sup->sat_substr;
+       }
+
        if ( at->at_syntax_oid ) {
                if ( (syn = syn_find(sat->sat_syntax_oid)) ) {
                        sat->sat_syntax = syn;
@@ -592,27 +620,40 @@ at_add(
                        *err = sat->sat_syntax_oid;
                        return SLAP_SCHERR_SYN_NOT_FOUND;
                }
-               if ( !strcmp(at->at_syntax_oid,
-                            "1.3.6.1.4.1.1466.115.121.1.15") ) {
-                       if ( at->at_equality_oid &&
-                            !strcmp(at->at_equality_oid, "2.5.13.5") ) {
+
+               if ( !strcmp(at->at_syntax_oid, SYNTAX_DS_OID) ) {
+                       if ( at->at_equality_oid && (
+                               !strcmp(at->at_equality_oid, SYNTAX_DSCE_OID) ) )
+                       {
                                sat->sat_syntax_compat = SYNTAX_CES;
                        } else {
                                sat->sat_syntax_compat = SYNTAX_CIS;
                        }
-               } else if ( !strcmp(at->at_syntax_oid,
-                                   "1.3.6.1.4.1.1466.115.121.1.50") ) {
-                       sat->sat_syntax_compat = SYNTAX_CIS | SYNTAX_TEL;
-               } else if ( !strcmp(at->at_syntax_oid,
-                                   "1.3.6.1.4.1.1466.115.121.1.12") ) {
+
+               } else if ( !strcmp(at->at_syntax_oid, SYNTAX_IA5_OID) ) {
+                       if ( at->at_equality_oid && (
+                               !strcmp(at->at_equality_oid, SYNTAX_IA5CE_OID) ) )
+                       {
+                               sat->sat_syntax_compat = SYNTAX_CES;
+                       } else {
+                               sat->sat_syntax_compat = SYNTAX_CIS;
+                       }
+
+               } else if ( !strcmp(at->at_syntax_oid, SYNTAX_DN_OID ) ) {
                        sat->sat_syntax_compat = SYNTAX_CIS | SYNTAX_DN;
-               } else if ( !strcmp(at->at_syntax_oid, "1.3.6.1.4.1.1466.115.121.1.5") ) {
+
+               } else if ( !strcmp(at->at_syntax_oid, SYNTAX_TEL_OID ) ) {
+                       sat->sat_syntax_compat = SYNTAX_CIS | SYNTAX_TEL;
+
+               } else if ( !strcmp(at->at_syntax_oid, SYNTAX_BIN_OID ) ) {
                        sat->sat_syntax_compat = SYNTAX_BIN;
+
                } else {
                        sat->sat_syntax_compat = DEFAULT_SYNTAX;
                }
-       } else {
-               sat->sat_syntax_compat = DEFAULT_SYNTAX;
+
+       } else if ( sat->sat_syntax == NULL ) {
+               return SLAP_SCHERR_ATTR_INCOMPLETE;
        }
 
        if ( sat->sat_equality_oid ) {
@@ -622,7 +663,9 @@ at_add(
                        *err = sat->sat_equality_oid;
                        return SLAP_SCHERR_MR_NOT_FOUND;
                }
+
        }
+
        if ( sat->sat_ordering_oid ) {
                if ( (mr = mr_find(sat->sat_ordering_oid)) ) {
                        sat->sat_ordering = mr;
@@ -631,6 +674,7 @@ at_add(
                        return SLAP_SCHERR_MR_NOT_FOUND;
                }
        }
+
        if ( sat->sat_substr_oid ) {
                if ( (mr = mr_find(sat->sat_substr_oid)) ) {
                        sat->sat_substr = mr;
@@ -640,26 +684,6 @@ at_add(
                }
        }
 
-       /*
-        * Now inherit definitions from superiors.  We only check the
-        * direct superior since that one has already inherited from
-        * its own superiorss
-        */
-       if ( sat->sat_sup ) {
-               if ( !sat->sat_syntax ) {
-                       sat->sat_syntax = sat->sat_sup->sat_syntax;
-                       sat->sat_syntax_len = sat->sat_sup->sat_syntax_len;
-               }
-               if ( !sat->sat_equality ) {
-                       sat->sat_equality = sat->sat_sup->sat_equality;
-               }
-               if ( !sat->sat_ordering ) {
-                       sat->sat_ordering = sat->sat_sup->sat_ordering;
-               }
-               if ( !sat->sat_substr ) {
-                       sat->sat_substr = sat->sat_sup->sat_substr;
-               }
-       }
        code = at_insert(sat,err);
        return code;
 }
index 8e19bb2d88effa91f0d64c8fb6954d4538455817..2b5150f79ba0ec01cbf7dc57b8072bd925f207b9 100644 (file)
@@ -444,20 +444,31 @@ LIBSLAPD_F (int) oc_check_usermod_attr LDAP_P(( const char *type ));
 LIBSLAPD_F (int) oc_check_no_usermod_attr LDAP_P(( const char *type ));
 LIBSLAPD_F (ObjectClass *) oc_find LDAP_P((const char *ocname));
 LIBSLAPD_F (int) oc_add LDAP_P((LDAP_OBJECT_CLASS *oc, const char **err));
+
 LIBSLAPD_F (Syntax *) syn_find LDAP_P((const char *synname));
 LIBSLAPD_F (Syntax *) syn_find_desc LDAP_P((const char *syndesc, int *slen));
-LIBSLAPD_F (int) syn_add LDAP_P((LDAP_SYNTAX *syn, slap_syntax_check_func *check, const char **err));
-LIBSLAPD_F (MatchingRule *) mr_find LDAP_P((const char *mrname));
-LIBSLAPD_F (int) mr_add LDAP_P((LDAP_MATCHING_RULE *mr, slap_mr_normalize_func *normalize, slap_mr_compare_func *compare, const char **err));
+LIBSLAPD_F (int) syn_add LDAP_P((LDAP_SYNTAX *syn,
+       slap_syntax_validate_func *validate,
+       slap_syntax_normalize_func *normalize,
+       const char **err));
 
-LIBSLAPD_F (int) caseIngoreIA5Normalize LDAP_P((struct berval *val, struct berval **normalized));
-
-LIBSLAPD_F (int) register_syntax LDAP_P((char *desc,   slap_syntax_check_func *check ));
-LIBSLAPD_F (int) register_matching_rule LDAP_P((char * desc,   slap_mr_normalize_func *normalize, slap_mr_compare_func *compare));
-LIBSLAPD_F (void) schema_info LDAP_P((Connection *conn, Operation *op, char **attrs, int attrsonly));
+LIBSLAPD_F (MatchingRule *) mr_find LDAP_P((const char *mrname));
+LIBSLAPD_F (int) mr_add LDAP_P((LDAP_MATCHING_RULE *mr,
+       slap_mr_match_func *match,
+       const char **err));
+
+LIBSLAPD_F (int) register_syntax LDAP_P((char *desc,
+       slap_syntax_validate_func *validate,
+       slap_syntax_normalize_func *normalize ));
+LIBSLAPD_F (int) register_matching_rule LDAP_P((char * desc,
+       slap_mr_match_func *match ));
+
+LIBSLAPD_F (void) schema_info LDAP_P((Connection *conn, Operation *op,
+       char **attrs, int attrsonly));
 LIBSLAPD_F (int) schema_init LDAP_P((void));
 
-LIBSLAPD_F (int) is_entry_objectclass LDAP_P(( Entry *, const char* objectclass ));
+LIBSLAPD_F (int) is_entry_objectclass LDAP_P((
+       Entry *, const char* objectclass ));
 #define is_entry_alias(e)              is_entry_objectclass((e), "ALIAS")
 #define is_entry_referral(e)   is_entry_objectclass((e), "REFERRAL")
 
index 375638d39401dd89532982bb7e2af2b3b8e8b745..12c30af94e8c4bb1885421db2d834e02e4098746 100644 (file)
 #include <ac/socket.h>
 
 #include "slap.h"
+#include "ldap_pvt.h"
 
 static char *  oc_check_required(Entry *e, char *ocname);
 static int             oc_check_allowed(char *type, struct berval **ocl);
 
-
 /*
  * oc_check - check that entry e conforms to the schema required by
  * its object class(es). returns 0 if so, non-zero otherwise.
@@ -650,7 +650,8 @@ syn_insert(
 int
 syn_add(
     LDAP_SYNTAX                *syn,
-    slap_syntax_check_func     *check,
+    slap_syntax_validate_func  *validate,
+    slap_syntax_normalize_func *normalize,
     const char         **err
 )
 {
@@ -659,7 +660,8 @@ syn_add(
 
        ssyn = (Syntax *) ch_calloc( 1, sizeof(Syntax) );
        memcpy( &ssyn->ssyn_syn, syn, sizeof(LDAP_SYNTAX));
-       ssyn->ssyn_check = check;
+       ssyn->ssyn_validate = validate;
+       ssyn->ssyn_normalize = normalize;
        code = syn_insert(ssyn,err);
        return code;
 }
@@ -757,8 +759,7 @@ mr_insert(
 int
 mr_add(
     LDAP_MATCHING_RULE         *mr,
-    slap_mr_normalize_func     *normalize,
-    slap_mr_compare_func       *compare,
+    slap_mr_match_func *match,
     const char         **err
 )
 {
@@ -768,8 +769,7 @@ mr_add(
 
        smr = (MatchingRule *) ch_calloc( 1, sizeof(MatchingRule) );
        memcpy( &smr->smr_mrule, mr, sizeof(LDAP_MATCHING_RULE));
-       smr->smr_normalize = normalize;
-       smr->smr_compare = compare;
+       smr->smr_match = match;
        if ( smr->smr_syntax_oid ) {
                if ( (syn = syn_find(smr->smr_syntax_oid)) ) {
                        smr->smr_syntax = syn;
@@ -786,54 +786,127 @@ mr_add(
 }
 
 static int
-caseExactIA5Normalize(
+octetStringValidate( struct berval *val )
+{
+       /* any value allowed */
+       return 0;
+}
+
+static int
+UTF8StringValidate( struct berval *val )
+{
+       ber_len_t count;
+       int len;
+       unsigned char *u = val->bv_val;
+
+       for( count = val->bv_len; count > 0; count+=len, u+=len ) {
+               /* get the length indicated by the first byte */
+               len = LDAP_UTF8_CHARLEN( u );
+
+               /* should not be zero */
+               if( len == 0 ) return -1;
+
+               /* make sure len corresponds with the offset
+                       to the next character */
+               if( LDAP_UTF8_OFFSET( u ) != len ) return -1;
+       }
+
+       if( count != 0 ) return -1;
+
+       return 0;
+}
+
+static int
+UTF8StringNormalize(
        struct berval *val,
        struct berval **normalized
 )
 {
        struct berval *newval;
-       char *p, *q;
+       char *p, *q, *s;
+
+       newval = ch_malloc( sizeof( struct berval ) );
+
+       p = val->bv_val;
 
-       newval = ber_bvdup( val );
-       p = q = newval->bv_val;
        /* Ignore initial whitespace */
-       while ( isspace( *p++ ) )
-               ;
+       while ( ldap_utf8_isspace( p ) ) {
+               LDAP_UTF8_INCR( p );
+       }
+
+       if( *p ) {
+               ch_free( newval );
+               return 1;
+       }
+
+       newval->bv_val = ch_strdup( p );
+       p = q = newval->bv_val;
+       s = NULL;
+
        while ( *p ) {
-               if ( isspace( *p ) ) {
-                       *q++ = *p++;
+               int len;
+
+               if ( ldap_utf8_isspace( p ) ) {
+                       len = LDAP_UTF8_COPY(q,p);
+                       s=q;
+                       p+=len;
+                       q+=len;
+
                        /* Ignore the extra whitespace */
-                       while ( isspace(*p++) )
-                               ;
+                       while ( ldap_utf8_isspace( p ) ) {
+                               LDAP_UTF8_INCR( p );
+                       }
                } else {
-                       *q++ = *p++;
+                       len = LDAP_UTF8_COPY(q,p);
+                       s=NULL;
+                       p+=len;
+                       q+=len;
                }
        }
+
+       assert( *newval->bv_val );
+       assert( newval->bv_val < p );
+       assert( p <= q );
+
+       /* cannot start with a space */
+       assert( !ldap_utf8_isspace(newval->bv_val) );
+
        /*
         * If the string ended in space, backup the pointer one
         * position.  One is enough because the above loop collapsed
         * all whitespace to a single space.
         */
-       if ( p != newval->bv_val && isspace( *(p-1) ) ) {
-               *(q-1) = '\0';
+
+       if ( s != NULL ) {
+               q = s;
        }
-       newval->bv_len = strlen( newval->bv_val );
+
+       /* cannot end with a space */
+       assert( !ldap_utf8_isspace( LDAP_UTF8_PREV(q) ) );
+
+       /* null terminate */
+       *q = '\0';
+
+       newval->bv_len = q - newval->bv_val;
        normalized = &newval;
 
        return 0;
 }
 
 static int
-caseExactIA5Match(
-       struct berval *val1,
-       struct berval *val2
-)
+IA5StringValidate( struct berval *val )
 {
-       return strcmp( val1->bv_val, val2->bv_val );
+       int i;
+
+       for(i=0; i < val->bv_len; i++) {
+               if( !isascii(val->bv_val[i]) ) return -1;
+       }
+
+       return 0;
 }
 
-int
-caseIgnoreIA5Normalize(
+static int
+IA5StringNormalize(
        struct berval *val,
        struct berval **normalized
 )
@@ -841,35 +914,74 @@ caseIgnoreIA5Normalize(
        struct berval *newval;
        char *p, *q;
 
-       newval = ber_bvdup( val );
-       p = q = newval->bv_val;
+       newval = ch_malloc( sizeof( struct berval ) );
+
+       p = val->bv_val;
+
        /* Ignore initial whitespace */
-       while ( isspace( *p++ ) )
-               ;
+       while ( isspace( *p++ ) ) {
+               /* EMPTY */  ;
+       }
+
+       if( *p ) {
+               ch_free( newval );
+               return 1;
+       }
+
+       newval->bv_val = ch_strdup( p );
+       p = q = newval->bv_val;
+
        while ( *p ) {
                if ( isspace( *p ) ) {
                        *q++ = *p++;
+
                        /* Ignore the extra whitespace */
-                       while ( isspace(*p++) )
-                               ;
+                       while ( isspace( *p++ ) ) {
+                               /* EMPTY */  ;
+                       }
                } else {
-                       *q++ = TOUPPER( *p++ );
+                       *q++ = *p++;
                }
        }
+
+       assert( *newval->bv_val );
+       assert( newval->bv_val < p );
+       assert( p <= q );
+
+       /* cannot start with a space */
+       assert( !isspace(*newval->bv_val) );
+
        /*
         * If the string ended in space, backup the pointer one
         * position.  One is enough because the above loop collapsed
         * all whitespace to a single space.
         */
-       if ( p != newval->bv_val && isspace( *(p-1) ) ) {
-               *(q-1) = '\0';
+
+       if ( isspace( q[-1] ) ) {
+               --q;
        }
-       newval->bv_len = strlen( newval->bv_val );
+
+       /* cannot end with a space */
+       assert( !isspace( q[-1] ) );
+
+       /* null terminate */
+       *q = '\0';
+
+       newval->bv_len = q - newval->bv_val;
        normalized = &newval;
 
        return 0;
 }
 
+static int
+caseExactIA5Match(
+       struct berval *val1,
+       struct berval *val2
+)
+{
+       return strcmp( val1->bv_val, val2->bv_val );
+}
+
 static int
 caseIgnoreIA5Match(
        struct berval *val1,
@@ -882,7 +994,8 @@ caseIgnoreIA5Match(
 int
 register_syntax(
        char * desc,
-       slap_syntax_check_func *check )
+       slap_syntax_validate_func *validate,
+       slap_syntax_normalize_func *normalize )
 {
        LDAP_SYNTAX     *syn;
        int             code;
@@ -894,7 +1007,7 @@ register_syntax(
                    ldap_scherr2str(code), err, desc );
                return( -1 );
        }
-       code = syn_add( syn, check, &err );
+       code = syn_add( syn, validate, normalize, &err );
        if ( code ) {
                Debug( LDAP_DEBUG_ANY, "Error in register_syntax: %s %s in %s\n",
                    scherr2str(code), err, desc );
@@ -906,8 +1019,7 @@ register_syntax(
 int
 register_matching_rule(
        char * desc,
-       slap_mr_normalize_func *normalize,
-       slap_mr_compare_func *compare )
+       slap_mr_match_func *match )
 {
        LDAP_MATCHING_RULE *mr;
        int             code;
@@ -919,7 +1031,7 @@ register_matching_rule(
                    ldap_scherr2str(code), err, desc );
                return( -1 );
        }
-       code = mr_add( mr, normalize, compare, &err );
+       code = mr_add( mr, match, &err );
        if ( code ) {
                Debug( LDAP_DEBUG_ANY, "Error in register_syntax: %s for %s in %s\n",
                    scherr2str(code), err, desc );
@@ -930,65 +1042,106 @@ register_matching_rule(
 
 struct syntax_defs_rec {
        char *sd_desc;
-       slap_syntax_check_func *sd_check;
+       slap_syntax_validate_func *sd_validate;
+       slap_syntax_normalize_func *sd_normalize;
 };
 
 struct syntax_defs_rec syntax_defs[] = {
-       {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'AttributeTypeDescription' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'BitString' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'CertificateList' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'CertificatePair' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'DN' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'DeliveryMethod' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'DirectoryString' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DITContentRuleDescription' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DITStructureRuleDescription' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'EnhancedGuide' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'FacsimileTelephoneNumber' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'GeneralizedTime' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5String' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'MatchingRuleDescription' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'MatchingRuleUseDescription' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'MailPreference' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'NameAndOptionalUID' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'NameFormDescription' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'NumericString' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'ObjectClassDescription' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'OtherMailbox' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'OctetString' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'PostalAddress' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'ProtocolInformation' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'PresentationAddress' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'PrintableString' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'SupportedAlgorithm' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'TelephoneNumber' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'TeletexTerminalIdentifier' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'TelexNumber' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTCTime' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAPSyntaxDescription' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'SubstringAssertion' )", NULL},
-       {"( 1.3.6.1.1.1.0.0 DESC 'NISnetgrouptriple' )", NULL},
-       {"( 1.3.6.1.1.1.0.1 DESC 'Bootparameter' )", NULL},
-       {NULL, NULL}
+       {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'AttributeTypeDescription' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'BitString' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'CertificateList' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'CertificatePair' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'DN' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'DeliveryMethod' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'DirectoryString' )",
+               UTF8StringValidate, UTF8StringNormalize},
+       {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DITContentRuleDescription' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DITStructureRuleDescription' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'EnhancedGuide' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'FacsimileTelephoneNumber' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'GeneralizedTime' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5String' )",
+               IA5StringValidate, IA5StringNormalize},
+       {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'MatchingRuleDescription' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'MatchingRuleUseDescription' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'MailPreference' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'NameAndOptionalUID' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'NameFormDescription' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'NumericString' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'ObjectClassDescription' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'OtherMailbox' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'OctetString' )",
+               octetStringValidate, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'PostalAddress' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'ProtocolInformation' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'PresentationAddress' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'PrintableString' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'SupportedAlgorithm' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'TelephoneNumber' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'TeletexTerminalIdentifier' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'TelexNumber' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTCTime' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAPSyntaxDescription' )",
+               NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'SubstringAssertion' )",
+               NULL, NULL},
+
+       {NULL, NULL, NULL}
 };
 
 struct mrule_defs_rec {
        char *mrd_desc;
-       slap_mr_normalize_func *mrd_normalize;
-       slap_mr_compare_func *mrd_compare;
+       slap_mr_match_func *mrd_match;
 };
 
 /*
  * Other matching rules in X.520 that we do not use:
  *
- * 2.5.13.9    numericStringOrderingMatch
+ * 2.5.13.9            numericStringOrderingMatch
  * 2.5.13.12   caseIgnoreListSubstringsMatch
  * 2.5.13.13   booleanMatch
  * 2.5.13.15   integerOrderingMatch
@@ -1012,42 +1165,141 @@ struct mrule_defs_rec {
  * 2.5.13.44   attributeIntegrityMatch
  */
 
+/* recycled matching functions */
+#define caseIgnoreMatch caseIgnoreIA5Match
+#define caseExactMatch caseExactIA5Match
+
+/* unimplemented matching functions */
+#define objectIdentifierMatch NULL
+#define distinguishedNameMatch NULL
+#define caseIgnoreOrderingMatch NULL
+#define caseIgnoreSubstringsMatch NULL
+#define caseExactOrderingMatch NULL
+#define caseExactSubstringsMatch NULL
+#define numericStringMatch NULL
+#define numericStringSubstringsMatch NULL
+#define caseIgnoreListMatch NULL
+#define integerMatch NULL
+#define bitStringMatch NULL
+#define octetStringMatch NULL
+#define telephoneNumberMatch NULL
+#define telephoneNumberSubstringsMatch NULL
+#define presentationAddressMatch NULL
+#define uniqueMemberMatch NULL
+#define protocolInformationMatch NULL
+#define generalizedTimeMatch NULL
+#define generalizedTimeOrderingMatch NULL
+#define integerFirstComponentMatch NULL
+#define objectIdentifierFirstComponentMatch NULL
+#define caseIgnoreIA5SubstringsMatch NULL
+
 struct mrule_defs_rec mrule_defs[] = {
-       {"( 2.5.13.0 NAME 'objectIdentifierMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", NULL, NULL},
-       {"( 2.5.13.1 NAME 'distinguishedNameMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", NULL, NULL},
-       {"( 2.5.13.2 NAME 'caseIgnoreMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
-        caseIgnoreIA5Normalize, caseIgnoreIA5Match},
-       {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
-        caseIgnoreIA5Normalize, caseIgnoreIA5Match},
-       {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
-        caseIgnoreIA5Normalize, caseIgnoreIA5Match},
+       {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
+               objectIdentifierMatch},
+
+       {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
+               distinguishedNameMatch},
+
+       {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
+               caseIgnoreMatch},
+
+       {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
+               caseIgnoreOrderingMatch},
+
+       {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
+               caseIgnoreSubstringsMatch},
+
        /* Next three are not in the RFC's, but are needed for compatibility */
-       {"( 2.5.13.5 NAME 'caseExactMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
-        caseExactIA5Normalize, caseExactIA5Match},
-       {"( 2.5.13.6 NAME 'caseExactOrderingMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
-        caseExactIA5Normalize, caseExactIA5Match},
-       {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
-        caseExactIA5Normalize, caseExactIA5Match},
-       {"( 2.5.13.8 NAME 'numericStringMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )", NULL, NULL},
-       {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", NULL, NULL},
-       {"( 2.5.13.11 NAME 'caseIgnoreListMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )", NULL, NULL},
-       {"( 2.5.13.14 NAME 'integerMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", NULL, NULL},
-       {"( 2.5.13.16 NAME 'bitStringMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )", NULL, NULL},
-       {"( 2.5.13.17 NAME 'octetStringMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )", NULL, NULL},
-       {"( 2.5.13.20 NAME 'telephoneNumberMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )", NULL, NULL},
-       {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", NULL, NULL},
-       {"( 2.5.13.22 NAME 'presentationAddressMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )", NULL, NULL},
-       {"( 2.5.13.23 NAME 'uniqueMemberMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )", NULL, NULL},
-       {"( 2.5.13.24 NAME 'protocolInformationMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )", NULL, NULL},
-       {"( 2.5.13.27 NAME 'generalizedTimeMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )", NULL, NULL},
-       {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )", NULL, NULL},
-       {"( 2.5.13.29 NAME 'integerFirstComponentMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", NULL, NULL},
-       {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", NULL, NULL},
-       {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
-        caseExactIA5Normalize, caseExactIA5Match},
-       {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
-        caseIgnoreIA5Normalize, caseIgnoreIA5Match},
-       {NULL, NULL, NULL}
+       {"( 2.5.13.5 NAME 'caseExactMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
+               caseExactMatch},
+
+       {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
+               caseExactOrderingMatch},
+
+       {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
+               caseExactSubstringsMatch},
+
+       {"( 2.5.13.8 NAME 'numericStringMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
+               numericStringMatch},
+
+       {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
+               numericStringSubstringsMatch},
+
+       {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
+               caseIgnoreListMatch},
+
+       {"( 2.5.13.14 NAME 'integerMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
+               integerMatch},
+
+       {"( 2.5.13.16 NAME 'bitStringMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
+               bitStringMatch},
+
+       {"( 2.5.13.17 NAME 'octetStringMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
+               octetStringMatch},
+
+       {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
+               telephoneNumberMatch},
+
+       {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
+               telephoneNumberSubstringsMatch},
+
+       {"( 2.5.13.22 NAME 'presentationAddressMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
+               presentationAddressMatch},
+
+       {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
+               uniqueMemberMatch},
+
+       {"( 2.5.13.24 NAME 'protocolInformationMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
+               protocolInformationMatch},
+
+       {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
+               generalizedTimeMatch},
+
+       {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
+               generalizedTimeOrderingMatch},
+
+       {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
+               integerFirstComponentMatch},
+
+       {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
+               objectIdentifierFirstComponentMatch},
+
+       {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
+               caseExactIA5Match},
+
+       {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
+               caseIgnoreIA5Match},
+
+       {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
+               caseIgnoreIA5SubstringsMatch},
+
+       {NULL, NULL}
 };
 
 int
@@ -1060,21 +1312,23 @@ schema_init( void )
        /* We are called from read_config that is recursive */
        if ( schema_init_done )
                return( 0 );
+
        for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
                res = register_syntax( syntax_defs[i].sd_desc,
-                   syntax_defs[i].sd_check );
+                   syntax_defs[i].sd_validate,
+                   syntax_defs[i].sd_normalize );
+
                if ( res ) {
                        fprintf( stderr, "schema_init: Error registering syntax %s\n",
                                 syntax_defs[i].sd_desc );
                        exit( EXIT_FAILURE );
                }
        }
+
        for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
                res = register_matching_rule( mrule_defs[i].mrd_desc,
-                   ( mrule_defs[i].mrd_normalize ?
-                     mrule_defs[i].mrd_normalize : caseIgnoreIA5Normalize ),
-                   ( mrule_defs[i].mrd_compare ?
-                     mrule_defs[i].mrd_compare : caseIgnoreIA5Match ) );
+                   mrule_defs[i].mrd_match );
+
                if ( res ) {
                        fprintf( stderr, "schema_init: Error registering matching rule %s\n",
                                 mrule_defs[i].mrd_desc );
index a9b82c60156894c8fa82065801493fb3b0a1dccb..64d3b144972a848ab1ce93c32143651bacf021a4 100644 (file)
@@ -115,13 +115,13 @@ struct replog_moddn {
  * represents an attribute value assertion (i.e., attr=value)
  */
 typedef struct slap_ava {
-       char            *ava_type;
+       char            *ava_type;      /* attribute description */
        struct berval   ava_value;
 } Ava;
 
 typedef struct slap_mra {
        char    *mra_rule;
-       char    *mra_type;
+       char    *mra_type;      /* attribute description */
        char    *mra_value;
        int             mra_dnattrs;
 } Mra;
@@ -180,7 +180,7 @@ typedef struct slap_filter {
  * represents an attribute (type + values + syntax)
  */
 typedef struct slap_attr {
-       char            *a_type;
+       char            *a_type;        /* description */
        struct berval   **a_vals;
        int             a_syntax;
        struct slap_attr        *a_next;
@@ -365,31 +365,37 @@ typedef struct slap_oid_macro {
        int oidlen;
 } OidMacro;
 
-typedef int slap_syntax_check_func LDAP_P((struct berval * val));
+typedef int slap_syntax_validate_func LDAP_P((
+       struct berval * in));
+
+typedef int slap_syntax_normalize_func LDAP_P((
+       struct berval * in,
+       struct berval ** out));
 
 typedef struct slap_syntax {
        LDAP_SYNTAX                     ssyn_syn;
-       slap_syntax_check_func          *ssyn_check;
+       slap_syntax_validate_func       *ssyn_validate;
+       slap_syntax_normalize_func      *ssyn_normalize;
        struct slap_syntax              *ssyn_next;
-} Syntax;
 #define ssyn_oid                       ssyn_syn.syn_oid
 #define ssyn_desc                      ssyn_syn.syn_desc
+} Syntax;
 
-typedef int slap_mr_normalize_func LDAP_P((struct berval * val, struct berval **normalized));
-typedef int slap_mr_compare_func LDAP_P((struct berval * val1, struct berval * val2));
+typedef int slap_mr_match_func LDAP_P((
+       struct berval * atval,
+       struct berval * matchval));
 
 typedef struct slap_matching_rule {
        LDAP_MATCHING_RULE              smr_mrule;
-       slap_mr_normalize_func          *smr_normalize;
-       slap_mr_compare_func            *smr_compare;
+       slap_mr_match_func              *smr_match;
        Syntax                          *smr_syntax;
        struct slap_matching_rule       *smr_next;
-} MatchingRule;
 #define smr_oid                                smr_mrule.mr_oid
 #define smr_names                      smr_mrule.mr_names
 #define smr_desc                       smr_mrule.mr_desc
 #define smr_obsolete                   smr_mrule.mr_obsolete
 #define smr_syntax_oid                 smr_mrule.mr_syntax_oid
+} MatchingRule;
 
 typedef struct slap_attribute_type {
        LDAP_ATTRIBUTE_TYPE             sat_atype;
@@ -402,7 +408,6 @@ typedef struct slap_attribute_type {
        /* The next one is created to help in the transition */
        int                             sat_syntax_compat;
        struct slap_attribute_type      *sat_next;
-} AttributeType;
 #define sat_oid                        sat_atype.at_oid
 #define sat_names              sat_atype.at_names
 #define sat_desc               sat_atype.at_desc
@@ -412,11 +417,11 @@ typedef struct slap_attribute_type {
 #define sat_ordering_oid       sat_atype.at_ordering_oid
 #define sat_substr_oid         sat_atype.at_substr_oid
 #define sat_syntax_oid         sat_atype.at_syntax_oid
-#define sat_syntax_len         sat_atype.at_syntax_len
 #define sat_single_value       sat_atype.at_single_value
 #define sat_collective         sat_atype.at_collective
 #define sat_no_user_mods       sat_atype.at_no_user_mods
 #define sat_usage              sat_atype.at_usage
+} AttributeType;
 
 typedef struct slap_object_class {
        LDAP_OBJECT_CLASS               soc_oclass;
@@ -424,7 +429,6 @@ typedef struct slap_object_class {
        AttributeType                   **soc_required;
        AttributeType                   **soc_allowed;
        struct slap_object_class        *soc_next;
-} ObjectClass;
 #define soc_oid                        soc_oclass.oc_oid
 #define soc_names              soc_oclass.oc_names
 #define soc_desc               soc_oclass.oc_desc
@@ -433,6 +437,7 @@ typedef struct slap_object_class {
 #define soc_kind               soc_oclass.oc_kind
 #define soc_at_oids_must       soc_oclass.oc_at_oids_must
 #define soc_at_oids_may                soc_oclass.oc_at_oids_may
+} ObjectClass;
 
 /*
  * Backend-info