1/* $OpenLDAP$ */ 2/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 3 * 4 * Copyright 1998-2011 The OpenLDAP Foundation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted only as authorized by the OpenLDAP 9 * Public License. 10 * 11 * A copy of this license is available in the file LICENSE in the 12 * top-level directory of the distribution or, alternatively, at 13 * <http://www.OpenLDAP.org/license.html>. 14 */ 15 16#include "portable.h" 17 18#include <stdio.h> 19 20#include <ac/stdlib.h> 21 22#include <ac/ctype.h> 23#include <ac/socket.h> 24#include <ac/string.h> 25#include <ac/time.h> 26#include <ac/unistd.h> 27 28#include <sys/stat.h> 29 30#ifdef HAVE_SYS_FILE_H 31#include <sys/file.h> 32#endif 33#ifdef HAVE_IO_H 34#include <io.h> 35#endif 36 37#include <fcntl.h> 38 39/* including the "internal" defs is legit and nec. since this test routine has 40 * a-priori knowledge of libldap internal workings. 41 * hodges@stanford.edu 5-Feb-96 42 */ 43#include "ldap-int.h" 44 45/* local functions */ 46static char *get_line LDAP_P(( char *line, int len, FILE *fp, const char *prompt )); 47static char **get_list LDAP_P(( const char *prompt )); 48static int file_read LDAP_P(( const char *path, struct berval *bv )); 49static LDAPMod **get_modlist LDAP_P(( const char *prompt1, 50 const char *prompt2, const char *prompt3 )); 51static void handle_result LDAP_P(( LDAP *ld, LDAPMessage *lm )); 52static void print_ldap_result LDAP_P(( LDAP *ld, LDAPMessage *lm, 53 const char *s )); 54static void print_search_entry LDAP_P(( LDAP *ld, LDAPMessage *res )); 55static void free_list LDAP_P(( char **list )); 56 57static char *dnsuffix; 58 59static char * 60get_line( char *line, int len, FILE *fp, const char *prompt ) 61{ 62 fputs(prompt, stdout); 63 64 if ( fgets( line, len, fp ) == NULL ) 65 return( NULL ); 66 67 line[ strlen( line ) - 1 ] = '\0'; 68 69 return( line ); 70} 71 72static char ** 73get_list( const char *prompt ) 74{ 75 static char buf[256]; 76 int num; 77 char **result; 78 79 num = 0; 80 result = (char **) 0; 81 while ( 1 ) { 82 get_line( buf, sizeof(buf), stdin, prompt ); 83 84 if ( *buf == '\0' ) 85 break; 86 87 if ( result == (char **) 0 ) 88 result = (char **) malloc( sizeof(char *) ); 89 else 90 result = (char **) realloc( result, 91 sizeof(char *) * (num + 1) ); 92 93 result[num++] = (char *) strdup( buf ); 94 } 95 if ( result == (char **) 0 ) 96 return( NULL ); 97 result = (char **) realloc( result, sizeof(char *) * (num + 1) ); 98 result[num] = NULL; 99 100 return( result ); 101} 102 103 104static void 105free_list( char **list ) 106{ 107 int i; 108 109 if ( list != NULL ) { 110 for ( i = 0; list[ i ] != NULL; ++i ) { 111 free( list[ i ] ); 112 } 113 free( (char *)list ); 114 } 115} 116 117 118static int 119file_read( const char *path, struct berval *bv ) 120{ 121 FILE *fp; 122 ber_slen_t rlen; 123 int eof; 124 125 if (( fp = fopen( path, "r" )) == NULL ) { 126 perror( path ); 127 return( -1 ); 128 } 129 130 if ( fseek( fp, 0L, SEEK_END ) != 0 ) { 131 perror( path ); 132 fclose( fp ); 133 return( -1 ); 134 } 135 136 bv->bv_len = ftell( fp ); 137 138 if (( bv->bv_val = (char *)malloc( bv->bv_len )) == NULL ) { 139 perror( "malloc" ); 140 fclose( fp ); 141 return( -1 ); 142 } 143 144 if ( fseek( fp, 0L, SEEK_SET ) != 0 ) { 145 perror( path ); 146 fclose( fp ); 147 return( -1 ); 148 } 149 150 rlen = fread( bv->bv_val, 1, bv->bv_len, fp ); 151 eof = feof( fp ); 152 fclose( fp ); 153 154 if ( (ber_len_t) rlen != bv->bv_len ) { 155 perror( path ); 156 free( bv->bv_val ); 157 return( -1 ); 158 } 159 160 return( bv->bv_len ); 161} 162 163 164static LDAPMod ** 165get_modlist( 166 const char *prompt1, 167 const char *prompt2, 168 const char *prompt3 ) 169{ 170 static char buf[256]; 171 int num; 172 LDAPMod tmp = { 0 }; 173 LDAPMod **result; 174 struct berval **bvals; 175 176 num = 0; 177 result = NULL; 178 while ( 1 ) { 179 if ( prompt1 ) { 180 get_line( buf, sizeof(buf), stdin, prompt1 ); 181 tmp.mod_op = atoi( buf ); 182 183 if ( tmp.mod_op == -1 || buf[0] == '\0' ) 184 break; 185 } 186 187 get_line( buf, sizeof(buf), stdin, prompt2 ); 188 if ( buf[0] == '\0' ) 189 break; 190 tmp.mod_type = strdup( buf ); 191 192 tmp.mod_values = get_list( prompt3 ); 193 194 if ( tmp.mod_values != NULL ) { 195 int i; 196 197 for ( i = 0; tmp.mod_values[i] != NULL; ++i ) 198 ; 199 bvals = (struct berval **)calloc( i + 1, 200 sizeof( struct berval *)); 201 for ( i = 0; tmp.mod_values[i] != NULL; ++i ) { 202 bvals[i] = (struct berval *)malloc( 203 sizeof( struct berval )); 204 if ( strncmp( tmp.mod_values[i], "{FILE}", 205 6 ) == 0 ) { 206 if ( file_read( tmp.mod_values[i] + 6, 207 bvals[i] ) < 0 ) { 208 free( bvals ); 209 for ( i = 0; i<num; i++ ) 210 free( result[ i ] ); 211 free( result ); 212 return( NULL ); 213 } 214 } else { 215 bvals[i]->bv_val = tmp.mod_values[i]; 216 bvals[i]->bv_len = 217 strlen( tmp.mod_values[i] ); 218 } 219 } 220 tmp.mod_bvalues = bvals; 221 tmp.mod_op |= LDAP_MOD_BVALUES; 222 } 223 224 if ( result == NULL ) 225 result = (LDAPMod **) malloc( sizeof(LDAPMod *) ); 226 else 227 result = (LDAPMod **) realloc( result, 228 sizeof(LDAPMod *) * (num + 1) ); 229 230 result[num] = (LDAPMod *) malloc( sizeof(LDAPMod) ); 231 *(result[num]) = tmp; /* struct copy */ 232 num++; 233 } 234 if ( result == NULL ) 235 return( NULL ); 236 result = (LDAPMod **) realloc( result, sizeof(LDAPMod *) * (num + 1) ); 237 result[num] = NULL; 238 239 return( result ); 240} 241 242 243static int 244bind_prompt( LDAP *ld, 245 LDAP_CONST char *url, 246 ber_tag_t request, ber_int_t msgid, 247 void *params ) 248{ 249 static char dn[256], passwd[256]; 250 int authmethod; 251 252 printf("rebind for request=%ld msgid=%ld url=%s\n", 253 request, (long) msgid, url ); 254 255 authmethod = LDAP_AUTH_SIMPLE; 256 257 get_line( dn, sizeof(dn), stdin, "re-bind dn? " ); 258 strcat( dn, dnsuffix ); 259 260 if ( authmethod == LDAP_AUTH_SIMPLE && dn[0] != '\0' ) { 261 get_line( passwd, sizeof(passwd), stdin, 262 "re-bind password? " ); 263 } else { 264 passwd[0] = '\0'; 265 } 266 267 return ldap_bind_s( ld, dn, passwd, authmethod); 268} 269 270 271int 272main( int argc, char **argv ) 273{ 274 LDAP *ld = NULL; 275 int i, c, port, errflg, method, id, msgtype; 276 char line[256], command1, command2, command3; 277 char passwd[64], dn[256], rdn[64], attr[64], value[256]; 278 char filter[256], *host, **types; 279 char **exdn; 280 static const char usage[] = 281 "usage: %s [-u] [-h host] [-d level] [-s dnsuffix] [-p port] [-t file] [-T file]\n"; 282 int bound, all, scope, attrsonly; 283 LDAPMessage *res; 284 LDAPMod **mods, **attrs; 285 struct timeval timeout; 286 char *copyfname = NULL; 287 int copyoptions = 0; 288 LDAPURLDesc *ludp; 289 290 host = NULL; 291 port = LDAP_PORT; 292 dnsuffix = ""; 293 errflg = 0; 294 295 while (( c = getopt( argc, argv, "h:d:s:p:t:T:" )) != -1 ) { 296 switch( c ) { 297 case 'd': 298#ifdef LDAP_DEBUG 299 ldap_debug = atoi( optarg ); 300#ifdef LBER_DEBUG 301 if ( ldap_debug & LDAP_DEBUG_PACKETS ) { 302 ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &ldap_debug ); 303 } 304#endif 305#else 306 printf( "Compile with -DLDAP_DEBUG for debugging\n" ); 307#endif 308 break; 309 310 case 'h': 311 host = optarg; 312 break; 313 314 case 's': 315 dnsuffix = optarg; 316 break; 317 318 case 'p': 319 port = atoi( optarg ); 320 break; 321 322 case 't': /* copy ber's to given file */ 323 copyfname = strdup( optarg ); 324/* copyoptions = LBER_TO_FILE; */ 325 break; 326 327 case 'T': /* only output ber's to given file */ 328 copyfname = strdup( optarg ); 329/* copyoptions = (LBER_TO_FILE | LBER_TO_FILE_ONLY); */ 330 break; 331 332 default: 333 ++errflg; 334 } 335 } 336 337 if ( host == NULL && optind == argc - 1 ) { 338 host = argv[ optind ]; 339 ++optind; 340 } 341 342 if ( errflg || optind < argc - 1 ) { 343 fprintf( stderr, usage, argv[ 0 ] ); 344 exit( EXIT_FAILURE ); 345 } 346 347 printf( "ldap_init( %s, %d )\n", 348 host == NULL ? "(null)" : host, port ); 349 350 ld = ldap_init( host, port ); 351 352 if ( ld == NULL ) { 353 perror( "ldap_init" ); 354 exit( EXIT_FAILURE ); 355 } 356 357 if ( copyfname != NULL ) { 358 if ( ( ld->ld_sb->sb_fd = open( copyfname, O_WRONLY|O_CREAT|O_EXCL, 359 0600 )) == -1 ) { 360 perror( copyfname ); 361 exit ( EXIT_FAILURE ); 362 } 363 ld->ld_sb->sb_options = copyoptions; 364 } 365 366 bound = 0; 367 timeout.tv_sec = 0; 368 timeout.tv_usec = 0; 369 370 (void) memset( line, '\0', sizeof(line) ); 371 while ( get_line( line, sizeof(line), stdin, "\ncommand? " ) != NULL ) { 372 command1 = line[0]; 373 command2 = line[1]; 374 command3 = line[2]; 375 376 switch ( command1 ) { 377 case 'a': /* add or abandon */ 378 switch ( command2 ) { 379 case 'd': /* add */ 380 get_line( dn, sizeof(dn), stdin, "dn? " ); 381 strcat( dn, dnsuffix ); 382 if ( (attrs = get_modlist( NULL, "attr? ", 383 "value? " )) == NULL ) 384 break; 385 if ( (id = ldap_add( ld, dn, attrs )) == -1 ) 386 ldap_perror( ld, "ldap_add" ); 387 else 388 printf( "Add initiated with id %d\n", 389 id ); 390 break; 391 392 case 'b': /* abandon */ 393 get_line( line, sizeof(line), stdin, "msgid? " ); 394 id = atoi( line ); 395 if ( ldap_abandon( ld, id ) != 0 ) 396 ldap_perror( ld, "ldap_abandon" ); 397 else 398 printf( "Abandon successful\n" ); 399 break; 400 default: 401 printf( "Possibilities: [ad]d, [ab]ort\n" ); 402 } 403 break; 404 405 case 'b': /* asynch bind */ 406 method = LDAP_AUTH_SIMPLE; 407 get_line( dn, sizeof(dn), stdin, "dn? " ); 408 strcat( dn, dnsuffix ); 409 410 if ( method == LDAP_AUTH_SIMPLE && dn[0] != '\0' ) 411 get_line( passwd, sizeof(passwd), stdin, 412 "password? " ); 413 else 414 passwd[0] = '\0'; 415 416 if ( ldap_bind( ld, dn, passwd, method ) == -1 ) { 417 fprintf( stderr, "ldap_bind failed\n" ); 418 ldap_perror( ld, "ldap_bind" ); 419 } else { 420 printf( "Bind initiated\n" ); 421 bound = 1; 422 } 423 break; 424 425 case 'B': /* synch bind */ 426 method = LDAP_AUTH_SIMPLE; 427 get_line( dn, sizeof(dn), stdin, "dn? " ); 428 strcat( dn, dnsuffix ); 429 430 if ( dn[0] != '\0' ) 431 get_line( passwd, sizeof(passwd), stdin, 432 "password? " ); 433 else 434 passwd[0] = '\0'; 435 436 if ( ldap_bind_s( ld, dn, passwd, method ) != 437 LDAP_SUCCESS ) { 438 fprintf( stderr, "ldap_bind_s failed\n" ); 439 ldap_perror( ld, "ldap_bind_s" ); 440 } else { 441 printf( "Bind successful\n" ); 442 bound = 1; 443 } 444 break; 445 446 case 'c': /* compare */ 447 get_line( dn, sizeof(dn), stdin, "dn? " ); 448 strcat( dn, dnsuffix ); 449 get_line( attr, sizeof(attr), stdin, "attr? " ); 450 get_line( value, sizeof(value), stdin, "value? " ); 451 452 if ( (id = ldap_compare( ld, dn, attr, value )) == -1 ) 453 ldap_perror( ld, "ldap_compare" ); 454 else 455 printf( "Compare initiated with id %d\n", id ); 456 break; 457 458 case 'd': /* turn on debugging */ 459#ifdef LDAP_DEBUG 460 get_line( line, sizeof(line), stdin, "debug level? " ); 461 ldap_debug = atoi( line ); 462#ifdef LBER_DEBUG 463 if ( ldap_debug & LDAP_DEBUG_PACKETS ) { 464 ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &ldap_debug ); 465 } 466#endif 467#else 468 printf( "Compile with -DLDAP_DEBUG for debugging\n" ); 469#endif 470 break; 471 472 case 'E': /* explode a dn */ 473 get_line( line, sizeof(line), stdin, "dn? " ); 474 exdn = ldap_explode_dn( line, 0 ); 475 for ( i = 0; exdn != NULL && exdn[i] != NULL; i++ ) { 476 printf( "\t%s\n", exdn[i] ); 477 } 478 break; 479 480 case 'g': /* set next msgid */ 481 get_line( line, sizeof(line), stdin, "msgid? " ); 482 ld->ld_msgid = atoi( line ); 483 break; 484 485 case 'v': /* set version number */ 486 get_line( line, sizeof(line), stdin, "version? " ); 487 ld->ld_version = atoi( line ); 488 break; 489 490 case 'm': /* modify or modifyrdn */ 491 if ( strncmp( line, "modify", 4 ) == 0 ) { 492 get_line( dn, sizeof(dn), stdin, "dn? " ); 493 strcat( dn, dnsuffix ); 494 if ( (mods = get_modlist( 495 "mod (0=>add, 1=>delete, 2=>replace -1=>done)? ", 496 "attribute type? ", "attribute value? " )) 497 == NULL ) 498 break; 499 if ( (id = ldap_modify( ld, dn, mods )) == -1 ) 500 ldap_perror( ld, "ldap_modify" ); 501 else 502 printf( "Modify initiated with id %d\n", 503 id ); 504 } else if ( strncmp( line, "modrdn", 4 ) == 0 ) { 505 get_line( dn, sizeof(dn), stdin, "dn? " ); 506 strcat( dn, dnsuffix ); 507 get_line( rdn, sizeof(rdn), stdin, "newrdn? " ); 508 if ( (id = ldap_modrdn( ld, dn, rdn )) == -1 ) 509 ldap_perror( ld, "ldap_modrdn" ); 510 else 511 printf( "Modrdn initiated with id %d\n", 512 id ); 513 } else { 514 printf( "Possibilities: [modi]fy, [modr]dn\n" ); 515 } 516 break; 517 518 case 'q': /* quit */ 519 ldap_unbind( ld ); 520 exit( EXIT_SUCCESS ); 521 break; 522 523 case 'r': /* result or remove */ 524 switch ( command3 ) { 525 case 's': /* result */ 526 get_line( line, sizeof(line), stdin, 527 "msgid (-1=>any)? " ); 528 if ( line[0] == '\0' ) 529 id = -1; 530 else 531 id = atoi( line ); 532 get_line( line, sizeof(line), stdin, 533 "all (0=>any, 1=>all)? " ); 534 if ( line[0] == '\0' ) 535 all = 1; 536 else 537 all = atoi( line ); 538 if (( msgtype = ldap_result( ld, id, all, 539 &timeout, &res )) < 1 ) { 540 ldap_perror( ld, "ldap_result" ); 541 break; 542 } 543 printf( "\nresult: msgtype %d msgid %d\n", 544 msgtype, res->lm_msgid ); 545 handle_result( ld, res ); 546 res = NULL; 547 break; 548 549 case 'm': /* remove */ 550 get_line( dn, sizeof(dn), stdin, "dn? " ); 551 strcat( dn, dnsuffix ); 552 if ( (id = ldap_delete( ld, dn )) == -1 ) 553 ldap_perror( ld, "ldap_delete" ); 554 else 555 printf( "Remove initiated with id %d\n", 556 id ); 557 break; 558 559 default: 560 printf( "Possibilities: [rem]ove, [res]ult\n" ); 561 break; 562 } 563 break; 564 565 case 's': /* search */ 566 get_line( dn, sizeof(dn), stdin, "searchbase? " ); 567 strcat( dn, dnsuffix ); 568 get_line( line, sizeof(line), stdin, 569 "scope (0=baseObject, 1=oneLevel, 2=subtree, 3=children)? " ); 570 scope = atoi( line ); 571 get_line( filter, sizeof(filter), stdin, 572 "search filter (e.g. sn=jones)? " ); 573 types = get_list( "attrs to return? " ); 574 get_line( line, sizeof(line), stdin, 575 "attrsonly (0=attrs&values, 1=attrs only)? " ); 576 attrsonly = atoi( line ); 577 578 if (( id = ldap_search( ld, dn, scope, filter, 579 types, attrsonly )) == -1 ) { 580 ldap_perror( ld, "ldap_search" ); 581 } else { 582 printf( "Search initiated with id %d\n", id ); 583 } 584 free_list( types ); 585 break; 586 587 case 't': /* set timeout value */ 588 get_line( line, sizeof(line), stdin, "timeout? " ); 589 timeout.tv_sec = atoi( line ); 590 break; 591 592 case 'p': /* parse LDAP URL */ 593 get_line( line, sizeof(line), stdin, "LDAP URL? " ); 594 if (( i = ldap_url_parse( line, &ludp )) != 0 ) { 595 fprintf( stderr, "ldap_url_parse: error %d\n", i ); 596 } else { 597 printf( "\t host: " ); 598 if ( ludp->lud_host == NULL ) { 599 printf( "DEFAULT\n" ); 600 } else { 601 printf( "<%s>\n", ludp->lud_host ); 602 } 603 printf( "\t port: " ); 604 if ( ludp->lud_port == 0 ) { 605 printf( "DEFAULT\n" ); 606 } else { 607 printf( "%d\n", ludp->lud_port ); 608 } 609 printf( "\t dn: <%s>\n", ludp->lud_dn ); 610 printf( "\t attrs:" ); 611 if ( ludp->lud_attrs == NULL ) { 612 printf( " ALL" ); 613 } else { 614 for ( i = 0; ludp->lud_attrs[ i ] != NULL; ++i ) { 615 printf( " <%s>", ludp->lud_attrs[ i ] ); 616 } 617 } 618 printf( "\n\t scope: %s\n", 619 ludp->lud_scope == LDAP_SCOPE_BASE ? "baseObject" 620 : ludp->lud_scope == LDAP_SCOPE_ONELEVEL ? "oneLevel" 621 : ludp->lud_scope == LDAP_SCOPE_SUBTREE ? "subtree" 622#ifdef LDAP_SCOPE_SUBORDINATE 623 : ludp->lud_scope == LDAP_SCOPE_SUBORDINATE ? "children" 624#endif 625 : "**invalid**" ); 626 printf( "\tfilter: <%s>\n", ludp->lud_filter ); 627 ldap_free_urldesc( ludp ); 628 } 629 break; 630 631 case 'n': /* set dn suffix, for convenience */ 632 get_line( line, sizeof(line), stdin, "DN suffix? " ); 633 strcpy( dnsuffix, line ); 634 break; 635 636 case 'o': /* set ldap options */ 637 get_line( line, sizeof(line), stdin, "alias deref (0=never, 1=searching, 2=finding, 3=always)?" ); 638 ld->ld_deref = atoi( line ); 639 get_line( line, sizeof(line), stdin, "timelimit?" ); 640 ld->ld_timelimit = atoi( line ); 641 get_line( line, sizeof(line), stdin, "sizelimit?" ); 642 ld->ld_sizelimit = atoi( line ); 643 644 LDAP_BOOL_ZERO(&ld->ld_options); 645 646 get_line( line, sizeof(line), stdin, 647 "Recognize and chase referrals (0=no, 1=yes)?" ); 648 if ( atoi( line ) != 0 ) { 649 LDAP_BOOL_SET(&ld->ld_options, LDAP_BOOL_REFERRALS); 650 get_line( line, sizeof(line), stdin, 651 "Prompt for bind credentials when chasing referrals (0=no, 1=yes)?" ); 652 if ( atoi( line ) != 0 ) { 653 ldap_set_rebind_proc( ld, bind_prompt, NULL ); 654 } 655 } 656 break; 657 658 case '?': /* help */ 659 printf( 660"Commands: [ad]d [ab]andon [b]ind\n" 661" [B]ind async [c]ompare\n" 662" [modi]fy [modr]dn [rem]ove\n" 663" [res]ult [s]earch [q]uit/unbind\n\n" 664" [d]ebug set ms[g]id\n" 665" d[n]suffix [t]imeout [v]ersion\n" 666" [?]help [o]ptions" 667" [E]xplode dn [p]arse LDAP URL\n" ); 668 break; 669 670 default: 671 printf( "Invalid command. Type ? for help.\n" ); 672 break; 673 } 674 675 (void) memset( line, '\0', sizeof(line) ); 676 } 677 678 return( 0 ); 679} 680 681static void 682handle_result( LDAP *ld, LDAPMessage *lm ) 683{ 684 switch ( lm->lm_msgtype ) { 685 case LDAP_RES_COMPARE: 686 printf( "Compare result\n" ); 687 print_ldap_result( ld, lm, "compare" ); 688 break; 689 690 case LDAP_RES_SEARCH_RESULT: 691 printf( "Search result\n" ); 692 print_ldap_result( ld, lm, "search" ); 693 break; 694 695 case LDAP_RES_SEARCH_ENTRY: 696 printf( "Search entry\n" ); 697 print_search_entry( ld, lm ); 698 break; 699 700 case LDAP_RES_ADD: 701 printf( "Add result\n" ); 702 print_ldap_result( ld, lm, "add" ); 703 break; 704 705 case LDAP_RES_DELETE: 706 printf( "Delete result\n" ); 707 print_ldap_result( ld, lm, "delete" ); 708 break; 709 710 case LDAP_RES_MODRDN: 711 printf( "ModRDN result\n" ); 712 print_ldap_result( ld, lm, "modrdn" ); 713 break; 714 715 case LDAP_RES_BIND: 716 printf( "Bind result\n" ); 717 print_ldap_result( ld, lm, "bind" ); 718 break; 719 720 default: 721 printf( "Unknown result type 0x%lx\n", 722 (unsigned long) lm->lm_msgtype ); 723 print_ldap_result( ld, lm, "unknown" ); 724 } 725} 726 727static void 728print_ldap_result( LDAP *ld, LDAPMessage *lm, const char *s ) 729{ 730 ldap_result2error( ld, lm, 1 ); 731 ldap_perror( ld, s ); 732/* 733 if ( ld->ld_error != NULL && *ld->ld_error != '\0' ) 734 fprintf( stderr, "Additional info: %s\n", ld->ld_error ); 735 if ( LDAP_NAME_ERROR( ld->ld_errno ) && ld->ld_matched != NULL ) 736 fprintf( stderr, "Matched DN: %s\n", ld->ld_matched ); 737*/ 738} 739 740static void 741print_search_entry( LDAP *ld, LDAPMessage *res ) 742{ 743 LDAPMessage *e; 744 745 for ( e = ldap_first_entry( ld, res ); e != NULL; 746 e = ldap_next_entry( ld, e ) ) 747 { 748 BerElement *ber = NULL; 749 char *a, *dn, *ufn; 750 751 if ( e->lm_msgtype == LDAP_RES_SEARCH_RESULT ) 752 break; 753 754 dn = ldap_get_dn( ld, e ); 755 printf( "\tDN: %s\n", dn ); 756 757 ufn = ldap_dn2ufn( dn ); 758 printf( "\tUFN: %s\n", ufn ); 759 760 free( dn ); 761 free( ufn ); 762 763 for ( a = ldap_first_attribute( ld, e, &ber ); a != NULL; 764 a = ldap_next_attribute( ld, e, ber ) ) 765 { 766 struct berval **vals; 767 768 printf( "\t\tATTR: %s\n", a ); 769 if ( (vals = ldap_get_values_len( ld, e, a )) 770 == NULL ) { 771 printf( "\t\t\t(no values)\n" ); 772 } else { 773 int i; 774 for ( i = 0; vals[i] != NULL; i++ ) { 775 int j, nonascii; 776 777 nonascii = 0; 778 for ( j = 0; (ber_len_t) j < vals[i]->bv_len; j++ ) 779 if ( !isascii( vals[i]->bv_val[j] ) ) { 780 nonascii = 1; 781 break; 782 } 783 784 if ( nonascii ) { 785 printf( "\t\t\tlength (%ld) (not ascii)\n", vals[i]->bv_len ); 786#ifdef BPRINT_NONASCII 787 ber_bprint( vals[i]->bv_val, 788 vals[i]->bv_len ); 789#endif /* BPRINT_NONASCII */ 790 continue; 791 } 792 printf( "\t\t\tlength (%ld) %s\n", 793 vals[i]->bv_len, vals[i]->bv_val ); 794 } 795 ber_bvecfree( vals ); 796 } 797 } 798 799 if(ber != NULL) { 800 ber_free( ber, 0 ); 801 } 802 } 803 804 if ( res->lm_msgtype == LDAP_RES_SEARCH_RESULT 805 || res->lm_chain != NULL ) 806 print_ldap_result( ld, res, "search" ); 807} 808