]> git.sur5r.net Git - openldap/commitdiff
Save attributes until we've completed schema check and
authorKurt Zeilenga <kurt@openldap.org>
Thu, 29 Jul 1999 04:41:49 +0000 (04:41 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Thu, 29 Jul 1999 04:41:49 +0000 (04:41 +0000)
modified indices.

servers/slapd/attr.c
servers/slapd/back-ldbm/modify.c
servers/slapd/proto-slap.h

index 8e3112200bf99c96797bc4776f39c2869615172d..59cd1452c795f9e5e80ccd037680e97b4abff852 100644 (file)
@@ -33,6 +33,69 @@ attr_free( Attribute *a )
        free( a );
 }
 
+void
+attrs_free( Attribute *a )
+{
+       Attribute *next;
+
+       for( ; a != NULL ; a = next ) {
+               next = a->a_next;
+               attr_free( a );
+       }
+}
+
+Attribute *attr_dup( Attribute *a )
+{
+       Attribute *tmp;
+
+       if( a == NULL) return NULL;
+
+       tmp = ch_malloc( sizeof(Attribute) );
+
+       if( a->a_vals != NULL ) {
+               int i;
+
+               for( i=0; a->a_vals[i] != NULL; i++ ) {
+                       /* EMPTY */ ;
+               }
+
+               tmp->a_vals = ch_malloc((i+1) * sizeof(struct berval*));
+
+               for( i=0; a->a_vals[i] != NULL; i++ ) {
+                       tmp->a_vals[i] = ber_bvdup( a->a_vals[i] );
+               }
+
+               tmp->a_vals[i] = NULL;
+
+       } else {
+               tmp->a_vals = NULL;
+       }
+
+       tmp->a_type = ch_strdup( a->a_type );
+       tmp->a_syntax = a->a_syntax;
+       tmp->a_next = NULL;
+
+       return tmp;
+}
+
+Attribute *attrs_dup( Attribute *a )
+{
+       Attribute *tmp, **next;
+
+       if( a == NULL ) return NULL;
+
+       tmp = NULL;
+       next = &tmp;
+
+       for( ; a != NULL ; a = a->a_next ) {
+               *next = attr_dup( a );
+               next = &((*next)->a_next);
+       }
+       *next = NULL;
+
+       return tmp;
+}
+
 /*
  * attr_normalize - normalize an attribute name (make it all lowercase)
  */
