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