]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
Avoid unnecessary calls to oc_bvfind
authorHoward Chu <hyc@openldap.org>
Mon, 27 Nov 2006 19:59:59 +0000 (19:59 +0000)
committerHoward Chu <hyc@openldap.org>
Mon, 27 Nov 2006 19:59:59 +0000 (19:59 +0000)
18 files changed:
servers/slapd/aclparse.c
servers/slapd/add.c
servers/slapd/back-bdb/add.c
servers/slapd/back-bdb/modify.c
servers/slapd/back-ldif/ldif.c
servers/slapd/back-monitor/log.c
servers/slapd/back-sql/add.c
servers/slapd/back-sql/entry-id.c
servers/slapd/back-sql/modify.c
servers/slapd/back-sql/modrdn.c
servers/slapd/bconfig.c
servers/slapd/modify.c
servers/slapd/proto-slap.h
servers/slapd/schema_check.c
servers/slapd/schema_prep.c
servers/slapd/slapadd.c
servers/slapd/slapi/slapi_pblock.c
servers/slapd/slapi/slapi_utils.c

index 48ec0cd7437d5959d54a0b5474773b46c6383633..d5bdf1b6e1839f374875b4d6221ca00dfc546f57 100644 (file)
@@ -1270,13 +1270,13 @@ parse_acl(
 
                                        {
                                                int rc;
-                                               struct berval vals[2];
+                                               ObjectClass *ocs[2];
 
-                                               ber_str2bv( b->a_group_oc->soc_oid, 0, 0, &vals[0] );
-                                               BER_BVZERO( &vals[1] );
+                                               ocs[0] = b->a_group_oc;
+                                               ocs[1] = NULL;
 
                                                rc = oc_check_allowed( b->a_group_at->ad_type,
-                                                       vals, NULL );
+                                                       ocs, NULL );
 
                                                if( rc != 0 ) {
                                                        char    buf[ SLAP_TEXT_BUFLEN ];
index d39af385a25c1021487e6078e522ce2dcc51f730..bacbe232a3a174d07288a0f6cbbd3e40830a3aa2 100644 (file)
@@ -631,30 +631,6 @@ int slap_add_opattrs(
        char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
        Attribute *a;
 
-       a = attr_find( op->ora_e->e_attrs,
-               slap_schema.si_ad_structuralObjectClass );
-
-       if ( !a ) {
-               Attribute *oc;
-               int rc;
-
-               oc = attr_find( op->ora_e->e_attrs, slap_schema.si_ad_objectClass );
-               if ( oc ) {
-                       rc = structural_class( oc->a_vals, &tmp, NULL, text,
-                               textbuf, textlen );
-                       if( rc == LDAP_SUCCESS ) {
-                               attr_merge_one( op->ora_e,
-                                       slap_schema.si_ad_structuralObjectClass,
-                                       &tmp, NULL );
-
-                       } else if ( !SLAP_NO_SCHEMA_CHECK( op->o_bd ) &&
-                               !get_no_schema_check( op ) )
-                       {
-                               return rc;
-                       }
-               }
-       }
-
        if ( SLAP_LASTMOD( op->o_bd ) ) {
                char *ptr;
                int gotcsn = 0;
index ecd1b4e0a3c60f4d381d259c4de7371ad6de958a..a705c4a9fdb00efc19f3d2d053358ac7079b0080 100644 (file)
@@ -91,22 +91,23 @@ txnReturn:
 
        ctrls[num_ctrls] = 0;
 
-       /* add opattrs to shadow as well, only missing attrs will actually
-        * be added; helps compatibility with older OL versions */
-       rs->sr_err = slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 );
+
+       /* check entry's schema */
+       rs->sr_err = entry_schema_check( op, op->oq_add.rs_e, NULL,
+               get_relax(op), 1, &rs->sr_text, textbuf, textlen );
        if ( rs->sr_err != LDAP_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_add) ": entry failed op attrs add: "
+                       LDAP_XSTRING(bdb_add) ": entry failed schema check: "
                        "%s (%d)\n", rs->sr_text, rs->sr_err, 0 );
                goto return_results;
        }
 
-       /* check entry's schema */
-       rs->sr_err = entry_schema_check( op, op->oq_add.rs_e, NULL,
-               get_relax(op), &rs->sr_text, textbuf, textlen );
+       /* add opattrs to shadow as well, only missing attrs will actually
+        * be added; helps compatibility with older OL versions */
+       rs->sr_err = slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 );
        if ( rs->sr_err != LDAP_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_add) ": entry failed schema check: "
+                       LDAP_XSTRING(bdb_add) ": entry failed op attrs add: "
                        "%s (%d)\n", rs->sr_text, rs->sr_err, 0 );
                goto return_results;
        }
index 6e4f4c4dc66feaa72232b1c604e55fa2d7ca78ac..89c3bf5f5f96115e74ef5ab9786994e6975d06ba 100644 (file)
@@ -205,7 +205,7 @@ int bdb_modify_internal(
        }
 
        /* check that the entry still obeys the schema */
