]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/oc.c
ITS#5376,ITS#5378
[openldap] / servers / slapd / oc.c
index 2772d72711fb99387701221a70809497753c91c4..7e2a66872dcc50de19adf8d76c0fcc2432305d06 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-2008 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -236,10 +236,10 @@ oc_bvfind_undef( struct berval *ocname )
 
 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;
@@ -267,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);
                        }
@@ -312,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;
@@ -524,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;
                        }
 
@@ -594,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;
 }