3 * Copyright 1998-2003 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 };
58 char *version_string = NULL;
62 tool_common_usage( void )
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"
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",
98 const char *const *cpp;
100 fputs( "Common options:\n", stderr );
101 for( cpp = descriptions; *cpp != NULL; cpp++ ) {
102 if( strchr( options, (*cpp)[3] ) ) {
103 fputs( *cpp, stderr );
110 tool_args( int argc, char **argv )
113 while (( i = getopt( argc, argv, options )) != EOF )
116 char *control, *cvalue;
118 case 'c': /* continuous operation mode */
125 debug |= atoi( optarg );
127 case 'D': /* bind DN */
128 if( binddn != NULL ) {
129 fprintf( stderr, "%s: -D previously specified\n", prog );
130 exit( EXIT_FAILURE );
132 binddn = ber_strdup( optarg );
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
141 if( optarg[0] == '!' ) {
146 control = ber_strdup( optarg );
147 if ( (cvalue = strchr( control, '=' )) != NULL ) {
151 if ( strcasecmp( control, "authzid" ) == 0 ) {
152 if( authzid != NULL ) {
153 fprintf( stderr, "authzid control previously specified\n");
154 exit( EXIT_FAILURE );
156 if( cvalue == NULL ) {
157 fprintf( stderr, "authzid: control value expected\n" );
161 fprintf( stderr, "authzid: must be marked critical\n" );
165 assert( authzid == NULL );
168 } else if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
171 "manageDSAit control previously specified\n");
172 exit( EXIT_FAILURE );
174 if( cvalue != NULL ) {
176 "manageDSAit: no control value expected\n" );
180 manageDSAit = 1 + crit;
182 } else if ( strcasecmp( control, "noop" ) == 0 ) {
184 fprintf( stderr, "noop control previously specified\n");
185 exit( EXIT_FAILURE );
187 if( cvalue != NULL ) {
188 fprintf( stderr, "noop: no control value expected\n" );
195 fprintf( stderr, "Invalid general control name: %s\n",
200 case 'f': /* read from file */
201 if( infile != NULL ) {
202 fprintf( stderr, "%s: -f previously specified\n", prog );
203 exit( EXIT_FAILURE );
205 infile = ber_strdup( optarg );
207 case 'h': /* ldap host */
208 if( ldaphost != NULL ) {
209 fprintf( stderr, "%s: -h previously specified\n", prog );
210 exit( EXIT_FAILURE );
212 ldaphost = ber_strdup( optarg );
214 case 'H': /* ldap URI */
215 if( ldapuri != NULL ) {
216 fprintf( stderr, "%s: -H previously specified\n", prog );
217 exit( EXIT_FAILURE );
219 ldapuri = ber_strdup( optarg );
222 #ifdef HAVE_CYRUS_SASL
223 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
224 fprintf( stderr, "%s: incompatible previous "
225 "authentication choice\n",
227 exit( EXIT_FAILURE );
229 authmethod = LDAP_AUTH_SASL;
230 sasl_flags = LDAP_SASL_INTERACTIVE;
233 fprintf( stderr, "%s: was not compiled with SASL support\n",
235 exit( EXIT_FAILURE );
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 );
244 authmethod = LDAP_AUTH_KRBV4;
246 fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
247 exit( EXIT_FAILURE );
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 );
257 authmethod = LDAP_AUTH_KRBV41;
259 fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
260 exit( EXIT_FAILURE );
264 /* enable Manage DSA IT */
267 case 'n': /* print operations, don't actually do them */
271 #ifdef HAVE_CYRUS_SASL
272 if( sasl_secprops != NULL ) {
273 fprintf( stderr, "%s: -O previously specified\n", prog );
274 exit( EXIT_FAILURE );
276 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
277 fprintf( stderr, "%s: incompatible previous "
278 "authentication choice\n", prog );
279 exit( EXIT_FAILURE );
281 authmethod = LDAP_AUTH_SASL;
282 sasl_secprops = ber_strdup( optarg );
284 fprintf( stderr, "%s: not compiled with SASL support\n",
286 exit( EXIT_FAILURE );
291 fprintf( stderr, "%s: -p previously specified\n", prog );
292 exit( EXIT_FAILURE );
294 ldapport = atoi( optarg );
297 switch( atoi(optarg) ) {
299 if( protocol == LDAP_VERSION3 ) {
300 fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
302 exit( EXIT_FAILURE );
304 protocol = LDAP_VERSION2;
307 if( protocol == LDAP_VERSION2 ) {
308 fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
310 exit( EXIT_FAILURE );
312 protocol = LDAP_VERSION3;
315 fprintf( stderr, "%s: protocol version should be 2 or 3\n",
321 #ifdef HAVE_CYRUS_SASL
322 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
323 fprintf( stderr, "%s: incompatible previous "
324 "authentication choice\n",
326 exit( EXIT_FAILURE );
328 authmethod = LDAP_AUTH_SASL;
329 sasl_flags = LDAP_SASL_QUIET;
332 fprintf( stderr, "%s: not compiled with SASL support\n",
334 exit( EXIT_FAILURE );
337 #ifdef HAVE_CYRUS_SASL
338 if( sasl_realm != NULL ) {
339 fprintf( stderr, "%s: -R previously specified\n", prog );
340 exit( EXIT_FAILURE );
342 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
343 fprintf( stderr, "%s: incompatible previous "
344 "authentication choice\n",
346 exit( EXIT_FAILURE );
348 authmethod = LDAP_AUTH_SASL;
349 sasl_realm = ber_strdup( optarg );
351 fprintf( stderr, "%s: not compiled with SASL support\n",
353 exit( EXIT_FAILURE );
357 #ifdef HAVE_CYRUS_SASL
358 if( sasl_authc_id != NULL ) {
359 fprintf( stderr, "%s: -U previously specified\n", prog );
360 exit( EXIT_FAILURE );
362 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
363 fprintf( stderr, "%s: incompatible previous "
364 "authentication choice\n",
366 exit( EXIT_FAILURE );
368 authmethod = LDAP_AUTH_SASL;
369 sasl_authc_id = ber_strdup( optarg );
371 fprintf( stderr, "%s: not compiled with SASL support\n",
373 exit( EXIT_FAILURE );
376 case 'v': /* verbose mode */
379 case 'V': /* version */
382 case 'w': /* password */
383 passwd.bv_val = ber_strdup( optarg );
387 for( p = optarg; *p != '\0'; p++ ) {
391 passwd.bv_len = strlen( passwd.bv_val );
400 #ifdef HAVE_CYRUS_SASL
401 if( sasl_mech != NULL ) {
402 fprintf( stderr, "%s: -Y previously specified\n", prog );
403 exit( EXIT_FAILURE );
405 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
406 fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
407 exit( EXIT_FAILURE );
409 authmethod = LDAP_AUTH_SASL;
410 sasl_mech = ber_strdup( optarg );
412 fprintf( stderr, "%s: not compiled with SASL support\n",
414 exit( EXIT_FAILURE );
418 if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
419 fprintf( stderr, "%s: incompatible with previous "
420 "authentication choice\n", prog );
421 exit( EXIT_FAILURE );
423 authmethod = LDAP_AUTH_SIMPLE;
426 #ifdef HAVE_CYRUS_SASL
427 if( sasl_authz_id != NULL ) {
428 fprintf( stderr, "%s: -X previously specified\n", prog );
429 exit( EXIT_FAILURE );
431 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
432 fprintf( stderr, "%s: -X incompatible with "
433 "authentication choice\n", prog );
434 exit( EXIT_FAILURE );
436 authmethod = LDAP_AUTH_SASL;
437 sasl_authz_id = ber_strdup( optarg );
439 fprintf( stderr, "%s: not compiled with SASL support\n", prog );
440 exit( EXIT_FAILURE );
447 fprintf( stderr, "%s: not compiled with TLS support\n", prog );
448 exit( EXIT_FAILURE );
452 if( handle_private_option( i ) )
454 fprintf( stderr, "%s: unrecognized option -%c\n",
461 fprintf( stderr, "%s: %s\n", prog,
462 version_string ? version_string : "version unknown" );
463 if (version > 1) exit( EXIT_SUCCESS );
467 protocol = LDAP_VERSION3;
469 if (authmethod == -1 && protocol > LDAP_VERSION2) {
470 #ifdef HAVE_CYRUS_SASL
471 authmethod = LDAP_AUTH_SASL;
473 authmethod = LDAP_AUTH_SIMPLE;
477 if( ldapuri != NULL ) {
478 if( ldaphost != NULL ) {
479 fprintf( stderr, "%s: -H incompatible with -h\n", prog );
480 exit( EXIT_FAILURE );
483 fprintf( stderr, "%s: -H incompatible with -p\n", prog );
484 exit( EXIT_FAILURE );
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 );
494 fprintf( stderr, "%s: -Z incompatible with LDAPv2\n", prog );
495 exit( EXIT_FAILURE );
498 #ifdef HAVE_CYRUS_SASL
499 if( authmethod == LDAP_AUTH_SASL ) {
500 fprintf( stderr, "%s: -[IOQRUXY] incompatible with LDAPv2\n",
502 exit( EXIT_FAILURE );
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",
510 exit( EXIT_FAILURE );
518 tool_conn_setup( int not, void (*private_setup)( LDAP * ) )
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 );
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 );
534 (void) SIGNAL( SIGPIPE, SIG_IGN );
538 /* connect to server */
539 if( ( ldaphost != NULL || ldapport ) && ( ldapuri == NULL ) ) {
541 fprintf( stderr, "ldap_init( %s, %d )\n",
542 ldaphost != NULL ? ldaphost : "<DEFAULT>",
546 ld = ldap_init( ldaphost, ldapport );
548 char buf[20 + sizeof(": ldap_init")];
549 sprintf( buf, "%.20s: ldap_init", prog );
551 exit( EXIT_FAILURE );
557 fprintf( stderr, "ldap_initialize( %s )\n",
558 ldapuri != NULL ? ldapuri : "<DEFAULT>" );
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 );
572 if( ldap_set_option( ld, LDAP_OPT_REFERRALS,
573 referrals ? LDAP_OPT_ON : LDAP_OPT_OFF )
574 != LDAP_OPT_SUCCESS )
576 fprintf( stderr, "Could not set LDAP_OPT_REFERRALS %s\n",
577 referrals ? "on" : "off" );
578 exit( EXIT_FAILURE );
581 if( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &protocol )
582 != LDAP_OPT_SUCCESS )
584 fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n",
586 exit( EXIT_FAILURE );
590 ( ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS )) {
591 ldap_perror( ld, "ldap_start_tls" );
593 exit( EXIT_FAILURE );
603 tool_bind( LDAP *ld )
605 if ( authmethod == LDAP_AUTH_SASL ) {
606 #ifdef HAVE_CYRUS_SASL
610 if( sasl_secprops != NULL ) {
611 rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
612 (void *) sasl_secprops );
614 if( rc != LDAP_OPT_SUCCESS ) {
616 "Could not set LDAP_OPT_X_SASL_SECPROPS: %s\n",
618 exit( EXIT_FAILURE );
622 defaults = lutil_sasl_defaults( ld,
629 rc = ldap_sasl_interactive_bind_s( ld, binddn,
630 sasl_mech, NULL, NULL,
631 sasl_flags, lutil_sasl_interact, defaults );
633 if( rc != LDAP_SUCCESS ) {
634 ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
635 exit( EXIT_FAILURE );
638 fprintf( stderr, "%s: not compiled with SASL support\n",
640 exit( EXIT_FAILURE );
643 if ( ldap_bind_s( ld, binddn, passwd.bv_val, authmethod )
645 ldap_perror( ld, "ldap_bind" );
646 exit( EXIT_FAILURE );
652 /* Set server controls. Add controls extra_c[0..count-1], if set. */
654 tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count )
656 int i = 0, j, crit = 0, err;
657 LDAPControl c[3], **ctrls;
659 ctrls = (LDAPControl **)malloc( sizeof(c) + (count + 1)*sizeof(LDAPControl *) );
660 if ( ctrls == NULL ) {
661 fprintf( stderr, "No memory\n" );
662 exit( EXIT_FAILURE );
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;
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;
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;
693 ctrls[i++] = extra_c++;
696 err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, ctrls );
698 if ( err != LDAP_OPT_SUCCESS ) {
699 for ( j = 0; j < i; j++ )
700 if ( ctrls[j]->ldctl_iscritical )
702 fprintf( stderr, "Could not set %scontrols\n",
703 crit ? "critical " : "" );
708 exit( EXIT_FAILURE );