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