]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/oc.c
fix previous commit (ITS#4861)
[openldap] / servers / slapd / oc.c
index cd381f1bf3443d3c69845924aa0cbfc8a32b2e17..89d32f39224da3b1e8bd64cd83f48d54ab9c9e85 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2005 The OpenLDAP Foundation.
+ * Copyright 1998-2007 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -57,7 +57,7 @@ int is_object_subclass(
 int is_entry_objectclass(
        Entry*  e,
        ObjectClass *oc,
-       int set_flags )
+       unsigned flags )
 {
        /*
         * set_flags should only be true if oc is one of operational
@@ -67,15 +67,16 @@ int is_entry_objectclass(
 
        Attribute *attr;
        struct berval *bv;
-       AttributeDescription *objectClass = slap_schema.si_ad_objectClass;
 
-       assert(!( e == NULL || oc == NULL ));
+       assert( !( e == NULL || oc == NULL ) );
+       assert( ( flags & SLAP_OCF_MASK ) != SLAP_OCF_MASK );
 
        if( e == NULL || oc == NULL ) {
                return 0;
        }
 
-       if( set_flags && ( e->e_ocflags & SLAP_OC__END )) {
+       if( flags == SLAP_OCF_SET_FLAGS && ( e->e_ocflags & SLAP_OC__END ) )
+       {
                /* flags are set, use them */
                return (e->e_ocflags & oc->soc_flags & SLAP_OC__MASK) != 0;
        }
@@ -83,7 +84,7 @@ int is_entry_objectclass(
        /*
         * find objectClass attribute
         */
-       attr = attr_find(e->e_attrs, objectClass);
+       attr = attr_find( e->e_attrs, slap_schema.si_ad_objectClass );
        if( attr == NULL ) {
                /* no objectClass attribute */
                Debug( LDAP_DEBUG_ANY, "is_entry_objectclass(\"%s\", \"%s\") "
@@ -97,19 +98,30 @@ int is_entry_objectclass(
        for( bv=attr->a_vals; bv->bv_val; bv++ ) {
                ObjectClass *objectClass = oc_bvfind( bv );
 
-               if ( !set_flags && objectClass == oc ) {
-                       return 1;
+               if ( objectClass == NULL ) {
+                       /* FIXME: is this acceptable? */
+                       continue;
                }
-               
-               if ( objectClass != NULL ) {
-                       e->e_ocflags |= objectClass->soc_flags;
+
+               if ( !( flags & SLAP_OCF_SET_FLAGS ) ) {
+                       if ( objectClass == oc ) {
+                               return 1;
+                       }
+
+                       if ( ( flags & SLAP_OCF_CHECK_SUP )
+                               && is_object_subclass( oc, objectClass ) )
+                       {
+                               return 1;
+                       }
                }
+               
+               e->e_ocflags |= objectClass->soc_flags;
        }
 
        /* mark flags as set */
        e->e_ocflags |= SLAP_OC__END;
 
-       return (e->e_ocflags & oc->soc_flags & SLAP_OC__MASK) != 0;
+       return ( e->e_ocflags & oc->soc_flags & SLAP_OC__MASK ) != 0;
 }
 
 
@@ -215,17 +227,19 @@ oc_bvfind_undef( struct berval *ocname )
        AC_MEMCPY( oc->soc_cname.bv_val, ocname->bv_val, ocname->bv_len );
 
        LDAP_STAILQ_NEXT( oc, soc_next ) = NULL;
+       ldap_pvt_thread_mutex_lock( &oc_undef_mutex );
        LDAP_STAILQ_INSERT_HEAD( &oc_undef_list, oc, soc_next );
+       ldap_pvt_thread_mutex_unlock( &oc_undef_mutex );
 
        return oc;
 }
 
 static int
 oc_create_required(
-    ObjectClass                *soc,
-    char               **attrs,
+       ObjectClass             *soc,
+       char                    **attrs,
        int                     *op,
-    const char         **err )
+       const char              **err )
 {
        char            **attrs1;
        AttributeType   *sat;
@@ -253,7 +267,7 @@ oc_create_required(
                }
                /* Now delete duplicates from the allowed list */
                for ( satp = soc->soc_required; *satp; satp++ ) {
-                       i = at_find_in_list(*satp,soc->soc_allowed);
+                       i = at_find_in_list(*satp, soc->soc_allowed);
                        if ( i >= 0 ) {
                                at_delete_from_list(i, &soc->soc_allowed);
                        }
@@ -298,10 +312,10 @@ oc_create_allowed(
 
 static int
 oc_add_sups(
-    ObjectClass                *soc,
-    char                       **sups,
+       ObjectClass             *soc,
+       char                    **sups,
        int                     *op,
-    const char         **err )
+       const char              **err )
 {
        int             code;
        ObjectClass     *soc1;
@@ -385,6 +399,7 @@ oc_destroy( void )
                if (o->soc_sups) ldap_memfree(o->soc_sups);
                if (o->soc_required) ldap_memfree(o->soc_required);
                if (o->soc_allowed) ldap_memfree(o->soc_allowed);
+               if (o->soc_oidmacro) ldap_memfree(o->soc_oidmacro);
                ldap_objectclass_free((LDAPObjectClass *)o);
        }
        
@@ -462,8 +477,8 @@ oc_insert(
                oir->oir_name.bv_len = strlen( soc->soc_oid );
                oir->oir_oc = soc;
 
-               assert( oir->oir_name.bv_val );
-               assert( oir->oir_oc );
+               assert( oir->oir_name.bv_val != NULL );
+               assert( oir->oir_oc != NULL );
 
                if ( avl_insert( &oc_index, (caddr_t) oir,
                        oc_index_cmp, avl_dup_error ) )
@@ -493,8 +508,8 @@ oc_insert(
                        oir->oir_name.bv_len = strlen( *names );
                        oir->oir_oc = soc;
 
-                       assert( oir->oir_name.bv_val );
-                       assert( oir->oir_oc );
+                       assert( oir->oir_name.bv_val != NULL );
+                       assert( oir->oir_oc != NULL );
 
                        if ( avl_insert( &oc_index, (caddr_t) oir,
                                oc_index_cmp, avl_dup_error ) )
@@ -509,6 +524,30 @@ oc_insert(
                                rc = oc_check_dup( old_soc, soc );
 
                                ldap_memfree( oir );
+
+                               while ( names > soc->soc_names ) {
+                                       struct oindexrec        tmpoir;
+
+                                       names--;
+                                       ber_str2bv( *names, 0, 0, &tmpoir.oir_name );
+                                       tmpoir.oir_oc = soc;
+                                       oir = (struct oindexrec *)avl_delete( &oc_index,
+                                               (caddr_t)&tmpoir, oc_index_cmp );
+                                       assert( oir != NULL );
+                                       ldap_memfree( oir );
+                               }
+
+                               if ( soc->soc_oid ) {
+                                       struct oindexrec        tmpoir;
+
+                                       ber_str2bv( soc->soc_oid, 0, 0, &tmpoir.oir_name );
+                                       tmpoir.oir_oc = soc;
+                                       oir = (struct oindexrec *)avl_delete( &oc_index,
+                                               (caddr_t)&tmpoir, oc_index_cmp );
+                                       assert( oir != NULL );
+                                       ldap_memfree( oir );
+                               }
+
                                return rc;
                        }
 
@@ -579,22 +618,54 @@ oc_add(
                code = oc_add_sups( soc, soc->soc_sup_oids, &op, err );
        }
 
-       if ( code != 0 ) return code;
-       if( user && op ) return SLAP_SCHERR_CLASS_BAD_SUP;
+       if ( code != 0 ) {
+               goto done;
+       }
+
+       if ( user && op ) {
+               code = SLAP_SCHERR_CLASS_BAD_SUP;
+               goto done;
+       }
 
        code = oc_create_required( soc, soc->soc_at_oids_must, &op, err );
-       if ( code != 0 ) return code;
+       if ( code != 0 ) {
+               goto done;
+       }
 
        code = oc_create_allowed( soc, soc->soc_at_oids_may, &op, err );
-       if ( code != 0 ) return code;
+       if ( code != 0 ) {
+               goto done;
+       }
 
-       if( user && op ) return SLAP_SCHERR_CLASS_BAD_USAGE;
+       if ( user && op ) {
+               code = SLAP_SCHERR_CLASS_BAD_USAGE;
+               goto done;
+       }
 
-       if( !user ) soc->soc_flags |= SLAP_OC_HARDCODE;
+       if ( !user ) {
+               soc->soc_flags |= SLAP_OC_HARDCODE;
+       }
 
        code = oc_insert(soc,err);
-       if ( code == 0 && rsoc )
+done:;
+       if ( code != 0 ) {
+               if ( soc->soc_sups ) {
+                       ch_free( soc->soc_sups );
+               }
+
+               if ( soc->soc_required ) {
+                       ch_free( soc->soc_required );
+               }
+
+               if ( soc->soc_allowed ) {
+                       ch_free( soc->soc_allowed );
+               }
+
+               ch_free( soc );
+
+       } else if ( rsoc ) {
                *rsoc = soc;
+       }
        return code;
 }
 
@@ -604,7 +675,7 @@ oc_unparse( BerVarray *res, ObjectClass *start, ObjectClass *end, int sys )
        ObjectClass *oc;
        int i, num;
        struct berval bv, *bva = NULL, idx;
-       char ibuf[32], *ptr;
+       char ibuf[32];
 
        if ( !start )
                start = LDAP_STAILQ_FIRST( &oc_list );