]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/schema_check.c
Bug fix for new sockbuf code under NT. Added mutex protection against
[openldap] / servers / slapd / schema_check.c
index cd328eed6a54ee8e8672a38c1ff08a8d2636d76a..d1c00935c31ff32fea0427985b83de765acf6dd4 100644 (file)
@@ -1,7 +1,7 @@
 /* schema_check.c - routines to enforce schema definitions */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 #include "slap.h"
 #include "ldap_pvt.h"
 
-#ifdef SLAPD_SCHEMA_NOT_COMPAT
-static int oc_check_allowed(
-       AttributeType *type,
-       struct berval **oclist );
-#else
+#ifndef SLAPD_SCHEMA_NOT_COMPAT
 static int             oc_check_allowed(char *type, struct berval **oclist);
 #endif
 static char *  oc_check_required(Entry *e, struct berval *ocname);
@@ -33,69 +29,92 @@ static char *       oc_check_required(Entry *e, struct berval *ocname);
  */
 
 int
-schema_check_entry( Entry *e )
+entry_schema_check( 
+       Entry *e, Attribute *oldattrs, const char** text )
 {
        Attribute       *a, *aoc;
        ObjectClass *oc;
        int             i;
-       int             ret = 0;
+       int             ret;
 #ifdef SLAPD_SCHEMA_NOT_COMPAT
-       static AttributeDescription *objectClass = NULL;
+       AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass;
 #else
-       static const char *objectClass = "objectclass";
+       static const char *ad_objectClass = "objectclass";
 #endif
+       int extensible = 0;
 
-
-       if( !global_schemacheck ) return 0;
+       if( !global_schemacheck ) return LDAP_SUCCESS;
 
        /* find the object class attribute - could error out here */
-       if ( (aoc = attr_find( e->e_attrs, objectClass )) == NULL ) {
+       if ( (aoc = attr_find( e->e_attrs, ad_objectClass )) == NULL ) {
                Debug( LDAP_DEBUG_ANY, "No object class for entry (%s)\n",
                    e->e_dn, 0, 0 );
-               return( 1 );
+               *text = "no objectclass attribute";
+               return oldattrs != NULL
+                       ? LDAP_OBJECT_CLASS_VIOLATION
+                       : LDAP_NO_OBJECT_CLASS_MODS;
        }
 
+       ret = LDAP_SUCCESS;
+
        /* 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
-               {
+                               "entry_check_schema(%s): objectclass \"%s\" not defined\n",
+                               e->e_dn, aoc->a_vals[i]->bv_val, 0 );
+
+               } else {
                        char *s = oc_check_required( e, aoc->a_vals[i] );
 
                        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;
+                               *text = "missing required attribute";
+                               ret = LDAP_OBJECT_CLASS_VIOLATION;
+                               break;
+                       }
+
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+                       if( oc == slap_schema.si_oc_extensibleObject )
+#else
+                       if( !strcmp( aoc->a_vals[i], "extensibleObject" ) == 0 )
+#endif
+                       {
+                               extensible=1;
                        }
+
                }
        }
 
-       if ( ret != 0 ) {
-           return( ret );
+       if ( ret != LDAP_SUCCESS ) {
+           return ret;
+       }
+
+       if( extensible ) {
+               return LDAP_SUCCESS;
        }
 
        /* 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;
-               }
+               ret = oc_check_allowed( a->a_desc->ad_type, aoc->a_vals );
+#else
+               ret = oc_check_allowed( a->a_type, aoc->a_vals );
+#endif
+               if ( ret != 0 ) {
+#ifdef SLAPD_SCHEMA_NOT_COMPAT
+                       char *type = a->a_desc->ad_cname->bv_val;
 #else
-               if ( oc_check_allowed( a->a_type, aoc->a_vals ) != 0 ) {
+                       char *type = a->a_type;
+#endif
                        Debug( LDAP_DEBUG_ANY,
                            "Entry (%s), attr \"%s\" not allowed\n",
-                           e->e_dn, a->a_type, 0 );
-                       ret = 1;
+                           e->e_dn, type, 0 );
+                       *text = "attribute not allowed";
+                       break;
                }
-#endif
        }
 
        return( ret );
@@ -111,16 +130,16 @@ oc_check_required( Entry *e, struct berval *ocname )
 
        Debug( LDAP_DEBUG_TRACE,
               "oc_check_required entry (%s), objectclass \"%s\"\n",
-              e->e_dn, ocname, 0 );
+              e->e_dn, ocname->bv_val, 0 );
 
        /* find global oc defn. it we don't know about it assume it's ok */
        if ( (oc = oc_find( ocname->bv_val )) == NULL ) {
-               return( 0 );
+               return NULL;
        }
 
        /* check for empty oc_required */
        if(oc->soc_required == NULL) {
-               return( 0 );
+               return NULL;
        }
 
        /* for each required attribute */
@@ -129,7 +148,7 @@ oc_check_required( Entry *e, struct berval *ocname )
                /* 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 ) {
+                       if( a->a_desc->ad_type == at ) {
                                break;
                        }
 #else
@@ -173,8 +192,10 @@ oc_check_required( Entry *e, struct berval *ocname )
        return( NULL );
 }
 
-static int
-oc_check_allowed(
+#ifndef SLAPD_SCHEMA_NOT_COMPAT
+static
+#endif
+int oc_check_allowed(
 #ifdef SLAPD_SCHEMA_NOT_COMPAT
        AttributeType *at,
 #else
@@ -192,7 +213,7 @@ oc_check_allowed(
 
        /* always allow objectclass attribute */
        if ( strcasecmp( at->sat_cname, "objectclass" ) == 0 ) {
-               return( 0 );
+               return LDAP_SUCCESS;
        }
 
 #else
@@ -206,13 +227,16 @@ oc_check_allowed(
 
        /* always allow objectclass attribute */
        if ( strcasecmp( type, "objectclass" ) == 0 ) {
-               return( 0 );
+               return LDAP_SUCCESS;
        }
 #endif
 
 #ifdef SLAPD_SCHEMA_NOT_COMPAT
+       /*
+        * All operational attributions are allowed by schema rules.
+        */
        if( is_at_operational(at) ) {
-               return 0;
+               return LDAP_SUCCESS;
        }
 #else
        /*
@@ -237,7 +261,7 @@ oc_check_allowed(
         * All operational attributions are allowed by schema rules.
         */
        if ( oc_check_op_attr( t ) ) {
-               return( 0 );
+               return LDAP_SUCCESS;
        }
 #endif
 
@@ -251,7 +275,7 @@ oc_check_allowed(
                        {
 #ifdef SLAPD_SCHEMA_NOT_COMPAT
                                if( at == oc->soc_required[j] ) {
-                                       return 0;
+                                       return LDAP_SUCCESS;
                                }
 #else
                                at = oc->soc_required[j];
@@ -259,7 +283,7 @@ oc_check_allowed(
                                     strcmp(at->sat_oid, t ) == 0 ) {
                                        if ( t != type )
                                                ldap_memfree( t );
-                                       return( 0 );
+                                       return LDAP_SUCCESS;
                                }
                                pp = at->sat_names;
                                if ( pp == NULL )
@@ -268,7 +292,7 @@ oc_check_allowed(
                                        if ( strcasecmp( *pp, t ) == 0 ) {
                                                if ( t != type )
                                                        ldap_memfree( t );
-                                               return( 0 );
+                                               return LDAP_SUCCESS;
                                        }
                                        pp++;
                                }
@@ -280,7 +304,7 @@ oc_check_allowed(
                        {
 #ifdef SLAPD_SCHEMA_NOT_COMPAT
                                if( at == oc->soc_allowed[j] ) {
-                                       return 0;
+                                       return LDAP_SUCCESS;
                                }
 #else
                                at = oc->soc_allowed[j];
@@ -288,7 +312,7 @@ oc_check_allowed(
                                     strcmp( at->sat_oid, t ) == 0 ) {
                                        if ( t != type )
                                                ldap_memfree( t );
-                                       return( 0 );
+                                       return LDAP_SUCCESS;
                                }
                                pp = at->sat_names;
                                if ( pp == NULL )
@@ -298,7 +322,7 @@ oc_check_allowed(
                                             strcmp( *pp, "*" ) == 0 ) {
                                                if ( t != type )
                                                        ldap_memfree( t );
-                                               return( 0 );
+                                               return LDAP_SUCCESS;
                                        }
                                        pp++;
                                }
@@ -311,7 +335,7 @@ oc_check_allowed(
                } else {
                        if ( t != type )
                                ldap_memfree( t );
-                       return( 0 );
+                       return LDAP_SUCCESS;
 #endif
                }
        }
@@ -322,5 +346,5 @@ oc_check_allowed(
 #endif
 
        /* not allowed by any oc */
-       return( 1 );
+       return LDAP_OBJECT_CLASS_VIOLATION;
 }