index 4970245e8e9577983dbae38ed44f212935a4cad0..a85987723b48b81abddf130d708b3f0d040f5a41 100644 (file)
@@ -31,6 +31,7 @@ int ldbm_modify_internal(
        LDAPMod         *mod;
        LDAPModList     *ml;
        Attribute       *a;
+       Attribute       *save_attrs;
 
        if ( (err = acl_check_modlist( be, conn, op, e, modlist ))
             != LDAP_SUCCESS )
@@ -40,8 +41,10 @@ int ldbm_modify_internal(
                return -1;
        }
 
-       for ( ml = modlist; ml != NULL; ml = ml->ml_next ) {
+       save_attrs = e->e_attrs;
+       e->e_attrs = attrs_dup( e->e_attrs );
 
+       for ( ml = modlist; ml != NULL; ml = ml->ml_next ) {
                mod = &ml->ml_mod;
 
                switch ( mod->mod_op & ~LDAP_MOD_BVALUES ) {
@@ -54,20 +57,6 @@ int ldbm_modify_internal(
                        break;
 
                case LDAP_MOD_REPLACE:
-                       /* Need to remove all values from indexes before they
-                        * are lost.
-                        */
-                       if( e->e_attrs
-                           && ((a = attr_find( e->e_attrs, mod->mod_type ))
-                          != NULL) ) {
-
-                           (void) index_change_values( be,
-                                                       mod->mod_type,
-                                                       a->a_vals,
-                                                       e->e_id,
-                                                       __INDEX_DELETE_OP);
-                       }
-
                        err = replace_values( e, mod, op->o_ndn );
                        break;
 
@@ -87,6 +76,8 @@ int ldbm_modify_internal(
                }
 
                if ( err != LDAP_SUCCESS ) {
+                       attrs_free( e->e_attrs );
+                       e->e_attrs = save_attrs;
                        /* unlock entry, delete from cache */
                        send_ldap_result( conn, op, err,
                                NULL, NULL, NULL, NULL );
@@ -94,8 +85,20 @@ int ldbm_modify_internal(
                }
        }
 
+       /* check for abandon */
+       ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
+       if ( op->o_abandon ) {
+               attrs_free( e->e_attrs );
+               e->e_attrs = save_attrs;
+               ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
+               return -1;
+       }
+       ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
+
        /* check that the entry still obeys the schema */
        if ( global_schemacheck && oc_schema_check( e ) != 0 ) {
+               attrs_free( e->e_attrs );
+               e->e_attrs = save_attrs;
                Debug( LDAP_DEBUG_ANY, "entry failed schema check\n", 0, 0, 0 );
                send_ldap_result( conn, op, LDAP_OBJECT_CLASS_VIOLATION,
                        NULL, NULL, NULL, NULL );
@@ -105,6 +108,8 @@ int ldbm_modify_internal(
        /* check for abandon */
        ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
        if ( op->o_abandon ) {
+               attrs_free( e->e_attrs );
+               e->e_attrs = save_attrs;
                ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
                return -1;
        }
@@ -112,11 +117,33 @@ int ldbm_modify_internal(
 
        /* modify indexes */
        if ( index_add_mods( be, modlist, e->e_id ) != 0 ) {
+               attrs_free( e->e_attrs );
+               e->e_attrs = save_attrs;
                send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
                        NULL, NULL, NULL, NULL );
                return -1;
        }
 
+       if( save_attrs != NULL ) {
+               for ( ml = modlist; ml != NULL; ml = ml->ml_next ) {
+                       if( ( mod->mod_op & ~LDAP_MOD_BVALUES )
+                               == LDAP_MOD_REPLACE )
+                       {
+                               /* Need to remove all values from indexes */
+                               a = attr_find( save_attrs, mod->mod_type );
+
+                               if( a != NULL ) {
+                                       (void) index_change_values( be,
+                                               mod->mod_type,
+                                               a->a_vals,
+                                               e->e_id,
+                                               __INDEX_DELETE_OP);
+                               }
+                       }
+               }
+               attrs_free( save_attrs );
+       }
+
        /* check for abandon */
        ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
        if ( op->o_abandon ) {
@@ -126,8 +153,7 @@ int ldbm_modify_internal(
        ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
 
        return 0;
-
-}/* int ldbm_modify_internal() */
+}
 
 
 int
@@ -313,11 +339,6 @@ replace_values(
     char       *dn
 )
 {
-
-       /* XXX: BEFORE YOU GET RID OF PREVIOUS VALUES REMOVE FROM INDEX
-        * FILES
-        */
-
        (void) attr_delete( &e->e_attrs, mod->mod_type );
 
        if ( attr_merge( e, mod->mod_type, mod->mod_bvalues ) != 0 ) {
index 1d0b470042af139594f240779723be4d8e072f6c..ab489d0d376e81c7ea10485da652d87863c46b13 100644 (file)
@@ -41,6 +41,7 @@ int str2access LDAP_P(( char *str ));
  */
 
 void attr_free LDAP_P(( Attribute *a ));
+Attribute *attr_dup LDAP_P(( Attribute *a ));
 char * attr_normalize LDAP_P(( char *s ));
 int attr_merge_fast LDAP_P(( Entry *e, char *type, struct berval **vals, int  nvals,
        int  naddvals, int  *maxvals, Attribute ***a ));
@@ -58,6 +59,9 @@ int at_schema_info LDAP_P(( Entry *e ));
 int at_add LDAP_P(( LDAP_ATTRIBUTE_TYPE *at, const char **err ));
 char * at_canonical_name LDAP_P(( char * a_type ));
 
+void attrs_free LDAP_P(( Attribute *a ));
+Attribute *attrs_dup LDAP_P(( Attribute *a ));
+
 /*
  * ava.c
  */