attr.c 5.78 KB
Newer Older
1
/* $OpenLDAP$ */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
2
/*
Kurt Zeilenga's avatar
Kurt Zeilenga committed
3
 * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
Kurt Zeilenga's avatar
Kurt Zeilenga committed
4
5
 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
6
7
/* attr.c - routines for dealing with attributes */

Kurt Zeilenga's avatar
Kurt Zeilenga committed
8
9
#include "portable.h"

Kurt Zeilenga's avatar
Kurt Zeilenga committed
10
#include <stdio.h>
Kurt Zeilenga's avatar
Kurt Zeilenga committed
11
12

#ifdef HAVE_FCNTL_H
Kurt Zeilenga's avatar
Kurt Zeilenga committed
13
#include <fcntl.h>
Kurt Zeilenga's avatar
Kurt Zeilenga committed
14
15
16
#endif

#include <ac/ctype.h>
17
#include <ac/errno.h>
Kurt Zeilenga's avatar
Kurt Zeilenga committed
18
19
20
21
#include <ac/socket.h>
#include <ac/string.h>
#include <ac/time.h>

22
#include "ldap_pvt.h"
Kurt Zeilenga's avatar
Kurt Zeilenga committed
23
24
25
26
27
#include "slap.h"

void
attr_free( Attribute *a )
{
28
	ber_bvarray_free( a->a_vals );
29
	if (a->a_nvals != a->a_vals) ber_bvarray_free( a->a_nvals );
Kurt Zeilenga's avatar
Kurt Zeilenga committed
30
31
32
	free( a );
}

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
void
attrs_free( Attribute *a )
{
	Attribute *next;

	for( ; a != NULL ; a = next ) {
		next = a->a_next;
		attr_free( a );
	}
}

Attribute *attr_dup( Attribute *a )
{
	Attribute *tmp;

	if( a == NULL) return NULL;

	tmp = ch_malloc( sizeof(Attribute) );

	if( a->a_vals != NULL ) {
		int i;

55
		for( i=0; a->a_vals[i].bv_val != NULL; i++ ) {
56
57
58
			/* EMPTY */ ;
		}

59
60
61
62
		tmp->a_vals = ch_malloc((i+1) * sizeof(struct berval));
		for( i=0; a->a_vals[i].bv_val != NULL; i++ ) {
			ber_dupbv( &tmp->a_vals[i], &a->a_vals[i] );
			if( tmp->a_vals[i].bv_val == NULL ) break;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
63
64
		}
		tmp->a_vals[i].bv_val = NULL;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
65

66
		if( a->a_nvals != a->a_vals ) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
67
68
			tmp->a_nvals = ch_malloc((i+1) * sizeof(struct berval));
			for( i=0; a->a_nvals[i].bv_val != NULL; i++ ) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
69
70
71
72
				ber_dupbv( &tmp->a_nvals[i], &a->a_nvals[i] );
				if( tmp->a_nvals[i].bv_val == NULL ) break;
			}
			tmp->a_nvals[i].bv_val = NULL;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
73
74

		} else {
75
			tmp->a_nvals = tmp->a_vals;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
76
		}
77
78
79

	} else {
		tmp->a_vals = NULL;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
80
		tmp->a_nvals = NULL;
81
82
	}

83
	tmp->a_desc = a->a_desc;
84
	tmp->a_next = NULL;
85
	tmp->a_flags = 0;
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

	return tmp;
}

Attribute *attrs_dup( Attribute *a )
{
	Attribute *tmp, **next;

	if( a == NULL ) return NULL;

	tmp = NULL;
	next = &tmp;

	for( ; a != NULL ; a = a->a_next ) {
		*next = attr_dup( a );
		next = &((*next)->a_next);
	}
	*next = NULL;

	return tmp;
}

Kurt Zeilenga's avatar
Kurt Zeilenga committed
108

109

