X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fmods.c;h=f1dbdffcb804468ef7db1ad83b7d3e8358aeeae0;hb=fa1f4d3c38b332fc5faf6d84911df2618ce9af09;hp=7ebba1b3e6a1cbac156b70b9e90974fc2665b122;hpb=81ecb0b1536785c830a264243c969e03a3858af6;p=openldap diff --git a/servers/slapd/mods.c b/servers/slapd/mods.c index 7ebba1b3e6..f1dbdffcb8 100644 --- a/servers/slapd/mods.c +++ b/servers/slapd/mods.c @@ -1,7 +1,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2005 The OpenLDAP Foundation. + * Copyright 1998-2006 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,6 +28,7 @@ #include #include "slap.h" +#include "lutil.h" int modify_add_values( @@ -73,11 +74,15 @@ modify_add_values( } if ( permissive ) { - for ( i = 0; !BER_BVISNULL( &mod->sm_values[i] ); i++ ) /* count 'em */; - pmod.sm_values = (BerVarray)ch_malloc( (i + 1)*sizeof( struct berval ) ); + for ( i = 0; !BER_BVISNULL( &mod->sm_values[i] ); i++ ) { + /* EMPTY -- just counting 'em */; + } + + pmod.sm_values = (BerVarray)ch_malloc( + (i + 1) * sizeof( struct berval )); if ( pmod.sm_nvalues != NULL ) { pmod.sm_nvalues = (BerVarray)ch_malloc( - (i + 1)*sizeof( struct berval ) ); + (i + 1) * sizeof( struct berval )); } } @@ -334,7 +339,7 @@ modify_delete_vindex( rc = LDAP_NO_SUCH_ATTRIBUTE; } } else if ( a->a_desc->ad_type->sat_flags & SLAP_AT_ORDERED_VAL ) { - /* For an ordered attribute, renumber the value indices */ + /* For an ordered attribute, renumber the value indices */ ordered_value_sort( a, 1 ); } @@ -372,17 +377,30 @@ modify_increment_values( a = attr_find( e->e_attrs, mod->sm_desc ); if( a == NULL ) { - *text = textbuf; - snprintf( textbuf, textlen, - "modify/increment: %s: no such attribute", - mod->sm_desc->ad_cname.bv_val ); - return LDAP_NO_SUCH_ATTRIBUTE; + if ( permissive ) { + Modification modReplace = *mod; + + modReplace.sm_op = LDAP_MOD_REPLACE; + + return modify_add_values(e, &modReplace, permissive, text, textbuf, textlen); + } else { + *text = textbuf; + snprintf( textbuf, textlen, + "modify/increment: %s: no such attribute", + mod->sm_desc->ad_cname.bv_val ); + return LDAP_NO_SUCH_ATTRIBUTE; + } } if ( !strcmp( a->a_desc->ad_type->sat_syntax_oid, SLAPD_INTEGER_SYNTAX )) { int i; char str[sizeof(long)*3 + 2]; /* overly long */ - long incr = atol( mod->sm_values[0].bv_val ); + long incr; + + if ( lutil_atol( &incr, mod->sm_values[0].bv_val ) != 0 ) { + *text = "modify/increment: invalid syntax of increment"; + return LDAP_INVALID_SYNTAX; + } /* treat zero and errors as a no-op */ if( incr == 0 ) { @@ -391,13 +409,18 @@ modify_increment_values( for( i = 0; !BER_BVISNULL( &a->a_nvals[i] ); i++ ) { char *tmp; - long value = atol( a->a_nvals[i].bv_val ); - size_t strln = snprintf( str, sizeof(str), "%ld", value+incr ); + long value; + size_t strln; + if ( lutil_atol( &value, a->a_nvals[i].bv_val ) != 0 ) { + *text = "modify/increment: invalid syntax of original value"; + return LDAP_INVALID_SYNTAX; + } + strln = snprintf( str, sizeof(str), "%ld", value+incr ); tmp = SLAP_REALLOC( a->a_nvals[i].bv_val, strln+1 ); if( tmp == NULL ) { *text = "modify/increment: reallocation error"; - return LDAP_OTHER;; + return LDAP_OTHER; } a->a_nvals[i].bv_val = tmp; a->a_nvals[i].bv_len = strln; @@ -432,14 +455,16 @@ slap_mod_free( void slap_mods_free( - Modifications *ml ) + Modifications *ml, + int freevals ) { Modifications *next; for ( ; ml != NULL; ml = next ) { next = ml->sml_next; - slap_mod_free( &ml->sml_mod, 0 ); + if ( freevals ) + slap_mod_free( &ml->sml_mod, 0 ); free( ml ); } }