Add structuralObjectClass support and a bit of const'ification

This commit is contained in:
Kurt Zeilenga 2001-12-19 22:08:24 +00:00
parent c90b4fc878
commit 49d16c4dce
6 changed files with 232 additions and 35 deletions

View 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 );

View 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;

View 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,

View 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);

View File

@ -16,7 +16,89 @@
#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: No objectClass for entry (%s).\n", e->e_dn ));
"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 ));
#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",

View 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,