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