]> git.sur5r.net Git - openldap/blob - clients/tools/ldapwhoami.c
12dda6f00066f09915d42924aa5a3e85faeed76c
[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
195                 } else if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
196                         if( manageDSAit ) {
197                                 fprintf( stderr, "manageDSAit control previously specified\n");
198                                 return EXIT_FAILURE;
199                         }
200                         if( cvalue != NULL ) {
201                                 fprintf( stderr, "manageDSAit: no control value expected\n" );
202                                 usage(prog);
203                                 return EXIT_FAILURE;
204                         }
205
206                         manageDSAit = 1 + crit;
207
208                 } else if ( strcasecmp( control, "noop" ) == 0 ) {
209                         if( noop ) {
210                                 fprintf( stderr, "noop control previously specified\n");
211                                 return EXIT_FAILURE;
212                         }
213                         if( cvalue != NULL ) {
214                                 fprintf( stderr, "noop: no control value expected\n" );
215                                 usage(prog);
216                                 return EXIT_FAILURE;
217                         }
218
219                         noop = 1 + crit;
220
221                 } else {
222                         fprintf( stderr, "Invalid general control name: %s\n", control );
223                         usage(prog);
224                         return EXIT_FAILURE;
225                 }
226                 break;
227         case 'h':       /* ldap host */
228                 if( ldapuri != NULL ) {
229                         fprintf( stderr, "%s: -h incompatible with -H\n", prog );
230                         return EXIT_FAILURE;
231                 }
232                 if( ldaphost != NULL ) {
233                         fprintf( stderr, "%s: -h previously specified\n", prog );
234                         return EXIT_FAILURE;
235                 }
236             ldaphost = strdup( optarg );
237             break;
238         case 'H':       /* ldap URI */
239                 if( ldaphost != NULL ) {
240                         fprintf( stderr, "%s: -H incompatible with -h\n", prog );
241                         return EXIT_FAILURE;
242                 }
243                 if( ldapport ) {
244                         fprintf( stderr, "%s: -H incompatible with -p\n", prog );
245                         return EXIT_FAILURE;
246                 }
247                 if( ldapuri != NULL ) {
248                         fprintf( stderr, "%s: -H previously specified\n", prog );
249                         return EXIT_FAILURE;
250                 }
251             ldapuri = strdup( optarg );
252             break;
253         case 'I':
254 #ifdef HAVE_CYRUS_SASL
255                 if( version == LDAP_VERSION2 ) {
256                         fprintf( stderr, "%s: -I incompatible with version %d\n",
257                                 prog, version );
258                         return EXIT_FAILURE;
259                 }
260                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
261                         fprintf( stderr, "%s: incompatible previous "
262                                 "authentication choice\n",
263                                 prog );
264                         return EXIT_FAILURE;
265                 }
266                 authmethod = LDAP_AUTH_SASL;
267                 version = LDAP_VERSION3;
268                 sasl_flags = LDAP_SASL_INTERACTIVE;
269                 break;
270 #else
271                 fprintf( stderr, "%s: was not compiled with SASL support\n",
272                         prog );
273                 return( EXIT_FAILURE );
274 #endif
275         case 'k':       /* kerberos bind */
276 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
277                 if( version > LDAP_VERSION2 ) {
278                         fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
279                                 prog, version );
280                         return EXIT_FAILURE;
281                 }
282
283                 if( authmethod != -1 ) {
284                         fprintf( stderr, "%s: -k incompatible with previous "
285                                 "authentication choice\n", prog );
286                         return EXIT_FAILURE;
287                 }
288                         
289                 authmethod = LDAP_AUTH_KRBV4;
290 #else
291                 fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
292                 return EXIT_FAILURE;
293 #endif
294             break;
295         case 'K':       /* kerberos bind, part one only */
296 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
297                 if( version > LDAP_VERSION2 ) {
298                         fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
299                                 prog, version );
300                         return EXIT_FAILURE;
301                 }
302                 if( authmethod != -1 ) {
303                         fprintf( stderr, "%s: incompatible with previous "
304                                 "authentication choice\n", prog );
305                         return EXIT_FAILURE;
306                 }
307
308                 authmethod = LDAP_AUTH_KRBV41;
309 #else
310                 fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
311                 return( EXIT_FAILURE );
312 #endif
313             break;
314         case 'n':       /* print deletes, don't actually do them */
315             ++not;
316             break;
317         case 'O':
318 #ifdef HAVE_CYRUS_SASL
319                 if( sasl_secprops != NULL ) {
320                         fprintf( stderr, "%s: -O previously specified\n", prog );
321                         return EXIT_FAILURE;
322                 }
323                 if( version == LDAP_VERSION2 ) {
324                         fprintf( stderr, "%s: -O incompatible with LDAPv%d\n",
325                                 prog, version );
326                         return EXIT_FAILURE;
327                 }
328                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
329                         fprintf( stderr, "%s: incompatible previous "
330                                 "authentication choice\n", prog );
331                         return EXIT_FAILURE;
332                 }
333                 authmethod = LDAP_AUTH_SASL;
334                 version = LDAP_VERSION3;
335                 sasl_secprops = strdup( optarg );
336 #else
337                 fprintf( stderr, "%s: not compiled with SASL support\n",
338                         prog );
339                 return( EXIT_FAILURE );
340 #endif
341                 break;
342         case 'p':
343                 if( ldapport ) {
344                         fprintf( stderr, "%s: -p previously specified\n", prog );
345                         return EXIT_FAILURE;
346                 }
347             ldapport = atoi( optarg );
348             break;
349         case 'P':
350                 switch( atoi(optarg) ) {
351                 case 2:
352                         if( version == LDAP_VERSION3 ) {
353                                 fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
354                                         prog, version );
355                                 return EXIT_FAILURE;
356                         }
357                         version = LDAP_VERSION2;
358                         break;
359                 case 3:
360                         if( version == LDAP_VERSION2 ) {
361                                 fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
362                                         prog, version );
363                                 return EXIT_FAILURE;
364                         }
365                         version = LDAP_VERSION3;
366                         break;
367                 default:
368                         fprintf( stderr, "%s: protocol version should be 2 or 3\n",
369                                 prog );
370                         usage( prog );
371                         return( EXIT_FAILURE );
372                 }
373                 break;
374         case 'Q':
375 #ifdef HAVE_CYRUS_SASL
376                 if( version == LDAP_VERSION2 ) {
377                         fprintf( stderr, "%s: -Q incompatible with version %d\n",
378                                 prog, version );
379                         return EXIT_FAILURE;
380                 }
381                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
382                         fprintf( stderr, "%s: incompatible previous "
383                                 "authentication choice\n",
384                                 prog );
385                         return EXIT_FAILURE;
386                 }
387                 authmethod = LDAP_AUTH_SASL;
388                 version = LDAP_VERSION3;
389                 sasl_flags = LDAP_SASL_QUIET;
390                 break;
391 #else
392                 fprintf( stderr, "%s: not compiled with SASL support\n",
393                         prog );
394                 return( EXIT_FAILURE );
395 #endif
396         case 'R':
397 #ifdef HAVE_CYRUS_SASL
398                 if( sasl_realm != NULL ) {
399                         fprintf( stderr, "%s: -R previously specified\n", prog );
400                         return EXIT_FAILURE;
401                 }
402                 if( version == LDAP_VERSION2 ) {
403                         fprintf( stderr, "%s: -R incompatible with version %d\n",
404                                 prog, version );
405                         return EXIT_FAILURE;
406                 }
407                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
408                         fprintf( stderr, "%s: incompatible previous "
409                                 "authentication choice\n",
410                                 prog );
411                         return EXIT_FAILURE;
412                 }
413                 authmethod = LDAP_AUTH_SASL;
414                 version = LDAP_VERSION3;
415                 sasl_realm = strdup( optarg );
416 #else
417                 fprintf( stderr, "%s: not compiled with SASL support\n",
418                         prog );
419                 return( EXIT_FAILURE );
420 #endif
421                 break;
422         case 'U':
423 #ifdef HAVE_CYRUS_SASL
424                 if( sasl_authc_id != NULL ) {
425                         fprintf( stderr, "%s: -U previously specified\n", prog );
426                         return EXIT_FAILURE;
427                 }
428                 if( version == LDAP_VERSION2 ) {
429                         fprintf( stderr, "%s: -U incompatible with version %d\n",
430                                 prog, version );
431                         return EXIT_FAILURE;
432                 }
433                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
434                         fprintf( stderr, "%s: incompatible previous "
435                                 "authentication choice\n",
436                                 prog );
437                         return EXIT_FAILURE;
438                 }
439                 authmethod = LDAP_AUTH_SASL;
440                 version = LDAP_VERSION3;
441                 sasl_authc_id = strdup( optarg );
442 #else
443                 fprintf( stderr, "%s: not compiled with SASL support\n",
444                         prog );
445                 return( EXIT_FAILURE );
446 #endif
447                 break;
448         case 'v':       /* verbose mode */
449             verbose++;
450             break;
451         case 'w':       /* password */
452             passwd.bv_val = strdup( optarg );
453                 {
454                         char* p;
455
456                         for( p = optarg; *p != '\0'; p++ ) {
457                                 *p = '\0';
458                         }
459                 }
460                 passwd.bv_len = strlen( passwd.bv_val );
461             break;
462         case 'W':
463                 want_bindpw++;
464                 break;
465         case 'y':
466                 pw_file = optarg;
467                 break;
468         case 'Y':
469 #ifdef HAVE_CYRUS_SASL
470                 if( sasl_mech != NULL ) {
471                         fprintf( stderr, "%s: -Y previously specified\n", prog );
472                         return EXIT_FAILURE;
473                 }
474                 if( version == LDAP_VERSION2 ) {
475                         fprintf( stderr, "%s: -Y incompatible with version %d\n",
476                                 prog, version );
477                         return EXIT_FAILURE;
478                 }
479                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
480                         fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
481                         return EXIT_FAILURE;
482                 }
483                 authmethod = LDAP_AUTH_SASL;
484                 version = LDAP_VERSION3;
485                 sasl_mech = strdup( optarg );
486 #else
487                 fprintf( stderr, "%s: not compiled with SASL support\n",
488                         prog );
489                 return( EXIT_FAILURE );
490 #endif
491                 break;
492         case 'x':
493                 if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
494                         fprintf( stderr, "%s: incompatible with previous "
495                                 "authentication choice\n", prog );
496                         return EXIT_FAILURE;
497                 }
498                 authmethod = LDAP_AUTH_SIMPLE;
499                 break;
500         case 'X':
501 #ifdef HAVE_CYRUS_SASL
502                 if( sasl_authz_id != NULL ) {
503                         fprintf( stderr, "%s: -X previously specified\n", prog );
504                         return EXIT_FAILURE;
505                 }
506                 if( version == LDAP_VERSION2 ) {
507                         fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
508                                 prog, version );
509                         return EXIT_FAILURE;
510                 }
511                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
512                         fprintf( stderr, "%s: -X incompatible with "
513                                 "authentication choice\n", prog );
514                         return EXIT_FAILURE;
515                 }
516                 authmethod = LDAP_AUTH_SASL;
517                 version = LDAP_VERSION3;
518                 sasl_authz_id = strdup( optarg );
519 #else
520                 fprintf( stderr, "%s: not compiled with SASL support\n",
521                         prog );
522                 return( EXIT_FAILURE );
523 #endif
524                 break;
525         case 'Z':
526 #ifdef HAVE_TLS
527                 if( version == LDAP_VERSION2 ) {
528                         fprintf( stderr, "%s: -Z incompatible with version %d\n",
529                                 prog, version );
530                         return EXIT_FAILURE;
531                 }
532                 version = LDAP_VERSION3;
533                 use_tls++;
534 #else
535                 fprintf( stderr, "%s: not compiled with TLS support\n",
536                         prog );
537                 return( EXIT_FAILURE );
538 #endif
539                 break;
540
541
542                 default:
543                         fprintf( stderr, "%s: unrecognized option -%c\n",
544                                 prog, optopt );
545                         usage (prog);
546                 }
547         }
548
549         if (authmethod == -1) {
550 #ifdef HAVE_CYRUS_SASL
551                 authmethod = LDAP_AUTH_SASL;
552 #else
553                 authmethod = LDAP_AUTH_SIMPLE;
554 #endif
555         }
556
557         if( argc - optind > 1 ) {
558                 usage( prog );
559         } else if ( argc - optind == 1 ) {
560                 user = strdup( argv[optind] );
561         } else {
562                 user = NULL;
563         }
564
565         if ( pw_file || want_bindpw ) {
566                 if ( pw_file ) {
567                         rc = lutil_get_filed_password( pw_file, &passwd );
568                         if( rc ) return EXIT_FAILURE;
569                 } else {
570                         passwd.bv_val = getpassphrase( "Enter LDAP Password: " );
571                         passwd.bv_len = passwd.bv_val ? strlen( passwd.bv_val ) : 0;
572                 }
573         }
574
575         if ( debug ) {
576                 if( ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug ) != LBER_OPT_SUCCESS ) {
577                         fprintf( stderr, "Could not set LBER_OPT_DEBUG_LEVEL %d\n", debug );
578                 }
579                 if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug ) != LDAP_OPT_SUCCESS ) {
580                         fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
581                 }
582         }
583
584 #ifdef SIGPIPE
585         (void) SIGNAL( SIGPIPE, SIG_IGN );
586 #endif
587
588         /* connect to server */
589         if( ( ldaphost != NULL || ldapport ) && ( ldapuri == NULL ) ) {
590                 if ( verbose ) {
591                         fprintf( stderr, "ldap_init( %s, %d )\n",
592                                 ldaphost != NULL ? ldaphost : "<DEFAULT>",
593                                 ldapport );
594                 }
595
596                 ld = ldap_init( ldaphost, ldapport );
597                 if( ld == NULL ) {
598                         perror("ldapwhoami: ldap_init");
599                         return EXIT_FAILURE;
600                 }
601
602         } else {
603                 if ( verbose ) {
604                         fprintf( stderr, "ldap_initialize( %s )\n",
605                                 ldapuri != NULL ? ldapuri : "<DEFAULT>" );
606                 }
607
608                 rc = ldap_initialize( &ld, ldapuri );
609                 if( rc != LDAP_SUCCESS ) {
610                         fprintf( stderr, "Could not create LDAP session handle (%d): %s\n",
611                                 rc, ldap_err2string(rc) );
612                         return EXIT_FAILURE;
613                 }
614         }
615
616         /* referrals */
617         if (ldap_set_option( ld, LDAP_OPT_REFERRALS,
618                 referrals ? LDAP_OPT_ON : LDAP_OPT_OFF ) != LDAP_OPT_SUCCESS )
619         {
620                 fprintf( stderr, "Could not set LDAP_OPT_REFERRALS %s\n",
621                         referrals ? "on" : "off" );
622                 return EXIT_FAILURE;
623         }
624
625         /* LDAPv3 only */
626         version = LDAP_VERSION3;
627         rc = ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
628
629         if(rc != LDAP_OPT_SUCCESS ) {
630                 fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", version );
631                 return EXIT_FAILURE;
632         }
633
634         if ( use_tls && ( ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS )) {
635                 ldap_perror( ld, "ldap_start_tls" );
636                 if ( use_tls > 1 ) {
637                         return( EXIT_FAILURE );
638                 }
639         }
640
641         if ( authmethod == LDAP_AUTH_SASL ) {
642 #ifdef HAVE_CYRUS_SASL
643                 void *defaults;
644
645                 if( sasl_secprops != NULL ) {
646                         rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
647                                 (void *) sasl_secprops );
648                         
649                         if( rc != LDAP_OPT_SUCCESS ) {
650                                 fprintf( stderr,
651                                         "Could not set LDAP_OPT_X_SASL_SECPROPS: %s\n",
652                                         sasl_secprops );
653                                 return( EXIT_FAILURE );
654                         }
655                 }
656                 
657                 defaults = lutil_sasl_defaults( ld,
658                         sasl_mech,
659                         sasl_realm,
660                         sasl_authc_id,
661                         passwd.bv_val,
662                         sasl_authz_id );
663
664                 rc = ldap_sasl_interactive_bind_s( ld, binddn,
665                         sasl_mech, NULL, NULL,
666                         sasl_flags, lutil_sasl_interact, defaults );
667
668                 if( rc != LDAP_SUCCESS ) {
669                         ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
670                         return( EXIT_FAILURE );
671                 }
672 #else
673                 fprintf( stderr, "%s: not compiled with SASL support\n",
674                         prog );
675                 return( EXIT_FAILURE );
676 #endif
677         }
678         else {
679                 if ( ldap_bind_s( ld, binddn, passwd.bv_val, authmethod )
680                                 != LDAP_SUCCESS ) {
681                         ldap_perror( ld, "ldap_bind" );
682                         return( EXIT_FAILURE );
683                 }
684         }
685
686         if ( not ) {
687                 rc = LDAP_SUCCESS;
688                 goto skip;
689         }
690
691         if ( authzid || manageDSAit || noop ) {
692                 int err, crit=0, i=0;
693                 LDAPControl c[3];
694                 LDAPControl *ctrls[4];
695
696                 if ( authzid ) {
697                         c[i].ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
698                         c[i].ldctl_value.bv_val = authzid;
699                         c[i].ldctl_value.bv_len = strlen( authzid );
700                         c[i].ldctl_iscritical = 1;
701
702                         if( c[i].ldctl_iscritical ) crit++;
703                         ctrls[i] = &c[i];
704                         ctrls[++i] = NULL;
705                 }
706
707                 if ( manageDSAit ) {
708                         c[i].ldctl_oid = LDAP_CONTROL_MANAGEDSAIT;
709                         c[i].ldctl_value.bv_val = NULL;
710                         c[i].ldctl_value.bv_len = 0;
711                         c[i].ldctl_iscritical = manageDSAit > 1;
712
713                         if( c[i].ldctl_iscritical ) crit++;
714                         ctrls[i] = &c[i];
715                         ctrls[++i] = NULL;
716                 }
717
718                 if ( noop ) {
719                         c[i].ldctl_oid = LDAP_CONTROL_NOOP;
720                         c[i].ldctl_value.bv_val = NULL;
721                         c[i].ldctl_value.bv_len = 0;
722                         c[i].ldctl_iscritical = noop > 1;
723
724                         if( c[i].ldctl_iscritical ) crit++;
725                         ctrls[i] = &c[i];
726                         ctrls[++i] = NULL;
727                 }
728         
729                 err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, ctrls );
730
731                 if( err != LDAP_OPT_SUCCESS ) {
732                         fprintf( stderr, "Could not set %scontrols\n",
733                                 crit ? "critical " : "" );
734                         if ( crit ) {
735                                 return EXIT_FAILURE;
736                         }
737                 }
738         }
739
740         rc = ldap_whoami_s( ld, &retdata, NULL, NULL ); 
741
742         if( retdata != NULL ) {
743                 if( retdata->bv_len == 0 ) {
744                         printf("anonymous\n" );
745                 } else {
746                         printf("%s\n", retdata->bv_val );
747                 }
748         }
749
750         if( verbose || ( rc != LDAP_SUCCESS ) || matcheddn || text || refs ) {
751                 printf( "Result: %s (%d)\n", ldap_err2string( rc ), rc );
752
753                 if( text && *text ) {
754                         printf( "Additional info: %s\n", text );
755                 }
756
757                 if( matcheddn && *matcheddn ) {
758                         printf( "Matched DN: %s\n", matcheddn );
759                 }
760
761                 if( refs ) {
762                         int i;
763                         for( i=0; refs[i]; i++ ) {
764                                 printf("Referral: %s\n", refs[i] );
765                         }
766                 }
767         }
768
769         ber_memfree( text );
770         ber_memfree( matcheddn );
771         ber_memvfree( (void **) refs );
772         ber_memfree( retoid );
773         ber_bvfree( retdata );
774
775 skip:
776         /* disconnect from server */
777         ldap_unbind (ld);
778
779         return rc == LDAP_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE;
780 }