/[pkg-openldap]/people/torsten/openldap2.2/servers/slapd/entry.c
ViewVC logotype

Contents of /people/torsten/openldap2.2/servers/slapd/entry.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 453 - (show annotations) (download)
Thu Mar 24 23:13:29 2005 UTC (8 years, 2 months ago) by torsten
File MIME type: text/plain
File size: 18854 byte(s)
 r1556@pulsar:  torsten | 2005-03-25 00:18:41 +0100
  * Applied patch by Quanah Gibson-Mount (directory administrator of Stanford)
    to add -q option to some tools for quick operation without updating
    logs. This is mostly for importing directories from LDIF backups.
1 /* entry.c - routines for dealing with entries */
2 /* $OpenLDAP: pkg/ldap/servers/slapd/entry.c,v 1.115.2.8 2005/01/20 17:01:07 kurt Exp $ */
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 #include <ac/ctype.h>
32 #include <ac/errno.h>
33 #include <ac/socket.h>
34 #include <ac/string.h>
35
36 #include "slap.h"
37 #include "ldif.h"
38
39 static unsigned char *ebuf; /* buf returned by entry2str */
40 static unsigned char *ecur; /* pointer to end of currently used ebuf */
41 static int emaxsize;/* max size of ebuf */
42
43 /*
44 * Empty root entry
45 */
46 const Entry slap_entry_root = {
47 NOID, { 0, "" }, { 0, "" }, NULL, 0, { 0, "" }, NULL
48 };
49
50 static const struct berval dn_bv = BER_BVC("dn");
51
52 int entry_destroy(void)
53 {
54 if ( ebuf ) free( ebuf );
55 ebuf = NULL;
56 ecur = NULL;
57 emaxsize = 0;
58 return 0;
59 }
60
61 Entry *
62 str2entry( char *s )
63 {
64 return str2entry2( s, 1 );
65 }
66
67 Entry *
68 str2entry2( char *s, int checkvals )
69 {
70 int rc;
71 Entry *e;
72 struct berval *nvalsp;
73 struct berval *type, *vals, *nvals;
74 char *freeval;
75 AttributeDescription *ad, *ad_prev;
76 const char *text;
77 char *next;
78 int attr_cnt;
79 int i, lines;
80 Attribute ahead, *atail;
81
82 /*
83 * LDIF is used as the string format.
84 * An entry looks like this:
85 *
86 * dn: <dn>\n
87 * [<attr>:[:] <value>\n]
88 * [<tab><continuedvalue>\n]*
89 * ...
90 *
91 * If a double colon is used after a type, it means the
92 * following value is encoded as a base 64 string. This
93 * happens if the value contains a non-printing character
94 * or newline.
95 */
96
97 Debug( LDAP_DEBUG_TRACE, "=> str2entry: \"%s\"\n",
98 s ? s : "NULL", 0, 0 );
99
100 /* initialize reader/writer lock */
101 e = (Entry *) ch_calloc( 1, sizeof(Entry) );
102
103 if( e == NULL ) {
104 Debug( LDAP_DEBUG_ANY,
105 "<= str2entry NULL (entry allocation failed)\n",
106 0, 0, 0 );
107 return( NULL );
108 }
109
110 /* initialize entry */
111 e->e_id = NOID;
112
113 /* dn + attributes */
114 atail = &ahead;
115 ahead.a_next = NULL;
116 ad = NULL;
117 ad_prev = NULL;
118 attr_cnt = 0;
119 next = s;
120
121 lines = ldif_countlines( s );
122 type = ch_calloc( 1, (lines+1)*3*sizeof(struct berval)+lines );
123 vals = type+lines+1;
124 nvals = vals+lines+1;
125 freeval = (char *)(nvals+lines+1);
126 i = -1;
127
128 /* parse into individual values, record DN */
129 while ( (s = ldif_getline( &next )) != NULL ) {
130 int freev;
131 if ( *s == '\n' || *s == '\0' ) {
132 break;
133 }
134 i++;
135
136 rc = ldif_parse_line2( s, type+i, vals+i, &freev );
137 freeval[i] = freev;
138 if ( rc ) {
139 Debug( LDAP_DEBUG_TRACE,
140 "<= str2entry NULL (parse_line)\n", 0, 0, 0 );
141 continue;
142 }
143
144 if ( type[i].bv_len == dn_bv.bv_len &&
145 strcasecmp( type[i].bv_val, dn_bv.bv_val ) == 0 ) {
146
147 if ( e->e_dn != NULL ) {
148 Debug( LDAP_DEBUG_ANY, "str2entry: "
149 "entry %ld has multiple DNs \"%s\" and \"%s\"\n",
150 (long) e->e_id, e->e_dn, vals[i].bv_val );
151 goto fail;
152 }
153
154 rc = dnPrettyNormal( NULL, &vals[i], &e->e_name, &e->e_nname, NULL );
155 if( rc != LDAP_SUCCESS ) {
156 Debug( LDAP_DEBUG_ANY, "str2entry: "
157 "entry %ld has invalid DN \"%s\"\n",
158 (long) e->e_id, vals[i].bv_val, 0 );
159 goto fail;
160 }
161 if ( freeval[i] ) free( vals[i].bv_val );
162 vals[i].bv_val = NULL;
163 i--;
164 continue;
165 }
166 }
167 lines = i+1;
168
169 /* check to make sure there was a dn: line */
170 if ( BER_BVISNULL( &e->e_name )) {
171 Debug( LDAP_DEBUG_ANY, "str2entry: entry %ld has no dn\n",
172 (long) e->e_id, 0, 0 );
173 goto fail;
174 }
175
176 /* Make sure all attributes with multiple values are contiguous */
177 if ( checkvals ) {
178 int j, k;
179 struct berval bv;
180 int fv;
181
182 for (i=0; i<lines; i++) {
183 k = i;
184 for ( j=i+1; j<lines; j++ ) {
185 if ( bvmatch( type+i, type+j )) {
186 /* out of order, move intervening attributes down */
187 if ( j != k+1 ) {
188 int l;
189 bv = vals[j];
190 fv = freeval[j];
191 for ( l=j; l>k; l-- ) {
192 type[l] = type[l-1];
193 vals[l] = vals[l-1];
194 freeval[l] = freeval[l-1];
195 }
196 type[l] = type[i];
197 vals[l] = bv;
198 freeval[l] = fv;
199 }
200 i = k = j;
201 }
202 }
203 }
204 }
205
206 for ( i=0; i<=lines; i++ ) {
207 ad_prev = ad;
208 if ( !ad || ( i<lines && !bvmatch( type+i, &ad->ad_cname ))) {
209 ad = NULL;
210 rc = slap_bv2ad( type+i, &ad, &text );
211
212 if( rc != LDAP_SUCCESS ) {
213 Debug( slapMode & SLAP_TOOL_MODE
214 ? LDAP_DEBUG_ANY : LDAP_DEBUG_TRACE,
215 "<= str2entry: str2ad(%s): %s\n", type[i].bv_val, text, 0 );
216 if( slapMode & SLAP_TOOL_MODE ) {
217 goto fail;
218 }
219
220 rc = slap_bv2undef_ad( type+i, &ad, &text );
221 if( rc != LDAP_SUCCESS ) {
222 Debug( LDAP_DEBUG_ANY,
223 "<= str2entry: str2undef_ad(%s): %s\n",
224 type[i].bv_val, text, 0 );
225 goto fail;
226 }
227 }
228 }
229
230 if (( ad_prev && ad != ad_prev ) || ( i == lines )) {
231 int j, k;
232 atail->a_next = (Attribute *) ch_malloc( sizeof(Attribute) );
233 atail = atail->a_next;
234 atail->a_desc = ad_prev;
235 atail->a_vals = ch_malloc( (attr_cnt + 1) * sizeof(struct berval));
236 if( ad_prev->ad_type->sat_equality &&
237 ad_prev->ad_type->sat_equality->smr_normalize )
238 atail->a_nvals = ch_malloc( (attr_cnt + 1) * sizeof(struct berval));
239 else
240 atail->a_nvals = NULL;
241 k = i - attr_cnt;
242 for ( j=0; j<attr_cnt; j++ ) {
243 if ( freeval[k] )
244 atail->a_vals[j] = vals[k];
245 else
246 ber_dupbv( atail->a_vals+j, &vals[k] );
247 vals[k].bv_val = NULL;
248 if ( atail->a_nvals ) {
249 atail->a_nvals[j] = nvals[k];
250 nvals[k].bv_val = NULL;
251 }
252 k++;
253 }
254 BER_BVZERO( &atail->a_vals[j] );
255 if ( atail->a_nvals ) {
256 BER_BVZERO( &atail->a_nvals[j] );
257 } else {
258 atail->a_nvals = atail->a_vals;
259 }
260 attr_cnt = 0;
261 if ( i == lines ) break;
262 }
263
264 if( slapMode & SLAP_TOOL_MODE ) {
265 struct berval pval;
266 slap_syntax_validate_func *validate =
267 ad->ad_type->sat_syntax->ssyn_validate;
268 slap_syntax_transform_func *pretty =
269 ad->ad_type->sat_syntax->ssyn_pretty;
270
271 if( pretty ) {
272 rc = pretty( ad->ad_type->sat_syntax,
273 &vals[i], &pval, NULL );
274
275 } else if( validate ) {
276 /*
277 * validate value per syntax
278 */
279 rc = validate( ad->ad_type->sat_syntax, &vals[i] );
280
281 } else {
282 Debug( LDAP_DEBUG_ANY,
283 "str2entry: attributeType %s #%d: "
284 "no validator for syntax %s\n",
285 ad->ad_cname.bv_val, attr_cnt,
286 ad->ad_type->sat_syntax->ssyn_oid );
287 goto fail;
288 }
289
290 if( rc != 0 ) {
291 Debug( LDAP_DEBUG_ANY,
292 "str2entry: invalid value "
293 "for attributeType %s #%d (syntax %s)\n",
294 ad->ad_cname.bv_val, attr_cnt,
295 ad->ad_type->sat_syntax->ssyn_oid );
296 goto fail;
297 }
298
299 if( pretty ) {
300 if ( freeval[i] ) free( vals[i].bv_val );
301 vals[i] = pval;
302 freeval[i] = 1;
303 }
304 }
305
306 if( ad->ad_type->sat_equality &&
307 ad->ad_type->sat_equality->smr_normalize )
308 {
309 rc = ad->ad_type->sat_equality->smr_normalize(
310 SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
311 ad->ad_type->sat_syntax,
312 ad->ad_type->sat_equality,
313 &vals[i], &nvals[i], NULL );
314
315 if( rc ) {
316 Debug( LDAP_DEBUG_ANY,
317 "<= str2entry NULL (smr_normalize %d)\n", rc, 0, 0 );
318 goto fail;
319 }
320 }
321
322 attr_cnt++;
323 }
324
325 free( type );
326 atail->a_next = NULL;
327 e->e_attrs = ahead.a_next;
328
329 Debug(LDAP_DEBUG_TRACE, "<= str2entry(%s) -> 0x%lx\n",
330 e->e_dn, (unsigned long) e, 0 );
331 return( e );
332
333 fail:
334 for ( i=0; i<lines; i++ ) {
335 if ( freeval[i] ) free( vals[i].bv_val );
336 free( nvals[i].bv_val );
337 }
338 free( type );
339 entry_free( e );
340 return NULL;
341 }
342
343 #define GRABSIZE BUFSIZ
344
345 #define MAKE_SPACE( n ) { \
346 while ( ecur + (n) > ebuf + emaxsize ) { \
347 ptrdiff_t offset; \
348 offset = (int) (ecur - ebuf); \
349 ebuf = (unsigned char *) ch_realloc( (char *) ebuf, \
350 emaxsize + GRABSIZE ); \
351 emaxsize += GRABSIZE; \
352 ecur = ebuf + offset; \
353 } \
354 }
355
356 char *
357 entry2str(
358 Entry *e,
359 int *len )
360 {
361 Attribute *a;
362 struct berval *bv;
363 int i;
364 ber_len_t tmplen;
365
366 assert( e != NULL );
367
368 /*
369 * In string format, an entry looks like this:
370 * dn: <dn>\n
371 * [<attr>: <value>\n]*
372 */
373
374 ecur = ebuf;
375
376 /* put the dn */
377 if ( e->e_dn != NULL ) {
378 /* put "dn: <dn>" */
379 tmplen = e->e_name.bv_len;
380 MAKE_SPACE( LDIF_SIZE_NEEDED( 2, tmplen ));
381 ldif_sput( (char **) &ecur, LDIF_PUT_VALUE, "dn", e->e_dn, tmplen );
382 }
383
384 /* put the attributes */
385 for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
386 /* put "<type>:[:] <value>" line for each value */
387 for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) {
388 bv = &a->a_vals[i];
389 tmplen = a->a_desc->ad_cname.bv_len;
390 MAKE_SPACE( LDIF_SIZE_NEEDED( tmplen, bv->bv_len ));
391 ldif_sput( (char **) &ecur, LDIF_PUT_VALUE,
392 a->a_desc->ad_cname.bv_val,
393 bv->bv_val, bv->bv_len );
394 }
395 }
396 MAKE_SPACE( 1 );
397 *ecur = '\0';
398 *len = ecur - ebuf;
399
400 return( (char *) ebuf );
401 }
402
403 void
404 entry_clean( Entry *e )
405 {
406 /* free an entry structure */
407 assert( e != NULL );
408
409 /* e_private must be freed by the caller */
410 assert( e->e_private == NULL );
411 e->e_private = NULL;
412
413 /* free DNs */
414 if ( !BER_BVISNULL( &e->e_name ) ) {
415 free( e->e_name.bv_val );
416 BER_BVZERO( &e->e_name );
417 }
418 if ( !BER_BVISNULL( &e->e_nname ) ) {
419 free( e->e_nname.bv_val );
420 BER_BVZERO( &e->e_nname );
421 }
422
423 if ( !BER_BVISNULL( &e->e_bv ) ) {
424 free( e->e_bv.bv_val );
425 BER_BVZERO( &e->e_bv );
426 }
427
428 /* free attributes */
429 attrs_free( e->e_attrs );
430 e->e_attrs = NULL;
431 }
432
433 void
434 entry_free( Entry *e )
435 {
436 entry_clean( e );
437
438 free( e );
439 }
440
441 /*
442 * These routines are used only by Backend.
443 *
444 * the Entry has three entry points (ways to find things):
445 *
446 * by entry e.g., if you already have an entry from the cache
447 * and want to delete it. (really by entry ptr)
448 * by dn e.g., when looking for the base object of a search
449 * by id e.g., for search candidates
450 *
451 * these correspond to three different avl trees that are maintained.
452 */
453
454 int
455 entry_cmp( Entry *e1, Entry *e2 )
456 {
457 return SLAP_PTRCMP( e1, e2 );
458 }
459
460 int
461 entry_dn_cmp( const void *v_e1, const void *v_e2 )
462 {
463 /* compare their normalized UPPERCASED dn's */
464 const Entry *e1 = v_e1, *e2 = v_e2;
465
466 return ber_bvcmp( &e1->e_nname, &e2->e_nname );
467 }
468
469 int
470 entry_id_cmp( const void *v_e1, const void *v_e2 )
471 {
472 const Entry *e1 = v_e1, *e2 = v_e2;
473 return( e1->e_id < e2->e_id ? -1 : (e1->e_id > e2->e_id ? 1 : 0) );
474 }
475
476 #define entry_lenlen(l) ((l) < 0x80) ? 1 : ((l) < 0x100) ? 2 : \
477 ((l) < 0x10000) ? 3 : ((l) < 0x1000000) ? 4 : 5
478 #if 0
479 /* This is like a ber_len */
480 static ber_len_t
481 entry_lenlen(ber_len_t len)
482 {
483 if (len <= 0x7f)
484 return 1;
485 if (len <= 0xff)
486 return 2;
487 if (len <= 0xffff)
488 return 3;
489 if (len <= 0xffffff)
490 return 4;
491 return 5;
492 }
493 #endif
494
495 static void
496 entry_putlen(unsigned char **buf, ber_len_t len)
497 {
498 ber_len_t lenlen = entry_lenlen(len);
499
500 if (lenlen == 1) {
501 **buf = (unsigned char) len;
502 } else {
503 int i;
504 **buf = 0x80 | ((unsigned char) lenlen - 1);
505 for (i=lenlen-1; i>0; i--) {
506 (*buf)[i] = (unsigned char) len;
507 len >>= 8;
508 }
509 }
510 *buf += lenlen;
511 }
512
513 static ber_len_t
514 entry_getlen(unsigned char **buf)
515 {
516 ber_len_t len;
517 int i;
518
519 len = *(*buf)++;
520 if (len <= 0x7f)
521 return len;
522 i = len & 0x7f;
523 len = 0;
524 for (;i > 0; i--) {
525 len <<= 8;
526 len |= *(*buf)++;
527 }
528 return len;
529 }
530
531 /* Add up the size of the entry for a flattened buffer */
532 void entry_flatsize(Entry *e, ber_len_t *psiz, ber_len_t *plen, int norm)
533 {
534 ber_len_t siz = sizeof(Entry);
535 ber_len_t len, dnlen, ndnlen;
536 int i;
537 Attribute *a;
538
539 dnlen = e->e_name.bv_len;
540 len = dnlen + 1; /* trailing NUL byte */
541 len += entry_lenlen(dnlen);
542 if (norm) {
543 ndnlen = e->e_nname.bv_len;
544 len += ndnlen + 1;
545 len += entry_lenlen(ndnlen);
546 }
547 for (a=e->e_attrs; a; a=a->a_next) {
548 /* For AttributeDesc, we only store the attr name */
549 siz += sizeof(Attribute);
550 len += a->a_desc->ad_cname.bv_len+1;
551 len += entry_lenlen(a->a_desc->ad_cname.bv_len);
552 for (i=0; a->a_vals[i].bv_val; i++) {
553 siz += sizeof(struct berval);
554 len += a->a_vals[i].bv_len + 1;
555 len += entry_lenlen(a->a_vals[i].bv_len);
556 }
557 len += entry_lenlen(i);
558 siz += sizeof(struct berval); /* empty berval at end */
559 if (norm && a->a_nvals != a->a_vals) {
560 for (i=0; a->a_nvals[i].bv_val; i++) {
561 siz += sizeof(struct berval);
562 len += a->a_nvals[i].bv_len + 1;
563 len += entry_lenlen(a->a_nvals[i].bv_len);
564 }
565 len += entry_lenlen(i); /* i nvals */
566 siz += sizeof(struct berval);
567 } else {
568 len += entry_lenlen(0); /* 0 nvals */
569 }
570 }
571 len += 1; /* NUL byte at end */
572 len += entry_lenlen(siz);
573 *psiz = siz;
574 *plen = len;
575 }
576
577 /* Flatten an Entry into a buffer. The buffer is filled with just the
578 * strings/bervals of all the entry components. Each field is preceded
579 * by its length, encoded the way ber_put_len works. Every field is NUL
580 * terminated. The entire buffer size is precomputed so that a single
581 * malloc can be performed. The entry size is also recorded,
582 * to aid in entry_decode.
583 */
584 int entry_encode(Entry *e, struct berval *bv)
585 {
586 ber_len_t siz = sizeof(Entry);
587 ber_len_t len, dnlen, ndnlen;
588 int i;
589 Attribute *a;
590 unsigned char *ptr;
591
592 #ifdef NEW_LOGGING
593 LDAP_LOG( OPERATION, DETAIL1, "entry_encode: id: 0x%08lx \"%s\"\n",
594 (long) e->e_id, e->e_dn, 0 );
595 #else
596 Debug( LDAP_DEBUG_TRACE, "=> entry_encode(0x%08lx): %s\n",
597 (long) e->e_id, e->e_dn, 0 );
598 #endif
599 dnlen = e->e_name.bv_len;
600 ndnlen = e->e_nname.bv_len;
601
602 entry_flatsize( e, &siz, &len, 1 );
603
604 bv->bv_len = len;
605 bv->bv_val = ch_malloc(len);
606 ptr = (unsigned char *)bv->bv_val;
607 entry_putlen(&ptr, siz);
608 entry_putlen(&ptr, dnlen);
609 AC_MEMCPY(ptr, e->e_dn, dnlen);
610 ptr += dnlen;
611 *ptr++ = '\0';
612 entry_putlen(&ptr, ndnlen);
613 AC_MEMCPY(ptr, e->e_ndn, ndnlen);
614 ptr += ndnlen;
615 *ptr++ = '\0';
616
617 for (a=e->e_attrs; a; a=a->a_next) {
618 entry_putlen(&ptr, a->a_desc->ad_cname.bv_len);
619 AC_MEMCPY(ptr, a->a_desc->ad_cname.bv_val,
620 a->a_desc->ad_cname.bv_len);
621 ptr += a->a_desc->ad_cname.bv_len;
622 *ptr++ = '\0';
623 if (a->a_vals) {
624 for (i=0; a->a_vals[i].bv_val; i++);
625 entry_putlen(&ptr, i);
626 for (i=0; a->a_vals[i].bv_val; i++) {
627 entry_putlen(&ptr, a->a_vals[i].bv_len);
628 AC_MEMCPY(ptr, a->a_vals[i].bv_val,
629 a->a_vals[i].bv_len);
630 ptr += a->a_vals[i].bv_len;
631 *ptr++ = '\0';
632 }
633 if (a->a_nvals != a->a_vals) {
634 entry_putlen(&ptr, i);
635 for (i=0; a->a_nvals[i].bv_val; i++) {
636 entry_putlen(&ptr, a->a_nvals[i].bv_len);
637 AC_MEMCPY(ptr, a->a_nvals[i].bv_val,
638 a->a_nvals[i].bv_len);
639 ptr += a->a_nvals[i].bv_len;
640 *ptr++ = '\0';
641 }
642 } else {
643 entry_putlen(&ptr, 0);
644 }
645 }
646 }
647 *ptr = '\0';
648 return 0;
649 }
650
651 /* Retrieve an Entry that was stored using entry_encode above.
652 * We malloc a single block with the size stored above for the Entry
653 * and all of its Attributes. We also must lookup the stored
654 * attribute names to get AttributeDescriptions. To detect if the
655 * attributes of an Entry are later modified, we note that e->e_attr
656 * is always a constant offset from (e).
657 *
658 * Note: everything is stored in a single contiguous block, so
659 * you can not free individual attributes or names from this
660 * structure. Attempting to do so will likely corrupt memory.
661 */
662 int entry_decode(struct berval *bv, Entry **e)
663 {
664 int i, j, count;
665 int rc;
666 Attribute *a;
667 Entry *x;
668 const char *text;
669 AttributeDescription *ad;
670 unsigned char *ptr = (unsigned char *)bv->bv_val;
671 BerVarray bptr;
672
673 i = entry_getlen(&ptr);
674 if (!i) {
675 #ifdef NEW_LOGGING
676 LDAP_LOG( OPERATION, INFO,
677 "entry_decode: entry length was zero\n", 0, 0, 0);
678 #else
679 Debug( LDAP_DEBUG_ANY,
680 "entry_decode: entry length was zero\n", 0, 0, 0);
681 #endif
682 return LDAP_OTHER;
683 }
684 x = ch_calloc(1, i);
685 i = entry_getlen(&ptr);
686 x->e_name.bv_val = (char *) ptr;
687 x->e_name.bv_len = i;
688 ptr += i+1;
689 i = entry_getlen(&ptr);
690 x->e_nname.bv_val = (char *) ptr;
691 x->e_nname.bv_len = i;
692 ptr += i+1;
693 #ifdef NEW_LOGGING
694 LDAP_LOG( OPERATION, DETAIL2, "entry_decode: \"%s\"\n", x->e_dn, 0, 0 );
695 #else
696 Debug( LDAP_DEBUG_TRACE,
697 "entry_decode: \"%s\"\n",
698 x->e_dn, 0, 0 );
699 #endif
700 x->e_bv = *bv;
701
702 /* A valid entry must have at least one attr, so this
703 * pointer can never be NULL
704 */
705 x->e_attrs = (Attribute *)(x+1);
706 bptr = (BerVarray)x->e_attrs;
707 a = NULL;
708
709 while ((i = entry_getlen(&ptr))) {
710 struct berval bv;
711 bv.bv_len = i;
712 bv.bv_val = (char *) ptr;
713 if (a) {
714 a->a_next = (Attribute *)bptr;
715 }
716 a = (Attribute *)bptr;
717 ad = NULL;
718 rc = slap_bv2ad( &bv, &ad, &text );
719
720 if( rc != LDAP_SUCCESS ) {
721 #ifdef NEW_LOGGING
722 LDAP_LOG( OPERATION, INFO,
723 "entry_decode: str2ad(%s): %s\n", ptr, text, 0 );
724 #else
725 Debug( LDAP_DEBUG_TRACE,
726 "<= entry_decode: str2ad(%s): %s\n", ptr, text, 0 );
727 #endif
728 rc = slap_bv2undef_ad( &bv, &ad, &text );
729
730 if( rc != LDAP_SUCCESS ) {
731 #ifdef NEW_LOGGING
732 LDAP_LOG( OPERATION, INFO,
733 "entry_decode: str2undef_ad(%s): %s\n", ptr, text, 0 );
734 #else
735 Debug( LDAP_DEBUG_ANY,
736 "<= entry_decode: str2undef_ad(%s): %s\n",
737 ptr, text, 0 );
738 #endif
739 return rc;
740 }
741 }
742 ptr += i + 1;
743 a->a_desc = ad;
744 bptr = (BerVarray)(a+1);
745 a->a_vals = bptr;
746 a->a_flags = 0;
747 count = j = entry_getlen(&ptr);
748
749 while (j) {
750 i = entry_getlen(&ptr);
751 bptr->bv_len = i;
752 bptr->bv_val = (char *)ptr;
753 ptr += i+1;
754 bptr++;
755 j--;
756 }
757 bptr->bv_val = NULL;
758 bptr->bv_len = 0;
759 bptr++;
760
761 j = entry_getlen(&ptr);
762 if (j) {
763 a->a_nvals = bptr;
764 while (j) {
765 i = entry_getlen(&ptr);
766 bptr->bv_len = i;
767 bptr->bv_val = (char *)ptr;
768 ptr += i+1;
769 bptr++;
770 j--;
771 }
772 bptr->bv_val = NULL;
773 bptr->bv_len = 0;
774 bptr++;
775 } else {
776 a->a_nvals = a->a_vals;
777 }
778 }
779
780 if (a) a->a_next = NULL;
781 #ifdef NEW_LOGGING
782 LDAP_LOG( OPERATION, DETAIL1, "entry_decode: %s\n", x->e_dn, 0, 0 );
783 #else
784 Debug(LDAP_DEBUG_TRACE, "<= entry_decode(%s)\n",
785 x->e_dn, 0, 0 );
786 #endif
787 *e = x;
788 return 0;
789 }
790
791 Entry *entry_dup( Entry *e )
792 {
793 Entry *ret;
794
795 ret = (Entry *)ch_calloc( 1, sizeof(*ret) );
796
797 ret->e_id = e->e_id;
798 ber_dupbv( &ret->e_name, &e->e_name );
799 ber_dupbv( &ret->e_nname, &e->e_nname );
800 ret->e_attrs = attrs_dup( e->e_attrs );
801 ret->e_ocflags = e->e_ocflags;
802 ret->e_bv.bv_val = NULL;
803 ret->e_bv.bv_len = 0;
804 ret->e_private = NULL;
805
806 return ret;
807 }
808

  ViewVC Help
Powered by ViewVC 1.1.5