]> git.sur5r.net Git - openldap/blob - servers/slapd/attr.c
cosmetic changes (the problem was not there)
[openldap] / servers / slapd / attr.c
1 /* attr.c - routines for dealing with attributes */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 1998-2005 The OpenLDAP Foundation.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted only as authorized by the OpenLDAP
10  * Public License.
11  *
12  * A copy of this license is available in the file LICENSE in the
13  * top-level directory of the distribution or, alternatively, at
14  * <http://www.OpenLDAP.org/license.html>.
15  */
16 /* Portions Copyright (c) 1995 Regents of the University of Michigan.
17  * All rights reserved.
18  *
19  * Redistribution and use in source and binary forms are permitted
20  * provided that this notice is preserved and that due credit is given
21  * to the University of Michigan at Ann Arbor. The name of the University
22  * may not be used to endorse or promote products derived from this
23  * software without specific prior written permission. This software
24  * is provided ``as is'' without express or implied warranty.
25  */
26
27 #include "portable.h"
28
29 #include <stdio.h>
30
31 #ifdef HAVE_FCNTL_H
32 #include <fcntl.h>
33 #endif
34
35 #include <ac/ctype.h>
36 #include <ac/errno.h>
37 #include <ac/socket.h>
38 #include <ac/string.h>
39 #include <ac/time.h>
40
41 #include "slap.h"
42
43 void
44 attr_free( Attribute *a )
45 {
46         if ( a->a_nvals && a->a_nvals != a->a_vals ) {
47                 ber_bvarray_free( a->a_nvals );
48         }
49         ber_bvarray_free( a->a_vals );
50         free( a );
51 }
52
53 #ifdef LDAP_COMP_MATCH
54 void
55 comp_tree_free( Attribute *a )
56 {
57         Attribute *next;
58
59         for( ; a != NULL ; a = next ) {
60                 next = a->a_next;
61                 if ( component_destructor && a->a_comp_data ) {
62                         if ( a->a_comp_data->cd_mem_op )
63                                 component_destructor( a->a_comp_data->cd_mem_op );
64                         free ( a->a_comp_data );
65                 }
66         }
67 }
68 #endif
69
70 void
71 attrs_free( Attribute *a )
72 {
73         Attribute *next;
74
75         for( ; a != NULL ; a = next ) {
76                 next = a->a_next;
77                 attr_free( a );
78         }
79 }
80
81 Attribute *
82 attr_dup( Attribute *a )
83 {
84         Attribute *tmp;
85
86         if ( a == NULL) return NULL;
87
88         tmp = ch_malloc( sizeof(Attribute) );
89
90         if ( a->a_vals != NULL ) {
91                 int i;
92
93                 for ( i = 0; !BER_BVISNULL( &a->a_vals[i] ); i++ ) {
94                         /* EMPTY */ ;
95                 }
96
97                 tmp->a_vals = ch_malloc( (i + 1) * sizeof(struct berval) );
98                 for ( i = 0; !BER_BVISNULL( &a->a_vals[i] ); i++ ) {
99                         ber_dupbv( &tmp->a_vals[i], &a->a_vals[i] );
100                         if ( BER_BVISNULL( &tmp->a_vals[i] ) ) break;
101                         /* FIXME: error? */
102                 }
103                 BER_BVZERO( &tmp->a_vals[i] );
104
105                 /* a_nvals must be non null; it may be equal to a_vals */
106                 assert( a->a_nvals );
107
108                 if ( a->a_nvals != a->a_vals ) {
109                         tmp->a_nvals = ch_malloc( (i + 1) * sizeof(struct berval) );
110                         for ( i = 0; !BER_BVISNULL( &a->a_nvals[i] ); i++ ) {
111                                 ber_dupbv( &tmp->a_nvals[i], &a->a_nvals[i] );
112                                 if ( BER_BVISNULL( &tmp->a_nvals[i] ) ) break;
113                                 /* FIXME: error? */
114                         }
115                         BER_BVZERO( &tmp->a_nvals[i] );
116
117                 } else {
118                         tmp->a_nvals = tmp->a_vals;
119                 }
120
121         } else {
122                 tmp->a_vals = NULL;
123                 tmp->a_nvals = NULL;
124         }
125
126         tmp->a_desc = a->a_desc;
127         tmp->a_next = NULL;
128         tmp->a_flags = 0;
129 #ifdef LDAP_COMP_MATCH
130         tmp->a_comp_data = NULL;
131 #endif
132
133         return tmp;
134 }
135
136 Attribute *
137 attrs_dup( Attribute *a )
138 {
139         Attribute *tmp, **next;
140
141         if( a == NULL ) return NULL;
142
143         tmp = NULL;
144         next = &tmp;
145
146         for( ; a != NULL ; a = a->a_next ) {
147                 *next = attr_dup( a );
148                 next = &((*next)->a_next);
149         }
150         *next = NULL;
151
152         return tmp;
153 }
154
155
156
157 /*
158  * attr_merge - merge the given type and value with the list of
159  * attributes in attrs.
160  *
161  * nvals must be NULL if the attribute has no normalizer.
162  * In this case, a->a_nvals will be set equal to a->a_vals.
163  *
164  * returns      0       everything went ok
165  *              -1      trouble
166  */
167
168 int
169 attr_merge(
170         Entry           *e,
171         AttributeDescription *desc,
172         BerVarray       vals,
173         BerVarray       nvals )
174 {
175         int rc;
176
177         Attribute       **a;
178
179         for ( a = &e->e_attrs; *a != NULL; a = &(*a)->a_next ) {
180                 if ( ad_cmp( (*a)->a_desc, desc ) == 0 ) {
181                         break;
182                 }
183         }
184
185         if ( *a == NULL ) {
186                 *a = (Attribute *) ch_malloc( sizeof(Attribute) );
187                 (*a)->a_desc = desc;
188                 (*a)->a_vals = NULL;
189                 (*a)->a_nvals = NULL;
190                 (*a)->a_next = NULL;
191                 (*a)->a_flags = 0;
192 #ifdef LDAP_COMP_MATCH
193                 (*a)->a_comp_data = NULL;
194 #endif
195         }
196
197         rc = value_add( &(*a)->a_vals, vals );
198
199         if ( rc == LDAP_SUCCESS ) {
200                 if ( nvals ) {
201                         rc = value_add( &(*a)->a_nvals, nvals );
202                         /* FIXME: what if rc != LDAP_SUCCESS ? */
203                 } else {
204                         (*a)->a_nvals = (*a)->a_vals;
205                 }
206         }
207
208         return rc;
209 }
210
211 int
212 attr_merge_normalize(
213         Entry           *e,
214         AttributeDescription *desc,
215         BerVarray       vals,
216         void     *memctx )
217 {
218         BerVarray       nvals = NULL;
219         int             rc;
220
221         if ( desc->ad_type->sat_equality &&
222                 desc->ad_type->sat_equality->smr_normalize )
223         {
224                 int     i;
225                 
226                 for ( i = 0; !BER_BVISNULL( &vals[i] ); i++ );
227
228                 nvals = slap_sl_calloc( sizeof(struct berval), i + 1, memctx );
229                 for ( i = 0; !BER_BVISNULL( &vals[i] ); i++ ) {
230                         rc = (*desc->ad_type->sat_equality->smr_normalize)(
231                                         SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
232                                         desc->ad_type->sat_syntax,
233                                         desc->ad_type->sat_equality,
234                                         &vals[i], &nvals[i], memctx );
235
236                         if ( rc != LDAP_SUCCESS ) {
237                                 BER_BVZERO( &nvals[i + 1] );
238                                 goto error_return;
239                         }
240                 }
241                 BER_BVZERO( &nvals[i] );
242         }
243
244         rc = attr_merge( e, desc, vals, nvals );
245
246 error_return:;
247         if ( nvals != NULL ) {
248                 ber_bvarray_free_x( nvals, memctx );
249         }
250         return rc;
251 }
252
253 int
254 attr_merge_one(
255         Entry           *e,
256         AttributeDescription *desc,
257         struct berval   *val,
258         struct berval   *nval )
259 {
260         int rc;
261         Attribute       **a;
262
263         for ( a = &e->e_attrs; *a != NULL; a = &(*a)->a_next ) {
264                 if ( ad_cmp( (*a)->a_desc, desc ) == 0 ) {
265                         break;
266                 }
267         }
268
269         if ( *a == NULL ) {
270                 *a = (Attribute *) ch_malloc( sizeof(Attribute) );
271                 (*a)->a_desc = desc;
272                 (*a)->a_vals = NULL;
273                 (*a)->a_nvals = NULL;
274                 (*a)->a_next = NULL;
275                 (*a)->a_flags = 0;
276 #ifdef LDAP_COMP_MATCH
277                 (*a)->a_comp_data = NULL;
278 #endif
279         }
280
281         rc = value_add_one( &(*a)->a_vals, val );
282
283         if ( rc == LDAP_SUCCESS ) {
284                 if ( nval ) {
285                         rc = value_add_one( &(*a)->a_nvals, nval );
286                         /* FIXME: what if rc != LDAP_SUCCESS ? */
287                 } else {
288                         (*a)->a_nvals = (*a)->a_vals;
289                 }
290         }
291         return rc;
292 }
293
294 int
295 attr_merge_normalize_one(
296         Entry           *e,
297         AttributeDescription *desc,
298         struct berval   *val,
299         void            *memctx )
300 {
301         struct berval   nval;
302         struct berval   *nvalp = NULL;
303         int             rc;
304
305         if ( desc->ad_type->sat_equality &&
306                 desc->ad_type->sat_equality->smr_normalize )
307         {
308                 rc = (*desc->ad_type->sat_equality->smr_normalize)(
309                                 SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
310                                 desc->ad_type->sat_syntax,
311                                 desc->ad_type->sat_equality,
312                                 val, &nval, memctx );
313
314                 if ( rc != LDAP_SUCCESS ) {
315                         return rc;
316                 }
317                 nvalp = &nval;
318         }
319
320         rc = attr_merge_one( e, desc, val, nvalp );
321         if ( nvalp != NULL ) {
322                 slap_sl_free( nval.bv_val, memctx );
323         }
324         return rc;
325 }
326
327 /*
328  * attrs_find - find attribute(s) by AttributeDescription
329  * returns next attribute which is subtype of provided description.
330  */
331
332 Attribute *
333 attrs_find(
334     Attribute   *a,
335         AttributeDescription *desc )
336 {
337         for ( ; a != NULL; a = a->a_next ) {
338                 if ( is_ad_subtype( a->a_desc, desc ) ) {
339                         return( a );
340                 }
341         }
342
343         return( NULL );
344 }
345
346 /*
347  * attr_find - find attribute by type
348  */
349
350 Attribute *
351 attr_find(
352     Attribute   *a,
353         AttributeDescription *desc )
354 {
355         for ( ; a != NULL; a = a->a_next ) {
356                 if ( ad_cmp( a->a_desc, desc ) == 0 ) {
357                         return( a );
358                 }
359         }
360
361         return( NULL );
362 }
363
364 /*
365  * attr_delete - delete the attribute type in list pointed to by attrs
366  * return       0       deleted ok
367  *              1       not found in list a
368  *              -1      something bad happened
369  */
370
371 int
372 attr_delete(
373     Attribute   **attrs,
374         AttributeDescription *desc )
375 {
376         Attribute       **a;
377
378         for ( a = attrs; *a != NULL; a = &(*a)->a_next ) {
379                 if ( ad_cmp( (*a)->a_desc, desc ) == 0 ) {
380                         Attribute       *save = *a;
381                         *a = (*a)->a_next;
382                         attr_free( save );
383
384                         return LDAP_SUCCESS;
385                 }
386         }
387
388         return LDAP_NO_SUCH_ATTRIBUTE;
389 }
390