]> git.sur5r.net Git - openldap/commitdiff
Another round of SLAPD_SCHEMA_NOT_COMPAT changes including
authorKurt Zeilenga <kurt@openldap.org>
Sat, 5 Feb 2000 05:01:41 +0000 (05:01 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Sat, 5 Feb 2000 05:01:41 +0000 (05:01 +0000)
basic structures for handing language tags and binary option
(but less actual code to actually support them).  Provided
for reference only.  Will not even compile.

22 files changed:
servers/slapd/Makefile.in
servers/slapd/add.c
servers/slapd/at.c [new file with mode: 0644]
servers/slapd/attr.c
servers/slapd/back-bdb2/add.c
servers/slapd/back-bdb2/modify.c
servers/slapd/back-ldbm/add.c
servers/slapd/back-ldbm/index.c
servers/slapd/back-ldbm/modify.c
servers/slapd/backend.c
servers/slapd/entry.c
servers/slapd/libslapd.dsp
servers/slapd/mr.c [new file with mode: 0644]
servers/slapd/oc.c [new file with mode: 0644]
servers/slapd/proto-slap.h
servers/slapd/result.c
servers/slapd/schema.c
servers/slapd/schema_check.c [new file with mode: 0644]
servers/slapd/slap.h
servers/slapd/syntax.c [new file with mode: 0644]
servers/slapd/tools/Makefile.in
servers/slapd/tools/slapadd.c

index bf0cca393fd2805b7ef8bb0ee8363182878b660a..b25e48efa078241c1c819e2d8ba6816c28aba462 100644 (file)
@@ -15,7 +15,8 @@ SRCS  = main.c daemon.c connection.c search.c filter.c add.c charray.c \
                value.c ava.c bind.c unbind.c abandon.c filterentry.c \
                phonetic.c acl.c str2filter.c aclparse.c init.c user.c \
                repl.c lock.c controls.c extended.c kerberos.c passwd.c \
-               schema.c schema_init.c schemaparse.c \
+               schema.c schema_check.c schema_init.c schemaparse.c \
+               at.c mr.c syntax.c oc.c \
                monitor.c configinfo.c starttls.c \
                root_dse.c sasl.c module.c suffixalias.c $(@PLAT@_SRCS)
 
@@ -25,7 +26,8 @@ OBJS  = main.o daemon.o connection.o search.o filter.o add.o charray.o \
                value.o ava.o bind.o unbind.o abandon.o filterentry.o \
                phonetic.o acl.o str2filter.o aclparse.o init.o user.o \
                repl.o lock.o controls.o extended.o kerberos.o passwd.o \
-               schema.o schema_init.o schemaparse.o \
+               schema.o schema_check.o schema_init.o schemaparse.o \
+               at.o mr.o syntax.o oc.o \
                monitor.o configinfo.o starttls.o \
                root_dse.o sasl.o module.o suffixalias.o $(@PLAT@_OBJS)
 
index 8fef1b17b3b97d0b128d4b048c731950c1b55499..11069badee927e37dc76af0997c0ef4e876f2686 100644 (file)
@@ -244,7 +244,12 @@ add_created_attrs( Operation *op, Entry *e )
 
        /* return error on any attempts by the user to add these attrs */
        for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
-               if ( oc_check_op_no_usermod_attr( a->a_type ) ) {
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+               if ( is_at_no_user_mod( a->a_desc.ad_type ))
+#else
+               if ( oc_check_op_no_usermod_attr( a->a_type ) )
+#endif
+               {
                        return LDAP_CONSTRAINT_VIOLATION;
                }
        }
diff --git a/servers/slapd/at.c b/servers/slapd/at.c
new file mode 100644 (file)
index 0000000..2538e14
--- /dev/null
@@ -0,0 +1,563 @@
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/* at.c - routines for dealing with attributes */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/ctype.h>
+#include <ac/errno.h>
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/time.h>
+
+#include "ldap_pvt.h"
+#include "slap.h"
+
+#ifndef SLAPD_SCHEMA_NOT_COMPAT
+char *
+at_canonical_name( const char * a_type )
+{
+       AttributeType   *atp;
+
+       atp=at_find(a_type);
+
+       if ( atp == NULL ) {
+               return (char *) a_type;
+
+       } else if ( atp->sat_names
+               && atp->sat_names[0] && (*(atp->sat_names[0]) != '\0') )
+       {
+               return atp->sat_names[0];
+
+       } else if (atp->sat_oid && (*atp->sat_oid != '\0')) {
+               return atp->sat_oid;
+       }
+
+       return (char *) a_type;
+}
+
+#define DEFAULT_SYNTAX SYNTAX_CIS
+
+/*
+ * attr_syntax - return the syntax of attribute type
+ */
+
+int
+attr_syntax( const char *type )
+{
+       AttributeType   *sat;
+
+       sat = at_find(type);
+       if ( sat ) {
+               return( sat->sat_syntax_compat );
+       }
+
+       return( DEFAULT_SYNTAX );
+}
+
+/*
+ * attr_syntax_config - process an attribute syntax config line
+ */
+
+void
+attr_syntax_config(
+    const char *fname,
+    int                lineno,
+    int                argc,
+    char       **argv
+)
+{
+       char                    *save;
+       LDAP_ATTRIBUTE_TYPE     *at;
+       int                     lasti;
+       int                     code;
+       const char              *err;
+
+       if ( argc < 2 ) {
+               Debug( LDAP_DEBUG_ANY,
+"%s: line %d: missing name in \"attribute <name>+ <syntax>\" (ignored)\n",
+                   fname, lineno, 0 );
+               return;
+       }
+
+       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  SLAPD_OID_DN_SYNTAX
+#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 = 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 = 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 = 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 = 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 ) {
+               /* 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",
+                   fname, lineno, argv[lasti] );
+               Debug( LDAP_DEBUG_ANY,
+    "possible syntaxes are \"cis\", \"ces\", \"tel\", \"dn\", or \"bin\"\n",
+                   0, 0, 0 );
+               free( (AttributeType *) at );
+               return;
+       }
+
+       save = argv[lasti];
+       argv[lasti] = NULL;
+       at->at_names = charray_dup( argv );
+       argv[lasti] = save;
+
+       code = at_add( at, &err );
+       if ( code ) {
+               fprintf( stderr, "%s: line %d: %s %s\n",
+                        fname, lineno, scherr2str(code), err);
+               exit( EXIT_FAILURE );
+       }
+
+       ldap_memfree(at);
+}
+
+int
+at_fake_if_needed(
+    const char *name
+)
+{
+       char *argv[3];
+
+       if ( at_find( name ) ) {
+               return 0;
+       } else {
+               argv[0] = (char*) name;
+               argv[1] = "cis";
+               argv[2] = NULL;
+               attr_syntax_config( "implicit", 0, 2, argv );
+               return 0;
+       }
+}
+
+#endif
+
+
+
+struct aindexrec {
+       char            *air_name;
+       AttributeType   *air_at;
+};
+
+static Avlnode *attr_index = NULL;
+static AttributeType *attr_list = NULL;
+
+static int
+attr_index_cmp(
+    struct aindexrec   *air1,
+    struct aindexrec   *air2
+)
+{
+       return (strcasecmp( air1->air_name, air2->air_name ));
+}
+
+static int
+attr_index_name_cmp(
+    char               *type,
+    struct aindexrec   *air
+)
+{
+       return (strcasecmp( type, air->air_name ));
+}
+
+AttributeType *
+at_find(
+    const char         *name
+)
+{
+       struct aindexrec        *air;
+       char                    *tmpname;
+
+#ifndef SLAPD_SCHEMA_NOT_COMPAT
+       /*
+        * The name may actually be an AttributeDescription, i.e. it may
+        * contain options.
+        */
+       /* Treat any attribute type with option as an unknown attribute type */
+       char *p = strchr( name, ';' );
+       if ( p ) {
+               tmpname = ch_malloc( p-name+1 );
+               strncpy( tmpname, name, p-name );
+               tmpname[p-name] = '\0';
+       } else
+#endif
+       {
+               tmpname = (char *)name;
+       }
+
+       if ( (air = (struct aindexrec *) avl_find( attr_index, tmpname,
+            (AVL_CMP) attr_index_name_cmp )) != NULL ) {
+               if ( tmpname != name )
+                       ldap_memfree( tmpname );
+               return( air->air_at );
+       }
+
+       if ( tmpname != name )
+               ldap_memfree( tmpname );
+       return( NULL );
+}
+
+int
+at_append_to_list(
+    AttributeType      *sat,
+    AttributeType      ***listp
+)
+{
+       AttributeType   **list;
+       AttributeType   **list1;
+       int             size;
+
+       list = *listp;
+       if ( !list ) {
+               size = 2;
+               list = calloc(size, sizeof(AttributeType *));
+               if ( !list ) {
+                       return -1;
+               }
+       } else {
+               size = 0;
+               list1 = *listp;
+               while ( *list1 ) {
+                       size++;
+                       list1++;
+               }
+               size += 2;
+               list1 = realloc(list, size*sizeof(AttributeType *));
+               if ( !list1 ) {
+                       return -1;
+               }
+               list = list1;
+       }
+       list[size-2] = sat;
+       list[size-1] = NULL;
+       *listp = list;
+       return 0;
+}
+
+int
+at_delete_from_list(
+    int                        pos,
+    AttributeType      ***listp
+)
+{
+       AttributeType   **list;
+       AttributeType   **list1;
+       int             i;
+       int             j;
+
+       if ( pos < 0 ) {
+               return -2;
+       }
+       list = *listp;
+       for ( i=0; list[i]; i++ )
+               ;
+       if ( pos >= i ) {
+               return -2;
+       }
+       for ( i=pos, j=pos+1; list[j]; i++, j++ ) {
+               list[i] = list[j];
+       }
+       list[i] = NULL;
+       /* Tell the runtime this can be shrinked */
+       list1 = realloc(list, (i+1)*sizeof(AttributeType **));
+       if ( !list1 ) {
+               return -1;
+       }
+       *listp = list1;
+       return 0;
+}
+
+int
+at_find_in_list(
+    AttributeType      *sat,
+    AttributeType      **list
+)
+{
+       int     i;
+
+       if ( !list ) {
+               return -1;
+       }
+       for ( i=0; list[i]; i++ ) {
+               if ( sat == list[i] ) {
+                       return i;
+               }
+       }
+       return -1;
+}
+
+static int
+at_insert(
+    AttributeType      *sat,
+    const char         **err
+)
+{
+       AttributeType           **atp;
+       struct aindexrec        *air;
+       char                    **names;
+
+       atp = &attr_list;
+       while ( *atp != NULL ) {
+               atp = &(*atp)->sat_next;
+       }
+       *atp = sat;
+
+       if ( sat->sat_oid ) {
+               air = (struct aindexrec *)
+                       ch_calloc( 1, sizeof(struct aindexrec) );
+               air->air_name = sat->sat_oid;
+               air->air_at = sat;
+               if ( avl_insert( &attr_index, (caddr_t) air,
+                                (AVL_CMP) attr_index_cmp,
+                                (AVL_DUP) avl_dup_error ) ) {
+                       *err = sat->sat_oid;
+                       ldap_memfree(air);
+                       return SLAP_SCHERR_DUP_ATTR;
+               }
+               /* FIX: temporal consistency check */
+               at_find(air->air_name);
+       }
+
+       if ( (names = sat->sat_names) ) {
+               while ( *names ) {
+                       air = (struct aindexrec *)
+                               ch_calloc( 1, sizeof(struct aindexrec) );
+                       air->air_name = ch_strdup(*names);
+                       air->air_at = sat;
+                       if ( avl_insert( &attr_index, (caddr_t) air,
+                                        (AVL_CMP) attr_index_cmp,
+                                        (AVL_DUP) avl_dup_error ) ) {
+                               *err = *names;
+                               ldap_memfree(air->air_name);
+                               ldap_memfree(air);
+                               return SLAP_SCHERR_DUP_ATTR;
+                       }
+                       /* FIX: temporal consistency check */
+                       at_find(air->air_name);
+                       names++;
+               }
+       }
+
+       return 0;
+}
+
+int
+at_add(
+    LDAP_ATTRIBUTE_TYPE        *at,
+    const char         **err
+)
+{
+       AttributeType   *sat;
+       MatchingRule    *mr;
+       Syntax          *syn;
+       int             code;
+       char                    *cname;
+
+       if ( at->at_names && at->at_names[0] ) {
+               cname = at->at_names[0];
+       } else if ( at->at_oid ) {
+               cname = at->at_oid;
+       } else {
+               cname = "";
+               return SLAP_SCHERR_ATTR_INCOMPLETE;
+       }
+       sat = (AttributeType *) ch_calloc( 1, sizeof(AttributeType) );
+       memcpy( &sat->sat_atype, at, sizeof(LDAP_ATTRIBUTE_TYPE));
+
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+       sat->sat_cname = cname;
+#endif
+
+       if ( at->at_sup_oid ) {
+               AttributeType *supsat = at_find(at->at_sup_oid);
+
+               if ( (supsat == NULL ) ) {
+                       *err = at->at_sup_oid;
+                       return SLAP_SCHERR_ATTR_NOT_FOUND;
+               }
+
+               sat->sat_sup = supsat;
+
+               if ( at_append_to_list(sat, &supsat->sat_subtypes) ) {
+                       *err = cname;
+                       return SLAP_SCHERR_OUTOFMEM;
+               }
+       }
+
+       /*
+        * 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;
+               } else {
+                       *err = sat->sat_syntax_oid;
+                       return SLAP_SCHERR_SYN_NOT_FOUND;
+               }
+
+#ifndef SLAPD_SCHEMA_NOT_COMPAT
+               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, 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, 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;
+               }
+#endif
+
+       } else if ( sat->sat_syntax == NULL ) {
+               return SLAP_SCHERR_ATTR_INCOMPLETE;
+       }
+
+       if ( sat->sat_equality_oid ) {
+               if ( (mr = mr_find(sat->sat_equality_oid)) ) {
+                       sat->sat_equality = mr;
+               } else {
+                       *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;
+               } else {
+                       *err = sat->sat_ordering_oid;
+                       return SLAP_SCHERR_MR_NOT_FOUND;
+               }
+       }
+
+       if ( sat->sat_substr_oid ) {
+               if ( (mr = mr_find(sat->sat_substr_oid)) ) {
+                       sat->sat_substr = mr;
+               } else {
+                       *err = sat->sat_substr_oid;
+                       return SLAP_SCHERR_MR_NOT_FOUND;
+               }
+       }
+
+       code = at_insert(sat,err);
+       return code;
+}
+
+#ifdef LDAP_DEBUG
+static int
+at_index_printnode( struct aindexrec *air )
+{
+
+       printf("%s = %s\n",
+               air->air_name,
+               ldap_attributetype2str(&air->air_at->sat_atype) );
+       return( 0 );
+}
+
+static void
+at_index_print( void )
+{
+       printf("Printing attribute type index:\n");
+       (void) avl_apply( attr_index, (AVL_APPLY) at_index_printnode,
+               0, -1, AVL_INORDER );
+}
+#endif
+
+#if defined( SLAPD_SCHEMA_DN )
+int
+at_schema_info( Entry *e )
+{
+       struct berval   val;
+       struct berval   *vals[2];
+       AttributeType   *at;
+
+       vals[0] = &val;
+       vals[1] = NULL;
+
+       for ( at = attr_list; at; at = at->sat_next ) {
+               val.bv_val = ldap_attributetype2str( &at->sat_atype );
+               if ( val.bv_val ) {
+                       val.bv_len = strlen( val.bv_val );
+                       Debug( LDAP_DEBUG_TRACE, "Merging at [%ld] %s\n",
+                              (long) val.bv_len, val.bv_val, 0 );
+                       attr_merge( e, "attributeTypes", vals );
+                       ldap_memfree( val.bv_val );
+               } else {
+                       return -1;
+               }
+       }
+       return 0;
+}
+#endif
index 0d95e2887f29185ee35716182e35e83eb56e3cd4..0621645f032cce948f3cd739678d8b8dcd245958 100644 (file)
 static void at_index_print( void );
 #endif
 
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+void
+ad_free( AttributeDescription *ad, int freeit )
+{
+       if( ad == NULL ) return;
+
+       ber_bvfree( ad->ad_cname );
+       free( ad->ad_lang );
+
+       if( freeit ) free( ad );
+}
+#endif
+
 void
 attr_free( Attribute *a )
 {
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+       /* not yet implemented */
+       ad_free( &a->a_desc, 0 );
+#else
        free( a->a_type );
+#endif
        ber_bvecfree( a->a_vals );
        free( a );
 }
@@ -74,8 +92,13 @@ Attribute *attr_dup( Attribute *a )
                tmp->a_vals = NULL;
        }
 
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+       /* not yet implemented */
+       tmp->a_desc = a->a_desc;
+       tmp->a_desc.ad_cname = ber_bvdup( a->a_desc.ad_cname );
+       tmp->a_desc.ad_lang = ch_strdup( a->a_desc.ad_lang );
+#else
        tmp->a_type = ch_strdup( a->a_type );