Kurt Zeilenga's avatar
Kurt Zeilenga committed
110
111
112
/*
 * attr_merge - merge the given type and value with the list of
 * attributes in attrs.
113
 *
Kurt Zeilenga's avatar
Kurt Zeilenga committed
114
115
 * nvals must be NULL if the attribute has no normalizer.
 * In this case, a->a_nvals will be set equal to a->a_vals.
116
 *
Kurt Zeilenga's avatar
Kurt Zeilenga committed
117
118
119
120
121
122
 * returns	0	everything went ok
 *		-1	trouble
 */

int
attr_merge(
123
	Entry		*e,
124
	AttributeDescription *desc,
125
126
	BerVarray	vals,
	BerVarray	nvals
Kurt Zeilenga's avatar
Kurt Zeilenga committed
127
128
129
) {
	int rc;

Kurt Zeilenga's avatar
Kurt Zeilenga committed
130
131
132
	Attribute	**a;

	for ( a = &e->e_attrs; *a != NULL; a = &(*a)->a_next ) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
133
		if ( ad_cmp( (*a)->a_desc, desc ) == 0 ) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
134
135
136
137
138
139
			break;
		}
	}

	if ( *a == NULL ) {
		*a = (Attribute *) ch_malloc( sizeof(Attribute) );
140
		(*a)->a_desc = desc;
141
		(*a)->a_vals = NULL;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
142
		(*a)->a_nvals = NULL;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
143
		(*a)->a_next = NULL;
144
		(*a)->a_flags = 0;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
145
146
	}

Kurt Zeilenga's avatar
Kurt Zeilenga committed
147
148
149
	rc = value_add( &(*a)->a_vals, vals );

	if( !rc && nvals ) rc = value_add( &(*a)->a_nvals, nvals );
150
	else (*a)->a_nvals = (*a)->a_vals;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
151
152

	return rc;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
153
154
}

155
156
157
158
int
attr_merge_normalize(
	Entry		*e,
	AttributeDescription *desc,
Howard Chu's avatar
Howard Chu committed
159
160
	BerVarray	vals,
	void	 *memctx
161
162
163
164
) {
	BerVarray	nvals = NULL;
	int		rc;

165
166
167
	if ( desc->ad_type->sat_equality &&
		desc->ad_type->sat_equality->smr_normalize )
	{
168
169
		int	i;
		
170
		for ( i = 0; vals[i].bv_val; i++ );
171

Howard Chu's avatar
Howard Chu committed
172
		nvals = sl_calloc( sizeof(struct berval), i + 1, memctx );
173
174
		for ( i = 0; vals[i].bv_val; i++ ) {
			rc = (*desc->ad_type->sat_equality->smr_normalize)(
175
					SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
176
177
					desc->ad_type->sat_syntax,
					desc->ad_type->sat_equality,
Howard Chu's avatar
Howard Chu committed
178
					&vals[i], &nvals[i], memctx );
179
180
181
182
183
184
185
186
187
188
189
190

			if ( rc != LDAP_SUCCESS ) {
				nvals[i+1].bv_val = NULL;
				goto error_return;
			}
		}
		nvals[i].bv_val = NULL;
	}

	rc = attr_merge( e, desc, vals, nvals );

error_return:;
191
	if ( nvals != NULL ) {
Howard Chu's avatar
Howard Chu committed
192
		ber_bvarray_free_x( nvals, memctx );
193
	}
194
195
196
	return rc;
}

