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