]> git.sur5r.net Git - openldap/commitdiff
Add structuralObjectClass support and a bit of const'ification
authorKurt Zeilenga <kurt@openldap.org>
Wed, 19 Dec 2001 22:08:24 +0000 (22:08 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Wed, 19 Dec 2001 22:08:24 +0000 (22:08 +0000)
servers/slapd/add.c
servers/slapd/modify.c
servers/slapd/mr.c
servers/slapd/proto-slap.h
servers/slapd/schema_check.c
servers/slapd/syntax.c

index 046ae393782cfbcad92f43974443f771a6f6d9a9..679411fbcd04e89cfdf4366eb5976c6563f6fa52 100644 (file)
@@ -266,7 +266,7 @@ do_add( Connection *conn, Operation *op )
                                        assert( (*modstail)->sml_op == LDAP_MOD_ADD );
                                        assert( (*modstail)->sml_desc != NULL );
                                }
-                               rc = slap_mods_opattrs( op, modstail, &text );
+                               rc = slap_mods_opattrs( op, mods, modstail, &text );
                                if( rc != LDAP_SUCCESS ) {
                                        send_ldap_result( conn, op, rc,
                                                NULL, text, NULL, NULL );
index 6c882c7ab568f01b33803a9177c367e4f2eb59da..e23dfa8ce67c77a5e55a02d724d66e5d2c940c2f 100644 (file)
@@ -348,7 +348,7 @@ do_modify(
                                {
                                        /* empty */
                                }
-                               rc = slap_mods_opattrs( op, modstail, &text );
+                               rc = slap_mods_opattrs( op, mods, modstail, &text );
 
                                if( rc != LDAP_SUCCESS ) {
                                        send_ldap_result( conn, op, rc,
@@ -563,6 +563,7 @@ int slap_modlist2mods(
 
 int slap_mods_opattrs(
        Operation *op,
+       Modifications *mods,
        Modifications **modtail,
        const char **text )
 {
@@ -599,17 +600,34 @@ int slap_mods_opattrs(
        }
 
        if( op->o_tag == LDAP_REQ_ADD ) {
-               struct berval uuid;
+               struct berval tmpval;
                char uuidbuf[40];
+               int rc;
 
-               uuid.bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ) );
-               uuid.bv_val = uuidbuf;
+               rc = mods_structural_class( mods, &tmpval, text );
+               if( rc != LDAP_SUCCESS ) {
+                       return rc;
+               }
+               if ( tmpval.bv_len ) {
+                       mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ) );
+                       mod->sml_op = mop;
+                       mod->sml_desc = slap_schema.si_ad_structuralObjectClass;
+                       mod->sml_bvalues = (struct berval **) malloc( 2 * sizeof( struct berval * ) );
+                       mod->sml_bvalues[0] = ber_bvdup( &tmpval );
+                       mod->sml_bvalues[1] = NULL;
+                       assert( mod->sml_bvalues[0] );
+                       *modtail = mod;
+                       modtail = &mod->sml_next;
+               }
+
+               tmpval.bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ) );
+               tmpval.bv_val = uuidbuf;
                
                mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ) );
                mod->sml_op = mop;
                mod->sml_desc = slap_schema.si_ad_entryUUID;
                mod->sml_bvalues = (struct berval **) malloc( 2 * sizeof( struct berval * ) );
-               mod->sml_bvalues[0] = ber_bvdup( &uuid );
+               mod->sml_bvalues[0] = ber_bvdup( &tmpval );
                mod->sml_bvalues[1] = NULL;
                assert( mod->sml_bvalues[0] );
                *modtail = mod;
