1 /* $NetBSD: ldif.c,v 1.3 2021/08/14 16:14:56 christos Exp $ */ 2 3 /* ldif.c - routines for dealing with LDIF files */ 4 /* $OpenLDAP$ */ 5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 6 * 7 * Copyright 1998-2021 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) 1992-1996 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 24 * University may not be used to endorse or promote products derived 25 * from this software without specific prior written permission. This 26 * software is provided ``as is'' without express or implied warranty. 27 */ 28 /* This work was originally developed by the University of Michigan 29 * and distributed as part of U-MICH LDAP. 30 */ 31 32 #include <sys/cdefs.h> 33 __RCSID("$NetBSD: ldif.c,v 1.3 2021/08/14 16:14:56 christos Exp $"); 34 35 #include "portable.h" 36 37 #include <stdio.h> 38 39 #include <ac/stdlib.h> 40 #include <ac/ctype.h> 41 42 #include <ac/string.h> 43 #include <ac/socket.h> 44 #include <ac/time.h> 45 46 int ldif_debug = 0; 47 48 #include "ldap-int.h" 49 #include "ldif.h" 50 51 #define CONTINUED_LINE_MARKER '\r' 52 53 #ifdef CSRIMALLOC 54 #define ber_memalloc malloc 55 #define ber_memcalloc calloc 56 #define ber_memrealloc realloc 57 #define ber_strdup strdup 58 #endif 59 60 static const char nib2b64[0x40] = 61 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 62 63 /* 64 * ldif_parse_line - takes a line of the form "type:[:] value" and splits it 65 * into components "type" and "value". if a double colon separates type from 66 * value, then value is encoded in base 64, and parse_line un-decodes it 67 * (in place) before returning. The type and value are stored in malloc'd 68 * memory which must be freed by the caller. 69 * 70 * ldif_parse_line2 - operates in-place on input buffer, returning type 71 * in-place. Will return value in-place if possible, (must malloc for 72 * fetched URLs). If freeval is NULL, all return data will be malloc'd 73 * and the input line will be unmodified. Otherwise freeval is set to 74 * True if the value was malloc'd. 75 */ 76 77 int 78 ldif_parse_line( 79 LDAP_CONST char *line, 80 char **typep, 81 char **valuep, 82 ber_len_t *vlenp 83 ) 84 { 85 struct berval type, value; 86 int rc = ldif_parse_line2( (char *)line, &type, &value, NULL ); 87 88 *typep = type.bv_val; 89 *valuep = value.bv_val; 90 *vlenp = value.bv_len; 91 return rc; 92 } 93 94 int 95 ldif_parse_line2( 96 char *line, 97 struct berval *type, 98 struct berval *value, 99 int *freeval 100 ) 101 { 102 char *s, *p, *d; 103 int b64, url; 104 105 BER_BVZERO( type ); 106 BER_BVZERO( value ); 107 108 /* skip any leading space */ 109 while ( isspace( (unsigned char) *line ) ) { 110 line++; 111 } 112 113 if ( freeval ) { 114 *freeval = 0; 115 } else { 116 line = ber_strdup( line ); 117 118 if( line == NULL ) { 119 ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug, 120 _("ldif_parse_line: line malloc failed\n")); 121 return( -1 ); 122 } 123 } 124 125 type->bv_val = line; 126 127 s = strchr( type->bv_val, ':' ); 128 129 if ( s == NULL ) { 130 ber_pvt_log_printf( LDAP_DEBUG_PARSE, ldif_debug, 131 _("ldif_parse_line: missing ':' after %s\n"), 132 type->bv_val ); 133 if ( !freeval ) ber_memfree( line ); 134 return( -1 ); 135 } 136 137 /* trim any space between type and : */ 138 for ( p = &s[-1]; p > type->bv_val && isspace( * (unsigned char *) p ); p-- ) { 139 *p = '\0'; 140 } 141 *s++ = '\0'; 142 type->bv_len = s - type->bv_val - 1; 143 144 url = 0; 145 b64 = 0; 146 147 if ( *s == '<' ) { 148 s++; 149 url = 1; 150 151 } else if ( *s == ':' ) { 152 /* base 64 encoded value */ 153 s++; 154 b64 = 1; 155 } 156 157 /* skip space between : and value */ 158 while ( isspace( (unsigned char) *s ) ) { 159 s++; 160 } 161 162 /* check for continued line markers that should be deleted */ 163 for ( p = s, d = s; *p; p++ ) { 164 if ( *p != CONTINUED_LINE_MARKER ) 165 *d++ = *p; 166 } 167 *d = '\0'; 168 169 if ( b64 ) { 170 char *byte = s; 171 172 if ( *s == '\0' ) { 173 /* no value is present, error out */ 174 ber_pvt_log_printf( LDAP_DEBUG_PARSE, ldif_debug, 175 _("ldif_parse_line: %s missing base64 value\n"), 176 type->bv_val ); 177 if ( !freeval ) ber_memfree( line ); 178 return( -1 ); 179 } 180 181 value->bv_val = s; 182 value->bv_len = d - s; 183 if ( ldap_int_decode_b64_inplace( value ) != LDAP_SUCCESS ) { 184 ber_pvt_log_printf( LDAP_DEBUG_PARSE, ldif_debug, 185 _("ldif_parse_line: %s base64 decode failed\n"), 186 type->bv_val ); 187 if ( !freeval ) ber_memfree( line ); 188 return( -1 ); 189 } 190 } else if ( url ) { 191 if ( *s == '\0' ) { 192 /* no value is present, error out */ 193 ber_pvt_log_printf( LDAP_DEBUG_PARSE, ldif_debug, 194 _("ldif_parse_line: %s missing URL value\n"), 195 type->bv_val ); 196 if ( !freeval ) ber_memfree( line ); 197 return( -1 ); 198 } 199 200 if( ldif_fetch_url( s, &value->bv_val, &value->bv_len ) ) { 201 ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug, 202 _("ldif_parse_line: %s: URL \"%s\" fetch failed\n"), 203 type->bv_val, s ); 204 if ( !freeval ) ber_memfree( line ); 205 return( -1 ); 206 } 207 if ( freeval ) *freeval = 1; 208 209 } else { 210 value->bv_val = s; 211 value->bv_len = (int) (d - s); 212 } 213 214 if ( !freeval ) { 215 struct berval bv = *type; 216 217 ber_dupbv( type, &bv ); 218 219 if( BER_BVISNULL( type )) { 220 ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug, 221 _("ldif_parse_line: type malloc failed\n")); 222 if( url ) ber_memfree( value->bv_val ); 223 ber_memfree( line ); 224 return( -1 ); 225 } 226 227 if( !url ) { 228 bv = *value; 229 ber_dupbv( value, &bv ); 230 if( BER_BVISNULL( value )) { 231 ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug, 232 _("ldif_parse_line: value malloc failed\n")); 233 ber_memfree( type->bv_val ); 234 ber_memfree( line ); 235 return( -1 ); 236 } 237 } 238 239 ber_memfree( line ); 240 } 241 242 return( 0 ); 243 } 244 245 /* 246 * ldif_getline - return the next "line" (minus newline) of input from a 247 * string buffer of lines separated by newlines, terminated by \n\n 248 * or \0. this routine handles continued lines, bundling them into 249 * a single big line before returning. if a line begins with a white 250 * space character, it is a continuation of the previous line. the white 251 * space character (nb: only one char), and preceding newline are changed 252 * into CONTINUED_LINE_MARKER chars, to be deleted later by the 253 * ldif_parse_line() routine above. 254 * 255 * ldif_getline will skip over any line which starts '#'. 256 * 257 * ldif_getline takes a pointer to a pointer to the buffer on the first call, 258 * which it updates and must be supplied on subsequent calls. 259 */ 260 261 int 262 ldif_countlines( LDAP_CONST char *buf ) 263 { 264 char *nl; 265 int ret = 0; 266 267 if ( !buf ) return ret; 268 269 for ( nl = strchr(buf, '\n'); nl; nl = strchr(nl, '\n') ) { 270 nl++; 271 if ( *nl != ' ' ) ret++; 272 } 273 return ret; 274 } 275 276 char * 277 ldif_getline( char **next ) 278 { 279 char *line; 280 281 do { 282 if ( *next == NULL || **next == '\n' || **next == '\0' ) { 283 return( NULL ); 284 } 285 286 line = *next; 287 288 while ( (*next = strchr( *next, '\n' )) != NULL ) { 289 #if CONTINUED_LINE_MARKER != '\r' 290 if ( (*next)[-1] == '\r' ) { 291 (*next)[-1] = CONTINUED_LINE_MARKER; 292 } 293 #endif 294 295 if ( (*next)[1] != ' ' ) { 296 if ( (*next)[1] == '\r' && (*next)[2] == '\n' ) { 297 *(*next)++ = '\0'; 298 } 299 *(*next)++ = '\0'; 300 break; 301 } 302 303 **next = CONTINUED_LINE_MARKER; 304 (*next)[1] = CONTINUED_LINE_MARKER; 305 (*next)++; 306 } 307 } while( *line == '#' ); 308 309 return( line ); 310 } 311 312 /* 313 * name and OID of attributeTypes that must be base64 encoded in any case 314 */ 315 typedef struct must_b64_encode_s { 316 struct berval name; 317 struct berval oid; 318 } must_b64_encode_s; 319 320 static must_b64_encode_s default_must_b64_encode[] = { 321 { BER_BVC( "userPassword" ), BER_BVC( "2.5.4.35" ) }, 322 { BER_BVNULL, BER_BVNULL } 323 }; 324 325 static must_b64_encode_s *must_b64_encode = default_must_b64_encode; 326 327 /* 328 * register name and OID of attributeTypes that must always be base64 329 * encoded 330 * 331 * NOTE: this routine mallocs memory in a static struct which must 332 * be explicitly freed when no longer required 333 */ 334 int 335 ldif_must_b64_encode_register( LDAP_CONST char *name, LDAP_CONST char *oid ) 336 { 337 int i; 338 ber_len_t len; 339 340 assert( must_b64_encode != NULL ); 341 assert( name != NULL ); 342 assert( oid != NULL ); 343 344 len = strlen( name ); 345 346 for ( i = 0; !BER_BVISNULL( &must_b64_encode[i].name ); i++ ) { 347 if ( len != must_b64_encode[i].name.bv_len ) { 348 continue; 349 } 350 351 if ( strcasecmp( name, must_b64_encode[i].name.bv_val ) == 0 ) { 352 break; 353 } 354 } 355 356 if ( !BER_BVISNULL( &must_b64_encode[i].name ) ) { 357 return 1; 358 } 359 360 for ( i = 0; !BER_BVISNULL( &must_b64_encode[i].name ); i++ ) 361 /* just count */ ; 362 363 if ( must_b64_encode == default_must_b64_encode ) { 364 must_b64_encode = ber_memalloc( sizeof( must_b64_encode_s ) * ( i + 2 ) ); 365 if ( must_b64_encode == NULL ) { 366 return 1; 367 } 368 369 for ( i = 0; !BER_BVISNULL( &default_must_b64_encode[i].name ); i++ ) { 370 ber_dupbv( &must_b64_encode[i].name, &default_must_b64_encode[i].name ); 371 ber_dupbv( &must_b64_encode[i].oid, &default_must_b64_encode[i].oid ); 372 } 373 374 } else { 375 must_b64_encode_s *tmp; 376 377 tmp = ber_memrealloc( must_b64_encode, 378 sizeof( must_b64_encode_s ) * ( i + 2 ) ); 379 if ( tmp == NULL ) { 380 return 1; 381 } 382 must_b64_encode = tmp; 383 } 384 385 ber_str2bv( name, len, 1, &must_b64_encode[i].name ); 386 ber_str2bv( oid, 0, 1, &must_b64_encode[i].oid ); 387 388 BER_BVZERO( &must_b64_encode[i + 1].name ); 389 390 return 0; 391 } 392 393 void 394 ldif_must_b64_encode_release( void ) 395 { 396 int i; 397 398 assert( must_b64_encode != NULL ); 399 400 if ( must_b64_encode == default_must_b64_encode ) { 401 return; 402 } 403 404 for ( i = 0; !BER_BVISNULL( &must_b64_encode[i].name ); i++ ) { 405 ber_memfree( must_b64_encode[i].name.bv_val ); 406 ber_memfree( must_b64_encode[i].oid.bv_val ); 407 } 408 409 ber_memfree( must_b64_encode ); 410 411 must_b64_encode = default_must_b64_encode; 412 } 413 414 /* 415 * returns 1 iff the string corresponds to the name or the OID of any 416 * of the attributeTypes listed in must_b64_encode 417 */ 418 static int 419 ldif_must_b64_encode( LDAP_CONST char *s ) 420 { 421 int i; 422 struct berval bv; 423 424 assert( must_b64_encode != NULL ); 425 assert( s != NULL ); 426 427 ber_str2bv( s, 0, 0, &bv ); 428 429 for ( i = 0; !BER_BVISNULL( &must_b64_encode[i].name ); i++ ) { 430 if ( ber_bvstrcasecmp( &must_b64_encode[i].name, &bv ) == 0 431 || ber_bvcmp( &must_b64_encode[i].oid, &bv ) == 0 ) 432 { 433 return 1; 434 } 435 } 436 437 return 0; 438 } 439 440 /* NOTE: only preserved for binary compatibility */ 441 void 442 ldif_sput( 443 char **out, 444 int type, 445 LDAP_CONST char *name, 446 LDAP_CONST char *val, 447 ber_len_t vlen ) 448 { 449 ldif_sput_wrap( out, type, name, val, vlen, 0 ); 450 } 451 452 void 453 ldif_sput_wrap( 454 char **out, 455 int type, 456 LDAP_CONST char *name, 457 LDAP_CONST char *val, 458 ber_len_t vlen, 459 ber_len_t wrap ) 460 { 461 const unsigned char *byte, *stop; 462 unsigned char buf[3]; 463 unsigned long bits; 464 char *save; 465 int pad; 466 int namelen = 0; 467 468 ber_len_t savelen; 469 ber_len_t len=0; 470 ber_len_t i; 471 472 if ( !wrap ) 473 wrap = LDIF_LINE_WIDTH; 474 475 /* prefix */ 476 switch( type ) { 477 case LDIF_PUT_COMMENT: 478 *(*out)++ = '#'; 479 len++; 480 481 if( vlen ) { 482 *(*out)++ = ' '; 483 len++; 484 } 485 486 break; 487 488 case LDIF_PUT_SEP: 489 *(*out)++ = '\n'; 490 return; 491 } 492 493 /* name (attribute type) */ 494 if( name != NULL ) { 495 /* put the name + ":" */ 496 namelen = strlen(name); 497 strcpy(*out, name); 498 *out += namelen; 499 len += namelen; 500 501 if( type != LDIF_PUT_COMMENT ) { 502 *(*out)++ = ':'; 503 len++; 504 } 505 506 } 507 #ifdef LDAP_DEBUG 508 else { 509 assert( type == LDIF_PUT_COMMENT ); 510 } 511 #endif 512 513 if( vlen == 0 ) { 514 *(*out)++ = '\n'; 515 return; 516 } 517 518 switch( type ) { 519 case LDIF_PUT_NOVALUE: 520 *(*out)++ = '\n'; 521 return; 522 523 case LDIF_PUT_URL: /* url value */ 524 *(*out)++ = '<'; 525 len++; 526 break; 527 528 case LDIF_PUT_B64: /* base64 value */ 529 *(*out)++ = ':'; 530 len++; 531 break; 532 } 533 534 switch( type ) { 535 case LDIF_PUT_TEXT: 536 case LDIF_PUT_URL: 537 case LDIF_PUT_B64: 538 *(*out)++ = ' '; 539 len++; 540 /* fall-thru */ 541 542 case LDIF_PUT_COMMENT: 543 /* pre-encoded names */ 544 for ( i=0; i < vlen; i++ ) { 545 if ( len > wrap ) { 546 *(*out)++ = '\n'; 547 *(*out)++ = ' '; 548 len = 1; 549 } 550 551 *(*out)++ = val[i]; 552 len++; 553 } 554 *(*out)++ = '\n'; 555 return; 556 } 557 558 save = *out; 559 savelen = len; 560 561 *(*out)++ = ' '; 562 len++; 563 564 stop = (const unsigned char *) (val + vlen); 565 566 if ( type == LDIF_PUT_VALUE 567 && isgraph( (unsigned char) val[0] ) && val[0] != ':' && val[0] != '<' 568 && isgraph( (unsigned char) val[vlen-1] ) 569 #ifndef LDAP_BINARY_DEBUG 570 && strstr( name, ";binary" ) == NULL 571 #endif 572 #ifndef LDAP_PASSWD_DEBUG 573 && !ldif_must_b64_encode( name ) 574 #endif 575 ) { 576 int b64 = 0; 577 578 for ( byte = (const unsigned char *) val; byte < stop; 579 byte++, len++ ) 580 { 581 if ( !isascii( *byte ) || !isprint( *byte ) ) { 582 b64 = 1; 583 break; 584 } 585 if ( len >= wrap ) { 586 *(*out)++ = '\n'; 587 *(*out)++ = ' '; 588 len = 1; 589 } 590 *(*out)++ = *byte; 591 } 592 593 if( !b64 ) { 594 *(*out)++ = '\n'; 595 return; 596 } 597 } 598 599 *out = save; 600 *(*out)++ = ':'; 601 *(*out)++ = ' '; 602 len = savelen + 2; 603 604 /* convert to base 64 (3 bytes => 4 base 64 digits) */ 605 for ( byte = (const unsigned char *) val; 606 byte < stop - 2; 607 byte += 3 ) 608 { 609 bits = (byte[0] & 0xff) << 16; 610 bits |= (byte[1] & 0xff) << 8; 611 bits |= (byte[2] & 0xff); 612 613 for ( i = 0; i < 4; i++, len++, bits <<= 6 ) { 614 if ( len >= wrap ) { 615 *(*out)++ = '\n'; 616 *(*out)++ = ' '; 617 len = 1; 618 } 619 620 /* get b64 digit from high order 6 bits */ 621 *(*out)++ = nib2b64[ (bits & 0xfc0000L) >> 18 ]; 622 } 623 } 624 625 /* add padding if necessary */ 626 if ( byte < stop ) { 627 for ( i = 0; byte + i < stop; i++ ) { 628 buf[i] = byte[i]; 629 } 630 for ( pad = 0; i < 3; i++, pad++ ) { 631 buf[i] = '\0'; 632 } 633 byte = buf; 634 bits = (byte[0] & 0xff) << 16; 635 bits |= (byte[1] & 0xff) << 8; 636 bits |= (byte[2] & 0xff); 637 638 for ( i = 0; i < 4; i++, len++, bits <<= 6 ) { 639 if ( len >= wrap ) { 640 *(*out)++ = '\n'; 641 *(*out)++ = ' '; 642 len = 1; 643 } 644 645 if( i + pad < 4 ) { 646 /* get b64 digit from low order 6 bits */ 647 *(*out)++ = nib2b64[ (bits & 0xfc0000L) >> 18 ]; 648 } else { 649 *(*out)++ = '='; 650 } 651 } 652 } 653 *(*out)++ = '\n'; 654 } 655 656 657 /* 658 * ldif_type_and_value return BER malloc'd, zero-terminated LDIF line 659 */ 660 661 /* NOTE: only preserved for binary compatibility */ 662 char * 663 ldif_put( 664 int type, 665 LDAP_CONST char *name, 666 LDAP_CONST char *val, 667 ber_len_t vlen ) 668 { 669 return ldif_put_wrap( type, name, val, vlen, 0 ); 670 } 671 672 char * 673 ldif_put_wrap( 674 int type, 675 LDAP_CONST char *name, 676 LDAP_CONST char *val, 677 ber_len_t vlen, 678 ber_len_t wrap ) 679 { 680 char *buf, *p; 681 ber_len_t nlen; 682 683 nlen = ( name != NULL ) ? strlen( name ) : 0; 684 685 buf = (char *) ber_memalloc( LDIF_SIZE_NEEDED_WRAP( nlen, vlen, wrap ) + 1 ); 686 687 if ( buf == NULL ) { 688 ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug, 689 _("ldif_type_and_value: malloc failed!")); 690 return NULL; 691 } 692 693 p = buf; 694 ldif_sput_wrap( &p, type, name, val, vlen, wrap ); 695 *p = '\0'; 696 697 return( buf ); 698 } 699 700 int ldif_is_not_printable( 701 LDAP_CONST char *val, 702 ber_len_t vlen ) 703 { 704 if( vlen == 0 || val == NULL ) { 705 return -1; 706 } 707 708 if( isgraph( (unsigned char) val[0] ) && val[0] != ':' && val[0] != '<' && 709 isgraph( (unsigned char) val[vlen-1] ) ) 710 { 711 ber_len_t i; 712 713 for ( i = 0; val[i]; i++ ) { 714 if ( !isascii( val[i] ) || !isprint( (unsigned char) val[i] ) ) { 715 return 1; 716 } 717 } 718 719 return 0; 720 } 721 722 return 1; 723 } 724 725 LDIFFP * 726 ldif_open( 727 LDAP_CONST char *file, 728 LDAP_CONST char *mode 729 ) 730 { 731 FILE *fp = fopen( file, mode ); 732 LDIFFP *lfp = NULL; 733 734 if ( fp ) { 735 lfp = ber_memalloc( sizeof( LDIFFP )); 736 if ( lfp == NULL ) { 737 return NULL; 738 } 739 lfp->fp = fp; 740 lfp->prev = NULL; 741 } 742 return lfp; 743 } 744 745 LDIFFP * 746 ldif_open_mem( 747 char *ldif, 748 size_t size, 749 LDAP_CONST char *mode 750 ) 751 { 752 #ifdef HAVE_FMEMOPEN 753 FILE *fp = fmemopen( ldif, size, mode ); 754 LDIFFP *lfp = NULL; 755 756 if ( fp ) { 757 lfp = ber_memalloc( sizeof( LDIFFP )); 758 lfp->fp = fp; 759 lfp->prev = NULL; 760 } 761 return lfp; 762 #else /* !HAVE_FMEMOPEN */ 763 return NULL; 764 #endif /* !HAVE_FMEMOPEN */ 765 } 766 767 void 768 ldif_close( 769 LDIFFP *lfp 770 ) 771 { 772 LDIFFP *prev; 773 774 while ( lfp ) { 775 fclose( lfp->fp ); 776 prev = lfp->prev; 777 ber_memfree( lfp ); 778 lfp = prev; 779 } 780 } 781 782 #define LDIF_MAXLINE 4096 783 784 /* 785 * ldif_read_record - read an ldif record. Return 1 for success, 0 for EOF, 786 * -1 for error. 787 */ 788 int 789 ldif_read_record( 790 LDIFFP *lfp, 791 unsigned long *lno, /* ptr to line number counter */ 792 char **bufp, /* ptr to malloced output buffer */ 793 int *buflenp ) /* ptr to length of *bufp */ 794 { 795 char line[LDIF_MAXLINE], *nbufp; 796 ber_len_t lcur = 0, len; 797 int last_ch = '\n', found_entry = 0, stop, top_comment = 0; 798 799 for ( stop = 0; !stop; last_ch = line[len-1] ) { 800 /* If we're at the end of this file, see if we should pop 801 * back to a previous file. (return from an include) 802 */ 803 while ( feof( lfp->fp )) { 804 if ( lfp->prev ) { 805 LDIFFP *tmp = lfp->prev; 806 fclose( lfp->fp ); 807 *lfp = *tmp; 808 ber_memfree( tmp ); 809 } else { 810 stop = 1; 811 break; 812 } 813 } 814 if ( !stop ) { 815 if ( fgets( line, sizeof( line ), lfp->fp ) == NULL ) { 816 stop = 1; 817 len = 0; 818 } else { 819 len = strlen( line ); 820 } 821 } 822 823 if ( stop ) { 824 /* Add \n in case the file does not end with newline */ 825 if (last_ch != '\n') { 826 len = 1; 827 line[0] = '\n'; 828 line[1] = '\0'; 829 goto last; 830 } 831 break; 832 } 833 834 /* Squash \r\n to \n */ 835 if ( len > 1 && line[len-2] == '\r' ) { 836 len--; 837 line[len] = '\0'; 838 line[len-1] = '\n'; 839 } 840 841 if ( last_ch == '\n' ) { 842 (*lno)++; 843 844 if ( line[0] == '\n' ) { 845 if ( !found_entry ) { 846 lcur = 0; 847 top_comment = 0; 848 continue; 849 } 850 break; 851 } 852 853 if ( !found_entry ) { 854 if ( line[0] == '#' ) { 855 top_comment = 1; 856 } else if ( ! ( top_comment && line[0] == ' ' ) ) { 857 /* Found a new entry */ 858 found_entry = 1; 859 860 if ( isdigit( (unsigned char) line[0] ) ) { 861 /* skip index */ 862 continue; 863 } 864 if ( !strncasecmp( line, "include:", 865 STRLENOF("include:"))) { 866 FILE *fp2; 867 char *ptr; 868 found_entry = 0; 869 870 if ( line[len-1] == '\n' ) { 871 len--; 872 line[len] = '\0'; 873 } 874 875 ptr = line + STRLENOF("include:"); 876 while (isspace((unsigned char) *ptr)) ptr++; 877 fp2 = ldif_open_url( ptr ); 878 if ( fp2 ) { 879 LDIFFP *lnew = ber_memalloc( sizeof( LDIFFP )); 880 if ( lnew == NULL ) { 881 fclose( fp2 ); 882 return 0; 883 } 884 lnew->prev = lfp->prev; 885 lnew->fp = lfp->fp; 886 lfp->prev = lnew; 887 lfp->fp = fp2; 888 line[len] = '\n'; 889 len++; 890 continue; 891 } else { 892 /* We failed to open the file, this should 893 * be reported as an error somehow. 894 */ 895 ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug, 896 _("ldif_read_record: include %s failed\n"), ptr ); 897 return -1; 898 } 899 } 900 } 901 } 902 } 903 904 last: 905 if ( *buflenp - lcur <= len ) { 906 *buflenp += len + LDIF_MAXLINE; 907 nbufp = ber_memrealloc( *bufp, *buflenp ); 908 if( nbufp == NULL ) { 909 return 0; 910 } 911 *bufp = nbufp; 912 } 913 strcpy( *bufp + lcur, line ); 914 lcur += len; 915 } 916 917 return( found_entry ); 918 } 919