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