index 2ec9ebcc15090d8222362c7e24578197eda60f74..52bdbe96eb252a759c0e66e12c63b11f72bad2e8 100644 (file)
@@ -165,7 +165,7 @@ mr_add(
 
 int
 register_matching_rule(
-       char * desc,
+       const char * desc,
        unsigned usage,
        slap_mr_convert_func *convert,
        slap_mr_normalize_func *normalize,
index 99129820101fbc7b072e2c008a87ae932667bf7d..708928d760b25a18b8c73988ee9daa98de10caac 100644 (file)
@@ -450,6 +450,7 @@ LDAP_SLAPD_F( int ) slap_modlist2mods(
 
 LDAP_SLAPD_F( int ) slap_mods_opattrs(
        Operation *op,
+       Modifications *mods,
        Modifications **modlist,
        const char **text );
 
@@ -693,14 +694,14 @@ LDAP_SLAPD_F (int) mr_add LDAP_P((LDAPMatchingRule *mr,
        const char **err));
 
 LDAP_SLAPD_F (int) register_syntax LDAP_P((
-       char *desc,
+       const char *desc,
        unsigned flags,
        slap_syntax_validate_func *validate,
        slap_syntax_transform_func *normalize,
        slap_syntax_transform_func *pretty ));
 
 LDAP_SLAPD_F (int) register_matching_rule LDAP_P((
-       char * desc,
+       const char * desc,
        unsigned usage,
        slap_mr_convert_func *convert,
        slap_mr_normalize_func *normalize,
@@ -727,6 +728,10 @@ LDAP_SLAPD_F (int) entry_schema_check LDAP_P((
        Entry *e, Attribute *attrs,
        const char** text,
        char *textbuf, size_t textlen ));
+LDAP_SLAPD_F (int) mods_structural_class LDAP_P((
+       Modifications *mods,
+       struct berval *oc,
+       const char** text ));
 
 
 /*
@@ -941,8 +946,6 @@ LDAP_SLAPD_F (int)  slap_startup LDAP_P(( Backend *be ));
 LDAP_SLAPD_F (int)     slap_shutdown LDAP_P(( Backend *be ));
 LDAP_SLAPD_F (int)     slap_destroy LDAP_P((void));
 
-struct sockaddr_in;
-
 LDAP_SLAPD_F (void) slapd_add_internal(ber_socket_t s);
 LDAP_SLAPD_F (int) slapd_daemon_init( const char *urls );
 LDAP_SLAPD_F (int) slapd_daemon_destroy(void);
index 87ba819c1d35e1a44a2d361067fe720855245234..d8ae713294edae9bfab29359f1b02eabc1cafe28 100644 (file)
 #include "slap.h"
 #include "ldap_pvt.h"
 
-static char *  oc_check_required(Entry *e, struct berval *ocname);
+static char * oc_check_required(
+       Entry *e,
+       ObjectClass *oc,
+       struct berval *ocname );
+
+/*
+ * Determine the structural object class from a set of OIDs
+ */
+static int structural_class(
+       struct berval **ocs,
+       struct berval *scbv,
+       const char **text )
+{
+       int i;
+       ObjectClass *oc;
+       ObjectClass *sc = NULL;
+       int scn = 0;
+
+       *text = "structural object error";
+       scbv->bv_len = 0;
+
+       for( i=0; ocs[i]; i++ ) {
+               oc = oc_find( ocs[i]->bv_val );
+
+               if( oc == NULL ) {
+                       *text = "unrecongized objectClass attribute";
+                       return LDAP_OBJECT_CLASS_VIOLATION;
+               }
+
+               if( oc->soc_kind == LDAP_SCHEMA_STRUCTURAL ) {
+                       if( sc == NULL || is_object_subclass( sc, oc ) ) {
+                               sc = oc;
+                               scn = i;
+
+                       } else if ( !is_object_subclass( oc, sc ) ) {
+                               /* FIXME: multiple inheritance possible! */
+                               *text = "invalid strucutural object class chain";
+                               return LDAP_OBJECT_CLASS_VIOLATION;
+                       }
+               }
+       }
+
+       if( sc == NULL ) {
+               *text = "no strucutural object classes";
+               return LDAP_OBJECT_CLASS_VIOLATION;
+       }
+
+       *scbv = *ocs[scn];
+       return LDAP_SUCCESS;
+}
+
+/*
+ * Return structural object class from list of modifications
+ */
+int mods_structural_class(
+       Modifications *mods,
+       struct berval *sc,
+       const char **text )
+{
+       Modifications *ocmod = NULL;
+
+       for( ; mods != NULL; mods = mods->sml_next ) {
+               if( mods->sml_desc == slap_schema.si_ad_objectClass ) {
+                       if( ocmod != NULL ) {
+                               *text = "entry has multiple objectClass attributes";
+                               return LDAP_OBJECT_CLASS_VIOLATION;
+                       }
+                       ocmod = mods;
+               }
+       }
+
+       if( ocmod == NULL ) {
+               *text = "entry has no objectClass attribute";
+               return LDAP_OBJECT_CLASS_VIOLATION;
+       }
+
+       if( ocmod->sml_bvalues == NULL || ocmod->sml_bvalues[0] == NULL ) {
+               *text = "objectClass attribute has no values";
+               return LDAP_OBJECT_CLASS_VIOLATION;
+       }
+
+       return structural_class( ocmod->sml_bvalues, sc, text );
+}
 
 /*
  * entry_schema_check - check that entry e conforms to the schema required
@@ -27,13 +109,18 @@ static char *      oc_check_required(Entry *e, struct berval *ocname);
 
 int
 entry_schema_check( 
-       Entry *e, Attribute *oldattrs, const char** text,
+       Entry *e, Attribute *oldattrs,
+       const char** text,
        char *textbuf, size_t textlen )
 {
-       Attribute       *a, *aoc;
-       ObjectClass *oc;
-       int             i;
-       AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass;
+       Attribute       *a, *asc, *aoc;
+       ObjectClass *sc, *oc;
+       int     rc, i;
+       struct berval nsc;
+       AttributeDescription *ad_structuralObjectClass
+               = slap_schema.si_ad_structuralObjectClass;
+       AttributeDescription *ad_objectClass
+               = slap_schema.si_ad_objectClass;
        int extensible = 0;
 
        *text = textbuf;
@@ -70,11 +157,72 @@ entry_schema_check(
 
        if( !global_schemacheck ) return LDAP_SUCCESS;
 
+#if 1
        /* find the object class attribute - could error out here */
-       if ( (aoc = attr_find( e->e_attrs, ad_objectClass )) == NULL ) {
+       asc = attr_find( e->e_attrs, ad_structuralObjectClass );
+       if ( asc == NULL ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "schema", LDAP_LEVEL_INFO, "entry_schema_check: "
+                       "No structuralObjectClass for entry (%s)\n",
+                       e->e_dn ));
+#else
+               Debug( LDAP_DEBUG_ANY,
+                       "No structuralObjectClass for entry (%s)\n",
+                   e->e_dn, 0, 0 );
+#endif
+
+               *text = "no structuralObjectClass operational attribute";
+               return LDAP_OBJECT_CLASS_VIOLATION;
+       }
+
+       assert( asc->a_vals != NULL );
+       assert( asc->a_vals[0] != NULL );
+       assert( asc->a_vals[1] == NULL );
+
+       sc = oc_find( asc->a_vals[0]->bv_val );
+       if( sc == NULL ) {
+               snprintf( textbuf, textlen, 
+                       "unrecognized structuralObjectClass '%s'",
+                       aoc->a_vals[0]->bv_val );
+
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "schema", LDAP_LEVEL_INFO,
+                       "entry_schema_check: dn (%s), %s\n",
+                       e->e_dn, textbuf ));
+#else
+               Debug( LDAP_DEBUG_ANY,
+                       "entry_check_schema(%s): %s\n",
+                       e->e_dn, textbuf, 0 );
+#endif
+
+               return LDAP_OBJECT_CLASS_VIOLATION;
+       }
+
+       if( sc->soc_kind != LDAP_SCHEMA_STRUCTURAL ) {
+               snprintf( textbuf, textlen, 
+                       "structuralObjectClass '%s' is not STRUCTURAL",
+                       aoc->a_vals[0]->bv_val );
+
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "schema", LDAP_LEVEL_INFO,
+                       "entry_schema_check: dn (%s), %s\n",
+                       e->e_dn, textbuf ));
+#else
+               Debug( LDAP_DEBUG_ANY,
+                       "entry_check_schema(%s): %s\n",
+                       e->e_dn, textbuf, 0 );
+#endif
+
+               return LDAP_OBJECT_CLASS_VIOLATION;
+       }
+#endif
+
+       /* find the object class attribute */
+       aoc = attr_find( e->e_attrs, ad_objectClass );
+       if ( aoc == NULL ) {
 #ifdef NEW_LOGGING
                LDAP_LOG(( "schema", LDAP_LEVEL_INFO,
-                          "entry_schema_check: No objectClass for entry (%s).\n", e->e_dn ));
+                       "entry_schema_check: No objectClass for entry (%s).\n", e->e_dn ));
 #else
                Debug( LDAP_DEBUG_ANY, "No objectClass for entry (%s)\n",
                    e->e_dn, 0, 0 );
