From 1aa829922f823f0463d7ce362e884f8adf72ff64 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Wed, 9 Oct 2002 23:02:01 +0000 Subject: [PATCH] Implement content rule checks w/ implicit default rules allowing any auxiliary class to be mixed in --- servers/slapd/schema_check.c | 149 ++++++++++++++++++++++++++++++++++- servers/slapd/slap.h | 4 + 2 files changed, 150 insertions(+), 3 deletions(-) diff --git a/servers/slapd/schema_check.c b/servers/slapd/schema_check.c index 0412bb4f20..ac1986161b 100644 --- a/servers/slapd/schema_check.c +++ b/servers/slapd/schema_check.c @@ -38,6 +38,10 @@ entry_schema_check( { Attribute *a, *asc, *aoc; ObjectClass *sc, *oc; +#ifdef SLAP_EXTENDED_SCHEMA + AttributeType *at; + ContentRule *cr; +#endif int rc, i; struct berval nsc; AttributeDescription *ad_structuralObjectClass @@ -48,7 +52,9 @@ entry_schema_check( int subentry = is_entry_subentry( e ); int collectiveSubentry = 0; - if( subentry) collectiveSubentry = is_entry_collectiveAttributeSubentry( e ); + if( subentry ) { + collectiveSubentry = is_entry_collectiveAttributeSubentry( e ); + } *text = textbuf; @@ -194,6 +200,77 @@ entry_schema_check( return LDAP_NO_OBJECT_CLASS_MODS; } +#ifdef SLAP_EXTENDED_SCHEMA + /* find the content rule for the structural class */ + cr = cr_find( sc->soc_oid ); + + /* the cr must be same as the structural class */ + 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++ ) { + at = cr->scr_required[i]; + + for ( a = e->e_attrs; a != NULL; a = a->a_next ) { + if( a->a_desc->ad_type == at ) { + break; + } + } + + /* not there => schema violation */ + if ( a == NULL ) { + snprintf( textbuf, textlen, + "content rule '%s' requires attribute '%s'", + ldap_contentrule2name( &cr->scr_crule ), + at->sat_cname.bv_val ); + +#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 && 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 ) { + if( a->a_desc->ad_type == at ) { + break; + } + } + + /* there => schema violation */ + if ( a != NULL ) { + snprintf( textbuf, textlen, + "content rule '%s' precluded attribute '%s'", + ldap_contentrule2name( &cr->scr_crule ), + at->sat_cname.bv_val ); + +#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; + } + } + } +#endif /* SLAP_EXTENDED_SCHEMA */ + /* 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 ) { @@ -284,8 +361,46 @@ entry_schema_check( } } else if ( oc->soc_kind != LDAP_SCHEMA_STRUCTURAL || oc == sc ) { - char *s = oc_check_required( e, oc, &aoc->a_vals[i] ); + char *s; + +#ifdef SLAP_EXTENDED_SCHEMA + if( oc->soc_kind == LDAP_SCHEMA_AUXILIARY ) { + int k=0; + if( cr ) { + if( cr->scr_auxiliaries ) { + for( ; cr->scr_auxiliaries[k]; k++ ) { + if( cr->scr_auxiliaries[k] == oc ) { + k=-1; + break; + } + } + } + } else if ( global_disallows & SLAP_DISALLOW_AUX_WO_CR ) { + k=-1; + } + + if( k == -1 ) { + snprintf( textbuf, textlen, + "content rule '%s' does not allow class '%s'", + ldap_contentrule2name( &cr->scr_crule ), + oc->soc_cname.bv_val ); + +#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; + } + } +#endif /* SLAP_EXTENDED_SCHEMA */ + s = oc_check_required( e, oc, &aoc->a_vals[i] ); if (s != NULL) { snprintf( textbuf, textlen, "object class '%s' requires attribute '%s'", @@ -315,7 +430,35 @@ entry_schema_check( /* 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 = oc_check_allowed( a->a_desc->ad_type, aoc->a_vals, sc ); + int ret; + +#ifdef SLAP_EXTENDED_SCHEMA + ret = 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; + break; + } + } + } + + if( ret != 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; + break; + } + } + } + + if( ret != LDAP_SUCCESS ) +#endif /* SLAP_EXTENDED_SCHEMA */ + { + ret = oc_check_allowed( a->a_desc->ad_type, aoc->a_vals, sc ); + } + if ( ret != LDAP_SUCCESS ) { char *type = a->a_desc->ad_cname.bv_val; diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index ea0d985d3a..df6b9abe18 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -35,6 +35,8 @@ #include "ldap_pvt_thread.h" #include "ldap_queue.h" +#define SLAP_EXTENDED_SCHEMA 1 + LDAP_BEGIN_DECL /* * SLAPD Memory allocation macros @@ -1270,6 +1272,8 @@ struct slap_backend_db { #define SLAP_DISALLOW_TLS_2_ANON 0x0010U /* StartTLS -> Anonymous */ #define SLAP_DISALLOW_TLS_AUTHC 0x0020U /* TLS while authenticated */ +#define SLAP_DISALLOW_AUX_WO_CR 0x4000U + slap_mask_t be_requires; /* pre-operation requirements */ #define SLAP_REQUIRE_BIND 0x0001U /* bind before op */ #define SLAP_REQUIRE_LDAP_V3 0x0002U /* LDAPv3 before op */ -- 2.39.2