3 * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6 /* common.c - common routines for the ldap client tools */
12 #include <ac/stdlib.h>
13 #include <ac/signal.h>
14 #include <ac/string.h>
15 #include <ac/unistd.h>
20 #include "lutil_ldap.h"
31 char *ldaphost = NULL;
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;
49 struct berval passwd = { 0, NULL };
61 tool_common_usage( void )
63 static const char *const descriptions[] = {
64 " -c continuous operation mode (do not stop on errors)\n",
65 " -C chase referrals\n",
66 " -d level set LDAP debugging level to `level'\n",
67 " -D binddn bind DN\n",
68 " -e [!]<ctrl>[=<ctrlparam>] general controls (! indicates criticality)\n"
69 " [!]authzid=<authzid> (\"dn:<dn>\" or \"u:<user>\")\n"
70 " [!]manageDSAit (alternate form, see -M)\n"
72 " -f file read operations from `file'\n",
73 " -h host LDAP server\n",
74 " -H URI LDAP Uniform Resource Indentifier(s)\n",
75 " -I use SASL Interactive mode\n",
76 " -k use Kerberos authentication\n",
77 " -K like -k, but do only step 1 of the Kerberos bind\n",
78 " -M enable Manage DSA IT control (-MM to make critical)\n",
79 " -n show what would be done but don't actually do it\n",
80 " -O props SASL security properties\n",
81 " -p port port on LDAP server\n",
82 " -P version procotol version (default: 3)\n",
83 " -Q use SASL Quiet mode\n",
84 " -R realm SASL realm\n",
85 " -U authcid SASL authentication identity\n",
86 " -v run in verbose mode (diagnostics to standard output)\n",
87 " -w passwd bind passwd (for simple authentication)\n",
88 " -W prompt for bind passwd\n",
89 " -x Simple authentication\n",
90 " -X authzid SASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n",
91 " -y file Read passwd from file\n",
92 " -Y mech SASL mechanism\n",
93 " -Z Start TLS request (-ZZ to require successful response)\n",
96 const char *const *cpp, *cp;
98 fputs( "Common options:\n", stderr );
99 for( cpp = descriptions; (cp = *cpp) != NULL; cpp++ )
100 if( strchr( options, cp[3] ) )
106 tool_args( int argc, char **argv )
109 while (( i = getopt( argc, argv, options )) != EOF )
112 char *control, *cvalue;
114 case 'c': /* continuous operation mode */
121 debug |= atoi( optarg );
123 case 'D': /* bind DN */
124 if( binddn != NULL ) {
125 fprintf( stderr, "%s: -D previously specified\n", prog );
126 exit( EXIT_FAILURE );
128 binddn = ber_strdup( optarg );
130 case 'e': /* general controls */
131 /* should be extended to support comma separated list of
132 * [!]key[=value] parameters, e.g. -e !foo,bar=567
137 if( optarg[0] == '!' ) {
142 control = ber_strdup( optarg );
143 if ( (cvalue = strchr( control, '=' )) != NULL ) {
147 if ( strcasecmp( control, "authzid" ) == 0 ) {
148 if( authzid != NULL ) {
149 fprintf( stderr, "authzid control previously specified\n");
150 exit( EXIT_FAILURE );
152 if( cvalue == NULL ) {
153 fprintf( stderr, "authzid: control value expected\n" );
157 fprintf( stderr, "authzid: must be marked critical\n" );
161 assert( authzid == NULL );
164 } else if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
167 "manageDSAit control previously specified\n");
168 exit( EXIT_FAILURE );
170 if( cvalue != NULL ) {
172 "manageDSAit: no control value expected\n" );
176 manageDSAit = 1 + crit;
178 } else if ( strcasecmp( control, "noop" ) == 0 ) {
180 fprintf( stderr, "noop control previously specified\n");
181 exit( EXIT_FAILURE );
183 if( cvalue != NULL ) {
184 fprintf( stderr, "noop: no control value expected\n" );
191 fprintf( stderr, "Invalid general control name: %s\n",
196 case 'f': /* read from file */
197 if( infile != NULL ) {
198 fprintf( stderr, "%s: -f previously specified\n", prog );
199 exit( EXIT_FAILURE );
201 infile = ber_strdup( optarg );
203 case 'h': /* ldap host */
204 if( ldaphost != NULL ) {
205 fprintf( stderr, "%s: -h previously specified\n", prog );
206 exit( EXIT_FAILURE );
208 ldaphost = ber_strdup( optarg );
210 case 'H': /* ldap URI */
211 if( ldapuri != NULL ) {
212 fprintf( stderr, "%s: -H previously specified\n", prog );
213 exit( EXIT_FAILURE );
215 ldapuri = ber_strdup( optarg );
218 #ifdef HAVE_CYRUS_SASL
219 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
220 fprintf( stderr, "%s: incompatible previous "
221 "authentication choice\n",
223 exit( EXIT_FAILURE );
225 authmethod = LDAP_AUTH_SASL;
226 sasl_flags = LDAP_SASL_INTERACTIVE;
229 fprintf( stderr, "%s: was not compiled with SASL support\n",
231 exit( EXIT_FAILURE );
233 case 'k': /* kerberos bind */
234 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
235 if( authmethod != -1 ) {
236 fprintf( stderr, "%s: -k incompatible with previous "
237 "authentication choice\n", prog );
238 exit( EXIT_FAILURE );
240 authmethod = LDAP_AUTH_KRBV4;
242 fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
243 exit( EXIT_FAILURE );
246 case 'K': /* kerberos bind, part one only */
247 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
248 if( authmethod != -1 ) {
249 fprintf( stderr, "%s: incompatible with previous "
250 "authentication choice\n", prog );
251 exit( EXIT_FAILURE );
253 authmethod = LDAP_AUTH_KRBV41;
255 fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
256 exit( EXIT_FAILURE );
260 /* enable Manage DSA IT */
263 case 'n': /* print operations, don't actually do them */
267 #ifdef HAVE_CYRUS_SASL
268 if( sasl_secprops != NULL ) {
269 fprintf( stderr, "%s: -O previously specified\n", prog );
270 exit( EXIT_FAILURE );
272 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
273 fprintf( stderr, "%s: incompatible previous "
274 "authentication choice\n", prog );
275 exit( EXIT_FAILURE );
277 authmethod = LDAP_AUTH_SASL;
278 sasl_secprops = ber_strdup( optarg );
280 fprintf( stderr, "%s: not compiled with SASL support\n",
282 exit( EXIT_FAILURE );
287 fprintf( stderr, "%s: -p previously specified\n", prog );
288 exit( EXIT_FAILURE );
290 ldapport = atoi( optarg );
293 switch( atoi(optarg) ) {
295 if( version == LDAP_VERSION3 ) {
296 fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
298 exit( EXIT_FAILURE );
300 version = LDAP_VERSION2;
303 if( version == LDAP_VERSION2 ) {
304 fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
306 exit( EXIT_FAILURE );
308 version = LDAP_VERSION3;
311 fprintf( stderr, "%s: protocol version should be 2 or 3\n",
317 #ifdef HAVE_CYRUS_SASL
318 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
319 fprintf( stderr, "%s: incompatible previous "
320 "authentication choice\n",
322 exit( EXIT_FAILURE );
324 authmethod = LDAP_AUTH_SASL;
325 sasl_flags = LDAP_SASL_QUIET;
328 fprintf( stderr, "%s: not compiled with SASL support\n",
330 exit( EXIT_FAILURE );
333 #ifdef HAVE_CYRUS_SASL
334 if( sasl_realm != NULL ) {
335 fprintf( stderr, "%s: -R previously specified\n", prog );
336 exit( EXIT_FAILURE );
338 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
339 fprintf( stderr, "%s: incompatible previous "
340 "authentication choice\n",
342 exit( EXIT_FAILURE );
344 authmethod = LDAP_AUTH_SASL;
345 sasl_realm = ber_strdup( optarg );
347 fprintf( stderr, "%s: not compiled with SASL support\n",
349 exit( EXIT_FAILURE );
353 #ifdef HAVE_CYRUS_SASL
354 if( sasl_authc_id != NULL ) {
355 fprintf( stderr, "%s: -U previously specified\n", prog );
356 exit( EXIT_FAILURE );
358 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
359 fprintf( stderr, "%s: incompatible previous "
360 "authentication choice\n",
362 exit( EXIT_FAILURE );
364 authmethod = LDAP_AUTH_SASL;
365 sasl_authc_id = ber_strdup( optarg );
367 fprintf( stderr, "%s: not compiled with SASL support\n",
369 exit( EXIT_FAILURE );
372 case 'v': /* verbose mode */
375 case 'w': /* password */
376 passwd.bv_val = ber_strdup( optarg );
380 for( p = optarg; *p != '\0'; p++ ) {
384 passwd.bv_len = strlen( passwd.bv_val );
393 #ifdef HAVE_CYRUS_SASL
394 if( sasl_mech != NULL ) {
395 fprintf( stderr, "%s: -Y previously specified\n", prog );
396 exit( EXIT_FAILURE );
398 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
399 fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
400 exit( EXIT_FAILURE );
402 authmethod = LDAP_AUTH_SASL;
403 sasl_mech = ber_strdup( optarg );
405 fprintf( stderr, "%s: not compiled with SASL support\n",
407 exit( EXIT_FAILURE );
411 if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
412 fprintf( stderr, "%s: incompatible with previous "
413 "authentication choice\n", prog );
414 exit( EXIT_FAILURE );
416 authmethod = LDAP_AUTH_SIMPLE;
419 #ifdef HAVE_CYRUS_SASL
420 if( sasl_authz_id != NULL ) {
421 fprintf( stderr, "%s: -X previously specified\n", prog );
422 exit( EXIT_FAILURE );
424 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
425 fprintf( stderr, "%s: -X incompatible with "
426 "authentication choice\n", prog );
427 exit( EXIT_FAILURE );
429 authmethod = LDAP_AUTH_SASL;
430 sasl_authz_id = ber_strdup( optarg );
432 fprintf( stderr, "%s: not compiled with SASL support\n", prog );
433 exit( EXIT_FAILURE );
440 fprintf( stderr, "%s: not compiled with TLS support\n", prog );
441 exit( EXIT_FAILURE );
445 if( handle_private_option( i ) )
447 fprintf( stderr, "%s: unrecognized option -%c\n",
454 version = LDAP_VERSION3;
456 if (authmethod == -1 && version > LDAP_VERSION2) {
457 #ifdef HAVE_CYRUS_SASL
458 authmethod = LDAP_AUTH_SASL;
460 authmethod = LDAP_AUTH_SIMPLE;
464 if( ldapuri != NULL ) {
465 if( ldaphost != NULL ) {
466 fprintf( stderr, "%s: -H incompatible with -h\n", prog );
467 exit( EXIT_FAILURE );
470 fprintf( stderr, "%s: -H incompatible with -p\n", prog );
471 exit( EXIT_FAILURE );
474 if( version == LDAP_VERSION2 ) {
475 if( authzid || manageDSAit || noop ) {
476 fprintf( stderr, "%s: -e/-M incompatible with LDAPv2\n", prog );
477 exit( EXIT_FAILURE );
481 fprintf( stderr, "%s: -Z incompatible with LDAPv2\n", prog );
482 exit( EXIT_FAILURE );
485 #ifdef HAVE_CYRUS_SASL
486 if( authmethod == LDAP_AUTH_SASL ) {
487 fprintf( stderr, "%s: -[IOQRUXY] incompatible with LDAPv2\n",
489 exit( EXIT_FAILURE );
493 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
494 if ( authmethod = LDAP_AUTH_KRBV4 || authmethod == LDAP_AUTH_KRBV41 ) {
495 fprintf( stderr, "%s: -k/-K incompatible with LDAPv%d\n",
497 exit( EXIT_FAILURE );
505 tool_conn_setup( int not, void (*private_setup)( LDAP * ) )
510 if( ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug )
511 != LBER_OPT_SUCCESS ) {
512 fprintf( stderr, "Could not set LBER_OPT_DEBUG_LEVEL %d\n", debug );
514 if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug )
515 != LDAP_OPT_SUCCESS ) {
516 fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
521 (void) SIGNAL( SIGPIPE, SIG_IGN );
525 /* connect to server */
526 if( ( ldaphost != NULL || ldapport ) && ( ldapuri == NULL ) ) {
528 fprintf( stderr, "ldap_init( %s, %d )\n",
529 ldaphost != NULL ? ldaphost : "<DEFAULT>",
533 ld = ldap_init( ldaphost, ldapport );
535 char buf[20 + sizeof(": ldap_init")];
536 sprintf( buf, "%.20s: ldap_init", prog );
538 exit( EXIT_FAILURE );
544 fprintf( stderr, "ldap_initialize( %s )\n",
545 ldapuri != NULL ? ldapuri : "<DEFAULT>" );
547 rc = ldap_initialize( &ld, ldapuri );
548 if( rc != LDAP_SUCCESS ) {
549 fprintf( stderr, "Could not create LDAP session handle (%d): %s\n",
550 rc, ldap_err2string(rc) );
551 exit( EXIT_FAILURE );
559 if( ldap_set_option( ld, LDAP_OPT_REFERRALS,
560 referrals ? LDAP_OPT_ON : LDAP_OPT_OFF )
561 != LDAP_OPT_SUCCESS )
563 fprintf( stderr, "Could not set LDAP_OPT_REFERRALS %s\n",
564 referrals ? "on" : "off" );
565 exit( EXIT_FAILURE );
568 if( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version )
569 != LDAP_OPT_SUCCESS )
571 fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n",
573 exit( EXIT_FAILURE );
577 ( ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS )) {
578 ldap_perror( ld, "ldap_start_tls" );
580 exit( EXIT_FAILURE );
590 tool_bind( LDAP *ld )
592 if ( authmethod == LDAP_AUTH_SASL ) {
593 #ifdef HAVE_CYRUS_SASL
597 if( sasl_secprops != NULL ) {
598 rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
599 (void *) sasl_secprops );
601 if( rc != LDAP_OPT_SUCCESS ) {
603 "Could not set LDAP_OPT_X_SASL_SECPROPS: %s\n",
605 exit( EXIT_FAILURE );
609 defaults = lutil_sasl_defaults( ld,
616 rc = ldap_sasl_interactive_bind_s( ld, binddn,
617 sasl_mech, NULL, NULL,
618 sasl_flags, lutil_sasl_interact, defaults );
620 if( rc != LDAP_SUCCESS ) {
621 ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
622 exit( EXIT_FAILURE );
625 fprintf( stderr, "%s: not compiled with SASL support\n",
627 exit( EXIT_FAILURE );
630 if ( ldap_bind_s( ld, binddn, passwd.bv_val, authmethod )
632 ldap_perror( ld, "ldap_bind" );
633 exit( EXIT_FAILURE );
639 /* Set server controls. Add controls extra_c[0..count-1], if set. */
641 tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count )
643 int i = 0, j, crit, err;
644 LDAPControl c[3], *ctrls[10];
647 c[i].ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
648 c[i].ldctl_value.bv_val = authzid;
649 c[i].ldctl_value.bv_len = strlen( authzid );
650 c[i].ldctl_iscritical = 1;
656 c[i].ldctl_oid = LDAP_CONTROL_MANAGEDSAIT;
657 c[i].ldctl_value.bv_val = NULL;
658 c[i].ldctl_value.bv_len = 0;
659 c[i].ldctl_iscritical = manageDSAit > 1;
665 c[i].ldctl_oid = LDAP_CONTROL_NOOP;
666 c[i].ldctl_value.bv_val = NULL;
667 c[i].ldctl_value.bv_len = 0;
668 c[i].ldctl_iscritical = noop > 1;
674 ctrls[i++] = extra_c++;
677 err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, ctrls );
679 if( err != LDAP_OPT_SUCCESS ) {
680 for ( j = crit = 0; j < i; j++ )
681 if ( ctrls[j]->ldctl_iscritical )
683 fprintf( stderr, "Could not set %scontrols\n",
684 crit ? "critical " : "" );
686 exit( EXIT_FAILURE );