2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
7 * The contents of this file are subject to the Netscape Public
8 * License Version 1.1 (the "License"); you may not use this file
9 * except in compliance with the License. You may obtain a copy of
10 * the License at http://www.mozilla.org/NPL/
12 * Software distributed under the License is distributed on an "AS
13 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * rights and limitations under the License.
17 * The Original Code is Mozilla Communicator client code, released
20 * The Initial Developer of the Original Code is Netscape
21 * Communications Corporation. Portions created by Netscape are
22 * Copyright (C) 1998-1999 Netscape Communications Corporation. All
26 * Copyright (c) 2016 by Delphix. All rights reserved.
30 * code that is shared by two or more of the LDAP command line tools
35 #ifdef SOLARIS_LDAP_CMD
36 #include "solaris-int.h"
40 #include <sys/types.h>
43 #endif /* SOLARIS_LDAP_CMD */
45 #ifdef LDAP_TOOL_ARGPIN
47 #include "ntuserpin.h"
48 #endif /* LDAP_TOOL_ARGPIN */
50 #ifndef SOLARIS_LDAP_CMD
51 #include <nspr.h> /* for PR_Cleanup() */
52 #endif /* SOLARIS_LDAP_CMD */
54 #include <time.h> /* for time() and ctime() */
55 #ifdef HAVE_SASL_OPTIONS
56 #ifdef SOLARIS_LDAP_CMD
57 #include <sasl/sasl.h>
60 #endif /* SOLARIS_LDAP_CMD */
61 #include "ldaptool-sasl.h"
62 #endif /* HAVE_SASL_OPTIONS */
64 #ifndef SOLARIS_LDAP_CMD
68 #ifdef SOLARIS_LDAP_CMD
69 #define PATH_BUF_SIZE (PATH_MAX + 1)
72 static LDAP_REBINDPROC_CALLBACK get_rebind_credentials
;
73 static void print_library_info( const LDAPAPIInfo
*aip
, FILE *fp
);
74 static int wait4result( LDAP
*ld
, int msgid
, struct berval
**servercredp
,
76 static int parse_result( LDAP
*ld
, LDAPMessage
*res
,
77 struct berval
**servercredp
, char *msg
, int freeit
);
79 #ifdef LDAPTOOL_DEBUG_MEMORY
80 static void *ldaptool_debug_malloc( size_t size
);
81 static void *ldaptool_debug_calloc( size_t nelem
, size_t elsize
);
82 static void *ldaptool_debug_realloc( void *ptr
, size_t size
);
83 static void ldaptool_debug_free( void *ptr
);
84 #endif /* LDAPTOOL_DEBUG_MEMORY */
87 static char *certpath2keypath( char *certdbpath
);
88 static int ldaptool_setcallbacks( struct ldapssl_pkcs_fns
*pfns
);
89 static char * buildTokenCertName( const char *tokenName
, const char *certName
);
91 static int ldaptool_fortezza_init( int exit_on_error
);
92 static int ldaptool_fortezza_alert( void *arg
, PRBool onOpen
,
93 char *string
, int value1
, void *value2
);
94 static void * ldaptool_fortezza_getpin( char **passwordp
);
95 static char * ldaptool_fortezza_err2string( int err
);
98 #ifdef HAVE_SASL_OPTIONS
99 static int saslSetParam(char *saslarg
);
100 #endif /* HAVE_SASL_OPTIONS */
103 * display usage for common options with one exception: -f is not included
104 * since the description tends to be tool-specific.
106 * As of 1-Jul-1998, of the characters in the set [A-Za-z] the following are
107 * not currently used by any of the tools: EJgjqr
110 ldaptool_common_usage( int two_hosts
)
112 fprintf( stderr
, gettext(" -n\t\tshow what would be done but don't actually do it\n") );
113 fprintf( stderr
, gettext(" -v\t\trun in verbose mode (diagnostics to standard output)\n") );
115 fprintf( stderr
, gettext(" -h host\tLDAP server1 name or IP address (default: %s)\n"), LDAPTOOL_DEFHOST
);
116 fprintf( stderr
, gettext(" -p port\tLDAP server1 TCP port number (default: %d)\n"), LDAP_PORT
);
117 fprintf( stderr
, gettext(" -h host\tLDAP server2 name or IP address (default: %s)\n"), LDAPTOOL_DEFHOST
);
118 fprintf( stderr
, gettext(" -p port\tLDAP server2 TCP port number (default: %d)\n"), LDAP_PORT
);
120 fprintf( stderr
, gettext(" -h host\tLDAP server name or IP address (default: %s)\n"), LDAPTOOL_DEFHOST
);
121 fprintf( stderr
, gettext(" -p port\tLDAP server TCP port number (default: %d)\n"), LDAP_PORT
);
124 gettext(" -V n\tLDAP protocol version number (%d or %d; default: %d)\n"),
125 LDAP_VERSION2
, LDAP_VERSION3
, LDAP_VERSION3
);
127 fprintf( stderr
, gettext(" -Z\t\tmake an SSL-encrypted connection\n") );
128 fprintf( stderr
, gettext(" -P pathname\tpath to SSL certificate database (default: current directory)\n") );
129 fprintf( stderr
, gettext(" -N\t\tname of certificate to use for SSL client authentication\n") );
130 #ifndef SOLARIS_LDAP_CMD
131 fprintf( stderr
, gettext(" -K pathname\tpath to key database to use for SSL client authentication\n") );
132 fprintf( stderr
, gettext(" \t\t(default: path to certificate database provided with -P option)\n") );
133 #endif /* SOLARIS_LDAP_CMD */
134 #ifdef LDAP_TOOL_PKCS11
135 fprintf( stderr
, gettext(" -m pathname\tpath to security module database\n"));
136 #endif /* LDAP_TOOL_PKCS11 */
137 fprintf( stderr
, gettext(" -W\t\tSSL key password\n") );
138 #ifndef SOLARIS_LDAP_CMD
139 fprintf( stderr
, gettext(" -3\t\tcheck hostnames in SSL certificates\n") );
140 #endif /* SOLARIS_LDAP_CMD */
142 #ifdef LDAP_TOOL_PKCS11
143 fprintf( stderr
, gettext(" -Q [token][:certificate name]\tPKCS 11\n") );
144 /* fprintf( stderr, " -X pathname\tFORTEZZA compromised key list (CKL)\n" ); */
145 fprintf( stderr
, gettext(" -I pin\tcard password file\n") );
146 #endif /* LDAP_TOOL_PKCS11 */
149 fprintf( stderr
, gettext(" -D binddn\tbind dn\n") );
150 fprintf( stderr
, gettext(" -w passwd\tbind passwd (for simple authentication)\n") );
151 fprintf( stderr
, gettext(" -w - \tprompt for bind passwd (for simple authentication)\n") );
152 fprintf( stderr
, gettext(" -j file\tread bind passwd (for simple authentication)\n") );
153 fprintf( stderr
, gettext(" \t\tor SSL key password from 'file'\n") );
154 fprintf( stderr
, gettext(" -E\t\task server to expose (report) bind identity\n") );
156 fprintf( stderr
, gettext(" -d level\tset LDAP debugging level to `level'\n") );
158 fprintf( stderr
, gettext(" -R\t\tdo not automatically follow referrals\n") );
159 fprintf( stderr
, gettext(" -O limit\tmaximum number of referral hops to traverse (default: %d)\n"), LDAPTOOL_DEFREFHOPLIMIT
);
160 fprintf( stderr
, gettext(" -M\t\tmanage references (treat them as regular entries)\n") );
161 #ifndef SOLARIS_LDAP_CMD
162 fprintf( stderr
, gettext(" -0\t\tignore LDAP library version mismatches\n") );
163 #endif /* SOLARIS_LDAP_CMD */
166 fprintf( stderr
, gettext(" -C cfgfile\tuse local database described by cfgfile\n") );
168 fprintf( stderr
, gettext(" -i charset\tcharacter set for command line input (default taken from locale)\n") );
169 fprintf( stderr
, gettext(" -k dir\tconversion routine directory (default: current directory)\n") );
172 * Suppress usage for -y (old proxied authorization control) even though
173 * we still support it. We want to encourage people to use -Y instead (the
174 * new proxied authorization control).
176 fprintf( stderr
, gettext(" -y proxydn\tDN used for proxy authorization\n") );
178 fprintf( stderr
, gettext(" -Y proxyid\tproxied authorization id,\n") );
179 fprintf( stderr
, gettext(" \te.g, dn:uid=bjensen,dc=example,dc=com\n") );
180 fprintf( stderr
, gettext(" -H\t\tdisplay usage information\n") );
181 #ifdef SOLARIS_LDAP_CMD
182 fprintf( stderr
, gettext(" -?\t\tdisplay usage information\n") );
183 #endif /* SOLARIS_LDAP_CMD */
184 fprintf( stderr
, gettext(" -J controloid[:criticality[:value|::b64value|:<fileurl]]\n") );
185 fprintf( stderr
, gettext("\t\tcriticality is a boolean value (default is false)\n") );
186 #ifdef HAVE_SASL_OPTIONS
187 fprintf( stderr
, gettext(" -o attrName=attrVal\tSASL options which are described in the man page\n"));
188 #endif /* HAVE_SASL_OPTIONS */
192 char *ldaptool_charset
= "";
193 char *ldaptool_host
= LDAPTOOL_DEFHOST
;
194 char *ldaptool_host2
= LDAPTOOL_DEFHOST
;
195 int ldaptool_port
= LDAP_PORT
;
196 int ldaptool_port2
= LDAP_PORT
;
197 int ldaptool_verbose
= 0;
198 int ldaptool_not
= 0;
199 #ifdef SOLARIS_LDAP_CMD
200 int ldaptool_require_binddn
= 1;
201 #endif /* SOLARIS_LDAP_CMD */
202 FILE *ldaptool_fp
= NULL
;
203 FILE *password_fp
= NULL
;
204 char *ldaptool_progname
= "";
205 char *ldaptool_nls_lang
= NULL
;
206 char *proxyauth_id
= NULL
;
207 int proxyauth_version
= 2; /* use newer proxy control */
208 LDAPControl
*ldaptool_request_ctrls
[CONTROL_REQUESTS
] = {0};
210 int ldaptool_dbg_lvl
= 0;
211 #endif /* LDAP_DEBUG */
214 static char *binddn
= NULL
;
215 static char *passwd
= NULL
;
216 static int send_auth_response_ctrl
= 0;
217 static int user_specified_port
= 0;
218 static int user_specified_port2
= 0;
219 static int chase_referrals
= 1;
220 static int lib_version_mismatch_is_fatal
= 1;
221 static int ldversion
= -1; /* use default */
222 static int refhoplim
= LDAPTOOL_DEFREFHOPLIMIT
;
223 static int send_manage_dsait_ctrl
= 0;
224 static int prompt_password
= 0;
225 #ifdef HAVE_SASL_OPTIONS
226 static unsigned sasl_flags
= LDAP_SASL_INTERACTIVE
;
227 static char *sasl_mech
= NULL
;
228 static char *sasl_authid
= NULL
;
229 static char *sasl_mode
= NULL
;
230 static char *sasl_realm
= NULL
;
231 static char *sasl_username
= NULL
;
232 static char *sasl_secprops
= NULL
;
233 static int ldapauth
= -1;
234 #endif /* HAVE_SASL_OPTIONS */
237 static char *cache_config_file
= NULL
;
238 #endif /* !NO_LIBLCACHE */
240 static int secure
= 0;
247 static int ssl_strength
= LDAPTOOL_DEFSSLSTRENGTH
;
248 #ifdef SOLARIS_LDAP_CMD
249 static char pathname
[PATH_BUF_SIZE
];
251 static char *ssl_certdbpath
= NULL
;
252 static char *ssl_keydbpath
= NULL
;
253 static char *ssl_keyname
= NULL
;
254 static char *ssl_certname
= NULL
;
255 static char *ssl_passwd
= NULL
;
257 #ifdef LDAP_TOOL_PKCS11
258 static char *ssl_secmodpath
= NULL
;
260 static char *pkcs_token
= NULL
;
262 static char *ssl_donglefile
= NULL
;
265 static char *pkcs_pin
= NULL
;
267 static struct ldapssl_pkcs_fns local_pkcs_fns
=
268 {0,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
, NULL
};
271 static uint32 fortezza_cardmask
= 0;
272 static char *fortezza_personality
= NULL
;
273 static char *fortezza_krlfile
= NULL
;
274 static char *fortezza_pin
= NULL
;
275 #endif /* FORTEZZA */
276 #endif /* LDAP_TOOL_PKCS11 */
280 * Handle general initialization and options that are common to all of
282 * Handle options that are common to all of the LDAP tools.
283 * Note the the H option is included here but handled via the
284 * extra_opt_callback function (along with any "extra_opts" ).
286 * Return: final value for optind or -1 if usage should be displayed (for
287 * some fatal errors, we call exit here).
290 ldaptool_process_args( int argc
, char **argv
, char *extra_opts
,
291 int two_hosts
, void (*extra_opt_callback
)( int option
, char *optarg
))
294 char *optstring
, *common_opts
;
298 char *ctrl_arg
, *ctrl_oid
=NULL
, *ctrl_value
=NULL
;
299 int ctrl_criticality
=0, vlen
;
301 #ifdef SOLARIS_LDAP_CMD
307 * Set program name global based on argv[0].
309 if (( ldaptool_progname
= strrchr( argv
[ 0 ], '/' )) == NULL
) {
310 ldaptool_progname
= argv
[ 0 ];
315 #ifdef LDAPTOOL_DEBUG_MEMORY
317 struct ldap_memalloc_fns mafns
= {
318 ldaptool_debug_malloc
,
319 ldaptool_debug_calloc
,
320 ldaptool_debug_realloc
,
324 ldap_set_option( NULL
, LDAP_OPT_MEMALLOC_FN_PTRS
, &mafns
);
326 #endif /* LDAPTOOL_DEBUG_MEMORY */
330 ldap_set_option( NULL
, LDAP_OPT_DEBUG_LEVEL
, (void *) &i
);
334 * Perform a sanity check on the revision of the LDAP API library to
335 * make sure it is at least as new as the one we were compiled against.
336 * If the API implementation is from the same vendor as we were compiled
337 * against, we also check to make sure the vendor version is at least
338 * as new as the library we were compiled against.
340 * Version differences are fatal unless the -0 option is passed on the
341 * tool command line (that's a zero, not an oh). We check for the
342 * presence of -0 in a crude way to it must appear by itself in argv.
344 for ( i
= 1; i
< argc
; ++i
) {
345 if ( strcmp( argv
[i
], "-0" ) == 0 ) {
346 lib_version_mismatch_is_fatal
= 0;
351 memset( &ldai
, 0, sizeof(ldai
));
352 ldai
.ldapai_info_version
= LDAP_API_INFO_VERSION
;
353 if (( rc
= ldap_get_option( NULL
, LDAP_OPT_API_INFO
, &ldai
)) != 0 ) {
354 fprintf( stderr
, gettext("%s: unable to retrieve LDAP library version"
355 " information;\n\tthis program requires an LDAP library that"
356 " implements revision\n\t%d or greater of the LDAP API.\n"),
357 ldaptool_progname
, LDAP_API_VERSION
);
358 if ( lib_version_mismatch_is_fatal
) {
359 exit( LDAP_LOCAL_ERROR
);
361 } else if ( ldai
.ldapai_api_version
< LDAP_API_VERSION
) {
362 fprintf( stderr
, gettext("%s: this program requires an LDAP library that"
363 " implements revision\n\t%d or greater of the LDAP API;"
364 " running with revision %d.\n"),
365 ldaptool_progname
, LDAP_API_VERSION
, ldai
.ldapai_api_version
);
366 if ( lib_version_mismatch_is_fatal
) {
367 exit( LDAP_LOCAL_ERROR
);
369 } else if ( strcmp( ldai
.ldapai_vendor_name
, LDAP_VENDOR_NAME
) != 0) {
370 fprintf( stderr
, gettext("%s: this program requires %s's LDAP\n"
371 "\tlibrary version %2.2f or greater; running with\n"
372 "\t%s's version %2.2f.\n"),
373 ldaptool_progname
, LDAP_VENDOR_NAME
,
374 (float)LDAP_VENDOR_VERSION
/ 100,
375 ldai
.ldapai_vendor_name
,
376 (float)ldai
.ldapai_vendor_version
/ 100 );
377 if ( lib_version_mismatch_is_fatal
) {
378 exit( LDAP_LOCAL_ERROR
);
380 } else if (ldai
.ldapai_vendor_version
< LDAP_VENDOR_VERSION
) {
381 fprintf( stderr
, gettext("%s: this program requires %s's LDAP\n"
382 "\tlibrary version %2.2f or greater; running with"
383 " version %2.2f.\n"),
384 ldaptool_progname
, LDAP_VENDOR_NAME
,
385 (float)LDAP_VENDOR_VERSION
/ 100,
386 (float)ldai
.ldapai_vendor_version
/ 100 );
387 if ( lib_version_mismatch_is_fatal
) {
388 exit( LDAP_LOCAL_ERROR
);
393 * Process command line options.
395 if ( extra_opts
== NULL
) {
399 #ifdef HAVE_SASL_OPTIONS
400 #ifdef SOLARIS_LDAP_CMD
401 common_opts
= "nvEMRH?Zd:D:f:h:j:N:O:o:P:p:W:w:V:i:k:y:Y:J:";
403 common_opts
= "nvEMRHZ03d:D:f:h:j:I:K:N:O:o:P:p:Q:W:w:V:X:m:i:k:y:Y:J:";
404 #endif /* SOLARIS_LDAP_CMD */
406 common_opts
= "nvEMRHZ03d:D:f:h:j:I:K:N:O:P:p:Q:W:w:V:X:m:i:k:y:Y:J:";
407 #endif /* HAVE_SASL_OPTIONS */
409 /* note: optstring must include room for liblcache "C:" option */
410 if (( optstring
= (char *) malloc( strlen( extra_opts
) + strlen( common_opts
)
413 exit( LDAP_NO_MEMORY
);
417 sprintf( optstring
, "%s%s", common_opts
, extra_opts
);
419 sprintf( optstring
, "%s%sC:", common_opts
, extra_opts
);
423 while ( (i
= getopt( argc
, argv
, optstring
)) != EOF
) {
425 case 'n': /* do Not do any LDAP operations */
428 case 'v': /* verbose mode */
433 ldaptool_dbg_lvl
= atoi( optarg
); /* */
434 #ifdef SOLARIS_LDAP_CMD
435 ldap_set_option(NULL
, LBER_OPT_DEBUG_LEVEL
,
436 (void *)&ldaptool_dbg_lvl
);
438 ber_set_option(NULL
, LBER_OPT_DEBUG_LEVEL
,
439 (void *)&ldaptool_dbg_lvl
);
440 #endif /* SOLARIS_LDAP_CMD */
441 ldaptool_dbg_lvl
|= LDAP_DEBUG_ANY
;
442 ldap_set_option( NULL
, LDAP_OPT_DEBUG_LEVEL
,
443 (void *)&ldaptool_dbg_lvl
);
444 #else /* LDAP_DEBUG */
445 fprintf( stderr
, gettext("compile with -DLDAP_DEBUG for debugging\n") );
446 #endif /* LDAP_DEBUG */
448 case 'R': /* don't automatically chase referrals */
452 case 'C': /* search local database */
453 cache_config_file
= strdup( optarg
);
456 case 'f': /* input file */
457 if ( optarg
[0] == '-' && optarg
[1] == '\0' ) {
459 } else if (( ldaptool_fp
= ldaptool_open_file( optarg
, "r" )) == NULL
) {
461 exit( LDAP_PARAM_ERROR
);
464 case 'h': /* ldap host */
465 if ( hostnum
== 0 ) {
466 ldaptool_host
= strdup( optarg
);
468 ldaptool_host2
= strdup( optarg
);
472 case 'D': /* bind DN */
474 binddn
= strdup( optarg
);
476 case 'E': /* expose bind identity via auth. response control */
477 ++send_auth_response_ctrl
;
480 case 'p': /* ldap port */
481 if ( !user_specified_port
) {
482 ++user_specified_port
;
483 ldaptool_port
= atoi( optarg
);
485 ++user_specified_port2
;
486 ldaptool_port2
= atoi( optarg
);
490 case 'P': /* path to security database */
491 secure
= 1; /* do SSL encryption */
492 #ifndef SOLARIS_LDAP_CMD
493 ssl_certdbpath
= strdup(optarg
);
494 if (NULL
== ssl_certdbpath
) {
496 exit( LDAP_NO_MEMORY
);
500 * Verify whether it's a base directory or a cert db file.
501 * If it is not a directory, truncate the file name as
502 * the revised NSS_Init() doesn't take file name any longer.
504 if (strlcpy(pathname
, optarg
, PATH_BUF_SIZE
) >= PATH_BUF_SIZE
) {
505 fprintf(stderr
, gettext("\"-P\": Path name is too "
507 exit(LDAP_PARAM_ERROR
);
510 if (stat(pathname
, &st
) != 0) {
512 fprintf(stderr
, gettext("\"-P\": Path name is "
514 exit(LDAP_PARAM_ERROR
);
516 if (S_ISREG(st
.st_mode
)) {
517 /* redir to a regular file's dir name */
518 ssl_certdbpath
= dirname(pathname
);
520 ssl_certdbpath
= pathname
;
522 #endif /* SOLARIS_LDAP_CMD */
524 case 'Z': /* do SSL encryption */
528 case 'N': /* nickname of cert. to use for client auth. */
529 ssl_certname
= strdup( optarg
);
530 if (NULL
== ssl_certname
)
533 exit( LDAP_NO_MEMORY
);
537 #ifndef SOLARIS_LDAP_CMD
538 case 'K': /* location of key database */
539 ssl_keydbpath
= strdup( optarg
);
540 if (NULL
== ssl_keydbpath
)
543 exit( LDAP_NO_MEMORY
);
546 #endif /* SOLARIS_LDAP_CMD */
548 case 'W': /* SSL key password */
549 ssl_passwd
= strdup( optarg
);
550 if (NULL
== ssl_passwd
)
553 exit( LDAP_NO_MEMORY
);
558 #ifndef SOLARIS_LDAP_CMD
559 case '3': /* check hostnames in SSL certificates ("no third") */
560 ssl_strength
= LDAPSSL_AUTH_CNCHECK
;
562 #endif /* SOLARIS_LDAP_CMD */
564 #ifdef LDAP_TOOL_PKCS11
565 case 'm': /* SSL secmod path */
566 ssl_secmodpath
= strdup( optarg
);
567 if (NULL
== ssl_secmodpath
)
570 exit( LDAP_NO_MEMORY
);
574 case 'Q': /* FORTEZZA [card][:personality] */
575 pkcs_token
= strdup(optarg
);
576 if (NULL
== pkcs_token
)
579 exit( LDAP_NO_MEMORY
);
583 /* This option removed to prevent interference
584 with the getEffectiveRights option, also -X
585 case 'X': * path to FORTEZZA CKL file *
587 fortezza_krlfile = strdup( optarg );
592 case 'I': /* FORTEZZA PIN (password file) */
593 ssl_donglefile
= strdup( optarg
);
596 #endif /* LDAP_TOOL_PKCS11 */
599 case 'w': /* bind password */
601 if ( optarg
[0] == '-' && optarg
[1] == '\0' )
604 passwd
= strdup( optarg
);
606 case 'j': /* bind password or SSL key password from file */
608 if ((password_fp
= fopen( optarg
, "r" )) == NULL
) {
609 fprintf(stderr
, gettext("%s: Unable to open '%s' file\n"),
610 ldaptool_progname
, optarg
);
611 exit( LDAP_PARAM_ERROR
);
614 case 'O': /* referral hop limit */
615 refhoplim
= atoi( optarg
);
617 case 'V': /* protocol version */
618 ldversion
= atoi (optarg
);
619 if ( ldversion
!= LDAP_VERSION2
&& ldversion
!= LDAP_VERSION3
) {
620 fprintf( stderr
, gettext("%s: LDAP protocol version %d is not "
621 "supported (use -V%d or -V%d)\n"),
622 ldaptool_progname
, ldversion
, LDAP_VERSION2
,
624 exit( LDAP_PARAM_ERROR
);
627 case 'M': /* send a manageDsaIT control */
628 send_manage_dsait_ctrl
= 1;
631 case 'i': /* character set specified */
632 ldaptool_charset
= strdup( optarg
);
633 if (NULL
== ldaptool_charset
)
636 exit( LDAP_NO_MEMORY
);
640 case 'k': /* conversion directory */
641 ldaptool_convdir
= strdup( optarg
);
642 if (NULL
== ldaptool_convdir
)
645 exit( LDAP_NO_MEMORY
);
648 case 'y': /* old (version 1) proxied authorization control */
649 proxyauth_version
= 1;
650 case 'Y': /* new (version 2 ) proxied authorization control */
652 proxyauth_id
= strdup(optarg
);
653 if (NULL
== proxyauth_id
)
656 exit( LDAP_NO_MEMORY
);
661 #ifndef SOLARIS_LDAP_CMD
662 case '0': /* zero -- override LDAP library version check */
663 break; /* already handled above */
664 #endif /* SOLARIS_LDAP_CMD */
665 case 'J': /* send an arbitrary control */
666 if ( (ctrl_arg
= strdup( optarg
)) == NULL
) {
668 exit (LDAP_NO_MEMORY
);
670 if (ldaptool_parse_ctrl_arg(ctrl_arg
, ':', &ctrl_oid
,
671 &ctrl_criticality
, &ctrl_value
, &vlen
)) {
674 ldctrl
= calloc(1,sizeof(LDAPControl
));
676 rc
= ldaptool_berval_from_ldif_value( ctrl_value
,
677 vlen
, &(ldctrl
->ldctl_value
),
678 1 /* recognize file URLs */,
679 0 /* always try file */,
680 1 /* report errors */ );
681 if ((rc
= ldaptool_fileurlerr2ldaperr( rc
)) != LDAP_SUCCESS
) {
682 fprintf( stderr
, gettext("Unable to parse %s\n"), ctrl_value
);
686 ldctrl
->ldctl_oid
= ctrl_oid
;
687 ldctrl
->ldctl_iscritical
= ctrl_criticality
;
688 ldaptool_add_control_to_array(ldctrl
, ldaptool_request_ctrls
);
690 #ifdef HAVE_SASL_OPTIONS
691 case 'o': /* attribute assignment */
692 if ((rc
= saslSetParam(optarg
)) == -1) {
695 ldapauth
= LDAP_AUTH_SASL
;
696 ldversion
= LDAP_VERSION3
;
698 #endif /* HAVE_SASL_OPTIONS */
700 (*extra_opt_callback
)( i
, optarg
);
705 /* If '-Z' is specified, check if '-P' is specified too. */
708 fprintf( stderr
, gettext("%s: with -N, -W options, please specify -Z\n\n"), ldaptool_progname
);
713 /* if '-N' is specified, -W is needed too */
714 if ( isN
&& NULL
== ssl_passwd
) {
715 fprintf( stderr
, gettext("%s: with the -N option, please specify -W also\n\n"),
720 #ifdef SOLARIS_LDAP_CMD
721 if ( isj
&& ( isw
|| isW
)) {
722 fprintf(stderr
, gettext("%s: -j and -w or -W options cannot be specified simultaneously\n\n"), ldaptool_progname
);
725 fprintf(stderr
, gettext("%s: -j and -w options cannot be specified simultaneously\n\n"), ldaptool_progname
);
726 #endif /* SOLARIS_LDAP_CMD */
730 /* complain if -j or -w does not also have -D, unless using SASL */
731 #ifdef HAVE_SASL_OPTIONS
732 if ( (isj
|| isw
) && !isD
&& ( ldapauth
!= LDAP_AUTH_SASL
) ) {
734 if ( (isj
|| isw
) && !isD
) {
736 fprintf(stderr
, gettext("%s: with -j, -w options, please specify -D\n\n"), ldaptool_progname
);
740 /* use default key and cert DB paths if not set on the command line */
741 if ( NULL
== ssl_keydbpath
) {
742 if ( NULL
== ssl_certdbpath
) {
743 ssl_keydbpath
= LDAPTOOL_DEFKEYDBPATH
;
745 ssl_keydbpath
= certpath2keypath( ssl_certdbpath
);
748 if ( NULL
== ssl_certdbpath
) {
749 ssl_certdbpath
= LDAPTOOL_DEFCERTDBPATH
;
752 if (prompt_password
!= 0) {
753 char *password_string
= "Enter bind password: ";
757 fputs(password_string
,stdout
);
759 if (fgets(pbuf
,256,stdin
) == NULL
) {
764 tmp
= strchr(pbuf
,'\n');
765 if (tmp
) *tmp
= '\0';
766 tmp
= strchr(pbuf
,'\r');
767 if (tmp
) *tmp
= '\0';
768 passwd
= strdup(pbuf
);
772 /* 256 characters on Solaris */
773 passwd
= getpassphrase(password_string
);
775 /* limited to 16 chars on Tru64, 32 on AIX */
776 passwd
= getpass(password_string
);
780 } else if (password_fp
!= NULL
) {
785 /* allocate initial block of memory */
786 if ((linep
= (char *)malloc(BUFSIZ
)) == NULL
) {
787 fprintf( stderr
, gettext("%s: not enough memory to read password from file\n"), ldaptool_progname
);
788 exit( LDAP_NO_MEMORY
);
792 while ((c
= fgetc( password_fp
)) != '\n' && c
!= EOF
) {
794 /* check if we will overflow the buffer */
795 if ((c
!= EOF
) && (index
== ((increment
* BUFSIZ
) -1))) {
797 /* if we did, add another BUFSIZ worth of bytes */
798 if ((linep
= (char *)
799 reallocarray(linep
, increment
+ 1, BUFSIZ
)) == NULL
) {
800 fprintf( stderr
, gettext("%s: not enough memory to read password from file\n"), ldaptool_progname
);
801 exit( LDAP_NO_MEMORY
);
811 #ifdef SOLARIS_LDAP_CMD
812 if (binddn
!= NULL
&& passwd
== NULL
) {
813 char *password_string
= gettext("Enter bind password: ");
814 passwd
= getpassphrase(password_string
);
817 #ifdef HAVE_SASL_OPTIONS
818 if (ldapauth
== LDAP_AUTH_SASL
) {
819 /* BindDN not required for SASL */
820 ldaptool_require_binddn
= 0;
822 #endif /* HAVE_SASL_OPTIONS */
826 /* BindDN not required for SSL */
827 ldaptool_require_binddn
= 0;
831 if (ldaptool_require_binddn
&& binddn
== NULL
&& passwd
== NULL
) {
833 gettext("%s: DN and Bind Password are required.\n"),
837 #endif /* SOLARIS_LDAP_CMD */
840 * If verbose (-v) flag was passed in, display program name and start time.
841 * If the verbose flag was passed at least twice (-vv), also display
842 * information about the API library we are running with.
844 if ( ldaptool_verbose
) {
847 curtime
= time( NULL
);
848 printf( gettext("%s: started %s\n"), ldaptool_progname
, ctime( &curtime
));
849 if ( ldaptool_verbose
> 1 ) {
850 print_library_info( &ldai
, stdout
);
854 #ifdef LDAP_TOOL_PKCS11
855 if ((NULL
!= pkcs_token
) && (NULL
!= ssl_certname
)) {
858 if ( (result
= buildTokenCertName( pkcs_token
, ssl_certname
)) != NULL
){
859 free( ssl_certname
);
860 ssl_certname
= result
;
863 #endif /* LDAP_TOOL_PKCS11 */
868 * Clean up and return index of first non-option argument.
870 if ( ldai
.ldapai_extensions
!= NULL
) {
871 ldap_value_free( ldai
.ldapai_extensions
);
873 if ( ldai
.ldapai_vendor_name
!= NULL
) {
874 ldap_memfree( ldai
.ldapai_vendor_name
);
877 #ifdef HAVE_SASL_OPTIONS
878 if (ldversion
== LDAP_VERSION2
&& ldapauth
== LDAP_AUTH_SASL
) {
879 fprintf( stderr
, gettext("Incompatible with version %d\n"), ldversion
);
882 #endif /* HAVE_SASL_OPTIONS */
888 * Write detailed information about the API library we are running with to fp.
891 print_library_info( const LDAPAPIInfo
*aip
, FILE *fp
)
894 LDAPAPIFeatureInfo fi
;
896 fprintf( fp
, gettext("LDAP Library Information -\n"
897 " Highest supported protocol version: %d\n"
898 " LDAP API revision: %d\n"
899 " API vendor name: %s\n"
900 " Vendor-specific version: %.2f\n"),
901 aip
->ldapai_protocol_version
, aip
->ldapai_api_version
,
902 aip
->ldapai_vendor_name
,
903 (float)aip
->ldapai_vendor_version
/ 100.0 );
905 if ( aip
->ldapai_extensions
!= NULL
) {
906 fputs( gettext(" LDAP API Extensions:\n"), fp
);
908 for ( i
= 0; aip
->ldapai_extensions
[i
] != NULL
; i
++ ) {
909 fprintf( fp
, gettext(" %s"), aip
->ldapai_extensions
[i
] );
910 fi
.ldapaif_info_version
= LDAP_FEATURE_INFO_VERSION
;
911 fi
.ldapaif_name
= aip
->ldapai_extensions
[i
];
912 fi
.ldapaif_version
= 0;
914 if ( ldap_get_option( NULL
, LDAP_OPT_API_FEATURE_INFO
, &fi
)
916 fprintf( fp
, gettext(" %s: ldap_get_option( NULL,"
917 " LDAP_OPT_API_FEATURE_INFO, ... ) for %s failed"
918 " (Feature Info version: %d)\n"), ldaptool_progname
,
919 fi
.ldapaif_name
, fi
.ldapaif_info_version
);
921 fprintf( fp
, gettext(" (revision %d)\n"), fi
.ldapaif_version
);
930 #ifdef LDAP_TOOL_ARGPIN
931 static int PinArgRegistration( void )
934 /* pkcs_init was successful register the pin args */
936 SVRCOREArgPinObj
*ArgPinObj
;
939 SVRCOREStdPinObj
*StdPinObj
;
941 SVRCOREFilePinObj
*FilePinObj
;
942 SVRCOREAltPinObj
*AltPinObj
;
943 SVRCORENTUserPinObj
*NTUserPinObj
;
948 /* Create and register the pin object for PKCS 11 */
949 local_pkcs_fns
.pkcs_getdonglefilename(NULL
, &filename
);
950 local_pkcs_fns
.pkcs_getpin(NULL
, "", &pin
);
952 if ( SVRCORE_CreateStdPinObj(&StdPinObj
, filename
, PR_TRUE
) !=
954 fprintf(stderr
, gettext("Security Initialization: Unable to create PinObj "
955 "(%d)"), PR_GetError());
960 local_pkcs_fns
.pkcs_gettokenname(NULL
, &tokenName
);
961 SVRCORE_CreateArgPinObj(&ArgPinObj
, tokenName
, pin
, (SVRCOREPinObj
*)StdPinObj
);
962 SVRCORE_RegisterPinObj((SVRCOREPinObj
*)ArgPinObj
);
966 SVRCORE_RegisterPinObj((SVRCOREPinObj
*)StdPinObj
);
971 local_pkcs_fns
.pkcs_gettokenname(NULL
, &tokenName
);
972 if ((err
= SVRCORE_CreateNTUserPinObj(&NTUserPinObj
)) != SVRCORE_Success
){
973 fprintf(stderr
, gettext("Security Initialization: Unable to create NTUserPinObj "
974 "(%d)"), PR_GetError());
975 exit( LDAP_LOCAL_ERROR
);
977 if ((err
= SVRCORE_CreateArgPinObj(&ArgPinObj
, tokenName
, pin
,
978 (SVRCOREPinObj
*)NTUserPinObj
)) != SVRCORE_Success
)
980 fprintf(stderr
, gettext("Security Initialization: Unable to create ArgPinObj "
981 "(%d)"), PR_GetError());
985 SVRCORE_RegisterPinObj((SVRCOREPinObj
*)ArgPinObj
);
990 if ((err
= SVRCORE_CreateNTUserPinObj(&NTUserPinObj
)) != SVRCORE_Success
){
991 fprintf(stderr
, gettext("Security Initialization: Unable to create NTUserPinObj "
992 "(%d)"), PR_GetError());
995 if (filename
&& *filename
)
997 if ((err
= SVRCORE_CreateFilePinObj(&FilePinObj
, filename
)) !=
999 fprintf(stderr
, gettext("Security Initialization: Unable to create FilePinObj "
1000 "(%d)"), PR_GetError());
1004 if ((err
= SVRCORE_CreateAltPinObj(&AltPinObj
, (SVRCOREPinObj
*)FilePinObj
,
1005 (SVRCOREPinObj
*)NTUserPinObj
)) != SVRCORE_Success
) {
1006 fprintf(stderr
, gettext("Security Initialization: Unable to create AltPinObj "
1007 "(%d)"), PR_GetError());
1010 SVRCORE_RegisterPinObj((SVRCOREPinObj
*)AltPinObj
);
1014 SVRCORE_RegisterPinObj((SVRCOREPinObj
*)NTUserPinObj
);
1018 return LDAP_SUCCESS
;
1021 #endif /* LDAP_TOOL_ARGPIN */
1025 * initialize and return an LDAP session handle.
1026 * if errors occur, we exit here.
1029 ldaptool_ldap_init( int second_host
)
1033 int port
, rc
, user_port
;
1035 if ( ldaptool_not
) {
1039 if ( second_host
) {
1040 host
= ldaptool_host2
;
1041 port
= ldaptool_port2
;
1042 user_port
= user_specified_port2
;
1044 host
= ldaptool_host
;
1045 port
= ldaptool_port
;
1046 user_port
= user_specified_port
;
1050 if ( ldaptool_verbose
) {
1051 printf( gettext("ldap_init( %s, %d )\n"), host
, port
);
1054 #if defined(NET_SSL)
1056 * Initialize security libraries and databases and LDAP session. If
1057 * ssl_certname is not NULL, then we will attempt to use client auth.
1058 * if the server supports it.
1060 #ifdef LDAP_TOOL_PKCS11
1061 ldaptool_setcallbacks( &local_pkcs_fns
);
1063 if ( !second_host
&& secure
1064 &&(rc
= ldapssl_pkcs_init( &local_pkcs_fns
)) < 0) {
1065 /* secure connection requested -- fail if no SSL */
1066 #ifndef SOLARIS_LDAP_CMD
1067 rc
= PORT_GetError();
1068 #endif /* SOLARIS_LDAP_CMD */
1069 fprintf( stderr
, gettext("SSL initialization failed: error %d (%s)\n"),
1070 rc
, ldapssl_err2string( rc
));
1071 exit( LDAP_LOCAL_ERROR
);
1074 #ifdef LDAP_TOOL_ARGPIN
1076 if (PinArgRegistration( )) {
1077 exit( LDAP_LOCAL_ERROR
);
1080 #endif /* LDAP_TOOL_ARGPIN */
1082 #else /* LDAP_TOOL_PKCS11 */
1083 if ( !second_host
&& secure
1084 &&(rc
= ldapssl_client_init( ssl_certdbpath
, NULL
)) < 0) {
1085 /* secure connection requested -- fail if no SSL */
1086 #ifndef SOLARIS_LDAP_CMD
1087 rc
= PORT_GetError();
1088 #endif /* SOLARIS_LDAP_CMD */
1089 fprintf( stderr
, gettext("SSL initialization failed: error %d (%s)\n"),
1090 rc
, ldapssl_err2string( rc
));
1091 exit( LDAP_LOCAL_ERROR
);
1093 #endif /* LDAP_TOOL_PKCS11 */
1095 /* set the default SSL strength (used for all future ld's we create) */
1096 if ( ldapssl_set_strength( NULL
, ssl_strength
) < 0 ) {
1097 perror( "ldapssl_set_strength" );
1098 exit( LDAP_LOCAL_ERROR
);
1107 if (( ld
= ldapssl_init( host
, port
,
1108 secure
)) != NULL
&& ssl_certname
!= NULL
)
1109 if (ldapssl_enable_clientauth( ld
, ssl_keydbpath
, ssl_passwd
,
1110 ssl_certname
) != 0 ) {
1111 exit ( ldaptool_print_lderror( ld
, "ldapssl_enable_clientauth",
1112 LDAPTOOL_CHECK4SSL_ALWAYS
));
1115 /* In order to support IPv6, we use NSPR I/O */
1116 #ifdef SOLARIS_LDAP_CMD
1117 ld
= ldap_init( host
, port
);
1119 ld
= prldap_init( host
, port
, 0 /* not shared across threads */ );
1120 #endif /* SOLARIS_LDAP_CMD */
1124 /* In order to support IPv6, we use NSPR I/O */
1125 #ifdef SOLARIS_LDAP_CMD
1126 ld
= ldap_init( host
, port
);
1128 ld
= prldap_init( host
, port
, 0 /* not shared across threads */ );
1129 #endif /* SOLARIS_LDAP_CMD */
1130 #endif /* NET_SSL */
1133 perror( "ldap_init" );
1134 exit( LDAP_LOCAL_ERROR
);
1137 #ifndef NO_LIBLCACHE
1138 if ( cache_config_file
!= NULL
) {
1141 if ( lcache_init( ld
, cache_config_file
) != 0 ) {
1142 exit( ldaptool_print_lderror( ld
, cache_config_file
,
1143 LDAPTOOL_CHECK4SSL_NEVER
));
1146 (void) ldap_set_option( ld
, LDAP_OPT_CACHE_ENABLE
, &opt
);
1147 opt
= LDAP_CACHE_LOCALDB
;
1148 (void) ldap_set_option( ld
, LDAP_OPT_CACHE_STRATEGY
, &opt
);
1149 if ( ldversion
== -1 ) { /* not set with -V */
1150 ldversion
= LDAP_VERSION2
; /* local db only supports v2 */
1156 ldap_set_option( ld
, LDAP_OPT_REFERRALS
, chase_referrals
? LDAP_OPT_ON
:
1158 if ( chase_referrals
) {
1159 ldap_set_rebind_proc( ld
, get_rebind_credentials
, NULL
);
1160 ldap_set_option( ld
, LDAP_OPT_REFERRAL_HOP_LIMIT
, &refhoplim
);
1163 if ( ldversion
== -1 ) { /* not set with -V and not using local db */
1164 ldversion
= LDAP_VERSION3
;
1166 ldap_set_option( ld
, LDAP_OPT_PROTOCOL_VERSION
, &ldversion
);
1173 * perform a bind to the LDAP server if needed.
1174 * if an error occurs, we exit here.
1177 ldaptool_bind( LDAP
*ld
)
1181 LDAPControl auth_resp_ctrl
, *ctrl_array
[ 2 ], **bindctrls
;
1182 #ifdef HAVE_SASL_OPTIONS
1186 if ( ldaptool_not
) {
1190 if ( send_auth_response_ctrl
) {
1191 auth_resp_ctrl
.ldctl_oid
= LDAP_CONTROL_AUTH_REQUEST
;
1192 auth_resp_ctrl
.ldctl_value
.bv_val
= NULL
;
1193 auth_resp_ctrl
.ldctl_value
.bv_len
= 0;
1194 auth_resp_ctrl
.ldctl_iscritical
= 0;
1196 ctrl_array
[0] = &auth_resp_ctrl
;
1197 ctrl_array
[1] = NULL
;
1198 bindctrls
= ctrl_array
;
1204 * if using LDAPv3 and not using client auth., omit NULL bind for
1207 if ( ldversion
> LDAP_VERSION2
&& binddn
== NULL
&& passwd
== NULL
1208 && ssl_certname
== NULL
) {
1209 #ifdef HAVE_SASL_OPTIONS
1210 if ( ldapauth
!= LDAP_AUTH_SASL
) {
1219 * do the bind, backing off one LDAP version if necessary
1221 conv
= ldaptool_local2UTF8( binddn
);
1223 #ifdef HAVE_SASL_OPTIONS
1224 if ( ldapauth
== LDAP_AUTH_SASL
) {
1225 if ( sasl_mech
== NULL
) {
1226 fprintf( stderr
, gettext("Please specify the SASL mechanism name when "
1227 "using SASL options\n"));
1231 if ( sasl_secprops
!= NULL
) {
1232 rc
= ldap_set_option( ld
, LDAP_OPT_X_SASL_SECPROPS
,
1233 (void *) sasl_secprops
);
1235 if ( rc
!= LDAP_SUCCESS
) {
1236 fprintf( stderr
, gettext("Unable to set LDAP_OPT_X_SASL_SECPROPS: %s\n"),
1242 defaults
= ldaptool_set_sasl_defaults( ld
, sasl_mech
, sasl_authid
, sasl_username
, passwd
, sasl_realm
);
1243 if (defaults
== NULL
) {
1245 exit (LDAP_NO_MEMORY
);
1248 rc
= ldap_sasl_interactive_bind_s( ld
, binddn
, sasl_mech
, NULL
, NULL
,
1249 sasl_flags
, ldaptool_sasl_interact
, defaults
);
1251 if (rc
!= LDAP_SUCCESS
) {
1252 ldap_perror( ld
, "ldap_sasl_interactive_bind_s" );
1255 #endif /* HAVE_SASL_OPTIONS */
1257 * if using LDAPv3 and client auth., try a SASL EXTERNAL bind
1259 if ( ldversion
> LDAP_VERSION2
&& binddn
== NULL
&& passwd
== NULL
1260 && ssl_certname
!= NULL
) {
1261 rc
= ldaptool_sasl_bind_s( ld
, NULL
, LDAP_SASL_EXTERNAL
, NULL
,
1262 bindctrls
, NULL
, NULL
, "ldap_sasl_bind" );
1265 rc
= ldaptool_simple_bind_s( ld
, conv
, passwd
, bindctrls
, NULL
,
1266 "ldap_simple_bind" );
1269 if ( rc
== LDAP_SUCCESS
) {
1270 if ( conv
!= NULL
) {
1273 return; /* success */
1276 #ifdef HAVE_SASL_OPTIONS
1277 if (ldapauth
!= LDAP_AUTH_SASL
) {
1278 #endif /* HAVE_SASL_OPTIONS */
1279 if ( rc
== LDAP_PROTOCOL_ERROR
&& ldversion
> LDAP_VERSION2
) {
1281 * try again, backing off one LDAP version
1282 * this is okay even for client auth. because the way to achieve
1283 * client auth. with LDAPv2 is to perform a NULL simple bind.
1286 fprintf( stderr
, gettext("%s: the server doesn't understand LDAPv%d;"
1287 " trying LDAPv%d instead...\n"), ldaptool_progname
,
1288 ldversion
+ 1, ldversion
);
1289 ldap_set_option( ld
, LDAP_OPT_PROTOCOL_VERSION
, &ldversion
);
1290 if (( rc
= ldaptool_simple_bind_s( ld
, conv
, passwd
,
1291 bindctrls
, NULL
, "ldap_simple_bind" )) == LDAP_SUCCESS
) {
1293 return; /* a qualified success */
1296 #ifdef HAVE_SASL_OPTIONS
1298 #endif /* HAVE_SASL_OPTIONS */
1300 if ( conv
!= NULL
) {
1305 * bind(s) failed -- fatal error
1313 * close open files, unbind, etc.
1316 ldaptool_cleanup( LDAP
*ld
)
1322 if ( ldaptool_fp
!= NULL
&& ldaptool_fp
!= stdin
) {
1323 fclose( ldaptool_fp
);
1330 * Retrieve and print an LDAP error message. Returns the LDAP error code.
1333 ldaptool_print_lderror( LDAP
*ld
, char *msg
, int check4ssl
)
1335 int lderr
= ldap_get_lderrno( ld
, NULL
, NULL
);
1337 ldap_perror( ld
, msg
);
1338 #ifndef SOLARIS_LDAP_CMD
1339 if ( secure
&& check4ssl
!= LDAPTOOL_CHECK4SSL_NEVER
) {
1340 if ( check4ssl
== LDAPTOOL_CHECK4SSL_ALWAYS
1341 || ( lderr
== LDAP_SERVER_DOWN
)) {
1342 int sslerr
= PORT_GetError();
1344 fprintf( stderr
, gettext("\tSSL error %d (%s)\n"), sslerr
,
1345 ldapssl_err2string( sslerr
));
1348 #endif /* SOLARIS_LDAP_CMD */
1355 * print referrals to stderr
1358 ldaptool_print_referrals( char **refs
)
1362 if ( refs
!= NULL
) {
1363 for ( i
= 0; refs
[ i
] != NULL
; ++i
) {
1364 fprintf( stderr
, gettext("Referral: %s\n"), refs
[ i
] );
1371 * print contents of an extended response to stderr
1372 * this is mainly to support unsolicited notifications
1373 * Returns an LDAP error code (from the extended result).
1376 ldaptool_print_extended_response( LDAP
*ld
, LDAPMessage
*res
, char *msg
)
1379 struct berval
*data
;
1381 if ( ldap_parse_extended_result( ld
, res
, &oid
, &data
, 0 )
1383 ldaptool_print_lderror( ld
, msg
, LDAPTOOL_CHECK4SSL_IF_APPROP
);
1385 if ( oid
!= NULL
) {
1386 if ( strcmp ( oid
, LDAP_NOTICE_OF_DISCONNECTION
) == 0 ) {
1387 fprintf( stderr
, gettext("%s: Notice of Disconnection\n"), msg
);
1389 fprintf( stderr
, gettext("%s: OID %s\n"), msg
, oid
);
1391 ldap_memfree( oid
);
1393 fprintf( stderr
, gettext("%s: missing OID\n"), msg
);
1396 if ( data
!= NULL
) {
1397 fprintf( stderr
, gettext("%s: Data (length %ld):\n"), msg
, data
->bv_len
);
1399 /* XXXmcs: maybe we should display the actual data? */
1400 lber_bprint( data
->bv_val
, data
->bv_len
);
1406 return parse_result( ld
, res
, NULL
, msg
, 1 );
1411 * Like ldap_sasl_bind_s() but calls wait4result() to display
1412 * any referrals returned and report errors in a consistent way.
1415 ldaptool_sasl_bind_s( LDAP
*ld
, const char *dn
, const char *mechanism
,
1416 const struct berval
*cred
, LDAPControl
**serverctrls
,
1417 LDAPControl
**clientctrls
, struct berval
**servercredp
, char *msg
)
1421 if ( servercredp
!= NULL
) {
1422 *servercredp
= NULL
;
1425 if (( rc
= ldap_sasl_bind( ld
, dn
, mechanism
, cred
, serverctrls
,
1426 clientctrls
, &msgid
)) != LDAP_SUCCESS
) {
1427 ldaptool_print_lderror( ld
, msg
, LDAPTOOL_CHECK4SSL_IF_APPROP
);
1429 rc
= wait4result( ld
, msgid
, servercredp
, msg
);
1437 * Like ldap_simple_bind_s() but calls wait4result() to display
1438 * any referrals returned and report errors in a consistent way.
1441 ldaptool_simple_bind_s( LDAP
*ld
, const char *dn
, const char *passwd
,
1442 LDAPControl
**serverctrls
, LDAPControl
**clientctrls
, char *msg
)
1446 bv
.bv_val
= (char *)passwd
; /* XXXmcs: had to cast away const */
1447 bv
.bv_len
= ( passwd
== NULL
? 0 : strlen( passwd
));
1448 return( ldaptool_sasl_bind_s( ld
, dn
, LDAP_SASL_SIMPLE
, &bv
, serverctrls
,
1449 clientctrls
, NULL
, msg
));
1454 * Like ldap_add_ext_s() but calls wait4result() to display
1455 * any referrals returned and report errors in a consistent way.
1458 ldaptool_add_ext_s( LDAP
*ld
, const char *dn
, LDAPMod
**attrs
,
1459 LDAPControl
**serverctrls
, LDAPControl
**clientctrls
, char *msg
)
1463 if (( rc
= ldap_add_ext( ld
, dn
, attrs
, serverctrls
, clientctrls
, &msgid
))
1465 ldaptool_print_lderror( ld
, msg
, LDAPTOOL_CHECK4SSL_IF_APPROP
);
1468 * 25-April-2000 Note: the next line used to read:
1469 * rc = wait4result( ld, msgid, NULL, msg );
1470 * 'msgid' it was changed to 'LDAP_RES_ANY' in order to receive
1471 * unsolicited notifications.
1473 rc
= wait4result( ld
, LDAP_RES_ANY
, NULL
, msg
);
1481 * Like ldap_modify_ext_s() but calls wait4result() to display
1482 * any referrals returned and report errors in a consistent way.
1485 ldaptool_modify_ext_s( LDAP
*ld
, const char *dn
, LDAPMod
**mods
,
1486 LDAPControl
**serverctrls
, LDAPControl
**clientctrls
, char *msg
)
1490 if (( rc
= ldap_modify_ext( ld
, dn
, mods
, serverctrls
, clientctrls
,
1491 &msgid
)) != LDAP_SUCCESS
) {
1492 ldaptool_print_lderror( ld
, msg
, LDAPTOOL_CHECK4SSL_IF_APPROP
);
1494 rc
= wait4result( ld
, msgid
, NULL
, msg
);
1502 * Like ldap_delete_ext_s() but calls wait4result() to display
1503 * any referrals returned and report errors in a consistent way.
1506 ldaptool_delete_ext_s( LDAP
*ld
, const char *dn
, LDAPControl
**serverctrls
,
1507 LDAPControl
**clientctrls
, char *msg
)
1511 if (( rc
= ldap_delete_ext( ld
, dn
, serverctrls
, clientctrls
, &msgid
))
1513 ldaptool_print_lderror( ld
, msg
, LDAPTOOL_CHECK4SSL_IF_APPROP
);
1515 rc
= wait4result( ld
, msgid
, NULL
, msg
);
1523 * Like ldap_compare_ext_s() but calls wait4result() to display
1524 * any referrals returned and report errors in a consistent way.
1526 int ldaptool_compare_ext_s( LDAP
*ld
, const char *dn
, const char *attrtype
,
1527 const struct berval
*bvalue
, LDAPControl
**serverctrls
,
1528 LDAPControl
**clientctrls
, char *msg
)
1532 if (( rc
= ldap_compare_ext( ld
, dn
, attrtype
, bvalue
, serverctrls
,
1533 clientctrls
, &msgid
)) != LDAP_SUCCESS
) {
1534 ldaptool_print_lderror( ld
, msg
, LDAPTOOL_CHECK4SSL_IF_APPROP
);
1536 rc
= wait4result( ld
, msgid
, NULL
, msg
);
1544 * Like ldap_rename_s() but calls wait4result() to display
1545 * any referrals returned and report errors in a consistent way.
1548 ldaptool_rename_s( LDAP
*ld
, const char *dn
, const char *newrdn
,
1549 const char *newparent
, int deleteoldrdn
, LDAPControl
**serverctrls
,
1550 LDAPControl
**clientctrls
, char *msg
)
1554 if (( rc
= ldap_rename( ld
, dn
, newrdn
, newparent
, deleteoldrdn
,
1555 serverctrls
, clientctrls
, &msgid
)) != LDAP_SUCCESS
) {
1556 ldaptool_print_lderror( ld
, msg
, LDAPTOOL_CHECK4SSL_IF_APPROP
);
1558 rc
= wait4result( ld
, msgid
, NULL
, msg
);
1566 * Wait for a result, check for and display errors and referrals.
1567 * Also recognize and display "Unsolicited notification" messages.
1568 * Returns an LDAP error code.
1571 wait4result( LDAP
*ld
, int msgid
, struct berval
**servercredp
, char *msg
)
1574 int rc
, received_only_unsolicited
= 1;
1576 while ( received_only_unsolicited
) {
1578 if (( rc
= ldap_result( ld
, msgid
, 1, NULL
, &res
))
1580 ldaptool_print_lderror( ld
, msg
, LDAPTOOL_CHECK4SSL_IF_APPROP
);
1581 return( ldap_get_lderrno( ld
, NULL
, NULL
));
1585 * Special handling for unsolicited notifications:
1586 * 1. Parse and display contents.
1587 * 2. go back and wait for another (real) result.
1589 if ( rc
== LDAP_RES_EXTENDED
1590 && ldap_msgid( res
) == LDAP_RES_UNSOLICITED
) {
1591 rc
= ldaptool_print_extended_response( ld
, res
,
1592 "Unsolicited response" );
1594 rc
= parse_result( ld
, res
, servercredp
, msg
, 1 );
1595 received_only_unsolicited
= 0; /* we're done */
1604 parse_result( LDAP
*ld
, LDAPMessage
*res
, struct berval
**servercredp
,
1605 char *msg
, int freeit
)
1607 int rc
, lderr
, errno
;
1608 int pw_days
=0, pw_hrs
=0, pw_mins
=0, pw_secs
=0; /* for pwpolicy */
1610 LDAPControl
**ctrls
;
1612 if (( rc
= ldap_parse_result( ld
, res
, &lderr
, NULL
, NULL
, &refs
,
1613 &ctrls
, 0 )) != LDAP_SUCCESS
) {
1614 ldaptool_print_lderror( ld
, msg
, LDAPTOOL_CHECK4SSL_IF_APPROP
);
1615 ldap_msgfree( res
);
1619 /* check for authentication response control & PWPOLICY control*/
1620 if ( NULL
!= ctrls
) {
1624 for ( i
= 0; NULL
!= ctrls
[i
]; ++i
) {
1625 if ( 0 == strcmp( ctrls
[i
]->ldctl_oid
,
1626 LDAP_CONTROL_AUTH_RESPONSE
)) {
1627 s
= ctrls
[i
]->ldctl_value
.bv_val
;
1630 } else if ( *s
== '\0' ) {
1633 fprintf( stderr
, gettext("%s: bound as %s\n"), ldaptool_progname
, s
);
1636 if ( 0 == strcmp( ctrls
[i
]->ldctl_oid
,
1637 LDAP_CONTROL_PWEXPIRING
)) {
1639 /* Warn the user that their passwd is to expire */
1641 pw_secs
= atoi(ctrls
[i
]->ldctl_value
.bv_val
);
1642 if ( pw_secs
> 0 && errno
!= ERANGE
) {
1643 if ( pw_secs
> 86400 ) {
1644 pw_days
= ( pw_secs
/ 86400 );
1645 pw_secs
= ( pw_secs
% 86400 );
1647 if ( pw_secs
> 3600 ) {
1648 pw_hrs
= ( pw_secs
/ 3600 );
1649 pw_secs
= ( pw_secs
% 3600 );
1651 if ( pw_secs
> 60 ) {
1652 pw_mins
= ( pw_secs
/ 60 );
1653 pw_secs
= ( pw_secs
% 60 );
1656 printf(gettext("%s: Warning ! Your password will expire after "), ldaptool_progname
);
1658 printf (gettext("%d days, "), pw_days
);
1661 printf (gettext("%d hrs, "), pw_hrs
);
1664 printf (gettext("%d mins, "), pw_mins
);
1666 printf(gettext("%d seconds.\n"), pw_secs
);
1671 ldap_controls_free( ctrls
);
1674 if ( servercredp
!= NULL
&& ( rc
= ldap_parse_sasl_bind_result( ld
, res
,
1675 servercredp
, 0 )) != LDAP_SUCCESS
) {
1676 ldaptool_print_lderror( ld
, msg
, LDAPTOOL_CHECK4SSL_IF_APPROP
);
1677 ldap_msgfree( res
);
1682 ldap_msgfree( res
);
1685 if ( LDAPTOOL_RESULT_IS_AN_ERROR( lderr
)) {
1686 ldaptool_print_lderror( ld
, msg
, LDAPTOOL_CHECK4SSL_IF_APPROP
);
1689 if ( refs
!= NULL
) {
1690 ldaptool_print_referrals( refs
);
1691 ldap_value_free( refs
);
1699 * if -M was passed on the command line, create and return a "Manage DSA IT"
1700 * LDAPv3 control. If not, return NULL.
1703 ldaptool_create_manage_dsait_control( void )
1707 if ( !send_manage_dsait_ctrl
) {
1711 if (( ctl
= (LDAPControl
*)calloc( 1, sizeof( LDAPControl
))) == NULL
||
1712 ( ctl
->ldctl_oid
= strdup( LDAP_CONTROL_MANAGEDSAIT
)) == NULL
) {
1714 exit( LDAP_NO_MEMORY
);
1717 ctl
->ldctl_iscritical
= 1;
1723 * if -y "dn" was supplied on the command line, create the control
1726 ldaptool_create_proxyauth_control( LDAP
*ld
)
1728 LDAPControl
*ctl
= NULL
;
1735 if ( 2 == proxyauth_version
) {
1736 rc
= ldap_create_proxiedauth_control( ld
, proxyauth_id
, &ctl
);
1738 rc
= ldap_create_proxyauth_control( ld
, proxyauth_id
, 1, &ctl
);
1740 if ( rc
!= LDAP_SUCCESS
)
1743 ldap_control_free( ctl
);
1749 #ifndef SOLARIS_LDAP_CMD
1751 ldaptool_create_geteffectiveRights_control ( LDAP
*ld
, const char *authzid
,
1752 const char **attrlist
)
1754 LDAPControl
*ctl
= NULL
;
1757 rc
= ldap_create_geteffectiveRights_control( ld
, authzid
, attrlist
, 1,
1760 if ( rc
!= LDAP_SUCCESS
)
1763 ldap_control_free( ctl
);
1768 #endif /* SOLARIS_LDAP_CMD */
1772 ldaptool_add_control_to_array( LDAPControl
*ctrl
, LDAPControl
**array
)
1776 for (i
=0; i
< CONTROL_REQUESTS
; i
++)
1778 if (*(array
+ i
) == NULL
)
1780 *(array
+ i
+1) = NULL
;
1781 *(array
+ i
) = ctrl
;
1785 fprintf(stderr
, gettext("%s: failed to store request control!!!!!!\n"),
1790 * Dispose of all controls in array and prepare array for reuse.
1793 ldaptool_reset_control_array( LDAPControl
**array
)
1797 for ( i
= 0; i
< CONTROL_REQUESTS
; i
++ ) {
1798 if ( array
[i
] != NULL
) {
1799 ldap_control_free( array
[i
] );
1806 * This function calculates control value and its length. *value can
1807 * be pointing to plain value, ":b64encoded value" or "<fileurl".
1810 calculate_ctrl_value( const char *value
,
1811 char **ctrl_value
, int *vlen
)
1814 if (*value
== ':') {
1820 *ctrl_value
= (char *)value
;
1823 if (( *vlen
= ldif_base64_decode( (char *)value
,
1824 (unsigned char *)value
)) < 0 ) {
1826 gettext("Unable to decode base64 control value \"%s\"\n"), value
);
1830 *vlen
= (int)strlen(*ctrl_value
);
1836 * Parse the optarg from -J option of ldapsearch
1837 * and within LDIFfile for ldapmodify. Take ctrl_arg
1838 * (the whole string) and divide it into oid, criticality
1839 * and value. This function breaks down original ctrl_arg
1840 * with '\0' in places. Also, calculate length of valuestring.
1843 ldaptool_parse_ctrl_arg(char *ctrl_arg
, char sep
,
1844 char **ctrl_oid
, int *ctrl_criticality
,
1845 char **ctrl_value
, int *vlen
)
1850 /* Initialize passed variables with default values */
1851 *ctrl_oid
= *ctrl_value
= NULL
;
1852 *ctrl_criticality
= 0;
1855 strict
= (sep
== ' ' ? 1 : 0);
1856 if(!(s
=strchr(ctrl_arg
, sep
))) {
1857 /* Possible values of ctrl_arg are
1858 * oid[:value|::b64value|:<fileurl] within LDIF, i.e. sep=' '
1859 * oid from command line option, i.e. sep=':'
1862 if (!(s
=strchr(ctrl_arg
, ':'))) {
1863 *ctrl_oid
= ctrl_arg
;
1866 /* ctrl_arg is of oid:[value|:b64value|<fileurl]
1867 * form in the LDIF record. So, grab the oid and then
1868 * jump to continue the parsing of ctrl_arg.
1869 * 's' is pointing just after oid ends.
1872 *ctrl_oid
= ctrl_arg
;
1873 return (calculate_ctrl_value( s
, ctrl_value
, vlen
));
1876 /* oid - from command line option, i.e. sep=':' */
1877 *ctrl_oid
= ctrl_arg
;
1881 /* Possible values of ctrl_arg are
1882 * oid:criticality[:value|::b64value|:<fileurl] - command line
1883 * oid criticality[:value|::b64value|:<fileurl] - LDIF
1884 * And 's' is pointing just after oid ends.
1887 if (*(s
+1) == '\0') {
1888 fprintf( stderr
, gettext("missing value\n") );
1892 *ctrl_oid
= ctrl_arg
;
1894 if(!(s
=strchr(p
, ':'))) {
1895 if ( (*ctrl_criticality
= ldaptool_boolean_str2value(p
, strict
))
1897 fprintf( stderr
, gettext("Invalid criticality value\n") );
1902 if (*(s
+1) == '\0') {
1903 fprintf( stderr
, gettext("missing value\n") );
1907 if ( (*ctrl_criticality
= ldaptool_boolean_str2value(p
, strict
))
1909 fprintf( stderr
, gettext("Invalid criticality value\n") );
1912 return (calculate_ctrl_value( s
, ctrl_value
, vlen
));
1921 * callback function for LDAP bind credentials
1926 get_rebind_credentials( LDAP
*ld
, char **whop
, char **credp
,
1927 int *methodp
, int freeit
, void* arg
)
1932 *methodp
= LDAP_AUTH_SIMPLE
;
1935 return( LDAP_SUCCESS
);
1940 * return pointer to pathname to temporary directory.
1941 * First we see if the environment variable "TEMP" is set and use it.
1942 * Then we see if the environment variable "TMP" is set and use it.
1943 * If this fails, we use "/tmp" on UNIX and fail on Windows.
1946 ldaptool_get_tmp_dir( void )
1951 if (( p
= getenv( "TEMP" )) == NULL
&& ( p
= getenv( "TMP" )) == NULL
) {
1953 fprintf( stderr
, gettext("%s: please set the TEMP environment variable.\n"),
1954 ldaptool_progname
);
1955 exit( LDAP_LOCAL_ERROR
);
1957 return( "/tmp" ); /* last resort on UNIX */
1962 * remove trailing slash if present
1964 offset
= strlen( p
) - 1;
1965 if ( p
[offset
] == '/'
1967 || p
[offset
] == '\\'
1970 if (( p
= strdup( p
)) == NULL
) {
1972 exit( LDAP_NO_MEMORY
);
1983 ldaptool_berval_is_ascii( const struct berval
*bvp
)
1986 int is_ascii
= 1; /* optimistic */
1988 for ( j
= 0; j
< bvp
->bv_len
; ++j
) {
1989 if ( !isascii( bvp
->bv_val
[ j
] )) {
1999 #ifdef LDAP_DEBUG_MEMORY
2000 #define LDAPTOOL_ALLOC_FREED 0xF001
2001 #define LDAPTOOL_ALLOC_INUSE 0xF002
2004 ldaptool_debug_alloc( void *ptr
, size_t size
)
2009 if ( ptr
== NULL
) {
2012 systemptr
= (void *)((char *)ptr
- sizeof(int));
2015 if (( statusp
= (int *)realloc( systemptr
, size
+ sizeof(int))) == NULL
) {
2016 fprintf( stderr
, gettext("%s: realloc( 0x%x, %d) failed\n"),
2017 ldaptool_progname
, systemptr
, size
);
2021 *statusp
= LDAPTOOL_ALLOC_INUSE
;
2023 return( (char *)statusp
+ sizeof(int));
2028 ldaptool_debug_realloc( void *ptr
, size_t size
)
2032 if ( ldaptool_dbg_lvl
& LDAP_DEBUG_TRACE
) {
2033 fprintf( stderr
, gettext("%s: => realloc( 0x%x, %d )\n"),
2034 ldaptool_progname
, ptr
, size
);
2037 p
= ldaptool_debug_alloc( ptr
, size
);
2039 if ( ldaptool_dbg_lvl
& LDAP_DEBUG_TRACE
) {
2040 fprintf( stderr
, gettext("%s: 0x%x <= realloc()\n"), ldaptool_progname
, p
);
2048 ldaptool_debug_malloc( size_t size
)
2052 if ( ldaptool_dbg_lvl
& LDAP_DEBUG_TRACE
) {
2053 fprintf( stderr
, gettext("%s: => malloc( %d)\n"), ldaptool_progname
, size
);
2056 p
= ldaptool_debug_alloc( NULL
, size
);
2058 if ( ldaptool_dbg_lvl
& LDAP_DEBUG_TRACE
) {
2059 fprintf( stderr
, gettext("%s: 0x%x <= malloc()\n"), ldaptool_progname
, p
);
2067 ldaptool_debug_calloc( size_t nelem
, size_t elsize
)
2071 if ( ldaptool_dbg_lvl
& LDAP_DEBUG_TRACE
) {
2072 fprintf( stderr
, gettext("%s: => calloc( %d, %d )\n"),
2073 ldaptool_progname
, nelem
, elsize
);
2076 if (( p
= ldaptool_debug_alloc( NULL
, nelem
* elsize
)) != NULL
) {
2077 memset( p
, 0, nelem
* elsize
);
2080 if ( ldaptool_dbg_lvl
& LDAP_DEBUG_TRACE
) {
2081 fprintf( stderr
, gettext("%s: 0x%x <= calloc()\n"), ldaptool_progname
, p
);
2089 ldaptool_debug_free( void *ptr
)
2091 int *statusp
= (int *)((char *)ptr
- sizeof(int));
2093 if ( ldaptool_dbg_lvl
& LDAP_DEBUG_TRACE
) {
2094 fprintf( stderr
, gettext("%s: => free( 0x%x )\n"), ldaptool_progname
, ptr
);
2097 if ( ptr
== NULL
) {
2098 fprintf( stderr
, gettext("%s: bad free( 0x0 ) attempted (NULL pointer)\n"),
2099 ldaptool_progname
);
2100 } else if ( *statusp
!= LDAPTOOL_ALLOC_INUSE
) {
2101 fprintf( stderr
, gettext("%s: bad free( 0x%x ) attempted"
2102 " (block not in use; status is %d)\n"),
2103 ldaptool_progname
, ptr
, *statusp
);
2105 *statusp
= LDAPTOOL_ALLOC_FREED
;
2109 #endif /* LDAP_DEBUG_MEMORY */
2112 #if defined(NET_SSL)
2114 * Derive key database path from certificate database path and return a
2117 * We just return an exact copy of "certdbpath" unless it ends in "cert.db",
2118 * "cert5.db", or "cert7.db". In those cases we strip off everything from
2119 * "cert" on and append "key.db", "key5.db", or "key3.db" as appropriate.
2120 * Strangely enough cert7.db and key3.db go together.
2123 certpath2keypath( char *certdbpath
)
2125 char *keydbpath
, *appendstr
;
2128 if ( certdbpath
== NULL
) {
2132 if (( keydbpath
= strdup( certdbpath
)) == NULL
) {
2134 exit( LDAP_NO_MEMORY
);
2137 len
= strlen( keydbpath
);
2139 strcasecmp( "cert.db", keydbpath
+ len
- 7 ) == 0 ) {
2141 appendstr
= "key.db";
2143 } else if ( len
> 8 &&
2144 strcasecmp( "cert5.db", keydbpath
+ len
- 8 ) == 0 ) {
2146 appendstr
= "key5.db";
2147 } else if ( len
> 8 &&
2148 strcasecmp( "cert7.db", keydbpath
+ len
- 8 ) == 0 ) {
2150 appendstr
= "key3.db";
2155 if ( striplen
> 0 ) {
2157 * The following code assumes that strlen( appendstr ) < striplen!
2159 strcpy( keydbpath
+ len
- striplen
, appendstr
);
2162 return( keydbpath
);
2165 #ifdef LDAP_TOOL_PKCS11
2168 buildTokenCertName( const char *tokenName
, const char *certName
)
2171 int tokenlen
= strlen(tokenName
);
2172 int len
= tokenlen
+ strlen(certName
) +2;
2175 if (( result
= malloc( len
)) != NULL
) {
2176 strcpy(result
, tokenName
);
2177 *(result
+tokenlen
) = ':';
2179 strcpy(result
+tokenlen
, certName
);
2182 exit( LDAP_NO_MEMORY
);
2191 ldaptool_getcertpath( void *context
, char **certlocp
)
2194 *certlocp
= ssl_certdbpath
;
2195 if ( ldaptool_verbose
) {
2198 printf(gettext("ldaptool_getcertpath -- %s\n"), ssl_certdbpath
);
2202 printf(gettext("ldaptool_getcertpath -- (null)\n"));
2206 return LDAP_SUCCESS
;
2210 ldaptool_getcertname( void *context
, char **certnamep
)
2213 *certnamep
= ssl_certname
;
2214 if ( ldaptool_verbose
) {
2217 printf(gettext("ldaptool_getcertname -- %s\n"), *certnamep
);
2221 printf(gettext("ldaptool_getcertname -- (null)\n"));
2224 return LDAP_SUCCESS
;
2228 ldaptool_getkeypath(void *context
, char **keylocp
)
2230 *keylocp
= ssl_keydbpath
;
2231 if ( ldaptool_verbose
) {
2234 printf(gettext("ldaptool_getkeypath -- %s\n"),*keylocp
);
2238 printf(gettext("ldaptool_getkeypath -- (null)\n"));
2242 return LDAP_SUCCESS
;
2246 ldaptool_gettokenname( void *context
, char **tokennamep
)
2249 *tokennamep
= pkcs_token
;
2250 if ( ldaptool_verbose
) {
2253 printf(gettext("ldaptool_gettokenname -- %s\n"),*tokennamep
);
2257 printf(gettext("ldaptool_gettokenname -- (null)\n"));
2261 return LDAP_SUCCESS
;
2264 ldaptool_gettokenpin( void *context
, const char *tokennamep
, char **tokenpinp
)
2271 /* XXXceb this stuff is removed for the time being.
2272 * This function should return the pin from ssl_password
2276 *tokenpinp
= ssl_passwd
;
2277 return LDAP_SUCCESS
;
2281 ldaptool_gettokenname( NULL
, &localtoken
);
2283 if (strcmp( localtoken
, tokennamep
))
2285 *tokenpinp
= pkcs_pin
;
2289 if ( ldaptool_verbose
) {
2292 printf(gettext("ldaptool_getokenpin --%s\n"), tokenpinp
);
2296 printf(gettext("ldaptool_getokenpin -- (null)\n"));
2299 return LDAP_SUCCESS
;
2304 ldaptool_getmodpath( void *context
, char **modulep
)
2306 *modulep
= ssl_secmodpath
;
2307 if ( ldaptool_verbose
) {
2310 printf(gettext("ldaptool_getmodpath -- %s\n"), *modulep
);
2314 printf(gettext("ldaptool_getmodpath -- (null)\n"));
2318 return LDAP_SUCCESS
;
2322 ldaptool_getdonglefilename( void *context
, char **filename
)
2324 *filename
= ssl_donglefile
;
2325 if ( ldaptool_verbose
) {
2328 printf(gettext("ldaptool_getdonglefilename -- %s\n"), *filename
);
2332 printf(gettext("ldaptool_getdonglefilename -- (null)\n"));
2337 return LDAP_SUCCESS
;
2341 ldaptool_setcallbacks( struct ldapssl_pkcs_fns
*pfns
)
2343 pfns
->pkcs_getcertpath
= (int (*)(void *, char **))ldaptool_getcertpath
;
2344 pfns
->pkcs_getcertname
= (int (*)(void *, char **))ldaptool_getcertname
;
2345 pfns
->pkcs_getkeypath
= (int (*)(void *, char **)) ldaptool_getkeypath
;
2346 pfns
->pkcs_getmodpath
= (int (*)(void *, char **)) ldaptool_getmodpath
;
2347 pfns
->pkcs_getpin
= (int (*)(void *, const char*, char **)) ldaptool_gettokenpin
;
2348 pfns
->pkcs_gettokenname
= (int (*)(void *, char **)) ldaptool_gettokenname
;
2349 pfns
->pkcs_getdonglefilename
= (int (*)(void *, char **)) ldaptool_getdonglefilename
;
2350 pfns
->local_structure_id
=PKCS_STRUCTURE_ID
;
2351 return LDAP_SUCCESS
;
2358 ldaptool_fortezza_init( int exit_on_error
)
2362 if ( fortezza_personality
== NULL
&& fortezza_cardmask
== 0 ) { /* no FORTEZZA desired */
2363 SSL_EnableGroup( SSL_GroupFortezza
, DSFalse
); /* disable FORTEZZA */
2367 if (( rc
= FortezzaConfigureServer( ldaptool_fortezza_getpin
, fortezza_cardmask
,
2368 fortezza_personality
, ldaptool_fortezza_alert
, NULL
, &errcode
,
2369 fortezza_krlfile
)) < 0 ) {
2371 "%s: FORTEZZA initialization failed (error %d - %s)\n",
2372 ldaptool_progname
, errcode
,
2373 ldaptool_fortezza_err2string( errcode
));
2374 if ( exit_on_error
) {
2375 exit( LDAP_LOCAL_ERROR
);
2378 SSL_EnableGroup( SSL_GroupFortezza
, DSFalse
); /* disable FORTEZZA */
2382 SSL_EnableGroup( SSL_GroupFortezza
, DSTrue
); /* enable FORTEZZA */
2388 ldaptool_fortezza_alert( void *arg
, PRBool onOpen
, char *string
,
2389 int value1
, void *value2
)
2391 fprintf( stderr
, "%s: FORTEZZA alert: ", ldaptool_progname
);
2392 fprintf( stderr
, string
, value1
, value2
);
2393 fprintf( stderr
, "\n" );
2399 ldaptool_fortezza_getpin( char **passwordp
)
2401 *passwordp
= fortezza_pin
;
2402 return( *passwordp
);
2407 * convert a Fortezza error code (as returned by FortezzaConfigureServer()
2408 * into a human-readable string.
2410 * Error strings are intentionally similar to those found in
2411 * ns/netsite/lib/libadmin/httpcon.c
2414 ldaptool_fortezza_err2string( int err
)
2419 case FORTEZZA_BADPASSWD
:
2420 s
= "invalid pin number";
2422 case FORTEZZA_BADCARD
:
2423 s
= "bad or missing card";
2425 case FORTEZZA_MISSING_KRL
:
2426 s
= "bad or missing compromised key list";
2428 case FORTEZZA_CERT_INIT_ERROR
:
2429 s
= "unable to initialize certificate cache. either a cert on "
2430 "the card is bad, or an old FORTEZZA certificate is in a"
2431 "readonly database";
2433 case FORTEZZA_EXPIRED_CERT
:
2434 s
= "unable to verify certificate";
2437 s
= "unknown error";
2443 #endif /* FORTEZZA */
2444 #endif /* LDAP_TOOL_PKCS11 */
2445 #endif /* NET_SSL */
2448 ldaptool_boolean_str2value ( const char *ptr
, int strict
)
2451 if ( !(strcasecmp(ptr
, "true"))) {
2454 else if ( !(strcasecmp(ptr
, "false"))) {
2462 if ( !(strcasecmp(ptr
, "true")) ||
2463 !(strcasecmp(ptr
, "t")) ||
2464 !(strcmp(ptr
, "1")) ) {
2467 else if ( !(strcasecmp(ptr
, "false")) ||
2468 !(strcasecmp(ptr
, "f")) ||
2469 !(strcmp(ptr
, "0")) ) {
2479 ldaptool_open_file(const char *filename
, const char *mode
)
2481 #ifdef _LARGEFILE64_SOURCE
2482 return fopen64(filename
, mode
);
2484 return fopen(filename
, mode
);
2489 /* Functions for list in ldapdelete.c */
2491 void L_Init(Head
*list
)
2501 void L_Insert(Element
*Node
, Head
*HeadNode
)
2503 if (!Node
|| !HeadNode
)
2508 if (HeadNode
->first
== NULL
)
2511 HeadNode
->last
= HeadNode
->first
= Node
;
2515 Node
->left
= HeadNode
->last
;
2516 HeadNode
->last
= Node
->left
->right
= Node
;
2521 void L_Remove(Element
*Node
, Head
*HeadNode
)
2523 Element
*traverse
= NULL
;
2524 Element
*prevnode
= NULL
;
2526 if(!Node
|| !HeadNode
)
2529 for(traverse
= HeadNode
->first
; traverse
; traverse
= traverse
->right
)
2531 if(traverse
== Node
)
2533 if(HeadNode
->first
== traverse
)
2535 HeadNode
->first
= traverse
->right
;
2537 if(HeadNode
->last
== traverse
)
2539 HeadNode
->last
= prevnode
;
2541 traverse
= traverse
->right
;
2542 if(prevnode
!= NULL
)
2544 prevnode
->right
= traverse
;
2546 if(traverse
!= NULL
)
2548 traverse
->left
= prevnode
;
2553 else /* traverse != node */
2555 prevnode
= traverse
;
2561 #ifdef HAVE_SASL_OPTIONS
2563 * Function checks for valid args, returns an error if not found
2564 * and sets SASL params from command line
2568 saslSetParam(char *saslarg
)
2572 attr
= strchr(saslarg
, '=');
2574 fprintf( stderr
, gettext("Didn't find \"=\" character in %s\n"), saslarg
);
2580 if (!strcasecmp(saslarg
, "secProp")) {
2581 if ( sasl_secprops
!= NULL
) {
2582 fprintf( stderr
, gettext("secProp previously specified\n"));
2585 if (( sasl_secprops
= strdup(attr
)) == NULL
) {
2587 exit (LDAP_NO_MEMORY
);
2589 } else if (!strcasecmp(saslarg
, "realm")) {
2590 if ( sasl_realm
!= NULL
) {
2591 fprintf( stderr
, gettext("Realm previously specified\n"));
2594 if (( sasl_realm
= strdup(attr
)) == NULL
) {
2596 exit (LDAP_NO_MEMORY
);
2598 } else if (!strcasecmp(saslarg
, "authzid")) {
2599 if (sasl_username
!= NULL
) {
2600 fprintf( stderr
, gettext("Authorization name previously specified\n"));
2603 if (( sasl_username
= strdup(attr
)) == NULL
) {
2605 exit (LDAP_NO_MEMORY
);
2607 } else if (!strcasecmp(saslarg
, "authid")) {
2608 if ( sasl_authid
!= NULL
) {
2609 fprintf( stderr
, gettext("Authentication name previously specified\n"));
2612 if (( sasl_authid
= strdup(attr
)) == NULL
) {
2614 exit (LDAP_NO_MEMORY
);
2616 } else if (!strcasecmp(saslarg
, "mech")) {
2617 if ( sasl_mech
!= NULL
) {
2618 fprintf( stderr
, gettext("Mech previously specified\n"));
2621 if (( sasl_mech
= strdup(attr
)) == NULL
) {
2623 exit (LDAP_NO_MEMORY
);
2626 fprintf (stderr
, gettext("Invalid attribute name %s\n"), saslarg
);
2631 #endif /* HAVE_SASL_OPTIONS */
2634 * check for and report input or output error on named stream
2635 * return ldap_err or ferror() (ldap_err takes precedence)
2636 * assume that fflush() already has been called if needed.
2637 * don't want to fflush() an input stream.
2640 ldaptool_check_ferror(FILE * stream
, const int ldap_err
, const char *msg
)
2643 if ((err
= ferror(stream
)) != 0 ) {
2644 fprintf(stderr
, gettext("%s: ERROR: "), ldaptool_progname
);
2646 err
= LDAP_LOCAL_ERROR
;
2650 * reporting LDAP error code is more important than
2651 * reporting errors from ferror()
2653 if (ldap_err
== LDAP_SUCCESS
) {