]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/oc.c
Fix corrupted CSN issue
[openldap] / servers / slapd / oc.c
index 87ced2d7cb073183b6791a7254db9eb2187b9b39..3ba9501db39cea3f71c32f17f830b25ba21cf897 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2006 The OpenLDAP Foundation.
+ * Copyright 1998-2009 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -37,16 +37,16 @@ int is_object_subclass(
                sup->soc_oid, sub->soc_oid, sup == sub );
 #endif
 
-       if( sup == sub ) {
+       if ( sup == sub ) {
                return 1;
        }
 
-       if( sub->soc_sups == NULL ) {
+       if ( sub->soc_sups == NULL ) {
                return 0;
        }
 
-       for( i=0; sub->soc_sups[i] != NULL; i++ ) {
-               if( is_object_subclass( sup, sub->soc_sups[i] ) ) {
+       for ( i = 0; sub->soc_sups[i] != NULL; i++ ) {
+               if ( is_object_subclass( sup, sub->soc_sups[i] ) ) {
                        return 1;
                }
        }
@@ -71,11 +71,11 @@ int is_entry_objectclass(
        assert( !( e == NULL || oc == NULL ) );
        assert( ( flags & SLAP_OCF_MASK ) != SLAP_OCF_MASK );
 
-       if( e == NULL || oc == NULL ) {
+       if ( e == NULL || oc == NULL ) {
                return 0;
        }
 
-       if( flags == SLAP_OCF_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;
@@ -85,17 +85,20 @@ int is_entry_objectclass(
         * find objectClass attribute
         */
        attr = attr_find( e->e_attrs, slap_schema.si_ad_objectClass );
-       if( attr == NULL ) {
+       if ( attr == NULL ) {
                /* no objectClass attribute */
                Debug( LDAP_DEBUG_ANY, "is_entry_objectclass(\"%s\", \"%s\") "
                        "no objectClass attribute\n",
                        e->e_dn == NULL ? "" : e->e_dn,
                        oc->soc_oclass.oc_oid, 0 );
 
+               /* mark flags as set */
+               e->e_ocflags |= SLAP_OC__END;
+
                return 0;
        }
 
-       for( bv=attr->a_vals; bv->bv_val; bv++ ) {
+       for ( bv = attr->a_vals; bv->bv_val; bv++ ) {
                ObjectClass *objectClass = oc_bvfind( bv );
 
                if ( objectClass == NULL ) {
@@ -132,9 +135,10 @@ struct oindexrec {
 
 static Avlnode *oc_index = NULL;
 static Avlnode *oc_cache = NULL;
-static LDAP_STAILQ_HEAD(OCList, slap_object_class) oc_list
+static LDAP_STAILQ_HEAD(OCList, ObjectClass) oc_list
        = LDAP_STAILQ_HEAD_INITIALIZER(oc_list);
-static ObjectClass *oc_sys_tail;
+
+ObjectClass *oc_sys_tail;
 
 static int
 oc_index_cmp(
@@ -192,7 +196,7 @@ oc_bvfind( struct berval *ocname )
        return( NULL );
 }
 
-static LDAP_STAILQ_HEAD(OCUList, slap_object_class) oc_undef_list
+static LDAP_STAILQ_HEAD(OCUList, ObjectClass) oc_undef_list
        = LDAP_STAILQ_HEAD_INITIALIZER(oc_undef_list);
 
 ObjectClass *
@@ -226,6 +230,10 @@ oc_bvfind_undef( struct berval *ocname )
        oc->soc_cname.bv_len = ocname->bv_len;
        oc->soc_cname.bv_val = (char *)&oc[ 1 ];
        AC_MEMCPY( oc->soc_cname.bv_val, ocname->bv_val, ocname->bv_len );
+       oc->soc_cname.bv_val[ oc->soc_cname.bv_len ] = '\0';
+
+       /* canonical to upper case */
+       ldap_pvt_str2upper( oc->soc_cname.bv_val );
 
        LDAP_STAILQ_NEXT( oc, soc_next ) = NULL;
        ldap_pvt_thread_mutex_lock( &oc_undef_mutex );
@@ -413,7 +421,7 @@ oc_delete( ObjectClass *oc )
 {
        oc->soc_flags |= SLAP_OC_DELETED;
 
-       LDAP_STAILQ_REMOVE(&oc_list,oc,slap_object_class,soc_next);
+       LDAP_STAILQ_REMOVE(&oc_list, oc, ObjectClass, soc_next);
 
        oc_delete_names( oc );
 }
@@ -421,10 +429,22 @@ oc_delete( ObjectClass *oc )
 static void
 oc_clean( ObjectClass *o )
 {
-       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);
+       if (o->soc_sups) {
+               ldap_memfree(o->soc_sups);
+               o->soc_sups = NULL;
+       }
+       if (o->soc_required) {
+               ldap_memfree(o->soc_required);
+               o->soc_required = NULL;
+       }
+       if (o->soc_allowed) {
+               ldap_memfree(o->soc_allowed);
+               o->soc_allowed = NULL;
+       }
+       if (o->soc_oidmacro) {
+               ldap_memfree(o->soc_oidmacro);
+               o->soc_oidmacro = NULL;
+       }
 }
 
 static void
@@ -475,7 +495,7 @@ oc_next( ObjectClass **oc )
 {
        assert( oc != NULL );
 
-#if 1  /* pedantic check */
+#if 0  /* pedantic check: breaks when deleting an oc, don't use it. */
        {
                ObjectClass *tmp = NULL;
 
@@ -489,6 +509,10 @@ oc_next( ObjectClass **oc )
        }
 #endif
 
+       if ( *oc == NULL ) {
+               return 0;
+       }
+
        *oc = LDAP_STAILQ_NEXT(*oc,soc_next);
 
        return (*oc != NULL);
@@ -805,7 +829,7 @@ oc_unparse( BerVarray *res, ObjectClass *start, ObjectClass *end, int sys )
        /* count the result size */
        i = 0;
        for ( oc=start; oc; oc=LDAP_STAILQ_NEXT(oc, soc_next)) {
-               if ( sys && !(oc->soc_flags & SLAP_OC_HARDCODE)) continue;
+               if ( sys && !(oc->soc_flags & SLAP_OC_HARDCODE)) break;
                i++;
                if ( oc == end ) break;
        }
@@ -822,7 +846,7 @@ oc_unparse( BerVarray *res, ObjectClass *start, ObjectClass *end, int sys )
        i = 0;
        for ( oc=start; oc; oc=LDAP_STAILQ_NEXT(oc, soc_next)) {
                LDAPObjectClass loc, *locp;
-               if ( sys && !(oc->soc_flags & SLAP_OC_HARDCODE)) continue;
+               if ( sys && !(oc->soc_flags & SLAP_OC_HARDCODE)) break;
                if ( oc->soc_oidmacro ) {
                        loc = oc->soc_oclass;
                        loc.oc_oid = oc->soc_oidmacro;
@@ -879,7 +903,7 @@ oc_schema_info( Entry *e )
 }
 
 int
-register_oc( char *def, ObjectClass **soc, int dupok )
+register_oc( const char *def, ObjectClass **soc, int dupok )
 {
        LDAPObjectClass *oc;
        int code;