Back to index

openldap  2.4.31
Functions
schema_check.c File Reference
#include "portable.h"
#include <stdio.h>
#include <ac/ctype.h>
#include <ac/string.h>
#include <ac/socket.h>
#include "slap.h"

Go to the source code of this file.

Functions

static char * oc_check_required (Entry *e, ObjectClass *oc, struct berval *ocname)
static int entry_naming_check (Entry *e, int manage, int add_naming, const char **text, char *textbuf, size_t textlen)
int entry_schema_check (Operation *op, Entry *e, Attribute *oldattrs, int manage, int add, Attribute **socp, const char **text, char *textbuf, size_t textlen)
int oc_check_allowed (AttributeType *at, ObjectClass **socs, ObjectClass *sc)
int structural_class (BerVarray ocs, ObjectClass **scp, ObjectClass ***socsp, const char **text, char *textbuf, size_t textlen, void *ctx)
int mods_structural_class (Modifications *mods, struct berval *sc, const char **text, char *textbuf, size_t textlen, void *ctx)

Function Documentation

static int entry_naming_check ( Entry e,
int  manage,
int  add_naming,
const char **  text,
char *  textbuf,
size_t  textlen 
) [static]

Definition at line 777 of file schema_check.c.

{
       /* naming check */
       LDAPRDN              rdn = NULL;
       const char    *p = NULL;
       ber_len_t     cnt;
       int           rc = LDAP_SUCCESS;

       if ( BER_BVISEMPTY( &e->e_name )) {
              return 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 = "unrecognized 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[cnt]; cnt++ ) {
              LDAPAVA *ava = rdn[cnt];
              AttributeDescription *desc = NULL;
              Attribute *attr;
              const char *errtext;
              int add = 0;

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

              rc = slap_bv2ad( &ava->la_attr, &desc, &errtext );
              if ( rc != LDAP_SUCCESS ) {
                     snprintf( textbuf, textlen, "%s (in RDN)", errtext );
                     break;
              }

              if( desc->ad_type->sat_usage ) {
                     snprintf( textbuf, textlen, 
                            "naming attribute '%s' is operational",
                            ava->la_attr.bv_val );
                     rc = LDAP_NAMING_VIOLATION;
                     break;
              }
 
              if( desc->ad_type->sat_collective ) {
                     snprintf( textbuf, textlen, 
                            "naming attribute '%s' is collective",
                            ava->la_attr.bv_val );
                     rc = LDAP_NAMING_VIOLATION;
                     break;
              }

              if( !manage && desc->ad_type->sat_obsolete ) {
                     snprintf( textbuf, textlen, 
                            "naming attribute '%s' is obsolete",
                            ava->la_attr.bv_val );
                     rc = LDAP_NAMING_VIOLATION;
                     break;
              }

              if( !desc->ad_type->sat_equality ) {
                     snprintf( textbuf, textlen, 
                            "naming attribute '%s' has no equality matching rule",
                            ava->la_attr.bv_val );
                     rc = LDAP_NAMING_VIOLATION;
                     break;
              }

              if( !desc->ad_type->sat_equality->smr_match ) {
                     snprintf( textbuf, textlen, 
                            "naming attribute '%s' has unsupported equality matching rule",
                            ava->la_attr.bv_val );
                     rc = LDAP_NAMING_VIOLATION;
                     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 );
                     if ( add_naming ) {
                            add = 1;

                     } else {
                            rc = LDAP_NAMING_VIOLATION;
                     }

              } else {
                     rc = attr_valfind( attr, SLAP_MR_VALUE_OF_ASSERTION_SYNTAX|
                            SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH,
                            &ava->la_value, NULL, NULL );

                     if ( rc != 0 ) {
                            switch( rc ) {
                            case LDAP_INAPPROPRIATE_MATCHING:
                                   snprintf( textbuf, textlen, 
                                          "inappropriate matching for naming attribute '%s'",
                                          ava->la_attr.bv_val );
                                   break;
                            case LDAP_INVALID_SYNTAX:
                                   snprintf( textbuf, textlen, 
                                          "value of naming attribute '%s' is invalid",
                                          ava->la_attr.bv_val );
                                   break;
                            case LDAP_NO_SUCH_ATTRIBUTE:
                                   if ( add_naming ) {
                                          if ( is_at_single_value( desc->ad_type ) ) {
                                                 snprintf( textbuf, textlen, 
                                                        "value of single-valued naming attribute '%s' conflicts with value present in entry",
                                                        ava->la_attr.bv_val );

                                          } else {
                                                 add = 1;
                                                 rc = LDAP_SUCCESS;
                                          }

                                   } else {
                                          snprintf( textbuf, textlen, 
                                                 "value of naming attribute '%s' is not present in entry",
                                                 ava->la_attr.bv_val );
                                   }
                                   break;
                            default:
                                   snprintf( textbuf, textlen, 
                                          "naming attribute '%s' is inappropriate",
                                          ava->la_attr.bv_val );
                            }

                            if ( !add ) {
                                   rc = LDAP_NAMING_VIOLATION;
                            }
                     }
              }

              if ( add ) {
                     attr_merge_normalize_one( e, desc, &ava->la_value, NULL );

              } else if ( rc != LDAP_SUCCESS ) {
                     break;
              }
       }

       ldap_rdnfree( rdn );
       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int entry_schema_check ( Operation op,
Entry e,
Attribute oldattrs,
int  manage,
int  add,
Attribute **  socp,
const char **  text,
char *  textbuf,
size_t  textlen 
)