-#ifndef SLAPD_SCHEMA_NOT_COMPAT
        tmp->a_syntax = a->a_syntax;
 #endif
        tmp->a_next = NULL;
@@ -101,6 +124,7 @@ Attribute *attrs_dup( Attribute *a )
        return tmp;
 }
 
+#ifndef SLAPD_SCHEMA_NOT_COMPAT
 /*
  * attr_normalize - normalize an attribute name (make it all lowercase)
  */
@@ -112,7 +136,9 @@ attr_normalize( char *s )
 
        return( ldap_pvt_str2lower( s ) );
 }
+#endif
 
+#ifndef SLAPD_SCHEMA_NOT_COMPAT
 /*
  * attr_merge_fast - merge the given type and value with the list of
  * attributes in attrs. called from str2entry(), where we can make some
@@ -134,17 +160,21 @@ attr_merge_fast(
 {
        if ( *a == NULL ) {
                for ( *a = &e->e_attrs; **a != NULL; *a = &(**a)->a_next ) {
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+                       /* not yet implemented */
+#else
                        if ( strcasecmp( (**a)->a_type, type ) == 0 ) {
                                break;
                        }
+#endif
                }
        }
 
        if ( **a == NULL ) {
                **a = (Attribute *) ch_malloc( sizeof(Attribute) );
-               (**a)->a_type = attr_normalize( ch_strdup( type ) );
                (**a)->a_vals = NULL;
 #ifndef SLAPD_SCHEMA_NOT_COMPAT
+               (**a)->a_type = attr_normalize( ch_strdup( type ) );
                (**a)->a_syntax = attr_syntax( type );
 #endif
                (**a)->a_next = NULL;
@@ -153,6 +183,7 @@ attr_merge_fast(
        return( value_add_fast( &(**a)->a_vals, vals, nvals, naddvals,
            maxvals ) );
 }
+#endif
 
 /*
  * attr_merge - merge the given type and value with the list of
@@ -171,18 +202,24 @@ attr_merge(
        Attribute       **a;
 
        for ( a = &e->e_attrs; *a != NULL; a = &(*a)->a_next ) {
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+               /* not yet implemented */
+#else
                if ( strcasecmp( (*a)->a_type, type ) == 0 ) {
                        break;
                }
+#endif
        }
 
        if ( *a == NULL ) {
                *a = (Attribute *) ch_malloc( sizeof(Attribute) );
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+               /* not yet implemented */
+#else
                (*a)->a_type = attr_normalize( ch_strdup( type ) );
-               (*a)->a_vals = NULL;
-#ifndef SLAPD_SCHEMA_NOT_COMPAT
                (*a)->a_syntax = attr_syntax( type );
 #endif
+               (*a)->a_vals = NULL;
                (*a)->a_next = NULL;
        }
 
