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