X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fmods.c;h=147e2d82674ac5314d4ed03962273c08d2a5c7bf;hb=bd1543ce44c8478d8785cabbe449516167d72141;hp=cb09775ac8217b12ec0b9f07c15059d2b372c3d4;hpb=c75be97ae946dab41f002a31d8347cc38cda7658;p=openldap diff --git a/servers/slapd/mods.c b/servers/slapd/mods.c index cb09775ac8..147e2d8267 100644 --- a/servers/slapd/mods.c +++ b/servers/slapd/mods.c @@ -1,9 +1,18 @@ -/* - * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. - * COPYING RESTRICTIONS APPLY, see COPYRIGHT file +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2003 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . */ -/* - * Copyright (c) 1995 Regents of the University of Michigan. +/* Portions Copyright (c) 1995 Regents of the University of Michigan. * All rights reserved. * * Redistribution and use in source and binary forms are permitted @@ -16,6 +25,8 @@ #include "portable.h" +#include + #include "slap.h" int @@ -40,8 +51,7 @@ modify_add_values( Modification *mod, int permissive, const char **text, - char *textbuf, size_t textlen -) + char *textbuf, size_t textlen ) { int i, j; int matched; @@ -164,7 +174,7 @@ modify_add_values( *text = textbuf; snprintf( textbuf, textlen, "modify/%s: %s: value #0 already exists", - op, mod->sm_desc->ad_cname.bv_val, 0 ); + op, mod->sm_desc->ad_cname.bv_val ); return LDAP_TYPE_OR_VALUE_EXISTS; } } @@ -176,8 +186,8 @@ modify_add_values( } else { rc = modify_check_duplicates( mod->sm_desc, mr, - a ? a->a_vals : NULL, mod->sm_bvalues, - permissive, text, textbuf, textlen ); + a ? a->a_vals : NULL, mod->sm_bvalues, + permissive, text, textbuf, textlen ); if ( permissive && rc == LDAP_TYPE_OR_VALUE_EXISTS ) { return LDAP_SUCCESS; @@ -190,8 +200,7 @@ modify_add_values( } /* no - add them */ - if( attr_merge( e, mod->sm_desc, mod->sm_values, mod->sm_nvalues ) != 0 ) - { + if( attr_merge( e, mod->sm_desc, mod->sm_values, mod->sm_nvalues ) != 0 ) { /* this should return result of attr_merge */ *text = textbuf; snprintf( textbuf, textlen, @@ -216,6 +225,7 @@ modify_delete_values( Attribute *a; MatchingRule *mr = mod->sm_desc->ad_type->sat_equality; char dummy = '\0'; + int match = 0; /* * If permissive is set, then the non-existence of an @@ -263,9 +273,7 @@ modify_delete_values( for ( i = 0; mod->sm_values[i].bv_val != NULL; i++ ) { int found = 0; - for ( j = 0; a->a_vals[j].bv_val != NULL; j++ ) - { - int match; + for ( j = 0; a->a_vals[j].bv_val != NULL; j++ ) { if( mod->sm_nvalues ) { assert( a->a_nvals ); @@ -292,7 +300,7 @@ modify_delete_values( snprintf( textbuf, textlen, "%s: matching rule failed", mod->sm_desc->ad_cname.bv_val ); - goto return_results; + break; } if ( match != 0 ) { @@ -312,20 +320,22 @@ modify_delete_values( break; } - if ( found == 0 ) { *text = textbuf; snprintf( textbuf, textlen, "modify/delete: %s: no such value", mod->sm_desc->ad_cname.bv_val ); rc = LDAP_NO_SUCH_ATTRIBUTE; - goto return_results; + if ( i > 0 ) { + break; + } else { + goto return_results; + } } } /* compact array skipping dummies */ - for ( k = 0, j = 0; a->a_vals[k].bv_val != NULL; k++ ) - { + for ( k = 0, j = 0; a->a_vals[k].bv_val != NULL; k++ ) { /* skip dummies */ if( a->a_vals[k].bv_val == &dummy ) { assert( a->a_nvals == NULL || a->a_nvals[k].bv_val == &dummy ); @@ -366,8 +376,7 @@ modify_replace_values( Modification *mod, int permissive, const char **text, - char *textbuf, size_t textlen -) + char *textbuf, size_t textlen ) { (void) attr_delete( &e->e_attrs, mod->sm_desc ); @@ -378,11 +387,67 @@ modify_replace_values( return LDAP_SUCCESS; } +int +modify_increment_values( + Entry *e, + Modification *mod, + int permissive, + const char **text, + char *textbuf, size_t textlen ) +{ + Attribute *a; + + 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 ( !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_bvalues[0].bv_val ); + + /* treat zero and errors as a no-op */ + if( incr == 0 ) { + return LDAP_SUCCESS; + } + + for( i=0; a->a_nvals[i].bv_val != NULL; i++ ) { + char *tmp; + long value = atol( a->a_nvals[i].bv_val ); + size_t 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;; + } + a->a_nvals[i].bv_val = tmp; + a->a_nvals[i].bv_len = strln; + + AC_MEMCPY( a->a_nvals[i].bv_val, str, strln+1 ); + } + + } else { + snprintf( textbuf, textlen, + "modify/increment: %s: increment not supported for value syntax %s", + mod->sm_desc->ad_cname.bv_val, + a->a_desc->ad_type->sat_syntax_oid ); + return LDAP_CONSTRAINT_VIOLATION; + } + + return LDAP_SUCCESS; +} + void slap_mod_free( Modification *mod, - int freeit -) + int freeit ) { if ( mod->sm_values != NULL ) ber_bvarray_free( mod->sm_values ); mod->sm_values = NULL; @@ -395,8 +460,7 @@ slap_mod_free( void slap_mods_free( - Modifications *ml -) + Modifications *ml ) { Modifications *next;