]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/schema_check.c
fix previous commit (ITS#5819)
[openldap] / servers / slapd / schema_check.c
index 19bed5b3bbcf03133ed0b5bc94de560842d0f4a2..eba6e707dd31cfcb78d13d76c63b154eb3fe1443 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2007 The OpenLDAP Foundation.
+ * Copyright 1998-2008 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -32,6 +32,7 @@ static char * oc_check_required(
 static int entry_naming_check(
        Entry *e,
        int manage,
+       int add_naming,
        const char** text,
        char *textbuf, size_t textlen );
 /*
@@ -47,7 +48,7 @@ entry_schema_check(
        Entry *e,
        Attribute *oldattrs,
        int manage,
-       int add_soc,
+       int add,
        const char** text,
        char *textbuf, size_t textlen )
 {
@@ -135,7 +136,7 @@ entry_schema_check(
        assert( aoc->a_vals[0].bv_val != NULL );
 
        /* check the structural object class attribute */
-       if ( asc == NULL && !add_soc ) {
+       if ( asc == NULL && !add ) {
                Debug( LDAP_DEBUG_ANY,
                        "No structuralObjectClass for entry (%s)\n",
                    e->e_dn, 0, 0 );
@@ -150,7 +151,7 @@ entry_schema_check(
                return rc;
        }
 
-       if ( asc == NULL && add_soc ) {
+       if ( asc == NULL && add ) {
                attr_merge_one( e, ad_structuralObjectClass, &oc->soc_cname, NULL );
                asc = attr_find( e->e_attrs, ad_structuralObjectClass );
                sc = oc;
@@ -172,7 +173,7 @@ entry_schema_check(
                        e->e_dn, textbuf, 0 );
 
                rc = LDAP_OBJECT_CLASS_VIOLATION;
-               goto leave;
+               goto done;
        }
 
        if( sc->soc_kind != LDAP_SCHEMA_STRUCTURAL ) {
@@ -185,7 +186,7 @@ entry_schema_check(
                        e->e_dn, textbuf, 0 );
 
                rc = LDAP_OTHER;
-               goto leave;
+               goto done;
        }
 
 got_soc:
@@ -199,7 +200,7 @@ got_soc:
                        e->e_dn, textbuf, 0 );
 
                rc = LDAP_OBJECT_CLASS_VIOLATION;
-               goto leave;
+               goto done;
        }
 
        *text = textbuf;
@@ -209,7 +210,7 @@ got_soc:
                        "unrecognized objectClass '%s'",
                        aoc->a_vals[0].bv_val );
                rc = LDAP_OBJECT_CLASS_VIOLATION;
-               goto leave;
+               goto done;
 
        } else if ( sc != slap_schema.si_oc_glue && sc != oc ) {
                snprintf( textbuf, textlen, 
@@ -217,16 +218,16 @@ got_soc:
                        "from '%s' to '%s' not allowed",
                        asc->a_vals[0].bv_val, oc->soc_cname.bv_val );
                rc = LDAP_NO_OBJECT_CLASS_MODS;
-               goto leave;
+               goto done;
        } else if ( sc == slap_schema.si_oc_glue ) {
                sc = oc;
        }
 
        /* naming check */
        if ( !is_entry_glue ( e ) ) {
-               rc = entry_naming_check( e, manage, text, textbuf, textlen );
+               rc = entry_naming_check( e, manage, add, text, textbuf, textlen );
                if( rc != LDAP_SUCCESS ) {
-                       goto leave;
+                       goto done;
                }
        } else {
                /* Glue Entry */
@@ -250,7 +251,7 @@ got_soc:
                                e->e_dn, textbuf, 0 );
 
                        rc = LDAP_OBJECT_CLASS_VIOLATION;
-                       goto leave;
+                       goto done;
                }
 
                if( cr->scr_required ) for( i=0; cr->scr_required[i]; i++ ) {
@@ -274,7 +275,7 @@ got_soc:
                                        e->e_dn, textbuf, 0 );
 
                                rc = LDAP_OBJECT_CLASS_VIOLATION;
-                               goto leave;
+                               goto done;
                        }
                }
 