@@ -84,6 +232,30 @@ entry_schema_check(
                return LDAP_OBJECT_CLASS_VIOLATION;
        }
 
+       assert( aoc->a_vals != NULL );
+       assert( aoc->a_vals[0] != NULL );
+
+       rc = structural_class( aoc->a_vals, &nsc, text );
+       if( rc != LDAP_SUCCESS ) {
+               return rc;
+       } else if ( nsc.bv_len == 0 ) {
+               return LDAP_OBJECT_CLASS_VIOLATION;
+       }
+
+       oc = oc_find( nsc.bv_val );
+       if ( oc == NULL ) {
+               snprintf( textbuf, textlen, 
+                       "unrecognized objectClass '%s'",
+                       aoc->a_vals[i]->bv_val );
+               return LDAP_OBJECT_CLASS_VIOLATION;
+
+       } else if ( sc != oc ) {
+               snprintf( textbuf, textlen, 
+                       "structuralObjectClass modification from '%s' to '%s' not allowed",
+                       asc->a_vals[0]->bv_val, nsc.bv_val );
+               return LDAP_NO_OBJECT_CLASS_MODS;
+       }
+
        /* 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 ) {
@@ -103,8 +275,16 @@ entry_schema_check(
 
                        return LDAP_OBJECT_CLASS_VIOLATION;
 
+               } else if ( oc->soc_kind == LDAP_SCHEMA_ABSTRACT ) {
+                       /* object class is abstract */
+                       /* FIXME: need to check that is is a superclass of something */
+
+               } else if ( oc->soc_kind == LDAP_SCHEMA_STRUCTURAL && oc != sc ) {
+                       /* object class is a superclass of the structural class */
+                       /* nothing in particular to check */
+
                } else {
-                       char *s = oc_check_required( e, aoc->a_vals[i] );
+                       char *s = oc_check_required( e, oc, aoc->a_vals[i] );
 
                        if (s != NULL) {
                                snprintf( textbuf, textlen, 
@@ -127,7 +307,6 @@ entry_schema_check(
                        if( oc == slap_schema.si_oc_extensibleObject ) {
                                extensible=1;
                        }
-
                }
        }
 
@@ -163,29 +342,26 @@ entry_schema_check(
 }
 
 static char *
-oc_check_required( Entry *e, struct berval *ocname )
+oc_check_required(
+       Entry *e,
+       ObjectClass *oc,
+       struct berval *ocname )
 {
-       ObjectClass     *oc;
        AttributeType   *at;
        int             i;
        Attribute       *a;
 
 #ifdef NEW_LOGGING
        LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
-                  "oc_check_required: dn (%s), objectClass \"%s\"\n",
-                  e->e_dn, ocname->bv_val ));
+               "oc_check_required: dn (%s), objectClass \"%s\"\n",
+       e->e_dn, ocname->bv_val ));
 #else
        Debug( LDAP_DEBUG_TRACE,
-              "oc_check_required entry (%s), objectClass \"%s\"\n",
-              e->e_dn, ocname->bv_val, 0 );
+               "oc_check_required entry (%s), objectClass \"%s\"\n",
+               e->e_dn, ocname->bv_val, 0 );
 #endif
 
 
