]> git.sur5r.net Git - openldap/commitdiff
Basic framework for DIT Content Rules (not yet enforced)
authorKurt Zeilenga <kurt@openldap.org>
Wed, 9 Oct 2002 07:11:50 +0000 (07:11 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Wed, 9 Oct 2002 07:11:50 +0000 (07:11 +0000)
servers/slapd/Makefile.in
servers/slapd/at.c
servers/slapd/compare.c
servers/slapd/config.c
servers/slapd/cr.c [new file with mode: 0644]
servers/slapd/libslapd.dsp
servers/slapd/oc.c
servers/slapd/proto-slap.h
servers/slapd/schema.c
servers/slapd/schemaparse.c
servers/slapd/slap.h

index 2176cdcc35807368a119ead166775ff9091fac83..717b91dc7050bdc08269440676b9e01c0c938937 100644 (file)
@@ -9,7 +9,7 @@ XSRCS=version.c
 NT_SRCS = nt_svc.c
 NT_OBJS = nt_svc.o ../../libraries/liblutil/slapdmsg.res
 
-SRCS   = main.c daemon.c connection.c search.c filter.c add.c \
+SRCS   = main.c daemon.c connection.c search.c filter.c add.c cr.c \
                attr.c entry.c config.c backend.c result.c operation.c \
                dn.c compare.c modify.c delete.c modrdn.c ch_malloc.c \
                value.c ava.c bind.c unbind.c abandon.c filterentry.c \
@@ -22,7 +22,7 @@ SRCS  = main.c daemon.c connection.c search.c filter.c add.c \
                limits.c backglue.c operational.c matchedValues.c \
                $(@PLAT@_SRCS)
 
-OBJS   = main.o daemon.o connection.o search.o filter.o add.o \
+OBJS   = main.o daemon.o connection.o search.o filter.o add.o cr.o \
                attr.o entry.o config.o backend.o result.o operation.o \
                dn.o compare.o modify.o delete.o modrdn.o ch_malloc.o \
                value.o ava.o bind.o unbind.o abandon.o filterentry.o \
index 7d2f6e1892d674e54b36d56aef4cc4a88953664a..42c1b7a39653e708378f5ee157976c2a0abbfe21 100644 (file)
@@ -591,12 +591,12 @@ at_schema_info( Entry *e )
        vals[1].bv_val = NULL;
 
        for ( at = attr_list; at; at = at->sat_next ) {
+               if( at->sat_flags & SLAP_AT_HIDE ) continue;
+
                if ( ldap_attributetype2bv( &at->sat_atype, vals ) == NULL ) {
                        return -1;
                }
 
-               if( at->sat_flags & SLAP_AT_HIDE ) continue;
-
                attr_merge( e, ad_attributeTypes, vals );
                ldap_memfree( vals[0].bv_val );
        }
index 7934821fd4f6e1c4f091df50c388950dce0e44a5..81e3e9f54e206783b54226bbe957f3b67fe4b4fa 100644 (file)
@@ -36,6 +36,7 @@ do_compare(
 )
 {
        Entry *entry = NULL;
+       Entry *fentry = NULL;
        struct berval dn = { 0, NULL };
        struct berval pdn = { 0, NULL };
        struct berval ndn = { 0, NULL };
@@ -169,6 +170,8 @@ do_compare(
                        goto cleanup;
                }
 
+               fentry = entry;
+
        } else if ( bvmatch( &ndn, &global_schemandn ) ) {
 #ifdef NEW_LOGGING
                LDAP_LOG( OPERATION, ARGS, 
@@ -198,11 +201,12 @@ do_compare(
                        rc = 0;
                        goto cleanup;
                }
+               fentry = entry;
        }
 
        if( entry ) {
                rc = compare_entry( conn, op, entry, &ava );
-               entry_free( entry );
+               if( fentry) entry_free( fentry );
 
                send_ldap_result( conn, op, rc, NULL, text, NULL, NULL );
 
index 3147c4ede93c31e5cd8f10d06c87f95ce213892e..44c410fac1f8eac7000e92b83a52d07804bacf66 100644 (file)
@@ -1577,9 +1577,9 @@ read_config( const char *fname, int depth )
 
                /* specify an objectclass */
                } else if ( strcasecmp( cargv[0], "objectclass" ) == 0 ) {
-                       if ( *cargv[1] == '(' ) {
+                       if ( *cargv[1] == '('  /*')'*/) {
                                char * p;
-                               p = strchr(saveline,'(');
+                               p = strchr(saveline,'(' /*')'*/);
                                rc = parse_oc( fname, lineno, p, cargv );
                                if( rc ) return rc;
 
@@ -1595,13 +1595,21 @@ read_config( const char *fname, int depth )
 #endif
                        }
 
+#ifdef SLAP_EXTENDED_SCHEMA
+               } else if ( strcasecmp( cargv[0], "ditcontentrule" ) == 0 ) {
+                       char * p;
+                       p = strchr(saveline,'(' /*')'*/);
+                       rc = parse_cr( fname, lineno, p, cargv );
+                       if( rc ) return rc;
+#endif
+
                /* specify an attribute type */
                } else if (( strcasecmp( cargv[0], "attributetype" ) == 0 )
                        || ( strcasecmp( cargv[0], "attribute" ) == 0 ))
                {
-                       if ( *cargv[1] == '(' ) {
+                       if ( *cargv[1] == '(' /*')'*/) {
                                char * p;
-                               p = strchr(saveline,'(');
+                               p = strchr(saveline,'(' /*')'*/);
                                rc = parse_at( fname, lineno, p, cargv );
                                if( rc ) return rc;
 
diff --git a/servers/slapd/cr.c b/servers/slapd/cr.c
new file mode 100644 (file)
index 0000000..f8f5216
--- /dev/null
@@ -0,0 +1,417 @@
+/* cr.c - content rule routines */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2002 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"
+
+#ifdef SLAP_EXTENDED_SCHEMA
+
+struct cindexrec {
+       struct berval   cir_name;
+       ContentRule     *cir_cr;
+};
+
+static Avlnode *cr_index = NULL;
+static ContentRule *cr_list = NULL;
+
+static int
+cr_index_cmp(
+    struct cindexrec   *cir1,
+    struct cindexrec   *cir2 )
+{
+       int i = cir1->cir_name.bv_len - cir2->cir_name.bv_len;
+       if (i)
+               return i;
+       return strcasecmp( cir1->cir_name.bv_val, cir2->cir_name.bv_val );
+}
+
+static int
+cr_index_name_cmp(
+    struct berval      *name,
+    struct cindexrec   *cir )
+{
+       int i = name->bv_len - cir->cir_name.bv_len;
+       if (i)
+               return i;
+       return strncasecmp( name->bv_val, cir->cir_name.bv_val, name->bv_len );
+}
+
+ContentRule *
+cr_find( const char *crname )
+{
+       struct berval bv;
+
+       bv.bv_val = (char *)crname;
+       bv.bv_len = strlen( crname );
+
+       return( cr_bvfind( &bv ) );
+}
+
+ContentRule *
+cr_bvfind( struct berval *crname )
+{
+       struct cindexrec        *cir;
+
+       cir = (struct cindexrec *) avl_find( cr_index, crname,
+            (AVL_CMP) cr_index_name_cmp );
+
+       if ( cir != NULL ) {
+               return( cir->cir_cr );
+       }
+
+       return( NULL );
+}
+
+void
+cr_destroy( void )
+{
+       ContentRule *c, *n;
+
+       avl_free(cr_index, ldap_memfree);
+       for (c=cr_list; c; c=n)
+       {
+               n = c->scr_next;
+               if (c->scr_auxiliaries) ldap_memfree(c->scr_auxiliaries);
+               if (c->scr_required) ldap_memfree(c->scr_required);
+               if (c->scr_allowed) ldap_memfree(c->scr_allowed);
+               if (c->scr_precluded) ldap_memfree(c->scr_precluded);
+               ldap_contentrule_free((LDAPContentRule *)c);
+       }
+}
+
+static int
+cr_insert(
+    ContentRule                *scr,
+    const char         **err
+)
+{
+       ContentRule     **crp;
+       struct cindexrec        *cir;
+       char                    **names;
+
+       crp = &cr_list;
+       while ( *crp != NULL ) {
+               crp = &(*crp)->scr_next;
+       }
+       *crp = scr;
+
+       if ( scr->scr_oid ) {
+               cir = (struct cindexrec *)
+                       ch_calloc( 1, sizeof(struct cindexrec) );
+               cir->cir_name.bv_val = scr->scr_oid;
+               cir->cir_name.bv_len = strlen( scr->scr_oid );
+               cir->cir_cr = scr;
+
+               assert( cir->cir_name.bv_val );
+               assert( cir->cir_cr );
+
+               if ( avl_insert( &cr_index, (caddr_t) cir,
+                                (AVL_CMP) cr_index_cmp,
+                                (AVL_DUP) avl_dup_error ) )
+               {
+                       *err = scr->scr_oid;
+                       ldap_memfree(cir);
+                       return SLAP_SCHERR_CR_DUP;
+               }
+
+               /* FIX: temporal consistency check */
+               assert( cr_bvfind(&cir->cir_name) != NULL );
+       }
+
+       if ( (names = scr->scr_names) ) {
+               while ( *names ) {
+                       cir = (struct cindexrec *)
+                               ch_calloc( 1, sizeof(struct cindexrec) );
+                       cir->cir_name.bv_val = *names;
+                       cir->cir_name.bv_len = strlen( *names );
+                       cir->cir_cr = scr;
+
+                       assert( cir->cir_name.bv_val );
+                       assert( cir->cir_cr );
+
+                       if ( avl_insert( &cr_index, (caddr_t) cir,
+                                        (AVL_CMP) cr_index_cmp,
+                                        (AVL_DUP) avl_dup_error ) )
+                       {
+                               *err = *names;
+                               ldap_memfree(cir);
+                               return SLAP_SCHERR_CR_DUP;
+                       }
+
+                       /* FIX: temporal consistency check */
+                       assert( cr_bvfind(&cir->cir_name) != NULL );
+
+                       names++;
+               }
+       }
+
+       return 0;
+}
+
+static int
+cr_add_auxiliaries(
+    ContentRule                *scr,
+       int                     *op,
+    const char         **err )
+{
+       int naux;
+
+       if( scr->scr_oc_oids_aux == NULL ) return 0;
+       
+       for( naux=0; scr->scr_oc_oids_aux[naux]; naux++ ) {
+               /* count them */ ;
+       }
+
+       scr->scr_auxiliaries = ch_calloc( naux+1, sizeof(ObjectClass *));
+
+       for( naux=0; scr->scr_oc_oids_aux[naux]; naux++ ) {
+               ObjectClass *soc = scr->scr_auxiliaries[naux]
+                       = oc_find(scr->scr_oc_oids_aux[naux]);
+               if ( !soc ) {
+                       *err = scr->scr_oc_oids_aux[naux];
+                       return SLAP_SCHERR_CLASS_NOT_FOUND;
+               }
+
+               if( soc->soc_flags & SLAP_OC_OPERATIONAL ) (*op)++;
+
+               if( soc->soc_kind != LDAP_SCHEMA_AUXILIARY ) {
+                       *err = scr->scr_oc_oids_aux[naux];
+                       return SLAP_SCHERR_CR_BAD_AUX;
+               }
+       }
+
+       scr->scr_auxiliaries[naux] = NULL;
+
+       return 0;
+}
+
+static int
+cr_create_required(
+    ContentRule                *scr,
+       int                     *op,
+    const char         **err )
+{
+    char               **attrs = scr->scr_at_oids_must;
+       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( is_at_operational( sat )) (*op)++;
+
+                       if ( at_find_in_list(sat, scr->scr_required) < 0) {
+                               if ( at_append_to_list(sat, &scr->scr_required) ) {
+                                       *err = *attrs1;
+                                       return SLAP_SCHERR_OUTOFMEM;
+                               }
+                       } else {
+                               *err = *attrs1;
+                               return SLAP_SCHERR_CR_BAD_AT;
+                       }
+                       attrs1++;
+               }
+       }
+       return 0;
+}
+
+static int
+cr_create_allowed(
+    ContentRule                *scr,
+       int                     *op,
+    const char         **err )
+{
+    char               **attrs = scr->scr_at_oids_may;
+       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( is_at_operational( sat )) (*op)++;
+
+                       if ( at_find_in_list(sat, scr->scr_required) < 0 &&
+                               at_find_in_list(sat, scr->scr_allowed) < 0 )
+                       {
+                               if ( at_append_to_list(sat, &scr->scr_allowed) ) {
+                                       *err = *attrs1;
+                                       return SLAP_SCHERR_OUTOFMEM;
+                               }
+                       } else {
+                               *err = *attrs1;
+                               return SLAP_SCHERR_CR_BAD_AT;
+                       }
+                       attrs1++;
+               }
+       }
+       return 0;
+}
+
+static int
+cr_create_precluded(
+    ContentRule                *scr,
+       int                     *op,
+    const char         **err )
+{
+    char               **attrs = scr->scr_at_oids_not;
+       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( is_at_operational( sat )) (*op)++;
+
+                       /* FIXME: should also make sure attribute type is not
+                               a required attribute of the structural class or
+                               any auxiliary class */
+                       if ( at_find_in_list(sat, scr->scr_required) < 0 &&
+                               at_find_in_list(sat, scr->scr_allowed) < 0 &&
+                               at_find_in_list(sat, scr->scr_precluded) < 0 )
+                       {
+                               if ( at_append_to_list(sat, &scr->scr_precluded) ) {
+                                       *err = *attrs1;
+                                       return SLAP_SCHERR_OUTOFMEM;
+                               }
+                       } else {
+                               *err = *attrs1;
+                               return SLAP_SCHERR_CR_BAD_AT;
+                       }
+                       attrs1++;
+               }
+       }
+       return 0;
+}
+
+int
+cr_add(
+    LDAPContentRule    *cr,
+       int user,
+    const char         **err
+)
+{
+       ContentRule     *scr;
+       int             code;
+       int             op = 0;
+
+       if ( cr->cr_names != NULL ) {
+               int i;
+
+               for( i=0; cr->cr_names[i]; i++ ) {
+                       if( !slap_valid_descr( cr->cr_names[i] ) ) {
+                               return SLAP_SCHERR_BAD_DESCR;
+                       }
+               }
+       }
+
+       if ( !OID_LEADCHAR( cr->cr_oid[0] )) {
+               /* Expand OID macros */
+               char *oid = oidm_find( cr->cr_oid );
+               if ( !oid ) {
+                       *err = cr->cr_oid;
+                       return SLAP_SCHERR_OIDM;
+               }
+               if ( oid != cr->cr_oid ) {
+                       ldap_memfree( cr->cr_oid );
+                       cr->cr_oid = oid;
+               }
+       }
+
+       scr = (ContentRule *) ch_calloc( 1, sizeof(ContentRule) );
+       AC_MEMCPY( &scr->scr_crule, cr, sizeof(LDAPContentRule) );
+
+       scr->scr_sclass = oc_find(cr->cr_oid);
+       if ( !scr->scr_sclass ) {
+               *err = cr->cr_oid;
+               return SLAP_SCHERR_CLASS_NOT_FOUND;
+       }
+
+       /* check object class usage */
+       if( scr->scr_sclass->soc_kind != LDAP_SCHEMA_STRUCTURAL )
+       {
+               *err = cr->cr_oid;
+               return SLAP_SCHERR_CR_BAD_STRUCT;
+       }
+
+       if( scr->scr_sclass->soc_flags & SLAP_OC_OPERATIONAL ) op++;
+
+       code = cr_add_auxiliaries( scr, &op, err );
+       if ( code != 0 ) return code;
+
+       code = cr_create_required( scr, &op, err );
+       if ( code != 0 ) return code;
+
+       code = cr_create_allowed( scr, &op, err );
+       if ( code != 0 ) return code;
+
+       code = cr_create_precluded( scr, &op, err );
+       if ( code != 0 ) return code;
+
+       if( user && op ) return SLAP_SCHERR_CR_BAD_AUX;
+
+       code = cr_insert(scr,err);
+       return code;
+}
+
+#endif
+
+int
+cr_schema_info( Entry *e )
+{
+#ifdef SLAP_EXTENDED_SCHEMA
+       struct berval   vals[2];
+       ContentRule     *cr;
+
+       AttributeDescription *ad_ditContentRules = slap_schema.si_ad_ditContentRules;
+
+       vals[1].bv_val = NULL;
+
+       for ( cr = cr_list; cr; cr = cr->scr_next ) {
+               if ( ldap_contentrule2bv( &cr->scr_crule, vals ) == NULL ) {
+                       return -1;
+               }
+
+#if 0
+               if( cr->scr_flags & SLAP_CR_HIDE ) continue;
+#endif
+
+#if 0
+               Debug( LDAP_DEBUG_TRACE, "Merging cr [%ld] %s\n",
+              (long) vals[0].bv_len, vals[0].bv_val, 0 );
+#endif
+               attr_merge( e, ad_ditContentRules, vals );
+               ldap_memfree( vals[0].bv_val );
+       }
+#endif
+       return 0;
+}
index 41614b649119c930c80c6244fef22116756e1592..9920e800dfb6c0689dbd0e2f86c58580e27fb643 100644 (file)
@@ -192,6 +192,10 @@ SOURCE=.\controls.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\cr.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\daemon.c
 # End Source File
 # Begin Source File
