From 1d6c8d81572a00ce8d2c448cbb0d40d439c7ffeb Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Thu, 20 Dec 2001 00:34:36 +0000 Subject: [PATCH] Add better error reporting. Handle multiple SUP objectClasses. --- servers/slapd/add.c | 3 +- servers/slapd/modify.c | 8 +++-- servers/slapd/proto-slap.h | 29 +++++++++++------ servers/slapd/schema_check.c | 61 +++++++++++++++++++++++++++++------ servers/slapd/tools/slapadd.c | 11 ++++--- 5 files changed, 83 insertions(+), 29 deletions(-) diff --git a/servers/slapd/add.c b/servers/slapd/add.c index 679411fbcd..7ab3b8300e 100644 --- a/servers/slapd/add.c +++ b/servers/slapd/add.c @@ -266,7 +266,8 @@ do_add( Connection *conn, Operation *op ) 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 ); diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c index e23dfa8ce6..a04ba30012 100644 --- a/servers/slapd/modify.c +++ b/servers/slapd/modify.c @@ -348,8 +348,9 @@ do_modify( { /* 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, @@ -565,7 +566,8 @@ int slap_mods_opattrs( 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(); @@ -604,7 +606,7 @@ int slap_mods_opattrs( 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; } diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 708928d760..f2fe409f44 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -437,9 +437,9 @@ LDAP_SLAPD_F (int) lock_fclose LDAP_P(( FILE *fp, FILE *lfp )); * 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, @@ -452,7 +452,8 @@ LDAP_SLAPD_F( int ) slap_mods_opattrs( Operation *op, Modifications *mods, Modifications **modlist, - const char **text ); + const char **text, + char *textbuf, size_t textlen ); /* * module.c @@ -721,18 +722,26 @@ LDAP_SLAPD_F (int) is_entry_objectclass LDAP_P(( /* * 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 diff --git a/servers/slapd/schema_check.c b/servers/slapd/schema_check.c index 1f1ed839fe..aa3341d079 100644 --- a/servers/slapd/schema_check.c +++ b/servers/slapd/schema_check.c @@ -27,12 +27,13 @@ static char * oc_check_required( 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; @@ -41,7 +42,10 @@ int structural_class( 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; } @@ -51,15 +55,50 @@ int structural_class( 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; } @@ -73,7 +112,8 @@ int structural_class( int mods_structural_class( Modifications *mods, struct berval *sc, - const char **text ) + const char **text, + char *textbuf, size_t textlen ) { Modifications *ocmod = NULL; @@ -97,7 +137,8 @@ int mods_structural_class( return LDAP_OBJECT_CLASS_VIOLATION; } - return structural_class( ocmod->sml_bvalues, sc, text ); + return structural_class( ocmod->sml_bvalues, sc, + text, textbuf, textlen ); } /* @@ -233,7 +274,7 @@ entry_schema_check( 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 ) { diff --git a/servers/slapd/tools/slapadd.c b/servers/slapd/tools/slapadd.c index 099033ac3b..41c654bb91 100644 --- a/servers/slapd/tools/slapadd.c +++ b/servers/slapd/tools/slapadd.c @@ -27,6 +27,10 @@ main( int argc, char **argv ) 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 || @@ -112,9 +116,9 @@ main( int argc, char **argv ) 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", @@ -134,9 +138,6 @@ main( int argc, char **argv ) 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 ); -- 2.39.5