xref: /netbsd-src/external/bsd/openldap/dist/servers/slapd/entry.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
1 /*	$NetBSD: entry.c,v 1.1.1.4 2014/05/28 09:58:46 tron Exp $	*/
2 
3 /* entry.c - routines for dealing with entries */
4 /* $OpenLDAP$ */
5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6  *
7  * Copyright 1998-2014 The OpenLDAP Foundation.
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted only as authorized by the OpenLDAP
12  * Public License.
13  *
14  * A copy of this license is available in the file LICENSE in the
15  * top-level directory of the distribution or, alternatively, at
16  * <http://www.OpenLDAP.org/license.html>.
17  */
18 /* Portions Copyright (c) 1995 Regents of the University of Michigan.
19  * All rights reserved.
20  *
21  * Redistribution and use in source and binary forms are permitted
22  * provided that this notice is preserved and that due credit is given
23  * to the University of Michigan at Ann Arbor. The name of the University
24  * may not be used to endorse or promote products derived from this
25  * software without specific prior written permission. This software
26  * is provided ``as is'' without express or implied warranty.
27  */
28 
29 #include "portable.h"
30 
31 #include <stdio.h>
32 
33 #include <ac/ctype.h>
34 #include <ac/errno.h>
35 #include <ac/socket.h>
36 #include <ac/string.h>
37 
38 #include "slap.h"
39 #include "ldif.h"
40 
41 static char		*ebuf;	/* buf returned by entry2str		 */
42 static char		*ecur;	/* pointer to end of currently used ebuf */
43 static int		emaxsize;/* max size of ebuf			 */
44 
45 /*
46  * Empty root entry
47  */
48 const Entry slap_entry_root = {
49 	NOID, { 0, "" }, { 0, "" }, NULL, 0, { 0, "" }, NULL
50 };
51 
52 /*
53  * these mutexes must be used when calling the entry2str()
54  * routine since it returns a pointer to static data.
55  */
56 ldap_pvt_thread_mutex_t	entry2str_mutex;
57 
58 static const struct berval dn_bv = BER_BVC("dn");
59 
60 /*
61  * Entry free list
62  *
63  * Allocate in chunks, minimum of 1000 at a time.
64  */
65 #define	CHUNK_SIZE	1000
66 typedef struct slap_list {
67 	struct slap_list *next;
68 } slap_list;
69 static slap_list *entry_chunks;
70 static Entry *entry_list;
71 static ldap_pvt_thread_mutex_t entry_mutex;
72 
73 int entry_destroy(void)
74 {
75 	slap_list *e;
76 	if ( ebuf ) free( ebuf );
77 	ebuf = NULL;
78 	ecur = NULL;
79 	emaxsize = 0;
80 
81 	for ( e=entry_chunks; e; e=entry_chunks ) {
82 		entry_chunks = e->next;
83 		free( e );
84 	}
85 
86 	ldap_pvt_thread_mutex_destroy( &entry_mutex );
87 	ldap_pvt_thread_mutex_destroy( &entry2str_mutex );
88 	return attr_destroy();
89 }
90 
91 int
92 entry_init(void)
93 {
94 	ldap_pvt_thread_mutex_init( &entry2str_mutex );
95 	ldap_pvt_thread_mutex_init( &entry_mutex );
96 	return attr_init();
97 }
98 
99 Entry *
100 str2entry( char *s )
101 {
102 	return str2entry2( s, 1 );
103 }
104 
105 #define bvcasematch(bv1, bv2)	(ber_bvstrcasecmp(bv1, bv2) == 0)
106 
107 Entry *
108 str2entry2( char *s, int checkvals )
109 {
110 	int rc;
111 	Entry		*e;
112 	struct berval	*type, *vals, *nvals;
113 	char 	*freeval;
114 	AttributeDescription *ad, *ad_prev;
115 	const char *text;
116 	char	*next;
117 	int		attr_cnt;
118 	int		i, lines;
119 	Attribute	ahead, *atail;
120 
121 	/*
122 	 * LDIF is used as the string format.
123 	 * An entry looks like this:
124 	 *
125 	 *	dn: <dn>\n
126 	 *	[<attr>:[:] <value>\n]
127 	 *	[<tab><continuedvalue>\n]*
128 	 *	...
129 	 *
130 	 * If a double colon is used after a type, it means the
131 	 * following value is encoded as a base 64 string.  This
132 	 * happens if the value contains a non-printing character
133 	 * or newline.
134 	 */
135 
136 	Debug( LDAP_DEBUG_TRACE, "=> str2entry: \"%s\"\n",
137 		s ? s : "NULL", 0, 0 );
138 
139 	e = entry_alloc();
140 
141 	if( e == NULL ) {
142 		Debug( LDAP_DEBUG_ANY,
143 			"<= str2entry NULL (entry allocation failed)\n",
144 			0, 0, 0 );
145 		return( NULL );
146 	}
147 
148 	/* initialize entry */
149 	e->e_id = NOID;
150 
151 	/* dn + attributes */
152 	atail = &ahead;
153 	ahead.a_next = NULL;
154 	ad = NULL;
155 	ad_prev = NULL;
156 	attr_cnt = 0;
157 	next = s;
158 
159 	lines = ldif_countlines( s );
160 	type = ch_calloc( 1, (lines+1)*3*sizeof(struct berval)+lines );
161 	vals = type+lines+1;
162 	nvals = vals+lines+1;
163 	freeval = (char *)(nvals+lines+1);
164 	i = -1;
165 
166 	/* parse into individual values, record DN */
167 	while ( (s = ldif_getline( &next )) != NULL ) {
168 		int freev;
169 		if ( *s == '\n' || *s == '\0' ) {
170 			break;
171 		}
172 		i++;
173 		if (i >= lines) {
174 			Debug( LDAP_DEBUG_TRACE,
175 				"<= str2entry ran past end of entry\n", 0, 0, 0 );
176 			goto fail;
177 		}
178 
179 		rc = ldif_parse_line2( s, type+i, vals+i, &freev );
180 		freeval[i] = freev;
181 		if ( rc ) {
182 			Debug( LDAP_DEBUG_TRACE,
183 				"<= str2entry NULL (parse_line)\n", 0, 0, 0 );
184 			continue;
185 		}
186 
187 		if ( bvcasematch( &type[i], &dn_bv ) ) {
188 			if ( e->e_dn != NULL ) {
189 				Debug( LDAP_DEBUG_ANY, "str2entry: "
190 					"entry %ld has multiple DNs \"%s\" and \"%s\"\n",
191 					(long) e->e_id, e->e_dn, vals[i].bv_val );
192 				goto fail;
193 			}
194 
195 			rc = dnPrettyNormal( NULL, &vals[i], &e->e_name, &e->e_nname, NULL );
196 			if( rc != LDAP_SUCCESS ) {
197 				Debug( LDAP_DEBUG_ANY, "str2entry: "
198 					"entry %ld has invalid DN \"%s\"\n",
199 					(long) e->e_id, vals[i].bv_val, 0 );
200 				goto fail;
201 			}
202 			if ( freeval[i] ) free( vals[i].bv_val );
203 			vals[i].bv_val = NULL;
204 			i--;
205 			continue;
206 		}
207 	}
208 	lines = i+1;
209 
210 	/* check to make sure there was a dn: line */
211 	if ( BER_BVISNULL( &e->e_name )) {
212 		Debug( LDAP_DEBUG_ANY, "str2entry: entry %ld has no dn\n",
213 			(long) e->e_id, 0, 0 );
214 		goto fail;
215 	}
216 
217 	/* Make sure all attributes with multiple values are contiguous */
218 	if ( checkvals ) {
219 		int j, k;
220 		struct berval bv;
221 		int fv;
222 
223 		for (i=0; i<lines; i++) {
224 			for ( j=i+1; j<lines; j++ ) {
225 				if ( bvcasematch( type+i, type+j )) {
226 					/* out of order, move intervening attributes down */
227 					if ( j != i+1 ) {
228 						bv = vals[j];
229 						fv = freeval[j];
230 						for ( k=j; k>i; k-- ) {
231 							type[k] = type[k-1];
232 							vals[k] = vals[k-1];
233 							freeval[k] = freeval[k-1];
234 						}
235 						k++;
236 						type[k] = type[i];
237 						vals[k] = bv;
238 						freeval[k] = fv;
239 					}
240 					i++;
241 				}
242 			}
243 		}
244 	}
245 
246 	if ( lines > 0 ) {
247 		for ( i=0; i<=lines; i++ ) {
248 			ad_prev = ad;
249 			if ( !ad || ( i<lines && !bvcasematch( type+i, &ad->ad_cname ))) {
250 				ad = NULL;
251 				rc = slap_bv2ad( type+i, &ad, &text );
252 
253 				if( rc != LDAP_SUCCESS ) {
254 					Debug( slapMode & SLAP_TOOL_MODE
255 						? LDAP_DEBUG_ANY : LDAP_DEBUG_TRACE,
256 						"<= str2entry: str2ad(%s): %s\n", type[i].bv_val, text, 0 );
257 					if( slapMode & SLAP_TOOL_MODE ) {
258 						goto fail;
259 					}
260 
261 					rc = slap_bv2undef_ad( type+i, &ad, &text, 0 );
262 					if( rc != LDAP_SUCCESS ) {
263 						Debug( LDAP_DEBUG_ANY,
264 							"<= str2entry: slap_str2undef_ad(%s): %s\n",
265 								type[i].bv_val, text, 0 );
266 						goto fail;
267 					}
268 				}
269 
270 				/* require ';binary' when appropriate (ITS#5071) */
271 				if ( slap_syntax_is_binary( ad->ad_type->sat_syntax ) && !slap_ad_is_binary( ad ) ) {
272 					Debug( LDAP_DEBUG_ANY,
273 						"str2entry: attributeType %s #%d: "
274 						"needs ';binary' transfer as per syntax %s\n",
275 						ad->ad_cname.bv_val, 0,
276 						ad->ad_type->sat_syntax->ssyn_oid );
277 					goto fail;
278 				}
279 			}
280 
281 			if (( ad_prev && ad != ad_prev ) || ( i == lines )) {
282 				int j, k;
283 				/* FIXME: we only need this when migrating from an unsorted DB */
284 				if ( atail != &ahead && atail->a_desc->ad_type->sat_flags & SLAP_AT_SORTED_VAL ) {
285 					rc = slap_sort_vals( (Modifications *)atail, &text, &j, NULL );
286 					if ( rc == LDAP_SUCCESS ) {
287 						atail->a_flags |= SLAP_ATTR_SORTED_VALS;
288 					} else if ( rc == LDAP_TYPE_OR_VALUE_EXISTS ) {
289 						Debug( LDAP_DEBUG_ANY,
290 							"str2entry: attributeType %s value #%d provided more than once\n",
291 							atail->a_desc->ad_cname.bv_val, j, 0 );
292 						goto fail;
293 					}
294 				}
295 				atail->a_next = attr_alloc( NULL );
296 				atail = atail->a_next;
297 				atail->a_flags = 0;
298 				atail->a_numvals = attr_cnt;
299 				atail->a_desc = ad_prev;
300 				atail->a_vals = ch_malloc( (attr_cnt + 1) * sizeof(struct berval));
301 				if( ad_prev->ad_type->sat_equality &&
302 					ad_prev->ad_type->sat_equality->smr_normalize )
303 					atail->a_nvals = ch_malloc( (attr_cnt + 1) * sizeof(struct berval));
304 				else
305 					atail->a_nvals = NULL;
306 				k = i - attr_cnt;
307 				for ( j=0; j<attr_cnt; j++ ) {
308 					if ( freeval[k] )
309 						atail->a_vals[j] = vals[k];
310 					else
311 						ber_dupbv( atail->a_vals+j, &vals[k] );
312 					vals[k].bv_val = NULL;
313 					if ( atail->a_nvals ) {
314 						atail->a_nvals[j] = nvals[k];
315 						nvals[k].bv_val = NULL;
316 					}
317 					k++;
318 				}
319 				BER_BVZERO( &atail->a_vals[j] );
320 				if ( atail->a_nvals ) {
321 					BER_BVZERO( &atail->a_nvals[j] );
322 				} else {
323 					atail->a_nvals = atail->a_vals;
324 				}
325 				attr_cnt = 0;
326 				if ( i == lines ) break;
327 			}
328 
329 			if ( BER_BVISNULL( &vals[i] ) ) {
330 				Debug( LDAP_DEBUG_ANY,
331 					"str2entry: attributeType %s #%d: "
332 					"no value\n",
333 					ad->ad_cname.bv_val, attr_cnt, 0 );
334 				goto fail;
335 			}
336 
337 			if( slapMode & SLAP_TOOL_MODE ) {
338 				struct berval pval;
339 				slap_syntax_validate_func *validate =
340 					ad->ad_type->sat_syntax->ssyn_validate;
341 				slap_syntax_transform_func *pretty =
342 					ad->ad_type->sat_syntax->ssyn_pretty;
343 
344 				if ( pretty ) {
345 					rc = ordered_value_pretty( ad,
346 						&vals[i], &pval, NULL );
347 
348 				} else if ( validate ) {
349 					/*
350 				 	 * validate value per syntax
351 				 	 */
352 					rc = ordered_value_validate( ad, &vals[i], LDAP_MOD_ADD );
353 
354 				} else {
355 					Debug( LDAP_DEBUG_ANY,
356 						"str2entry: attributeType %s #%d: "
357 						"no validator for syntax %s\n",
358 						ad->ad_cname.bv_val, attr_cnt,
359 						ad->ad_type->sat_syntax->ssyn_oid );
360 					goto fail;
361 				}
362 
363 				if( rc != 0 ) {
364 					Debug( LDAP_DEBUG_ANY,
365 						"str2entry: invalid value "
366 						"for attributeType %s #%d (syntax %s)\n",
367 						ad->ad_cname.bv_val, attr_cnt,
368 						ad->ad_type->sat_syntax->ssyn_oid );
369 					goto fail;
370 				}
371 
372 				if( pretty ) {
373 					if ( freeval[i] ) free( vals[i].bv_val );
374 					vals[i] = pval;
375 					freeval[i] = 1;
376 				}
377 			}
378 
379 			if ( ad->ad_type->sat_equality &&
380 				ad->ad_type->sat_equality->smr_normalize )
381 			{
382 				rc = ordered_value_normalize(
383 					SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
384 					ad,
385 					ad->ad_type->sat_equality,
386 					&vals[i], &nvals[i], NULL );
387 
388 				if ( rc ) {
389 					Debug( LDAP_DEBUG_ANY,
390 				   		"<= str2entry NULL (smr_normalize %s %d)\n", ad->ad_cname.bv_val, rc, 0 );
391 					goto fail;
392 				}
393 			}
394 
395 			attr_cnt++;
396 		}
397 	}
398 
399 	free( type );
400 	atail->a_next = NULL;
401 	e->e_attrs = ahead.a_next;
402 
403 	Debug(LDAP_DEBUG_TRACE, "<= str2entry(%s) -> 0x%lx\n",
404 		e->e_dn, (unsigned long) e, 0 );
405 	return( e );
406 
407 fail:
408 	for ( i=0; i<lines; i++ ) {
409 		if ( freeval[i] ) free( vals[i].bv_val );
410 		free( nvals[i].bv_val );
411 	}
412 	free( type );
413 	entry_free( e );
414 	return NULL;
415 }
416 
417 
418 #define GRABSIZE	BUFSIZ
419 
420 #define MAKE_SPACE( n )	{ \
421 		while ( ecur + (n) > ebuf + emaxsize ) { \
422 			ptrdiff_t	offset; \
423 			offset = (int) (ecur - ebuf); \
424 			ebuf = ch_realloc( ebuf, \
425 				emaxsize + GRABSIZE ); \
426 			emaxsize += GRABSIZE; \
427 			ecur = ebuf + offset; \
428 		} \
429 	}
430 
431 /* NOTE: only preserved for binary compatibility */
432 char *
433 entry2str(
434 	Entry	*e,
435 	int		*len )
436 {
437 	return entry2str_wrap( e, len, LDIF_LINE_WIDTH );
438 }
439 
440 char *
441 entry2str_wrap(
442 	Entry		*e,
443 	int			*len,
444 	ber_len_t	wrap )
445 {
446 	Attribute	*a;
447 	struct berval	*bv;
448 	int		i;
449 	ber_len_t tmplen;
450 
451 	assert( e != NULL );
452 
453 	/*
454 	 * In string format, an entry looks like this:
455 	 *	dn: <dn>\n
456 	 *	[<attr>: <value>\n]*
457 	 */
458 
459 	ecur = ebuf;
460 
461 	/* put the dn */
462 	if ( e->e_dn != NULL ) {
463 		/* put "dn: <dn>" */
464 		tmplen = e->e_name.bv_len;
465 		MAKE_SPACE( LDIF_SIZE_NEEDED( 2, tmplen ));
466 		ldif_sput_wrap( &ecur, LDIF_PUT_VALUE, "dn", e->e_dn, tmplen, wrap );
467 	}
468 
469 	/* put the attributes */
470 	for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
471 		/* put "<type>:[:] <value>" line for each value */
472 		for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) {
473 			bv = &a->a_vals[i];
474 			tmplen = a->a_desc->ad_cname.bv_len;
475 			MAKE_SPACE( LDIF_SIZE_NEEDED( tmplen, bv->bv_len ));
476 			ldif_sput_wrap( &ecur, LDIF_PUT_VALUE,
477 				a->a_desc->ad_cname.bv_val,
478 				bv->bv_val, bv->bv_len, wrap );
479 		}
480 	}
481 	MAKE_SPACE( 1 );
482 	*ecur = '\0';
483 	*len = ecur - ebuf;
484 
485 	return( ebuf );
486 }
487 
488 void
489 entry_clean( Entry *e )
490 {
491 	/* free an entry structure */
492 	assert( e != NULL );
493 
494 	/* e_private must be freed by the caller */
495 	assert( e->e_private == NULL );
496 
497 	e->e_id = 0;
498 
499 	/* free DNs */
500 	if ( !BER_BVISNULL( &e->e_name ) ) {
501 		free( e->e_name.bv_val );
502 		BER_BVZERO( &e->e_name );
503 	}
504 	if ( !BER_BVISNULL( &e->e_nname ) ) {
505 		free( e->e_nname.bv_val );
506 		BER_BVZERO( &e->e_nname );
507 	}
508 
509 	if ( !BER_BVISNULL( &e->e_bv ) ) {
510 		free( e->e_bv.bv_val );
511 		BER_BVZERO( &e->e_bv );
512 	}
513 
514 	/* free attributes */
515 	if ( e->e_attrs ) {
516 		attrs_free( e->e_attrs );
517 		e->e_attrs = NULL;
518 	}
519 
520 	e->e_ocflags = 0;
521 }
522 
523 void
524 entry_free( Entry *e )
525 {
526 	entry_clean( e );
527 
528 	ldap_pvt_thread_mutex_lock( &entry_mutex );
529 	e->e_private = entry_list;
530 	entry_list = e;
531 	ldap_pvt_thread_mutex_unlock( &entry_mutex );
532 }
533 
534 /* These parameters work well on AMD64 */
535 #if 0
536 #define	STRIDE 8
537 #define	STRIPE 5
538 #else
539 #define	STRIDE 1
540 #define	STRIPE 1
541 #endif
542 #define	STRIDE_FACTOR (STRIDE*STRIPE)
543 
544 int
545 entry_prealloc( int num )
546 {
547 	Entry *e, **prev, *tmp;
548 	slap_list *s;
549 	int i, j;
550 
551 	if (!num) return 0;
552 
553 #if STRIDE_FACTOR > 1
554 	/* Round up to our stride factor */
555 	num += STRIDE_FACTOR-1;
556 	num /= STRIDE_FACTOR;
557 	num *= STRIDE_FACTOR;
558 #endif
559 
560 	s = ch_calloc( 1, sizeof(slap_list) + num * sizeof(Entry));
561 	s->next = entry_chunks;
562 	entry_chunks = s;
563 
564 	prev = &tmp;
565 	for (i=0; i<STRIPE; i++) {
566 		e = (Entry *)(s+1);
567 		e += i;
568 		for (j=i; j<num; j+= STRIDE) {
569 			*prev = e;
570 			prev = (Entry **)&e->e_private;
571 			e += STRIDE;
572 		}
573 	}
574 	*prev = entry_list;
575 	entry_list = (Entry *)(s+1);
576 
577 	return 0;
578 }
579 
580 Entry *
581 entry_alloc( void )
582 {
583 	Entry *e;
584 
585 	ldap_pvt_thread_mutex_lock( &entry_mutex );
586 	if ( !entry_list )
587 		entry_prealloc( CHUNK_SIZE );
588 	e = entry_list;
589 	entry_list = e->e_private;
590 	e->e_private = NULL;
591 	ldap_pvt_thread_mutex_unlock( &entry_mutex );
592 
593 	return e;
594 }
595 
596 
597 /*
598  * These routines are used only by Backend.
599  *
600  * the Entry has three entry points (ways to find things):
601  *
602  *	by entry	e.g., if you already have an entry from the cache
603  *			and want to delete it. (really by entry ptr)
604  *	by dn		e.g., when looking for the base object of a search
605  *	by id		e.g., for search candidates
606  *
607  * these correspond to three different avl trees that are maintained.
608  */
609 
610 int
611 entry_cmp( Entry *e1, Entry *e2 )
612 {
613 	return SLAP_PTRCMP( e1, e2 );
614 }
615 
616 int
617 entry_dn_cmp( const void *v_e1, const void *v_e2 )
618 {
619 	/* compare their normalized UPPERCASED dn's */
620 	const Entry *e1 = v_e1, *e2 = v_e2;
621 
622 	return ber_bvcmp( &e1->e_nname, &e2->e_nname );
623 }
624 
625 int
626 entry_id_cmp( const void *v_e1, const void *v_e2 )
627 {
628 	const Entry *e1 = v_e1, *e2 = v_e2;
629 	return( e1->e_id < e2->e_id ? -1 : (e1->e_id > e2->e_id ? 1 : 0) );
630 }
631 
632 /* This is like a ber_len */
633 #define entry_lenlen(l)	(((l) < 0x80) ? 1 : ((l) < 0x100) ? 2 : \
634 	((l) < 0x10000) ? 3 : ((l) < 0x1000000) ? 4 : 5)
635 
636 static void
637 entry_putlen(unsigned char **buf, ber_len_t len)
638 {
639 	ber_len_t lenlen = entry_lenlen(len);
640 
641 	if (lenlen == 1) {
642 		**buf = (unsigned char) len;
643 	} else {
644 		int i;
645 		**buf = 0x80 | ((unsigned char) lenlen - 1);
646 		for (i=lenlen-1; i>0; i--) {
647 			(*buf)[i] = (unsigned char) len;
648 			len >>= 8;
649 		}
650 	}
651 	*buf += lenlen;
652 }
653 
654 static ber_len_t
655 entry_getlen(unsigned char **buf)
656 {
657 	ber_len_t len;
658 	int i;
659 
660 	len = *(*buf)++;
661 	if (len <= 0x7f)
662 		return len;
663 	i = len & 0x7f;
664 	len = 0;
665 	for (;i > 0; i--) {
666 		len <<= 8;
667 		len |= *(*buf)++;
668 	}
669 	return len;
670 }
671 
672 /* Count up the sizes of the components of an entry */
673 void entry_partsize(Entry *e, ber_len_t *plen,
674 	int *pnattrs, int *pnvals, int norm)
675 {
676 	ber_len_t len, dnlen, ndnlen;
677 	int i, nat = 0, nval = 0;
678 	Attribute *a;
679 
680 	dnlen = e->e_name.bv_len;
681 	len = dnlen + 1;	/* trailing NUL byte */
682 	len += entry_lenlen(dnlen);
683 	if (norm) {
684 		ndnlen = e->e_nname.bv_len;
685 		len += ndnlen + 1;
686 		len += entry_lenlen(ndnlen);
687 	}
688 	for (a=e->e_attrs; a; a=a->a_next) {
689 		/* For AttributeDesc, we only store the attr name */
690 		nat++;
691 		len += a->a_desc->ad_cname.bv_len+1;
692 		len += entry_lenlen(a->a_desc->ad_cname.bv_len);
693 		for (i=0; a->a_vals[i].bv_val; i++) {
694 			nval++;
695 			len += a->a_vals[i].bv_len + 1;
696 			len += entry_lenlen(a->a_vals[i].bv_len);
697 		}
698 		len += entry_lenlen(i);
699 		nval++;	/* empty berval at end */
700 		if (norm && a->a_nvals != a->a_vals) {
701 			for (i=0; a->a_nvals[i].bv_val; i++) {
702 				nval++;
703 				len += a->a_nvals[i].bv_len + 1;
704 				len += entry_lenlen(a->a_nvals[i].bv_len);
705 			}
706 			len += entry_lenlen(i);	/* i nvals */
707 			nval++;
708 		} else {
709 			len += entry_lenlen(0);	/* 0 nvals */
710 		}
711 	}
712 	len += entry_lenlen(nat);
713 	len += entry_lenlen(nval);
714 	*plen = len;
715 	*pnattrs = nat;
716 	*pnvals = nval;
717 }
718 
719 /* Add up the size of the entry for a flattened buffer */
720 ber_len_t entry_flatsize(Entry *e, int norm)
721 {
722 	ber_len_t len;
723 	int nattrs, nvals;
724 
725 	entry_partsize(e, &len, &nattrs, &nvals, norm);
726 	len += sizeof(Entry) + (nattrs * sizeof(Attribute)) +
727 		(nvals * sizeof(struct berval));
728 	return len;
729 }
730 
731 /* Flatten an Entry into a buffer. The buffer is filled with just the
732  * strings/bervals of all the entry components. Each field is preceded
733  * by its length, encoded the way ber_put_len works. Every field is NUL
734  * terminated.  The entire buffer size is precomputed so that a single
735  * malloc can be performed. The entry size is also recorded,
736  * to aid in entry_decode.
737  */
738 int entry_encode(Entry *e, struct berval *bv)
739 {
740 	ber_len_t len, dnlen, ndnlen, i;
741 	int nattrs, nvals;
742 	Attribute *a;
743 	unsigned char *ptr;
744 
745 	Debug( LDAP_DEBUG_TRACE, "=> entry_encode(0x%08lx): %s\n",
746 		(long) e->e_id, e->e_dn, 0 );
747 
748 	dnlen = e->e_name.bv_len;
749 	ndnlen = e->e_nname.bv_len;
750 
751 	entry_partsize( e, &len, &nattrs, &nvals, 1 );
752 
753 	bv->bv_len = len;
754 	bv->bv_val = ch_malloc(len);
755 	ptr = (unsigned char *)bv->bv_val;
756 	entry_putlen(&ptr, nattrs);
757 	entry_putlen(&ptr, nvals);
758 	entry_putlen(&ptr, dnlen);
759 	AC_MEMCPY(ptr, e->e_dn, dnlen);
760 	ptr += dnlen;
761 	*ptr++ = '\0';
762 	entry_putlen(&ptr, ndnlen);
763 	AC_MEMCPY(ptr, e->e_ndn, ndnlen);
764 	ptr += ndnlen;
765 	*ptr++ = '\0';
766 
767 	for (a=e->e_attrs; a; a=a->a_next) {
768 		entry_putlen(&ptr, a->a_desc->ad_cname.bv_len);
769 		AC_MEMCPY(ptr, a->a_desc->ad_cname.bv_val,
770 			a->a_desc->ad_cname.bv_len);
771 		ptr += a->a_desc->ad_cname.bv_len;
772 		*ptr++ = '\0';
773 		if (a->a_vals) {
774 			for (i=0; a->a_vals[i].bv_val; i++);
775 			assert( i == a->a_numvals );
776 			entry_putlen(&ptr, i);
777 			for (i=0; a->a_vals[i].bv_val; i++) {
778 				entry_putlen(&ptr, a->a_vals[i].bv_len);
779 				AC_MEMCPY(ptr, a->a_vals[i].bv_val,
780 					a->a_vals[i].bv_len);
781 				ptr += a->a_vals[i].bv_len;
782 				*ptr++ = '\0';
783 			}
784 			if (a->a_nvals != a->a_vals) {
785 				entry_putlen(&ptr, i);
786 				for (i=0; a->a_nvals[i].bv_val; i++) {
787 					entry_putlen(&ptr, a->a_nvals[i].bv_len);
788 					AC_MEMCPY(ptr, a->a_nvals[i].bv_val,
789 					a->a_nvals[i].bv_len);
790 					ptr += a->a_nvals[i].bv_len;
791 					*ptr++ = '\0';
792 				}
793 			} else {
794 				entry_putlen(&ptr, 0);
795 			}
796 		}
797 	}
798 
799 	Debug( LDAP_DEBUG_TRACE, "<= entry_encode(0x%08lx): %s\n",
800 		(long) e->e_id, e->e_dn, 0 );
801 
802 	return 0;
803 }
804 
805 /* Retrieve an Entry that was stored using entry_encode above.
806  * First entry_header must be called to decode the size of the entry.
807  * Then a single block of memory must be malloc'd to accomodate the
808  * bervals and the bulk data. Next the bulk data is retrieved from
809  * the DB and parsed by entry_decode.
810  *
811  * Note: everything is stored in a single contiguous block, so
812  * you can not free individual attributes or names from this
813  * structure. Attempting to do so will likely corrupt memory.
814  */
815 int entry_header(EntryHeader *eh)
816 {
817 	unsigned char *ptr = (unsigned char *)eh->bv.bv_val;
818 
819 	/* Some overlays can create empty entries
820 	 * so don't check for zeros here.
821 	 */
822 	eh->nattrs = entry_getlen(&ptr);
823 	eh->nvals = entry_getlen(&ptr);
824 	eh->data = (char *)ptr;
825 	return LDAP_SUCCESS;
826 }
827 
828 int
829 entry_decode_dn( EntryHeader *eh, struct berval *dn, struct berval *ndn )
830 {
831 	int i;
832 	unsigned char *ptr = (unsigned char *)eh->bv.bv_val;
833 
834 	assert( dn != NULL || ndn != NULL );
835 
836 	ptr = (unsigned char *)eh->data;
837 	i = entry_getlen(&ptr);
838 	if ( dn != NULL ) {
839 		dn->bv_val = (char *) ptr;
840 		dn->bv_len = i;
841 	}
842 
843 	if ( ndn != NULL ) {
844 		ptr += i + 1;
845 		i = entry_getlen(&ptr);
846 		ndn->bv_val = (char *) ptr;
847 		ndn->bv_len = i;
848 	}
849 
850 	Debug( LDAP_DEBUG_TRACE,
851 		"entry_decode_dn: \"%s\"\n",
852 		dn ? dn->bv_val : ndn->bv_val, 0, 0 );
853 
854 	return 0;
855 }
856 
857 #ifdef SLAP_ZONE_ALLOC
858 int entry_decode(EntryHeader *eh, Entry **e, void *ctx)
859 #else
860 int entry_decode(EntryHeader *eh, Entry **e)
861 #endif
862 {
863 	int i, j, nattrs, nvals;
864 	int rc;
865 	Attribute *a;
866 	Entry *x;
867 	const char *text;
868 	AttributeDescription *ad;
869 	unsigned char *ptr = (unsigned char *)eh->bv.bv_val;
870 	BerVarray bptr;
871 
872 	nattrs = eh->nattrs;
873 	nvals = eh->nvals;
874 	x = entry_alloc();
875 	x->e_attrs = attrs_alloc( nattrs );
876 	ptr = (unsigned char *)eh->data;
877 	i = entry_getlen(&ptr);
878 	x->e_name.bv_val = (char *) ptr;
879 	x->e_name.bv_len = i;
880 	ptr += i+1;
881 	i = entry_getlen(&ptr);
882 	x->e_nname.bv_val = (char *) ptr;
883 	x->e_nname.bv_len = i;
884 	ptr += i+1;
885 	Debug( LDAP_DEBUG_TRACE,
886 		"entry_decode: \"%s\"\n",
887 		x->e_dn, 0, 0 );
888 	x->e_bv = eh->bv;
889 
890 	a = x->e_attrs;
891 	bptr = (BerVarray)eh->bv.bv_val;
892 
893 	while ((i = entry_getlen(&ptr))) {
894 		struct berval bv;
895 		bv.bv_len = i;
896 		bv.bv_val = (char *) ptr;
897 		ad = NULL;
898 		rc = slap_bv2ad( &bv, &ad, &text );
899 
900 		if( rc != LDAP_SUCCESS ) {
901 			Debug( LDAP_DEBUG_TRACE,
902 				"<= entry_decode: str2ad(%s): %s\n", ptr, text, 0 );
903 			rc = slap_bv2undef_ad( &bv, &ad, &text, 0 );
904 
905 			if( rc != LDAP_SUCCESS ) {
906 				Debug( LDAP_DEBUG_ANY,
907 					"<= entry_decode: slap_str2undef_ad(%s): %s\n",
908 						ptr, text, 0 );
909 				return rc;
910 			}
911 		}
912 		ptr += i + 1;
913 		a->a_desc = ad;
914 		a->a_flags = SLAP_ATTR_DONT_FREE_DATA | SLAP_ATTR_DONT_FREE_VALS;
915 		j = entry_getlen(&ptr);
916 		a->a_numvals = j;
917 		a->a_vals = bptr;
918 
919 		while (j) {
920 			i = entry_getlen(&ptr);
921 			bptr->bv_len = i;
922 			bptr->bv_val = (char *)ptr;
923 			ptr += i+1;
924 			bptr++;
925 			j--;
926 		}
927 		bptr->bv_val = NULL;
928 		bptr->bv_len = 0;
929 		bptr++;
930 
931 		j = entry_getlen(&ptr);
932 		if (j) {
933 			a->a_nvals = bptr;
934 			while (j) {
935 				i = entry_getlen(&ptr);
936 				bptr->bv_len = i;
937 				bptr->bv_val = (char *)ptr;
938 				ptr += i+1;
939 				bptr++;
940 				j--;
941 			}
942 			bptr->bv_val = NULL;
943 			bptr->bv_len = 0;
944 			bptr++;
945 		} else {
946 			a->a_nvals = a->a_vals;
947 		}
948 		/* FIXME: This is redundant once a sorted entry is saved into the DB */
949 		if ( a->a_desc->ad_type->sat_flags & SLAP_AT_SORTED_VAL ) {
950 			rc = slap_sort_vals( (Modifications *)a, &text, &j, NULL );
951 			if ( rc == LDAP_SUCCESS ) {
952 				a->a_flags |= SLAP_ATTR_SORTED_VALS;
953 			} else if ( rc == LDAP_TYPE_OR_VALUE_EXISTS ) {
954 				/* should never happen */
955 				Debug( LDAP_DEBUG_ANY,
956 					"entry_decode: attributeType %s value #%d provided more than once\n",
957 					a->a_desc->ad_cname.bv_val, j, 0 );
958 				return rc;
959 			}
960 		}
961 		a = a->a_next;
962 		nattrs--;
963 		if ( !nattrs )
964 			break;
965 	}
966 
967 	Debug(LDAP_DEBUG_TRACE, "<= entry_decode(%s)\n",
968 		x->e_dn, 0, 0 );
969 	*e = x;
970 	return 0;
971 }
972 
973 Entry *
974 entry_dup2( Entry *dest, Entry *source )
975 {
976 	assert( dest != NULL );
977 	assert( source != NULL );
978 
979 	assert( dest->e_private == NULL );
980 
981 	dest->e_id = source->e_id;
982 	ber_dupbv( &dest->e_name, &source->e_name );
983 	ber_dupbv( &dest->e_nname, &source->e_nname );
984 	dest->e_attrs = attrs_dup( source->e_attrs );
985 	dest->e_ocflags = source->e_ocflags;
986 
987 	return dest;
988 }
989 
990 Entry *
991 entry_dup( Entry *e )
992 {
993 	return entry_dup2( entry_alloc(), e );
994 }
995 
996 #if 1
997 /* Duplicates an entry using a single malloc. Saves CPU time, increases
998  * heap usage because a single large malloc is harder to satisfy than
999  * lots of small ones, and the freed space isn't as easily reusable.
1000  *
1001  * Probably not worth using this function.
1002  */
1003 Entry *entry_dup_bv( Entry *e )
1004 {
1005 	ber_len_t len;
1006 	int nattrs, nvals;
1007 	Entry *ret;
1008 	struct berval *bvl;
1009 	char *ptr;
1010 	Attribute *src, *dst;
1011 
1012 	ret = entry_alloc();
1013 
1014 	entry_partsize(e, &len, &nattrs, &nvals, 1);
1015 	ret->e_id = e->e_id;
1016 	ret->e_attrs = attrs_alloc( nattrs );
1017 	ret->e_ocflags = e->e_ocflags;
1018 	ret->e_bv.bv_len = len + nvals * sizeof(struct berval);
1019 	ret->e_bv.bv_val = ch_malloc( ret->e_bv.bv_len );
1020 
1021 	bvl = (struct berval *)ret->e_bv.bv_val;
1022 	ptr = (char *)(bvl + nvals);
1023 
1024 	ret->e_name.bv_len = e->e_name.bv_len;
1025 	ret->e_name.bv_val = ptr;
1026 	AC_MEMCPY( ptr, e->e_name.bv_val, e->e_name.bv_len );
1027 	ptr += e->e_name.bv_len;
1028 	*ptr++ = '\0';
1029 
1030 	ret->e_nname.bv_len = e->e_nname.bv_len;
1031 	ret->e_nname.bv_val = ptr;
1032 	AC_MEMCPY( ptr, e->e_nname.bv_val, e->e_nname.bv_len );
1033 	ptr += e->e_name.bv_len;
1034 	*ptr++ = '\0';
1035 
1036 	dst = ret->e_attrs;
1037 	for (src = e->e_attrs; src; src=src->a_next,dst=dst->a_next ) {
1038 		int i;
1039 		dst->a_desc = src->a_desc;
1040 		dst->a_flags = SLAP_ATTR_DONT_FREE_DATA | SLAP_ATTR_DONT_FREE_VALS;
1041 		dst->a_vals = bvl;
1042 		dst->a_numvals = src->a_numvals;
1043 		for ( i=0; src->a_vals[i].bv_val; i++ ) {
1044 			bvl->bv_len = src->a_vals[i].bv_len;
1045 			bvl->bv_val = ptr;
1046 			AC_MEMCPY( ptr, src->a_vals[i].bv_val, bvl->bv_len );
1047 			ptr += bvl->bv_len;
1048 			*ptr++ = '\0';
1049 			bvl++;
1050 		}
1051 		BER_BVZERO(bvl);
1052 		bvl++;
1053 		if ( src->a_vals != src->a_nvals ) {
1054 			dst->a_nvals = bvl;
1055 			for ( i=0; src->a_nvals[i].bv_val; i++ ) {
1056 				bvl->bv_len = src->a_nvals[i].bv_len;
1057 				bvl->bv_val = ptr;
1058 				AC_MEMCPY( ptr, src->a_nvals[i].bv_val, bvl->bv_len );
1059 				ptr += bvl->bv_len;
1060 				*ptr++ = '\0';
1061 				bvl++;
1062 			}
1063 			BER_BVZERO(bvl);
1064 			bvl++;
1065 		}
1066 	}
1067 	return ret;
1068 }
1069 #endif
1070