Skip to content
Snippets Groups Projects
Commit 51d16c18 authored by Kurt Zeilenga's avatar Kurt Zeilenga
Browse files

Save attributes until we've completed schema check and

modified indices.
parent 4bf65c0d
No related branches found
No related tags found
No related merge requests found
...@@ -33,6 +33,69 @@ attr_free( Attribute *a ) ...@@ -33,6 +33,69 @@ attr_free( Attribute *a )
free( 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) * attr_normalize - normalize an attribute name (make it all lowercase)
*/ */
......
...@@ -31,6 +31,7 @@ int ldbm_modify_internal( ...@@ -31,6 +31,7 @@ int ldbm_modify_internal(
LDAPMod *mod; LDAPMod *mod;
LDAPModList *ml; LDAPModList *ml;
Attribute *a; Attribute *a;
Attribute *save_attrs;
if ( (err = acl_check_modlist( be, conn, op, e, modlist )) if ( (err = acl_check_modlist( be, conn, op, e, modlist ))
!= LDAP_SUCCESS ) != LDAP_SUCCESS )
...@@ -40,8 +41,10 @@ int ldbm_modify_internal( ...@@ -40,8 +41,10 @@ int ldbm_modify_internal(
return -1; 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; mod = &ml->ml_mod;
switch ( mod->mod_op & ~LDAP_MOD_BVALUES ) { switch ( mod->mod_op & ~LDAP_MOD_BVALUES ) {
...@@ -54,20 +57,6 @@ int ldbm_modify_internal( ...@@ -54,20 +57,6 @@ int ldbm_modify_internal(
break; break;
case LDAP_MOD_REPLACE: 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 ); err = replace_values( e, mod, op->o_ndn );
break; break;
...@@ -87,6 +76,8 @@ int ldbm_modify_internal( ...@@ -87,6 +76,8 @@ int ldbm_modify_internal(
} }
if ( err != LDAP_SUCCESS ) { if ( err != LDAP_SUCCESS ) {
attrs_free( e->e_attrs );
e->e_attrs = save_attrs;
/* unlock entry, delete from cache */ /* unlock entry, delete from cache */
send_ldap_result( conn, op, err, send_ldap_result( conn, op, err,
NULL, NULL, NULL, NULL ); NULL, NULL, NULL, NULL );
...@@ -94,8 +85,20 @@ int ldbm_modify_internal( ...@@ -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 */ /* check that the entry still obeys the schema */
if ( global_schemacheck && oc_schema_check( e ) != 0 ) { 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 ); Debug( LDAP_DEBUG_ANY, "entry failed schema check\n", 0, 0, 0 );
send_ldap_result( conn, op, LDAP_OBJECT_CLASS_VIOLATION, send_ldap_result( conn, op, LDAP_OBJECT_CLASS_VIOLATION,
NULL, NULL, NULL, NULL ); NULL, NULL, NULL, NULL );
...@@ -105,6 +108,8 @@ int ldbm_modify_internal( ...@@ -105,6 +108,8 @@ int ldbm_modify_internal(
/* check for abandon */ /* check for abandon */
ldap_pvt_thread_mutex_lock( &op->o_abandonmutex ); ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
if ( op->o_abandon ) { if ( op->o_abandon ) {
attrs_free( e->e_attrs );
e->e_attrs = save_attrs;
ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex ); ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
return -1; return -1;
} }
...@@ -112,11 +117,33 @@ int ldbm_modify_internal( ...@@ -112,11 +117,33 @@ int ldbm_modify_internal(
/* modify indexes */ /* modify indexes */
if ( index_add_mods( be, modlist, e->e_id ) != 0 ) { 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, send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL, NULL ); NULL, NULL, NULL, NULL );
return -1; 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 */ /* check for abandon */
ldap_pvt_thread_mutex_lock( &op->o_abandonmutex ); ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
if ( op->o_abandon ) { if ( op->o_abandon ) {
...@@ -126,8 +153,7 @@ int ldbm_modify_internal( ...@@ -126,8 +153,7 @@ int ldbm_modify_internal(
ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex ); ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
return 0; return 0;
}
}/* int ldbm_modify_internal() */
int int
...@@ -313,11 +339,6 @@ replace_values( ...@@ -313,11 +339,6 @@ replace_values(
char *dn char *dn
) )
{ {
/* XXX: BEFORE YOU GET RID OF PREVIOUS VALUES REMOVE FROM INDEX
* FILES
*/
(void) attr_delete( &e->e_attrs, mod->mod_type ); (void) attr_delete( &e->e_attrs, mod->mod_type );
if ( attr_merge( e, mod->mod_type, mod->mod_bvalues ) != 0 ) { if ( attr_merge( e, mod->mod_type, mod->mod_bvalues ) != 0 ) {
......
...@@ -41,6 +41,7 @@ int str2access LDAP_P(( char *str )); ...@@ -41,6 +41,7 @@ int str2access LDAP_P(( char *str ));
*/ */
void attr_free LDAP_P(( Attribute *a )); void attr_free LDAP_P(( Attribute *a ));
Attribute *attr_dup LDAP_P(( Attribute *a ));
char * attr_normalize LDAP_P(( char *s )); char * attr_normalize LDAP_P(( char *s ));
int attr_merge_fast LDAP_P(( Entry *e, char *type, struct berval **vals, int nvals, int attr_merge_fast LDAP_P(( Entry *e, char *type, struct berval **vals, int nvals,
int naddvals, int *maxvals, Attribute ***a )); int naddvals, int *maxvals, Attribute ***a ));
...@@ -58,6 +59,9 @@ int at_schema_info LDAP_P(( Entry *e )); ...@@ -58,6 +59,9 @@ int at_schema_info LDAP_P(( Entry *e ));
int at_add LDAP_P(( LDAP_ATTRIBUTE_TYPE *at, const char **err )); int at_add LDAP_P(( LDAP_ATTRIBUTE_TYPE *at, const char **err ));
char * at_canonical_name LDAP_P(( char * a_type )); 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 * ava.c
*/ */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment