]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/schema.c
Import unprotected strtok fix from -devel. Yes, you have to edit 8 files
[openldap] / servers / slapd / schema.c
index ba16d9b0f13540041d9b221fcc4db4888f99a794..f4fab6022c3403ff5e94d6b2a5c05cf38754ba2e 100644 (file)
@@ -1,21 +1,17 @@
 /* schema.c - routines to enforce schema definitions */
 
+#include "portable.h"
+
 #include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include "slap.h"
 
-extern Attribute       *attr_find();
-extern char            **str2charray();
-extern void            charray_merge();
+#include <ac/string.h>
+#include <ac/socket.h>
 
-extern struct objclass *global_oc;
-extern int             global_schemacheck;
+#include "slap.h"
 
-static struct objclass *oc_find();
-static int             oc_check_required();
-static int             oc_check_allowed();
+static struct objclass *oc_find(char *ocname);
+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
@@ -39,10 +35,12 @@ oc_schema_check( Entry *e )
 
        /* check that the entry has required attrs for each oc */
        for ( i = 0; aoc->a_vals[i] != NULL; i++ ) {
-               if ( oc_check_required( e, aoc->a_vals[i]->bv_val ) != 0 ) {
+               char *s = oc_check_required( e, aoc->a_vals[i]->bv_val );
+
+               if (s != NULL) {
                        Debug( LDAP_DEBUG_ANY,
-                           "Entry (%s), required attr (%s) missing\n",
-                           e->e_dn, aoc->a_vals[i]->bv_val, 0 );
+                           "Entry (%s), oc \"%s\" requires attr \"%s\"\n",
+                           e->e_dn, aoc->a_vals[i]->bv_val, s );
                        ret = 1;
                }
        }
@@ -55,7 +53,7 @@ oc_schema_check( Entry *e )
        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",
+                           "Entry (%s), attr \"%s\" not allowed\n",
                            e->e_dn, a->a_type, 0 );
                        ret = 1;
                }
@@ -64,7 +62,7 @@ oc_schema_check( Entry *e )
        return( ret );
 }
 
-static int
+static char *
 oc_check_required( Entry *e, char *ocname )
 {
        struct objclass *oc;
@@ -76,6 +74,11 @@ oc_check_required( Entry *e, char *ocname )
                return( 0 );
        }
 
+       /* check for empty oc_required */
+       if(oc->oc_required == NULL) {
+               return( 0 );
+       }
+
        /* for each required attribute */
        for ( i = 0; oc->oc_required[i] != NULL; i++ ) {
                /* see if it's in the entry */
@@ -88,11 +91,25 @@ oc_check_required( Entry *e, char *ocname )
 
                /* not there => schema violation */
                if ( a == NULL ) {
-                       return( 1 );
+                       return oc->oc_required[i];
                }
        }
 
-       return( 0 );
+       return( NULL );
+}
+
+/*
+ * check to see if attribute is 'operational' or not.
+ * this function should be externalized...
+ */
+static int
+oc_check_operational( char *type )
+{
+       return ( strcasecmp( type, "modifiersname" ) == 0 ||
+               strcasecmp( type, "modifytimestamp" ) == 0 ||
+               strcasecmp( type, "creatorsname" ) == 0 ||
+               strcasecmp( type, "createtimestamp" ) == 0 )
+               ? 1 : 0;
 }
 
 static int
@@ -106,19 +123,25 @@ oc_check_allowed( char *type, struct berval **ocl )
                return( 0 );
        }
 
+       if ( oc_check_operational( type ) ) {
+               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->oc_required[j] != NULL; j++ ) {
+                       for ( j = 0; oc->oc_required != NULL && 
+                               oc->oc_required[j] != NULL; j++ ) {
                                if ( strcasecmp( oc->oc_required[j], type )
                                    == 0 ) {
                                        return( 0 );
                                }
                        }
                        /* does it allow the type? */
-                       for ( j = 0; oc->oc_allowed[j] != NULL; j++ ) {
+                       for ( j = 0; oc->oc_allowed != NULL && 
+                               oc->oc_allowed[j] != NULL; j++ ) {
                                if ( strcasecmp( oc->oc_allowed[j], type )
                                    == 0 || strcmp( oc->oc_allowed[j], "*" )
                                    == 0 )
@@ -154,7 +177,7 @@ oc_find( char *ocname )
 
 #ifdef LDAP_DEBUG
 
-static
+static void
 oc_print( struct objclass *oc )
 {
        int     i;