-       /* find global oc defn. it we don't know about it assume it's ok */
-       if ( (oc = oc_find( ocname->bv_val )) == NULL ) {
-               return NULL;
-       }
-
        /* check for empty oc_required */
        if(oc->soc_required == NULL) {
                return NULL;
@@ -218,7 +394,7 @@ int oc_check_allowed(
 
 #ifdef NEW_LOGGING
        LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
-                  "oc_check_allowed: type \"%s\"\n", at->sat_cname.bv_val ));
+               "oc_check_allowed: type \"%s\"\n", at->sat_cname.bv_val ));
 #else
        Debug( LDAP_DEBUG_TRACE,
                "oc_check_allowed type \"%s\"\n",
index 25ca0258ff2e2f176ff9ee52ae34ed83086f9cf0..78bddd3276f7e6e8f2a83cda1de046f21bd458f4 100644 (file)
@@ -36,7 +36,7 @@ syn_index_cmp(
 
 static int
 syn_index_name_cmp(
-    char               *name,
+    const char         *name,
     struct sindexrec   *sir
 )
 {
@@ -150,7 +150,7 @@ syn_add(
 
 int
 register_syntax(
-       char * desc,
+       const char * desc,
        unsigned flags,
        slap_syntax_validate_func *validate,
        slap_syntax_transform_func *normalize,