]> git.sur5r.net Git - openldap/commitdiff
Implement content rule checks
authorKurt Zeilenga <kurt@openldap.org>
Wed, 9 Oct 2002 23:02:01 +0000 (23:02 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Wed, 9 Oct 2002 23:02:01 +0000 (23:02 +0000)
w/ implicit default rules allowing any auxiliary class to be mixed in

servers/slapd/schema_check.c
servers/slapd/slap.h

index 0412bb4f2028bd2ebefec86835c42cca688d9a97..ac1986161be24c37062bf8e0da17fdc7770a7446 100644 (file)
@@ -38,6 +38,10 @@ entry_schema_check(
 {
        Attribute       *a, *asc, *aoc;
        ObjectClass *sc, *oc;
+#ifdef SLAP_EXTENDED_SCHEMA
+       AttributeType *at;
+       ContentRule *cr;
+#endif
        int     rc, i;
        struct berval nsc;
        AttributeDescription *ad_structuralObjectClass
@@ -48,7 +52,9 @@ entry_schema_check(
        int subentry = is_entry_subentry( e );
        int collectiveSubentry = 0;
 
-       if( subentry) collectiveSubentry = is_entry_collectiveAttributeSubentry( e );
+       if( subentry ) {
+               collectiveSubentry = is_entry_collectiveAttributeSubentry( e );
+       }
 
        *text = textbuf;
 
@@ -194,6 +200,77 @@ entry_schema_check(
                return LDAP_NO_OBJECT_CLASS_MODS;
        }
 
+#ifdef SLAP_EXTENDED_SCHEMA
+       /* find the content rule for the structural class */
+       cr = cr_find( sc->soc_oid );
+
+       /* the cr must be same as the structural class */
+       assert( !cr || !strcmp( cr->scr_oid, sc->soc_oid ) );
+
+       /* check that the entry has required attrs of the content rule */
+       if( cr && cr->scr_required ) {
+               for( i=0; cr->scr_required[i]; i++ ) {
+                       at = cr->scr_required[i];
+
+                       for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
+                               if( a->a_desc->ad_type == at ) {
+                                       break;
+                               }
+                       }
+
+                       /* not there => schema violation */
+                       if ( a == NULL ) {
+                               snprintf( textbuf, textlen, 
+                                       "content rule '%s' requires attribute '%s'",
+                                       ldap_contentrule2name( &cr->scr_crule ),
+                                       at->sat_cname.bv_val );
+
+#ifdef NEW_LOGGING
+                               LDAP_LOG( OPERATION, INFO, 
+                                       "entry_schema_check: dn=\"%s\" %s", e->e_dn, textbuf, 0 );
+#else
+                               Debug( LDAP_DEBUG_ANY,
+                                       "Entry (%s): %s\n",
+                                       e->e_dn, textbuf, 0 );
+#endif
+
+                               return LDAP_OBJECT_CLASS_VIOLATION;
+                       }
+               }
+       }
+
+       if( cr && cr->scr_precluded ) {
+               for( i=0; cr->scr_precluded[i]; i++ ) {
+                       at = cr->scr_precluded[i];
+
+                       for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
+                               if( a->a_desc->ad_type == at ) {
+                                       break;
+                               }
+                       }
+
+                       /* there => schema violation */
+                       if ( a != NULL ) {
+                               snprintf( textbuf, textlen, 
+                                       "content rule '%s' precluded attribute '%s'",
+                                       ldap_contentrule2name( &cr->scr_crule ),
+                                       at->sat_cname.bv_val );
+
+#ifdef NEW_LOGGING
+                               LDAP_LOG( OPERATION, INFO, 
+                                       "entry_schema_check: dn=\"%s\" %s", e->e_dn, textbuf, 0 );
+#else
+                               Debug( LDAP_DEBUG_ANY,
+                                       "Entry (%s): %s\n",
+                                       e->e_dn, textbuf, 0 );
+#endif
+
+                               return LDAP_OBJECT_CLASS_VIOLATION;
+                       }
+               }
+       }
+#endif /* SLAP_EXTENDED_SCHEMA */
+
        /* check that the entry has required attrs for each oc */
        for ( i = 0; aoc->a_vals[i].bv_val != NULL; i++ ) {
                if ( (oc = oc_bvfind( &aoc->a_vals[i] )) == NULL ) {
@@ -284,8 +361,46 @@ entry_schema_check(
                        }
 
                } else if ( oc->soc_kind != LDAP_SCHEMA_STRUCTURAL || oc == sc ) {
-                       char *s = oc_check_required( e, oc, &aoc->a_vals[i] );
+                       char *s;
+
+#ifdef SLAP_EXTENDED_SCHEMA
+                       if( oc->soc_kind == LDAP_SCHEMA_AUXILIARY ) {
+                               int k=0;
+                               if( cr ) {
+                                       if( cr->scr_auxiliaries ) {
+                                               for( ; cr->scr_auxiliaries[k]; k++ ) {
+                                                       if( cr->scr_auxiliaries[k] == oc ) {
+                                                               k=-1;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                               } else if ( global_disallows & SLAP_DISALLOW_AUX_WO_CR ) {
+                                       k=-1;
+                               }
+
+                               if( k == -1 ) {
+                                       snprintf( textbuf, textlen, 
+                                               "content rule '%s' does not allow class '%s'",
+                                               ldap_contentrule2name( &cr->scr_crule ),
+                                               oc->soc_cname.bv_val );
+
+#ifdef NEW_LOGGING
+                                       LDAP_LOG( OPERATION, INFO, 
+                                               "entry_schema_check: dn=\"%s\" %s",
+                                               e->e_dn, textbuf, 0 );
+#else
+                                       Debug( LDAP_DEBUG_ANY,
+                                               "Entry (%s): %s\n",
+                                               e->e_dn, textbuf, 0 );
+#endif
+
+                                       return LDAP_OBJECT_CLASS_VIOLATION;
+                               }
+                       }
+#endif /* SLAP_EXTENDED_SCHEMA */
 
+                       s = oc_check_required( e, oc, &aoc->a_vals[i] );
                        if (s != NULL) {
                                snprintf( textbuf, textlen, 
                                        "object class '%s' requires attribute '%s'",
@@ -315,7 +430,35 @@ entry_schema_check(
 
        /* check that each attr in the entry is allowed by some oc */
        for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
-               int ret = oc_check_allowed( a->a_desc->ad_type, aoc->a_vals, sc );
+               int ret;
+
+#ifdef SLAP_EXTENDED_SCHEMA
+               ret = LDAP_OBJECT_CLASS_VIOLATION;
+
+               if( cr && cr->scr_required ) {
+                       for( i=0; cr->scr_required[i]; i++ ) {
+                               if( cr->scr_required[i] == a->a_desc->ad_type ) {
+                                       ret = LDAP_SUCCESS;
+                                       break;
+                               }
+                       }
+               }
+
+               if( ret != LDAP_SUCCESS && cr && cr->scr_allowed ) {
+                       for( i=0; cr->scr_allowed[i]; i++ ) {
+                               if( cr->scr_allowed[i] == a->a_desc->ad_type ) {
+                                       ret = LDAP_SUCCESS;
+                                       break;
+                               }
+                       }
+               }
+
+               if( ret != LDAP_SUCCESS ) 
+#endif /* SLAP_EXTENDED_SCHEMA */
+               {
+                       ret = oc_check_allowed( a->a_desc->ad_type, aoc->a_vals, sc );
+               }
+
                if ( ret != LDAP_SUCCESS ) {
                        char *type = a->a_desc->ad_cname.bv_val;
 
index ea0d985d3a6e1e7fcd5c3ff1f312bf488c5902ee..df6b9abe18e37c022aa1e50e57a9cd508978157d 100644 (file)
@@ -35,6 +35,8 @@
 #include "ldap_pvt_thread.h"
 #include "ldap_queue.h"
 
+#define SLAP_EXTENDED_SCHEMA 1
+
 LDAP_BEGIN_DECL
 /*
  * SLAPD Memory allocation macros
@@ -1270,6 +1272,8 @@ struct slap_backend_db {
 #define SLAP_DISALLOW_TLS_2_ANON       0x0010U /* StartTLS -> Anonymous */
 #define SLAP_DISALLOW_TLS_AUTHC                0x0020U /* TLS while authenticated */
 
+#define SLAP_DISALLOW_AUX_WO_CR                0x4000U
+
        slap_mask_t     be_requires;    /* pre-operation requirements */
 #define SLAP_REQUIRE_BIND              0x0001U /* bind before op */
 #define SLAP_REQUIRE_LDAP_V3   0x0002U /* LDAPv3 before op */