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