]> git.sur5r.net Git - openldap/blob - servers/slapd/attr.c
762c90cb6f5025d49df038935175307bebe0f94a
[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-2004 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 "ldap_pvt.h"
42 #include "slap.h"
43
44 void
45 attr_free( Attribute *a )
46 {
47         if ( a->a_nvals && a->a_nvals != a->a_vals )
48                 ber_bvarray_free( a->a_nvals );
49         ber_bvarray_free( a->a_vals );
50         free( a );
51 }
52
53 void
54 attrs_free( Attribute *a )
55 {
56         Attribute *next;
57
58         for( ; a != NULL ; a = next ) {
59                 next = a->a_next;
60                 attr_free( a );
61         }
62 }
63
64 Attribute *attr_dup( Attribute *a )
65 {
66         Attribute *tmp;
67
68         if( a == NULL) return NULL;
69
70         tmp = ch_malloc( sizeof(Attribute) );
71
72         if( a->a_vals != NULL ) {
73                 int i;
74
75                 for( i=0; a->a_vals[i].bv_val != NULL; i++ ) {
76                         /* EMPTY */ ;
77                 }
78
79                 tmp->a_vals = ch_malloc((i+1) * sizeof(struct berval));
80                 for( i=0; a->a_vals[i].bv_val != NULL; i++ ) {
81                         ber_dupbv( &tmp->a_vals[i], &a->a_vals[i] );
82                         if( BER_BVISNULL( &tmp->a_vals[i] ) ) break;
83                 }
84                 BER_BVZERO( &tmp->a_vals[i] );
85
86                 if( a->a_nvals != a->a_vals ) {
87                         tmp->a_nvals = ch_malloc((i+1) * sizeof(struct berval));
88                         for( i=0; a->a_nvals[i].bv_val != NULL; i++ ) {
89                                 ber_dupbv( &tmp->a_nvals[i], &a->a_nvals[i] );
90                                 if( BER_BVISNULL( &tmp->a_nvals[i] ) ) break;
91                         }
92                         BER_BVZERO( &tmp->a_nvals[i] );
93
94                 } else {
95                         tmp->a_nvals = tmp->a_vals;
96                 }
97
98         } else {
99                 tmp->a_vals = NULL;
100                 tmp->a_nvals = NULL;
101         }
102
103         tmp->a_desc = a->a_desc;
104         tmp->a_next = NULL;
105         tmp->a_flags = 0;
106
107         return tmp;
108 }
109
110 Attribute *attrs_dup( Attribute *a )
111 {
112         Attribute *tmp, **next;
113
114         if( a == NULL ) return NULL;
115
116         tmp = NULL;
117         next = &tmp;
118
119         for( ; a != NULL ; a = a->a_next ) {
120                 *next = attr_dup( a );
121                 next = &((*next)->a_next);
122         }
123         *next = NULL;
124
125         return tmp;
126 }
127
128
129
130 /*
131  * attr_merge - merge the given type and value with the list of
132  * attributes in attrs.
133  *
134  * nvals must be NULL if the attribute has no normalizer.
135  * In this case, a->a_nvals will be set equal to a->a_vals.
136  *
137  * returns      0       everything went ok
138  *              -1      trouble
139  */
140
141 int
142 attr_merge(
143         Entry           *e,
144         AttributeDescription *desc,
145         BerVarray       vals,
146         BerVarray       nvals )
147 {
148         int rc;
149
150         Attribute       **a;
151
152         for ( a = &e->e_attrs; *a != NULL; a = &(*a)->a_next ) {
153                 if ( ad_cmp( (*a)->a_desc, desc ) == 0 ) {
154                         break;
155                 }
156         }
157
158         if ( *a == NULL ) {
159                 *a = (Attribute *) ch_malloc( sizeof(Attribute) );
160                 (*a)->a_desc = desc;
161                 (*a)->a_vals = NULL;
162                 (*a)->a_nvals = NULL;
163                 (*a)->a_next = NULL;
164                 (*a)->a_flags = 0;
165         }
166
167         rc = value_add( &(*a)->a_vals, vals );
168
169         if( !rc && nvals ) rc = value_add( &(*a)->a_nvals, nvals );
170         else (*a)->a_nvals = (*a)->a_vals;
171
172         return rc;
173 }
174
175 int
176 attr_merge_normalize(
177         Entry           *e,
178         AttributeDescription *desc,
179         BerVarray       vals,
180         void     *memctx )
181 {
182         BerVarray       nvals = NULL;
183         int             rc;
184
185         if ( desc->ad_type->sat_equality &&
186                 desc->ad_type->sat_equality->smr_normalize )
187         {
188                 int     i;
189                 
190                 for ( i = 0; vals[i].bv_val; i++ );
191
192                 nvals = slap_sl_calloc( sizeof(struct berval), i + 1, memctx );
193                 for ( i = 0; vals[i].bv_val; i++ ) {
194                         rc = (*desc->ad_type->sat_equality->smr_normalize)(
195                                         SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
196                                         desc->ad_type->sat_syntax,
197                                         desc->ad_type->sat_equality,
198                                         &vals[i], &nvals[i], memctx );
199
200                         if ( rc != LDAP_SUCCESS ) {
201                                 BER_BVZERO( &nvals[i+1] );
202                                 goto error_return;
203                         }
204                 }
205                 BER_BVZERO( &nvals[i] );
206         }
207
208         rc = attr_merge( e, desc, vals, nvals );
209
210 error_return:;
211         if ( nvals != NULL ) {
212                 ber_bvarray_free_x( nvals, memctx );
213         }
214         return rc;
215 }
216
217 int
218 attr_merge_one(
219         Entry           *e,
220         AttributeDescription *desc,
221         struct berval   *val,
222         struct berval   *nval )
223 {
224         int rc;
225         Attribute       **a;
226
227         for ( a = &e->e_attrs; *a != NULL; a = &(*a)->a_next ) {
228                 if ( ad_cmp( (*a)->a_desc, desc ) == 0 ) {
229                         break;
230                 }
231         }
232
233         if ( *a == NULL ) {
234                 *a = (Attribute *) ch_malloc( sizeof(Attribute) );
235                 (*a)->a_desc = desc;
236                 (*a)->a_vals = NULL;
237                 (*a)->a_nvals = NULL;
238                 (*a)->a_next = NULL;
239                 (*a)->a_flags = 0;
240         }
241
242         rc = value_add_one( &(*a)->a_vals, val );
243
244         if( !rc && nval ) rc = value_add_one( &(*a)->a_nvals, nval );
245         else (*a)->a_nvals = (*a)->a_vals;
246         return rc;
247 }
248
249 int
250 attr_merge_normalize_one(
251         Entry           *e,
252         AttributeDescription *desc,
253         struct berval   *val,
254         void            *memctx )
255 {
256         struct berval   nval;
257         struct berval   *nvalp;
258         int             rc;
259
260         if ( desc->ad_type->sat_equality &&
261                 desc->ad_type->sat_equality->smr_normalize )
262         {
263                 rc = (*desc->ad_type->sat_equality->smr_normalize)(
264                                 SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
265                                 desc->ad_type->sat_syntax,
266                                 desc->ad_type->sat_equality,
267                                 val, &nval, memctx );
268
269                 if ( rc != LDAP_SUCCESS ) {
270                         return rc;
271                 }
272                 nvalp = &nval;
273         } else {
274                 nvalp = NULL;
275         }
276
277         rc = attr_merge_one( e, desc, val, nvalp );
278         if ( nvalp != NULL ) {
279                 slap_sl_free( nval.bv_val, memctx );
280         }
281         return rc;
282 }
283
284 /*
285  * attrs_find - find attribute(s) by AttributeDescription
286  * returns next attribute which is subtype of provided description.
287  */
288
289 Attribute *
290 attrs_find(
291     Attribute   *a,
292         AttributeDescription *desc )
293 {
294         for ( ; a != NULL; a = a->a_next ) {
295                 if ( is_ad_subtype( a->a_desc, desc ) ) {
296                         return( a );
297                 }
298         }
299
300         return( NULL );
301 }
302
303 /*
304  * attr_find - find attribute by type
305  */
306
307 Attribute *
308 attr_find(
309     Attribute   *a,
310         AttributeDescription *desc )
311 {
312         for ( ; a != NULL; a = a->a_next ) {
313                 if ( ad_cmp( a->a_desc, desc ) == 0 ) {
314                         return( a );
315                 }
316         }
317
318         return( NULL );
319 }
320
321 /*
322  * attr_delete - delete the attribute type in list pointed to by attrs
323  * return       0       deleted ok
324  *              1       not found in list a
325  *              -1      something bad happened
326  */
327
328 int
329 attr_delete(
330     Attribute   **attrs,
331         AttributeDescription *desc )
332 {
333         Attribute       **a;
334
335         for ( a = attrs; *a != NULL; a = &(*a)->a_next ) {
336                 if ( ad_cmp( (*a)->a_desc, desc ) == 0 ) {
337                         Attribute       *save = *a;
338                         *a = (*a)->a_next;
339                         attr_free( save );
340
341                         return LDAP_SUCCESS;
342                 }
343         }
344
345         return LDAP_NO_SUCH_ATTRIBUTE;
346 }
347