]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/schema_check.c
fix possible uninitialized use of nmods
[openldap] / servers / slapd / schema_check.c
index b53cd45353e4e35fcdc08211f17835a1537290f9..31c16e2f2d58747c6c8fe4f70e183de4df065151 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;
 
@@ -143,6 +149,23 @@ entry_schema_check(
                        "structuralObjectClass '%s' is not STRUCTURAL",
                        asc->a_vals[0].bv_val );
 
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, INFO, 
+                       "entry_schema_check: dn (%s), %s\n", e->e_dn, textbuf, 0 );
+#else
+               Debug( LDAP_DEBUG_ANY,
+                       "entry_check_schema(%s): %s\n",
+                       e->e_dn, textbuf, 0 );
+#endif
+
+               return LDAP_OTHER;
+       }
+
+       if( sc->soc_obsolete ) {
+               snprintf( textbuf, textlen, 
+                       "structuralObjectClass '%s' is OBSOLETE",
+                       asc->a_vals[0].bv_val );
+
 #ifdef NEW_LOGGING
                LDAP_LOG( OPERATION, INFO, 
                        "entry_schema_check: dn (%s), %s\n", e->e_dn, textbuf, 0 );
@@ -189,11 +212,97 @@ entry_schema_check(
 
        } else if ( sc != oc ) {
                snprintf( textbuf, textlen, 
-                       "structuralObjectClass modification from '%s' to '%s' not allowed",
+                       "structural object class modification from '%s' to '%s' not allowed",
                        asc->a_vals[0].bv_val, nsc.bv_val );
                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 ) {
+               if( cr->scr_obsolete ) {
+                       snprintf( textbuf, textlen, 
+                               "content rule '%s' is obsolete",
+                               ldap_contentrule2name( &cr->scr_crule ));
+
+#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->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->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 ) {
@@ -201,6 +310,24 @@ entry_schema_check(
                                "unrecognized objectClass '%s'",
                                aoc->a_vals[i].bv_val );
 
+#ifdef NEW_LOGGING
+                       LDAP_LOG( OPERATION, INFO, 
+                               "entry_schema_check: dn (%s), %s\n", e->e_dn, textbuf, 0 );
+#else
+                       Debug( LDAP_DEBUG_ANY,
+                               "entry_check_schema(%s): %s\n",
+                               e->e_dn, textbuf, 0 );
+#endif
+
+                       return LDAP_OBJECT_CLASS_VIOLATION;
+               }
+
+               if ( oc->soc_obsolete ) {
+                       /* disallow obsolete classes */
+                       snprintf( textbuf, textlen, 
+                               "objectClass '%s' is OBSOLETE",
+                               aoc->a_vals[i].bv_val );
+
 #ifdef NEW_LOGGING
                        LDAP_LOG( OPERATION, INFO, 
                                "entry_schema_check: dn (%s), %s\n", e->e_dn, textbuf, 0 );
@@ -284,8 +411,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 +480,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;
 
@@ -544,7 +737,12 @@ int structural_class(
        }
 
        if( sc == NULL ) {
-               *text = "no structural object classes provided";
+               *text = "no structural object class provided";
+               return LDAP_OBJECT_CLASS_VIOLATION;
+       }
+
+       if( scn < 0 ) {
+               *text = "invalid structural object class";
                return LDAP_OBJECT_CLASS_VIOLATION;
        }