X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fschema_check.c;h=0cc09ddb0415aeaaee247e3bcd75e1a4600f79a6;hb=fbc6a7e8ac780fd421e057c34caa9d4ecb166807;hp=ac1986161be24c37062bf8e0da17fdc7770a7446;hpb=1aa829922f823f0463d7ce362e884f8adf72ff64;p=openldap diff --git a/servers/slapd/schema_check.c b/servers/slapd/schema_check.c index ac1986161b..0cc09ddb04 100644 --- a/servers/slapd/schema_check.c +++ b/servers/slapd/schema_check.c @@ -1,7 +1,7 @@ /* schema_check.c - routines to enforce schema definitions */ /* $OpenLDAP$ */ /* - * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ @@ -21,6 +21,10 @@ static char * oc_check_required( ObjectClass *oc, struct berval *ocname ); +static int entry_naming_check( + Entry *e, + const char** text, + char *textbuf, size_t textlen ); /* * entry_schema_check - check that entry e conforms to the schema required * by its object class(es). @@ -161,6 +165,23 @@ entry_schema_check( return LDAP_OTHER; } + if( sc->soc_obsolete ) { + snprintf( textbuf, textlen, + "structuralObjectClass '%s' is OBSOLETE", + asc->a_vals[0].bv_val ); + +#ifdef NEW_LOGGING + LDAP_LOG( OPERATION, INFO, + "entry_schema_check: dn (%s), %s\n", e->e_dn, textbuf, 0 ); +#else + Debug( LDAP_DEBUG_ANY, + "entry_check_schema(%s): %s\n", + e->e_dn, textbuf, 0 ); +#endif + + return LDAP_OBJECT_CLASS_VIOLATION; + } + /* find the object class attribute */ aoc = attr_find( e->e_attrs, ad_objectClass ); if ( aoc == NULL ) { @@ -195,11 +216,18 @@ entry_schema_check( } else if ( sc != oc ) { snprintf( textbuf, textlen, - "structural object class modification from '%s' to '%s' not allowed", + "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; } + /* naming check */ + rc = entry_naming_check( e, text, textbuf, textlen ); + if( rc != LDAP_SUCCESS ) { + return rc; + } + #ifdef SLAP_EXTENDED_SCHEMA /* find the content rule for the structural class */ cr = cr_find( sc->soc_oid ); @@ -208,8 +236,25 @@ entry_schema_check( assert( !cr || !strcmp( cr->scr_oid, sc->soc_oid ) ); /* check that the entry has required attrs of the content rule */ - if( cr && cr->scr_required ) { - for( i=0; cr->scr_required[i]; i++ ) { + if( cr ) { + if( cr->scr_obsolete ) { + snprintf( textbuf, textlen, + "content rule '%s' is obsolete", + ldap_contentrule2name( &cr->scr_crule )); + +#ifdef NEW_LOGGING + LDAP_LOG( OPERATION, INFO, + "entry_schema_check: dn=\"%s\" %s", e->e_dn, textbuf, 0 ); +#else + Debug( LDAP_DEBUG_ANY, + "Entry (%s): %s\n", + e->e_dn, textbuf, 0 ); +#endif + + return LDAP_OBJECT_CLASS_VIOLATION; + } + + if( cr->scr_required ) for( i=0; cr->scr_required[i]; i++ ) { at = cr->scr_required[i]; for ( a = e->e_attrs; a != NULL; a = a->a_next ) { @@ -237,10 +282,8 @@ entry_schema_check( return LDAP_OBJECT_CLASS_VIOLATION; } } - } - if( cr && cr->scr_precluded ) { - for( i=0; cr->scr_precluded[i]; i++ ) { + if( cr->scr_precluded ) for( i=0; cr->scr_precluded[i]; i++ ) { at = cr->scr_precluded[i]; for ( a = e->e_attrs; a != NULL; a = a->a_next ) { @@ -278,6 +321,24 @@ entry_schema_check( "unrecognized objectClass '%s'", aoc->a_vals[i].bv_val ); +#ifdef NEW_LOGGING + LDAP_LOG( OPERATION, INFO, + "entry_schema_check: dn (%s), %s\n", e->e_dn, textbuf, 0 ); +#else + Debug( LDAP_DEBUG_ANY, + "entry_check_schema(%s): %s\n", + e->e_dn, textbuf, 0 ); +#endif + + return LDAP_OBJECT_CLASS_VIOLATION; + } + + if ( oc->soc_obsolete ) { + /* disallow obsolete classes */ + snprintf( textbuf, textlen, + "objectClass '%s' is OBSOLETE", + aoc->a_vals[i].bv_val ); + #ifdef NEW_LOGGING LDAP_LOG( OPERATION, INFO, "entry_schema_check: dn (%s), %s\n", e->e_dn, textbuf, 0 ); @@ -687,7 +748,7 @@ int structural_class( } if( sc == NULL ) { - *text = "no structural object classes provided"; + *text = "no structural object class provided"; return LDAP_OBJECT_CLASS_VIOLATION; } @@ -740,3 +801,75 @@ int mods_structural_class( return structural_class( ocmod->sml_bvalues, sc, NULL, text, textbuf, textlen ); } + + +static int +entry_naming_check( + Entry *e, + const char** text, + char *textbuf, size_t textlen ) +{ + /* naming check */ + LDAPRDN *rdn = NULL; + const char *p = NULL; + ber_len_t cnt; + int rc = LDAP_SUCCESS; + + /* + * Get attribute type(s) and attribute value(s) of our RDN + */ + if ( ldap_bv2rdn( &e->e_name, &rdn, (char **)&p, + LDAP_DN_FORMAT_LDAP ) ) + { + *text = "unrecongized attribute type(s) in RDN"; + return LDAP_INVALID_DN_SYNTAX; + } + + /* Check that each AVA of the RDN is present in the entry */ + /* FIXME: Should also check that each AVA lists a distinct type */ + for ( cnt = 0; rdn[0][cnt]; cnt++ ) { + LDAPAVA *ava = rdn[0][cnt]; + AttributeDescription *desc = NULL; + Attribute *attr; + const char *errtext; + + rc = slap_bv2ad( &ava->la_attr, &desc, &errtext ); + if ( rc != LDAP_SUCCESS ) { + snprintf( textbuf, textlen, "%s (in RDN)", errtext ); + break; + } + + /* find the naming attribute */ + attr = attr_find( e->e_attrs, desc ); + if ( attr == NULL ) { + snprintf( textbuf, textlen, + "naming attribute '%s' is not present in entry", + ava->la_attr.bv_val ); + rc = LDAP_NAMING_VIOLATION; + break; + } + + if( ava->la_flags & LDAP_AVA_BINARY ) { + snprintf( textbuf, textlen, + "value of naming attribute '%s' in unsupported BER form", + ava->la_attr.bv_val ); + rc = LDAP_NAMING_VIOLATION; + } + + if ( value_find_ex( desc, + SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH, + attr->a_nvals, + &ava->la_value ) != 0 ) + { + snprintf( textbuf, textlen, + "value of naming attribute '%s' is not present in entry", + ava->la_attr.bv_val ); + rc = LDAP_NAMING_VIOLATION; + break; + } + } + + ldap_rdnfree( rdn ); + return rc; +} +