Definition at line 46 of file schema_check.c.

{
       Attribute     *a, *asc = NULL, *aoc = NULL;
       ObjectClass *sc, *oc, **socs = NULL;
       AttributeType *at;
       ContentRule *cr;
       int    rc, i;
       AttributeDescription *ad_structuralObjectClass
              = slap_schema.si_ad_structuralObjectClass;
       AttributeDescription *ad_objectClass
              = slap_schema.si_ad_objectClass;
       int extensible = 0;
       int subentry = is_entry_subentry( e );
       int collectiveSubentry = 0;

       if ( SLAP_NO_SCHEMA_CHECK( op->o_bd )) {
              return LDAP_SUCCESS;
       }

       if ( get_no_schema_check( op ) ) {
              return LDAP_SUCCESS;
       }

       if( subentry ) {
              collectiveSubentry = is_entry_collectiveAttributeSubentry( e );
       }

       *text = textbuf;

       /* misc attribute checks */
       for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
              const char *type = a->a_desc->ad_cname.bv_val;

              /* there should be at least one value */
              assert( a->a_vals != NULL );
              assert( a->a_vals[0].bv_val != NULL ); 

              if( a->a_desc->ad_type->sat_check ) {
                     rc = (a->a_desc->ad_type->sat_check)(
                            op->o_bd, e, a, text, textbuf, textlen );
                     if( rc != LDAP_SUCCESS ) {
                            return rc;
                     }
              }

              if( a->a_desc == ad_structuralObjectClass )
                     asc = a;
              else if ( a->a_desc == ad_objectClass )
                     aoc = a;

              if( !collectiveSubentry && is_at_collective( a->a_desc->ad_type ) ) {
                     snprintf( textbuf, textlen,
                            "'%s' can only appear in collectiveAttributeSubentry",
                            type );
                     return LDAP_OBJECT_CLASS_VIOLATION;
              }

              /* if single value type, check for multiple values */
              if( is_at_single_value( a->a_desc->ad_type ) &&
                     a->a_vals[1].bv_val != NULL )
              {
                     snprintf( textbuf, textlen, 
                            "attribute '%s' cannot have multiple values",
                            type );

                     Debug( LDAP_DEBUG_ANY,
                         "Entry (%s), %s\n",
                         e->e_dn, textbuf, 0 );

                     return LDAP_CONSTRAINT_VIOLATION;
              }
       }

       /* check the object class attribute */
       if ( aoc == NULL ) {
              Debug( LDAP_DEBUG_ANY, "No objectClass for entry (%s)\n",
                  e->e_dn, 0, 0 );

              *text = "no objectClass attribute";
              return LDAP_OBJECT_CLASS_VIOLATION;
       }

       assert( aoc->a_vals != NULL );
       assert( aoc->a_vals[0].bv_val != NULL );

       /* check the structural object class attribute */
       if ( asc == NULL && !add ) {
              Debug( LDAP_DEBUG_ANY,
                     "No structuralObjectClass for entry (%s)\n",
                  e->e_dn, 0, 0 );

              *text = "no structuralObjectClass operational attribute";
              return LDAP_OTHER;
       }

       rc = structural_class( aoc->a_vals, &oc, &socs, text, textbuf, textlen,
              op->o_tmpmemctx );
       if( rc != LDAP_SUCCESS ) {
              return rc;
       }

       if ( asc == NULL && add ) {
              attr_merge_one( e, ad_structuralObjectClass, &oc->soc_cname, NULL );
              asc = attr_find( e->e_attrs, ad_structuralObjectClass );
              sc = oc;
              goto got_soc;
       }

       assert( asc->a_vals != NULL );
       assert( asc->a_vals[0].bv_val != NULL );
       assert( asc->a_vals[1].bv_val == NULL );

       sc = oc_bvfind( &asc->a_vals[0] );
       if( sc == NULL ) {
              snprintf( textbuf, textlen, 
                     "unrecognized structuralObjectClass '%s'",
                     asc->a_vals[0].bv_val );

              Debug( LDAP_DEBUG_ANY,
                     "entry_check_schema(%s): %s\n",
                     e->e_dn, textbuf, 0 );

              rc = LDAP_OBJECT_CLASS_VIOLATION;
              goto done;
       }

       if( sc->soc_kind != LDAP_SCHEMA_STRUCTURAL ) {
              snprintf( textbuf, textlen, 
                     "structuralObjectClass '%s' is not STRUCTURAL",
                     asc->a_vals[0].bv_val );

              Debug( LDAP_DEBUG_ANY,
                     "entry_check_schema(%s): %s\n",
                     e->e_dn, textbuf, 0 );

              rc = LDAP_OTHER;
              goto done;
       }

