1 /* common.c - common routines for the ldap client tools */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 1998-2005 The OpenLDAP Foundation.
6 * Portions Copyright 2003 Kurt D. Zeilenga.
7 * Portions Copyright 2003 IBM Corporation.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted only as authorized by the OpenLDAP
14 * A copy of this license is available in the file LICENSE in the
15 * top-level directory of the distribution or, alternatively, at
16 * <http://www.OpenLDAP.org/license.html>.
19 * This file was initially created by Hallvard B. Furuseth based (in
20 * part) upon argument parsing code for individual tools located in
21 * this directory. Additional contributors include:
22 * Kurt D. Zeilenga (additional common argument and control support)
29 #include <ac/stdlib.h>
30 #include <ac/signal.h>
31 #include <ac/string.h>
32 #include <ac/unistd.h>
37 #include "lutil_ldap.h"
38 #include "ldap_defaults.h"
51 char *ldaphost = NULL;
53 #ifdef HAVE_CYRUS_SASL
54 unsigned sasl_flags = LDAP_SASL_AUTOMATIC;
55 char *sasl_realm = NULL;
56 char *sasl_authc_id = NULL;
57 char *sasl_authz_id = NULL;
58 char *sasl_mech = NULL;
59 char *sasl_secprops = NULL;
64 char *assertion = NULL;
70 char *preread_attrs = NULL;
72 char *postread_attrs = NULL;
76 struct berval passwd = { 0, NULL };
83 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
85 static int chainingResolve = -1;
86 static int chainingContinuation = -1;
87 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
95 ldap_pvt_setlocale(LC_MESSAGES, "");
96 ldap_pvt_bindtextdomain(OPENLDAP_PACKAGE, LDAP_LOCALEDIR);
97 ldap_pvt_textdomain(OPENLDAP_PACKAGE);
101 tool_common_usage( void )
103 static const char *const descriptions[] = {
104 N_(" -c continuous operation mode (do not stop on errors)\n"),
105 N_(" -C chase referrals (anonymously)\n"),
106 N_(" -d level set LDAP debugging level to `level'\n"),
107 N_(" -D binddn bind DN\n"),
108 N_(" -e [!]<ext>[=<extparam>] general extensions (! indicates criticality)\n")
109 N_(" [!]assert=<filter> (an RFC 2254 Filter)\n")
110 N_(" [!]authzid=<authzid> (\"dn:<dn>\" or \"u:<user>\")\n")
111 N_(" [!]manageDSAit\n")
113 #ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
116 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
117 N_(" [!]chaining[=<resolveBehavior>[/<continuationBehavior>]]\n")
118 N_(" one of \"chainingPreferred\", \"chainingRequired\",\n")
119 N_(" \"referralsPreferred\", \"referralsRequired\"\n")
120 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
121 N_(" [!]postread[=<attrs>] (a comma-separated attribute list)\n")
122 N_(" [!]preread[=<attrs>] (a comma-separated attribute list)\n"),
123 N_(" -f file read operations from `file'\n"),
124 N_(" -h host LDAP server\n"),
125 N_(" -H URI LDAP Uniform Resource Indentifier(s)\n"),
126 N_(" -I use SASL Interactive mode\n"),
127 N_(" -k use Kerberos authentication\n"),
128 N_(" -K like -k, but do only step 1 of the Kerberos bind\n"),
129 N_(" -M enable Manage DSA IT control (-MM to make critical)\n"),
130 N_(" -n show what would be done but don't actually do it\n"),
131 N_(" -O props SASL security properties\n"),
132 N_(" -p port port on LDAP server\n"),
133 N_(" -P version procotol version (default: 3)\n"),
134 N_(" -Q use SASL Quiet mode\n"),
135 N_(" -R realm SASL realm\n"),
136 N_(" -U authcid SASL authentication identity\n"),
137 N_(" -v run in verbose mode (diagnostics to standard output)\n"),
138 N_(" -V print version info (-VV only)\n"),
139 N_(" -w passwd bind password (for simple authentication)\n"),
140 N_(" -W prompt for bind password\n"),
141 N_(" -x Simple authentication\n"),
142 N_(" -X authzid SASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"),
143 N_(" -y file Read password from file\n"),
144 N_(" -Y mech SASL mechanism\n"),
145 N_(" -Z Start TLS request (-ZZ to require successful response)\n"),
148 const char *const *cpp;
150 fputs( _("Common options:\n"), stderr );
151 for( cpp = descriptions; *cpp != NULL; cpp++ ) {
152 if( strchr( options, (*cpp)[3] ) || (*cpp)[3] == ' ' ) {
153 fputs( _(*cpp), stderr );
160 tool_args( int argc, char **argv )
164 while (( i = getopt( argc, argv, options )) != EOF ) {
166 char *control, *cvalue, *next;
168 case 'c': /* continuous operation mode */
175 ival = strtol( optarg, &next, 10 );
176 if (next == NULL || next[0] != '\0') {
177 fprintf( stderr, "%s: unable to parse debug value \"%s\"\n", prog, optarg);
182 case 'D': /* bind DN */
183 if( binddn != NULL ) {
184 fprintf( stderr, "%s: -D previously specified\n", prog );
185 exit( EXIT_FAILURE );
187 binddn = ber_strdup( optarg );
189 case 'e': /* general extensions (controls and such) */
190 /* should be extended to support comma separated list of
191 * [!]key[=value] parameters, e.g. -e !foo,bar=567
196 if( optarg[0] == '!' ) {
201 control = ber_strdup( optarg );
202 if ( (cvalue = strchr( control, '=' )) != NULL ) {
206 if ( strcasecmp( control, "assert" ) == 0 ) {
208 fprintf( stderr, "assert control previously specified\n");
209 exit( EXIT_FAILURE );
211 if( cvalue == NULL ) {
212 fprintf( stderr, "assert: control value expected\n" );
216 assertctl = 1 + crit;
218 assert( assertion == NULL );
221 } else if ( strcasecmp( control, "authzid" ) == 0 ) {
222 if( authzid != NULL ) {
223 fprintf( stderr, "authzid control previously specified\n");
224 exit( EXIT_FAILURE );
226 if( cvalue == NULL ) {
227 fprintf( stderr, "authzid: control value expected\n" );
231 fprintf( stderr, "authzid: must be marked critical\n" );
235 assert( authzid == NULL );
238 } else if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
241 "manageDSAit control previously specified\n");
242 exit( EXIT_FAILURE );
244 if( cvalue != NULL ) {
246 "manageDSAit: no control value expected\n" );
250 manageDSAit = 1 + crit;
252 } else if ( strcasecmp( control, "noop" ) == 0 ) {
254 fprintf( stderr, "noop control previously specified\n");
255 exit( EXIT_FAILURE );
257 if( cvalue != NULL ) {
258 fprintf( stderr, "noop: no control value expected\n" );
264 #ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
265 } else if ( strcasecmp( control, "ppolicy" ) == 0 ) {
267 fprintf( stderr, "ppolicy control previously specified\n");
268 exit( EXIT_FAILURE );
270 if( cvalue != NULL ) {
271 fprintf( stderr, "ppolicy: no control value expected\n" );
275 fprintf( stderr, "ppolicy: critical flag not allowed\n" );
282 } else if ( strcasecmp( control, "preread" ) == 0 ) {
284 fprintf( stderr, "preread control previously specified\n");
285 exit( EXIT_FAILURE );
289 preread_attrs = cvalue;
291 } else if ( strcasecmp( control, "postread" ) == 0 ) {
293 fprintf( stderr, "postread control previously specified\n");
294 exit( EXIT_FAILURE );
298 postread_attrs = cvalue;
300 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
301 } else if ( strcasecmp( control, "chaining" ) == 0 ) {
304 if ( cvalue != NULL ) {
307 continuation = strchr( cvalue, '/' );
308 if ( continuation ) {
309 /* FIXME: this makes sense only in searches */
310 *continuation++ = '\0';
311 if ( strcasecmp( continuation, "chainingPreferred" ) == 0 ) {
312 chainingContinuation = LDAP_CHAINING_PREFERRED;
313 } else if ( strcasecmp( continuation, "chainingRequired" ) == 0 ) {
314 chainingContinuation = LDAP_CHAINING_REQUIRED;
315 } else if ( strcasecmp( continuation, "referralsPreferred" ) == 0 ) {
316 chainingContinuation = LDAP_REFERRALS_PREFERRED;
317 } else if ( strcasecmp( continuation, "referralsRequired" ) == 0 ) {
318 chainingContinuation = LDAP_REFERRALS_REQUIRED;
321 "chaining behavior control "
322 "continuation value \"%s\" invalid\n",
324 exit( EXIT_FAILURE );
328 if ( strcasecmp( cvalue, "chainingPreferred" ) == 0 ) {
329 chainingResolve = LDAP_CHAINING_PREFERRED;
330 } else if ( strcasecmp( cvalue, "chainingRequired" ) == 0 ) {
331 chainingResolve = LDAP_CHAINING_REQUIRED;
332 } else if ( strcasecmp( cvalue, "referralsPreferred" ) == 0 ) {
333 chainingResolve = LDAP_REFERRALS_PREFERRED;
334 } else if ( strcasecmp( cvalue, "referralsRequired" ) == 0 ) {
335 chainingResolve = LDAP_REFERRALS_REQUIRED;
338 "chaining behavior control "
339 "resolve value \"%s\" invalid\n",
341 exit( EXIT_FAILURE );
344 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
347 fprintf( stderr, "Invalid general control name: %s\n",
352 case 'f': /* read from file */
353 if( infile != NULL ) {
354 fprintf( stderr, "%s: -f previously specified\n", prog );
355 exit( EXIT_FAILURE );
357 infile = ber_strdup( optarg );
359 case 'h': /* ldap host */
360 if( ldaphost != NULL ) {
361 fprintf( stderr, "%s: -h previously specified\n", prog );
362 exit( EXIT_FAILURE );
364 ldaphost = ber_strdup( optarg );
366 case 'H': /* ldap URI */
367 if( ldapuri != NULL ) {
368 fprintf( stderr, "%s: -H previously specified\n", prog );
369 exit( EXIT_FAILURE );
371 ldapuri = ber_strdup( optarg );
374 #ifdef HAVE_CYRUS_SASL
375 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
376 fprintf( stderr, "%s: incompatible previous "
377 "authentication choice\n",
379 exit( EXIT_FAILURE );
381 authmethod = LDAP_AUTH_SASL;
382 sasl_flags = LDAP_SASL_INTERACTIVE;
385 fprintf( stderr, "%s: was not compiled with SASL support\n",
387 exit( EXIT_FAILURE );
389 case 'k': /* kerberos bind */
390 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
391 if( authmethod != -1 ) {
392 fprintf( stderr, "%s: -k incompatible with previous "
393 "authentication choice\n", prog );
394 exit( EXIT_FAILURE );
396 authmethod = LDAP_AUTH_KRBV4;
398 fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
399 exit( EXIT_FAILURE );
402 case 'K': /* kerberos bind, part one only */
403 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
404 if( authmethod != -1 ) {
405 fprintf( stderr, "%s: incompatible with previous "
406 "authentication choice\n", prog );
407 exit( EXIT_FAILURE );
409 authmethod = LDAP_AUTH_KRBV41;
411 fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
412 exit( EXIT_FAILURE );
416 /* enable Manage DSA IT */
419 case 'n': /* print operations, don't actually do them */
423 #ifdef HAVE_CYRUS_SASL
424 if( sasl_secprops != NULL ) {
425 fprintf( stderr, "%s: -O previously specified\n", prog );
426 exit( EXIT_FAILURE );
428 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
429 fprintf( stderr, "%s: incompatible previous "
430 "authentication choice\n", prog );
431 exit( EXIT_FAILURE );
433 authmethod = LDAP_AUTH_SASL;
434 sasl_secprops = ber_strdup( optarg );
436 fprintf( stderr, "%s: not compiled with SASL support\n", prog );
437 exit( EXIT_FAILURE );
442 fprintf( stderr, "%s: -p previously specified\n", prog );
443 exit( EXIT_FAILURE );
445 ival = strtol( optarg, &next, 10 );
446 if ( next == NULL || next[0] != '\0' ) {
447 fprintf( stderr, "%s: unable to parse port number \"%s\"\n", prog, optarg );
448 exit( EXIT_FAILURE );
453 ival = strtol( optarg, &next, 10 );
454 if ( next == NULL || next[0] != '\0' ) {
455 fprintf( stderr, "%s: unabel to parse protocol version \"%s\"\n", prog, optarg );
456 exit( EXIT_FAILURE );
460 if( protocol == LDAP_VERSION3 ) {
461 fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
463 exit( EXIT_FAILURE );
465 protocol = LDAP_VERSION2;
468 if( protocol == LDAP_VERSION2 ) {
469 fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
471 exit( EXIT_FAILURE );
473 protocol = LDAP_VERSION3;
476 fprintf( stderr, "%s: protocol version should be 2 or 3\n",
482 #ifdef HAVE_CYRUS_SASL
483 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
484 fprintf( stderr, "%s: incompatible previous "
485 "authentication choice\n",
487 exit( EXIT_FAILURE );
489 authmethod = LDAP_AUTH_SASL;
490 sasl_flags = LDAP_SASL_QUIET;
493 fprintf( stderr, "%s: not compiled with SASL support\n",
495 exit( EXIT_FAILURE );
498 #ifdef HAVE_CYRUS_SASL
499 if( sasl_realm != NULL ) {
500 fprintf( stderr, "%s: -R previously specified\n", prog );
501 exit( EXIT_FAILURE );
503 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
504 fprintf( stderr, "%s: incompatible previous "
505 "authentication choice\n",
507 exit( EXIT_FAILURE );
509 authmethod = LDAP_AUTH_SASL;
510 sasl_realm = ber_strdup( optarg );
512 fprintf( stderr, "%s: not compiled with SASL support\n",
514 exit( EXIT_FAILURE );
518 #ifdef HAVE_CYRUS_SASL
519 if( sasl_authc_id != NULL ) {
520 fprintf( stderr, "%s: -U previously specified\n", prog );
521 exit( EXIT_FAILURE );
523 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
524 fprintf( stderr, "%s: incompatible previous "
525 "authentication choice\n",
527 exit( EXIT_FAILURE );
529 authmethod = LDAP_AUTH_SASL;
530 sasl_authc_id = ber_strdup( optarg );
532 fprintf( stderr, "%s: not compiled with SASL support\n",
534 exit( EXIT_FAILURE );
537 case 'v': /* verbose mode */
540 case 'V': /* version */
543 case 'w': /* password */
544 passwd.bv_val = ber_strdup( optarg );
548 for( p = optarg; *p != '\0'; p++ ) {
552 passwd.bv_len = strlen( passwd.bv_val );
561 #ifdef HAVE_CYRUS_SASL
562 if( sasl_mech != NULL ) {
563 fprintf( stderr, "%s: -Y previously specified\n", prog );
564 exit( EXIT_FAILURE );
566 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
568 "%s: incompatible with authentication choice\n", prog );
569 exit( EXIT_FAILURE );
571 authmethod = LDAP_AUTH_SASL;
572 sasl_mech = ber_strdup( optarg );
574 fprintf( stderr, "%s: not compiled with SASL support\n", prog );
575 exit( EXIT_FAILURE );
579 if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
580 fprintf( stderr, "%s: incompatible with previous "
581 "authentication choice\n", prog );
582 exit( EXIT_FAILURE );
584 authmethod = LDAP_AUTH_SIMPLE;
587 #ifdef HAVE_CYRUS_SASL
588 if( sasl_authz_id != NULL ) {
589 fprintf( stderr, "%s: -X previously specified\n", prog );
590 exit( EXIT_FAILURE );
592 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
593 fprintf( stderr, "%s: -X incompatible with "
594 "authentication choice\n", prog );
595 exit( EXIT_FAILURE );
597 authmethod = LDAP_AUTH_SASL;
598 sasl_authz_id = ber_strdup( optarg );
600 fprintf( stderr, "%s: not compiled with SASL support\n", prog );
601 exit( EXIT_FAILURE );
608 fprintf( stderr, "%s: not compiled with TLS support\n", prog );
609 exit( EXIT_FAILURE );
613 if( handle_private_option( i ) ) break;
614 fprintf( stderr, "%s: unrecognized option -%c\n",
621 /* prevent bad linking */
623 api.ldapai_info_version = LDAP_API_INFO_VERSION;
625 if ( ldap_get_option(NULL, LDAP_OPT_API_INFO, &api)
626 != LDAP_OPT_SUCCESS )
628 fprintf( stderr, "%s: ldap_get_option(API_INFO) failed\n", prog );
629 exit( EXIT_FAILURE );
632 if (api.ldapai_info_version != LDAP_API_INFO_VERSION) {
633 fprintf( stderr, "LDAP APIInfo version mismatch: "
634 "got %d, expected %d\n",
635 api.ldapai_info_version, LDAP_API_INFO_VERSION );
636 exit( EXIT_FAILURE );
639 if( api.ldapai_api_version != LDAP_API_VERSION ) {
640 fprintf( stderr, "LDAP API version mismatch: "
641 "got %d, expected %d\n",
642 api.ldapai_api_version, LDAP_API_VERSION );
643 exit( EXIT_FAILURE );
646 if( strcmp(api.ldapai_vendor_name, LDAP_VENDOR_NAME ) != 0 ) {
647 fprintf( stderr, "LDAP vendor name mismatch: "
648 "got %s, expected %s\n",
649 api.ldapai_vendor_name, LDAP_VENDOR_NAME );
650 exit( EXIT_FAILURE );
653 if( api.ldapai_vendor_version != LDAP_VENDOR_VERSION ) {
654 fprintf( stderr, "LDAP vendor version mismatch: "
655 "got %d, expected %d\n",
656 api.ldapai_vendor_version, LDAP_VENDOR_VERSION );
657 exit( EXIT_FAILURE );
661 fprintf( stderr, "%s: %s\t(LDAP library: %s %d)\n",
663 LDAP_VENDOR_NAME, LDAP_VENDOR_VERSION );
664 if (version > 1) exit( EXIT_SUCCESS );
669 protocol = LDAP_VERSION3;
671 if (authmethod == -1 && protocol > LDAP_VERSION2) {
672 #ifdef HAVE_CYRUS_SASL
673 authmethod = LDAP_AUTH_SASL;
675 authmethod = LDAP_AUTH_SIMPLE;
679 if( ldapuri == NULL ) {
680 if( ldapport && ( ldaphost == NULL )) {
681 fprintf( stderr, "%s: -p without -h is invalid.\n", prog );
682 exit( EXIT_FAILURE );
685 if( ldaphost != NULL ) {
686 fprintf( stderr, "%s: -H incompatible with -h\n", prog );
687 exit( EXIT_FAILURE );
690 fprintf( stderr, "%s: -H incompatible with -p\n", prog );
691 exit( EXIT_FAILURE );
694 if( protocol == LDAP_VERSION2 ) {
695 if( authzid || manageDSAit || noop || ppolicy ) {
696 fprintf( stderr, "%s: -e/-M incompatible with LDAPv2\n", prog );
697 exit( EXIT_FAILURE );
701 fprintf( stderr, "%s: -Z incompatible with LDAPv2\n", prog );
702 exit( EXIT_FAILURE );
705 #ifdef HAVE_CYRUS_SASL
706 if( authmethod == LDAP_AUTH_SASL ) {
707 fprintf( stderr, "%s: -[IOQRUXY] incompatible with LDAPv2\n",
709 exit( EXIT_FAILURE );
713 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
714 if ( authmethod == LDAP_AUTH_KRBV4 || authmethod == LDAP_AUTH_KRBV41 ) {
715 fprintf( stderr, "%s: -k/-K incompatible with LDAPv%d\n",
717 exit( EXIT_FAILURE );
725 tool_conn_setup( int not, void (*private_setup)( LDAP * ) )
730 if( ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug )
731 != LBER_OPT_SUCCESS )
734 "Could not set LBER_OPT_DEBUG_LEVEL %d\n", debug );
736 if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug )
737 != LDAP_OPT_SUCCESS )
740 "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
745 (void) SIGNAL( SIGPIPE, SIG_IGN );
751 if( ( ldaphost != NULL || ldapport ) && ( ldapuri == NULL ) ) {
754 memset( &url, 0, sizeof(url));
756 url.lud_scheme = "ldap";
757 url.lud_host = ldaphost;
758 url.lud_port = ldapport;
759 url.lud_scope = LDAP_SCOPE_DEFAULT;
761 ldapuri = ldap_url_desc2str( &url );
765 fprintf( stderr, "ldap_initialize( %s )\n",
766 ldapuri != NULL ? ldapuri : "<DEFAULT>" );
768 rc = ldap_initialize( &ld, ldapuri );
769 if( rc != LDAP_SUCCESS ) {
771 "Could not create LDAP session handle for URI=%s (%d): %s\n",
772 ldapuri, rc, ldap_err2string(rc) );
773 exit( EXIT_FAILURE );
776 if( private_setup ) private_setup( ld );
779 if( ldap_set_option( ld, LDAP_OPT_REFERRALS,
780 referrals ? LDAP_OPT_ON : LDAP_OPT_OFF ) != LDAP_OPT_SUCCESS )
782 fprintf( stderr, "Could not set LDAP_OPT_REFERRALS %s\n",
783 referrals ? "on" : "off" );
784 exit( EXIT_FAILURE );
787 if( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &protocol )
788 != LDAP_OPT_SUCCESS )
790 fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n",
792 exit( EXIT_FAILURE );
796 ( ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS ))
798 ldap_perror( ld, "ldap_start_tls" );
800 exit( EXIT_FAILURE );
810 tool_bind( LDAP *ld )
812 #ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
814 LDAPControl *ctrls[2], c;
815 c.ldctl_oid = LDAP_CONTROL_PASSWORDPOLICYREQUEST;
816 c.ldctl_value.bv_val = NULL;
817 c.ldctl_value.bv_len = 0;
818 c.ldctl_iscritical = 0;
821 ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, ctrls );
825 if ( authmethod == LDAP_AUTH_SASL ) {
826 #ifdef HAVE_CYRUS_SASL
830 if( sasl_secprops != NULL ) {
831 rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
832 (void *) sasl_secprops );
834 if( rc != LDAP_OPT_SUCCESS ) {
836 "Could not set LDAP_OPT_X_SASL_SECPROPS: %s\n",
838 exit( EXIT_FAILURE );
842 defaults = lutil_sasl_defaults( ld,
849 rc = ldap_sasl_interactive_bind_s( ld, binddn,
850 sasl_mech, NULL, NULL,
851 sasl_flags, lutil_sasl_interact, defaults );
853 lutil_sasl_freedefs( defaults );
854 if( rc != LDAP_SUCCESS ) {
855 ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
856 exit( EXIT_FAILURE );
859 fprintf( stderr, "%s: not compiled with SASL support\n",
861 exit( EXIT_FAILURE );
871 if (( msgid = ldap_bind( ld, binddn, passwd.bv_val, authmethod )) == -1 )
873 ldap_perror( ld, "ldap_bind" );
874 exit( EXIT_FAILURE );
877 if ( ldap_result( ld, msgid, 1, NULL, &result ) == -1 ) {
878 ldap_perror( ld, "ldap_result" );
879 exit( EXIT_FAILURE );
882 if ( ldap_parse_result( ld, result, &err, NULL, NULL, NULL,
883 &ctrls, 1 ) != LDAP_SUCCESS ) {
884 ldap_perror( ld, "ldap_bind parse result" );
885 exit( EXIT_FAILURE );
888 #ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
889 if ( ctrls && ppolicy ) {
891 int expire, grace, len = 0;
892 LDAPPasswordPolicyError pErr = -1;
894 ctrl = ldap_find_control( LDAP_CONTROL_PASSWORDPOLICYRESPONSE, ctrls );
895 if ( ctrl && ldap_parse_passwordpolicy_control( ld, ctrl,
896 &expire, &grace, &pErr ) == LDAP_SUCCESS ) {
897 if ( pErr != PP_noError ){
900 strcpy( msgbuf+2, ldap_passwordpolicy_err2txt( pErr ));
901 len = strlen( msgbuf );
904 sprintf( msgbuf+len, " (Password expires in %d seconds)", expire );
905 } else if ( grace >= 0 ) {
906 sprintf( msgbuf+len, " (Password expired, %d grace logins remain)", grace );
911 if ( err != LDAP_SUCCESS || msgbuf[0] ) {
912 fprintf( stderr, "ldap_bind: %s%s\n", ldap_err2string( err ),
914 if ( err != LDAP_SUCCESS ) {
915 exit( EXIT_FAILURE );
922 /* Set server controls. Add controls extra_c[0..count-1], if set. */
924 tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count )
926 int i = 0, j, crit = 0, err;
927 LDAPControl c[9], **ctrls;
929 ctrls = (LDAPControl**) malloc(sizeof(c) + (count+1)*sizeof(LDAPControl*));
930 if ( ctrls == NULL ) {
931 fprintf( stderr, "No memory\n" );
932 exit( EXIT_FAILURE );
936 BerElementBuffer berbuf;
937 BerElement *ber = (BerElement *)&berbuf;
939 if( assertion == NULL || *assertion == '\0' ) {
940 fprintf( stderr, "Assertion=<empty>\n" );
941 exit( EXIT_FAILURE );
944 ber_init2( ber, NULL, LBER_USE_DER );
946 err = ldap_pvt_put_filter( ber, assertion );
948 fprintf( stderr, "assertion encode failed (%d)\n", err );
949 exit( EXIT_FAILURE );
952 err = ber_flatten2( ber, &c[i].ldctl_value, 0 );
954 fprintf( stderr, "assertion flatten failed (%d)\n", err );
955 exit( EXIT_FAILURE );
958 c[i].ldctl_oid = LDAP_CONTROL_ASSERT;
959 c[i].ldctl_iscritical = assertctl > 1;
965 c[i].ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
966 c[i].ldctl_value.bv_val = authzid;
967 c[i].ldctl_value.bv_len = strlen( authzid );
968 c[i].ldctl_iscritical = 1;
974 c[i].ldctl_oid = LDAP_CONTROL_MANAGEDSAIT;
975 BER_BVZERO( &c[i].ldctl_value );
976 c[i].ldctl_iscritical = manageDSAit > 1;
982 c[i].ldctl_oid = LDAP_CONTROL_NOOP;
983 BER_BVZERO( &c[i].ldctl_value );
984 c[i].ldctl_iscritical = noop > 1;
990 char berbuf[LBER_ELEMENT_SIZEOF];
991 BerElement *ber = (BerElement *)berbuf;
994 if( preread_attrs ) {
995 attrs = ldap_str2charray( preread_attrs, "," );
998 ber_init2( ber, NULL, LBER_USE_DER );
1000 if( ber_printf( ber, "{v}", attrs ) == -1 ) {
1001 fprintf( stderr, "preread attrs encode failed.\n" );
1002 exit( EXIT_FAILURE );
1005 err = ber_flatten2( ber, &c[i].ldctl_value, 0 );
1007 fprintf( stderr, "preread flatten failed (%d)\n", err );
1008 exit( EXIT_FAILURE );
1011 c[i].ldctl_oid = LDAP_CONTROL_PRE_READ;
1012 c[i].ldctl_iscritical = preread > 1;
1016 if( attrs ) ldap_charray_free( attrs );
1020 char berbuf[LBER_ELEMENT_SIZEOF];
1021 BerElement *ber = (BerElement *)berbuf;
1022 char **attrs = NULL;
1024 if( postread_attrs ) {
1025 attrs = ldap_str2charray( postread_attrs, "," );
1028 ber_init2( ber, NULL, LBER_USE_DER );
1030 if( ber_printf( ber, "{v}", attrs ) == -1 ) {
1031 fprintf( stderr, "postread attrs encode failed.\n" );
1032 exit( EXIT_FAILURE );
1035 err = ber_flatten2( ber, &c[i].ldctl_value, 0 );
1037 fprintf( stderr, "postread flatten failed (%d)\n", err );
1038 exit( EXIT_FAILURE );
1041 c[i].ldctl_oid = LDAP_CONTROL_POST_READ;
1042 c[i].ldctl_iscritical = postread > 1;
1046 if( attrs ) ldap_charray_free( attrs );
1049 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
1051 if ( chainingResolve > -1 ) {
1052 BerElementBuffer berbuf;
1053 BerElement *ber = (BerElement *)&berbuf;
1055 ber_init2( ber, NULL, LBER_USE_DER );
1057 err = ber_printf( ber, "{e" /* } */, chainingResolve );
1060 fprintf( stderr, _("Chaining behavior control encoding error!\n") );
1061 exit( EXIT_FAILURE );
1064 if ( chainingContinuation > -1 ) {
1065 err = ber_printf( ber, "e", chainingContinuation );
1068 fprintf( stderr, _("Chaining behavior control encoding error!\n") );
1069 exit( EXIT_FAILURE );
1073 err = ber_printf( ber, /* { */ "N}" );
1076 fprintf( stderr, _("Chaining behavior control encoding error!\n") );
1077 exit( EXIT_FAILURE );
1080 if ( ber_flatten2( ber, &c[i].ldctl_value, 0 ) == -1 ) {
1081 exit( EXIT_FAILURE );
1085 BER_BVZERO( &c[i].ldctl_value );
1088 c[i].ldctl_oid = LDAP_CONTROL_X_CHAINING_BEHAVIOR;
1089 c[i].ldctl_iscritical = chaining > 1;
1093 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
1096 ctrls[i++] = extra_c++;
1100 err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, ctrls );
1102 if ( err != LDAP_OPT_SUCCESS ) {
1103 for ( j = 0; j < i; j++ ) {
1104 if ( ctrls[j]->ldctl_iscritical ) crit = 1;
1106 fprintf( stderr, "Could not set %scontrols\n",
1107 crit ? "critical " : "" );
1112 exit( EXIT_FAILURE );