index 16a64ebf514af8e002b31686b97608263676b61f..eeceeb2ac69bf3756cc19d64f447de0790203a3e 100644 (file)
@@ -465,31 +465,6 @@ oc_add(
        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
-
 int
 oc_schema_info( Entry *e )
 {
@@ -501,12 +476,12 @@ oc_schema_info( Entry *e )
        vals[1].bv_val = NULL;
 
        for ( oc = oc_list; oc; oc = oc->soc_next ) {
+               if( oc->soc_flags & SLAP_OC_HIDE ) continue;
+
                if ( ldap_objectclass2bv( &oc->soc_oclass, vals ) == NULL ) {
                        return -1;
                }
 
-               if( oc->soc_flags & SLAP_OC_HIDE ) continue;
-
 #if 0
                Debug( LDAP_DEBUG_TRACE, "Merging oc [%ld] %s\n",
               (long) vals[0].bv_len, vals[0].bv_val, 0 );
index 74f2b2655b452d6d5ca8668efd75d69b4f49fb42..d7a963ed1b5d193ab3aa98a58d810a1e1b5a9bf0 100644 (file)
@@ -312,6 +312,22 @@ LDAP_SLAPD_F (void) connection_done LDAP_P((Connection *));
 
 LDAP_SLAPD_F (void) connection2anonymous LDAP_P((Connection *));
 
+/*
+ * cr.c
+ */
+LDAP_SLAPD_F (int) cr_schema_info( Entry *e );
+
+LDAP_SLAPD_F (int) cr_add LDAP_P((
+       LDAPContentRule *oc,
+       int user,
+       const char **err));
+LDAP_SLAPD_F (void) cr_destroy LDAP_P(( void ));
+
+LDAP_SLAPD_F (ContentRule *) cr_find LDAP_P((
+       const char *crname));
+LDAP_SLAPD_F (ContentRule *) cr_bvfind LDAP_P((
+       struct berval *crname));
+
 /*
  * daemon.c
  */
@@ -954,8 +970,8 @@ LDAP_SLAPD_F (int) slap_schema_check LDAP_P((void));
  */
 LDAP_SLAPD_F( int ) slap_valid_descr( const char * );
 
-LDAP_SLAPD_F (int) parse_oc_old LDAP_P((
-       Backend *be, const char *fname, int lineno, int argc, char **argv ));
+LDAP_SLAPD_F (int) parse_cr LDAP_P((
+       const char *fname, int lineno, char *line, char **argv ));
 LDAP_SLAPD_F (int) parse_oc LDAP_P((
        const char *fname, int lineno, char *line, char **argv ));
 LDAP_SLAPD_F (int) parse_at LDAP_P((
index bc218fcca8dc71afa47c3549d8fa4a6fba9607d7..c9d4436e8bc12f7da86f7cb4b8b8801cc9d2523e 100644 (file)
@@ -115,7 +115,8 @@ schema_info( Entry **entry, const char **text )
                || mr_schema_info( e )
                || mru_schema_info( e )
                || at_schema_info( e )
-               || oc_schema_info( e ) )
+               || oc_schema_info( e )
+               || cr_schema_info( e ) )
        {
                /* Out of memory, do something about it */
                entry_free( e );
index cb5fca8f82d05f7f792ed66f1593ad4f05594dfc..d0aca20d90b8d6f7d89035e1328f587714387d4e 100644 (file)
@@ -42,7 +42,11 @@ static char *const err2text[] = {
        "OID or name required",
        "Qualifier not supported",
        "Invalid NAME",
-       "OID could not be expanded"
+       "OID could not be expanded",
+       "Duplicate Content Rule",
+       "Content Rule not for STRUCTURAL object class",
+       "Content Rule AUX contains non-AUXILIARY object class"
+       "Content Rule attribute type list contains duplicate"
 };
 
 char *
@@ -92,6 +96,64 @@ dscompare(const char *s1, const char *s2, char delim)
        return 0;
 }
 
+#ifdef SLAP_EXTENDED_SCHEMA
+
+static void
+cr_usage( void )
+{
+       fprintf( stderr,
+               "DITContentRuleDescription = \"(\" whsp\n"
+               "  numericoid whsp       ; StructuralObjectClass identifier\n"
+               "  [ \"NAME\" qdescrs ]\n"
+               "  [ \"DESC\" qdstring ]\n"
+               "  [ \"OBSOLETE\" whsp ]\n"
+               "  [ \"AUX\" oids ]      ; Auxiliary ObjectClasses\n"
+               "  [ \"MUST\" oids ]     ; AttributeTypes\n"
+               "  [ \"MAY\" oids ]      ; AttributeTypes\n"
+               "  [ \"NOT\" oids ]      ; AttributeTypes\n"
+               "  whsp \")\"\n" );
+}
+
+int
+parse_cr(
+    const char *fname,
+    int                lineno,
+    char       *line,
+    char       **argv
+)
+{
+       LDAPContentRule *cr;
+       int             code;
+       const char      *err;
+
+       cr = ldap_str2contentrule(line, &code, &err, LDAP_SCHEMA_ALLOW_ALL );
+       if ( !cr ) {
+               fprintf( stderr, "%s: line %d: %s before %s\n",
+                        fname, lineno, ldap_scherr2str(code), err );
+               cr_usage();
+               return 1;
+       }
+
+       if ( cr->cr_oid == NULL ) {
+               fprintf( stderr,
+                       "%s: line %d: Content rule has no OID\n",
+                       fname, lineno );
+               cr_usage();
+               return 1;
+       }
+
+       code = cr_add(cr,1,&err);
+       if ( code ) {
+               fprintf( stderr, "%s: line %d: %s: \"%s\"\n",
+                        fname, lineno, scherr2str(code), err);
+               return 1;
+       }
+
+       ldap_memfree(cr);
+       return 0;
+}
+
+#endif
 
 int
 parse_oc(
@@ -149,7 +211,6 @@ oc_usage( void )
                "  whsp \")\"\n" );
 }
 
-
 static void
 at_usage( void )
 {
index 329a10868873d9ac6b86a0964bf2170a6145657a..ea0d985d3a6e1e7fcd5c3ff1f312bf488c5902ee 100644 (file)
@@ -212,9 +212,11 @@ typedef struct slap_ssf_set {
 #define SLAP_INDEX_SUBSTR_FINAL_PREFIX '$'
 #define SLAP_INDEX_CONT_PREFIX         '.'             /* prefix for continuation keys */
 
-#define SLAP_SYNTAX_MATCHINGRULES_OID  "1.3.6.1.4.1.1466.115.121.1.30"
-#define SLAP_SYNTAX_ATTRIBUTETYPES_OID "1.3.6.1.4.1.1466.115.121.1.3"
-#define SLAP_SYNTAX_OBJECTCLASSES_OID  "1.3.6.1.4.1.1466.115.121.1.37"
+#define SLAP_SYNTAX_MATCHINGRULES_OID   "1.3.6.1.4.1.1466.115.121.1.30"
+#define SLAP_SYNTAX_ATTRIBUTETYPES_OID  "1.3.6.1.4.1.1466.115.121.1.3"
+#define SLAP_SYNTAX_OBJECTCLASSES_OID   "1.3.6.1.4.1.1466.115.121.1.37"
+#define SLAP_SYNTAX_MATCHINGRULEUSES_OID "1.3.6.1.4.1.1466.115.121.1.31"
+#define SLAP_SYNTAX_CONTENTRULE_OID             "1.3.6.1.4.1.1466.115.121.1.16"
 
 #ifdef LDAP_CLIENT_UPDATE
 #define LCUP_COOKIE_OID "1.3.6.1.4.1.4203.666.10.1"
@@ -243,7 +245,11 @@ typedef struct slap_ssf_set {
 #define SLAP_SCHERR_NOT_SUPPORTED              18
 #define SLAP_SCHERR_BAD_DESCR                  19
 #define SLAP_SCHERR_OIDM                               20
-#define SLAP_SCHERR_LAST                               SLAP_SCHERR_OIDM
+#define SLAP_SCHERR_CR_DUP                             21
+#define SLAP_SCHERR_CR_BAD_STRUCT              22
+#define SLAP_SCHERR_CR_BAD_AUX                 23
+#define SLAP_SCHERR_CR_BAD_AT                  24
+#define SLAP_SCHERR_LAST                               SLAP_SCHERR_CR_BAD_AT
 
 typedef union slap_sockaddr {
        struct sockaddr sa_addr;
@@ -591,7 +597,6 @@ typedef struct slap_object_class {
 #define SLAP_OC_OPERATIONAL    0x4000
 #define SLAP_OC_HIDE           0x8000
 
-#ifdef LDAP_EXTENDED_SCHEMA
 /*
  * DIT content rule
  */
@@ -602,16 +607,17 @@ typedef struct slap_content_rule {
        AttributeType           **scr_required;         /* optional */
        AttributeType           **scr_allowed;          /* optional */
        AttributeType           **scr_precluded;        /* optional */
-#define scr_oid                        scr_crule.cr_oid
-#define scr_names              scr_crule.cr_names
-#define scr_desc               scr_crule.cr_desc
-#define scr_obsolete           soc_oclass.cr_obsolete
-#define scr_cr_oids_aux                soc_oclass.cr_oc_oids_aux
-#define scr_cr_oids_must       soc_oclass.cr_at_oids_must
-#define scr_cr_oids_may                soc_oclass.cr_at_oids_may
-#define scr_cr_oids_not                soc_oclass.cr_at_oids_not
+#define scr_oid                                scr_crule.cr_oid
+#define scr_names                      scr_crule.cr_names
+#define scr_desc                       scr_crule.cr_desc
+#define scr_obsolete           scr_crule.cr_obsolete
+#define scr_oc_oids_aux                scr_crule.cr_oc_oids_aux
+#define scr_at_oids_must       scr_crule.cr_at_oids_must
+#define scr_at_oids_may                scr_crule.cr_at_oids_may
+#define scr_at_oids_not                scr_crule.cr_at_oids_not
+
+       struct slap_content_rule *scr_next;
 } ContentRule;
-#endif
 
 /*
  * represents a recognized attribute description ( type + options )