]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/schema_check.c
cleanup bind
[openldap] / servers / slapd / schema_check.c
index 31c16e2f2d58747c6c8fe4f70e183de4df065151..75cf612d2f72a259826edf3df0c0cbdb3423badc 100644 (file)
@@ -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).
@@ -212,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 );
@@ -790,3 +801,72 @@ 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_NO_SUCH_ATTRIBUTE;
+                       break;
+               }
+
+#ifdef SLAP_NVALUES
+               if ( value_find_ex( desc,
+                       SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH,
+                       attr->a_nvals ? attr->a_nvals : attr->a_vals,
+                       &ava->la_value ) != 0 )
+#else
+               if ( value_find( desc, attr->a_vals, &ava->la_value ) != 0 )
+#endif
+               {
+                       snprintf( textbuf, textlen, 
+                               "value of naming attribute '%s' is not present in entry",
+                               ava->la_attr.bv_val );
+                       rc = LDAP_NO_SUCH_ATTRIBUTE;
+                       break;
+               }
+       }
+
+       ldap_rdnfree( rdn );
+       return rc;
+}
+