got_soc:
       if( !manage && sc->soc_obsolete ) {
              snprintf( textbuf, textlen, 
                     "structuralObjectClass '%s' is OBSOLETE",
                     asc->a_vals[0].bv_val );

              Debug( LDAP_DEBUG_ANY,
                     "entry_check_schema(%s): %s\n",
                     e->e_dn, textbuf, 0 );

              rc = LDAP_OBJECT_CLASS_VIOLATION;
              goto done;
       }

       *text = textbuf;

       if ( oc == NULL ) {
              snprintf( textbuf, textlen, 
                     "unrecognized objectClass '%s'",
                     aoc->a_vals[0].bv_val );
              rc = LDAP_OBJECT_CLASS_VIOLATION;
              goto done;

       } else if ( sc != oc ) {
              if ( !manage && sc != slap_schema.si_oc_glue ) {
                     snprintf( textbuf, textlen, 
                            "structural object class modification "
                            "from '%s' to '%s' not allowed",
                            asc->a_vals[0].bv_val, oc->soc_cname.bv_val );
                     rc = LDAP_NO_OBJECT_CLASS_MODS;
                     goto done;
              }

              assert( asc->a_vals != NULL );
              assert( !BER_BVISNULL( &asc->a_vals[0] ) );
              assert( BER_BVISNULL( &asc->a_vals[1] ) );
              assert( asc->a_nvals == asc->a_vals );

              /* draft-zeilenga-ldap-relax: automatically modify
               * structuralObjectClass if changed with relax */
              sc = oc;
              ber_bvreplace( &asc->a_vals[ 0 ], &sc->soc_cname );
              if ( socp ) {
                     *socp = asc;
              }
       }

       /* naming check */
       if ( !is_entry_glue ( e ) ) {
              rc = entry_naming_check( e, manage, add, text, textbuf, textlen );
              if( rc != LDAP_SUCCESS ) {
                     goto done;
              }
       } else {
              /* Glue Entry */
       }

       /* 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 ) {
              if( !manage && cr->scr_obsolete ) {
                     snprintf( textbuf, textlen, 
                            "content rule '%s' is obsolete",
                            ldap_contentrule2name( &cr->scr_crule ));

                     Debug( LDAP_DEBUG_ANY,
                            "Entry (%s): %s\n",
                            e->e_dn, textbuf, 0 );

                     rc = LDAP_OBJECT_CLASS_VIOLATION;
                     goto done;
              }

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

                            Debug( LDAP_DEBUG_ANY,
                                   "Entry (%s): %s\n",
                                   e->e_dn, textbuf, 0 );

                            rc = LDAP_OBJECT_CLASS_VIOLATION;
                            goto done;
                     }
              }

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

                            Debug( LDAP_DEBUG_ANY,
                                   "Entry (%s): %s\n",
                                   e->e_dn, textbuf, 0 );

                            rc = LDAP_OBJECT_CLASS_VIOLATION;
                            goto done;
                     }
              }
       }

       /* check that the entry has required attrs for each oc */
       for ( i = 0; socs[i]; i++ ) {
              oc = socs[i];
              if ( !manage && oc->soc_obsolete ) {
                     /* disallow obsolete classes */
                     snprintf( textbuf, textlen, 
                            "objectClass '%s' is OBSOLETE",
                            aoc->a_vals[i].bv_val );

                     Debug( LDAP_DEBUG_ANY,
                            "entry_check_schema(%s): %s\n",
                            e->e_dn, textbuf, 0 );

                     rc = LDAP_OBJECT_CLASS_VIOLATION;
                     goto done;
              }

              if ( oc->soc_check ) {
                     rc = (oc->soc_check)( op->o_bd, e, oc,
                            text, textbuf, textlen );
                     if( rc != LDAP_SUCCESS ) {
                            goto done;
                     }
              }

              if ( oc->soc_kind == LDAP_SCHEMA_ABSTRACT ) {
                     /* object class is abstract */
                     if ( oc != slap_schema.si_oc_top &&
                            !is_object_subclass( oc, sc ))
                     {
                            int j;
                            ObjectClass *xc = NULL;
                            for( j=0; socs[j]; j++ ) {
                                   if( i != j ) {
                                          xc = socs[j];

                                          /* since we previous check against the
                                           * structural object of this entry, the
                                           * abstract class must be a (direct or indirect)
                                           * superclass of one of the auxiliary classes of
                                           * the entry.
                                           */
                                          if ( xc->soc_kind == LDAP_SCHEMA_AUXILIARY &&
                                                 is_object_subclass( oc, xc ) )
                                          {
                                                 xc = NULL;
                                                 break;
                                          }
                                   }
                            }

                            if( xc != NULL ) {
                                   snprintf( textbuf, textlen, "instantiation of "
                                          "abstract objectClass '%s' not allowed",
                                          aoc->a_vals[i].bv_val );

                                   Debug( LDAP_DEBUG_ANY,
                                          "entry_check_schema(%s): %s\n",
                                          e->e_dn, textbuf, 0 );

                                   rc = LDAP_OBJECT_CLASS_VIOLATION;
                                   goto done;
                            }
                     }

              } else if ( oc->soc_kind != LDAP_SCHEMA_STRUCTURAL || oc == sc ) {
                     char *s;

                     if( oc->soc_kind == LDAP_SCHEMA_AUXILIARY ) {
                            int k;

                            if( cr ) {
                                   int j;

                                   k = -1;
                                   if( cr->scr_auxiliaries ) {
                                          for( j = 0; cr->scr_auxiliaries[j]; j++ ) {
                                                 if( cr->scr_auxiliaries[j] == oc ) {
                                                        k = 0;
                                                        break;
                                                 }
                                          }
                                   }
                                   if ( k ) {
                                          snprintf( textbuf, textlen, 
                                                 "class '%s' not allowed by content rule '%s'",
                                                 oc->soc_cname.bv_val,
                                                 ldap_contentrule2name( &cr->scr_crule ) );
                                   }
                            } else if ( global_disallows & SLAP_DISALLOW_AUX_WO_CR ) {
                                   k = -1;
                                   snprintf( textbuf, textlen, 
                                          "class '%s' not allowed by any content rule",
                                          oc->soc_cname.bv_val );
                            } else {
                                   k = 0; 
                            }

                            if( k == -1 ) {
                                   Debug( LDAP_DEBUG_ANY,
                                          "Entry (%s): %s\n",
                                          e->e_dn, textbuf, 0 );

                                   rc = LDAP_OBJECT_CLASS_VIOLATION;
                                   goto done;
                            }
                     }

                     s = oc_check_required( e, oc, &aoc->a_vals[i] );
                     if (s != NULL) {
                            snprintf( textbuf, textlen, 
                                   "object class '%s' requires attribute '%s'",
                                   aoc->a_vals[i].bv_val, s );

                            Debug( LDAP_DEBUG_ANY,
                                   "Entry (%s): %s\n",
                                   e->e_dn, textbuf, 0 );

                            rc = LDAP_OBJECT_CLASS_VIOLATION;
                            goto done;
                     }

                     if( oc == slap_schema.si_oc_extensibleObject ) {
                            extensible=1;
                     }
              }
       }

       if( extensible ) {
              *text = NULL;
              rc = LDAP_SUCCESS;
              goto done;
       }

       /* check that each attr in the entry is allowed by some oc */
       for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
              rc = 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 ) {
                                   rc = LDAP_SUCCESS;
                                   break;
                            }
                     }
              }

              if( rc != LDAP_SUCCESS && cr && cr->scr_allowed ) {
                     for( i=0; cr->scr_allowed[i]; i++ ) {
                            if( cr->scr_allowed[i] == a->a_desc->ad_type ) {
                                   rc = LDAP_SUCCESS;
                                   break;
                            }
                     }
              }

              if( rc != LDAP_SUCCESS ) 
              {
                     rc = oc_check_allowed( a->a_desc->ad_type, socs, sc );
              }

              if ( rc != LDAP_SUCCESS ) {
                     char *type = a->a_desc->ad_cname.bv_val;

                     snprintf( textbuf, textlen, 
                            "attribute '%s' not allowed",
                            type );

                     Debug( LDAP_DEBUG_ANY,
                         "Entry (%s), %s\n",
                         e->e_dn, textbuf, 0 );

                     goto done;
              }
       }

       *text = NULL;
