From: Kurt Zeilenga Date: Thu, 29 Jul 1999 04:41:49 +0000 (+0000) Subject: Save attributes until we've completed schema check and X-Git-Tag: OPENLDAP_REL_ENG_2_BP~5 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=51d16c18a9f98db224e8008a955d6444b1d2e162;p=openldap Save attributes until we've completed schema check and modified indices. --- diff --git a/servers/slapd/attr.c b/servers/slapd/attr.c index 8e3112200b..59cd1452c7 100644 --- a/servers/slapd/attr.c +++ b/servers/slapd/attr.c @@ -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) */ diff --git a/servers/slapd/back-ldbm/modify.c b/servers/slapd/back-ldbm/modify.c index 4970245e8e..a85987723b 100644 --- a/servers/slapd/back-ldbm/modify.c +++ b/servers/slapd/back-ldbm/modify.c @@ -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 ) { diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 1d0b470042..ab489d0d37 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -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 */