Handle multiple SUP objectClasses.
assert( (*modstail)->sml_op == LDAP_MOD_ADD );
assert( (*modstail)->sml_desc != NULL );
}
- rc = slap_mods_opattrs( op, mods, modstail, &text );
+ rc = slap_mods_opattrs( op, mods, modstail, &text,
+ &textbuf, textlen );
if( rc != LDAP_SUCCESS ) {
send_ldap_result( conn, op, rc,
NULL, text, NULL, NULL );
{
/* empty */
}
- rc = slap_mods_opattrs( op, mods, modstail, &text );
+ rc = slap_mods_opattrs( op, mods, modstail, &text,
+ textbuf, textlen );
if( rc != LDAP_SUCCESS ) {
send_ldap_result( conn, op, rc,
NULL, text,
Operation *op,
Modifications *mods,
Modifications **modtail,
- const char **text )
+ const char **text,
+ char *textbuf, size_t textlen )
{
struct berval name, timestamp, csn;
time_t now = slap_get_time();
char uuidbuf[40];
int rc;
- rc = mods_structural_class( mods, &tmpval, text );
+ rc = mods_structural_class( mods, &tmpval, text, textbuf, textlen );
if( rc != LDAP_SUCCESS ) {
return rc;
}
* modify.c
* should be relocated to separate file
*/
-LDAP_SLAPD_F( void ) slap_mod_free LDAP_P(( Modification *mod, int freeit ));
-LDAP_SLAPD_F( void ) slap_mods_free LDAP_P(( Modifications *mods ));
-LDAP_SLAPD_F( void ) slap_modlist_free LDAP_P(( LDAPModList *ml ));
+LDAP_SLAPD_F( void ) slap_mod_free( Modification *mod, int freeit );
+LDAP_SLAPD_F( void ) slap_mods_free( Modifications *mods );
+LDAP_SLAPD_F( void ) slap_modlist_free( LDAPModList *ml );
LDAP_SLAPD_F( int ) slap_modlist2mods(
LDAPModList *ml,
Operation *op,
Modifications *mods,
Modifications **modlist,
- const char **text );
+ const char **text,
+ char *textbuf, size_t textlen );
/*
* module.c
/*
* schema_check.c
*/
-int oc_check_allowed(
+LDAP_SLAPD_F( int ) oc_check_allowed(
AttributeType *type,
struct berval **oclist );
-LDAP_SLAPD_F (int) entry_schema_check LDAP_P((
+
+LDAP_SLAPD_F( int ) structural_class(
+ struct berval **ocs,
+ struct berval *scbv,
+ const char **text,
+ char *textbuf, size_t textlen );
+
+LDAP_SLAPD_F( int ) entry_schema_check(
Entry *e, Attribute *attrs,
const char** text,
- char *textbuf, size_t textlen ));
-LDAP_SLAPD_F (int) mods_structural_class LDAP_P((
+ char *textbuf, size_t textlen );
+
+LDAP_SLAPD_F( int ) mods_structural_class(
Modifications *mods,
struct berval *oc,
- const char** text ));
-
+ const char** text,
+ char *textbuf, size_t textlen );
/*
* schema_init.c
int structural_class(
struct berval **ocs,
struct berval *scbv,
- const char **text )
+ const char **text,
+ char *textbuf, size_t textlen )
{
int i;
ObjectClass *oc;
ObjectClass *sc = NULL;
- int scn = 0;
+ int scn = -1;
*text = "structural_class: internal error";
scbv->bv_len = 0;
oc = oc_find( ocs[i]->bv_val );
if( oc == NULL ) {
- *text = "unrecongized objectClass attribute";
+ snprintf( textbuf, textlen,
+ "unrecongized objectClass '%s'",
+ ocs[i]->bv_val );
+ *text = textbuf;
return LDAP_OBJECT_CLASS_VIOLATION;
}
scn = i;
} else if ( !is_object_subclass( oc, sc ) ) {
- /* FIXME: multiple inheritance possible! */
- *text = "invalid strucutural object class chain";
- return LDAP_OBJECT_CLASS_VIOLATION;
+ int j;
+ ObjectClass *xc = NULL;
+
+ /* find common superior */
+ for( j=i+1; ocs[j]; j++ ) {
+ xc = oc_find( ocs[j]->bv_val );
+
+ if( xc == NULL ) {
+ snprintf( textbuf, textlen,
+ "unrecongized objectClass '%s'",
+ ocs[i]->bv_val );
+ *text = textbuf;
+ return LDAP_OBJECT_CLASS_VIOLATION;
+ }
+
+ if( xc->soc_kind != LDAP_SCHEMA_STRUCTURAL ) {
+ xc = NULL;
+ continue;
+ }
+
+ if( is_object_subclass( sc, xc ) &&
+ is_object_subclass( oc, xc ) )
+ {
+ /* found common subclass */
+ break;
+ }
+
+ xc = NULL;
+ }
+
+ if( xc == NULL ) {
+ /* no common subclass */
+ snprintf( textbuf, textlen,
+ "invalid structural object class chain (%s/%s)",
+ ocs[scn]->bv_val, ocs[i]->bv_val );
+ *text = textbuf;
+ return LDAP_OBJECT_CLASS_VIOLATION;
+ }
}
}
}
if( sc == NULL ) {
- *text = "no strucutural object classes";
+ *text = "no structural object classes provided";
return LDAP_OBJECT_CLASS_VIOLATION;
}
int mods_structural_class(
Modifications *mods,
struct berval *sc,
- const char **text )
+ const char **text,
+ char *textbuf, size_t textlen )
{
Modifications *ocmod = NULL;
return LDAP_OBJECT_CLASS_VIOLATION;
}
- return structural_class( ocmod->sml_bvalues, sc, text );
+ return structural_class( ocmod->sml_bvalues, sc,
+ text, textbuf, textlen );
}
/*
assert( aoc->a_vals != NULL );
assert( aoc->a_vals[0] != NULL );
- rc = structural_class( aoc->a_vals, &nsc, text );
+ rc = structural_class( aoc->a_vals, &nsc, text, textbuf, textlen );
if( rc != LDAP_SUCCESS ) {
return rc;
} else if ( nsc.bv_len == 0 ) {
int lmax;
int rc = EXIT_SUCCESS;
+ const char *text;
+ char textbuf[SLAP_TEXT_BUFLEN];
+ size_t textlen = sizeof textbuf;
+
slap_tool_init( "slapadd", SLAPADD, argc, argv );
if( !be->be_entry_open ||
if( sc == NULL ) {
struct berval *vals[2];
struct berval scbv;
- const char *text;
+
int ret = structural_class(
- oc->a_vals, &scbv, &text );
+ oc->a_vals, &scbv, &text, textbuf, textlen );
if( scbv.bv_len == 0 ) {
fprintf( stderr, "%s: dn=\"%s\" (line=%d): %s\n",
if( global_schemacheck ) {
/* check schema */
- const char *text;
- char textbuf[SLAP_TEXT_BUFLEN];
- size_t textlen = sizeof textbuf;
rc = entry_schema_check( e, NULL, &text, textbuf, textlen );