-       rc = entry_schema_check( op, e, save_attrs, get_relax(op),
+       rc = entry_schema_check( op, e, save_attrs, get_relax(op), 0,
                text, textbuf, textlen );
        if ( rc != LDAP_SUCCESS || op->o_noop ) {
                attrs_free( e->e_attrs );
index 59bc846ad1e5bbca8acac17441a148cc96e8f0c4..79a4b636f3654411ea259508c3d4a14df5c009a8 100644 (file)
@@ -582,7 +582,7 @@ static int apply_modify_to_entry(Entry * entry,
                        entry->e_ocflags = 0;
                }
                /* check that the entry still obeys the schema */
-               rc = entry_schema_check( op, entry, NULL, 0,
+               rc = entry_schema_check( op, entry, NULL, 0, 0,
                          &rs->sr_text, textbuf, sizeof( textbuf ) );
        }
 
@@ -792,14 +792,14 @@ static int ldif_back_add(Operation *op, SlapReply *rs) {
 
        Debug( LDAP_DEBUG_TRACE, "ldif_back_add: \"%s\"\n", dn.bv_val, 0, 0);
 
+       rs->sr_err = entry_schema_check(op, e, NULL, 0, 1,
+               &rs->sr_text, textbuf, sizeof( textbuf ) );
+       if ( rs->sr_err != LDAP_SUCCESS ) goto send_res;
+
        rs->sr_err = slap_add_opattrs( op,
                &rs->sr_text, textbuf, sizeof( textbuf ), 1 );
        if ( rs->sr_err != LDAP_SUCCESS ) goto send_res;
 
-       rs->sr_err = entry_schema_check(op, e, NULL, 0,
-               &rs->sr_text, textbuf, sizeof( textbuf ) );
-       if ( rs->sr_err != LDAP_SUCCESS ) goto send_res;
-                               
        ldap_pvt_thread_rdwr_wlock(&ni->li_rdwr);
 
        dn2path(&dn, &op->o_bd->be_nsuffix[0], &ni->li_base_path, &leaf_path);
index 6b74d7115e8471d0e1f28a42dd8dbfee9406b9fc..5683460eb1a88ed7ce4aceb414c73a2bc920e669 100644 (file)
@@ -181,7 +181,7 @@ monitor_subsys_log_modify(
                }
 
                /* check that the entry still obeys the schema */
-               rc = entry_schema_check( op, e, save_attrs, 0,
+               rc = entry_schema_check( op, e, save_attrs, 0, 0,
                        &text, textbuf, sizeof( textbuf ) );
                if ( rc != LDAP_SUCCESS ) {
                        rs->sr_err = rc;
index eb24f67b928cd61e29a50932023c521973690df6..ad64fc4372464afb2d095af2917a149e392491ae 100644 (file)
@@ -957,13 +957,11 @@ backsql_add( Operation *op, SlapReply *rs )
        Debug( LDAP_DEBUG_TRACE, "==>backsql_add(\"%s\")\n",
                        op->ora_e->e_name.bv_val, 0, 0 );
 
-       slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 );
-
        /* check schema */
        if ( BACKSQL_CHECK_SCHEMA( bi ) ) {
                char            textbuf[ SLAP_TEXT_BUFLEN ] = { '\0' };
 
-               rs->sr_err = entry_schema_check( op, op->ora_e, NULL, 0,
+               rs->sr_err = entry_schema_check( op, op->ora_e, NULL, 0, 1,
                        &rs->sr_text, textbuf, sizeof( textbuf ) );
                if ( rs->sr_err != LDAP_SUCCESS ) {
                        Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
@@ -974,6 +972,8 @@ backsql_add( Operation *op, SlapReply *rs )
                }
        }
 
+       slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 );
+
        /* search structuralObjectClass */
        for ( at = op->ora_e->e_attrs; at != NULL; at = at->a_next ) {
                if ( at->a_desc == slap_schema.si_ad_structuralObjectClass ) {
@@ -1003,7 +1003,7 @@ backsql_add( Operation *op, SlapReply *rs )
                }
 
                rs->sr_err = structural_class( at->a_vals, &scname, NULL,
-                               &text, buf, sizeof( buf ) );
+                               &text, buf, sizeof( buf ), op->o_tmpmemctx );
                if ( rs->sr_err != LDAP_SUCCESS ) {
                        Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
                                "%s (%d)\n",
index d381fe3a29c2ffedf9e376428bba0c9cbbd76987..dc073eaa23e79b0225516c4830aa2f9acfd418c4 100644 (file)
@@ -1021,7 +1021,7 @@ next:;
                        }
 
                        rc = structural_class( nvals, &soc, NULL, 
-                                       &text, textbuf, textlen );
+                                       &text, textbuf, textlen, op->o_tmpmemctx );
                        if ( rc != LDAP_SUCCESS ) {
                                Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(%s): "
                                        "structural_class() failed %d (%s)\n",
index df1c95341e5f8fc77cdfd148abaf5c5c081c62ac..82b69e8fab85725b0b949069ba134fe684d9d576 100644 (file)
@@ -152,10 +152,10 @@ backsql_modify( Operation *op, SlapReply *rs )
                        goto do_transact;
                }
 
-               rs->sr_err = entry_schema_check( op, &m, NULL, 0,
+               rs->sr_err = entry_schema_check( op, &m, NULL, 0, 0,
                        &rs->sr_text, textbuf, sizeof( textbuf ) );
                if ( rs->sr_err != LDAP_SUCCESS ) {
-                       Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
+                       Debug( LDAP_DEBUG_TRACE, "   backsql_modify(\"%s\"): "
                                "entry failed schema check -- aborting\n",
                                m.e_name.bv_val, 0, 0 );
                        e = NULL;
index 67940a58ba881d3e649c0ffc6a2ca950bc595729..1e452019b7128ebc9034524095c0a8c16b25997b 100644 (file)
@@ -452,10 +452,10 @@ backsql_modrdn( Operation *op, SlapReply *rs )
 
                e_id = bsi.bsi_base_id;
 
-               rs->sr_err = entry_schema_check( op, &r, NULL, 0,
+               rs->sr_err = entry_schema_check( op, &r, NULL, 0, 0,
                        &rs->sr_text, textbuf, sizeof( textbuf ) );
                if ( rs->sr_err != LDAP_SUCCESS ) {
-                       Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
+                       Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(\"%s\"): "
                                "entry failed schema check -- aborting\n",
                                r.e_name.bv_val, 0, 0 );
                        e = NULL;
index e8fa653bfdb082dedd97908d362582dc1d8c4e89..180f941d58e825f64eb7da1c4052efd3a04e842f 100644 (file)
@@ -4243,7 +4243,7 @@ config_modify_internal( CfEntryInfo *ce, Operation *op, SlapReply *rs,
        
        if(rc == LDAP_SUCCESS) {
                /* check that the entry still obeys the schema */
-               rc = entry_schema_check(op, e, NULL, 0,
+               rc = entry_schema_check(op, e, NULL, 0, 0,
                        &rs->sr_text, ca->msg, sizeof(ca->msg) );
        }
        if ( rc == LDAP_SUCCESS ) {
@@ -4646,10 +4646,10 @@ config_build_entry( Operation *op, SlapReply *rs, CfEntryInfo *parent,
        }
 
        oc_at = attr_find( e->e_attrs, slap_schema.si_ad_objectClass );
-       rc = structural_class(oc_at->a_vals, &val, NULL, &text, c->msg,
-               sizeof(c->msg));
-       attr_merge_normalize_one(e, slap_schema.si_ad_structuralObjectClass, &val, NULL );
-       if ( op ) {
+       rc = structural_class(oc_at->a_vals, &oc, NULL, &text, c->msg,
+               sizeof(c->msg), op->o_tmpmemctx );
+       attr_merge_normalize_one(e, slap_schema.si_ad_structuralObjectClass, &oc->soc_cname, NULL );
+       if ( !op->o_noop ) {
                op->ora_e = e;
                op->o_bd->be_add( op, rs );
                if ( ( rs->sr_err != LDAP_SUCCESS ) 
@@ -4881,18 +4881,18 @@ config_back_db_open( BackendDB *be )
                return config_check_schema( cfb );
        }
 
-       if ( cfb->cb_use_ldif ) {
-               thrctx = ldap_pvt_thread_pool_context();
-               op = (Operation *) &opbuf;
-               connection_fake_init( &conn, op, thrctx );
+       thrctx = ldap_pvt_thread_pool_context();
+       op = (Operation *) &opbuf;
+       connection_fake_init( &conn, op, thrctx );
 
-               op->o_tag = LDAP_REQ_ADD;
-               op->o_callback = &cb;
-               op->o_bd = &cfb->cb_db;
-               op->o_dn = op->o_bd->be_rootdn;
-               op->o_ndn = op->o_bd->be_rootndn;
-       } else {
-               op = NULL;
+       op->o_tag = LDAP_REQ_ADD;
+       op->o_callback = &cb;
+       op->o_bd = &cfb->cb_db;
+       op->o_dn = op->o_bd->be_rootdn;
+       op->o_ndn = op->o_bd->be_rootndn;
+
+       if ( !cfb->cb_use_ldif ) {
+               op->o_noop = 1;
        }
 
        /* create root of tree */
index cb91b3015eb4fbe77c36b2ca64d77217eb2572ac..826219c4c09e05b3110f9f53da6621371dd6af9a 100644 (file)
@@ -810,6 +810,8 @@ int slap_mods_check(
 #endif /* PRESERVE_ORDER */
 
                                        cv = ml->sml_nvalues ? ml->sml_nvalues : ml->sml_values;
+                                       if ( ad == slap_schema.si_ad_objectClass )
+                                               mr = NULL;      /* shortcut matching */
 
                                        /* record indices to preserve input ordering */
                                        ix = slap_sl_malloc( nvals * sizeof(int), ctx );
index f674f4cc6da8f5c2078e7f17f8928d9692cb98aa..5a8e0dc2d9728cb106810d9da3f87dcf914e2f45 100644 (file)
@@ -1515,21 +1515,22 @@ LDAP_SLAPD_F (int) schema_info LDAP_P(( Entry **entry, const char **text ));
  */
 LDAP_SLAPD_F( int ) oc_check_allowed(
        AttributeType *type,
-       BerVarray oclist,
+       ObjectClass **socs,
        ObjectClass *sc );
 
 LDAP_SLAPD_F( int ) structural_class(
        BerVarray ocs,
-       struct berval *scbv,
        ObjectClass **sc,
+       ObjectClass ***socs,
        const char **text,
-       char *textbuf, size_t textlen );
+       char *textbuf, size_t textlen, void *ctx );
 
 LDAP_SLAPD_F( int ) entry_schema_check(
        Operation *op,
        Entry *e,
        Attribute *attrs,
        int manage,
+       int add_soc,
        const char** text,
        char *textbuf, size_t textlen );
 
@@ -1537,7 +1538,7 @@ LDAP_SLAPD_F( int ) mods_structural_class(
        Modifications *mods,
        struct berval *oc,
        const char** text,
-       char *textbuf, size_t textlen );
+       char *textbuf, size_t textlen, void *ctx );
 
 /*
  * schema_init.c
index bf6b75a8ca21f9382b4818df1bcbe3bb840a2035..7a9448a13ee595b800e33cfbd0570242d6ec788e 100644 (file)
@@ -47,15 +47,15 @@ entry_schema_check(
        Entry *e,
        Attribute *oldattrs,
        int manage,
+       int add_soc,
        const char** text,
        char *textbuf, size_t textlen )
 {
-       Attribute       *a, *asc, *aoc;
-       ObjectClass *sc, *oc;
+       Attribute       *a, *asc = NULL, *aoc = NULL;
+       ObjectClass *sc, *oc, **socs = NULL;
        AttributeType *at;
        ContentRule *cr;
        int     rc, i;
-       struct berval nsc;
        AttributeDescription *ad_structuralObjectClass
                = slap_schema.si_ad_structuralObjectClass;
        AttributeDescription *ad_objectClass
@@ -87,13 +87,18 @@ entry_schema_check(
                assert( a->a_vals[0].bv_val != NULL ); 
 
                if( a->a_desc->ad_type->sat_check ) {
-                       int rc = (a->a_desc->ad_type->sat_check)(
+                       rc = (a->a_desc->ad_type->sat_check)(
                                op->o_bd, e, a, text, textbuf, textlen );
                        if( rc != LDAP_SUCCESS ) {
                                return rc;
                        }
                }
 
+               if( a->a_desc == ad_structuralObjectClass )
+                       asc = a;
+               else if ( a->a_desc == ad_objectClass )
+                       aoc = a;
+
                if( !collectiveSubentry && is_at_collective( a->a_desc->ad_type ) ) {
                        snprintf( textbuf, textlen,
                                "'%s' can only appear in collectiveAttributeSubentry",
@@ -117,9 +122,20 @@ entry_schema_check(
                }
        }
 
-       /* find the structural object class attribute */
-       asc = attr_find( e->e_attrs, ad_structuralObjectClass );
-       if ( asc == NULL ) {
+       /* check the object class attribute */
+       if ( aoc == NULL ) {
+               Debug( LDAP_DEBUG_ANY, "No objectClass for entry (%s)\n",
+                   e->e_dn, 0, 0 );
+
+               *text = "no objectClass attribute";
+               return LDAP_OBJECT_CLASS_VIOLATION;
+       }
+
+       assert( aoc->a_vals != NULL );
+       assert( aoc->a_vals[0].bv_val != NULL );
+
+       /* check the structural object class attribute */
+       if ( asc == NULL && !add_soc ) {
                Debug( LDAP_DEBUG_ANY,
                        "No structuralObjectClass for entry (%s)\n",
                    e->e_dn, 0, 0 );
@@ -128,6 +144,19 @@ entry_schema_check(
                return LDAP_OTHER;
        }
 
+       rc = structural_class( aoc->a_vals, &oc, &socs, text, textbuf, textlen,
+               op->o_tmpmemctx );
+       if( rc != LDAP_SUCCESS ) {
+               return rc;
+       }
+
+       if ( asc == NULL && add_soc ) {
+               attr_merge_one( e, ad_structuralObjectClass, &oc->soc_cname, NULL );
+               asc = attr_find( e->e_attrs, ad_structuralObjectClass );
+               sc = oc;
+               goto got_soc;
+       }
+
        assert( asc->a_vals != NULL );
        assert( asc->a_vals[0].bv_val != NULL );
        assert( asc->a_vals[1].bv_val == NULL );
@@ -157,6 +186,7 @@ entry_schema_check(
                return LDAP_OTHER;
        }
 
+got_soc:
        if( !manage && sc->soc_obsolete ) {
                snprintf( textbuf, textlen, 
                        "structuralObjectClass '%s' is OBSOLETE",
@@ -169,47 +199,31 @@ entry_schema_check(
                return LDAP_OBJECT_CLASS_VIOLATION;
        }
 
-       /* find the object class attribute */
-       aoc = attr_find( e->e_attrs, ad_objectClass );
-       if ( aoc == NULL ) {
-               Debug( LDAP_DEBUG_ANY, "No objectClass for entry (%s)\n",
-                   e->e_dn, 0, 0 );
-
-               *text = "no objectClass attribute";
-               return LDAP_OBJECT_CLASS_VIOLATION;
-       }
-
-       assert( aoc->a_vals != NULL );
-       assert( aoc->a_vals[0].bv_val != NULL );
-
-       rc = structural_class( aoc->a_vals, &nsc, &oc, text, textbuf, textlen );
-       if( rc != LDAP_SUCCESS ) {
-               return rc;
-       }
-
        *text = textbuf;
 
        if ( oc == NULL ) {
                snprintf( textbuf, textlen, 
                        "unrecognized objectClass '%s'",
                        aoc->a_vals[0].bv_val );
-               return LDAP_OBJECT_CLASS_VIOLATION;
+               rc = LDAP_OBJECT_CLASS_VIOLATION;
+               goto leave;
 
        } else if ( sc != slap_schema.si_oc_glue && sc != oc ) {
                snprintf( textbuf, textlen, 
                        "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;
+                       asc->a_vals[0].bv_val, oc->soc_cname.bv_val );
+               rc = LDAP_NO_OBJECT_CLASS_MODS;
+               goto leave;
        } else if ( sc == slap_schema.si_oc_glue ) {
                sc = oc;
        }
 
        /* naming check */
-       if ( !is_entry_objectclass ( e, slap_schema.si_oc_glue, 0 ) ) {
+       if ( !is_entry_glue ( e ) ) {
                rc = entry_naming_check( e, manage, text, textbuf, textlen );
                if( rc != LDAP_SUCCESS ) {
-                       return rc;
+                       goto leave;
                }
        } else {
                /* Glue Entry */
@@ -232,7 +246,8 @@ entry_schema_check(
                                "Entry (%s): %s\n",
                                e->e_dn, textbuf, 0 );
 
-                       return LDAP_OBJECT_CLASS_VIOLATION;
+                       rc = LDAP_OBJECT_CLASS_VIOLATION;
+                       goto leave;
                }
 
                if( cr->scr_required ) for( i=0; cr->scr_required[i]; i++ ) {
@@ -255,7 +270,8 @@ entry_schema_check(
                                        "Entry (%s): %s\n",
                                        e->e_dn, textbuf, 0 );
 
-                               return LDAP_OBJECT_CLASS_VIOLATION;
+                               rc = LDAP_OBJECT_CLASS_VIOLATION;
+                               goto leave;
                        }
                }
 
@@ -279,25 +295,15 @@ entry_schema_check(
                                        "Entry (%s): %s\n",
                                        e->e_dn, textbuf, 0 );
 
-                               return LDAP_OBJECT_CLASS_VIOLATION;
+                               rc = LDAP_OBJECT_CLASS_VIOLATION;
+                               goto leave;
                        }
                }
        }
 
        /* 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 ) {
-                       snprintf( textbuf, textlen, 
-                               "unrecognized objectClass '%s'",
-                               aoc->a_vals[i].bv_val );
-
-                       Debug( LDAP_DEBUG_ANY,
-                               "entry_check_schema(%s): %s\n",
-                               e->e_dn, textbuf, 0 );
-
-                       return LDAP_OBJECT_CLASS_VIOLATION;
-               }
-
+       for ( i = 0; socs[i]; i++ ) {
+               oc = socs[i];
                if ( !manage && oc->soc_obsolete ) {
                        /* disallow obsolete classes */
                        snprintf( textbuf, textlen, 
@@ -308,14 +314,15 @@ entry_schema_check(
                                "entry_check_schema(%s): %s\n",
                                e->e_dn, textbuf, 0 );
 
-                       return LDAP_OBJECT_CLASS_VIOLATION;
+                       rc = LDAP_OBJECT_CLASS_VIOLATION;
+                       goto leave;
                }
 
                if ( oc->soc_check ) {
-                       int rc = (oc->soc_check)( op->o_bd, e, oc,
+                       rc = (oc->soc_check)( op->o_bd, e, oc,
                                text, textbuf, textlen );
                        if( rc != LDAP_SUCCESS ) {
-                               return rc;
+                               goto leave;
                        }
                }
 
@@ -326,20 +333,9 @@ entry_schema_check(
                        {
                                int j;
                                ObjectClass *xc = NULL;
-                               for( j=0; aoc->a_vals[j].bv_val; j++ ) {
+                               for( j=0; socs[j]; j++ ) {
                                        if( i != j ) {
-                                               xc = oc_bvfind( &aoc->a_vals[i] );
-                                               if( xc == NULL ) {
-                                                       snprintf( textbuf, textlen, 
-                                                               "unrecognized objectClass '%s'",
-                                                               aoc->a_vals[i].bv_val );
-
-                                                       Debug( LDAP_DEBUG_ANY,
-                                                               "entry_check_schema(%s): %s\n",
-                                                               e->e_dn, textbuf, 0 );
-
-                                                       return LDAP_OBJECT_CLASS_VIOLATION;
-                                               }
+                                               xc = socs[j];
 
                                                /* since we previous check against the
                                                 * structural object of this entry, the
@@ -365,7 +361,8 @@ entry_schema_check(
                                                "entry_check_schema(%s): %s\n",
                                                e->e_dn, textbuf, 0 );
 
-                                       return LDAP_OBJECT_CLASS_VIOLATION;
+                                       rc = LDAP_OBJECT_CLASS_VIOLATION;
+                                       goto leave;
                                }
                        }
 
@@ -403,7 +400,8 @@ entry_schema_check(
                                                "Entry (%s): %s\n",
                                                e->e_dn, textbuf, 0 );
 
-                                       return LDAP_OBJECT_CLASS_VIOLATION;
+                                       rc = LDAP_OBJECT_CLASS_VIOLATION;
+                                       goto leave;
                                }
                        }
 
@@ -417,7 +415,8 @@ entry_schema_check(
                                        "Entry (%s): %s\n",
                                        e->e_dn, textbuf, 0 );
 
-                               return LDAP_OBJECT_CLASS_VIOLATION;
+                               rc = LDAP_OBJECT_CLASS_VIOLATION;
+                               goto leave;
                        }
 
                        if( oc == slap_schema.si_oc_extensibleObject ) {
@@ -428,39 +427,38 @@ entry_schema_check(
 
        if( extensible ) {
                *text = NULL;
-               return LDAP_SUCCESS;
+               rc = LDAP_SUCCESS;
+               goto leave;
        }
 
        /* 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;
-
-               ret = LDAP_OBJECT_CLASS_VIOLATION;
+               rc = 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;
+                                       rc = LDAP_SUCCESS;
                                        break;
                                }
                        }
                }
 
-               if( ret != LDAP_SUCCESS && cr && cr->scr_allowed ) {
+               if( rc != 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;
+                                       rc = LDAP_SUCCESS;
                                        break;
                                }
                        }
                }
 
-               if( ret != LDAP_SUCCESS ) 
+               if( rc != LDAP_SUCCESS ) 
                {
-                       ret = oc_check_allowed( a->a_desc->ad_type, aoc->a_vals, sc );
+                       rc = oc_check_allowed( a->a_desc->ad_type, socs, sc );
                }
 
-               if ( ret != LDAP_SUCCESS ) {
+               if ( rc != LDAP_SUCCESS ) {
                        char *type = a->a_desc->ad_cname.bv_val;
 
                        snprintf( textbuf, textlen, 
@@ -471,12 +469,14 @@ entry_schema_check(
                            "Entry (%s), %s\n",
                            e->e_dn, textbuf, 0 );
 
-                       return ret;
+                       goto leave;
                }
        }
 
        *text = NULL;
-       return LDAP_SUCCESS;
+leave:
+       slap_sl_free( socs, op->o_tmpmemctx );
+       return rc;
 }
 
 static char *
@@ -519,7 +519,7 @@ oc_check_required(
 
 int oc_check_allowed(
        AttributeType *at,
-       BerVarray ocl,
+       ObjectClass **socs,
        ObjectClass *sc )
 {
        int             i, j;
@@ -562,9 +562,9 @@ int oc_check_allowed(
        }
 
        /* check that the type appears as req or opt in at least one oc */
-       for ( i = 0; ocl[i].bv_val != NULL; i++ ) {
+       for ( i = 0; socs[i]; i++ ) {
                /* if we know about the oc */
-               ObjectClass     *oc = oc_bvfind( &ocl[i] );
+               ObjectClass     *oc = socs[i];
                if ( oc != NULL && oc->soc_kind != LDAP_SCHEMA_ABSTRACT &&
                        ( sc == NULL || oc->soc_kind == LDAP_SCHEMA_AUXILIARY ))
                {
@@ -596,30 +596,40 @@ int oc_check_allowed(
  */
 int structural_class(
        BerVarray ocs,
-       struct berval *scbv,
        ObjectClass **scp,
+       ObjectClass ***socsp,
        const char **text,
-       char *textbuf, size_t textlen )
+       char *textbuf, size_t textlen,
+       void *ctx )
 {
-       int i;
-       ObjectClass *oc;
+       int i, nocs;
+       ObjectClass *oc, **socs;
        ObjectClass *sc = NULL;
        int scn = -1;
 
        *text = "structural_class: internal error";
-       scbv->bv_len = 0;
+
+       /* count them */
+       for( i=0; ocs[i].bv_val; i++ ) ;
+       nocs = i;
+       
+       socs = slap_sl_malloc( (nocs+1) * sizeof(ObjectClass *), ctx );
 
        for( i=0; ocs[i].bv_val; i++ ) {
-               oc = oc_bvfind( &ocs[i] );
+               socs[i] = oc_bvfind( &ocs[i] );
 
-               if( oc == NULL ) {
+               if( socs[i] == NULL ) {
                        snprintf( textbuf, textlen,
                                "unrecognized objectClass '%s'",
                                ocs[i].bv_val );
                        *text = textbuf;
-                       return LDAP_OBJECT_CLASS_VIOLATION;
+                       goto fail;
                }
+       }
+       socs[i] = NULL;
 
+       for( i=0; ocs[i].bv_val; i++ ) {
+               oc = socs[i];
                if( oc->soc_kind == LDAP_SCHEMA_STRUCTURAL ) {
                        if( sc == NULL || is_object_subclass( sc, oc ) ) {
                                sc = oc;
@@ -631,14 +641,14 @@ int structural_class(
 
                                /* find common superior */
                                for( j=i+1; ocs[j].bv_val; j++ ) {
-                                       xc = oc_bvfind( &ocs[j] );
+                                       xc = socs[j];
 
                                        if( xc == NULL ) {
                                                snprintf( textbuf, textlen,
                                                        "unrecognized objectClass '%s'",
                                                        ocs[j].bv_val );
                                                *text = textbuf;
-                                               return LDAP_OBJECT_CLASS_VIOLATION;
+                                               goto fail;
                                        }
 
                                        if( xc->soc_kind != LDAP_SCHEMA_STRUCTURAL ) {
@@ -662,7 +672,7 @@ int structural_class(
                                                "invalid structural object class chain (%s/%s)",
                                                ocs[scn].bv_val, ocs[i].bv_val );
                                        *text = textbuf;
-                                       return LDAP_OBJECT_CLASS_VIOLATION;
+                                       goto fail;
                                }
                        }
                }
@@ -674,24 +684,26 @@ int structural_class(
 
        if( sc == NULL ) {
                *text = "no structural object class provided";
-               return LDAP_OBJECT_CLASS_VIOLATION;
+               goto fail;
        }
 
        if( scn < 0 ) {
                *text = "invalid structural object class";
-               return LDAP_OBJECT_CLASS_VIOLATION;
+               goto fail;
        }
 
-       *scbv = ocs[scn];
-
-       if( scbv->bv_len == 0 ) {
-               *text = "invalid structural object class";
-               return LDAP_OBJECT_CLASS_VIOLATION;
+       if ( socsp ) {
+               *socsp = socs;
+       } else {
+               slap_sl_free( socs, ctx );
        }
-
        *text = NULL;
 
        return LDAP_SUCCESS;
+
+fail:
+       slap_sl_free( socs, ctx );
+       return LDAP_OBJECT_CLASS_VIOLATION;
 }
 
 /*
@@ -701,9 +713,11 @@ int mods_structural_class(
        Modifications *mods,
        struct berval *sc,
        const char **text,
-       char *textbuf, size_t textlen )
+       char *textbuf, size_t textlen, void *ctx )
 {
        Modifications *ocmod = NULL;
+       ObjectClass *ssc;
+       int rc;
 
        for( ; mods != NULL; mods = mods->sml_next ) {
                if( mods->sml_desc == slap_schema.si_ad_objectClass ) {
@@ -725,8 +739,11 @@ int mods_structural_class(
                return LDAP_OBJECT_CLASS_VIOLATION;
        }
 
-       return structural_class( ocmod->sml_values, sc, NULL,
-               text, textbuf, textlen );
+       rc = structural_class( ocmod->sml_values, &ssc, NULL,
+               text, textbuf, textlen, ctx );
+       if ( rc == LDAP_SUCCESS )
+               *sc = ssc->soc_cname;
+       return rc;
 }
 
 
index 5bc607d3f17d4bd8e3b1aae482b1d4f10d28ed66..568f9980c77a07e8f6df3c5d6b0ab9db6beeeb1d 100644 (file)
@@ -250,31 +250,24 @@ static int objectSubClassIndexer(
 {
        int rc, noc, i;
        BerVarray ocvalues;
+       ObjectClass **socs;
        
        for( noc=0; values[noc].bv_val != NULL; noc++ ) {
                /* just count em */;
        }
 
        /* over allocate */
-       ocvalues = slap_sl_malloc( sizeof( struct berval ) * (noc+16), ctx );
+       socs = slap_sl_malloc( (noc+16) * sizeof( ObjectClass * ), ctx );
 
-       /* copy listed values (and termination) */
+       /* initialize */
        for( i=0; i<noc; i++ ) {
-               ObjectClass *oc = oc_bvfind( &values[i] );
-               if( oc ) {
-                       ocvalues[i] = oc->soc_cname;
-               } else {
-                       ocvalues[i] = values[i];
-               }
+               socs[i] = oc_bvfind( &values[i] );
        }
 
-       ocvalues[i].bv_val = NULL;
-       ocvalues[i].bv_len = 0;
-
        /* expand values */
        for( i=0; i<noc; i++ ) {
                int j;
-               ObjectClass *oc = oc_bvfind( &ocvalues[i] );
+               ObjectClass *oc = socs[i];
                if( oc == NULL || oc->soc_sups == NULL ) continue;
                
                for( j=0; oc->soc_sups[j] != NULL; j++ ) {
@@ -283,35 +276,37 @@ static int objectSubClassIndexer(
                        int k;
 
                        for( k=0; k<noc; k++ ) {
-                               if( bvmatch( &ocvalues[k], &sup->soc_cname ) ) {
+                               if( sup == socs[k] ) {
                                        found++;
                                        break;
                                }
                        }
 
                        if( !found ) {
-                               ocvalues = slap_sl_realloc( ocvalues,
-                                       sizeof( struct berval ) * (noc+2), ctx );
+                               socs = slap_sl_realloc( socs,
+                                       sizeof( ObjectClass * ) * (noc+2), ctx );
 
                                assert( k == noc );
-
-                               ocvalues[noc] = sup->soc_cname;
-
-                               assert( ocvalues[noc].bv_val != NULL );
-                               assert( ocvalues[noc].bv_len != 0 );
-
-                               noc++;
-
-                               ocvalues[noc].bv_len = 0;
-                               ocvalues[noc].bv_val = NULL;
+                               socs[noc++] = sup;
                        }
                }
        }
 
+       ocvalues = slap_sl_malloc( sizeof( struct berval ) * (noc+1), ctx );
+       /* copy values */
+       for( i=0; i<noc; i++ ) {
+               if ( socs[i] )
+                       ocvalues[i] = socs[i]->soc_cname;
+               else
+                       ocvalues[i] = values[i];
+       }
+       BER_BVZERO( &ocvalues[i] );
+
        rc = octetStringIndexer( use, mask, syntax, mr,
                prefix, ocvalues, keysp, ctx );
 
        slap_sl_free( ocvalues, ctx );
+       slap_sl_free( socs, ctx );
        return rc;
 }
 
index 6a01077dae327813f45dcb482c4aafadb0acf54b..898f0347a1c1e14c37543ec0acaed3040aa3b944 100644 (file)
@@ -71,6 +71,7 @@ slapadd( int argc, char **argv )
 
        memset( &opbuf, 0, sizeof(opbuf) );
        op = (Operation *) &opbuf;
+       op->o_hdr = (Opheader *)(op+1);
 
        if( !be->be_entry_open ||
                !be->be_entry_close ||
@@ -163,8 +164,6 @@ slapadd( int argc, char **argv )
                }
 
                {
-                       Attribute *sc = attr_find( e->e_attrs,
-                               slap_schema.si_ad_structuralObjectClass );
                        Attribute *oc = attr_find( e->e_attrs,
                                slap_schema.si_ad_objectClass );
 
@@ -178,30 +177,11 @@ slapadd( int argc, char **argv )
                                break;
                        }
 
-                       if( sc == NULL ) {
-                               struct berval val;
-
-                               rc = structural_class( oc->a_vals, &val,
-                                       NULL, &text, textbuf, textlen );
-
-                               if( rc != LDAP_SUCCESS ) {
-                                       fprintf( stderr, "%s: dn=\"%s\" (line=%d): (%d) %s\n",
-                                               progname, e->e_dn, lineno, rc, text );
-                                       rc = EXIT_FAILURE;
-                                       entry_free( e );
-                                       if( continuemode ) continue;
-                                       break;
-                               }
-
-                               attr_merge_one( e, slap_schema.si_ad_structuralObjectClass,
-                                       &val, NULL );
-                       }
-
                        /* check schema */
                        op->o_bd = be;
 
                        if ( (slapMode & SLAP_TOOL_NO_SCHEMA_CHECK) == 0) {
-                               rc = entry_schema_check( op, e, NULL, manage,
+                               rc = entry_schema_check( op, e, NULL, manage, 1,
                                        &text, textbuf, textlen );
 
                                if( rc != LDAP_SUCCESS ) {
index bdf0e167ea5b3bd0a2ddbdb8c85695220b68a449..30fd74292cf17cb28cc1c644c91d2e3376064b00 100644 (file)
@@ -497,7 +497,8 @@ pblock_get( Slapi_PBlock *pb, int param, void **value )
 
                        rc = mods_structural_class( pb->pb_op->ora_modlist,
                                &tmpval, &pb->pb_rs->sr_text,
-                               pb->pb_textbuf, sizeof( pb->pb_textbuf ));
+                               pb->pb_textbuf, sizeof( pb->pb_textbuf ),
+                               pb->pb_op->o_tmpmemctx );
                        *((char **)value) = tmpval.bv_val;
                } else {
                        rc = PBLOCK_ERROR;
index 3a0939ff43a16e0f9e493a8265579ec387d3c006..ac618cf50d8b8fe068cb0757c50da7bd99fa0c84 100644 (file)
@@ -3118,7 +3118,7 @@ int slapi_entry_schema_check( Slapi_PBlock *pb, Slapi_Entry *e )
 
        pb->pb_op->o_bd = select_backend( &e->e_nname, 0, 0 );
        if ( pb->pb_op->o_bd != NULL ) {
-               rc = entry_schema_check( pb->pb_op, e, NULL, 0,
+               rc = entry_schema_check( pb->pb_op, e, NULL, 0, 0,
                        &text, textbuf, textlen );
        }
        pb->pb_op->o_bd = be_orig;