Commit 2a9afa55 authored by Howard Chu's avatar Howard Chu
Browse files

Avoid unnecessary calls to oc_bvfind

parent 37111836
......@@ -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 ];
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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 );
......
......@@ -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);
......
......@@ -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;
......
......@@ -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",
......
......@@ -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",
......
......@@ -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;
......
......@@ -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;
......
......@@ -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 */
......
......@@ -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 );
......
......@@ -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
......
......@@ -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 )
<