done:
       slap_sl_free( socs, op->o_tmpmemctx );
       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mods_structural_class ( Modifications mods,
struct berval sc,
const char **  text,
char *  textbuf,
size_t  textlen,
void ctx 
)

Definition at line 738 of file schema_check.c.

{
       Modifications *ocmod = NULL;
       ObjectClass *ssc;
       int rc;

       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_values == NULL || ocmod->sml_values[0].bv_val == NULL ) {
              *text = "objectClass attribute has no values";
              return LDAP_OBJECT_CLASS_VIOLATION;
       }

       rc = structural_class( ocmod->sml_values, &ssc, NULL,
              text, textbuf, textlen, ctx );
       if ( rc == LDAP_SUCCESS )
              *sc = ssc->soc_cname;
       return rc;
}

Here is the call graph for this function:

int oc_check_allowed ( AttributeType at,
ObjectClass **  socs,
ObjectClass sc 
)

Definition at line 542 of file schema_check.c.

{
       int           i, j;

       Debug( LDAP_DEBUG_TRACE,
              "oc_check_allowed type \"%s\"\n",
              at->sat_cname.bv_val, 0, 0 );

       /* always allow objectClass attribute */
       if ( strcasecmp( at->sat_cname.bv_val, "objectClass" ) == 0 ) {
              return LDAP_SUCCESS;
       }

       /*
        * All operational attributions are allowed by schema rules.
        */
       if( is_at_operational(at) ) {
              return LDAP_SUCCESS;
       }

       /* check to see if its allowed by the structuralObjectClass */
       if( sc ) {
              /* does it require the type? */
              for ( j = 0; sc->soc_required != NULL && 
                     sc->soc_required[j] != NULL; j++ )
              {
                     if( at == sc->soc_required[j] ) {
                            return LDAP_SUCCESS;
                     }
              }

              /* does it allow the type? */
              for ( j = 0; sc->soc_allowed != NULL && 
                     sc->soc_allowed[j] != NULL; j++ )
              {
                     if( at == sc->soc_allowed[j] ) {
                            return LDAP_SUCCESS;
                     }
              }
       }

       /* check that the type appears as req or opt in at least one oc */
       for ( i = 0; socs[i]; i++ ) {
              /* if we know about the oc */
              ObjectClass   *oc = socs[i];
              /* extensibleObject allows all */
              if ( oc == slap_schema.si_oc_extensibleObject ) {
                     return LDAP_SUCCESS;
              }
              if ( oc != NULL && oc->soc_kind != LDAP_SCHEMA_ABSTRACT &&
                     ( sc == NULL || oc->soc_kind == LDAP_SCHEMA_AUXILIARY ))
              {
                     /* does it require the type? */
                     for ( j = 0; oc->soc_required != NULL && 
                            oc->soc_required[j] != NULL; j++ )
                     {
                            if( at == oc->soc_required[j] ) {
                                   return LDAP_SUCCESS;
                            }
                     }
                     /* does it allow the type? */
                     for ( j = 0; oc->soc_allowed != NULL && 
                            oc->soc_allowed[j] != NULL; j++ )
                     {
                            if( at == oc->soc_allowed[j] ) {
                                   return LDAP_SUCCESS;
                            }
                     }
              }
       }

       /* not allowed by any oc */
       return LDAP_OBJECT_CLASS_VIOLATION;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char * oc_check_required ( Entry e,
ObjectClass oc,
struct berval ocname 
) [static]

Definition at line 505 of file schema_check.c.

{
       AttributeType *at;
       int           i;
       Attribute     *a;

       Debug( LDAP_DEBUG_TRACE,
              "oc_check_required entry (%s), objectClass \"%s\"\n",
              e->e_dn, ocname->bv_val, 0 );


       /* check for empty oc_required */
       if(oc->soc_required == NULL) {
              return NULL;
       }

       /* for each required attribute */
       for ( i = 0; oc->soc_required[i] != NULL; i++ ) {
              at = oc->soc_required[i];
              /* see if it's in the entry */
              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 ) {
                     return at->sat_cname.bv_val;
              }
       }

       return( NULL );
}

