2 * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
3 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6 * Copyright (c) 1995 Regents of the University of Michigan.
9 * Redistribution and use in source and binary forms are permitted
10 * provided that this notice is preserved and that due credit is given
11 * to the University of Michigan at Ann Arbor. The name of the University
12 * may not be used to endorse or promote products derived from this
13 * software without specific prior written permission. This software
14 * is provided ``as is'' without express or implied warranty.
26 char *textbuf, size_t textlen
31 MatchingRule *mr = mod->sm_desc->ad_type->sat_equality;
34 switch( mod->sm_op ) {
38 case LDAP_MOD_REPLACE:
46 a = attr_find( e->e_attrs, mod->sm_desc );
48 /* check if the values we're adding already exist */
49 if( mr == NULL || !mr->smr_match ) {
51 /* do not allow add of additional attribute
52 if no equality rule exists */
54 snprintf( textbuf, textlen,
55 "modify/%s: %s: no equality matching rule",
56 op, mod->sm_desc->ad_cname.bv_val );
57 return LDAP_INAPPROPRIATE_MATCHING;
60 for ( i = 0; mod->sm_bvalues[i].bv_val != NULL; i++ ) {
61 /* test asserted values against existing values */
63 for( j = 0; a->a_vals[j].bv_val != NULL; j++ ) {
64 int rc = ber_bvcmp( &mod->sm_bvalues[i],
68 /* value exists already */
70 snprintf( textbuf, textlen,
71 "modify/%s: %s: value #%i already exists",
72 op, mod->sm_desc->ad_cname.bv_val );
73 return LDAP_TYPE_OR_VALUE_EXISTS;
78 /* test asserted values against themselves */
79 for( j = 0; j < i; j++ ) {
80 int rc = ber_bvcmp( &mod->sm_bvalues[i],
81 &mod->sm_bvalues[j] );
84 /* value exists already */
86 snprintf( textbuf, textlen,
87 "modify/%s: %s: value #%i already exists",
88 op, mod->sm_desc->ad_cname.bv_val );
89 return LDAP_TYPE_OR_VALUE_EXISTS;
95 for ( i = 0; mod->sm_bvalues[i].bv_val != NULL; i++ ) {
97 struct berval asserted;
99 rc = value_normalize( mod->sm_desc,
105 if( rc != LDAP_SUCCESS ) return rc;
108 for ( j = 0; a->a_vals[j].bv_val != NULL; j++ ) {
109 int rc = value_match( &match, mod->sm_desc, mr,
110 SLAP_MR_VALUE_SYNTAX_MATCH,
111 &a->a_vals[j], &asserted, text );
113 if( rc == LDAP_SUCCESS && match == 0 ) {
114 free( asserted.bv_val );
115 return LDAP_TYPE_OR_VALUE_EXISTS;
120 for ( j = 0; j < i; j++ ) {
121 int rc = value_match( &match, mod->sm_desc, mr,
122 SLAP_MR_VALUE_SYNTAX_MATCH,
123 &mod->sm_bvalues[j], &asserted, text );
125 if( rc == LDAP_SUCCESS && match == 0 ) {
126 free( asserted.bv_val );
127 return LDAP_TYPE_OR_VALUE_EXISTS;
131 free( asserted.bv_val );
136 if( attr_merge( e, mod->sm_desc, mod->sm_bvalues ) != 0 ) {
137 /* this should return result of attr_merge */
139 snprintf( textbuf, textlen,
140 "modify/%s: %s: merge error",
141 op, mod->sm_desc->ad_cname.bv_val );
149 modify_delete_values(
153 char *textbuf, size_t textlen
158 char *desc = mod->sm_desc->ad_cname.bv_val;
159 MatchingRule *mr = mod->sm_desc->ad_type->sat_equality;
161 /* delete the entire attribute */
162 if ( mod->sm_bvalues == NULL ) {
163 int rc = attr_delete( &e->e_attrs, mod->sm_desc );
165 if( rc != LDAP_SUCCESS ) {
167 snprintf( textbuf, textlen,
168 "modify/delete: %s: no such attribute",
169 mod->sm_desc->ad_cname.bv_val );
170 rc = LDAP_NO_SUCH_ATTRIBUTE;
175 if( mr == NULL || !mr->smr_match ) {
176 /* disallow specific attributes from being deleted if
179 snprintf( textbuf, textlen,
180 "modify/delete: %s: no equality matching rule",
181 mod->sm_desc->ad_cname.bv_val );
182 return LDAP_INAPPROPRIATE_MATCHING;
185 /* delete specific values - find the attribute first */
186 if ( (a = attr_find( e->e_attrs, mod->sm_desc )) == NULL ) {
188 snprintf( textbuf, textlen,
189 "modify/delete: %s: no such attribute",
190 mod->sm_desc->ad_cname.bv_val );
191 return LDAP_NO_SUCH_ATTRIBUTE;
194 /* find each value to delete */
195 for ( i = 0; mod->sm_bvalues[i].bv_val != NULL; i++ ) {
197 struct berval asserted;
199 rc = value_normalize( mod->sm_desc,
205 if( rc != LDAP_SUCCESS ) return rc;
208 for ( j = 0; a->a_vals[j].bv_val != NULL; j++ ) {
210 int rc = value_match( &match, mod->sm_desc, mr,
211 SLAP_MR_VALUE_SYNTAX_MATCH,
212 &a->a_vals[j], &asserted, text );
214 if( rc == LDAP_SUCCESS && match != 0 ) {
218 /* found a matching value */
222 free( a->a_vals[j].bv_val );
223 for ( k = j + 1; a->a_vals[k].bv_val != NULL; k++ ) {
224 a->a_vals[k - 1] = a->a_vals[k];
226 a->a_vals[k - 1].bv_val = NULL;
227 a->a_vals[k - 1].bv_len = 0;
232 free( asserted.bv_val );
234 /* looked through them all w/o finding it */
237 snprintf( textbuf, textlen,
238 "modify/delete: %s: no such value",
239 mod->sm_desc->ad_cname.bv_val );
240 return LDAP_NO_SUCH_ATTRIBUTE;
244 /* if no values remain, delete the entire attribute */
245 if ( a->a_vals[0].bv_val == NULL ) {
246 if ( attr_delete( &e->e_attrs, mod->sm_desc ) ) {
248 snprintf( textbuf, textlen,
249 "modify/delete: %s: no such attribute",
250 mod->sm_desc->ad_cname.bv_val );
251 return LDAP_NO_SUCH_ATTRIBUTE;
259 modify_replace_values(
263 char *textbuf, size_t textlen
266 (void) attr_delete( &e->e_attrs, mod->sm_desc );
268 if ( mod->sm_bvalues ) {
269 return modify_add_values( e, mod, text, textbuf, textlen );
282 if ( mod->sm_type.bv_val)
283 free( mod->sm_type.bv_val );
285 if ( mod->sm_bvalues != NULL )
286 ber_bvarray_free( mod->sm_bvalues );
299 for ( ; ml != NULL; ml = next ) {
302 slap_mod_free( &ml->sml_mod, 0 );
314 for ( ; ml != NULL; ml = next ) {
320 if ( ml->ml_bvalues != NULL )
321 ber_bvecfree( ml->ml_bvalues );