197
198
199
200
int
attr_merge_one(
	Entry		*e,
	AttributeDescription *desc,
201
202
	struct berval	*val,
	struct berval	*nval
Kurt Zeilenga's avatar
Kurt Zeilenga committed
203
204
) {
	int rc;
205
206
207
208
209
210
211
212
213
214
215
216
	Attribute	**a;

	for ( a = &e->e_attrs; *a != NULL; a = &(*a)->a_next ) {
		if ( ad_cmp( (*a)->a_desc, desc ) == 0 ) {
			break;
		}
	}

	if ( *a == NULL ) {
		*a = (Attribute *) ch_malloc( sizeof(Attribute) );
		(*a)->a_desc = desc;
		(*a)->a_vals = NULL;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
217
		(*a)->a_nvals = NULL;
218
219
220
221
		(*a)->a_next = NULL;
		(*a)->a_flags = 0;
	}

Kurt Zeilenga's avatar
Kurt Zeilenga committed
222
223
224
	rc = value_add_one( &(*a)->a_vals, val );

	if( !rc && nval ) rc = value_add_one( &(*a)->a_nvals, nval );
225
	else (*a)->a_nvals = (*a)->a_vals;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
226
	return rc;
227
228
}

229
230
231
232
int
attr_merge_normalize_one(
	Entry		*e,
	AttributeDescription *desc,
Howard Chu's avatar
Howard Chu committed
233
234
	struct berval	*val,
	void		*memctx
235
236
) {
	struct berval	nval;
237
	struct berval	*nvalp;
238
239
	int		rc;

240
241
242
	if ( desc->ad_type->sat_equality &&
		desc->ad_type->sat_equality->smr_normalize )
	{
243
		rc = (*desc->ad_type->sat_equality->smr_normalize)(
244
				SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
245
246
				desc->ad_type->sat_syntax,
				desc->ad_type->sat_equality,
Howard Chu's avatar
Howard Chu committed
247
				val, &nval, memctx );
248
249
250
251

		if ( rc != LDAP_SUCCESS ) {
			return rc;
		}
252
253
254
		nvalp = &nval;
	} else {
		nvalp = NULL;
255
256
	}

257
258
	rc = attr_merge_one( e, desc, val, nvalp );
	if ( nvalp != NULL ) {
Howard Chu's avatar
Howard Chu committed
259
		sl_free( nval.bv_val, memctx );
260
	}
261
262
263
	return rc;
}

264
265
266
267
268
269
270
271
272
273
274
275
/*
 * attrs_find - find attribute(s) by AttributeDescription
 * returns next attribute which is subtype of provided description.
 */

Attribute *
attrs_find(
    Attribute	*a,
	AttributeDescription *desc
)
{
	for ( ; a != NULL; a = a->a_next ) {
276
		if ( is_ad_subtype( a->a_desc, desc ) ) {
277
278
279
280
281
282
283
			return( a );
		}
	}

	return( NULL );
}

Kurt Zeilenga's avatar
Kurt Zeilenga committed
284
/*
285
 * attr_find - find attribute by type
Kurt Zeilenga's avatar
Kurt Zeilenga committed
286
287
288
289
290
 */

Attribute *
attr_find(
    Attribute	*a,
291
	AttributeDescription *desc
Kurt Zeilenga's avatar
Kurt Zeilenga committed
292
293
294
)
{
	for ( ; a != NULL; a = a->a_next ) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
295
		if ( ad_cmp( a->a_desc, desc ) == 0 ) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
			return( a );
		}
	}

	return( NULL );
}

/*
 * attr_delete - delete the attribute type in list pointed to by attrs
 * return	0	deleted ok
 * 		1	not found in list a
 * 		-1	something bad happened
 */

int
attr_delete(
    Attribute	**attrs,
313
	AttributeDescription *desc
Kurt Zeilenga's avatar
Kurt Zeilenga committed
314
315
316
317
318
)
{
	Attribute	**a;

	for ( a = attrs; *a != NULL; a = &(*a)->a_next ) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
319
		if ( ad_cmp( (*a)->a_desc, desc ) == 0 ) {
320
321
322
			Attribute	*save = *a;
			*a = (*a)->a_next;
			attr_free( save );
Kurt Zeilenga's avatar
Kurt Zeilenga committed
323

324
			return LDAP_SUCCESS;
325
		}
Kurt Zeilenga's avatar
Kurt Zeilenga committed
326
327
	}

328
	return LDAP_NO_SUCH_ATTRIBUTE;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
329
330
}