@@ -299,7 +300,7 @@ got_soc:
                                        e->e_dn, textbuf, 0 );
 
                                rc = LDAP_OBJECT_CLASS_VIOLATION;
-                               goto leave;
+                               goto done;
                        }
                }
        }
@@ -318,14 +319,14 @@ got_soc:
                                e->e_dn, textbuf, 0 );
 
                        rc = LDAP_OBJECT_CLASS_VIOLATION;
-                       goto leave;
+                       goto done;
                }
 
                if ( oc->soc_check ) {
                        rc = (oc->soc_check)( op->o_bd, e, oc,
                                text, textbuf, textlen );
                        if( rc != LDAP_SUCCESS ) {
-                               goto leave;
+                               goto done;
                        }
                }
 
@@ -355,8 +356,8 @@ got_soc:
                                        }
                                }
 
-                               if( xc == NULL ) {
-                                       snprintf( textbuf, textlen, "instanstantiation of "
+                               if( xc != NULL ) {
+                                       snprintf( textbuf, textlen, "instantiation of "
                                                "abstract objectClass '%s' not allowed",
                                                aoc->a_vals[i].bv_val );
 
@@ -365,7 +366,7 @@ got_soc:
                                                e->e_dn, textbuf, 0 );
 
                                        rc = LDAP_OBJECT_CLASS_VIOLATION;
-                                       goto leave;
+                                       goto done;
                                }
                        }
 
@@ -408,7 +409,7 @@ got_soc:
                                                e->e_dn, textbuf, 0 );
 
                                        rc = LDAP_OBJECT_CLASS_VIOLATION;
-                                       goto leave;
+                                       goto done;
                                }
                        }
 
@@ -423,7 +424,7 @@ got_soc:
                                        e->e_dn, textbuf, 0 );
 
                                rc = LDAP_OBJECT_CLASS_VIOLATION;
-                               goto leave;
+                               goto done;
                        }
 
                        if( oc == slap_schema.si_oc_extensibleObject ) {
@@ -435,7 +436,7 @@ got_soc:
        if( extensible ) {
                *text = NULL;
                rc = LDAP_SUCCESS;
-               goto leave;
+               goto done;
        }
 
        /* check that each attr in the entry is allowed by some oc */
@@ -476,12 +477,12 @@ got_soc:
                            "Entry (%s), %s\n",
                            e->e_dn, textbuf, 0 );
 
-                       goto leave;
+                       goto done;
                }
        }
 
        *text = NULL;
-leave:
+done:
        slap_sl_free( socs, op->o_tmpmemctx );
        return rc;
 }
@@ -572,6 +573,10 @@ int oc_check_allowed(
        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 ))
                {
@@ -758,6 +763,7 @@ static int
 entry_naming_check(
        Entry *e,
        int manage,
+       int add_naming,
        const char** text,
        char *textbuf, size_t textlen )
 {
@@ -788,6 +794,7 @@ entry_naming_check(
                AttributeDescription *desc = NULL;
                Attribute *attr;
                const char *errtext;
+               int add = 0;
 
                if( ava->la_flags & LDAP_AVA_BINARY ) {
                        snprintf( textbuf, textlen, 
@@ -848,37 +855,56 @@ entry_naming_check(
                        snprintf( textbuf, textlen, 
                                "naming attribute '%s' is not present in entry",
                                ava->la_attr.bv_val );
-                       rc = LDAP_NAMING_VIOLATION;
-                       break;
-               }
+                       if ( add_naming ) {
+                               add = 1;
 
-               rc = value_find_ex( desc, SLAP_MR_VALUE_OF_ASSERTION_SYNTAX|
-                       SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH,
-                       attr->a_nvals, &ava->la_value, NULL );
+                       } else {
+                               rc = LDAP_NAMING_VIOLATION;
+                       }
 
-               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:
-                               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 );
+               } 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 ) {
+                                               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;
+                               }
                        }
-                       rc = LDAP_NAMING_VIOLATION;
+               }
+
+               if ( add ) {
+                       attr_merge_normalize_one( e, desc, &ava->la_value, NULL );
+
+               } else if ( rc != LDAP_SUCCESS ) {
                        break;
                }
        }