]> git.sur5r.net Git - openldap/blob - clients/tools/ldapwhoami.c
Fix typo in last commit
[openldap] / clients / tools / ldapwhoami.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6
7 #include "portable.h"
8
9 #include <stdio.h>
10
11 #include <ac/stdlib.h>
12
13 #include <ac/ctype.h>
14 #include <ac/signal.h>
15 #include <ac/socket.h>
16 #include <ac/string.h>
17 #include <ac/time.h>
18 #include <ac/unistd.h>
19
20 #include <ldap.h>
21
22 #include "lutil_ldap.h"
23 #include "ldap_defaults.h"
24
25 static int      verbose = 0;
26
27 static void
28 usage(const char *s)
29 {
30         fprintf(stderr,
31 "Issue LDAP Who am I? operation to request user's authzid\n\n"
32 "usage: %s [options]\n"
33
34 "Common options:\n"
35 "  -d level   set LDAP debugging level to `level'\n"
36 "  -D binddn  bind DN\n"
37 "  -f file    read operations from `file'\n"
38 "  -h host    LDAP server(s)\n"
39 "  -H URI     LDAP Uniform Resource Indentifier(s)\n"
40 "  -I         use SASL Interactive mode\n"
41 "  -n         show what would be done but don't actually search\n"
42 "  -O props   SASL security properties\n"
43 "  -p port    port on LDAP server\n"
44 "  -Q         use SASL Quiet mode\n"
45 "  -R realm   SASL realm\n"
46 "  -U authcid SASL authentication identity\n"
47 "  -v         run in verbose mode (diagnostics to standard output)\n"
48 "  -w passwd  bind passwd (for simple authentication)\n"
49 "  -W         prompt for bind passwd\n"
50 "  -x         Simple authentication\n"
51 "  -X authzid SASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
52 "  -Y mech    SASL mechanism\n"
53 "  -Z         Start TLS request (-ZZ to require successful response)\n"
54                 , s );
55
56         exit( EXIT_FAILURE );
57 }
58
59 int
60 main( int argc, char *argv[] )
61 {
62         int rc;
63         char    *prog = NULL;
64         char    *ldaphost = NULL;
65         char    *ldapuri = NULL;
66
67         char    *user = NULL;
68         char    *binddn = NULL;
69
70         struct berval passwd = { 0, NULL };
71         char    *newpw = NULL;
72         char    *oldpw = NULL;
73
74         int             want_bindpw = 0;
75         int             want_newpw = 0;
76         int             want_oldpw = 0;
77
78         int             not = 0;
79         int             i;
80         int             ldapport = 0;
81         int             debug = 0;
82         int             version = -1;
83         int             authmethod = -1;
84         int             manageDSAit = 0;
85 #ifdef HAVE_CYRUS_SASL
86         unsigned        sasl_flags = LDAP_SASL_AUTOMATIC;
87         char            *sasl_realm = NULL;
88         char            *sasl_authc_id = NULL;
89         char            *sasl_authz_id = NULL;
90         char            *sasl_mech = NULL;
91         char            *sasl_secprops = NULL;
92 #endif
93         int             use_tls = 0;
94         int             referrals = 0;
95         LDAP           *ld = NULL;
96         struct berval *bv = NULL;
97
98         int id, code;
99         LDAPMessage *res;
100         char *matcheddn = NULL, *text = NULL, **refs = NULL;
101         char    *retoid = NULL;
102         struct berval *retdata = NULL;
103
104     prog = (prog = strrchr(argv[0], *LDAP_DIRSEP)) == NULL ? argv[0] : prog + 1;
105
106         while( (i = getopt( argc, argv, "Aa:Ss:"
107                 "Cd:D:h:H:InO:p:QR:U:vw:WxX:Y:Z" )) != EOF )
108         {
109                 switch (i) {
110                 /* Password Options */
111                 case 'A':       /* prompt for old password */
112                         want_oldpw++;
113                         break;
114
115                 case 'a':       /* old password (secret) */
116                         oldpw = strdup (optarg);
117
118                         {
119                                 char* p;
120
121                                 for( p = optarg; *p != '\0'; p++ ) {
122                                         *p = '\0';
123                                 }
124                         }
125                         break;
126
127                 case 'S':       /* prompt for user password */
128                         want_newpw++;
129                         break;
130
131                 case 's':       /* new password (secret) */
132                         newpw = strdup (optarg);
133                         {
134                                 char* p;
135
136                                 for( p = optarg; *p != '\0'; p++ ) {
137                                         *p = '\0';
138                                 }
139                         }
140                         break;
141
142         /* Common Options (including options we don't use) */
143         case 'C':
144                 referrals++;
145                 break;
146         case 'd':
147             debug |= atoi( optarg );
148             break;
149         case 'D':       /* bind DN */
150                 if( binddn != NULL ) {
151                         fprintf( stderr, "%s: -D previously specified\n", prog );
152                         return EXIT_FAILURE;
153                 }
154             binddn = strdup( optarg );
155             break;
156         case 'h':       /* ldap host */
157                 if( ldapuri != NULL ) {
158                         fprintf( stderr, "%s: -h incompatible with -H\n", prog );
159                         return EXIT_FAILURE;
160                 }
161                 if( ldaphost != NULL ) {
162                         fprintf( stderr, "%s: -h previously specified\n", prog );
163                         return EXIT_FAILURE;
164                 }
165             ldaphost = strdup( optarg );
166             break;
167         case 'H':       /* ldap URI */
168                 if( ldaphost != NULL ) {
169                         fprintf( stderr, "%s: -H incompatible with -h\n", prog );
170                         return EXIT_FAILURE;
171                 }
172                 if( ldapport ) {
173                         fprintf( stderr, "%s: -H incompatible with -p\n", prog );
174                         return EXIT_FAILURE;
175                 }
176                 if( ldapuri != NULL ) {
177                         fprintf( stderr, "%s: -H previously specified\n", prog );
178                         return EXIT_FAILURE;
179                 }
180             ldapuri = strdup( optarg );
181             break;
182         case 'I':
183 #ifdef HAVE_CYRUS_SASL
184                 if( version == LDAP_VERSION2 ) {
185                         fprintf( stderr, "%s: -I incompatible with version %d\n",
186                                 prog, version );
187                         return EXIT_FAILURE;
188                 }
189                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
190                         fprintf( stderr, "%s: incompatible previous "
191                                 "authentication choice\n",
192                                 prog );
193                         return EXIT_FAILURE;
194                 }
195                 authmethod = LDAP_AUTH_SASL;
196                 version = LDAP_VERSION3;
197                 sasl_flags = LDAP_SASL_INTERACTIVE;
198                 break;
199 #else
200                 fprintf( stderr, "%s: was not compiled with SASL support\n",
201                         prog );
202                 return( EXIT_FAILURE );
203 #endif
204         case 'k':       /* kerberos bind */
205 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
206                 if( version > LDAP_VERSION2 ) {
207                         fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
208                                 prog, version );
209                         return EXIT_FAILURE;
210                 }
211
212                 if( authmethod != -1 ) {
213                         fprintf( stderr, "%s: -k incompatible with previous "
214                                 "authentication choice\n", prog );
215                         return EXIT_FAILURE;
216                 }
217                         
218                 authmethod = LDAP_AUTH_KRBV4;
219 #else
220                 fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
221                 return EXIT_FAILURE;
222 #endif
223             break;
224         case 'K':       /* kerberos bind, part one only */
225 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
226                 if( version > LDAP_VERSION2 ) {
227                         fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
228                                 prog, version );
229                         return EXIT_FAILURE;
230                 }
231                 if( authmethod != -1 ) {
232                         fprintf( stderr, "%s: incompatible with previous "
233                                 "authentication choice\n", prog );
234                         return EXIT_FAILURE;
235                 }
236
237                 authmethod = LDAP_AUTH_KRBV41;
238 #else
239                 fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
240                 return( EXIT_FAILURE );
241 #endif
242             break;
243         case 'M':
244                 /* enable Manage DSA IT */
245                 if( version == LDAP_VERSION2 ) {
246                         fprintf( stderr, "%s: -M incompatible with LDAPv%d\n",
247                                 prog, version );
248                         return EXIT_FAILURE;
249                 }
250                 manageDSAit++;
251                 version = LDAP_VERSION3;
252                 break;
253         case 'n':       /* print deletes, don't actually do them */
254             ++not;
255             break;
256         case 'O':
257 #ifdef HAVE_CYRUS_SASL
258                 if( sasl_secprops != NULL ) {
259                         fprintf( stderr, "%s: -O previously specified\n", prog );
260                         return EXIT_FAILURE;
261                 }
262                 if( version == LDAP_VERSION2 ) {
263                         fprintf( stderr, "%s: -O incompatible with LDAPv%d\n",
264                                 prog, version );
265                         return EXIT_FAILURE;
266                 }
267                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
268                         fprintf( stderr, "%s: incompatible previous "
269                                 "authentication choice\n", prog );
270                         return EXIT_FAILURE;
271                 }
272                 authmethod = LDAP_AUTH_SASL;
273                 version = LDAP_VERSION3;
274                 sasl_secprops = strdup( optarg );
275 #else
276                 fprintf( stderr, "%s: not compiled with SASL support\n",
277                         prog );
278                 return( EXIT_FAILURE );
279 #endif
280                 break;
281         case 'p':
282                 if( ldapport ) {
283                         fprintf( stderr, "%s: -p previously specified\n", prog );
284                         return EXIT_FAILURE;
285                 }
286             ldapport = atoi( optarg );
287             break;
288         case 'P':
289                 switch( atoi(optarg) ) {
290                 case 2:
291                         if( version == LDAP_VERSION3 ) {
292                                 fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
293                                         prog, version );
294                                 return EXIT_FAILURE;
295                         }
296                         version = LDAP_VERSION2;
297                         break;
298                 case 3:
299                         if( version == LDAP_VERSION2 ) {
300                                 fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
301                                         prog, version );
302                                 return EXIT_FAILURE;
303                         }
304                         version = LDAP_VERSION3;
305                         break;
306                 default:
307                         fprintf( stderr, "%s: protocol version should be 2 or 3\n",
308                                 prog );
309                         usage( prog );
310                         return( EXIT_FAILURE );
311                 } break;
312         case 'Q':
313 #ifdef HAVE_CYRUS_SASL
314                 if( version == LDAP_VERSION2 ) {
315                         fprintf( stderr, "%s: -Q incompatible with version %d\n",
316                                 prog, version );
317                         return EXIT_FAILURE;
318                 }
319                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
320                         fprintf( stderr, "%s: incompatible previous "
321                                 "authentication choice\n",
322                                 prog );
323                         return EXIT_FAILURE;
324                 }
325                 authmethod = LDAP_AUTH_SASL;
326                 version = LDAP_VERSION3;
327                 sasl_flags = LDAP_SASL_QUIET;
328                 break;
329 #else
330                 fprintf( stderr, "%s: not compiled with SASL support\n",
331                         prog );
332                 return( EXIT_FAILURE );
333 #endif
334         case 'R':
335 #ifdef HAVE_CYRUS_SASL
336                 if( sasl_realm != NULL ) {
337                         fprintf( stderr, "%s: -R previously specified\n", prog );
338                         return EXIT_FAILURE;
339                 }
340                 if( version == LDAP_VERSION2 ) {
341                         fprintf( stderr, "%s: -R incompatible with version %d\n",
342                                 prog, version );
343                         return EXIT_FAILURE;
344                 }
345                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
346                         fprintf( stderr, "%s: incompatible previous "
347                                 "authentication choice\n",
348                                 prog );
349                         return EXIT_FAILURE;
350                 }
351                 authmethod = LDAP_AUTH_SASL;
352                 version = LDAP_VERSION3;
353                 sasl_realm = strdup( optarg );
354 #else
355                 fprintf( stderr, "%s: not compiled with SASL support\n",
356                         prog );
357                 return( EXIT_FAILURE );
358 #endif
359                 break;
360         case 'U':
361 #ifdef HAVE_CYRUS_SASL
362                 if( sasl_authc_id != NULL ) {
363                         fprintf( stderr, "%s: -U previously specified\n", prog );
364                         return EXIT_FAILURE;
365                 }
366                 if( version == LDAP_VERSION2 ) {
367                         fprintf( stderr, "%s: -U incompatible with version %d\n",
368                                 prog, version );
369                         return EXIT_FAILURE;
370                 }
371                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
372                         fprintf( stderr, "%s: incompatible previous "
373                                 "authentication choice\n",
374                                 prog );
375                         return EXIT_FAILURE;
376                 }
377                 authmethod = LDAP_AUTH_SASL;
378                 version = LDAP_VERSION3;
379                 sasl_authc_id = strdup( optarg );
380 #else
381                 fprintf( stderr, "%s: not compiled with SASL support\n",
382                         prog );
383                 return( EXIT_FAILURE );
384 #endif
385                 break;
386         case 'v':       /* verbose mode */
387             verbose++;
388             break;
389         case 'w':       /* password */
390             passwd.bv_val = strdup( optarg );
391                 {
392                         char* p;
393
394                         for( p = optarg; *p != '\0'; p++ ) {
395                                 *p = '\0';
396                         }
397                 }
398                 passwd.bv_len = strlen( passwd.bv_val );
399             break;
400         case 'W':
401                 want_bindpw++;
402                 break;
403         case 'Y':
404 #ifdef HAVE_CYRUS_SASL
405                 if( sasl_mech != NULL ) {
406                         fprintf( stderr, "%s: -Y previously specified\n", prog );
407                         return EXIT_FAILURE;
408                 }
409                 if( version == LDAP_VERSION2 ) {
410                         fprintf( stderr, "%s: -Y incompatible with version %d\n",
411                                 prog, version );
412                         return EXIT_FAILURE;
413                 }
414                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
415                         fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
416                         return EXIT_FAILURE;
417                 }
418                 authmethod = LDAP_AUTH_SASL;
419                 version = LDAP_VERSION3;
420                 sasl_mech = strdup( optarg );
421 #else
422                 fprintf( stderr, "%s: not compiled with SASL support\n",
423                         prog );
424                 return( EXIT_FAILURE );
425 #endif
426                 break;
427         case 'x':
428                 if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
429                         fprintf( stderr, "%s: incompatible with previous "
430                                 "authentication choice\n", prog );
431                         return EXIT_FAILURE;
432                 }
433                 authmethod = LDAP_AUTH_SIMPLE;
434                 break;
435         case 'X':
436 #ifdef HAVE_CYRUS_SASL
437                 if( sasl_authz_id != NULL ) {
438                         fprintf( stderr, "%s: -X previously specified\n", prog );
439                         return EXIT_FAILURE;
440                 }
441                 if( version == LDAP_VERSION2 ) {
442                         fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
443                                 prog, version );
444                         return EXIT_FAILURE;
445                 }
446                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
447                         fprintf( stderr, "%s: -X incompatible with "
448                                 "authentication choice\n", prog );
449                         return EXIT_FAILURE;
450                 }
451                 authmethod = LDAP_AUTH_SASL;
452                 version = LDAP_VERSION3;
453                 sasl_authz_id = strdup( optarg );
454 #else
455                 fprintf( stderr, "%s: not compiled with SASL support\n",
456                         prog );
457                 return( EXIT_FAILURE );
458 #endif
459                 break;
460         case 'Z':
461 #ifdef HAVE_TLS
462                 if( version == LDAP_VERSION2 ) {
463                         fprintf( stderr, "%s: -Z incompatible with version %d\n",
464                                 prog, version );
465                         return EXIT_FAILURE;
466                 }
467                 version = LDAP_VERSION3;
468                 use_tls++;
469 #else
470                 fprintf( stderr, "%s: not compiled with TLS support\n",
471                         prog );
472                 return( EXIT_FAILURE );
473 #endif
474                 break;
475
476
477                 default:
478                         fprintf( stderr, "%s: unrecognized option -%c\n",
479                                 prog, optopt );
480                         usage (prog);
481                 }
482         }
483
484         if (authmethod == -1) {
485 #ifdef HAVE_CYRUS_SASL
486                 authmethod = LDAP_AUTH_SASL;
487 #else
488                 authmethod = LDAP_AUTH_SIMPLE;
489 #endif
490         }
491
492         if( argc - optind > 1 ) {
493                 usage( prog );
494         } else if ( argc - optind == 1 ) {
495                 user = strdup( argv[optind] );
496         } else {
497                 user = NULL;
498         }
499
500         if( want_oldpw && oldpw == NULL ) {
501                 /* prompt for old password */
502                 char *ckoldpw;
503                 oldpw = strdup(getpassphrase("Old password: "));
504                 ckoldpw = getpassphrase("Re-enter old password: ");
505
506                 if( oldpw== NULL || ckoldpw == NULL ||
507                         strcmp( oldpw, ckoldpw ))
508                 {
509                         fprintf( stderr, "passwords do not match\n" );
510                         return EXIT_FAILURE;
511                 }
512         }
513
514         if( want_newpw && newpw == NULL ) {
515                 /* prompt for new password */
516                 char *cknewpw;
517                 newpw = strdup(getpassphrase("New password: "));
518                 cknewpw = getpassphrase("Re-enter new password: ");
519
520                 if( newpw== NULL || cknewpw == NULL ||
521                         strcmp( newpw, cknewpw ))
522                 {
523                         fprintf( stderr, "passwords do not match\n" );
524                         return EXIT_FAILURE;
525                 }
526         }
527
528         if (want_bindpw && passwd.bv_val == NULL ) {
529                 /* handle bind password */
530                 passwd.bv_val = strdup( getpassphrase("Enter bind password: "));
531                 passwd.bv_len = passwd.bv_val ? strlen( passwd.bv_val ) : 0;
532         }
533
534         if ( debug ) {
535                 if( ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug ) != LBER_OPT_SUCCESS ) {
536                         fprintf( stderr, "Could not set LBER_OPT_DEBUG_LEVEL %d\n", debug );
537                 }
538                 if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug ) != LDAP_OPT_SUCCESS ) {
539                         fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
540                 }
541         }
542
543 #ifdef SIGPIPE
544         (void) SIGNAL( SIGPIPE, SIG_IGN );
545 #endif
546
547         /* connect to server */
548         if( ( ldaphost != NULL || ldapport ) && ( ldapuri == NULL ) ) {
549                 if ( verbose ) {
550                         fprintf( stderr, "ldap_init( %s, %d )\n",
551                                 ldaphost != NULL ? ldaphost : "<DEFAULT>",
552                                 ldapport );
553                 }
554
555                 ld = ldap_init( ldaphost, ldapport );
556                 if( ld == NULL ) {
557                         perror("ldapsearch: ldap_init");
558                         return EXIT_FAILURE;
559                 }
560
561         } else {
562                 if ( verbose ) {
563                         fprintf( stderr, "ldap_initialize( %s )\n",
564                                 ldapuri != NULL ? ldapuri : "<DEFAULT>" );
565                 }
566
567                 rc = ldap_initialize( &ld, ldapuri );
568                 if( rc != LDAP_SUCCESS ) {
569                         fprintf( stderr, "Could not create LDAP session handle (%d): %s\n",
570                                 rc, ldap_err2string(rc) );
571                         return EXIT_FAILURE;
572                 }
573         }
574
575         /* referrals */
576         if (ldap_set_option( ld, LDAP_OPT_REFERRALS,
577                 referrals ? LDAP_OPT_ON : LDAP_OPT_OFF ) != LDAP_OPT_SUCCESS )
578         {
579                 fprintf( stderr, "Could not set LDAP_OPT_REFERRALS %s\n",
580                         referrals ? "on" : "off" );
581                 return EXIT_FAILURE;
582         }
583
584         /* LDAPv3 only */
585         version = LDAP_VERSION3;
586         rc = ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
587
588         if(rc != LDAP_OPT_SUCCESS ) {
589                 fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", version );
590                 return EXIT_FAILURE;
591         }
592
593         if ( use_tls && ( ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS )) {
594                 ldap_perror( ld, "ldap_start_tls" );
595                 if ( use_tls > 1 ) {
596                         return( EXIT_FAILURE );
597                 }
598         }
599
600         if ( authmethod == LDAP_AUTH_SASL ) {
601 #ifdef HAVE_CYRUS_SASL
602                 void *defaults;
603
604                 if( sasl_secprops != NULL ) {
605                         rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
606                                 (void *) sasl_secprops );
607                         
608                         if( rc != LDAP_OPT_SUCCESS ) {
609                                 fprintf( stderr,
610                                         "Could not set LDAP_OPT_X_SASL_SECPROPS: %s\n",
611                                         sasl_secprops );
612                                 return( EXIT_FAILURE );
613                         }
614                 }
615                 
616                 defaults = lutil_sasl_defaults( ld,
617                         sasl_mech,
618                         sasl_realm,
619                         sasl_authc_id,
620                         passwd.bv_val,
621                         sasl_authz_id );
622
623                 rc = ldap_sasl_interactive_bind_s( ld, binddn,
624                         sasl_mech, NULL, NULL,
625                         sasl_flags, lutil_sasl_interact, defaults );
626
627                 if( rc != LDAP_SUCCESS ) {
628                         ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
629                         return( EXIT_FAILURE );
630                 }
631 #else
632                 fprintf( stderr, "%s: not compiled with SASL support\n",
633                         prog );
634                 return( EXIT_FAILURE );
635 #endif
636         }
637         else {
638                 if ( ldap_bind_s( ld, binddn, passwd.bv_val, authmethod )
639                                 != LDAP_SUCCESS ) {
640                         ldap_perror( ld, "ldap_bind" );
641                         return( EXIT_FAILURE );
642                 }
643         }
644
645         if ( not ) {
646                 rc = LDAP_SUCCESS;
647                 goto skip;
648         }
649
650         rc = ldap_extended_operation( ld,
651                 LDAP_EXOP_X_WHO_AM_I, NULL, 
652                 NULL, NULL, &id );
653
654         if( rc != LDAP_SUCCESS ) {
655                 ldap_perror( ld, "ldap_extended_operation" );
656                 ldap_unbind( ld );
657                 return EXIT_FAILURE;
658         }
659
660         rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, NULL, &res );
661         if ( rc < 0 ) {
662                 ldap_perror( ld, "ldappasswd: ldap_result" );
663                 return rc;
664         }
665
666         rc = ldap_parse_result( ld, res, &code, &matcheddn, &text, &refs, NULL, 0 );
667
668         if( rc != LDAP_SUCCESS ) {
669                 ldap_perror( ld, "ldap_parse_result" );
670                 return rc;
671         }
672
673         rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 1 );
674
675         if( rc != LDAP_SUCCESS ) {
676                 ldap_perror( ld, "ldap_parse_result" );
677                 return rc;
678         }
679
680         if( retdata != NULL ) {
681                 if( retdata->bv_len == 0 ) {
682                         printf("anonymous\n" );
683                 } else {
684                         printf("%s\n", retdata->bv_val );
685                 }
686         }
687
688         if( verbose || ( code != LDAP_SUCCESS ) || matcheddn || text || refs ) {
689                 printf( "Result: %s (%d)\n", ldap_err2string( code ), code );
690
691                 if( text && *text ) {
692                         printf( "Additional info: %s\n", text );
693                 }
694
695                 if( matcheddn && *matcheddn ) {
696                         printf( "Matched DN: %s\n", matcheddn );
697                 }
698
699                 if( refs ) {
700                         int i;
701                         for( i=0; refs[i]; i++ ) {
702                                 printf("Referral: %s\n", refs[i] );
703                         }
704                 }
705         }
706
707         ber_memfree( text );
708         ber_memfree( matcheddn );
709         ber_memvfree( (void **) refs );
710         ber_memfree( retoid );
711         ber_bvfree( retdata );
712
713 skip:
714         /* disconnect from server */
715         ldap_unbind (ld);
716
717         return EXIT_SUCCESS;
718 }