@@ -190,19 +227,23 @@ attr_merge(
 }
 
 /*
- * attr_find - find and return attribute type in list a
+ * attr_find - find attribute by type
  */
 
 Attribute *
 attr_find(
     Attribute  *a,
-    const char *type
+       const char      *type
 )
 {
        for ( ; a != NULL; a = a->a_next ) {
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+               /* not yet implemented */
+#else
                if ( strcasecmp( a->a_type, type ) == 0 ) {
                        return( a );
                }
+#endif
        }
 
        return( NULL );
@@ -225,9 +266,13 @@ attr_delete(
        Attribute       *save;
 
        for ( a = attrs; *a != NULL; a = &(*a)->a_next ) {
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+               /* not yet implemented */
+#else
                if ( strcasecmp( (*a)->a_type, type ) == 0 ) {
                        break;
                }
+#endif
        }
 
        if ( *a == NULL ) {
@@ -241,552 +286,3 @@ attr_delete(
        return( 0 );
 }
 
-#ifndef SLAPD_SCHEMA_NOT_COMPAT
-
-#define DEFAULT_SYNTAX SYNTAX_CIS
-
-/*
- * attr_syntax - return the syntax of attribute type
- */
-
-int
-attr_syntax( const char *type )
-{
-       AttributeType   *sat;
-
-       sat = at_find(type);
-       if ( sat ) {
-               return( sat->sat_syntax_compat );
-       }
-
-       return( DEFAULT_SYNTAX );
-}
-
-/*
- * attr_syntax_config - process an attribute syntax config line
- */
-
-void
-attr_syntax_config(
-    const char *fname,
-    int                lineno,
-    int                argc,
-    char       **argv
-)
-{
-       char                    *save;
-       LDAP_ATTRIBUTE_TYPE     *at;
-       int                     lasti;
-       int                     code;
-       const char              *err;
-
-       if ( argc < 2 ) {
-               Debug( LDAP_DEBUG_ANY,
-"%s: line %d: missing name in \"attribute <name>+ <syntax>\" (ignored)\n",
-                   fname, lineno, 0 );
-               return;
-       }
-
-       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  SLAPD_OID_DN_SYNTAX
-#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 = 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 = 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 = 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 = 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 ) {
-               /* 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",
-                   fname, lineno, argv[lasti] );
-               Debug( LDAP_DEBUG_ANY,
-    "possible syntaxes are \"cis\", \"ces\", \"tel\", \"dn\", or \"bin\"\n",
-                   0, 0, 0 );
-               free( (AttributeType *) at );
-               return;
-       }
-
-       save = argv[lasti];
-       argv[lasti] = NULL;
-       at->at_names = charray_dup( argv );
-       argv[lasti] = save;
-
-       code = at_add( at, &err );
-       if ( code ) {
-               fprintf( stderr, "%s: line %d: %s %s\n",
-                        fname, lineno, scherr2str(code), err);
-               exit( EXIT_FAILURE );
-       }
-
-       ldap_memfree(at);
-}
-
-int
-at_fake_if_needed(
-    const char *name
-)
-{
-       char *argv[3];
-
-       if ( at_find( name ) ) {
-               return 0;
-       } else {
-               argv[0] = (char*) name;
-               argv[1] = "cis";
-               argv[2] = NULL;
-               attr_syntax_config( "implicit", 0, 2, argv );
-               return 0;
-       }
-}
-#endif
-
-struct aindexrec {
-       char            *air_name;
-       AttributeType   *air_at;
-};
-
-static Avlnode *attr_index = NULL;
-static AttributeType *attr_list = NULL;
-
-static int
-attr_index_cmp(
-    struct aindexrec   *air1,
-    struct aindexrec   *air2
-)
-{
-       return (strcasecmp( air1->air_name, air2->air_name ));
-}
-
-static int
-attr_index_name_cmp(
-    char               *type,
-    struct aindexrec   *air
-)
-{
-       return (strcasecmp( type, air->air_name ));
-}
-
-AttributeType *
-at_find(
-    const char         *name
-)
-{
-       struct aindexrec        *air;
-       char                    *tmpname;
-
-#ifndef SLAPD_SCHEMA_NOT_COMPAT
-       /*
-        * The name may actually be an AttributeDescription, i.e. it may
-        * contain options.
-        */
-       /* Treat any attribute type with option as an unknown attribute type */
-       char *p = strchr( name, ';' );
-       if ( p ) {
-               tmpname = ch_malloc( p-name+1 );
-               strncpy( tmpname, name, p-name );
-               tmpname[p-name] = '\0';
-       } else
-#endif
-       {
-               tmpname = (char *)name;
-       }
-
-       if ( (air = (struct aindexrec *) avl_find( attr_index, tmpname,
-            (AVL_CMP) attr_index_name_cmp )) != NULL ) {
-               if ( tmpname != name )
-                       ldap_memfree( tmpname );
-               return( air->air_at );
-       }
-
-       if ( tmpname != name )
-               ldap_memfree( tmpname );
-       return( NULL );
-}
-
-int
-at_append_to_list(
-    AttributeType      *sat,
-    AttributeType      ***listp
-)
-{
-       AttributeType   **list;
-       AttributeType   **list1;
-       int             size;
-
-       list = *listp;
-       if ( !list ) {
-               size = 2;
-               list = calloc(size, sizeof(AttributeType *));
-               if ( !list ) {
-                       return -1;
-               }
-       } else {
-               size = 0;
-               list1 = *listp;
-               while ( *list1 ) {
-                       size++;
-                       list1++;
-               }
-               size += 2;
-               list1 = realloc(list, size*sizeof(AttributeType *));
-               if ( !list1 ) {
-                       return -1;
-               }
-               list = list1;
-       }
-       list[size-2] = sat;
-       list[size-1] = NULL;
-       *listp = list;
-       return 0;
-}
-
-int
-at_delete_from_list(
-    int                        pos,
-    AttributeType      ***listp
-)
-{
-       AttributeType   **list;
-       AttributeType   **list1;
-       int             i;
-       int             j;
-
-       if ( pos < 0 ) {
-               return -2;
-       }
-       list = *listp;
-       for ( i=0; list[i]; i++ )
-               ;
-       if ( pos >= i ) {
-               return -2;
-       }
-       for ( i=pos, j=pos+1; list[j]; i++, j++ ) {
-               list[i] = list[j];
-       }
-       list[i] = NULL;
-       /* Tell the runtime this can be shrinked */
-       list1 = realloc(list, (i+1)*sizeof(AttributeType **));
-       if ( !list1 ) {
-               return -1;
-       }
-       *listp = list1;
-       return 0;
-}
-
-int
-at_find_in_list(
-    AttributeType      *sat,
-    AttributeType      **list
-)
-{
-       int     i;
-
-       if ( !list ) {
-               return -1;
-       }
-       for ( i=0; list[i]; i++ ) {
-               if ( sat == list[i] ) {
-                       return i;
-               }
-       }
-       return -1;
-}
-
-static int
-at_insert(
-    AttributeType      *sat,
-    const char         **err
-)
-{
-       AttributeType           **atp;
-       struct aindexrec        *air;
-       char                    **names;
-
-       atp = &attr_list;
-       while ( *atp != NULL ) {
-               atp = &(*atp)->sat_next;
-       }
-       *atp = sat;
-
-       if ( sat->sat_oid ) {
-               air = (struct aindexrec *)
-                       ch_calloc( 1, sizeof(struct aindexrec) );
-               air->air_name = sat->sat_oid;
-               air->air_at = sat;
-               if ( avl_insert( &attr_index, (caddr_t) air,
-                                (AVL_CMP) attr_index_cmp,
-                                (AVL_DUP) avl_dup_error ) ) {
-                       *err = sat->sat_oid;
-                       ldap_memfree(air);
-                       return SLAP_SCHERR_DUP_ATTR;
-               }
-               /* FIX: temporal consistency check */
-               at_find(air->air_name);
-       }
-       if ( (names = sat->sat_names) ) {
-               while ( *names ) {
-                       air = (struct aindexrec *)
-                               ch_calloc( 1, sizeof(struct aindexrec) );
-                       air->air_name = ch_strdup(*names);
-                       air->air_at = sat;
-                       if ( avl_insert( &attr_index, (caddr_t) air,
-                                        (AVL_CMP) attr_index_cmp,
-                                        (AVL_DUP) avl_dup_error ) ) {
-                               *err = *names;
-                               ldap_memfree(air->air_name);
-                               ldap_memfree(air);
-                               return SLAP_SCHERR_DUP_ATTR;
-                       }
-                       /* FIX: temporal consistency check */
-                       at_find(air->air_name);
-                       names++;
-               }
-       }
-
-       return 0;
-}
-
-int
-at_add(
-    LDAP_ATTRIBUTE_TYPE        *at,
-    const char         **err
-)
-{
-       AttributeType   *sat;
-       AttributeType   *sat1;
-       MatchingRule    *mr;
-       Syntax          *syn;
-       int             code;
-       char            *errattr;
-
-       if ( at->at_names && at->at_names[0] ) {
-               errattr = at->at_names[0];
-       } else if ( at->at_oid ) {
-               errattr = at->at_oid;
-       } else {
-               errattr = "";
-               return SLAP_SCHERR_ATTR_INCOMPLETE;
-       }
-       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;
-                       if ( at_append_to_list(sat, &sat1->sat_subtypes) ) {
-                               *err = errattr;
-                               return SLAP_SCHERR_OUTOFMEM;
-                       }
-               } else {
-                       *err = at->at_sup_oid;
-                       return SLAP_SCHERR_ATTR_NOT_FOUND;
-               }
-       }
-
-       /*
-        * 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;
-               } else {
-                       *err = sat->sat_syntax_oid;
-                       return SLAP_SCHERR_SYN_NOT_FOUND;
-               }
-
-#ifndef SLAPD_SCHEMA_NOT_COMPAT
-               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, 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, 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;
-               }
-#endif
-
-       } else if ( sat->sat_syntax == NULL ) {
-               return SLAP_SCHERR_ATTR_INCOMPLETE;
-       }
-
-       if ( sat->sat_equality_oid ) {
-               if ( (mr = mr_find(sat->sat_equality_oid)) ) {
-                       sat->sat_equality = mr;
-               } else {
-                       *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;
-               } else {
-                       *err = sat->sat_ordering_oid;
-                       return SLAP_SCHERR_MR_NOT_FOUND;
-               }
-       }
-
-       if ( sat->sat_substr_oid ) {
-               if ( (mr = mr_find(sat->sat_substr_oid)) ) {
-                       sat->sat_substr = mr;
-               } else {
-                       *err = sat->sat_substr_oid;
-                       return SLAP_SCHERR_MR_NOT_FOUND;
-               }
-       }
-
-       code = at_insert(sat,err);
-       return code;
-}
-
-
-char *
-#ifdef SLAPD_SCHEMA_NOT_COMPAT
-at_canonical_name( AttributeType * atp )
-#else
-at_canonical_name( const char * a_type )
-#endif
-{
-#ifndef SLAPD_SCHEMA_NOT_COMPAT
-       AttributeType   *atp;
-
-       atp=at_find(a_type);
-#endif
-
-       if ( atp == NULL ) {
-#ifdef SLAPD_SCHEMA_NOT_COMPAT
-               return NULL;
-#else
-               return (char *) a_type;
-#endif
-
-       } else if ( atp->sat_names
-               && atp->sat_names[0] && (*(atp->sat_names[0]) != '\0') )
-       {
-               return atp->sat_names[0];
-
-       } else if (atp->sat_oid && (*atp->sat_oid != '\0')) {
-               return atp->sat_oid;
-       }
-
-#ifdef SLAPD_SCHEMA_NOT_COMPAT
-       return NULL;
-#else
-       return (char *) a_type;
-#endif
-}
-
-#if defined( SLAPD_SCHEMA_DN )
-int
-at_schema_info( Entry *e )
-{
-       struct berval   val;
-       struct berval   *vals[2];
-       AttributeType   *at;
-
-       vals[0] = &val;
-       vals[1] = NULL;
-
-       for ( at = attr_list; at; at = at->sat_next ) {
-               val.bv_val = ldap_attributetype2str( &at->sat_atype );
-               if ( val.bv_val ) {
-                       val.bv_len = strlen( val.bv_val );
-                       Debug( LDAP_DEBUG_TRACE, "Merging at [%ld] %s\n",
-                              (long) val.bv_len, val.bv_val, 0 );
-                       attr_merge( e, "attributeTypes", vals );
-                       ldap_memfree( val.bv_val );
-               } else {
-                       return -1;
-               }
-       }
-       return 0;
-}
-#endif
-
-#ifdef LDAP_DEBUG
-static int
-at_index_printnode( struct aindexrec *air )
-{
-
-       printf("%s = %s\n",
-               air->air_name,
-               ldap_attributetype2str(&air->air_at->sat_atype) );
-       return( 0 );
-}
-
-static void
-at_index_print( void )
-{
-       printf("Printing attribute type index:\n");
-       (void) avl_apply( attr_index, (AVL_APPLY) at_index_printnode,
-               0, -1, AVL_INORDER );
-}
-#endif
index b72dc515129b92902ca5bb7ada826df9d115f6b5..2ab81e76a6ff935043f47d4d643b956cd7eca11d 100644 (file)
@@ -38,7 +38,7 @@ bdb2i_back_add_internal(
                return( -1 );
        }
 
-       if ( global_schemacheck && oc_schema_check( e ) != 0 ) {
+       if ( schema_check_entry( e ) != 0 ) {
                Debug( LDAP_DEBUG_TRACE, "entry failed schema check\n",
                        0, 0, 0 );
 
index badab589eb4cc993bd6c5944277ca8607cb8d2f4..bcb6f1c3946b2c5fdd56f956a95414d358e9baba 100644 (file)
@@ -74,7 +74,7 @@ bdb2i_back_modify_internal(
        }
 
        /* check that the entry still obeys the schema */
-       if ( global_schemacheck && oc_schema_check( e ) != 0 ) {
+       if ( schema_check_entry( e ) != 0 ) {
                Debug( LDAP_DEBUG_ANY, "entry failed schema check\n", 0, 0, 0 );
                send_ldap_result( conn, op, LDAP_OBJECT_CLASS_VIOLATION,
                        NULL, NULL, NULL, NULL );
index edeaf57a10062c0a28be9291182a0e6ef364075b..fce939ddd2a393c247c3e702173232c441d31b1f 100644 (file)
@@ -43,7 +43,7 @@ ldbm_back_add(
                return( -1 );
        }
 
-       if ( global_schemacheck && oc_schema_check( e ) != 0 ) {
+       if ( schema_check_entry( e ) != 0 ) {
                ldap_pvt_thread_mutex_unlock(&li->li_add_mutex);
 
                Debug( LDAP_DEBUG_TRACE, "entry failed schema check\n",
index 1e746fc8f984f4a75c1a986ced9b3e3ec1099cf4..6c90a6f179e301d87a3d13e2fcb337408ccd99b2 100644 (file)
@@ -15,6 +15,7 @@
 #include "slap.h"
 #include "back-ldbm.h"
 
+
 static int     change_value(Backend *be,
                          DBCache *db,
                          char *type,
@@ -51,7 +52,11 @@ index_add_entry(
        /* add the dn to the indexes */
        {
                char *dn = ch_strdup("dn");
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+               /* not yet implemented */
+#else
                index_change_values( be, dn, bvals, e->e_id, SLAP_INDEX_ADD_OP );
+#endif
                free( dn );
        }
 
@@ -59,8 +64,12 @@ index_add_entry(
 
        /* add each attribute to the indexes */
        for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) {
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+               /* index_change_values( be, SLAP_INDEX_ADD_OP, e->e_id, ap ); */
+#else
                index_change_values( be, ap->a_type, ap->a_vals, e->e_id,
                                     SLAP_INDEX_ADD_OP );
+#endif
        }
 
        Debug( LDAP_DEBUG_TRACE, "<= index_add( %ld, \"%s\" ) 0\n", e->e_id,
index d22fcc614cf3e619116b6aec998e43160889bf35..f30a153a42faac48d39298672cccd07fe36cbaec 100644 (file)
@@ -95,7 +95,7 @@ int ldbm_modify_internal(
        ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
 
        /* check that the entry still obeys the schema */
-       if ( global_schemacheck && oc_schema_check( e ) != 0 ) {
+       if ( schema_check_entry( e ) != 0 ) {
                attrs_free( e->e_attrs );
                e->e_attrs = save_attrs;
                Debug( LDAP_DEBUG_ANY, "entry failed schema check\n", 0, 0, 0 );
index c2ed169b9a17737f91d9f7937987ae75fce46281..8dd65ff26e0eb280de80bad425be929d08e65194 100644 (file)
@@ -633,26 +633,27 @@ backend_group(
 }
 
 #ifdef SLAPD_SCHEMA_DN
-Attribute *backend_subschemasubentry( Backend *be )
+Attribute *backend_operational(
+       Backend *be,
+       Entry *e )
 {
-       /*
-        * This routine returns points to STATIC data!!!
-        */
-       /* and should be backend specific */
-
-       static struct berval ss_val = {
-               sizeof(SLAPD_SCHEMA_DN)-1,
-               SLAPD_SCHEMA_DN };
-       static struct berval *ss_vals[2] = { &ss_val, NULL };
-       static Attribute ss_attr = {
-               "subschemasubentry",
-               ss_vals,
-#ifndef SLAPD_SCHEMA_NOT_COMPAT
-               SYNTAX_DN | SYNTAX_CIS,
+       Attribute *a = ch_malloc( sizeof( Attribute ) );
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+       /* not yet implemented */
+#else
+       a->a_type = "subschemasubentry";
+       a->a_syntax = SYNTAX_DN | SYNTAX_CIS;
 #endif
-               NULL
-       };
 
-       return &ss_attr;
+       /* Should be backend specific */
+       a->a_vals = ch_malloc( 2 * sizeof( struct berval * ) );
+       a->a_vals[0] = ch_malloc( sizeof( struct berval ) );
+       a->a_vals[0]->bv_val = strdup( SLAPD_SCHEMA_DN );
+       a->a_vals[0]->bv_len = sizeof( SLAPD_SCHEMA_DN ) - 1;
+       a->a_vals[1] = NULL;
+
+       a->a_next = NULL;
+
+       return a;
 }
 #endif
index b0cd52e28fda5384293f95be943bee64000f0968..86abbae9c1174b2f14a03ac3b5c1aa07fbdc249a 100644 (file)
@@ -197,9 +197,18 @@ entry2str(
                /* put "<type>:[:] <value>" line for each value */
                for ( i = 0; a->a_vals[i] != NULL; i++ ) {
                        bv = a->a_vals[i];
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+                       tmplen = a->a_desc.ad_cname->bv_len;
+#else
                        tmplen = strlen( a->a_type );
+#endif
                        MAKE_SPACE( LDIF_SIZE_NEEDED( tmplen, bv->bv_len ));
-                       ldif_sput( (char **) &ecur, LDIF_PUT_VALUE, a->a_type,
+                       ldif_sput( (char **) &ecur, LDIF_PUT_VALUE,
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+                               a->a_desc.ad_cname->bv_val,
+#else
+                               a->a_type,
+#endif
                            bv->bv_val, bv->bv_len );
                }
        }
index 8e2d0200cad93f0008ec5cb7534d7f9b9a427fcb..fa3e332047f5db305a98b7d0c0a5e43d1206aa3b 100644 (file)
@@ -140,6 +140,10 @@ SOURCE=.\add.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\at.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\attr.c
 # End Source File
 # Begin Source File
@@ -236,6 +240,14 @@ SOURCE=.\monitor.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\mr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\oc.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\operation.c
 # End Source File
 # Begin Source File
@@ -268,6 +280,10 @@ SOURCE=.\schema.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\schema_check.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\schema_init.c
 # End Source File
 # Begin Source File
@@ -292,6 +308,10 @@ SOURCE=.\suffixalias.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\syntax.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\unbind.c
 # End Source File
 # Begin Source File
diff --git a/servers/slapd/mr.c b/servers/slapd/mr.c
new file mode 100644 (file)
index 0000000..8dbfb96
--- /dev/null
@@ -0,0 +1,206 @@
+/* mr.c - routines to manage matching rule definitions */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/ctype.h>
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "ldap_pvt.h"
+
+
+struct mindexrec {
+       char            *mir_name;
+       MatchingRule    *mir_mr;
+};
+
+static Avlnode *mr_index = NULL;
+static MatchingRule *mr_list = NULL;
+
+static int
+mr_index_cmp(
+    struct mindexrec   *mir1,
+    struct mindexrec   *mir2
+)
+{
+       return (strcmp( mir1->mir_name, mir2->mir_name ));
+}
+
+static int
+mr_index_name_cmp(
+    char               *name,
+    struct mindexrec   *mir
+)
+{
+       return (strcmp( name, mir->mir_name ));
+}
+
+MatchingRule *
+mr_find( const char *mrname )
+{
+       struct mindexrec        *mir = NULL;
+
+       if ( (mir = (struct mindexrec *) avl_find( mr_index, mrname,
+            (AVL_CMP) mr_index_name_cmp )) != NULL ) {
+               return( mir->mir_mr );
+       }
+       return( NULL );
+}
+
+static int
+mr_insert(
+    MatchingRule       *smr,
+    const char         **err
+)
+{
+       MatchingRule            **mrp;
+       struct mindexrec        *mir;
+       char                    **names;
+
+       mrp = &mr_list;
+       while ( *mrp != NULL ) {
+               mrp = &(*mrp)->smr_next;
+       }
+       *mrp = smr;
+
+       if ( smr->smr_oid ) {
+               mir = (struct mindexrec *)
+                       ch_calloc( 1, sizeof(struct mindexrec) );
+               mir->mir_name = smr->smr_oid;
+               mir->mir_mr = smr;
+               if ( avl_insert( &mr_index, (caddr_t) mir,
+                                (AVL_CMP) mr_index_cmp,
+                                (AVL_DUP) avl_dup_error ) ) {
+                       *err = smr->smr_oid;
+                       ldap_memfree(mir);
+                       return SLAP_SCHERR_DUP_RULE;
+               }
+               /* FIX: temporal consistency check */
+               mr_find(mir->mir_name);
+       }
+       if ( (names = smr->smr_names) ) {
+               while ( *names ) {
+                       mir = (struct mindexrec *)
+                               ch_calloc( 1, sizeof(struct mindexrec) );
+                       mir->mir_name = ch_strdup(*names);
+                       mir->mir_mr = smr;
+                       if ( avl_insert( &mr_index, (caddr_t) mir,
+                                        (AVL_CMP) mr_index_cmp,
+                                        (AVL_DUP) avl_dup_error ) ) {
+                               *err = *names;
+                               ldap_memfree(mir);
+                               return SLAP_SCHERR_DUP_RULE;
+                       }
+                       /* FIX: temporal consistency check */
+                       mr_find(mir->mir_name);
+                       names++;
+               }
+       }
+       return 0;
+}
+
+int
+mr_add(
+    LDAP_MATCHING_RULE         *mr,
+       slap_mr_convert_func *convert,
+       slap_mr_normalize_func *normalize,
+    slap_mr_match_func *match,
+       slap_mr_indexer_func *indexer,
+    slap_mr_filter_func        *filter,
+    const char         **err
+)
+{
+       MatchingRule    *smr;
+       Syntax          *syn;
+       int             code;
+
+       smr = (MatchingRule *) ch_calloc( 1, sizeof(MatchingRule) );
+       memcpy( &smr->smr_mrule, mr, sizeof(LDAP_MATCHING_RULE));
+
+       smr->smr_convert = convert;
+       smr->smr_normalize = normalize;
+       smr->smr_match = match;
+       smr->smr_indexer = indexer;
+       smr->smr_filter = filter;
+
+       if ( smr->smr_syntax_oid ) {
+               if ( (syn = syn_find(smr->smr_syntax_oid)) ) {
+                       smr->smr_syntax = syn;
+               } else {
+                       *err = smr->smr_syntax_oid;
+                       return SLAP_SCHERR_SYN_NOT_FOUND;
+               }
+       } else {
+               *err = "";
+               return SLAP_SCHERR_MR_INCOMPLETE;
+       }
+       code = mr_insert(smr,err);
+       return code;
+}
+
+
+int
+register_matching_rule(
+       char * desc,
+       slap_mr_convert_func *convert,
+       slap_mr_normalize_func *normalize,
+       slap_mr_match_func *match,
+       slap_mr_indexer_func *indexer,
+       slap_mr_filter_func *filter )
+{
+       LDAP_MATCHING_RULE *mr;
+       int             code;
+       const char      *err;
+
+       mr = ldap_str2matchingrule( desc, &code, &err);
+       if ( !mr ) {
+               Debug( LDAP_DEBUG_ANY, "Error in register_matching_rule: %s before %s in %s\n",
+                   ldap_scherr2str(code), err, desc );
+               return( -1 );
+       }
+
+       code = mr_add( mr, convert, normalize, match, indexer, filter, &err );
+       if ( code ) {
+               Debug( LDAP_DEBUG_ANY, "Error in register_syntax: %s for %s in %s\n",
+                   scherr2str(code), err, desc );
+               return( -1 );
+       }
+       return( 0 );
+}
+
+
+#if defined( SLAPD_SCHEMA_DN )
+
+int mr_schema_info( Entry *e )
+{
+       struct berval   val;
+       struct berval   *vals[2];
+       MatchingRule    *mr;
+
+       vals[0] = &val;
+       vals[1] = NULL;
+
+       for ( mr = mr_list; mr; mr = mr->smr_next ) {
+               val.bv_val = ldap_matchingrule2str( &mr->smr_mrule );
+               if ( val.bv_val ) {
+                       val.bv_len = strlen( val.bv_val );
+                       Debug( LDAP_DEBUG_TRACE, "Merging mr [%ld] %s\n",
+                              (long) val.bv_len, val.bv_val, 0 );
+                       attr_merge( e, "matchingRules", vals );
+                       ldap_memfree( val.bv_val );
+               } else {
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+#endif
diff --git a/servers/slapd/oc.c b/servers/slapd/oc.c
new file mode 100644 (file)
index 0000000..88e1809
--- /dev/null
@@ -0,0 +1,456 @@
+/* oc.c - object class routines */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/ctype.h>
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "ldap_pvt.h"
+
+int is_entry_objectclass(
+       Entry*  e,
+       const char*     oc)
+{
+       Attribute *attr;
+       struct berval bv;
+
+       if( e == NULL || oc == NULL || *oc == '\0' )
+               return 0;
+
+       /*
+        * find objectClass attribute
+        */
+       attr = attr_find(e->e_attrs, "objectclass");
+
+       if( attr == NULL ) {
+               /* no objectClass attribute */
+               return 0;
+       }
+
+       bv.bv_val = (char *) oc;
+       bv.bv_len = strlen( bv.bv_val );
+
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+       /* not yet implemented */
+#else
+       if( value_find(attr->a_vals, &bv, attr->a_syntax, 1) != 0) {
+               /* entry is not of this objectclass */
+               return 0;
+       }
+#endif
+
+       return 1;
+}
+
+
+#ifndef SLAPD_SCHEMA_NOT_COMPAT
+       /* these shouldn't be hardcoded */
+
+static char *oc_op_usermod_attrs[] = {
+       /*
+        * these are operational attributes which are
+        * not defined as NO-USER_MODIFICATION and
+        * which slapd supports modification of.
+        *
+        * Currently none.
+        * Likely candidate, "aci"
+        */
+       NULL
+};
+
+static char *oc_op_attrs[] = {
+       /*
+        * these are operational attributes 
+        * most could be user modifiable
+        */
+       "objectClasses",
+       "attributeTypes",
+       "matchingRules",
+       "matchingRuleUse",
+       "dITStructureRules",
+       "dITContentRules",
+       "nameForms",
+       "ldapSyntaxes",
+       "namingContexts",
+       "supportedExtension",
+       "supportedControl",
+       "supportedSASLMechanisms",
+       "supportedLDAPversion",
+       "supportedACIMechanisms",
+       "subschemaSubentry",            /* NO USER MOD */
+       NULL
+
+};
+
+/* this list should be extensible  */
+static char *oc_op_no_usermod_attrs[] = {
+       /*
+        * Operational and 'no user modification' attributes
+        * which are STORED in the directory server.
+        */
+
+       /* RFC2252, 3.2.1 */
+       "creatorsName",
+       "createTimestamp",
+       "modifiersName",
+       "modifyTimestamp",
+
+       NULL
+};
+#endif
+
+
+/*
+ * check to see if attribute is 'operational' or not.
+ */
+int
+oc_check_op_attr( const char *type )
+{
+#ifndef SLAPD_SCHEMA_NOT_COMPAT
+       return charray_inlist( oc_op_attrs, type )
+               || charray_inlist( oc_op_usermod_attrs, type )
+               || charray_inlist( oc_op_no_usermod_attrs, type );
+#else
+       AttributeType *at = at_find( type );
+
+       if( at == NULL ) return 0;
+
+       return at->sat_usage != LDAP_SCHEMA_USER_APPLICATIONS;
+#endif
+}
+
+/*
+ * check to see if attribute can be user modified or not.
+ */
+int
+oc_check_op_usermod_attr( const char *type )
+{
+#ifndef SLAPD_SCHEMA_NOT_COMPAT
+       return charray_inlist( oc_op_usermod_attrs, type );
+#else
+       /* not (yet) in schema */
+       return 0;
+#endif
+}
+
+/*
+ * check to see if attribute is 'no user modification' or not.
+ */
+int
+oc_check_op_no_usermod_attr( const char *type )
+{
+#ifndef SLAPD_SCHEMA_NOT_COMPAT
+       return charray_inlist( oc_op_no_usermod_attrs, type );
+#else
+       AttributeType *at = at_find( type );
+
+       if( at == NULL ) return 0;
+
+       return at->sat_no_user_mod;
+#endif
+}
+
+
+struct oindexrec {
+       char            *oir_name;
+       ObjectClass     *oir_oc;
+};
+
+static Avlnode *oc_index = NULL;
+static ObjectClass *oc_list = NULL;
+
+static int
+oc_index_cmp(
+    struct oindexrec   *oir1,
+    struct oindexrec   *oir2
+)
+{
+       return (strcasecmp( oir1->oir_name, oir2->oir_name ));
+}
+
+static int
+oc_index_name_cmp(
+    char               *name,
+    struct oindexrec   *oir
+)
+{
+       return (strcasecmp( name, oir->oir_name ));
+}
+
+ObjectClass *
+oc_find( const char *ocname )
+{
+       struct oindexrec        *oir = NULL;
+
+       if ( (oir = (struct oindexrec *) avl_find( oc_index, ocname,
+            (AVL_CMP) oc_index_name_cmp )) != NULL ) {
+               return( oir->oir_oc );
+       }
+       return( NULL );
+}
+
+static int
+oc_create_required(
+    ObjectClass                *soc,
+    char               **attrs,
+    const char         **err
+)
+{
+       char            **attrs1;
+       AttributeType   *sat;
+       AttributeType   **satp;
+       int             i;
+
+       if ( attrs ) {
+               attrs1 = attrs;
+               while ( *attrs1 ) {
+                       sat = at_find(*attrs1);
+                       if ( !sat ) {
+                               *err = *attrs1;
+                               return SLAP_SCHERR_ATTR_NOT_FOUND;
+                       }
+                       if ( at_find_in_list(sat, soc->soc_required) < 0) {
+                               if ( at_append_to_list(sat, &soc->soc_required) ) {
+                                       *err = *attrs1;
+                                       return SLAP_SCHERR_OUTOFMEM;
+                               }
+                       }
+                       attrs1++;
+               }
+               /* Now delete duplicates from the allowed list */
+               for ( satp = soc->soc_required; *satp; satp++ ) {
+                       i = at_find_in_list(*satp,soc->soc_allowed);
+                       if ( i >= 0 ) {
+                               at_delete_from_list(i, &soc->soc_allowed);
+                       }
+               }
+       }
+       return 0;
+}
+
+static int
+oc_create_allowed(
+    ObjectClass                *soc,
+    char               **attrs,
+    const char         **err
+)
+{
+       char            **attrs1;
+       AttributeType   *sat;
+
+       if ( attrs ) {
+               attrs1 = attrs;
+               while ( *attrs1 ) {
+                       sat = at_find(*attrs1);
+                       if ( !sat ) {
+                               *err = *attrs1;
+                               return SLAP_SCHERR_ATTR_NOT_FOUND;
+                       }
+                       if ( at_find_in_list(sat, soc->soc_required) < 0 &&
+                            at_find_in_list(sat, soc->soc_allowed) < 0 ) {
+                               if ( at_append_to_list(sat, &soc->soc_allowed) ) {
+                                       *err = *attrs1;
+                                       return SLAP_SCHERR_OUTOFMEM;
+                               }
+                       }
+                       attrs1++;
+               }
+       }
+       return 0;
+}
+
+static int
+oc_add_sups(
+    ObjectClass                *soc,
+    char               **sups,
+    const char         **err
+)
+{
+       int             code;
+       ObjectClass     *soc1;
+       int             nsups;
+       char            **sups1;
+       int             add_sups = 0;
+
+       if ( sups ) {
+               if ( !soc->soc_sups ) {
+                       /* We are at the first recursive level */
+                       add_sups = 1;
+                       nsups = 0;
+                       sups1 = sups;
+                       while ( *sups1 ) {
+                               nsups++;
+                               sups1++;
+                       }
+                       nsups++;
+                       soc->soc_sups = (ObjectClass **)ch_calloc(1,
+                                         nsups*sizeof(ObjectClass *));
+               }
+               nsups = 0;
+               sups1 = sups;
+               while ( *sups1 ) {
+                       soc1 = oc_find(*sups1);
+                       if ( !soc1 ) {
+                               *err = *sups1;
+                               return SLAP_SCHERR_CLASS_NOT_FOUND;
+                       }
+
+                       if ( add_sups )
+                               soc->soc_sups[nsups] = soc1;
+
+                       code = oc_add_sups(soc,soc1->soc_sup_oids, err);
+                       if ( code )
+                               return code;
+
+                       code = oc_create_required(soc,soc1->soc_at_oids_must,err);
+                       if ( code )
+                               return code;
+                       code = oc_create_allowed(soc,soc1->soc_at_oids_may,err);
+                       if ( code )
+                               return code;
+
+                       nsups++;
+                       sups1++;
+               }
+       }
+       return 0;
+}
+
+static int
+oc_insert(
+    ObjectClass                *soc,
+    const char         **err
+)
+{
+       ObjectClass     **ocp;
+       struct oindexrec        *oir;
+       char                    **names;
+
+       ocp = &oc_list;
+       while ( *ocp != NULL ) {
+               ocp = &(*ocp)->soc_next;
+       }
+       *ocp = soc;
+
+       if ( soc->soc_oid ) {
+               oir = (struct oindexrec *)
+                       ch_calloc( 1, sizeof(struct oindexrec) );
+               oir->oir_name = soc->soc_oid;
+               oir->oir_oc = soc;
+               if ( avl_insert( &oc_index, (caddr_t) oir,
+                                (AVL_CMP) oc_index_cmp,
+                                (AVL_DUP) avl_dup_error ) ) {
+                       *err = soc->soc_oid;
+                       ldap_memfree(oir);
+                       return SLAP_SCHERR_DUP_CLASS;
+               }
+               /* FIX: temporal consistency check */
+               oc_find(oir->oir_name);
+       }
+       if ( (names = soc->soc_names) ) {
+               while ( *names ) {
+                       oir = (struct oindexrec *)
+                               ch_calloc( 1, sizeof(struct oindexrec) );
+                       oir->oir_name = ch_strdup(*names);
+                       oir->oir_oc = soc;
+                       if ( avl_insert( &oc_index, (caddr_t) oir,
+                                        (AVL_CMP) oc_index_cmp,
+                                        (AVL_DUP) avl_dup_error ) ) {
+                               *err = *names;
+                               ldap_memfree(oir);
+                               return SLAP_SCHERR_DUP_CLASS;
+                       }
+                       /* FIX: temporal consistency check */
+                       oc_find(oir->oir_name);
+                       names++;
+               }
+       }
+       return 0;
+}
+
+int
+oc_add(
+    LDAP_OBJECT_CLASS  *oc,
+    const char         **err
+)
+{
+       ObjectClass     *soc;
+       int             code;
+
+       soc = (ObjectClass *) ch_calloc( 1, sizeof(ObjectClass) );
+       memcpy( &soc->soc_oclass, oc, sizeof(LDAP_OBJECT_CLASS));
+       if ( (code = oc_add_sups(soc,soc->soc_sup_oids,err)) != 0 )
+               return code;
+       if ( (code = oc_create_required(soc,soc->soc_at_oids_must,err)) != 0 )
+               return code;
+       if ( (code = oc_create_allowed(soc,soc->soc_at_oids_may,err)) != 0 )
+               return code;
+       code = oc_insert(soc,err);
+       return code;
+}
+
+#ifdef LDAP_DEBUG
+
+static void
+oc_print( ObjectClass *oc )
+{
+       int     i;
+       const char *mid;
+
+       printf( "objectclass %s\n", ldap_objectclass2name( &oc->soc_oclass ) );
+       if ( oc->soc_required != NULL ) {
+               mid = "\trequires ";
+               for ( i = 0; oc->soc_required[i] != NULL; i++, mid = "," )
+                       printf( "%s%s", mid,
+                               ldap_attributetype2name( &oc->soc_required[i]->sat_atype ) );
+               printf( "\n" );
+       }
+       if ( oc->soc_allowed != NULL ) {
+               mid = "\tallows ";
+               for ( i = 0; oc->soc_allowed[i] != NULL; i++, mid = "," )
+                       printf( "%s%s", mid,
+                               ldap_attributetype2name( &oc->soc_allowed[i]->sat_atype ) );
+               printf( "\n" );
+       }
+}
+
+#endif
+
+
+#if defined( SLAPD_SCHEMA_DN )
+
+int
+oc_schema_info( Entry *e )
+{
+       struct berval   val;
+       struct berval   *vals[2];
+       ObjectClass     *oc;
+
+       vals[0] = &val;
+       vals[1] = NULL;
+
+       for ( oc = oc_list; oc; oc = oc->soc_next ) {
+               val.bv_val = ldap_objectclass2str( &oc->soc_oclass );
+               if ( val.bv_val ) {
+                       val.bv_len = strlen( val.bv_val );
+                       Debug( LDAP_DEBUG_TRACE, "Merging oc [%ld] %s\n",
+                              (long) val.bv_len, val.bv_val, 0 );
+                       attr_merge( e, "objectClasses", vals );
+                       ldap_memfree( val.bv_val );
+               } else {
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+#endif
index 83d03eba59f8114c901f0f5b7af83eacdffec644..0fdac434cbf597d577738cbeb1f168afca089d9b 100644 (file)
@@ -70,14 +70,15 @@ LIBSLAPD_F (int) at_fake_if_needed LDAP_P(( const char *name ));
 LIBSLAPD_F (int) at_schema_info LDAP_P(( Entry *e ));
 LIBSLAPD_F (int) at_add LDAP_P(( LDAP_ATTRIBUTE_TYPE *at, const char **err ));
 
+LIBSLAPD_F (void) attrs_free LDAP_P(( Attribute *a ));
+LIBSLAPD_F (Attribute *) attrs_dup LDAP_P(( Attribute *a ));
+
 #ifdef SLAPD_SCHEMA_NOT_COMPAT
-LIBSLAPD_F (char *) at_canonical_name LDAP_P(( AttributeType *a_type ));
+#      define at_canonical_name(at) ((at)->sat_cname)  
 #else
 LIBSLAPD_F (char *) at_canonical_name LDAP_P(( const char * a_type ));
 #endif
 
-LIBSLAPD_F (void) attrs_free LDAP_P(( Attribute *a ));
-LIBSLAPD_F (Attribute *) attrs_dup LDAP_P(( Attribute *a ));
 
 /*
  * ava.c
@@ -138,10 +139,8 @@ LIBSLAPD_F (int) backend_group LDAP_P((Backend *be,
 ));
 #endif
 
-#ifdef SLAPD_SCHEMA_DN
-/* temporary extern for temporary routine*/
-LIBSLAPD_F (Attribute *) backend_subschemasubentry( Backend * );
-#endif
+LIBSLAPD_F (Attribute *) backend_operational( Backend *, Entry * );
+
 
 
 /*
@@ -455,11 +454,19 @@ LIBSLAPD_F (int) sasl_bind LDAP_P((Backend *,
        char *, char *, char *, struct berval *, char **));
 #endif
 
+/* oc.c */
+LIBSLAPD_F (int) oc_schema_info( Entry *e );
+
+/* mr.c */
+LIBSLAPD_F (int) mr_schema_info( Entry *e );
+
+/* syntax.c */
+LIBSLAPD_F (int) syn_schema_info( Entry *e );
+
 /*
  * schema.c
  */
 
-LIBSLAPD_F (int) oc_schema_check LDAP_P(( Entry *e ));
 LIBSLAPD_F (int) oc_check_op_attr LDAP_P(( const char *type ));
 LIBSLAPD_F (int) oc_check_op_usermod_attr LDAP_P(( const char *type ));
 LIBSLAPD_F (int) oc_check_op_no_usermod_attr LDAP_P(( const char *type ));
@@ -503,6 +510,11 @@ LIBSLAPD_F (int) is_entry_objectclass LDAP_P((
 #define is_entry_alias(e)              is_entry_objectclass((e), "ALIAS")
 #define is_entry_referral(e)   is_entry_objectclass((e), "REFERRAL")
 
+/*
+ * schema_check.c
+ */
+LIBSLAPD_F (int) schema_check_entry LDAP_P(( Entry *e ));
+
 
 /*
  * schema_init.c
index ab5b12750e3132f2eb1b17341e209855511b9bec..f90c92e930611721e883d6ed6e10d0de8868e0a5 100644 (file)
@@ -612,7 +612,7 @@ send_search_entry(
 )
 {
        BerElement      *ber;
-       Attribute       *a;
+       Attribute       *a, *aa;
        int             i, rc=-1, bytes;
        char            *edn;
        int             userattrs;
@@ -659,36 +659,40 @@ send_search_entry(
                : charray_inlist( attrs, LDAP_ALL_OPERATIONAL_ATTRIBUTES );
 
        for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
+               char *desc;
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+               desc = a->a_desc.ad_type->sat_cname;
+#else
+               desc = a->a_type;
+#endif
+
                if ( attrs == NULL ) {
                        /* all addrs request, skip operational attributes */
-                       if( !opattrs && oc_check_op_attr( a->a_type ) ) {
+                       if( !opattrs && oc_check_op_attr( desc ) ) {
                                continue;
                        }
 
                } else {
                        /* specific addrs requested */
-                       if (  oc_check_op_attr( a->a_type ) ) {
-                               if( !opattrs && !charray_inlist( attrs, a->a_type ) )
-                               {
+                       if ( oc_check_op_attr( desc ) )
+                       {
+                               if( !opattrs && !charray_inlist( attrs, desc ) ) {
                                        continue;
                                }
                        } else {
-                               if (!userattrs && !charray_inlist( attrs, a->a_type ) )
-                               {
+                               if (!userattrs && !charray_inlist( attrs, desc ) ) {
                                        continue;
                                }
                        }
                }
 
-               if ( ! access_allowed( be, conn, op, e,
-                       a->a_type, NULL, ACL_READ ) )
-               {
+               if ( ! access_allowed( be, conn, op, e, desc, NULL, ACL_READ ) ) {
                        Debug( LDAP_DEBUG_ACL, "acl: access to attribute %s not allowed\n",
-                           a->a_type, 0, 0 );
+                           desc, 0, 0 );
                        continue;
                }
 
-               if (( rc = ber_printf( ber, "{s[" /*]}*/ , a->a_type )) == -1 ) {
+               if (( rc = ber_printf( ber, "{s[" /*]}*/ , desc )) == -1 ) {
                        Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
                        ber_free( ber, 1 );
                        send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
@@ -699,11 +703,11 @@ send_search_entry(
                if ( ! attrsonly ) {
                        for ( i = 0; a->a_vals[i] != NULL; i++ ) {
                                if ( ! access_allowed( be, conn, op, e,
-                                       a->a_type, a->a_vals[i], ACL_READ ) )
+                                       desc, a->a_vals[i], ACL_READ ) )
                                {
                                        Debug( LDAP_DEBUG_ACL,
                                                "acl: access to attribute %s, value %d not allowed\n",
-                                       a->a_type, i, 0 );
+                                       desc, i, 0 );
                                        continue;
                                }
 
@@ -727,42 +731,46 @@ send_search_entry(
                }
        }
 
-#ifdef SLAPD_SCHEMA_DN
        /* eventually will loop through generated operational attributes */
        /* only have subschemaSubentry implemented */
-       a = backend_subschemasubentry( be );
+       aa = backend_operational( be, e );
        
-       do {
+       for (a = aa ; a == NULL; a = a->a_next ) {
+               char *desc;
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+               desc = a->a_desc.ad_type->sat_cname;
+#else
+               desc = a->a_type;
+#endif
+
                if ( attrs == NULL ) {
                        /* all addrs request, skip operational attributes */
-                       if( !opattrs && oc_check_op_attr( a->a_type ) ) {
+                       if( !opattrs && oc_check_op_attr( desc ) ) {
                                continue;
                        }
 
                } else {
                        /* specific addrs requested */
-                       if (  oc_check_op_attr( a->a_type ) ) {
-                               if( !opattrs && !charray_inlist( attrs, a->a_type ) )
+                       if (  oc_check_op_attr( desc ) ) {
+                               if( !opattrs && !charray_inlist( attrs, desc ) )
                                {
                                        continue;
                                }
                        } else {
-                               if (!userattrs && !charray_inlist( attrs, a->a_type ) )
+                               if (!userattrs && !charray_inlist( attrs, desc ) )
                                {
                                        continue;
                                }
                        }
                }
 
-               if ( ! access_allowed( be, conn, op, e,
-                       a->a_type, NULL, ACL_READ ) )
-               {
+               if ( ! access_allowed( be, conn, op, e, desc, NULL, ACL_READ ) ) {
                        Debug( LDAP_DEBUG_ACL, "acl: access to attribute %s not allowed\n",
-                           a->a_type, 0, 0 );
+                           desc, 0, 0 );
                        continue;
                }
 
-               if (( rc = ber_printf( ber, "{s[" /*]}*/ , a->a_type )) == -1 ) {
+               if (( rc = ber_printf( ber, "{s[" /*]}*/ , desc )) == -1 ) {
                        Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
                        ber_free( ber, 1 );
                        send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
@@ -773,11 +781,11 @@ send_search_entry(
                if ( ! attrsonly ) {
                        for ( i = 0; a->a_vals[i] != NULL; i++ ) {
                                if ( ! access_allowed( be, conn, op, e,
-                                       a->a_type, a->a_vals[i], ACL_READ ) )
+                                       desc, a->a_vals[i], ACL_READ ) )
                                {
                                        Debug( LDAP_DEBUG_ACL,
                                                "acl: access to attribute %s, value %d not allowed\n",
-                                       a->a_type, i, 0 );
+                                       desc, i, 0 );
                                        continue;
                                }
 
@@ -800,8 +808,9 @@ send_search_entry(
                            NULL, "encode end error", NULL, NULL );
                        goto error_return;
                }
-       } while (0);
-#endif
+       }
+
+       attrs_free( aa );
 
        rc = ber_printf( ber, /*{{{*/ "}}}" );
 
index ab847d391f68691a876e3e7153767e02437738eb..3318ee1aa9a829a322eca67a1180d003e5e0c9aa 100644 (file)
@@ -1,4 +1,4 @@
-/* schema.c - routines to enforce schema definitions */
+/* schema.c - routines to manage schema definitions */
 /* $OpenLDAP$ */
 /*
  * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
 #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.
- */
-
-int
-oc_schema_check( Entry *e )
-{
-       Attribute       *a, *aoc;
-       ObjectClass *oc;
-       int             i;
-       int             ret = 0;
-
-
-       /* find the object class attribute - could error out here */
-       if ( (aoc = attr_find( e->e_attrs, "objectclass" )) == NULL ) {
-               Debug( LDAP_DEBUG_ANY, "No object class for entry (%s)\n",
-                   e->e_dn, 0, 0 );
-               return( 1 );
-       }
-
-       /* check that the entry has required attrs for each oc */
-       for ( i = 0; aoc->a_vals[i] != NULL; i++ ) {
-               if ( (oc = oc_find( aoc->a_vals[i]->bv_val )) == NULL ) {
-                       Debug( LDAP_DEBUG_ANY,
-                               "Objectclass \"%s\" not defined\n",
-                               aoc->a_vals[i]->bv_val, 0, 0 );
-               }
-               else
-               {
-                       char *s = oc_check_required( e, aoc->a_vals[i]->bv_val );
-
-                       if (s != NULL) {
-                               Debug( LDAP_DEBUG_ANY,
-                                       "Entry (%s), oc \"%s\" requires attr \"%s\"\n",
-                                       e->e_dn, aoc->a_vals[i]->bv_val, s );
-                               ret = 1;
-                       }
-               }
-       }
-
-       if ( ret != 0 ) {
-           return( ret );
-       }
-
-       /* check that each attr in the entry is allowed by some oc */
-       for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
-               if ( oc_check_allowed( a->a_type, aoc->a_vals ) != 0 ) {
-                       Debug( LDAP_DEBUG_ANY,
-                           "Entry (%s), attr \"%s\" not allowed\n",
-                           e->e_dn, a->a_type, 0 );
-                       ret = 1;
-               }
-       }
-
-       return( ret );
-}
-
-static char *
-oc_check_required( Entry *e, char *ocname )
-{
-       ObjectClass     *oc;
-       AttributeType   *at;
-       int             i;
-       Attribute       *a;
-       char            **pp;
-
-       Debug( LDAP_DEBUG_TRACE,
-              "oc_check_required entry (%s), objectclass \"%s\"\n",
-              e->e_dn, ocname, 0 );
-
-       /* find global oc defn. it we don't know about it assume it's ok */
-       if ( (oc = oc_find( ocname )) == NULL ) {
-               return( 0 );
-       }
-
-       /* check for empty oc_required */
-       if(oc->soc_required == NULL) {
-               return( 0 );
-       }
-
-       /* for each required attribute */
-       for ( i = 0; oc->soc_required[i] != NULL; i++ ) {
-               at = oc->soc_required[i];
-               /* see if it's in the entry */
-               for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
-                       if ( at->sat_oid &&
-                            strcmp( a->a_type, at->sat_oid ) == 0 ) {
-                               break;
-                       }
-                       pp = at->sat_names;
-                       if ( pp  == NULL ) {
-                               /* Empty name list => not found */
-                               a = NULL;
-                               break;
-                       }
-                       while ( *pp ) {
-                               if ( strcasecmp( a->a_type, *pp ) == 0 ) {
-                                       break;
-                               }
-                               pp++;
-                       }
-                       if ( *pp ) {
-                               break;
-                       }
-               }
-               /* not there => schema violation */
-               if ( a == NULL ) {
-                       if ( at->sat_names && at->sat_names[0] ) {
-                               return at->sat_names[0];
-                       } else {
-                               return at->sat_oid;
-                       }
-               }
-       }
-
-       return( NULL );
-}
-
-static int
-oc_check_allowed( char *type, struct berval **ocl )
-{
-       ObjectClass     *oc;
-       AttributeType   *at;
-       int             i, j;
-       char            **pp;
-       char            *p, *t;
-
-       Debug( LDAP_DEBUG_TRACE,
-              "oc_check_allowed type \"%s\"\n", type, 0, 0 );
-
-       /* always allow objectclass attribute */
-       if ( strcasecmp( type, "objectclass" ) == 0 ) {
-               return( 0 );
-       }
-
-#ifndef SLAPD_SCHEMA_NOT_COMPAT
-       /* Treat any attribute type with option as an unknown attribute type */
-       /*
-        * The "type" we have received is actually an AttributeDescription.
-        * Let's find out the corresponding type.
-        */
-       p = strchr( type, ';' );
-       if ( p ) {
-               t = ch_malloc( p-type+1 );
-               strncpy( t, type, p-type );
-               t[p-type] = '\0';
-               Debug( LDAP_DEBUG_TRACE,
-                      "oc_check_allowed type \"%s\" from \"%s\"\n",
-                      t, type, 0 );
-
-       } else
-#endif
-       {
-               t = type;
-       }
-
-
-       /*
-        * All operational attributions are allowed by schema rules.
-        */
-       if ( oc_check_op_attr( t ) ) {
-               return( 0 );
-       }
-
-       /* check that the type appears as req or opt in at least one oc */
-       for ( i = 0; ocl[i] != NULL; i++ ) {
-               /* if we know about the oc */
-               if ( (oc = oc_find( ocl[i]->bv_val )) != NULL ) {
-                       /* does it require the type? */
-                       for ( j = 0; oc->soc_required != NULL && 
-                               oc->soc_required[j] != NULL; j++ ) {
-                               at = oc->soc_required[j];
-                               if ( at->sat_oid &&
-                                    strcmp(at->sat_oid, t ) == 0 ) {
-                                       if ( t != type )
-                                               ldap_memfree( t );
-                                       return( 0 );
-                               }
-                               pp = at->sat_names;
-                               if ( pp == NULL )
-                                       continue;
-                               while ( *pp ) {
-                                       if ( strcasecmp( *pp, t ) == 0 ) {
-                                               if ( t != type )
-                                                       ldap_memfree( t );
-                                               return( 0 );
-                                       }
-                                       pp++;
-                               }
-                       }
-                       /* does it allow the type? */
-                       for ( j = 0; oc->soc_allowed != NULL && 
-                               oc->soc_allowed[j] != NULL; j++ ) {
-                               at = oc->soc_allowed[j];
-                               if ( at->sat_oid &&
-                                    strcmp( at->sat_oid, t ) == 0 ) {
-                                       if ( t != type )
-                                               ldap_memfree( t );
-                                       return( 0 );
-                               }
-                               pp = at->sat_names;
-                               if ( pp == NULL )
-                                       continue;
-                               while ( *pp ) {
-                                       if ( strcasecmp( *pp, t ) == 0 ||
-                                            strcmp( *pp, "*" ) == 0 ) {
-                                               if ( t != type )
-                                                       ldap_memfree( t );
-                                               return( 0 );
-                                       }
-                                       pp++;
-                               }
-                       }
-                       /* maybe the next oc allows it */
-
-#ifdef OC_UNDEFINED_IMPLES_EXTENSIBLE
-               /* we don't know about the oc. assume it allows it */
-               } else {
-                       if ( t != type )
-                               ldap_memfree( t );
-                       return( 0 );
-#endif
-               }
-       }
-
-       if ( t != type )
-               ldap_memfree( t );
-       /* not allowed by any oc */
-       return( 1 );
-}
-
-
-#ifndef SLAPD_SCHEMA_NOT_COMPAT
-       /* these shouldn't be hardcoded */
-
-static char *oc_op_usermod_attrs[] = {
-       /*
-        * these are operational attributes which are
-        * not defined as NO-USER_MODIFICATION and
-        * which slapd supports modification of.
-        *
-        * Currently none.
-        * Likely candidate, "aci"
-        */
-       NULL
-};
-
-static char *oc_op_attrs[] = {
-       /*
-        * these are operational attributes 
-        * most could be user modifiable
-        */
-       "objectClasses",
-       "attributeTypes",
-       "matchingRules",
-       "matchingRuleUse",
-       "dITStructureRules",
-       "dITContentRules",
-       "nameForms",
-       "ldapSyntaxes",
-       "namingContexts",
-       "supportedExtension",
-       "supportedControl",
-       "supportedSASLMechanisms",
-       "supportedLDAPversion",
-       "supportedACIMechanisms",
-       "subschemaSubentry",            /* NO USER MOD */
-       NULL
-
-};
-
-/* this list should be extensible  */
-static char *oc_op_no_usermod_attrs[] = {
-       /*
-        * Operational and 'no user modification' attributes
-        * which are STORED in the directory server.
-        */
-
-       /* RFC2252, 3.2.1 */
-       "creatorsName",
-       "createTimestamp",
-       "modifiersName",
-       "modifyTimestamp",
-
-       NULL
-};
-#endif
-
-
-/*
- * check to see if attribute is 'operational' or not.
- */
-int
-oc_check_op_attr( const char *type )
-{
-#ifndef SLAPD_SCHEMA_NOT_COMPAT
-       return charray_inlist( oc_op_attrs, type )
-               || charray_inlist( oc_op_usermod_attrs, type )
-               || charray_inlist( oc_op_no_usermod_attrs, type );
-#else
-       AttributeType *at = at_find( type );
-
-       if( at == NULL ) return 0;
-
-       return at->sat_usage != LDAP_SCHEMA_USER_APPLICATIONS;
-#endif
-}
-
-/*
- * check to see if attribute can be user modified or not.
- */
-int
-oc_check_op_usermod_attr( const char *type )
-{
-#ifndef SLAPD_SCHEMA_NOT_COMPAT
-       return charray_inlist( oc_op_usermod_attrs, type );
-#else
-       /* not (yet) in schema */
-       return 0;
-#endif
-}
-
-/*
- * check to see if attribute is 'no user modification' or not.
- */
-int
-oc_check_op_no_usermod_attr( const char *type )
-{
-#ifndef SLAPD_SCHEMA_NOT_COMPAT
-       return charray_inlist( oc_op_no_usermod_attrs, type );
-#else
-       AttributeType *at = at_find( type );
-
-       if( at == NULL ) return 0;
-
-       return at->sat_no_user_mod;
-#endif
-}
-
-
-struct oindexrec {
-       char            *oir_name;
-       ObjectClass     *oir_oc;
-};
-
-static Avlnode *oc_index = NULL;
-static ObjectClass *oc_list = NULL;
-
-static int
-oc_index_cmp(
-    struct oindexrec   *oir1,
-    struct oindexrec   *oir2
-)
-{
-       return (strcasecmp( oir1->oir_name, oir2->oir_name ));
-}
-
-static int
-oc_index_name_cmp(
-    char               *name,
-    struct oindexrec   *oir
-)
-{
-       return (strcasecmp( name, oir->oir_name ));
-}
-
-ObjectClass *
-oc_find( const char *ocname )
-{
-       struct oindexrec        *oir = NULL;
-
-       if ( (oir = (struct oindexrec *) avl_find( oc_index, ocname,
-            (AVL_CMP) oc_index_name_cmp )) != NULL ) {
-               return( oir->oir_oc );
-       }
-       return( NULL );
-}
-
-static int
-oc_create_required(
-    ObjectClass                *soc,
-    char               **attrs,
-    const char         **err
-)
-{
-       char            **attrs1;
-       AttributeType   *sat;
-       AttributeType   **satp;
-       int             i;
-
-       if ( attrs ) {
-               attrs1 = attrs;
-               while ( *attrs1 ) {
-                       sat = at_find(*attrs1);
-                       if ( !sat ) {
-                               *err = *attrs1;
-                               return SLAP_SCHERR_ATTR_NOT_FOUND;
-                       }
-                       if ( at_find_in_list(sat, soc->soc_required) < 0) {
-                               if ( at_append_to_list(sat, &soc->soc_required) ) {
-                                       *err = *attrs1;
-                                       return SLAP_SCHERR_OUTOFMEM;
-                               }
-                       }
-                       attrs1++;
-               }
-               /* Now delete duplicates from the allowed list */
-               for ( satp = soc->soc_required; *satp; satp++ ) {
-                       i = at_find_in_list(*satp,soc->soc_allowed);
-                       if ( i >= 0 ) {
-                               at_delete_from_list(i, &soc->soc_allowed);
-                       }
-               }
-       }
-       return 0;
-}
-
-static int
-oc_create_allowed(
-    ObjectClass                *soc,
-    char               **attrs,
-    const char         **err
-)
-{
-       char            **attrs1;
-       AttributeType   *sat;
-
-       if ( attrs ) {
-               attrs1 = attrs;
-               while ( *attrs1 ) {
-                       sat = at_find(*attrs1);
-                       if ( !sat ) {
-                               *err = *attrs1;
-                               return SLAP_SCHERR_ATTR_NOT_FOUND;
-                       }
-                       if ( at_find_in_list(sat, soc->soc_required) < 0 &&
-                            at_find_in_list(sat, soc->soc_allowed) < 0 ) {
-                               if ( at_append_to_list(sat, &soc->soc_allowed) ) {
-                                       *err = *attrs1;
-                                       return SLAP_SCHERR_OUTOFMEM;
-                               }
-                       }
-                       attrs1++;
-               }
-       }
-       return 0;
-}
-
-static int
-oc_add_sups(
-    ObjectClass                *soc,
-    char               **sups,
-    const char         **err
-)
-{
-       int             code;
-       ObjectClass     *soc1;
-       int             nsups;
-       char            **sups1;
-       int             add_sups = 0;
-
-       if ( sups ) {
-               if ( !soc->soc_sups ) {
-                       /* We are at the first recursive level */
-                       add_sups = 1;
-                       nsups = 0;
-                       sups1 = sups;
-                       while ( *sups1 ) {
-                               nsups++;
-                               sups1++;
-                       }
-                       nsups++;
-                       soc->soc_sups = (ObjectClass **)ch_calloc(1,
-                                         nsups*sizeof(ObjectClass *));
-               }
-               nsups = 0;
-               sups1 = sups;
-               while ( *sups1 ) {
-                       soc1 = oc_find(*sups1);
-                       if ( !soc1 ) {
-                               *err = *sups1;
-                               return SLAP_SCHERR_CLASS_NOT_FOUND;
-                       }
-
-                       if ( add_sups )
-                               soc->soc_sups[nsups] = soc1;
-
-                       code = oc_add_sups(soc,soc1->soc_sup_oids, err);
-                       if ( code )
-                               return code;
-
-                       code = oc_create_required(soc,soc1->soc_at_oids_must,err);
-                       if ( code )
-                               return code;
-                       code = oc_create_allowed(soc,soc1->soc_at_oids_may,err);
-                       if ( code )
-                               return code;
-
-                       nsups++;
-                       sups1++;
-               }
-       }
-       return 0;
-}
-
-static int
-oc_insert(
-    ObjectClass                *soc,
-    const char         **err
-)
-{
-       ObjectClass     **ocp;
-       struct oindexrec        *oir;
-       char                    **names;
-
-       ocp = &oc_list;
-       while ( *ocp != NULL ) {
-               ocp = &(*ocp)->soc_next;
-       }
-       *ocp = soc;
-
-       if ( soc->soc_oid ) {
-               oir = (struct oindexrec *)
-                       ch_calloc( 1, sizeof(struct oindexrec) );
-               oir->oir_name = soc->soc_oid;
-               oir->oir_oc = soc;
-               if ( avl_insert( &oc_index, (caddr_t) oir,
-                                (AVL_CMP) oc_index_cmp,
-                                (AVL_DUP) avl_dup_error ) ) {
-                       *err = soc->soc_oid;
-                       ldap_memfree(oir);
-                       return SLAP_SCHERR_DUP_CLASS;
-               }
-               /* FIX: temporal consistency check */
-               oc_find(oir->oir_name);
-       }
-       if ( (names = soc->soc_names) ) {
-               while ( *names ) {
-                       oir = (struct oindexrec *)
-                               ch_calloc( 1, sizeof(struct oindexrec) );
-                       oir->oir_name = ch_strdup(*names);
-                       oir->oir_oc = soc;
-                       if ( avl_insert( &oc_index, (caddr_t) oir,
-                                        (AVL_CMP) oc_index_cmp,
-                                        (AVL_DUP) avl_dup_error ) ) {
-                               *err = *names;
-                               ldap_memfree(oir);
-                               return SLAP_SCHERR_DUP_CLASS;
-                       }
-                       /* FIX: temporal consistency check */
-                       oc_find(oir->oir_name);
-                       names++;
-               }
-       }
-       return 0;
-}
-
-int
-oc_add(
-    LDAP_OBJECT_CLASS  *oc,
-    const char         **err
-)
-{
-       ObjectClass     *soc;
-       int             code;
-
-       soc = (ObjectClass *) ch_calloc( 1, sizeof(ObjectClass) );
-       memcpy( &soc->soc_oclass, oc, sizeof(LDAP_OBJECT_CLASS));
-       if ( (code = oc_add_sups(soc,soc->soc_sup_oids,err)) != 0 )
-               return code;
-       if ( (code = oc_create_required(soc,soc->soc_at_oids_must,err)) != 0 )
-               return code;
-       if ( (code = oc_create_allowed(soc,soc->soc_at_oids_may,err)) != 0 )
-               return code;
-       code = oc_insert(soc,err);
-       return code;
-}
-
-struct sindexrec {
-       char            *sir_name;
-       Syntax          *sir_syn;
-};
-
-static Avlnode *syn_index = NULL;
-static Syntax *syn_list = NULL;
-
-static int
-syn_index_cmp(
-    struct sindexrec   *sir1,
-    struct sindexrec   *sir2
-)
-{
-       return (strcmp( sir1->sir_name, sir2->sir_name ));
-}
-
-static int
-syn_index_name_cmp(
-    char               *name,
-    struct sindexrec   *sir
-)
-{
-       return (strcmp( name, sir->sir_name ));
-}
-
-Syntax *
-syn_find( const char *synname )
-{
-       struct sindexrec        *sir = NULL;
-
-       if ( (sir = (struct sindexrec *) avl_find( syn_index, synname,
-            (AVL_CMP) syn_index_name_cmp )) != NULL ) {
-               return( sir->sir_syn );
-       }
-       return( NULL );
-}
-
-Syntax *
-syn_find_desc( const char *syndesc, int *len )
-{
-       Syntax          *synp;
-
-       for (synp = syn_list; synp; synp = synp->ssyn_next)
-               if ((*len = dscompare( synp->ssyn_syn.syn_desc, syndesc, '{')))
-                       return synp;
-       return( NULL );
-}
-
-static int
-syn_insert(
-    Syntax             *ssyn,
-    const char         **err
-)
-{
-       Syntax          **synp;
-       struct sindexrec        *sir;
-
-       synp = &syn_list;
-       while ( *synp != NULL ) {
-               synp = &(*synp)->ssyn_next;
-       }
-       *synp = ssyn;
-
-       if ( ssyn->ssyn_oid ) {
-               sir = (struct sindexrec *)
-                       ch_calloc( 1, sizeof(struct sindexrec) );
-               sir->sir_name = ssyn->ssyn_oid;
-               sir->sir_syn = ssyn;
-               if ( avl_insert( &syn_index, (caddr_t) sir,
-                                (AVL_CMP) syn_index_cmp,
-                                (AVL_DUP) avl_dup_error ) ) {
-                       *err = ssyn->ssyn_oid;
-                       ldap_memfree(sir);
-                       return SLAP_SCHERR_DUP_SYNTAX;
-               }
-               /* FIX: temporal consistency check */
-               syn_find(sir->sir_name);
-       }
-       return 0;
-}
-
-int
-syn_add(
-    LDAP_SYNTAX                *syn,
-       int flags,
-    slap_syntax_validate_func  *validate,
-    slap_syntax_transform_func *ber2str,
-    slap_syntax_transform_func *str2ber,
-    const char         **err
-)
-{
-       Syntax          *ssyn;
-       int             code;
-
-       ssyn = (Syntax *) ch_calloc( 1, sizeof(Syntax) );
-       memcpy( &ssyn->ssyn_syn, syn, sizeof(LDAP_SYNTAX));
-
-       ssyn->ssyn_flags = flags;
-       ssyn->ssyn_validate = validate;
-       ssyn->ssyn_ber2str = ber2str;
-       ssyn->ssyn_str2ber = str2ber;
-
-       code = syn_insert(ssyn,err);
-       return code;
-}
-
-struct mindexrec {
-       char            *mir_name;
-       MatchingRule    *mir_mr;
-};
-
-static Avlnode *mr_index = NULL;
-static MatchingRule *mr_list = NULL;
-
-static int
-mr_index_cmp(
-    struct mindexrec   *mir1,
-    struct mindexrec   *mir2
-)
-{
-       return (strcmp( mir1->mir_name, mir2->mir_name ));
-}
-
-static int
-mr_index_name_cmp(
-    char               *name,
-    struct mindexrec   *mir
-)
-{
-       return (strcmp( name, mir->mir_name ));
-}
-
-MatchingRule *
-mr_find( const char *mrname )
-{
-       struct mindexrec        *mir = NULL;
-
-       if ( (mir = (struct mindexrec *) avl_find( mr_index, mrname,
-            (AVL_CMP) mr_index_name_cmp )) != NULL ) {
-               return( mir->mir_mr );
-       }
-       return( NULL );
-}
-
-static int
-mr_insert(
-    MatchingRule       *smr,
-    const char         **err
-)
-{
-       MatchingRule            **mrp;
-       struct mindexrec        *mir;
-       char                    **names;
-
-       mrp = &mr_list;
-       while ( *mrp != NULL ) {
-               mrp = &(*mrp)->smr_next;
-       }
-       *mrp = smr;
-
-       if ( smr->smr_oid ) {
-               mir = (struct mindexrec *)
-                       ch_calloc( 1, sizeof(struct mindexrec) );
-               mir->mir_name = smr->smr_oid;
-               mir->mir_mr = smr;
-               if ( avl_insert( &mr_index, (caddr_t) mir,
-                                (AVL_CMP) mr_index_cmp,
-                                (AVL_DUP) avl_dup_error ) ) {
-                       *err = smr->smr_oid;
-                       ldap_memfree(mir);
-                       return SLAP_SCHERR_DUP_RULE;
-               }
-               /* FIX: temporal consistency check */
-               mr_find(mir->mir_name);
-       }
-       if ( (names = smr->smr_names) ) {
-               while ( *names ) {
-                       mir = (struct mindexrec *)
-                               ch_calloc( 1, sizeof(struct mindexrec) );
-                       mir->mir_name = ch_strdup(*names);
-                       mir->mir_mr = smr;
-                       if ( avl_insert( &mr_index, (caddr_t) mir,
-                                        (AVL_CMP) mr_index_cmp,
-                                        (AVL_DUP) avl_dup_error ) ) {
-                               *err = *names;
-                               ldap_memfree(mir);
-                               return SLAP_SCHERR_DUP_RULE;
-                       }
-                       /* FIX: temporal consistency check */
-                       mr_find(mir->mir_name);
-                       names++;
-               }
-       }
-       return 0;
-}
-
-int
-mr_add(
-    LDAP_MATCHING_RULE         *mr,
-       slap_mr_convert_func *convert,
-       slap_mr_normalize_func *normalize,
-    slap_mr_match_func *match,
-       slap_mr_indexer_func *indexer,
-    slap_mr_filter_func        *filter,
-    const char         **err
-)
-{
-       MatchingRule    *smr;
-       Syntax          *syn;
-       int             code;
-
-       smr = (MatchingRule *) ch_calloc( 1, sizeof(MatchingRule) );
-       memcpy( &smr->smr_mrule, mr, sizeof(LDAP_MATCHING_RULE));
-
-       smr->smr_convert = convert;
-       smr->smr_normalize = normalize;
-       smr->smr_match = match;
-       smr->smr_indexer = indexer;
-       smr->smr_filter = filter;
-
-       if ( smr->smr_syntax_oid ) {
-               if ( (syn = syn_find(smr->smr_syntax_oid)) ) {
-                       smr->smr_syntax = syn;
-               } else {
-                       *err = smr->smr_syntax_oid;
-                       return SLAP_SCHERR_SYN_NOT_FOUND;
-               }
-       } else {
-               *err = "";
-               return SLAP_SCHERR_MR_INCOMPLETE;
-       }
-       code = mr_insert(smr,err);
-       return code;
-}
-
-int
-register_syntax(
-       char * desc, int flags,
-       slap_syntax_validate_func *validate,
-       slap_syntax_transform_func *ber2str,
-       slap_syntax_transform_func *str2ber )
-{
-       LDAP_SYNTAX     *syn;
-       int             code;
-       const char      *err;
-
-       syn = ldap_str2syntax( desc, &code, &err);
-       if ( !syn ) {
-               Debug( LDAP_DEBUG_ANY, "Error in register_syntax: %s before %s in %s\n",
-                   ldap_scherr2str(code), err, desc );
-               return( -1 );
-       }
-
-       code = syn_add( syn, flags, validate, ber2str, str2ber, &err );
-       if ( code ) {
-               Debug( LDAP_DEBUG_ANY, "Error in register_syntax: %s %s in %s\n",
-                   scherr2str(code), err, desc );
-               return( -1 );
-       }
-
-       return( 0 );
-}
-
-int
-register_matching_rule(
-       char * desc,
-       slap_mr_convert_func *convert,
-       slap_mr_normalize_func *normalize,
-       slap_mr_match_func *match,
-       slap_mr_indexer_func *indexer,
-       slap_mr_filter_func *filter )
-{
-       LDAP_MATCHING_RULE *mr;
-       int             code;
-       const char      *err;
-
-       mr = ldap_str2matchingrule( desc, &code, &err);
-       if ( !mr ) {
-               Debug( LDAP_DEBUG_ANY, "Error in register_matching_rule: %s before %s in %s\n",
-                   ldap_scherr2str(code), err, desc );
-               return( -1 );
-       }
-
-       code = mr_add( mr, convert, normalize, match, indexer, filter, &err );
-       if ( code ) {
-               Debug( LDAP_DEBUG_ANY, "Error in register_syntax: %s for %s in %s\n",
-                   scherr2str(code), err, desc );
-               return( -1 );
-       }
-       return( 0 );
-}
-
 
 #if defined( SLAPD_SCHEMA_DN )
 
-static int
-syn_schema_info( Entry *e )
-{
-       struct berval   val;
-       struct berval   *vals[2];
-       Syntax          *syn;
-
-       vals[0] = &val;
-       vals[1] = NULL;
-
-       for ( syn = syn_list; syn; syn = syn->ssyn_next ) {
-               val.bv_val = ldap_syntax2str( &syn->ssyn_syn );
-               if ( val.bv_val ) {
-                       val.bv_len = strlen( val.bv_val );
-                       Debug( LDAP_DEBUG_TRACE, "Merging syn [%ld] %s\n",
-                              (long) val.bv_len, val.bv_val, 0 );
-                       attr_merge( e, "ldapSyntaxes", vals );
-                       ldap_memfree( val.bv_val );
-               } else {
-                       return -1;
-               }
-       }
-       return 0;
-}
-
-static int
-mr_schema_info( Entry *e )
-{
-       struct berval   val;
-       struct berval   *vals[2];
-       MatchingRule    *mr;
-
-       vals[0] = &val;
-       vals[1] = NULL;
-
-       for ( mr = mr_list; mr; mr = mr->smr_next ) {
-               val.bv_val = ldap_matchingrule2str( &mr->smr_mrule );
-               if ( val.bv_val ) {
-                       val.bv_len = strlen( val.bv_val );
-                       Debug( LDAP_DEBUG_TRACE, "Merging mr [%ld] %s\n",
-                              (long) val.bv_len, val.bv_val, 0 );
-                       attr_merge( e, "matchingRules", vals );
-                       ldap_memfree( val.bv_val );
-               } else {
-                       return -1;
-               }
-       }
-       return 0;
-}
-
-static int
-oc_schema_info( Entry *e )
-{
-       struct berval   val;
-       struct berval   *vals[2];
-       ObjectClass     *oc;
-
-       vals[0] = &val;
-       vals[1] = NULL;
-
-       for ( oc = oc_list; oc; oc = oc->soc_next ) {
-               val.bv_val = ldap_objectclass2str( &oc->soc_oclass );
-               if ( val.bv_val ) {
-                       val.bv_len = strlen( val.bv_val );
-                       Debug( LDAP_DEBUG_TRACE, "Merging oc [%ld] %s\n",
-                              (long) val.bv_len, val.bv_val, 0 );
-                       attr_merge( e, "objectClasses", vals );
-                       ldap_memfree( val.bv_val );
-               } else {
-                       return -1;
-               }
-       }
-       return 0;
-}
-
 void
 schema_info( Connection *conn, Operation *op, char **attrs, int attrsonly )
 {
@@ -1001,24 +51,15 @@ schema_info( Connection *conn, Operation *op, char **attrs, int attrsonly )
                free( rdn );
        }
 
-       if ( syn_schema_info( e ) ) {
-               /* Out of memory, do something about it */
-               entry_free( e );
-               return;
-       }
-       if ( mr_schema_info( e ) ) {
-               /* Out of memory, do something about it */
-               entry_free( e );
-               return;
-       }
-       if ( at_schema_info( e ) ) {
-               /* Out of memory, do something about it */
-               entry_free( e );
-               return;
-       }
-       if ( oc_schema_info( e ) ) {
+       if ( syn_schema_info( e ) 
+               || mr_schema_info( e )
+               || at_schema_info( e )
+               || oc_schema_info( e ) )
+       {
                /* Out of memory, do something about it */
                entry_free( e );
+               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
+                       NULL, NULL, NULL, NULL );
                return;
        }
        
@@ -1047,64 +88,3 @@ schema_info( Connection *conn, Operation *op, char **attrs, int attrsonly )
 }
 #endif
 
-#ifdef LDAP_DEBUG
-
-static void
-oc_print( ObjectClass *oc )
-{
-       int     i;
-       const char *mid;
-
-       printf( "objectclass %s\n", ldap_objectclass2name( &oc->soc_oclass ) );
-       if ( oc->soc_required != NULL ) {
-               mid = "\trequires ";
-               for ( i = 0; oc->soc_required[i] != NULL; i++, mid = "," )
-                       printf( "%s%s", mid,
-                               ldap_attributetype2name( &oc->soc_required[i]->sat_atype ) );
-               printf( "\n" );
-       }
-       if ( oc->soc_allowed != NULL ) {
-               mid = "\tallows ";
-               for ( i = 0; oc->soc_allowed[i] != NULL; i++, mid = "," )
-                       printf( "%s%s", mid,
-                               ldap_attributetype2name( &oc->soc_allowed[i]->sat_atype ) );
-               printf( "\n" );
-       }
-}
-
-#endif
-
-int is_entry_objectclass(
-       Entry*  e,
-       const char*     oc)
-{
-       Attribute *attr;
-       struct berval bv;
-
-       if( e == NULL || oc == NULL || *oc == '\0' )
-               return 0;
-
-       /*
-        * find objectClass attribute
-        */
-       attr = attr_find(e->e_attrs, "objectclass");
-
-       if( attr == NULL ) {
-               /* no objectClass attribute */
-               return 0;
-       }
-
-       bv.bv_val = (char *) oc;
-       bv.bv_len = strlen( bv.bv_val );
-
-#ifdef SLAPD_SCHEMA_NOT_COMPAT
-       /* not yet implemented */
-#else
-       if( value_find(attr->a_vals, &bv, attr->a_syntax, 1) != 0) {
-               /* entry is not of this objectclass */
-               return 0;
-       }
-#endif
-
-       return 1;
-}
diff --git a/servers/slapd/schema_check.c b/servers/slapd/schema_check.c
new file mode 100644 (file)
index 0000000..25bbd54
--- /dev/null
@@ -0,0 +1,271 @@
+/* schema_check.c - routines to enforce schema definitions */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/ctype.h>
+#include <ac/string.h>
+#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);
+
+/*
+ * entry_schema_check - check that entry e conforms to the schema required
+ * by its object class(es).
+ *
+ * returns 0 if so, non-zero otherwise.
+ */
+
+int
+schema_check_entry( Entry *e )
+{
+       Attribute       *a, *aoc;
+       ObjectClass *oc;
+       int             i;
+       int             ret = 0;
+
+       if( !global_schemacheck ) return 0;
+
+       /* find the object class attribute - could error out here */
+       if ( (aoc = attr_find( e->e_attrs, "objectclass" )) == NULL ) {
+               Debug( LDAP_DEBUG_ANY, "No object class for entry (%s)\n",
+                   e->e_dn, 0, 0 );
+               return( 1 );
+       }
+
+       /* check that the entry has required attrs for each oc */
+       for ( i = 0; aoc->a_vals[i] != NULL; i++ ) {
+               if ( (oc = oc_find( aoc->a_vals[i]->bv_val )) == NULL ) {
+                       Debug( LDAP_DEBUG_ANY,
+                               "Objectclass \"%s\" not defined\n",
+                               aoc->a_vals[i]->bv_val, 0, 0 );
+               }
+               else
+               {
+                       char *s = oc_check_required( e, aoc->a_vals[i]->bv_val );
+
+                       if (s != NULL) {
+                               Debug( LDAP_DEBUG_ANY,
+                                       "Entry (%s), oc \"%s\" requires attr \"%s\"\n",
+                                       e->e_dn, aoc->a_vals[i]->bv_val, s );
+                               ret = 1;
+                       }
+               }
+       }
+
+       if ( ret != 0 ) {
+           return( ret );
+       }
+
+       /* check that each attr in the entry is allowed by some oc */
+       for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+               if ( oc_check_allowed( a->a_desc.ad_type, aoc->a_vals ) != 0 ) {
+                       Debug( LDAP_DEBUG_ANY,
+                           "Entry (%s), attr \"%s\" not allowed\n",
+                           e->e_dn, a->a_desc.ad_cname->bv_val, 0 );
+                       ret = 1;
+               }
+#else
+               if ( oc_check_allowed( a->a_type, aoc->a_vals ) != 0 ) {
+                       Debug( LDAP_DEBUG_ANY,
+                           "Entry (%s), attr \"%s\" not allowed\n",
+                           e->e_dn, a->a_type, 0 );
+                       ret = 1;
+               }
+#endif
+       }
+
+       return( ret );
+}
+
+static char *
+oc_check_required( Entry *e, char *ocname )
+{
+       ObjectClass     *oc;
+       AttributeType   *at;
+       int             i;
+       Attribute       *a;
+
+       Debug( LDAP_DEBUG_TRACE,
+              "oc_check_required entry (%s), objectclass \"%s\"\n",
+              e->e_dn, ocname, 0 );
+
+       /* find global oc defn. it we don't know about it assume it's ok */
+       if ( (oc = oc_find( ocname )) == NULL ) {
+               return( 0 );
+       }
+
+       /* check for empty oc_required */
+       if(oc->soc_required == NULL) {
+               return( 0 );
+       }
+
+       /* for each required attribute */
+       for ( i = 0; oc->soc_required[i] != NULL; i++ ) {
+               at = oc->soc_required[i];
+               /* see if it's in the entry */
+               for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+                       if( a->a_desc.ad_type == at ) {
+                               break;
+                       }
+#else
+                       char            **pp;
+
+                       if ( at->sat_oid &&
+                            strcmp( a->a_type, at->sat_oid ) == 0 ) {
+                               break;
+                       }
+                       pp = at->sat_names;
+                       if ( pp  == NULL ) {
+                               /* Empty name list => not found */
+                               a = NULL;
+                               break;
+                       }
+                       while ( *pp ) {
+                               if ( strcasecmp( a->a_type, *pp ) == 0 ) {
+                                       break;
+                               }
+                               pp++;
+                       }
+                       if ( *pp ) {
+                               break;
+                       }
+#endif
+               }
+               /* not there => schema violation */
+               if ( a == NULL ) {
+                       if ( at->sat_names && at->sat_names[0] ) {
+                               return at->sat_names[0];
+                       } else {
+                               return at->sat_oid;
+                       }
+               }
+       }
+
+       return( NULL );
+}
+
+static int
+oc_check_allowed( char *type, struct berval **ocl )
+{
+       ObjectClass     *oc;
+       AttributeType   *at;
+       int             i, j;
+       char            **pp;
+       char            *p, *t;
+
+       Debug( LDAP_DEBUG_TRACE,
+              "oc_check_allowed type \"%s\"\n", type, 0, 0 );
+
+       /* always allow objectclass attribute */
+       if ( strcasecmp( type, "objectclass" ) == 0 ) {
+               return( 0 );
+       }
+
+#ifndef SLAPD_SCHEMA_NOT_COMPAT
+       /* Treat any attribute type with option as an unknown attribute type */
+       /*
+        * The "type" we have received is actually an AttributeDescription.
+        * Let's find out the corresponding type.
+        */
+       p = strchr( type, ';' );
+       if ( p ) {
+               t = ch_malloc( p-type+1 );
+               strncpy( t, type, p-type );
+               t[p-type] = '\0';
+               Debug( LDAP_DEBUG_TRACE,
+                      "oc_check_allowed type \"%s\" from \"%s\"\n",
+                      t, type, 0 );
+
+       } else
+#endif
+       {
+               t = type;
+       }
+
+
+       /*
+        * All operational attributions are allowed by schema rules.
+        */
+       if ( oc_check_op_attr( t ) ) {
+               return( 0 );
+       }
+
+       /* check that the type appears as req or opt in at least one oc */
+       for ( i = 0; ocl[i] != NULL; i++ ) {
+               /* if we know about the oc */
+               if ( (oc = oc_find( ocl[i]->bv_val )) != NULL ) {
+                       /* does it require the type? */
+                       for ( j = 0; oc->soc_required != NULL && 
+                               oc->soc_required[j] != NULL; j++ ) {
+                               at = oc->soc_required[j];
+                               if ( at->sat_oid &&
+                                    strcmp(at->sat_oid, t ) == 0 ) {
+                                       if ( t != type )
+                                               ldap_memfree( t );
+                                       return( 0 );
+                               }
+                               pp = at->sat_names;
+                               if ( pp == NULL )
+                                       continue;
+                               while ( *pp ) {
+                                       if ( strcasecmp( *pp, t ) == 0 ) {
+                                               if ( t != type )
+                                                       ldap_memfree( t );
+                                               return( 0 );
+                                       }
+                                       pp++;
+                               }
+                       }
+                       /* does it allow the type? */
+                       for ( j = 0; oc->soc_allowed != NULL && 
+                               oc->soc_allowed[j] != NULL; j++ ) {
+                               at = oc->soc_allowed[j];
+                               if ( at->sat_oid &&
+                                    strcmp( at->sat_oid, t ) == 0 ) {
+                                       if ( t != type )
+                                               ldap_memfree( t );
+                                       return( 0 );
+                               }
+                               pp = at->sat_names;
+                               if ( pp == NULL )
+                                       continue;
+                               while ( *pp ) {
+                                       if ( strcasecmp( *pp, t ) == 0 ||
+                                            strcmp( *pp, "*" ) == 0 ) {
+                                               if ( t != type )
+                                                       ldap_memfree( t );
+                                               return( 0 );
+                                       }
+                                       pp++;
+                               }
+                       }
+                       /* maybe the next oc allows it */
+
+#ifdef OC_UNDEFINED_IMPLES_EXTENSIBLE
+               /* we don't know about the oc. assume it allows it */
+               } else {
+                       if ( t != type )
+                               ldap_memfree( t );
+                       return( 0 );
+#endif
+               }
+       }
+
+       if ( t != type )
+               ldap_memfree( t );
+       /* not allowed by any oc */
+       return( 1 );
+}
index 35b864562fe7c5ef4b77d801b089ca65f5f7ca8e..8403bfc0f51d8cd99cdc01dcd3cc39d704bdfac8 100644 (file)
@@ -143,10 +143,10 @@ typedef int slap_syntax_transform_func LDAP_P((
 
 typedef struct slap_syntax {
        LDAP_SYNTAX                     ssyn_syn;
-       int     ssyn_flags;
+       unsigned        ssyn_flags;
 
-#define SLAP_SYNTAX_NONE       0
-#define SLAP_SYNTAX_BINARY     1
+#define SLAP_SYNTAX_NONE       0x0U
+#define SLAP_SYNTAX_BINARY     0x1U
 
        slap_syntax_validate_func       *ssyn_validate;
 
@@ -210,6 +210,9 @@ typedef struct slap_matching_rule {
 } MatchingRule;
 
 typedef struct slap_attribute_type {
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+       char                                    *sat_cname;
+#endif
        LDAP_ATTRIBUTE_TYPE             sat_atype;
        struct slap_attribute_type      *sat_sup;
        struct slap_attribute_type      **sat_subtypes;
@@ -235,6 +238,11 @@ typedef struct slap_attribute_type {
 #define sat_usage              sat_atype.at_usage
 } AttributeType;
 
+#define is_at_operational(at)  ((at)->sat_usage)
+#define is_at_single_value(at) ((at)->sat_single_value)
+#define is_at_collective(at)   ((at)->sat_collective)
+#define is_at_no_user_mod(at)  ((at)->sat_no_user_mod)
+
 typedef struct slap_object_class {
        LDAP_OBJECT_CLASS               soc_oclass;
        struct slap_object_class        **soc_sups;
@@ -279,6 +287,32 @@ typedef struct slap_mra {
        struct berval   *mra_value;
 } Mra;
 
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+/*
+ * represents a recognized attribute description ( type + options )
+ */
+typedef struct slap_attr_desc {
+       struct berval *ad_cname;        /* canonical name */
+       AttributeType *ad_type;         /* NULL if unknown */
+       char *ad_lang;                          /* NULL if no language tags */
+       unsigned ad_flags;
+#define SLAP_DESC_NONE         0x0U
+#define SLAP_DESC_BINARY       0x1U
+} AttributeDescription;
+
+typedef struct slap_attr_assertion {
+       AttributeDescription    aa_desc;
+       struct berval *aa_value;
+} AttributeAssertion;
+
+typedef struct slap_mr_assertion {
+       char                                    *ma_rule;       /* optional */
+       AttributeDescription    *ma_desc;       /* optional */
+       int                                             ma_dnattrs; /* boolean */
+       struct berval                   *ma_value;      /* required */
+} MatchingRuleAssertion;
+#endif
+
 /*
  * represents a search filter
  */
@@ -331,14 +365,16 @@ typedef struct slap_filter {
 } Filter;
 
 /*
- * represents an attribute (type + values + syntax)
+ * represents an attribute (description + values)
  */
 typedef struct slap_attr {
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+       AttributeDescription a_desc;
+#else
        char            *a_type;        /* description */
-       struct berval   **a_vals;
-#ifndef SLAPD_SCHEMA_NOT_COMPAT
        int             a_syntax;
 #endif
+       struct berval   **a_vals;
        struct slap_attr        *a_next;
 } Attribute;
 
diff --git a/servers/slapd/syntax.c b/servers/slapd/syntax.c
new file mode 100644 (file)
index 0000000..e26fe83
--- /dev/null
@@ -0,0 +1,182 @@
+/* syntax.c - routines to manage syntax definitions */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/ctype.h>
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "ldap_pvt.h"
+
+
+struct sindexrec {
+       char            *sir_name;
+       Syntax          *sir_syn;
+};
+
+static Avlnode *syn_index = NULL;
+static Syntax *syn_list = NULL;
+
+static int
+syn_index_cmp(
+    struct sindexrec   *sir1,
+    struct sindexrec   *sir2
+)
+{
+       return (strcmp( sir1->sir_name, sir2->sir_name ));
+}
+
+static int
+syn_index_name_cmp(
+    char               *name,
+    struct sindexrec   *sir
+)
+{
+       return (strcmp( name, sir->sir_name ));
+}
+
+Syntax *
+syn_find( const char *synname )
+{
+       struct sindexrec        *sir = NULL;
+
+       if ( (sir = (struct sindexrec *) avl_find( syn_index, synname,
+            (AVL_CMP) syn_index_name_cmp )) != NULL ) {
+               return( sir->sir_syn );
+       }
+       return( NULL );
+}
+
+Syntax *
+syn_find_desc( const char *syndesc, int *len )
+{
+       Syntax          *synp;
+
+       for (synp = syn_list; synp; synp = synp->ssyn_next)
+               if ((*len = dscompare( synp->ssyn_syn.syn_desc, syndesc, '{')))
+                       return synp;
+       return( NULL );
+}
+
+static int
+syn_insert(
+    Syntax             *ssyn,
+    const char         **err
+)
+{
+       Syntax          **synp;
+       struct sindexrec        *sir;
+
+       synp = &syn_list;
+       while ( *synp != NULL ) {
+               synp = &(*synp)->ssyn_next;
+       }
+       *synp = ssyn;
+
+       if ( ssyn->ssyn_oid ) {
+               sir = (struct sindexrec *)
+                       ch_calloc( 1, sizeof(struct sindexrec) );
+               sir->sir_name = ssyn->ssyn_oid;
+               sir->sir_syn = ssyn;
+               if ( avl_insert( &syn_index, (caddr_t) sir,
+                                (AVL_CMP) syn_index_cmp,
+                                (AVL_DUP) avl_dup_error ) ) {
+                       *err = ssyn->ssyn_oid;
+                       ldap_memfree(sir);
+                       return SLAP_SCHERR_DUP_SYNTAX;
+               }
+               /* FIX: temporal consistency check */
+               syn_find(sir->sir_name);
+       }
+       return 0;
+}
+
+int
+syn_add(
+    LDAP_SYNTAX                *syn,
+       int flags,
+    slap_syntax_validate_func  *validate,
+    slap_syntax_transform_func *ber2str,
+    slap_syntax_transform_func *str2ber,
+    const char         **err
+)
+{
+       Syntax          *ssyn;
+       int             code;
+
+       ssyn = (Syntax *) ch_calloc( 1, sizeof(Syntax) );
+       memcpy( &ssyn->ssyn_syn, syn, sizeof(LDAP_SYNTAX));
+
+       ssyn->ssyn_flags = flags;
+       ssyn->ssyn_validate = validate;
+       ssyn->ssyn_ber2str = ber2str;
+       ssyn->ssyn_str2ber = str2ber;
+
+       code = syn_insert(ssyn,err);
+       return code;
+}
+
+int
+register_syntax(
+       char * desc, int flags,
+       slap_syntax_validate_func *validate,
+       slap_syntax_transform_func *ber2str,
+       slap_syntax_transform_func *str2ber )
+{
+       LDAP_SYNTAX     *syn;
+       int             code;
+       const char      *err;
+
+       syn = ldap_str2syntax( desc, &code, &err);
+       if ( !syn ) {
+               Debug( LDAP_DEBUG_ANY, "Error in register_syntax: %s before %s in %s\n",
+                   ldap_scherr2str(code), err, desc );
+               return( -1 );
+       }
+
+       code = syn_add( syn, flags, validate, ber2str, str2ber, &err );
+       if ( code ) {
+               Debug( LDAP_DEBUG_ANY, "Error in register_syntax: %s %s in %s\n",
+                   scherr2str(code), err, desc );
+               return( -1 );
+       }
+
+       return( 0 );
+}
+
+#if defined( SLAPD_SCHEMA_DN )
+
+int
+syn_schema_info( Entry *e )
+{
+       struct berval   val;
+       struct berval   *vals[2];
+       Syntax          *syn;
+
+       vals[0] = &val;
+       vals[1] = NULL;
+
+       for ( syn = syn_list; syn; syn = syn->ssyn_next ) {
+               val.bv_val = ldap_syntax2str( &syn->ssyn_syn );
+               if ( val.bv_val ) {
+                       val.bv_len = strlen( val.bv_val );
+                       Debug( LDAP_DEBUG_TRACE, "Merging syn [%ld] %s\n",
+                              (long) val.bv_len, val.bv_val, 0 );
+                       attr_merge( e, "ldapSyntaxes", vals );
+                       ldap_memfree( val.bv_val );
+               } else {
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+#endif
index 17c9a94e17f7f64fdf1934f863b737af2f509d5b..f450db9f46920455679f7a503290c3032a1260ef 100644 (file)
@@ -51,7 +51,8 @@ BDB2SRCS =
 QUIPUSRCS      = edb2ldif.c ldapsyntax.c chlog2replog.c
 SLAPD_OBJS = ../config.o ../ch_malloc.o ../backend.o ../charray.o \
                ../module.o ../aclparse.o ../filterentry.o \
-               ../schema.o ../schema_init.o ../schemaparse.o \
+               ../schema.o ../schema_check.o ../schema_init.o ../schemaparse.o \
+               ../at.o ../mr.o ../oc.o ../syntax.o \
                ../acl.o ../phonetic.o ../attr.o ../value.o ../entry.o \
                ../dn.o ../filter.o ../str2filter.o ../ava.o ../init.o \
                ../controls.o ../kerberos.o ../passwd.o \
index 73a4b7656afcde0b02cfaa2138ff8e872a94f0a6..0acdbdf4530ed7f1c827b536e11f9439a057f0c4 100644 (file)
@@ -69,7 +69,7 @@ main( int argc, char **argv )
                        }
 
                        /* check schema */
-                       if ( global_schemacheck && oc_schema_check( e ) != 0 ) {
+                       if ( schema_check_entry( e ) != 0 ) {
                                fprintf( stderr, "%s: schema violation in entry dn=\"%s\" (line=%d)\n",
                                        progname, e->e_dn, lineno );
                                rc = EXIT_FAILURE;