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