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