Here is the caller graph for this function:

int structural_class ( BerVarray  ocs,
ObjectClass **  scp,
ObjectClass ***  socsp,
const char **  text,
char *  textbuf,
size_t  textlen,
void ctx 
)

Definition at line 623 of file schema_check.c.

{
       int i, nocs;
       ObjectClass *oc, **socs;
       ObjectClass *sc = NULL;
       int scn = -1;

       *text = "structural_class: internal error";

       /* count them */
       for( i=0; ocs[i].bv_val; i++ ) ;
       nocs = i;
       
       socs = slap_sl_malloc( (nocs+1) * sizeof(ObjectClass *), ctx );

       for( i=0; ocs[i].bv_val; i++ ) {
              socs[i] = oc_bvfind( &ocs[i] );

              if( socs[i] == NULL ) {
                     snprintf( textbuf, textlen,
                            "unrecognized objectClass '%s'",
                            ocs[i].bv_val );
                     *text = textbuf;
                     goto fail;
              }
       }
       socs[i] = NULL;

       for( i=0; ocs[i].bv_val; i++ ) {
              oc = socs[i];
              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 ) ) {
                            int j;
                            ObjectClass *xc = NULL;

                            /* find common superior */
                            for( j=i+1; ocs[j].bv_val; j++ ) {
                                   xc = socs[j];

                                   if( xc == NULL ) {
                                          snprintf( textbuf, textlen,
                                                 "unrecognized objectClass '%s'",
                                                 ocs[j].bv_val );
                                          *text = textbuf;
                                          goto fail;
                                   }

                                   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;
                                   goto fail;
                            }
                     }
              }
       }

       if( scp ) {
              *scp = sc;
       }

       if( sc == NULL ) {
              *text = "no structural object class provided";
              goto fail;
       }

       if( scn < 0 ) {
              *text = "invalid structural object class";
              goto fail;
       }

       if ( socsp ) {
              *socsp = socs;
       } else {
              slap_sl_free( socs, ctx );
       }
       *text = NULL;

       return LDAP_SUCCESS;

fail:
       slap_sl_free( socs, ctx );
       return LDAP_OBJECT_CLASS_VIOLATION;
}

Here is the call graph for this function:

Here is the caller graph for this function: