xref: /illumos-gate/usr/src/cmd/ldap/common/common.c (revision b232a944)
17c478bd9Sstevel@tonic-gate /*
2ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
6a506a34cSth /*
77c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the Netscape Public
87c478bd9Sstevel@tonic-gate  * License Version 1.1 (the "License"); you may not use this file
97c478bd9Sstevel@tonic-gate  * except in compliance with the License. You may obtain a copy of
107c478bd9Sstevel@tonic-gate  * the License at http://www.mozilla.org/NPL/
1148bbca81SDaniel Hoffman  *
127c478bd9Sstevel@tonic-gate  * Software distributed under the License is distributed on an "AS
137c478bd9Sstevel@tonic-gate  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
147c478bd9Sstevel@tonic-gate  * implied. See the License for the specific language governing
157c478bd9Sstevel@tonic-gate  * rights and limitations under the License.
1648bbca81SDaniel Hoffman  *
177c478bd9Sstevel@tonic-gate  * The Original Code is Mozilla Communicator client code, released
187c478bd9Sstevel@tonic-gate  * March 31, 1998.
1948bbca81SDaniel Hoffman  *
207c478bd9Sstevel@tonic-gate  * The Initial Developer of the Original Code is Netscape
217c478bd9Sstevel@tonic-gate  * Communications Corporation. Portions created by Netscape are
227c478bd9Sstevel@tonic-gate  * Copyright (C) 1998-1999 Netscape Communications Corporation. All
237c478bd9Sstevel@tonic-gate  * Rights Reserved.
2448bbca81SDaniel Hoffman  *
2548bbca81SDaniel Hoffman  * Contributor(s):
2648bbca81SDaniel Hoffman  * Copyright (c) 2016 by Delphix. All rights reserved.
277c478bd9Sstevel@tonic-gate  */
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate /*
307c478bd9Sstevel@tonic-gate  * code that is shared by two or more of the LDAP command line tools
317c478bd9Sstevel@tonic-gate  */
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate #include "ldaptool.h"
347c478bd9Sstevel@tonic-gate #include "fileurl.h"
357c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
367c478bd9Sstevel@tonic-gate #include "solaris-int.h"
377c478bd9Sstevel@tonic-gate #include <ldap.h>
387c478bd9Sstevel@tonic-gate #include <locale.h>
397c478bd9Sstevel@tonic-gate #include <libgen.h>
407c478bd9Sstevel@tonic-gate #include <sys/types.h>
417c478bd9Sstevel@tonic-gate #include <sys/stat.h>
427c478bd9Sstevel@tonic-gate #include <limits.h>
437c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate #ifdef LDAP_TOOL_ARGPIN
467c478bd9Sstevel@tonic-gate #include "argpin.h"
477c478bd9Sstevel@tonic-gate #include "ntuserpin.h"
487c478bd9Sstevel@tonic-gate #endif /* LDAP_TOOL_ARGPIN */
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
517c478bd9Sstevel@tonic-gate #include <nspr.h> /* for PR_Cleanup() */
527c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
537c478bd9Sstevel@tonic-gate #include <stdlib.h>
547c478bd9Sstevel@tonic-gate #include <time.h>	/* for time() and ctime() */
557c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
567c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
577c478bd9Sstevel@tonic-gate #include <sasl/sasl.h>
587c478bd9Sstevel@tonic-gate #else
597c478bd9Sstevel@tonic-gate #include <sasl.h>
607c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
617c478bd9Sstevel@tonic-gate #include "ldaptool-sasl.h"
627c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
657c478bd9Sstevel@tonic-gate #define gettext(s) s
667c478bd9Sstevel@tonic-gate #endif
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
697c478bd9Sstevel@tonic-gate #define	PATH_BUF_SIZE	(PATH_MAX + 1)
707c478bd9Sstevel@tonic-gate #endif
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate static LDAP_REBINDPROC_CALLBACK get_rebind_credentials;
737c478bd9Sstevel@tonic-gate static void print_library_info( const LDAPAPIInfo *aip, FILE *fp );
747c478bd9Sstevel@tonic-gate static int wait4result( LDAP *ld, int msgid, struct berval **servercredp,
757c478bd9Sstevel@tonic-gate 	char *msg );
767c478bd9Sstevel@tonic-gate static int parse_result( LDAP *ld, LDAPMessage *res,
777c478bd9Sstevel@tonic-gate 	struct berval **servercredp, char *msg, int freeit );
787c478bd9Sstevel@tonic-gate 
7948bbca81SDaniel Hoffman #ifdef LDAPTOOL_DEBUG_MEMORY
807c478bd9Sstevel@tonic-gate static void *ldaptool_debug_malloc( size_t size );
817c478bd9Sstevel@tonic-gate static void *ldaptool_debug_calloc( size_t nelem, size_t elsize );
827c478bd9Sstevel@tonic-gate static void *ldaptool_debug_realloc( void *ptr, size_t size );
837c478bd9Sstevel@tonic-gate static void ldaptool_debug_free( void *ptr );
847c478bd9Sstevel@tonic-gate #endif /* LDAPTOOL_DEBUG_MEMORY */
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate #if defined(NET_SSL)
877c478bd9Sstevel@tonic-gate static char *certpath2keypath( char *certdbpath );
887c478bd9Sstevel@tonic-gate static int ldaptool_setcallbacks( struct ldapssl_pkcs_fns *pfns);
897c478bd9Sstevel@tonic-gate static char * buildTokenCertName( const char *tokenName, const char *certName);
907c478bd9Sstevel@tonic-gate #ifdef FORTEZZA
917c478bd9Sstevel@tonic-gate static int ldaptool_fortezza_init( int exit_on_error );
927c478bd9Sstevel@tonic-gate static int ldaptool_fortezza_alert( void *arg, PRBool onOpen,
937c478bd9Sstevel@tonic-gate 	char *string, int value1, void *value2 );
947c478bd9Sstevel@tonic-gate static void * ldaptool_fortezza_getpin( char **passwordp );
957c478bd9Sstevel@tonic-gate static char * ldaptool_fortezza_err2string( int err );
967c478bd9Sstevel@tonic-gate #endif /* FORTEZZA */
977c478bd9Sstevel@tonic-gate #endif
987c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
997c478bd9Sstevel@tonic-gate static int saslSetParam(char *saslarg);
1007c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
1017c478bd9Sstevel@tonic-gate 
1027c478bd9Sstevel@tonic-gate /*
1037c478bd9Sstevel@tonic-gate  * display usage for common options with one exception: -f is not included
1047c478bd9Sstevel@tonic-gate  * since the description tends to be tool-specific.
1057c478bd9Sstevel@tonic-gate  *
1067c478bd9Sstevel@tonic-gate  * As of 1-Jul-1998, of the characters in the set [A-Za-z] the following are
1077c478bd9Sstevel@tonic-gate  * not currently used by any of the tools: EJgjqr
1087c478bd9Sstevel@tonic-gate  */
1097c478bd9Sstevel@tonic-gate void
ldaptool_common_usage(int two_hosts)1107c478bd9Sstevel@tonic-gate ldaptool_common_usage( int two_hosts )
1117c478bd9Sstevel@tonic-gate {
1127c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -n\t\tshow what would be done but don't actually do it\n") );
1137c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -v\t\trun in verbose mode (diagnostics to standard output)\n") );
1147c478bd9Sstevel@tonic-gate     if ( two_hosts ) {
1157c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("    -h host\tLDAP server1 name or IP address (default: %s)\n"), LDAPTOOL_DEFHOST );
1167c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("    -p port\tLDAP server1 TCP port number (default: %d)\n"), LDAP_PORT );
1177c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("    -h host\tLDAP server2 name or IP address (default: %s)\n"), LDAPTOOL_DEFHOST );
1187c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("    -p port\tLDAP server2 TCP port number (default: %d)\n"), LDAP_PORT );
1197c478bd9Sstevel@tonic-gate     } else {
1207c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("    -h host\tLDAP server name or IP address (default: %s)\n"), LDAPTOOL_DEFHOST );
1217c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("    -p port\tLDAP server TCP port number (default: %d)\n"), LDAP_PORT );
1227c478bd9Sstevel@tonic-gate     }
1237c478bd9Sstevel@tonic-gate     fprintf( stderr,
1247c478bd9Sstevel@tonic-gate 	    gettext("    -V n\tLDAP protocol version number (%d or %d; default: %d)\n"),
1257c478bd9Sstevel@tonic-gate 	    LDAP_VERSION2, LDAP_VERSION3, LDAP_VERSION3 );
1267c478bd9Sstevel@tonic-gate #if defined(NET_SSL)
1277c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -Z\t\tmake an SSL-encrypted connection\n") );
1287c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -P pathname\tpath to SSL certificate database (default: current directory)\n") );
1297c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -N\t\tname of certificate to use for SSL client authentication\n") );
1307c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
1317c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -K pathname\tpath to key database to use for SSL client authentication\n") );
1327c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    \t\t(default: path to certificate database provided with -P option)\n") );
1337c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
1347c478bd9Sstevel@tonic-gate #ifdef LDAP_TOOL_PKCS11
1357c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -m pathname\tpath to security module database\n"));
1367c478bd9Sstevel@tonic-gate #endif /* LDAP_TOOL_PKCS11 */
1377c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -W\t\tSSL key password\n") );
1387c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
1397c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -3\t\tcheck hostnames in SSL certificates\n") );
140a506a34cSth #endif	/* SOLARIS_LDAP_CMD */
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate #ifdef LDAP_TOOL_PKCS11
1437c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -Q [token][:certificate name]\tPKCS 11\n") );
1447c478bd9Sstevel@tonic-gate     /*    fprintf( stderr, "    -X pathname\tFORTEZZA compromised key list (CKL)\n" ); */
1457c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -I pin\tcard password file\n") );
1467c478bd9Sstevel@tonic-gate #endif /* LDAP_TOOL_PKCS11 */
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate #endif /* NET_SSL */
1497c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -D binddn\tbind dn\n") );
1507c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -w passwd\tbind passwd (for simple authentication)\n") );
1517c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -w - \tprompt for bind passwd (for simple authentication)\n") );
1527c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -j file\tread bind passwd (for simple authentication)\n") );
1537c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("      \t\tor SSL key password from 'file'\n") );
1547c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -E\t\task server to expose (report) bind identity\n") );
1557c478bd9Sstevel@tonic-gate #ifdef LDAP_DEBUG
1567c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -d level\tset LDAP debugging level to `level'\n") );
1577c478bd9Sstevel@tonic-gate #endif
1587c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -R\t\tdo not automatically follow referrals\n") );
1597c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -O limit\tmaximum number of referral hops to traverse (default: %d)\n"), LDAPTOOL_DEFREFHOPLIMIT );
1607c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -M\t\tmanage references (treat them as regular entries)\n") );
1617c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
1627c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -0\t\tignore LDAP library version mismatches\n") );
1637c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate #ifndef NO_LIBLCACHE
1667c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -C cfgfile\tuse local database described by cfgfile\n") );
1677c478bd9Sstevel@tonic-gate #endif
1687c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -i charset\tcharacter set for command line input (default taken from locale)\n") );
1697c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -k dir\tconversion routine directory (default: current directory)\n") );
1707c478bd9Sstevel@tonic-gate #if 0
1717c478bd9Sstevel@tonic-gate /*
1727c478bd9Sstevel@tonic-gate  * Suppress usage for -y (old proxied authorization control) even though
1737c478bd9Sstevel@tonic-gate  * we still support it.  We want to encourage people to use -Y instead (the
1747c478bd9Sstevel@tonic-gate  * new proxied authorization control).
1757c478bd9Sstevel@tonic-gate  */
1767c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -y proxydn\tDN used for proxy authorization\n") );
1777c478bd9Sstevel@tonic-gate #endif
1787c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -Y proxyid\tproxied authorization id,\n") );
1797c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("              \te.g, dn:uid=bjensen,dc=example,dc=com\n") );
1807c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -H\t\tdisplay usage information\n") );
1817c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
1827c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -?\t\tdisplay usage information\n") );
1837c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
1847c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -J controloid[:criticality[:value|::b64value|:<fileurl]]\n") );
1857c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("\t\tcriticality is a boolean value (default is false)\n") );
1867c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
1877c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -o attrName=attrVal\tSASL options which are described in the man page\n"));
1887c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
1897c478bd9Sstevel@tonic-gate }
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate /* globals */
1927c478bd9Sstevel@tonic-gate char			*ldaptool_charset = "";
1937c478bd9Sstevel@tonic-gate char			*ldaptool_host = LDAPTOOL_DEFHOST;
1947c478bd9Sstevel@tonic-gate char			*ldaptool_host2 = LDAPTOOL_DEFHOST;
1957c478bd9Sstevel@tonic-gate int			ldaptool_port = LDAP_PORT;
1967c478bd9Sstevel@tonic-gate int			ldaptool_port2 = LDAP_PORT;
1977c478bd9Sstevel@tonic-gate int			ldaptool_verbose = 0;
1987c478bd9Sstevel@tonic-gate int			ldaptool_not = 0;
1997c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
2007c478bd9Sstevel@tonic-gate int			ldaptool_require_binddn = 1;
2017c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
2027c478bd9Sstevel@tonic-gate FILE			*ldaptool_fp = NULL;
2037c478bd9Sstevel@tonic-gate FILE			*password_fp = NULL;
2047c478bd9Sstevel@tonic-gate char			*ldaptool_progname = "";
2057c478bd9Sstevel@tonic-gate char			*ldaptool_nls_lang = NULL;
2067c478bd9Sstevel@tonic-gate char                    *proxyauth_id = NULL;
2077c478bd9Sstevel@tonic-gate int			proxyauth_version = 2;	/* use newer proxy control */
2087c478bd9Sstevel@tonic-gate LDAPControl		*ldaptool_request_ctrls[CONTROL_REQUESTS] = {0};
2097c478bd9Sstevel@tonic-gate #ifdef LDAP_DEBUG
2107c478bd9Sstevel@tonic-gate int			ldaptool_dbg_lvl = 0;
2117c478bd9Sstevel@tonic-gate #endif /* LDAP_DEBUG */
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate /* statics */
2147c478bd9Sstevel@tonic-gate static char		*binddn = NULL;
2157c478bd9Sstevel@tonic-gate static char		*passwd = NULL;
2167c478bd9Sstevel@tonic-gate static int		send_auth_response_ctrl = 0;
2177c478bd9Sstevel@tonic-gate static int		user_specified_port = 0;
2187c478bd9Sstevel@tonic-gate static int		user_specified_port2 = 0;
2197c478bd9Sstevel@tonic-gate static int		chase_referrals = 1;
2207c478bd9Sstevel@tonic-gate static int		lib_version_mismatch_is_fatal = 1;
2217c478bd9Sstevel@tonic-gate static int		ldversion = -1;	/* use default */
2227c478bd9Sstevel@tonic-gate static int		refhoplim = LDAPTOOL_DEFREFHOPLIMIT;
2237c478bd9Sstevel@tonic-gate static int		send_manage_dsait_ctrl = 0;
2247c478bd9Sstevel@tonic-gate static int		prompt_password = 0;
2257c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
2267c478bd9Sstevel@tonic-gate static unsigned		sasl_flags = LDAP_SASL_INTERACTIVE;
2277c478bd9Sstevel@tonic-gate static char		*sasl_mech = NULL;
2287c478bd9Sstevel@tonic-gate static char		*sasl_authid = NULL;
2297c478bd9Sstevel@tonic-gate static char		*sasl_mode = NULL;
2307c478bd9Sstevel@tonic-gate static char		*sasl_realm = NULL;
2317c478bd9Sstevel@tonic-gate static char		*sasl_username = NULL;
2327c478bd9Sstevel@tonic-gate static char		*sasl_secprops = NULL;
2337c478bd9Sstevel@tonic-gate static int		ldapauth = -1;
2347c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate #ifndef NO_LIBLCACHE
2377c478bd9Sstevel@tonic-gate static char		*cache_config_file = NULL;
2387c478bd9Sstevel@tonic-gate #endif /* !NO_LIBLCACHE */
2397c478bd9Sstevel@tonic-gate #if defined(NET_SSL)
2407c478bd9Sstevel@tonic-gate static int		secure = 0;
2417c478bd9Sstevel@tonic-gate static int		isZ = 0;
2427c478bd9Sstevel@tonic-gate static int		isN = 0;
2437c478bd9Sstevel@tonic-gate static int		isW = 0;
2447c478bd9Sstevel@tonic-gate static int		isw = 0;
2457c478bd9Sstevel@tonic-gate static int		isD = 0;
2467c478bd9Sstevel@tonic-gate static int		isj = 0;
2477c478bd9Sstevel@tonic-gate static int		ssl_strength = LDAPTOOL_DEFSSLSTRENGTH;
2487c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
2497c478bd9Sstevel@tonic-gate static char		pathname[PATH_BUF_SIZE];
2507c478bd9Sstevel@tonic-gate #endif
2517c478bd9Sstevel@tonic-gate static char		*ssl_certdbpath = NULL;
2527c478bd9Sstevel@tonic-gate static char		*ssl_keydbpath = NULL;
2537c478bd9Sstevel@tonic-gate static char		*ssl_keyname = NULL;
2547c478bd9Sstevel@tonic-gate static char		*ssl_certname = NULL;
2557c478bd9Sstevel@tonic-gate static char		*ssl_passwd = NULL;
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate #ifdef LDAP_TOOL_PKCS11
2587c478bd9Sstevel@tonic-gate static char     	*ssl_secmodpath = NULL;
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate static char             *pkcs_token = NULL;
2617c478bd9Sstevel@tonic-gate 
2627c478bd9Sstevel@tonic-gate static char             *ssl_donglefile = NULL;
2637c478bd9Sstevel@tonic-gate 
2647c478bd9Sstevel@tonic-gate #if 0
2657c478bd9Sstevel@tonic-gate static char             *pkcs_pin = NULL;
2667c478bd9Sstevel@tonic-gate #endif
26748bbca81SDaniel Hoffman static struct ldapssl_pkcs_fns local_pkcs_fns =
2687c478bd9Sstevel@tonic-gate     {0,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL };
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate #ifdef FORTEZZA
2717c478bd9Sstevel@tonic-gate static uint32		fortezza_cardmask = 0;
2727c478bd9Sstevel@tonic-gate static char		*fortezza_personality = NULL;
2737c478bd9Sstevel@tonic-gate static char		*fortezza_krlfile = NULL;
2747c478bd9Sstevel@tonic-gate static char		*fortezza_pin = NULL;
2757c478bd9Sstevel@tonic-gate #endif /* FORTEZZA */
2767c478bd9Sstevel@tonic-gate #endif /* LDAP_TOOL_PKCS11 */
2777c478bd9Sstevel@tonic-gate #endif /* NET_SSL */
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate /*
2807c478bd9Sstevel@tonic-gate  * Handle general initialization and options that are common to all of
2817c478bd9Sstevel@tonic-gate  * the LDAP tools.
2827c478bd9Sstevel@tonic-gate  * Handle options that are common to all of the LDAP tools.
2837c478bd9Sstevel@tonic-gate  * Note the the H option is included here but handled via the
2847c478bd9Sstevel@tonic-gate  * extra_opt_callback function (along with any "extra_opts" ).
2857c478bd9Sstevel@tonic-gate  *
2867c478bd9Sstevel@tonic-gate  * Return: final value for optind or -1 if usage should be displayed (for
2877c478bd9Sstevel@tonic-gate  * some fatal errors, we call exit here).
2887c478bd9Sstevel@tonic-gate  */
2897c478bd9Sstevel@tonic-gate int
ldaptool_process_args(int argc,char ** argv,char * extra_opts,int two_hosts,void (* extra_opt_callback)(int option,char * optarg))2907c478bd9Sstevel@tonic-gate ldaptool_process_args( int argc, char **argv, char *extra_opts,
2917c478bd9Sstevel@tonic-gate 	int two_hosts, void (*extra_opt_callback)( int option, char *optarg ))
2927c478bd9Sstevel@tonic-gate {
2937c478bd9Sstevel@tonic-gate     int		rc, i, hostnum;
2947c478bd9Sstevel@tonic-gate     char	*optstring, *common_opts;
2957c478bd9Sstevel@tonic-gate     extern char	*optarg;
2967c478bd9Sstevel@tonic-gate     extern int	optind;
2977c478bd9Sstevel@tonic-gate     LDAPAPIInfo	ldai;
2987c478bd9Sstevel@tonic-gate     char *ctrl_arg, *ctrl_oid=NULL, *ctrl_value=NULL;
2997c478bd9Sstevel@tonic-gate     int ctrl_criticality=0, vlen;
3007c478bd9Sstevel@tonic-gate     LDAPControl *ldctrl;
3017c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
3027c478bd9Sstevel@tonic-gate 	struct stat st;
3037c478bd9Sstevel@tonic-gate #endif
3047c478bd9Sstevel@tonic-gate 
3057c478bd9Sstevel@tonic-gate 
3067c478bd9Sstevel@tonic-gate     /*
3077c478bd9Sstevel@tonic-gate      * Set program name global based on argv[0].
3087c478bd9Sstevel@tonic-gate      */
3097c478bd9Sstevel@tonic-gate     if (( ldaptool_progname = strrchr( argv[ 0 ], '/' )) == NULL ) {
3107c478bd9Sstevel@tonic-gate         ldaptool_progname = argv[ 0 ];
3117c478bd9Sstevel@tonic-gate     } else {
3127c478bd9Sstevel@tonic-gate         ++ldaptool_progname;
3137c478bd9Sstevel@tonic-gate     }
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate #ifdef LDAPTOOL_DEBUG_MEMORY
3167c478bd9Sstevel@tonic-gate     {
3177c478bd9Sstevel@tonic-gate 	struct ldap_memalloc_fns mafns = {
3187c478bd9Sstevel@tonic-gate 		ldaptool_debug_malloc,
3197c478bd9Sstevel@tonic-gate 		ldaptool_debug_calloc,
3207c478bd9Sstevel@tonic-gate 		ldaptool_debug_realloc,
3217c478bd9Sstevel@tonic-gate 		ldaptool_debug_free
3227c478bd9Sstevel@tonic-gate 	};
3237c478bd9Sstevel@tonic-gate 
3247c478bd9Sstevel@tonic-gate 	ldap_set_option( NULL, LDAP_OPT_MEMALLOC_FN_PTRS, &mafns );
3257c478bd9Sstevel@tonic-gate     }
3267c478bd9Sstevel@tonic-gate #endif	/* LDAPTOOL_DEBUG_MEMORY */
3277c478bd9Sstevel@tonic-gate 
3287c478bd9Sstevel@tonic-gate #ifdef LDAP_DEBUG
3297c478bd9Sstevel@tonic-gate     i = LDAP_DEBUG_ANY;
3307c478bd9Sstevel@tonic-gate     ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, (void *) &i);
3317c478bd9Sstevel@tonic-gate #endif
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate     /*
3347c478bd9Sstevel@tonic-gate      * Perform a sanity check on the revision of the LDAP API library to
3357c478bd9Sstevel@tonic-gate      * make sure it is at least as new as the one we were compiled against.
3367c478bd9Sstevel@tonic-gate      * If the API implementation is from the same vendor as we were compiled
3377c478bd9Sstevel@tonic-gate      * against, we also check to make sure the vendor version is at least
3387c478bd9Sstevel@tonic-gate      * as new as the library we were compiled against.
3397c478bd9Sstevel@tonic-gate      *
3407c478bd9Sstevel@tonic-gate      * Version differences are fatal unless the -0 option is passed on the
3417c478bd9Sstevel@tonic-gate      * tool command line (that's a zero, not an oh).  We check for the
3427c478bd9Sstevel@tonic-gate      * presence of -0 in a crude way to it must appear by itself in argv.
3437c478bd9Sstevel@tonic-gate      */
3447c478bd9Sstevel@tonic-gate     for ( i = 1; i < argc; ++i ) {
3457c478bd9Sstevel@tonic-gate 	if ( strcmp( argv[i], "-0" ) == 0 ) {
3467c478bd9Sstevel@tonic-gate 	    lib_version_mismatch_is_fatal = 0;
3477c478bd9Sstevel@tonic-gate 	    break;
3487c478bd9Sstevel@tonic-gate 	}
3497c478bd9Sstevel@tonic-gate     }
3507c478bd9Sstevel@tonic-gate 
3517c478bd9Sstevel@tonic-gate     memset( &ldai, 0, sizeof(ldai));
3527c478bd9Sstevel@tonic-gate     ldai.ldapai_info_version = LDAP_API_INFO_VERSION;
3537c478bd9Sstevel@tonic-gate     if (( rc = ldap_get_option( NULL, LDAP_OPT_API_INFO, &ldai )) != 0 ) {
3547c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: unable to retrieve LDAP library version"
3557c478bd9Sstevel@tonic-gate 		" information;\n\tthis program requires an LDAP library that"
3567c478bd9Sstevel@tonic-gate 		" implements revision\n\t%d or greater of the LDAP API.\n"),
3577c478bd9Sstevel@tonic-gate 		ldaptool_progname, LDAP_API_VERSION );
3587c478bd9Sstevel@tonic-gate 	if ( lib_version_mismatch_is_fatal ) {
3597c478bd9Sstevel@tonic-gate 	    exit( LDAP_LOCAL_ERROR );
3607c478bd9Sstevel@tonic-gate 	}
3617c478bd9Sstevel@tonic-gate     } else if ( ldai.ldapai_api_version < LDAP_API_VERSION ) {
3627c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: this program requires an LDAP library that"
3637c478bd9Sstevel@tonic-gate 		" implements revision\n\t%d or greater of the LDAP API;"
3647c478bd9Sstevel@tonic-gate 		" running with revision %d.\n"),
3657c478bd9Sstevel@tonic-gate 		ldaptool_progname, LDAP_API_VERSION, ldai.ldapai_api_version );
3667c478bd9Sstevel@tonic-gate 	if ( lib_version_mismatch_is_fatal ) {
3677c478bd9Sstevel@tonic-gate 	    exit( LDAP_LOCAL_ERROR );
3687c478bd9Sstevel@tonic-gate 	}
3697c478bd9Sstevel@tonic-gate     } else if ( strcmp( ldai.ldapai_vendor_name, LDAP_VENDOR_NAME ) != 0) {
3707c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: this program requires %s's LDAP\n"
3717c478bd9Sstevel@tonic-gate 		"\tlibrary version %2.2f or greater; running with\n"
3727c478bd9Sstevel@tonic-gate 		"\t%s's version %2.2f.\n"),
3737c478bd9Sstevel@tonic-gate 		ldaptool_progname, LDAP_VENDOR_NAME,
3747c478bd9Sstevel@tonic-gate 		(float)LDAP_VENDOR_VERSION / 100,
3757c478bd9Sstevel@tonic-gate 		ldai.ldapai_vendor_name,
3767c478bd9Sstevel@tonic-gate 		(float)ldai.ldapai_vendor_version / 100 );
3777c478bd9Sstevel@tonic-gate 	if ( lib_version_mismatch_is_fatal ) {
3787c478bd9Sstevel@tonic-gate 	    exit( LDAP_LOCAL_ERROR );
3797c478bd9Sstevel@tonic-gate 	}
3807c478bd9Sstevel@tonic-gate     } else if (ldai.ldapai_vendor_version < LDAP_VENDOR_VERSION ) {
3817c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: this program requires %s's LDAP\n"
3827c478bd9Sstevel@tonic-gate 		"\tlibrary version %2.2f or greater; running with"
3837c478bd9Sstevel@tonic-gate 		" version %2.2f.\n"),
3847c478bd9Sstevel@tonic-gate 		ldaptool_progname, LDAP_VENDOR_NAME,
3857c478bd9Sstevel@tonic-gate 		(float)LDAP_VENDOR_VERSION / 100,
3867c478bd9Sstevel@tonic-gate 		(float)ldai.ldapai_vendor_version / 100 );
3877c478bd9Sstevel@tonic-gate 	if ( lib_version_mismatch_is_fatal ) {
3887c478bd9Sstevel@tonic-gate 	    exit( LDAP_LOCAL_ERROR );
3897c478bd9Sstevel@tonic-gate 	}
3907c478bd9Sstevel@tonic-gate     }
3917c478bd9Sstevel@tonic-gate 
3927c478bd9Sstevel@tonic-gate     /*
3937c478bd9Sstevel@tonic-gate      * Process command line options.
3947c478bd9Sstevel@tonic-gate      */
3957c478bd9Sstevel@tonic-gate     if ( extra_opts == NULL ) {
3967c478bd9Sstevel@tonic-gate 	extra_opts = "";
3977c478bd9Sstevel@tonic-gate     }
3987c478bd9Sstevel@tonic-gate 
3997c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
4007c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
4017c478bd9Sstevel@tonic-gate     common_opts = "nvEMRH?Zd:D:f:h:j:N:O:o:P:p:W:w:V:i:k:y:Y:J:";
4027c478bd9Sstevel@tonic-gate #else
4037c478bd9Sstevel@tonic-gate     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:";
4047c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
4057c478bd9Sstevel@tonic-gate #else
4067c478bd9Sstevel@tonic-gate     common_opts = "nvEMRHZ03d:D:f:h:j:I:K:N:O:P:p:Q:W:w:V:X:m:i:k:y:Y:J:";
4077c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
4087c478bd9Sstevel@tonic-gate 
4097c478bd9Sstevel@tonic-gate     /* note: optstring must include room for liblcache "C:" option */
4107c478bd9Sstevel@tonic-gate     if (( optstring = (char *) malloc( strlen( extra_opts ) + strlen( common_opts )
4117c478bd9Sstevel@tonic-gate 	    + 3 )) == NULL ) {
4127c478bd9Sstevel@tonic-gate 	perror( "malloc" );
4137c478bd9Sstevel@tonic-gate 	exit( LDAP_NO_MEMORY );
4147c478bd9Sstevel@tonic-gate     }
4157c478bd9Sstevel@tonic-gate 
4167c478bd9Sstevel@tonic-gate #ifdef NO_LIBLCACHE
4177c478bd9Sstevel@tonic-gate     sprintf( optstring, "%s%s", common_opts, extra_opts );
4187c478bd9Sstevel@tonic-gate #else
4197c478bd9Sstevel@tonic-gate     sprintf( optstring, "%s%sC:", common_opts, extra_opts );
4207c478bd9Sstevel@tonic-gate #endif
4217c478bd9Sstevel@tonic-gate 
4227c478bd9Sstevel@tonic-gate     hostnum = 0;
4237c478bd9Sstevel@tonic-gate     while ( (i = getopt( argc, argv, optstring )) != EOF ) {
4247c478bd9Sstevel@tonic-gate 	switch( i ) {
4257c478bd9Sstevel@tonic-gate 	case 'n':	/* do Not do any LDAP operations */
4267c478bd9Sstevel@tonic-gate 	    ++ldaptool_not;
4277c478bd9Sstevel@tonic-gate 	    break;
4287c478bd9Sstevel@tonic-gate 	case 'v':	/* verbose mode */
4297c478bd9Sstevel@tonic-gate 	    ++ldaptool_verbose;
4307c478bd9Sstevel@tonic-gate 	    break;
4317c478bd9Sstevel@tonic-gate 	case 'd':
4327c478bd9Sstevel@tonic-gate #ifdef LDAP_DEBUG
4337c478bd9Sstevel@tonic-gate 	    ldaptool_dbg_lvl = atoi( optarg );	/* */
4347c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
4357c478bd9Sstevel@tonic-gate 	    ldap_set_option(NULL, LBER_OPT_DEBUG_LEVEL,
4367c478bd9Sstevel@tonic-gate 		    (void *)&ldaptool_dbg_lvl);
4377c478bd9Sstevel@tonic-gate #else
4387c478bd9Sstevel@tonic-gate 	    ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL,
4397c478bd9Sstevel@tonic-gate 		    (void *)&ldaptool_dbg_lvl);
4407c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
4417c478bd9Sstevel@tonic-gate 	    ldaptool_dbg_lvl |= LDAP_DEBUG_ANY;
4427c478bd9Sstevel@tonic-gate 	    ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL,
4437c478bd9Sstevel@tonic-gate 		    (void *)&ldaptool_dbg_lvl);
4447c478bd9Sstevel@tonic-gate #else /* LDAP_DEBUG */
4457c478bd9Sstevel@tonic-gate 	    fprintf( stderr, gettext("compile with -DLDAP_DEBUG for debugging\n") );
4467c478bd9Sstevel@tonic-gate #endif /* LDAP_DEBUG */
4477c478bd9Sstevel@tonic-gate 	    break;
4487c478bd9Sstevel@tonic-gate 	case 'R':	/* don't automatically chase referrals */
4497c478bd9Sstevel@tonic-gate 	    chase_referrals = 0;
4507c478bd9Sstevel@tonic-gate 	    break;
4517c478bd9Sstevel@tonic-gate #ifndef NO_LIBLCACHE
4527c478bd9Sstevel@tonic-gate 	case 'C':	/* search local database */
4537c478bd9Sstevel@tonic-gate 	    cache_config_file = strdup( optarg );
4547c478bd9Sstevel@tonic-gate 	    break;
4557c478bd9Sstevel@tonic-gate #endif
4567c478bd9Sstevel@tonic-gate 	case 'f':	/* input file */
4577c478bd9Sstevel@tonic-gate 	    if ( optarg[0] == '-' && optarg[1] == '\0' ) {
4587c478bd9Sstevel@tonic-gate 		ldaptool_fp = stdin;
4597c478bd9Sstevel@tonic-gate 	    } else if (( ldaptool_fp = ldaptool_open_file( optarg, "r" )) == NULL ) {
4607c478bd9Sstevel@tonic-gate 		perror( optarg );
4617c478bd9Sstevel@tonic-gate 		exit( LDAP_PARAM_ERROR );
4627c478bd9Sstevel@tonic-gate 	    }
4637c478bd9Sstevel@tonic-gate 	    break;
4647c478bd9Sstevel@tonic-gate 	case 'h':	/* ldap host */
4657c478bd9Sstevel@tonic-gate 	    if ( hostnum == 0 ) {
4667c478bd9Sstevel@tonic-gate 		ldaptool_host = strdup( optarg );
4677c478bd9Sstevel@tonic-gate 	    } else {
4687c478bd9Sstevel@tonic-gate 		ldaptool_host2 = strdup( optarg );
4697c478bd9Sstevel@tonic-gate 	    }
4707c478bd9Sstevel@tonic-gate 	    ++hostnum;
4717c478bd9Sstevel@tonic-gate 	    break;
4727c478bd9Sstevel@tonic-gate 	case 'D':	/* bind DN */
4737c478bd9Sstevel@tonic-gate 	    isD = 1;
4747c478bd9Sstevel@tonic-gate 	    binddn = strdup( optarg );
4757c478bd9Sstevel@tonic-gate 	    break;
4767c478bd9Sstevel@tonic-gate 	case 'E':	/* expose bind identity via auth. response control */
4777c478bd9Sstevel@tonic-gate 	    ++send_auth_response_ctrl;
4787c478bd9Sstevel@tonic-gate 	    break;
4797c478bd9Sstevel@tonic-gate 
4807c478bd9Sstevel@tonic-gate 	case 'p':	/* ldap port */
4817c478bd9Sstevel@tonic-gate 	    if ( !user_specified_port ) {
4827c478bd9Sstevel@tonic-gate 		++user_specified_port;
4837c478bd9Sstevel@tonic-gate 		ldaptool_port = atoi( optarg );
4847c478bd9Sstevel@tonic-gate 	    } else {
4857c478bd9Sstevel@tonic-gate 		++user_specified_port2;
4867c478bd9Sstevel@tonic-gate 		ldaptool_port2 = atoi( optarg );
4877c478bd9Sstevel@tonic-gate 	    }
4887c478bd9Sstevel@tonic-gate 	    break;
4897c478bd9Sstevel@tonic-gate #if defined(NET_SSL)
4907c478bd9Sstevel@tonic-gate 	case 'P':	/* path to security database */
4917c478bd9Sstevel@tonic-gate 	    secure = 1; /* do SSL encryption */
4927c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
4937c478bd9Sstevel@tonic-gate 	    ssl_certdbpath = strdup(optarg);
4947c478bd9Sstevel@tonic-gate 	    if (NULL == ssl_certdbpath) {
4957c478bd9Sstevel@tonic-gate 		perror("malloc");
4967c478bd9Sstevel@tonic-gate 		exit( LDAP_NO_MEMORY );
4977c478bd9Sstevel@tonic-gate 	    }
4987c478bd9Sstevel@tonic-gate #else
4997c478bd9Sstevel@tonic-gate 		/*
5007c478bd9Sstevel@tonic-gate 		 * Verify whether it's a base directory or a cert db file.
5017c478bd9Sstevel@tonic-gate 		 * If it is not a directory, truncate the file name as
5027c478bd9Sstevel@tonic-gate 		 * the revised NSS_Init() doesn't take file name any longer.
5037c478bd9Sstevel@tonic-gate 		 */
5047c478bd9Sstevel@tonic-gate 		if (strlcpy(pathname, optarg, PATH_BUF_SIZE) >= PATH_BUF_SIZE) {
5057c478bd9Sstevel@tonic-gate 			fprintf(stderr, gettext("\"-P\": Path name is too "
5067c478bd9Sstevel@tonic-gate 				"long\n"));
5077c478bd9Sstevel@tonic-gate 			exit(LDAP_PARAM_ERROR);
5087c478bd9Sstevel@tonic-gate 		}
5097c478bd9Sstevel@tonic-gate 
5107c478bd9Sstevel@tonic-gate 		if (stat(pathname, &st) != 0) {
5117c478bd9Sstevel@tonic-gate 			perror("stat");
5127c478bd9Sstevel@tonic-gate 			fprintf(stderr, gettext("\"-P\": Path name is "
5137c478bd9Sstevel@tonic-gate 				"invalid\n"));
5147c478bd9Sstevel@tonic-gate 			exit(LDAP_PARAM_ERROR);
5157c478bd9Sstevel@tonic-gate 		} else {
5167c478bd9Sstevel@tonic-gate 			if (S_ISREG(st.st_mode)) {
5177c478bd9Sstevel@tonic-gate 				/* redir to a regular file's dir name */
5187c478bd9Sstevel@tonic-gate 				ssl_certdbpath = dirname(pathname);
5197c478bd9Sstevel@tonic-gate 			} else
5207c478bd9Sstevel@tonic-gate 				ssl_certdbpath = pathname;
5217c478bd9Sstevel@tonic-gate 		}
5227c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */
5237c478bd9Sstevel@tonic-gate 	    break;
5247c478bd9Sstevel@tonic-gate 	case 'Z':	/* do SSL encryption */
5257c478bd9Sstevel@tonic-gate 	    secure = 1;
5267c478bd9Sstevel@tonic-gate 	    isZ = 1;
5277c478bd9Sstevel@tonic-gate 	    break;
5287c478bd9Sstevel@tonic-gate 	case 'N':	/* nickname of cert. to use for client auth. */
5297c478bd9Sstevel@tonic-gate 	    ssl_certname = strdup( optarg );
5307c478bd9Sstevel@tonic-gate 	    if (NULL == ssl_certname)
5317c478bd9Sstevel@tonic-gate 	    {
5327c478bd9Sstevel@tonic-gate 		perror("malloc");
5337c478bd9Sstevel@tonic-gate 		exit( LDAP_NO_MEMORY );
5347c478bd9Sstevel@tonic-gate 	    }
5357c478bd9Sstevel@tonic-gate 	    isN = 1;
5367c478bd9Sstevel@tonic-gate 	    break;
5377c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
5387c478bd9Sstevel@tonic-gate 	case 'K':	/* location of key database */
5397c478bd9Sstevel@tonic-gate 	    ssl_keydbpath = strdup( optarg );
5407c478bd9Sstevel@tonic-gate 	    if (NULL == ssl_keydbpath)
5417c478bd9Sstevel@tonic-gate 	    {
5427c478bd9Sstevel@tonic-gate 		perror("malloc");
5437c478bd9Sstevel@tonic-gate 		exit( LDAP_NO_MEMORY );
5447c478bd9Sstevel@tonic-gate 	    }
5457c478bd9Sstevel@tonic-gate 	    break;
5467c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
5477c478bd9Sstevel@tonic-gate 
5487c478bd9Sstevel@tonic-gate 	case 'W':	/* SSL key password */
5497c478bd9Sstevel@tonic-gate 	    ssl_passwd = strdup( optarg );
5507c478bd9Sstevel@tonic-gate 	    if (NULL == ssl_passwd)
5517c478bd9Sstevel@tonic-gate 	    {
5527c478bd9Sstevel@tonic-gate 		perror("malloc");
5537c478bd9Sstevel@tonic-gate 		exit( LDAP_NO_MEMORY );
5547c478bd9Sstevel@tonic-gate 	    }
5557c478bd9Sstevel@tonic-gate 	    isW = 1;
5567c478bd9Sstevel@tonic-gate 	    break;
5577c478bd9Sstevel@tonic-gate 
5587c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
5597c478bd9Sstevel@tonic-gate 	case '3': /* check hostnames in SSL certificates ("no third") */
5607c478bd9Sstevel@tonic-gate 	    ssl_strength = LDAPSSL_AUTH_CNCHECK;
5617c478bd9Sstevel@tonic-gate 	    break;
5627c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
5637c478bd9Sstevel@tonic-gate 
5647c478bd9Sstevel@tonic-gate #ifdef LDAP_TOOL_PKCS11
5657c478bd9Sstevel@tonic-gate 	case 'm':	/* SSL secmod path */
5667c478bd9Sstevel@tonic-gate 	    ssl_secmodpath = strdup( optarg);
5677c478bd9Sstevel@tonic-gate 	    if (NULL == ssl_secmodpath)
5687c478bd9Sstevel@tonic-gate 	    {
5697c478bd9Sstevel@tonic-gate 		perror("malloc");
5707c478bd9Sstevel@tonic-gate 		exit( LDAP_NO_MEMORY );
5717c478bd9Sstevel@tonic-gate 	    }
5727c478bd9Sstevel@tonic-gate 	    break;
5737c478bd9Sstevel@tonic-gate 
5747c478bd9Sstevel@tonic-gate 	case 'Q': 	/* FORTEZZA [card][:personality] */
5757c478bd9Sstevel@tonic-gate 	    pkcs_token = strdup(optarg);
5767c478bd9Sstevel@tonic-gate 	    if (NULL == pkcs_token)
5777c478bd9Sstevel@tonic-gate 	    {
5787c478bd9Sstevel@tonic-gate 		perror("malloc");
5797c478bd9Sstevel@tonic-gate 		exit( LDAP_NO_MEMORY );
5807c478bd9Sstevel@tonic-gate 	    }
5817c478bd9Sstevel@tonic-gate 
5827c478bd9Sstevel@tonic-gate 	    break;
5837c478bd9Sstevel@tonic-gate 	    /* This option removed to prevent interference
5847c478bd9Sstevel@tonic-gate 	       with the getEffectiveRights option, also -X
5857c478bd9Sstevel@tonic-gate 	       case 'X':	* path to FORTEZZA CKL file *
58648bbca81SDaniel Hoffman 
5877c478bd9Sstevel@tonic-gate 	       fortezza_krlfile = strdup( optarg );
58848bbca81SDaniel Hoffman 
58948bbca81SDaniel Hoffman 
5907c478bd9Sstevel@tonic-gate 	       break;
5917c478bd9Sstevel@tonic-gate 	    */
5927c478bd9Sstevel@tonic-gate 	case 'I':	/* FORTEZZA PIN (password file) */
5937c478bd9Sstevel@tonic-gate 	    ssl_donglefile = strdup( optarg );
59448bbca81SDaniel Hoffman 
5957c478bd9Sstevel@tonic-gate 	    break;
5967c478bd9Sstevel@tonic-gate #endif /* LDAP_TOOL_PKCS11 */
5977c478bd9Sstevel@tonic-gate 
5987c478bd9Sstevel@tonic-gate #endif /* NET_SSL */
5997c478bd9Sstevel@tonic-gate 	case 'w':	/* bind password */
6007c478bd9Sstevel@tonic-gate 	    isw = 1;
6017c478bd9Sstevel@tonic-gate 	    if ( optarg[0] == '-' && optarg[1] == '\0' )
6027c478bd9Sstevel@tonic-gate 		prompt_password = 1;
6037c478bd9Sstevel@tonic-gate 	    else
6047c478bd9Sstevel@tonic-gate 		passwd = strdup( optarg );
6057c478bd9Sstevel@tonic-gate 	    break;
6067c478bd9Sstevel@tonic-gate 	    case 'j':       /* bind password or SSL key password from file */
6077c478bd9Sstevel@tonic-gate 	    isj = 1;
6087c478bd9Sstevel@tonic-gate 	    if ((password_fp = fopen( optarg, "r" )) == NULL ) {
6097c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("%s: Unable to open '%s' file\n"),
6107c478bd9Sstevel@tonic-gate 			ldaptool_progname, optarg);
6117c478bd9Sstevel@tonic-gate 		exit( LDAP_PARAM_ERROR );
6127c478bd9Sstevel@tonic-gate 	    }
6137c478bd9Sstevel@tonic-gate             break;
6147c478bd9Sstevel@tonic-gate 	case 'O':	/* referral hop limit */
6157c478bd9Sstevel@tonic-gate 	    refhoplim = atoi( optarg );
6167c478bd9Sstevel@tonic-gate 	    break;
6177c478bd9Sstevel@tonic-gate 	case 'V':	/* protocol version */
6187c478bd9Sstevel@tonic-gate 	    ldversion = atoi (optarg);
6197c478bd9Sstevel@tonic-gate 	    if ( ldversion != LDAP_VERSION2 && ldversion != LDAP_VERSION3 ) {
6207c478bd9Sstevel@tonic-gate 		fprintf( stderr, gettext("%s: LDAP protocol version %d is not "
6217c478bd9Sstevel@tonic-gate 			"supported (use -V%d or -V%d)\n"),
6227c478bd9Sstevel@tonic-gate 			ldaptool_progname, ldversion, LDAP_VERSION2,
6237c478bd9Sstevel@tonic-gate 			LDAP_VERSION3 );
6247c478bd9Sstevel@tonic-gate 		exit( LDAP_PARAM_ERROR );
6257c478bd9Sstevel@tonic-gate 	    }
6267c478bd9Sstevel@tonic-gate 	    break;
6277c478bd9Sstevel@tonic-gate 	case 'M':	/* send a manageDsaIT control */
6287c478bd9Sstevel@tonic-gate 	    send_manage_dsait_ctrl = 1;
6297c478bd9Sstevel@tonic-gate 	    break;
6307c478bd9Sstevel@tonic-gate 
6317c478bd9Sstevel@tonic-gate 	case 'i':   /* character set specified */
6327c478bd9Sstevel@tonic-gate 	    ldaptool_charset = strdup( optarg );
6337c478bd9Sstevel@tonic-gate 	    if (NULL == ldaptool_charset)
6347c478bd9Sstevel@tonic-gate 	    {
6357c478bd9Sstevel@tonic-gate 		perror( "malloc" );
6367c478bd9Sstevel@tonic-gate 		exit( LDAP_NO_MEMORY );
6377c478bd9Sstevel@tonic-gate 	    }
63848bbca81SDaniel Hoffman 
6397c478bd9Sstevel@tonic-gate 	    break;
6407c478bd9Sstevel@tonic-gate 	case 'k':   /* conversion directory */
6417c478bd9Sstevel@tonic-gate 	    ldaptool_convdir = strdup( optarg );
6427c478bd9Sstevel@tonic-gate 	    if (NULL == ldaptool_convdir)
6437c478bd9Sstevel@tonic-gate 	    {
6447c478bd9Sstevel@tonic-gate 		perror( "malloc" );
6457c478bd9Sstevel@tonic-gate 		exit( LDAP_NO_MEMORY );
6467c478bd9Sstevel@tonic-gate 	    }
6477c478bd9Sstevel@tonic-gate 	    break;
6487c478bd9Sstevel@tonic-gate 	case 'y':   /* old (version 1) proxied authorization control */
6497c478bd9Sstevel@tonic-gate 		proxyauth_version = 1;
650*b232a944SToomas Soome 		/* FALLTHROUGH */
6517c478bd9Sstevel@tonic-gate 	case 'Y':   /* new (version 2 ) proxied authorization control */
6527c478bd9Sstevel@tonic-gate 	    proxyauth_id = strdup(optarg);
6537c478bd9Sstevel@tonic-gate 	    if (NULL == proxyauth_id)
6547c478bd9Sstevel@tonic-gate 	    {
6557c478bd9Sstevel@tonic-gate 		perror( "malloc" );
6567c478bd9Sstevel@tonic-gate 		exit( LDAP_NO_MEMORY );
6577c478bd9Sstevel@tonic-gate 	    }
6587c478bd9Sstevel@tonic-gate 
6597c478bd9Sstevel@tonic-gate 	    break;
6607c478bd9Sstevel@tonic-gate 
6617c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
6627c478bd9Sstevel@tonic-gate  	case '0':	/* zero -- override LDAP library version check */
6637c478bd9Sstevel@tonic-gate 	    break;	/* already handled above */
6647c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
6657c478bd9Sstevel@tonic-gate 	case 'J':	 /* send an arbitrary control */
6667c478bd9Sstevel@tonic-gate 	    if ( (ctrl_arg = strdup( optarg)) == NULL ) {
6677c478bd9Sstevel@tonic-gate 		perror ("strdup");
6687c478bd9Sstevel@tonic-gate 		exit (LDAP_NO_MEMORY);
6697c478bd9Sstevel@tonic-gate 	    }
6707c478bd9Sstevel@tonic-gate 	    if (ldaptool_parse_ctrl_arg(ctrl_arg, ':', &ctrl_oid,
6717c478bd9Sstevel@tonic-gate 		    &ctrl_criticality, &ctrl_value, &vlen)) {
6727c478bd9Sstevel@tonic-gate 		return (-1);
6737c478bd9Sstevel@tonic-gate 	    }
6747c478bd9Sstevel@tonic-gate 	    ldctrl = calloc(1,sizeof(LDAPControl));
6757c478bd9Sstevel@tonic-gate 	    if (ctrl_value) {
67648bbca81SDaniel Hoffman 		rc = ldaptool_berval_from_ldif_value( ctrl_value,
6777c478bd9Sstevel@tonic-gate 			vlen, &(ldctrl->ldctl_value),
67848bbca81SDaniel Hoffman 			1 /* recognize file URLs */,
6797c478bd9Sstevel@tonic-gate 			0 /* always try file */,
6807c478bd9Sstevel@tonic-gate 			1 /* report errors */ );
6817c478bd9Sstevel@tonic-gate 		if ((rc = ldaptool_fileurlerr2ldaperr( rc )) != LDAP_SUCCESS) {
6827c478bd9Sstevel@tonic-gate 		    fprintf( stderr, gettext("Unable to parse %s\n"), ctrl_value);
6837c478bd9Sstevel@tonic-gate 		    return (-1);
6847c478bd9Sstevel@tonic-gate 		}
6857c478bd9Sstevel@tonic-gate 	    }
6867c478bd9Sstevel@tonic-gate 	    ldctrl->ldctl_oid = ctrl_oid;
6877c478bd9Sstevel@tonic-gate 	    ldctrl->ldctl_iscritical = ctrl_criticality;
6887c478bd9Sstevel@tonic-gate 	    ldaptool_add_control_to_array(ldctrl, ldaptool_request_ctrls);
6897c478bd9Sstevel@tonic-gate 	    break;
6907c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
6917c478bd9Sstevel@tonic-gate 	case 'o':	/* attribute assignment */
6927c478bd9Sstevel@tonic-gate 	      if ((rc = saslSetParam(optarg)) == -1) {
6937c478bd9Sstevel@tonic-gate 	      	  return (-1);
6947c478bd9Sstevel@tonic-gate 	      }
6957c478bd9Sstevel@tonic-gate 	      ldapauth = LDAP_AUTH_SASL;
6967c478bd9Sstevel@tonic-gate 	      ldversion = LDAP_VERSION3;
6977c478bd9Sstevel@tonic-gate 	      break;
6987c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
6997c478bd9Sstevel@tonic-gate 	default:
7007c478bd9Sstevel@tonic-gate 	    (*extra_opt_callback)( i, optarg );
7017c478bd9Sstevel@tonic-gate 	}
7027c478bd9Sstevel@tonic-gate     }
7037c478bd9Sstevel@tonic-gate 
7047c478bd9Sstevel@tonic-gate 
7057c478bd9Sstevel@tonic-gate     /* If '-Z' is specified, check if '-P' is specified too. */
7067c478bd9Sstevel@tonic-gate     if ( isN || isW ) {
7077c478bd9Sstevel@tonic-gate 	if ( !isZ ) {
70848bbca81SDaniel Hoffman 		fprintf( stderr, gettext("%s: with -N, -W options, please specify -Z\n\n"), ldaptool_progname );
7097c478bd9Sstevel@tonic-gate 		return (-1);
7107c478bd9Sstevel@tonic-gate 	}
7117c478bd9Sstevel@tonic-gate     }
7127c478bd9Sstevel@tonic-gate 
7137c478bd9Sstevel@tonic-gate     /* if '-N' is specified, -W is needed too */
7147c478bd9Sstevel@tonic-gate     if ( isN && NULL == ssl_passwd ) {
7157c478bd9Sstevel@tonic-gate         fprintf( stderr, gettext("%s: with the -N option, please specify -W also\n\n"),
7167c478bd9Sstevel@tonic-gate 		ldaptool_progname );
7177c478bd9Sstevel@tonic-gate         return (-1);
7187c478bd9Sstevel@tonic-gate     }
7197c478bd9Sstevel@tonic-gate 
7207c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
7217c478bd9Sstevel@tonic-gate     if ( isj && ( isw || isW )) {
7227c478bd9Sstevel@tonic-gate 	fprintf(stderr, gettext("%s: -j and -w or -W options cannot be specified simultaneously\n\n"), ldaptool_progname );
7237c478bd9Sstevel@tonic-gate #else
7247c478bd9Sstevel@tonic-gate     if ( isj && isw ) {
7257c478bd9Sstevel@tonic-gate 	fprintf(stderr, gettext("%s: -j and -w options cannot be specified simultaneously\n\n"), ldaptool_progname );
7267c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
7277c478bd9Sstevel@tonic-gate 	return (-1);
7287c478bd9Sstevel@tonic-gate     }
7297c478bd9Sstevel@tonic-gate 
7307c478bd9Sstevel@tonic-gate     /* complain if -j or -w does not also have -D, unless using SASL */
7317c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
7327c478bd9Sstevel@tonic-gate     if ( (isj || isw) && !isD && (  ldapauth != LDAP_AUTH_SASL ) ) {
7337c478bd9Sstevel@tonic-gate #else
7347c478bd9Sstevel@tonic-gate     if ( (isj || isw) && !isD ) {
7357c478bd9Sstevel@tonic-gate #endif
7367c478bd9Sstevel@tonic-gate 	fprintf(stderr, gettext("%s: with -j, -w options, please specify -D\n\n"), ldaptool_progname );
7377c478bd9Sstevel@tonic-gate 	return (-1);
7387c478bd9Sstevel@tonic-gate     }
7397c478bd9Sstevel@tonic-gate 
7407c478bd9Sstevel@tonic-gate     /* use default key and cert DB paths if not set on the command line */
7417c478bd9Sstevel@tonic-gate     if ( NULL == ssl_keydbpath ) {
7427c478bd9Sstevel@tonic-gate         if ( NULL == ssl_certdbpath ) {
7437c478bd9Sstevel@tonic-gate             ssl_keydbpath = LDAPTOOL_DEFKEYDBPATH;
7447c478bd9Sstevel@tonic-gate         } else {
7457c478bd9Sstevel@tonic-gate             ssl_keydbpath = certpath2keypath( ssl_certdbpath );
7467c478bd9Sstevel@tonic-gate         }
7477c478bd9Sstevel@tonic-gate     }
7487c478bd9Sstevel@tonic-gate     if ( NULL == ssl_certdbpath ) {
7497c478bd9Sstevel@tonic-gate         ssl_certdbpath = LDAPTOOL_DEFCERTDBPATH;
7507c478bd9Sstevel@tonic-gate     }
7517c478bd9Sstevel@tonic-gate 
7527c478bd9Sstevel@tonic-gate     if (prompt_password != 0) {
7537c478bd9Sstevel@tonic-gate 	char *password_string = "Enter bind password: ";
7547c478bd9Sstevel@tonic-gate 
7557c478bd9Sstevel@tonic-gate #if defined(_WIN32)
7567c478bd9Sstevel@tonic-gate 	char pbuf[257];
7577c478bd9Sstevel@tonic-gate 	fputs(password_string,stdout);
7587c478bd9Sstevel@tonic-gate 	fflush(stdout);
7597c478bd9Sstevel@tonic-gate 	if (fgets(pbuf,256,stdin) == NULL) {
7607c478bd9Sstevel@tonic-gate 	    passwd = NULL;
7617c478bd9Sstevel@tonic-gate 	} else {
7627c478bd9Sstevel@tonic-gate 	    char *tmp;
7637c478bd9Sstevel@tonic-gate 
7647c478bd9Sstevel@tonic-gate 	    tmp = strchr(pbuf,'\n');
7657c478bd9Sstevel@tonic-gate 	    if (tmp) *tmp = '\0';
7667c478bd9Sstevel@tonic-gate 	    tmp = strchr(pbuf,'\r');
7677c478bd9Sstevel@tonic-gate 	    if (tmp) *tmp = '\0';
7687c478bd9Sstevel@tonic-gate 	    passwd = strdup(pbuf);
7697c478bd9Sstevel@tonic-gate 	}
7707c478bd9Sstevel@tonic-gate #else
7717c478bd9Sstevel@tonic-gate #if defined(SOLARIS)
7727c478bd9Sstevel@tonic-gate 	/* 256 characters on Solaris */
7737c478bd9Sstevel@tonic-gate 	passwd = getpassphrase(password_string);
7747c478bd9Sstevel@tonic-gate #else
7757c478bd9Sstevel@tonic-gate 	/* limited to 16 chars on Tru64, 32 on AIX */
7767c478bd9Sstevel@tonic-gate 	passwd = getpass(password_string);
7777c478bd9Sstevel@tonic-gate #endif
7787c478bd9Sstevel@tonic-gate #endif
7797c478bd9Sstevel@tonic-gate 
7807c478bd9Sstevel@tonic-gate     } else if (password_fp != NULL) {
7817c478bd9Sstevel@tonic-gate 	char *linep = NULL;
7827c478bd9Sstevel@tonic-gate 	int   increment = 0;
7837c478bd9Sstevel@tonic-gate 	int   c, index;
7847c478bd9Sstevel@tonic-gate 
7857c478bd9Sstevel@tonic-gate 	/* allocate initial block of memory */
7867c478bd9Sstevel@tonic-gate 	if ((linep = (char *)malloc(BUFSIZ)) == NULL) {
7877c478bd9Sstevel@tonic-gate 	    fprintf( stderr, gettext("%s: not enough memory to read password from file\n"), ldaptool_progname );
7887c478bd9Sstevel@tonic-gate 	    exit( LDAP_NO_MEMORY );
7897c478bd9Sstevel@tonic-gate 	}
7907c478bd9Sstevel@tonic-gate 	increment++;
7917c478bd9Sstevel@tonic-gate 	index = 0;
7927c478bd9Sstevel@tonic-gate 	while ((c = fgetc( password_fp )) != '\n' && c != EOF) {
7937c478bd9Sstevel@tonic-gate 
7947c478bd9Sstevel@tonic-gate 	    /* check if we will overflow the buffer */
7957c478bd9Sstevel@tonic-gate 	    if ((c != EOF) && (index == ((increment * BUFSIZ) -1))) {
7967c478bd9Sstevel@tonic-gate 
7977c478bd9Sstevel@tonic-gate 		/* if we did, add another BUFSIZ worth of bytes */
7987c478bd9Sstevel@tonic-gate 		if ((linep = (char *)
7997c478bd9Sstevel@tonic-gate 		    realloc(linep, (increment + 1) * BUFSIZ)) == NULL) {
8007c478bd9Sstevel@tonic-gate 			fprintf( stderr, gettext("%s: not enough memory to read password from file\n"), ldaptool_progname );
8017c478bd9Sstevel@tonic-gate 			exit( LDAP_NO_MEMORY );
8027c478bd9Sstevel@tonic-gate 		}
8037c478bd9Sstevel@tonic-gate 	 	increment++;
8047c478bd9Sstevel@tonic-gate 	    }
8057c478bd9Sstevel@tonic-gate 	    linep[index++] = c;
8067c478bd9Sstevel@tonic-gate 	}
8077c478bd9Sstevel@tonic-gate 	linep[index] = '\0';
8087c478bd9Sstevel@tonic-gate 	passwd = linep;
8097c478bd9Sstevel@tonic-gate     }
8107c478bd9Sstevel@tonic-gate 
8117c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
8127c478bd9Sstevel@tonic-gate     if (binddn != NULL && passwd == NULL) {
8137c478bd9Sstevel@tonic-gate 	char *password_string = gettext("Enter bind password: ");
8147c478bd9Sstevel@tonic-gate 	passwd = getpassphrase(password_string);
8157c478bd9Sstevel@tonic-gate     }
8167c478bd9Sstevel@tonic-gate 
8177c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
8187c478bd9Sstevel@tonic-gate     if (ldapauth == LDAP_AUTH_SASL) {
81948bbca81SDaniel Hoffman 	/* BindDN not required for SASL */
8207c478bd9Sstevel@tonic-gate 	ldaptool_require_binddn = 0;
8217c478bd9Sstevel@tonic-gate     }
8227c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
8237c478bd9Sstevel@tonic-gate 
8247c478bd9Sstevel@tonic-gate #ifdef NET_SSL
8257c478bd9Sstevel@tonic-gate     if (secure == 1) {
82648bbca81SDaniel Hoffman 	/* BindDN not required for SSL */
8277c478bd9Sstevel@tonic-gate 	ldaptool_require_binddn = 0;
8287c478bd9Sstevel@tonic-gate     }
8297c478bd9Sstevel@tonic-gate #endif	/* NET_SSL */
8307c478bd9Sstevel@tonic-gate 
8317c478bd9Sstevel@tonic-gate     if (ldaptool_require_binddn && binddn == NULL && passwd == NULL) {
8327c478bd9Sstevel@tonic-gate 		fprintf(stderr,
8337c478bd9Sstevel@tonic-gate 			gettext("%s: DN and Bind Password are required.\n"),
8347c478bd9Sstevel@tonic-gate 			ldaptool_progname );
8357c478bd9Sstevel@tonic-gate 		exit(1);
8367c478bd9Sstevel@tonic-gate     }
8377c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
8387c478bd9Sstevel@tonic-gate 
8397c478bd9Sstevel@tonic-gate     /*
8407c478bd9Sstevel@tonic-gate      * If verbose (-v) flag was passed in, display program name and start time.
8417c478bd9Sstevel@tonic-gate      * If the verbose flag was passed at least twice (-vv), also display
8427c478bd9Sstevel@tonic-gate      * information about the API library we are running with.
8437c478bd9Sstevel@tonic-gate      */
8447c478bd9Sstevel@tonic-gate     if ( ldaptool_verbose ) {
8457c478bd9Sstevel@tonic-gate 	time_t	curtime;
8467c478bd9Sstevel@tonic-gate 
8477c478bd9Sstevel@tonic-gate 	curtime = time( NULL );
8487c478bd9Sstevel@tonic-gate 	printf( gettext("%s: started %s\n"), ldaptool_progname, ctime( &curtime ));
8497c478bd9Sstevel@tonic-gate 	if ( ldaptool_verbose > 1 ) {
8507c478bd9Sstevel@tonic-gate 	    print_library_info( &ldai, stdout );
8517c478bd9Sstevel@tonic-gate 	}
8527c478bd9Sstevel@tonic-gate     }
8537c478bd9Sstevel@tonic-gate 
8547c478bd9Sstevel@tonic-gate #ifdef LDAP_TOOL_PKCS11
8557c478bd9Sstevel@tonic-gate     if ((NULL != pkcs_token) && (NULL != ssl_certname)) {
8567c478bd9Sstevel@tonic-gate 	char *result;
85748bbca81SDaniel Hoffman 
8587c478bd9Sstevel@tonic-gate 	if ( (result = buildTokenCertName( pkcs_token, ssl_certname)) != NULL){
8597c478bd9Sstevel@tonic-gate 	    free( ssl_certname );
8607c478bd9Sstevel@tonic-gate 	    ssl_certname = result;
8617c478bd9Sstevel@tonic-gate 	}
8627c478bd9Sstevel@tonic-gate     }
8637c478bd9Sstevel@tonic-gate #endif /* LDAP_TOOL_PKCS11 */
8647c478bd9Sstevel@tonic-gate 
8657c478bd9Sstevel@tonic-gate     free( optstring );
8667c478bd9Sstevel@tonic-gate 
8677c478bd9Sstevel@tonic-gate     /*
8687c478bd9Sstevel@tonic-gate      * Clean up and return index of first non-option argument.
8697c478bd9Sstevel@tonic-gate      */
8707c478bd9Sstevel@tonic-gate     if ( ldai.ldapai_extensions != NULL ) {
8717c478bd9Sstevel@tonic-gate 	ldap_value_free( ldai.ldapai_extensions );
8727c478bd9Sstevel@tonic-gate     }
8737c478bd9Sstevel@tonic-gate     if ( ldai.ldapai_vendor_name != NULL ) {
8747c478bd9Sstevel@tonic-gate 	ldap_memfree( ldai.ldapai_vendor_name );
8757c478bd9Sstevel@tonic-gate     }
8767c478bd9Sstevel@tonic-gate 
8777c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
8787c478bd9Sstevel@tonic-gate     if (ldversion == LDAP_VERSION2 && ldapauth == LDAP_AUTH_SASL) {
8797c478bd9Sstevel@tonic-gate        fprintf( stderr, gettext("Incompatible with version %d\n"), ldversion);
8807c478bd9Sstevel@tonic-gate        return (-1);
8817c478bd9Sstevel@tonic-gate     }
8827c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
8837c478bd9Sstevel@tonic-gate     return( optind );
8847c478bd9Sstevel@tonic-gate }
8857c478bd9Sstevel@tonic-gate 
8867c478bd9Sstevel@tonic-gate 
8877c478bd9Sstevel@tonic-gate /*
8887c478bd9Sstevel@tonic-gate  * Write detailed information about the API library we are running with to fp.
8897c478bd9Sstevel@tonic-gate  */
8907c478bd9Sstevel@tonic-gate static void
8917c478bd9Sstevel@tonic-gate print_library_info( const LDAPAPIInfo *aip, FILE *fp )
8927c478bd9Sstevel@tonic-gate {
89348bbca81SDaniel Hoffman     int                 i;
89448bbca81SDaniel Hoffman     LDAPAPIFeatureInfo  fi;
8957c478bd9Sstevel@tonic-gate 
8967c478bd9Sstevel@tonic-gate     fprintf( fp, gettext("LDAP Library Information -\n"
8977c478bd9Sstevel@tonic-gate 	    "    Highest supported protocol version: %d\n"
8987c478bd9Sstevel@tonic-gate 	    "    LDAP API revision:                  %d\n"
8997c478bd9Sstevel@tonic-gate 	    "    API vendor name:                    %s\n"
9007c478bd9Sstevel@tonic-gate 	    "    Vendor-specific version:            %.2f\n"),
90148bbca81SDaniel Hoffman 	    aip->ldapai_protocol_version, aip->ldapai_api_version,
9027c478bd9Sstevel@tonic-gate 	    aip->ldapai_vendor_name,
9037c478bd9Sstevel@tonic-gate 	    (float)aip->ldapai_vendor_version / 100.0 );
9047c478bd9Sstevel@tonic-gate 
9057c478bd9Sstevel@tonic-gate     if ( aip->ldapai_extensions != NULL ) {
9067c478bd9Sstevel@tonic-gate 	fputs( gettext("    LDAP API Extensions:\n"), fp );
9077c478bd9Sstevel@tonic-gate 
9087c478bd9Sstevel@tonic-gate 	for ( i = 0; aip->ldapai_extensions[i] != NULL; i++ )  {
9097c478bd9Sstevel@tonic-gate 	    fprintf( fp, gettext("        %s"), aip->ldapai_extensions[i] );
9107c478bd9Sstevel@tonic-gate 	    fi.ldapaif_info_version = LDAP_FEATURE_INFO_VERSION;
9117c478bd9Sstevel@tonic-gate 	    fi.ldapaif_name = aip->ldapai_extensions[i];
9127c478bd9Sstevel@tonic-gate 	    fi.ldapaif_version = 0;
9137c478bd9Sstevel@tonic-gate 
9147c478bd9Sstevel@tonic-gate 	    if ( ldap_get_option( NULL, LDAP_OPT_API_FEATURE_INFO, &fi )
9157c478bd9Sstevel@tonic-gate 		    != 0 ) {
9167c478bd9Sstevel@tonic-gate 		fprintf( fp, gettext(" %s: ldap_get_option( NULL,"
9177c478bd9Sstevel@tonic-gate 			" LDAP_OPT_API_FEATURE_INFO, ... ) for %s failed"
9187c478bd9Sstevel@tonic-gate 			" (Feature Info version: %d)\n"), ldaptool_progname,
9197c478bd9Sstevel@tonic-gate 			fi.ldapaif_name, fi.ldapaif_info_version );
9207c478bd9Sstevel@tonic-gate 	    } else {
9217c478bd9Sstevel@tonic-gate 		fprintf( fp, gettext(" (revision %d)\n"), fi.ldapaif_version);
9227c478bd9Sstevel@tonic-gate 	    }
9237c478bd9Sstevel@tonic-gate 	}
9247c478bd9Sstevel@tonic-gate     }
9257c478bd9Sstevel@tonic-gate    fputc( '\n', fp );
9267c478bd9Sstevel@tonic-gate }
9277c478bd9Sstevel@tonic-gate 
9287c478bd9Sstevel@tonic-gate 
9297c478bd9Sstevel@tonic-gate 
9307c478bd9Sstevel@tonic-gate #ifdef LDAP_TOOL_ARGPIN
9317c478bd9Sstevel@tonic-gate static int PinArgRegistration( void )
9327c478bd9Sstevel@tonic-gate {
93348bbca81SDaniel Hoffman 
9347c478bd9Sstevel@tonic-gate     /* pkcs_init was successful  register the pin args */
93548bbca81SDaniel Hoffman 
9367c478bd9Sstevel@tonic-gate     SVRCOREArgPinObj *ArgPinObj;
9377c478bd9Sstevel@tonic-gate     char *tokenName;
9387c478bd9Sstevel@tonic-gate #ifndef _WIN32
9397c478bd9Sstevel@tonic-gate     SVRCOREStdPinObj *StdPinObj;
9407c478bd9Sstevel@tonic-gate #else
9417c478bd9Sstevel@tonic-gate     SVRCOREFilePinObj *FilePinObj;
9427c478bd9Sstevel@tonic-gate     SVRCOREAltPinObj *AltPinObj;
9437c478bd9Sstevel@tonic-gate     SVRCORENTUserPinObj *NTUserPinObj;
9447c478bd9Sstevel@tonic-gate     int err;
9457c478bd9Sstevel@tonic-gate #endif
9467c478bd9Sstevel@tonic-gate     char *pin;
9477c478bd9Sstevel@tonic-gate     char *filename;
9487c478bd9Sstevel@tonic-gate     /* Create and register the pin object for PKCS 11 */
9497c478bd9Sstevel@tonic-gate     local_pkcs_fns.pkcs_getdonglefilename(NULL, &filename);
9507c478bd9Sstevel@tonic-gate     local_pkcs_fns.pkcs_getpin(NULL, "", &pin);
9517c478bd9Sstevel@tonic-gate #ifndef _WIN32
9527c478bd9Sstevel@tonic-gate     if ( SVRCORE_CreateStdPinObj(&StdPinObj, filename, PR_TRUE) !=
9537c478bd9Sstevel@tonic-gate 	 SVRCORE_Success) {
9547c478bd9Sstevel@tonic-gate 	fprintf(stderr, gettext("Security Initialization: Unable to create PinObj "
9557c478bd9Sstevel@tonic-gate 	       "(%d)"), PR_GetError());
9567c478bd9Sstevel@tonic-gate 	return -1;
9577c478bd9Sstevel@tonic-gate     }
9587c478bd9Sstevel@tonic-gate     if (pin != NULL)
9597c478bd9Sstevel@tonic-gate     {
9607c478bd9Sstevel@tonic-gate 	local_pkcs_fns.pkcs_gettokenname(NULL, &tokenName);
9617c478bd9Sstevel@tonic-gate 	SVRCORE_CreateArgPinObj(&ArgPinObj, tokenName, pin, (SVRCOREPinObj *)StdPinObj);
9627c478bd9Sstevel@tonic-gate 	SVRCORE_RegisterPinObj((SVRCOREPinObj *)ArgPinObj);
9637c478bd9Sstevel@tonic-gate     }
9647c478bd9Sstevel@tonic-gate     else
9657c478bd9Sstevel@tonic-gate     {
9667c478bd9Sstevel@tonic-gate 	SVRCORE_RegisterPinObj((SVRCOREPinObj *)StdPinObj);
9677c478bd9Sstevel@tonic-gate     }
9687c478bd9Sstevel@tonic-gate #else
9697c478bd9Sstevel@tonic-gate     if (NULL != pin)
9707c478bd9Sstevel@tonic-gate     {
9717c478bd9Sstevel@tonic-gate 	local_pkcs_fns.pkcs_gettokenname(NULL, &tokenName);
9727c478bd9Sstevel@tonic-gate 	if ((err = SVRCORE_CreateNTUserPinObj(&NTUserPinObj)) != SVRCORE_Success){
9737c478bd9Sstevel@tonic-gate 	    fprintf(stderr, gettext("Security Initialization: Unable to create NTUserPinObj "
9747c478bd9Sstevel@tonic-gate 		   "(%d)"), PR_GetError());
9757c478bd9Sstevel@tonic-gate 	    exit( LDAP_LOCAL_ERROR );
9767c478bd9Sstevel@tonic-gate 	}
9777c478bd9Sstevel@tonic-gate 	if ((err = SVRCORE_CreateArgPinObj(&ArgPinObj, tokenName, pin,
9787c478bd9Sstevel@tonic-gate 					   (SVRCOREPinObj *)NTUserPinObj)) != SVRCORE_Success)
9797c478bd9Sstevel@tonic-gate 	{
9807c478bd9Sstevel@tonic-gate 	    fprintf(stderr, gettext("Security Initialization: Unable to create ArgPinObj "
9817c478bd9Sstevel@tonic-gate 		   "(%d)"), PR_GetError());
9827c478bd9Sstevel@tonic-gate 	    return -1;
9837c478bd9Sstevel@tonic-gate 
9847c478bd9Sstevel@tonic-gate 	}
9857c478bd9Sstevel@tonic-gate 	SVRCORE_RegisterPinObj((SVRCOREPinObj *)ArgPinObj);
98648bbca81SDaniel Hoffman 
9877c478bd9Sstevel@tonic-gate     }
9887c478bd9Sstevel@tonic-gate     else
9897c478bd9Sstevel@tonic-gate     {
9907c478bd9Sstevel@tonic-gate 	if ((err = SVRCORE_CreateNTUserPinObj(&NTUserPinObj)) != SVRCORE_Success){
9917c478bd9Sstevel@tonic-gate 	    fprintf(stderr, gettext("Security Initialization: Unable to create NTUserPinObj "
9927c478bd9Sstevel@tonic-gate 		   "(%d)"), PR_GetError());
9937c478bd9Sstevel@tonic-gate 		return -1;
9947c478bd9Sstevel@tonic-gate 	}
9957c478bd9Sstevel@tonic-gate 	if (filename && *filename)
9967c478bd9Sstevel@tonic-gate 	{
9977c478bd9Sstevel@tonic-gate 	    if ((err = SVRCORE_CreateFilePinObj(&FilePinObj, filename)) !=
9987c478bd9Sstevel@tonic-gate 		SVRCORE_Success) {
9997c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("Security Initialization: Unable to create FilePinObj "
10007c478bd9Sstevel@tonic-gate 		       "(%d)"), PR_GetError());
10017c478bd9Sstevel@tonic-gate 		return -1;
10027c478bd9Sstevel@tonic-gate 
10037c478bd9Sstevel@tonic-gate 	    }
10047c478bd9Sstevel@tonic-gate 	    if ((err = SVRCORE_CreateAltPinObj(&AltPinObj, (SVRCOREPinObj *)FilePinObj,
10057c478bd9Sstevel@tonic-gate 					       (SVRCOREPinObj *)NTUserPinObj)) != SVRCORE_Success) {
10067c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("Security Initialization: Unable to create AltPinObj "
10077c478bd9Sstevel@tonic-gate 		       "(%d)"), PR_GetError());
10087c478bd9Sstevel@tonic-gate 		return -1;
10097c478bd9Sstevel@tonic-gate 	    }
10107c478bd9Sstevel@tonic-gate 	    SVRCORE_RegisterPinObj((SVRCOREPinObj *)AltPinObj);
10117c478bd9Sstevel@tonic-gate 	}
10127c478bd9Sstevel@tonic-gate 	else
10137c478bd9Sstevel@tonic-gate 	{
10147c478bd9Sstevel@tonic-gate 	    SVRCORE_RegisterPinObj((SVRCOREPinObj *)NTUserPinObj);
10157c478bd9Sstevel@tonic-gate 	}
10167c478bd9Sstevel@tonic-gate     }
10177c478bd9Sstevel@tonic-gate #endif
10187c478bd9Sstevel@tonic-gate     return LDAP_SUCCESS;
101948bbca81SDaniel Hoffman 
10207c478bd9Sstevel@tonic-gate }
10217c478bd9Sstevel@tonic-gate #endif /* LDAP_TOOL_ARGPIN */
10227c478bd9Sstevel@tonic-gate 
10237c478bd9Sstevel@tonic-gate 
10247c478bd9Sstevel@tonic-gate /*
10257c478bd9Sstevel@tonic-gate  * initialize and return an LDAP session handle.
10267c478bd9Sstevel@tonic-gate  * if errors occur, we exit here.
10277c478bd9Sstevel@tonic-gate  */
10287c478bd9Sstevel@tonic-gate LDAP *
10297c478bd9Sstevel@tonic-gate ldaptool_ldap_init( int second_host )
10307c478bd9Sstevel@tonic-gate {
10317c478bd9Sstevel@tonic-gate     LDAP	*ld = NULL;
10327c478bd9Sstevel@tonic-gate     char	*host;
10337c478bd9Sstevel@tonic-gate     int		port, rc, user_port;
10347c478bd9Sstevel@tonic-gate 
10357c478bd9Sstevel@tonic-gate     if ( ldaptool_not ) {
10367c478bd9Sstevel@tonic-gate 	return( NULL );
10377c478bd9Sstevel@tonic-gate     }
103848bbca81SDaniel Hoffman 
10397c478bd9Sstevel@tonic-gate     if ( second_host ) {
10407c478bd9Sstevel@tonic-gate 	host = ldaptool_host2;
10417c478bd9Sstevel@tonic-gate 	port = ldaptool_port2;
10427c478bd9Sstevel@tonic-gate 	user_port = user_specified_port2;
10437c478bd9Sstevel@tonic-gate     } else {
10447c478bd9Sstevel@tonic-gate 	host = ldaptool_host;
10457c478bd9Sstevel@tonic-gate 	port = ldaptool_port;
10467c478bd9Sstevel@tonic-gate 	user_port = user_specified_port;
10477c478bd9Sstevel@tonic-gate     }
10487c478bd9Sstevel@tonic-gate 
10497c478bd9Sstevel@tonic-gate 
10507c478bd9Sstevel@tonic-gate     if ( ldaptool_verbose ) {
10517c478bd9Sstevel@tonic-gate 	printf( gettext("ldap_init( %s, %d )\n"), host, port );
10527c478bd9Sstevel@tonic-gate     }
10537c478bd9Sstevel@tonic-gate 
10547c478bd9Sstevel@tonic-gate #if defined(NET_SSL)
10557c478bd9Sstevel@tonic-gate     /*
10567c478bd9Sstevel@tonic-gate      * Initialize security libraries and databases and LDAP session.  If
10577c478bd9Sstevel@tonic-gate      * ssl_certname is not NULL, then we will attempt to use client auth.
10587c478bd9Sstevel@tonic-gate      * if the server supports it.
10597c478bd9Sstevel@tonic-gate      */
10607c478bd9Sstevel@tonic-gate #ifdef LDAP_TOOL_PKCS11
10617c478bd9Sstevel@tonic-gate     ldaptool_setcallbacks( &local_pkcs_fns );
10627c478bd9Sstevel@tonic-gate 
106348bbca81SDaniel Hoffman     if ( !second_host 	&& secure
10647c478bd9Sstevel@tonic-gate 	 &&(rc = ldapssl_pkcs_init( &local_pkcs_fns))  < 0) {
10657c478bd9Sstevel@tonic-gate 	    /* secure connection requested -- fail if no SSL */
10667c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
10677c478bd9Sstevel@tonic-gate 	    rc = PORT_GetError();
10687c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
10697c478bd9Sstevel@tonic-gate 	    fprintf( stderr, gettext("SSL initialization failed: error %d (%s)\n"),
10707c478bd9Sstevel@tonic-gate 		    rc, ldapssl_err2string( rc ));
10717c478bd9Sstevel@tonic-gate 	    exit( LDAP_LOCAL_ERROR );
10727c478bd9Sstevel@tonic-gate     }
10737c478bd9Sstevel@tonic-gate 
10747c478bd9Sstevel@tonic-gate #ifdef LDAP_TOOL_ARGPIN
10757c478bd9Sstevel@tonic-gate     if (secure) {
10767c478bd9Sstevel@tonic-gate 	if (PinArgRegistration( )) {
10777c478bd9Sstevel@tonic-gate 	    exit( LDAP_LOCAL_ERROR);
10787c478bd9Sstevel@tonic-gate 	}
10797c478bd9Sstevel@tonic-gate     }
10807c478bd9Sstevel@tonic-gate #endif /* LDAP_TOOL_ARGPIN */
10817c478bd9Sstevel@tonic-gate 
10827c478bd9Sstevel@tonic-gate #else /* LDAP_TOOL_PKCS11 */
108348bbca81SDaniel Hoffman     if ( !second_host 	&& secure
10847c478bd9Sstevel@tonic-gate 	 &&(rc = ldapssl_client_init( ssl_certdbpath, NULL )) < 0) {
10857c478bd9Sstevel@tonic-gate 	    /* secure connection requested -- fail if no SSL */
10867c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
10877c478bd9Sstevel@tonic-gate 	    rc = PORT_GetError();
10887c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
10897c478bd9Sstevel@tonic-gate 	    fprintf( stderr, gettext("SSL initialization failed: error %d (%s)\n"),
10907c478bd9Sstevel@tonic-gate 		    rc, ldapssl_err2string( rc ));
10917c478bd9Sstevel@tonic-gate 	    exit( LDAP_LOCAL_ERROR );
10927c478bd9Sstevel@tonic-gate     }
10937c478bd9Sstevel@tonic-gate #endif /* LDAP_TOOL_PKCS11 */
10947c478bd9Sstevel@tonic-gate 
10957c478bd9Sstevel@tonic-gate     /* set the default SSL strength (used for all future ld's we create) */
10967c478bd9Sstevel@tonic-gate     if ( ldapssl_set_strength( NULL, ssl_strength ) < 0 ) {
10977c478bd9Sstevel@tonic-gate         perror( "ldapssl_set_strength" );
10987c478bd9Sstevel@tonic-gate         exit( LDAP_LOCAL_ERROR );
10997c478bd9Sstevel@tonic-gate     }
11007c478bd9Sstevel@tonic-gate 
11017c478bd9Sstevel@tonic-gate 
11027c478bd9Sstevel@tonic-gate     if (secure) {
11037c478bd9Sstevel@tonic-gate 	if ( !user_port ) {
11047c478bd9Sstevel@tonic-gate 	    port = LDAPS_PORT;
11057c478bd9Sstevel@tonic-gate 	}
110648bbca81SDaniel Hoffman 
11077c478bd9Sstevel@tonic-gate 	if (( ld = ldapssl_init( host, port,
11087c478bd9Sstevel@tonic-gate 		secure )) != NULL && ssl_certname != NULL )
11097c478bd9Sstevel@tonic-gate 	    if (ldapssl_enable_clientauth( ld, ssl_keydbpath, ssl_passwd,
11107c478bd9Sstevel@tonic-gate 		ssl_certname ) != 0 ) {
11117c478bd9Sstevel@tonic-gate 		exit ( ldaptool_print_lderror( ld, "ldapssl_enable_clientauth",
11127c478bd9Sstevel@tonic-gate 		    LDAPTOOL_CHECK4SSL_ALWAYS ));
11137c478bd9Sstevel@tonic-gate 	    }
11147c478bd9Sstevel@tonic-gate     } else {
11157c478bd9Sstevel@tonic-gate 	/* In order to support IPv6, we use NSPR I/O */
11167c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
11177c478bd9Sstevel@tonic-gate 	ld = ldap_init( host, port );
11187c478bd9Sstevel@tonic-gate #else
11197c478bd9Sstevel@tonic-gate 	ld = prldap_init( host, port, 0 /* not shared across threads */ );
11207c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */
11217c478bd9Sstevel@tonic-gate     }
11227c478bd9Sstevel@tonic-gate 
11237c478bd9Sstevel@tonic-gate #else /* NET_SSL */
11247c478bd9Sstevel@tonic-gate     /* In order to support IPv6, we use NSPR I/O */
11257c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
11267c478bd9Sstevel@tonic-gate     ld = ldap_init( host, port );
11277c478bd9Sstevel@tonic-gate #else
11287c478bd9Sstevel@tonic-gate     ld = prldap_init( host, port, 0 /* not shared across threads */ );
11297c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */
11307c478bd9Sstevel@tonic-gate #endif /* NET_SSL */
11317c478bd9Sstevel@tonic-gate 
11327c478bd9Sstevel@tonic-gate     if ( ld == NULL ) {
11337c478bd9Sstevel@tonic-gate 	perror( "ldap_init" );
11347c478bd9Sstevel@tonic-gate 	exit( LDAP_LOCAL_ERROR );
11357c478bd9Sstevel@tonic-gate     }
11367c478bd9Sstevel@tonic-gate 
11377c478bd9Sstevel@tonic-gate #ifndef NO_LIBLCACHE
11387c478bd9Sstevel@tonic-gate     if ( cache_config_file != NULL ) {
11397c478bd9Sstevel@tonic-gate 	int	opt;
11407c478bd9Sstevel@tonic-gate 
11417c478bd9Sstevel@tonic-gate 	if ( lcache_init( ld, cache_config_file ) != 0 ) {
11427c478bd9Sstevel@tonic-gate 		exit( ldaptool_print_lderror( ld, cache_config_file,
11437c478bd9Sstevel@tonic-gate 			LDAPTOOL_CHECK4SSL_NEVER ));
11447c478bd9Sstevel@tonic-gate 	}
11457c478bd9Sstevel@tonic-gate 	opt = 1;
11467c478bd9Sstevel@tonic-gate 	(void) ldap_set_option( ld, LDAP_OPT_CACHE_ENABLE, &opt );
11477c478bd9Sstevel@tonic-gate 	opt = LDAP_CACHE_LOCALDB;
11487c478bd9Sstevel@tonic-gate 	(void) ldap_set_option( ld, LDAP_OPT_CACHE_STRATEGY, &opt );
11497c478bd9Sstevel@tonic-gate 	if ( ldversion == -1 ) {	/* not set with -V */
11507c478bd9Sstevel@tonic-gate 	    ldversion = LDAP_VERSION2;	/* local db only supports v2 */
11517c478bd9Sstevel@tonic-gate 	}
11527c478bd9Sstevel@tonic-gate     }
11537c478bd9Sstevel@tonic-gate #endif
11547c478bd9Sstevel@tonic-gate 
11557c478bd9Sstevel@tonic-gate 
11567c478bd9Sstevel@tonic-gate     ldap_set_option( ld, LDAP_OPT_REFERRALS, chase_referrals ? LDAP_OPT_ON:
11577c478bd9Sstevel@tonic-gate 	LDAP_OPT_OFF );
11587c478bd9Sstevel@tonic-gate     if ( chase_referrals ) {
11597c478bd9Sstevel@tonic-gate 	ldap_set_rebind_proc( ld, get_rebind_credentials, NULL );
11607c478bd9Sstevel@tonic-gate 	ldap_set_option( ld, LDAP_OPT_REFERRAL_HOP_LIMIT, &refhoplim );
11617c478bd9Sstevel@tonic-gate     }
11627c478bd9Sstevel@tonic-gate 
11637c478bd9Sstevel@tonic-gate     if ( ldversion == -1 ) {	/* not set with -V and not using local db */
11647c478bd9Sstevel@tonic-gate 	ldversion = LDAP_VERSION3;
11657c478bd9Sstevel@tonic-gate     }
11667c478bd9Sstevel@tonic-gate     ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &ldversion );
11677c478bd9Sstevel@tonic-gate 
11687c478bd9Sstevel@tonic-gate     return( ld );
11697c478bd9Sstevel@tonic-gate }
11707c478bd9Sstevel@tonic-gate 
11717c478bd9Sstevel@tonic-gate 
11727c478bd9Sstevel@tonic-gate /*
11737c478bd9Sstevel@tonic-gate  * perform a bind to the LDAP server if needed.
11747c478bd9Sstevel@tonic-gate  * if an error occurs, we exit here.
11757c478bd9Sstevel@tonic-gate  */
11767c478bd9Sstevel@tonic-gate void
11777c478bd9Sstevel@tonic-gate ldaptool_bind( LDAP *ld )
11787c478bd9Sstevel@tonic-gate {
11797c478bd9Sstevel@tonic-gate     int		rc;
11807c478bd9Sstevel@tonic-gate     char	*conv;
11817c478bd9Sstevel@tonic-gate     LDAPControl	auth_resp_ctrl, *ctrl_array[ 2 ], **bindctrls;
11827c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
11837c478bd9Sstevel@tonic-gate     void *defaults;
11847c478bd9Sstevel@tonic-gate #endif
11857c478bd9Sstevel@tonic-gate 
11867c478bd9Sstevel@tonic-gate     if ( ldaptool_not ) {
11877c478bd9Sstevel@tonic-gate 	return;
11887c478bd9Sstevel@tonic-gate     }
11897c478bd9Sstevel@tonic-gate 
11907c478bd9Sstevel@tonic-gate     if ( send_auth_response_ctrl ) {
11917c478bd9Sstevel@tonic-gate 	auth_resp_ctrl.ldctl_oid = LDAP_CONTROL_AUTH_REQUEST;
11927c478bd9Sstevel@tonic-gate 	auth_resp_ctrl.ldctl_value.bv_val = NULL;
11937c478bd9Sstevel@tonic-gate 	auth_resp_ctrl.ldctl_value.bv_len = 0;
11947c478bd9Sstevel@tonic-gate 	auth_resp_ctrl.ldctl_iscritical = 0;
11957c478bd9Sstevel@tonic-gate 
11967c478bd9Sstevel@tonic-gate 	ctrl_array[0] = &auth_resp_ctrl;
11977c478bd9Sstevel@tonic-gate 	ctrl_array[1] = NULL;
11987c478bd9Sstevel@tonic-gate 	bindctrls = ctrl_array;
11997c478bd9Sstevel@tonic-gate     } else {
12007c478bd9Sstevel@tonic-gate 	bindctrls = NULL;
12017c478bd9Sstevel@tonic-gate     }
12027c478bd9Sstevel@tonic-gate 
12037c478bd9Sstevel@tonic-gate     /*
12047c478bd9Sstevel@tonic-gate      * if using LDAPv3 and not using client auth., omit NULL bind for
12057c478bd9Sstevel@tonic-gate      * efficiency.
12067c478bd9Sstevel@tonic-gate      */
12077c478bd9Sstevel@tonic-gate     if ( ldversion > LDAP_VERSION2 && binddn == NULL && passwd == NULL
12087c478bd9Sstevel@tonic-gate 	    && ssl_certname == NULL ) {
12097c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
12107c478bd9Sstevel@tonic-gate 	if ( ldapauth != LDAP_AUTH_SASL ) {
12117c478bd9Sstevel@tonic-gate 	   return;
12127c478bd9Sstevel@tonic-gate 	}
12137c478bd9Sstevel@tonic-gate #else
12147c478bd9Sstevel@tonic-gate 	return;
12157c478bd9Sstevel@tonic-gate #endif
12167c478bd9Sstevel@tonic-gate     }
12177c478bd9Sstevel@tonic-gate 
12187c478bd9Sstevel@tonic-gate     /*
12197c478bd9Sstevel@tonic-gate      * do the bind, backing off one LDAP version if necessary
12207c478bd9Sstevel@tonic-gate      */
12217c478bd9Sstevel@tonic-gate     conv = ldaptool_local2UTF8( binddn );
12227c478bd9Sstevel@tonic-gate 
12237c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
12247c478bd9Sstevel@tonic-gate     if ( ldapauth == LDAP_AUTH_SASL) {
12257c478bd9Sstevel@tonic-gate 	if ( sasl_mech == NULL) {
12267c478bd9Sstevel@tonic-gate 	   fprintf( stderr, gettext("Please specify the SASL mechanism name when "
12277c478bd9Sstevel@tonic-gate 				"using SASL options\n"));
12287c478bd9Sstevel@tonic-gate 	   return;
12297c478bd9Sstevel@tonic-gate 	}
12307c478bd9Sstevel@tonic-gate 
12317c478bd9Sstevel@tonic-gate         if ( sasl_secprops != NULL) {
12327c478bd9Sstevel@tonic-gate            rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
12337c478bd9Sstevel@tonic-gate                                 (void *) sasl_secprops );
12347c478bd9Sstevel@tonic-gate 
12357c478bd9Sstevel@tonic-gate            if ( rc != LDAP_SUCCESS ) {
12367c478bd9Sstevel@tonic-gate               fprintf( stderr, gettext("Unable to set LDAP_OPT_X_SASL_SECPROPS: %s\n"),
12377c478bd9Sstevel@tonic-gate 				sasl_secprops );
12387c478bd9Sstevel@tonic-gate               return;
12397c478bd9Sstevel@tonic-gate            }
12407c478bd9Sstevel@tonic-gate         }
124148bbca81SDaniel Hoffman 
12427c478bd9Sstevel@tonic-gate         defaults = ldaptool_set_sasl_defaults( ld, sasl_mech, sasl_authid, sasl_username, passwd, sasl_realm );
12437c478bd9Sstevel@tonic-gate         if (defaults == NULL) {
12447c478bd9Sstevel@tonic-gate 	   perror ("malloc");
12457c478bd9Sstevel@tonic-gate 	   exit (LDAP_NO_MEMORY);
12467c478bd9Sstevel@tonic-gate 	}
12477c478bd9Sstevel@tonic-gate 
12487c478bd9Sstevel@tonic-gate         rc = ldap_sasl_interactive_bind_s( ld, binddn, sasl_mech, NULL, NULL,
12497c478bd9Sstevel@tonic-gate                         sasl_flags, ldaptool_sasl_interact, defaults );
12507c478bd9Sstevel@tonic-gate 
12517c478bd9Sstevel@tonic-gate         if (rc != LDAP_SUCCESS ) {
12527c478bd9Sstevel@tonic-gate            ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
12537c478bd9Sstevel@tonic-gate         }
12547c478bd9Sstevel@tonic-gate     } else
12557c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
12567c478bd9Sstevel@tonic-gate         /*
12577c478bd9Sstevel@tonic-gate          * if using LDAPv3 and client auth., try a SASL EXTERNAL bind
12587c478bd9Sstevel@tonic-gate          */
12597c478bd9Sstevel@tonic-gate          if ( ldversion > LDAP_VERSION2 && binddn == NULL && passwd == NULL
12607c478bd9Sstevel@tonic-gate 	    	&& ssl_certname != NULL ) {
12617c478bd9Sstevel@tonic-gate 	     rc = ldaptool_sasl_bind_s( ld, NULL, LDAP_SASL_EXTERNAL, NULL,
12627c478bd9Sstevel@tonic-gate 			bindctrls, NULL, NULL, "ldap_sasl_bind" );
12637c478bd9Sstevel@tonic-gate     	 }
12647c478bd9Sstevel@tonic-gate          else {
12657c478bd9Sstevel@tonic-gate 	     rc = ldaptool_simple_bind_s( ld, conv, passwd, bindctrls, NULL,
12667c478bd9Sstevel@tonic-gate 		    "ldap_simple_bind" );
12677c478bd9Sstevel@tonic-gate 	  }
12687c478bd9Sstevel@tonic-gate 
12697c478bd9Sstevel@tonic-gate     if ( rc == LDAP_SUCCESS ) {
12707c478bd9Sstevel@tonic-gate         if ( conv != NULL ) {
12717c478bd9Sstevel@tonic-gate            free( conv );
12727c478bd9Sstevel@tonic-gate 	}
12737c478bd9Sstevel@tonic-gate 	return;			/* success */
12747c478bd9Sstevel@tonic-gate     }
12757c478bd9Sstevel@tonic-gate 
12767c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
12777c478bd9Sstevel@tonic-gate   if (ldapauth != LDAP_AUTH_SASL) {
12787c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
12797c478bd9Sstevel@tonic-gate     if ( rc == LDAP_PROTOCOL_ERROR && ldversion > LDAP_VERSION2 ) {
12807c478bd9Sstevel@tonic-gate 	/*
12817c478bd9Sstevel@tonic-gate 	 * try again, backing off one LDAP version
12827c478bd9Sstevel@tonic-gate 	 * this is okay even for client auth. because the way to achieve
12837c478bd9Sstevel@tonic-gate 	 * client auth. with LDAPv2 is to perform a NULL simple bind.
12847c478bd9Sstevel@tonic-gate 	 */
12857c478bd9Sstevel@tonic-gate 	--ldversion;
12867c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: the server doesn't understand LDAPv%d;"
12877c478bd9Sstevel@tonic-gate 		" trying LDAPv%d instead...\n"), ldaptool_progname,
12887c478bd9Sstevel@tonic-gate 		ldversion + 1, ldversion );
12897c478bd9Sstevel@tonic-gate 	ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &ldversion );
12907c478bd9Sstevel@tonic-gate 	if (( rc = ldaptool_simple_bind_s( ld, conv, passwd,
12917c478bd9Sstevel@tonic-gate 		bindctrls, NULL, "ldap_simple_bind" )) == LDAP_SUCCESS ) {
12927c478bd9Sstevel@tonic-gate             if( conv != NULL )
12937c478bd9Sstevel@tonic-gate                 free( conv );
12947c478bd9Sstevel@tonic-gate 	    return;		/* a qualified success */
12957c478bd9Sstevel@tonic-gate 	}
12967c478bd9Sstevel@tonic-gate     }
12977c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
12987c478bd9Sstevel@tonic-gate   }
12997c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
13007c478bd9Sstevel@tonic-gate 
13017c478bd9Sstevel@tonic-gate     if ( conv != NULL ) {
13027c478bd9Sstevel@tonic-gate         free( conv );
13037c478bd9Sstevel@tonic-gate     }
13047c478bd9Sstevel@tonic-gate 
13057c478bd9Sstevel@tonic-gate     /*
13067c478bd9Sstevel@tonic-gate      * bind(s) failed -- fatal error
13077c478bd9Sstevel@tonic-gate      */
13087c478bd9Sstevel@tonic-gate     ldap_unbind( ld );
13097c478bd9Sstevel@tonic-gate     exit( rc );
13107c478bd9Sstevel@tonic-gate }
13117c478bd9Sstevel@tonic-gate 
13127c478bd9Sstevel@tonic-gate 
13137c478bd9Sstevel@tonic-gate /*
13147c478bd9Sstevel@tonic-gate  * close open files, unbind, etc.
13157c478bd9Sstevel@tonic-gate  */
13167c478bd9Sstevel@tonic-gate void
13177c478bd9Sstevel@tonic-gate ldaptool_cleanup( LDAP *ld )
13187c478bd9Sstevel@tonic-gate {
13197c478bd9Sstevel@tonic-gate     if ( ld != NULL ) {
13207c478bd9Sstevel@tonic-gate 	ldap_unbind( ld );
13217c478bd9Sstevel@tonic-gate     }
13227c478bd9Sstevel@tonic-gate 
13237c478bd9Sstevel@tonic-gate     if ( ldaptool_fp != NULL && ldaptool_fp != stdin ) {
13247c478bd9Sstevel@tonic-gate 	fclose( ldaptool_fp );
13257c478bd9Sstevel@tonic-gate 	ldaptool_fp = NULL;
13267c478bd9Sstevel@tonic-gate     }
13277c478bd9Sstevel@tonic-gate }
13287c478bd9Sstevel@tonic-gate 
13297c478bd9Sstevel@tonic-gate 
13307c478bd9Sstevel@tonic-gate /*
13317c478bd9Sstevel@tonic-gate  * Retrieve and print an LDAP error message.  Returns the LDAP error code.
13327c478bd9Sstevel@tonic-gate  */
13337c478bd9Sstevel@tonic-gate int
13347c478bd9Sstevel@tonic-gate ldaptool_print_lderror( LDAP *ld, char *msg, int check4ssl )
13357c478bd9Sstevel@tonic-gate {
13367c478bd9Sstevel@tonic-gate     int		lderr = ldap_get_lderrno( ld, NULL, NULL );
13377c478bd9Sstevel@tonic-gate 
13387c478bd9Sstevel@tonic-gate     ldap_perror( ld, msg );
13397c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
13407c478bd9Sstevel@tonic-gate     if ( secure && check4ssl != LDAPTOOL_CHECK4SSL_NEVER ) {
13417c478bd9Sstevel@tonic-gate 	if ( check4ssl == LDAPTOOL_CHECK4SSL_ALWAYS
13427c478bd9Sstevel@tonic-gate 		|| ( lderr == LDAP_SERVER_DOWN )) {
13437c478bd9Sstevel@tonic-gate 	    int		sslerr = PORT_GetError();
13447c478bd9Sstevel@tonic-gate 
13457c478bd9Sstevel@tonic-gate 	    fprintf( stderr, gettext("\tSSL error %d (%s)\n"), sslerr,
13467c478bd9Sstevel@tonic-gate 		    ldapssl_err2string( sslerr ));
13477c478bd9Sstevel@tonic-gate 	}
13487c478bd9Sstevel@tonic-gate     }
13497c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
13507c478bd9Sstevel@tonic-gate 
13517c478bd9Sstevel@tonic-gate     return( lderr );
13527c478bd9Sstevel@tonic-gate }
13537c478bd9Sstevel@tonic-gate 
13547c478bd9Sstevel@tonic-gate 
13557c478bd9Sstevel@tonic-gate /*
13567c478bd9Sstevel@tonic-gate  * print referrals to stderr
13577c478bd9Sstevel@tonic-gate  */
13587c478bd9Sstevel@tonic-gate void
13597c478bd9Sstevel@tonic-gate ldaptool_print_referrals( char **refs )
13607c478bd9Sstevel@tonic-gate {
13617c478bd9Sstevel@tonic-gate     int		i;
13627c478bd9Sstevel@tonic-gate 
13637c478bd9Sstevel@tonic-gate     if ( refs != NULL ) {
13647c478bd9Sstevel@tonic-gate 	for ( i = 0; refs[ i ] != NULL; ++i ) {
13657c478bd9Sstevel@tonic-gate 	    fprintf( stderr, gettext("Referral: %s\n"), refs[ i ] );
13667c478bd9Sstevel@tonic-gate 	}
13677c478bd9Sstevel@tonic-gate     }
13687c478bd9Sstevel@tonic-gate }
13697c478bd9Sstevel@tonic-gate 
13707c478bd9Sstevel@tonic-gate 
13717c478bd9Sstevel@tonic-gate /*
13727c478bd9Sstevel@tonic-gate  * print contents of an extended response to stderr
13737c478bd9Sstevel@tonic-gate  * this is mainly to support unsolicited notifications
13747c478bd9Sstevel@tonic-gate  * Returns an LDAP error code (from the extended result).
13757c478bd9Sstevel@tonic-gate  */
13767c478bd9Sstevel@tonic-gate int
13777c478bd9Sstevel@tonic-gate ldaptool_print_extended_response( LDAP *ld, LDAPMessage *res, char *msg )
13787c478bd9Sstevel@tonic-gate {
13797c478bd9Sstevel@tonic-gate     char		*oid;
13807c478bd9Sstevel@tonic-gate     struct berval	*data;
13817c478bd9Sstevel@tonic-gate 
13827c478bd9Sstevel@tonic-gate     if ( ldap_parse_extended_result( ld, res, &oid, &data, 0 )
13837c478bd9Sstevel@tonic-gate 	    != LDAP_SUCCESS ) {
13847c478bd9Sstevel@tonic-gate 	ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP );
13857c478bd9Sstevel@tonic-gate     } else {
13867c478bd9Sstevel@tonic-gate 	if ( oid != NULL ) {
13877c478bd9Sstevel@tonic-gate 	    if ( strcmp ( oid, LDAP_NOTICE_OF_DISCONNECTION ) == 0 ) {
13887c478bd9Sstevel@tonic-gate 		fprintf( stderr, gettext("%s: Notice of Disconnection\n"), msg );
13897c478bd9Sstevel@tonic-gate 	    } else {
13907c478bd9Sstevel@tonic-gate 		fprintf( stderr, gettext("%s: OID %s\n"), msg, oid );
13917c478bd9Sstevel@tonic-gate 	    }
13927c478bd9Sstevel@tonic-gate 	    ldap_memfree( oid );
13937c478bd9Sstevel@tonic-gate 	} else {
13947c478bd9Sstevel@tonic-gate 	    fprintf( stderr, gettext("%s: missing OID\n"), msg );
13957c478bd9Sstevel@tonic-gate 	}
13967c478bd9Sstevel@tonic-gate 
13977c478bd9Sstevel@tonic-gate 	if ( data != NULL ) {
13987c478bd9Sstevel@tonic-gate 	    fprintf( stderr, gettext("%s: Data (length %ld):\n"), msg, data->bv_len );
13997c478bd9Sstevel@tonic-gate #if 0
14007c478bd9Sstevel@tonic-gate /* XXXmcs: maybe we should display the actual data? */
14017c478bd9Sstevel@tonic-gate 	    lber_bprint( data->bv_val, data->bv_len );
14027c478bd9Sstevel@tonic-gate #endif
14037c478bd9Sstevel@tonic-gate 	    ber_bvfree( data );
14047c478bd9Sstevel@tonic-gate 	}
14057c478bd9Sstevel@tonic-gate     }
14067c478bd9Sstevel@tonic-gate 
14077c478bd9Sstevel@tonic-gate     return parse_result( ld, res, NULL, msg, 1 );
14087c478bd9Sstevel@tonic-gate }
14097c478bd9Sstevel@tonic-gate 
14107c478bd9Sstevel@tonic-gate 
14117c478bd9Sstevel@tonic-gate /*
14127c478bd9Sstevel@tonic-gate  * Like ldap_sasl_bind_s() but calls wait4result() to display
14137c478bd9Sstevel@tonic-gate  * any referrals returned and report errors in a consistent way.
14147c478bd9Sstevel@tonic-gate  */
14157c478bd9Sstevel@tonic-gate int
14167c478bd9Sstevel@tonic-gate ldaptool_sasl_bind_s( LDAP *ld, const char *dn, const char *mechanism,
14177c478bd9Sstevel@tonic-gate 	const struct berval *cred, LDAPControl **serverctrls,
14187c478bd9Sstevel@tonic-gate 	LDAPControl **clientctrls, struct berval **servercredp, char *msg )
14197c478bd9Sstevel@tonic-gate {
14207c478bd9Sstevel@tonic-gate     int		rc, msgid;
14217c478bd9Sstevel@tonic-gate 
14227c478bd9Sstevel@tonic-gate     if ( servercredp != NULL ) {
14237c478bd9Sstevel@tonic-gate 	    *servercredp = NULL;
14247c478bd9Sstevel@tonic-gate     }
14257c478bd9Sstevel@tonic-gate 
14267c478bd9Sstevel@tonic-gate     if (( rc = ldap_sasl_bind( ld, dn, mechanism, cred, serverctrls,
14277c478bd9Sstevel@tonic-gate 	    clientctrls, &msgid )) != LDAP_SUCCESS ) {
14287c478bd9Sstevel@tonic-gate 	ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP );
14297c478bd9Sstevel@tonic-gate     } else {
14307c478bd9Sstevel@tonic-gate 	rc = wait4result( ld, msgid, servercredp, msg );
14317c478bd9Sstevel@tonic-gate     }
14327c478bd9Sstevel@tonic-gate 
14337c478bd9Sstevel@tonic-gate     return( rc );
14347c478bd9Sstevel@tonic-gate }
14357c478bd9Sstevel@tonic-gate 
14367c478bd9Sstevel@tonic-gate 
14377c478bd9Sstevel@tonic-gate /*
14387c478bd9Sstevel@tonic-gate  * Like ldap_simple_bind_s() but calls wait4result() to display
14397c478bd9Sstevel@tonic-gate  * any referrals returned and report errors in a consistent way.
14407c478bd9Sstevel@tonic-gate  */
14417c478bd9Sstevel@tonic-gate int
14427c478bd9Sstevel@tonic-gate ldaptool_simple_bind_s( LDAP *ld, const char *dn, const char *passwd,
14437c478bd9Sstevel@tonic-gate 	LDAPControl **serverctrls, LDAPControl **clientctrls, char *msg )
14447c478bd9Sstevel@tonic-gate {
14457c478bd9Sstevel@tonic-gate     struct berval	bv;
14467c478bd9Sstevel@tonic-gate 
14477c478bd9Sstevel@tonic-gate     bv.bv_val = (char *)passwd;		/* XXXmcs: had to cast away const */
14487c478bd9Sstevel@tonic-gate     bv.bv_len = ( passwd == NULL ? 0 : strlen( passwd ));
14497c478bd9Sstevel@tonic-gate     return( ldaptool_sasl_bind_s( ld, dn, LDAP_SASL_SIMPLE, &bv, serverctrls,
14507c478bd9Sstevel@tonic-gate 	    clientctrls, NULL, msg ));
14517c478bd9Sstevel@tonic-gate }
14527c478bd9Sstevel@tonic-gate 
14537c478bd9Sstevel@tonic-gate 
14547c478bd9Sstevel@tonic-gate /*
14557c478bd9Sstevel@tonic-gate  * Like ldap_add_ext_s() but calls wait4result() to display
14567c478bd9Sstevel@tonic-gate  * any referrals returned and report errors in a consistent way.
14577c478bd9Sstevel@tonic-gate  */
14587c478bd9Sstevel@tonic-gate int
14597c478bd9Sstevel@tonic-gate ldaptool_add_ext_s( LDAP *ld, const char *dn, LDAPMod **attrs,
14607c478bd9Sstevel@tonic-gate 	LDAPControl **serverctrls, LDAPControl **clientctrls, char *msg )
14617c478bd9Sstevel@tonic-gate {
14627c478bd9Sstevel@tonic-gate     int		rc, msgid;
14637c478bd9Sstevel@tonic-gate 
14647c478bd9Sstevel@tonic-gate     if (( rc = ldap_add_ext( ld, dn, attrs, serverctrls, clientctrls, &msgid ))
14657c478bd9Sstevel@tonic-gate 	    != LDAP_SUCCESS ) {
14667c478bd9Sstevel@tonic-gate 	ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP );
14677c478bd9Sstevel@tonic-gate     } else {
14687c478bd9Sstevel@tonic-gate 	/*
14697c478bd9Sstevel@tonic-gate 	 * 25-April-2000 Note: the next line used to read:
14707c478bd9Sstevel@tonic-gate 	 *	rc = wait4result( ld, msgid, NULL, msg );
14717c478bd9Sstevel@tonic-gate 	 * 'msgid' it was changed to 'LDAP_RES_ANY' in order to receive
14727c478bd9Sstevel@tonic-gate 	 * unsolicited notifications.
14737c478bd9Sstevel@tonic-gate 	 */
14747c478bd9Sstevel@tonic-gate 	rc = wait4result( ld, LDAP_RES_ANY, NULL, msg );
14757c478bd9Sstevel@tonic-gate     }
14767c478bd9Sstevel@tonic-gate 
14777c478bd9Sstevel@tonic-gate     return( rc );
14787c478bd9Sstevel@tonic-gate }
14797c478bd9Sstevel@tonic-gate 
14807c478bd9Sstevel@tonic-gate 
14817c478bd9Sstevel@tonic-gate /*
14827c478bd9Sstevel@tonic-gate  * Like ldap_modify_ext_s() but calls wait4result() to display
14837c478bd9Sstevel@tonic-gate  * any referrals returned and report errors in a consistent way.
14847c478bd9Sstevel@tonic-gate  */
14857c478bd9Sstevel@tonic-gate int
14867c478bd9Sstevel@tonic-gate ldaptool_modify_ext_s( LDAP *ld, const char *dn, LDAPMod **mods,
14877c478bd9Sstevel@tonic-gate 	LDAPControl **serverctrls, LDAPControl **clientctrls, char *msg )
14887c478bd9Sstevel@tonic-gate {
14897c478bd9Sstevel@tonic-gate     int		rc, msgid;
14907c478bd9Sstevel@tonic-gate 
14917c478bd9Sstevel@tonic-gate     if (( rc = ldap_modify_ext( ld, dn, mods, serverctrls, clientctrls,
14927c478bd9Sstevel@tonic-gate 	    &msgid )) != LDAP_SUCCESS ) {
14937c478bd9Sstevel@tonic-gate 	ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP );
14947c478bd9Sstevel@tonic-gate     } else {
14957c478bd9Sstevel@tonic-gate 	rc = wait4result( ld, msgid, NULL, msg );
14967c478bd9Sstevel@tonic-gate     }
14977c478bd9Sstevel@tonic-gate 
14987c478bd9Sstevel@tonic-gate     return( rc );
14997c478bd9Sstevel@tonic-gate }
15007c478bd9Sstevel@tonic-gate 
15017c478bd9Sstevel@tonic-gate 
15027c478bd9Sstevel@tonic-gate /*
15037c478bd9Sstevel@tonic-gate  * Like ldap_delete_ext_s() but calls wait4result() to display
15047c478bd9Sstevel@tonic-gate  * any referrals returned and report errors in a consistent way.
15057c478bd9Sstevel@tonic-gate  */
15067c478bd9Sstevel@tonic-gate int
15077c478bd9Sstevel@tonic-gate ldaptool_delete_ext_s( LDAP *ld, const char *dn, LDAPControl **serverctrls,
15087c478bd9Sstevel@tonic-gate 	LDAPControl **clientctrls, char *msg )
15097c478bd9Sstevel@tonic-gate {
15107c478bd9Sstevel@tonic-gate     int		rc, msgid;
15117c478bd9Sstevel@tonic-gate 
15127c478bd9Sstevel@tonic-gate     if (( rc = ldap_delete_ext( ld, dn, serverctrls, clientctrls, &msgid ))
15137c478bd9Sstevel@tonic-gate 	    != LDAP_SUCCESS ) {
15147c478bd9Sstevel@tonic-gate 	ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP );
15157c478bd9Sstevel@tonic-gate     } else {
15167c478bd9Sstevel@tonic-gate 	rc = wait4result( ld, msgid, NULL, msg );
15177c478bd9Sstevel@tonic-gate     }
15187c478bd9Sstevel@tonic-gate 
15197c478bd9Sstevel@tonic-gate     return( rc );
15207c478bd9Sstevel@tonic-gate }
15217c478bd9Sstevel@tonic-gate 
15227c478bd9Sstevel@tonic-gate 
15237c478bd9Sstevel@tonic-gate /*
15247c478bd9Sstevel@tonic-gate  * Like ldap_compare_ext_s() but calls wait4result() to display
15257c478bd9Sstevel@tonic-gate  * any referrals returned and report errors in a consistent way.
15267c478bd9Sstevel@tonic-gate  */
15277c478bd9Sstevel@tonic-gate int ldaptool_compare_ext_s( LDAP *ld, const char *dn, const char *attrtype,
15287c478bd9Sstevel@tonic-gate 	    const struct berval *bvalue, LDAPControl **serverctrls,
15297c478bd9Sstevel@tonic-gate 	    LDAPControl **clientctrls, char *msg )
15307c478bd9Sstevel@tonic-gate {
15317c478bd9Sstevel@tonic-gate     int		rc, msgid;
15327c478bd9Sstevel@tonic-gate 
15337c478bd9Sstevel@tonic-gate     if (( rc = ldap_compare_ext( ld, dn, attrtype, bvalue, serverctrls,
15347c478bd9Sstevel@tonic-gate 	    clientctrls, &msgid )) != LDAP_SUCCESS ) {
15357c478bd9Sstevel@tonic-gate 	ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP );
15367c478bd9Sstevel@tonic-gate     } else {
15377c478bd9Sstevel@tonic-gate 	rc = wait4result( ld, msgid, NULL, msg );
15387c478bd9Sstevel@tonic-gate     }
15397c478bd9Sstevel@tonic-gate 
15407c478bd9Sstevel@tonic-gate     return( rc );
15417c478bd9Sstevel@tonic-gate }
15427c478bd9Sstevel@tonic-gate 
15437c478bd9Sstevel@tonic-gate 
15447c478bd9Sstevel@tonic-gate /*
15457c478bd9Sstevel@tonic-gate  * Like ldap_rename_s() but calls wait4result() to display
15467c478bd9Sstevel@tonic-gate  * any referrals returned and report errors in a consistent way.
15477c478bd9Sstevel@tonic-gate  */
15487c478bd9Sstevel@tonic-gate int
15497c478bd9Sstevel@tonic-gate ldaptool_rename_s(  LDAP *ld, const char *dn, const char *newrdn,
15507c478bd9Sstevel@tonic-gate 	const char *newparent, int deleteoldrdn, LDAPControl **serverctrls,
15517c478bd9Sstevel@tonic-gate 	LDAPControl **clientctrls, char *msg )
15527c478bd9Sstevel@tonic-gate {
15537c478bd9Sstevel@tonic-gate     int		rc, msgid;
15547c478bd9Sstevel@tonic-gate 
15557c478bd9Sstevel@tonic-gate     if (( rc = ldap_rename( ld, dn, newrdn, newparent, deleteoldrdn,
15567c478bd9Sstevel@tonic-gate 	    serverctrls, clientctrls, &msgid )) != LDAP_SUCCESS ) {
15577c478bd9Sstevel@tonic-gate 	ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP );
15587c478bd9Sstevel@tonic-gate     } else {
15597c478bd9Sstevel@tonic-gate 	rc = wait4result( ld, msgid, NULL, msg );
15607c478bd9Sstevel@tonic-gate     }
15617c478bd9Sstevel@tonic-gate 
15627c478bd9Sstevel@tonic-gate     return( rc );
15637c478bd9Sstevel@tonic-gate }
15647c478bd9Sstevel@tonic-gate 
15657c478bd9Sstevel@tonic-gate 
15667c478bd9Sstevel@tonic-gate /*
15677c478bd9Sstevel@tonic-gate  * Wait for a result, check for and display errors and referrals.
15687c478bd9Sstevel@tonic-gate  * Also recognize and display "Unsolicited notification" messages.
15697c478bd9Sstevel@tonic-gate  * Returns an LDAP error code.
15707c478bd9Sstevel@tonic-gate  */
15717c478bd9Sstevel@tonic-gate static int
15727c478bd9Sstevel@tonic-gate wait4result( LDAP *ld, int msgid, struct berval **servercredp, char *msg )
15737c478bd9Sstevel@tonic-gate {
15747c478bd9Sstevel@tonic-gate     LDAPMessage	*res;
15757c478bd9Sstevel@tonic-gate     int		rc, received_only_unsolicited = 1;
15767c478bd9Sstevel@tonic-gate 
15777c478bd9Sstevel@tonic-gate     while ( received_only_unsolicited ) {
15787c478bd9Sstevel@tonic-gate 	res = NULL;
15797c478bd9Sstevel@tonic-gate 	if (( rc = ldap_result( ld, msgid, 1, (struct timeval *)NULL, &res ))
15807c478bd9Sstevel@tonic-gate 		    == -1 ) {
15817c478bd9Sstevel@tonic-gate 	    ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP );
15827c478bd9Sstevel@tonic-gate 	    return( ldap_get_lderrno( ld, NULL, NULL ));
15837c478bd9Sstevel@tonic-gate 	}
15847c478bd9Sstevel@tonic-gate 
15857c478bd9Sstevel@tonic-gate 	/*
15867c478bd9Sstevel@tonic-gate 	 * Special handling for unsolicited notifications:
15877c478bd9Sstevel@tonic-gate 	 *    1. Parse and display contents.
15887c478bd9Sstevel@tonic-gate 	 *    2. go back and wait for another (real) result.
15897c478bd9Sstevel@tonic-gate 	 */
15907c478bd9Sstevel@tonic-gate 	if ( rc == LDAP_RES_EXTENDED
15917c478bd9Sstevel@tonic-gate 		    && ldap_msgid( res ) == LDAP_RES_UNSOLICITED ) {
15927c478bd9Sstevel@tonic-gate 	    rc = ldaptool_print_extended_response( ld, res,
15937c478bd9Sstevel@tonic-gate 		    "Unsolicited response" );
15947c478bd9Sstevel@tonic-gate 	} else {
15957c478bd9Sstevel@tonic-gate 	    rc = parse_result( ld, res, servercredp, msg, 1 );
15967c478bd9Sstevel@tonic-gate 	    received_only_unsolicited = 0;	/* we're done */
15977c478bd9Sstevel@tonic-gate 	}
15987c478bd9Sstevel@tonic-gate     }
15997c478bd9Sstevel@tonic-gate 
16007c478bd9Sstevel@tonic-gate     return( rc );
16017c478bd9Sstevel@tonic-gate }
16027c478bd9Sstevel@tonic-gate 
16037c478bd9Sstevel@tonic-gate 
16047c478bd9Sstevel@tonic-gate static int
16057c478bd9Sstevel@tonic-gate parse_result( LDAP *ld, LDAPMessage *res, struct berval **servercredp,
16067c478bd9Sstevel@tonic-gate 	char *msg, int freeit )
16077c478bd9Sstevel@tonic-gate {
16087c478bd9Sstevel@tonic-gate     int		rc, lderr, errno;
16097c478bd9Sstevel@tonic-gate     int		pw_days=0, pw_hrs=0, pw_mins=0, pw_secs=0; /* for pwpolicy */
16107c478bd9Sstevel@tonic-gate     char	**refs = NULL;
16117c478bd9Sstevel@tonic-gate     LDAPControl	**ctrls;
16127c478bd9Sstevel@tonic-gate 
16137c478bd9Sstevel@tonic-gate     if (( rc = ldap_parse_result( ld, res, &lderr, NULL, NULL, &refs,
16147c478bd9Sstevel@tonic-gate 	    &ctrls, 0 )) != LDAP_SUCCESS ) {
16157c478bd9Sstevel@tonic-gate 	ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP );
16167c478bd9Sstevel@tonic-gate 	ldap_msgfree( res );
16177c478bd9Sstevel@tonic-gate 	return( rc );
16187c478bd9Sstevel@tonic-gate     }
16197c478bd9Sstevel@tonic-gate 
16207c478bd9Sstevel@tonic-gate     /* check for authentication response control & PWPOLICY control*/
16217c478bd9Sstevel@tonic-gate     if ( NULL != ctrls ) {
16227c478bd9Sstevel@tonic-gate 	int		i;
16237c478bd9Sstevel@tonic-gate 	char		*s;
16247c478bd9Sstevel@tonic-gate 
16257c478bd9Sstevel@tonic-gate 	for ( i = 0; NULL != ctrls[i]; ++i ) {
16267c478bd9Sstevel@tonic-gate 	    if ( 0 == strcmp( ctrls[i]->ldctl_oid,
16277c478bd9Sstevel@tonic-gate 			LDAP_CONTROL_AUTH_RESPONSE )) {
16287c478bd9Sstevel@tonic-gate 		    s = ctrls[i]->ldctl_value.bv_val;
16297c478bd9Sstevel@tonic-gate 		    if ( NULL == s ) {
16307c478bd9Sstevel@tonic-gate 			s = "Null";
16317c478bd9Sstevel@tonic-gate 		    } else if ( *s == '\0' ) {
16327c478bd9Sstevel@tonic-gate 			s = "Anonymous";
16337c478bd9Sstevel@tonic-gate 		    }
16347c478bd9Sstevel@tonic-gate 		fprintf( stderr, gettext("%s: bound as %s\n"), ldaptool_progname, s );
16357c478bd9Sstevel@tonic-gate 	    }
16367c478bd9Sstevel@tonic-gate 
16377c478bd9Sstevel@tonic-gate 	    if ( 0 == strcmp( ctrls[i]->ldctl_oid,
16387c478bd9Sstevel@tonic-gate 			LDAP_CONTROL_PWEXPIRING )) {
16397c478bd9Sstevel@tonic-gate 
164048bbca81SDaniel Hoffman 		    /* Warn the user that their passwd is to expire */
164148bbca81SDaniel Hoffman 		    errno = 0;
16427c478bd9Sstevel@tonic-gate 		    pw_secs = atoi(ctrls[i]->ldctl_value.bv_val);
16437c478bd9Sstevel@tonic-gate 		    if ( pw_secs > 0  && errno != ERANGE ) {
16447c478bd9Sstevel@tonic-gate 			if ( pw_secs > 86400 ) {
16457c478bd9Sstevel@tonic-gate 				pw_days = ( pw_secs / 86400 );
16467c478bd9Sstevel@tonic-gate 				pw_secs = ( pw_secs % 86400 );
164748bbca81SDaniel Hoffman 			}
16487c478bd9Sstevel@tonic-gate 			if ( pw_secs > 3600 ) {
16497c478bd9Sstevel@tonic-gate 				pw_hrs = ( pw_secs / 3600 );
16507c478bd9Sstevel@tonic-gate 				pw_secs = ( pw_secs % 3600 );
16517c478bd9Sstevel@tonic-gate 			}
16527c478bd9Sstevel@tonic-gate 			if ( pw_secs > 60 ) {
16537c478bd9Sstevel@tonic-gate 				pw_mins = ( pw_secs / 60 );
16547c478bd9Sstevel@tonic-gate 				pw_secs = ( pw_secs % 60 );
16557c478bd9Sstevel@tonic-gate 			}
16567c478bd9Sstevel@tonic-gate 
16577c478bd9Sstevel@tonic-gate 			printf(gettext("%s: Warning ! Your password will expire after "), ldaptool_progname);
16587c478bd9Sstevel@tonic-gate 			if ( pw_days ) {
16597c478bd9Sstevel@tonic-gate 				printf (gettext("%d days, "), pw_days);
16607c478bd9Sstevel@tonic-gate 			}
16617c478bd9Sstevel@tonic-gate 			if ( pw_hrs ) {
16627c478bd9Sstevel@tonic-gate 				printf (gettext("%d hrs, "), pw_hrs);
16637c478bd9Sstevel@tonic-gate 			}
16647c478bd9Sstevel@tonic-gate 			if ( pw_mins ) {
16657c478bd9Sstevel@tonic-gate 				printf (gettext("%d mins, "), pw_mins);
16667c478bd9Sstevel@tonic-gate 			}
16677c478bd9Sstevel@tonic-gate 			printf(gettext("%d seconds.\n"), pw_secs);
166848bbca81SDaniel Hoffman 
16697c478bd9Sstevel@tonic-gate 		   }
16707c478bd9Sstevel@tonic-gate 		}
16717c478bd9Sstevel@tonic-gate 	}
16727c478bd9Sstevel@tonic-gate 	ldap_controls_free( ctrls );
16737c478bd9Sstevel@tonic-gate     }
16747c478bd9Sstevel@tonic-gate 
16757c478bd9Sstevel@tonic-gate     if ( servercredp != NULL && ( rc = ldap_parse_sasl_bind_result( ld, res,
16767c478bd9Sstevel@tonic-gate 	    servercredp, 0 )) != LDAP_SUCCESS ) {
16777c478bd9Sstevel@tonic-gate 	ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP );
16787c478bd9Sstevel@tonic-gate 	ldap_msgfree( res );
16797c478bd9Sstevel@tonic-gate 	return( rc );
16807c478bd9Sstevel@tonic-gate     }
16817c478bd9Sstevel@tonic-gate 
16827c478bd9Sstevel@tonic-gate     if ( freeit ) {
16837c478bd9Sstevel@tonic-gate 	ldap_msgfree( res );
16847c478bd9Sstevel@tonic-gate     }
16857c478bd9Sstevel@tonic-gate 
16867c478bd9Sstevel@tonic-gate     if ( LDAPTOOL_RESULT_IS_AN_ERROR( lderr )) {
16877c478bd9Sstevel@tonic-gate 	ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP );
16887c478bd9Sstevel@tonic-gate     }
16897c478bd9Sstevel@tonic-gate 
16907c478bd9Sstevel@tonic-gate     if ( refs != NULL ) {
16917c478bd9Sstevel@tonic-gate 	ldaptool_print_referrals( refs );
16927c478bd9Sstevel@tonic-gate 	ldap_value_free( refs );
16937c478bd9Sstevel@tonic-gate     }
16947c478bd9Sstevel@tonic-gate 
16957c478bd9Sstevel@tonic-gate     return( lderr );
16967c478bd9Sstevel@tonic-gate }
16977c478bd9Sstevel@tonic-gate 
16987c478bd9Sstevel@tonic-gate 
16997c478bd9Sstevel@tonic-gate /*
17007c478bd9Sstevel@tonic-gate  * if -M was passed on the command line, create and return a "Manage DSA IT"
17017c478bd9Sstevel@tonic-gate  * LDAPv3 control.  If not, return NULL.
17027c478bd9Sstevel@tonic-gate  */
17037c478bd9Sstevel@tonic-gate LDAPControl *
17047c478bd9Sstevel@tonic-gate ldaptool_create_manage_dsait_control( void )
17057c478bd9Sstevel@tonic-gate {
17067c478bd9Sstevel@tonic-gate     LDAPControl	*ctl;
17077c478bd9Sstevel@tonic-gate 
17087c478bd9Sstevel@tonic-gate     if ( !send_manage_dsait_ctrl ) {
17097c478bd9Sstevel@tonic-gate 	return( NULL );
17107c478bd9Sstevel@tonic-gate     }
17117c478bd9Sstevel@tonic-gate 
17127c478bd9Sstevel@tonic-gate     if (( ctl = (LDAPControl *)calloc( 1, sizeof( LDAPControl ))) == NULL ||
17137c478bd9Sstevel@tonic-gate 	    ( ctl->ldctl_oid = strdup( LDAP_CONTROL_MANAGEDSAIT )) == NULL ) {
17147c478bd9Sstevel@tonic-gate 	perror( "calloc" );
17157c478bd9Sstevel@tonic-gate 	exit( LDAP_NO_MEMORY );
17167c478bd9Sstevel@tonic-gate     }
17177c478bd9Sstevel@tonic-gate 
17187c478bd9Sstevel@tonic-gate     ctl->ldctl_iscritical = 1;
17197c478bd9Sstevel@tonic-gate 
17207c478bd9Sstevel@tonic-gate     return( ctl );
17217c478bd9Sstevel@tonic-gate }
17227c478bd9Sstevel@tonic-gate 
17237c478bd9Sstevel@tonic-gate /*
17247c478bd9Sstevel@tonic-gate  * if -y "dn" was supplied on the command line, create the control
17257c478bd9Sstevel@tonic-gate  */
17267c478bd9Sstevel@tonic-gate LDAPControl *
17277c478bd9Sstevel@tonic-gate ldaptool_create_proxyauth_control( LDAP *ld )
17287c478bd9Sstevel@tonic-gate {
17297c478bd9Sstevel@tonic-gate     LDAPControl	*ctl = NULL;
17307c478bd9Sstevel@tonic-gate     int rc;
173148bbca81SDaniel Hoffman 
17327c478bd9Sstevel@tonic-gate 
17337c478bd9Sstevel@tonic-gate     if ( !proxyauth_id)
17347c478bd9Sstevel@tonic-gate 	return( NULL );
17357c478bd9Sstevel@tonic-gate 
17367c478bd9Sstevel@tonic-gate     if ( 2 == proxyauth_version ) {
17377c478bd9Sstevel@tonic-gate 	rc = ldap_create_proxiedauth_control( ld, proxyauth_id, &ctl);
17387c478bd9Sstevel@tonic-gate     } else {
17397c478bd9Sstevel@tonic-gate 	rc = ldap_create_proxyauth_control( ld, proxyauth_id, 1, &ctl);
17407c478bd9Sstevel@tonic-gate     }
174148bbca81SDaniel Hoffman     if ( rc != LDAP_SUCCESS)
17427c478bd9Sstevel@tonic-gate     {
17437c478bd9Sstevel@tonic-gate 	if (ctl)
17447c478bd9Sstevel@tonic-gate 	    ldap_control_free( ctl);
17457c478bd9Sstevel@tonic-gate 	return NULL;
17467c478bd9Sstevel@tonic-gate     }
17477c478bd9Sstevel@tonic-gate     return( ctl );
17487c478bd9Sstevel@tonic-gate }
17497c478bd9Sstevel@tonic-gate 
17507c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
17517c478bd9Sstevel@tonic-gate LDAPControl *
17527c478bd9Sstevel@tonic-gate ldaptool_create_geteffectiveRights_control ( LDAP *ld, const char *authzid,
17537c478bd9Sstevel@tonic-gate 											const char **attrlist)
17547c478bd9Sstevel@tonic-gate {
17557c478bd9Sstevel@tonic-gate     LDAPControl	*ctl = NULL;
17567c478bd9Sstevel@tonic-gate     int rc;
175748bbca81SDaniel Hoffman 
17587c478bd9Sstevel@tonic-gate 	rc = ldap_create_geteffectiveRights_control( ld, authzid, attrlist, 1,
17597c478bd9Sstevel@tonic-gate 							&ctl);
176048bbca81SDaniel Hoffman 
176148bbca81SDaniel Hoffman     if ( rc != LDAP_SUCCESS)
17627c478bd9Sstevel@tonic-gate     {
17637c478bd9Sstevel@tonic-gate 		if (ctl)
17647c478bd9Sstevel@tonic-gate 	    	ldap_control_free( ctl);
17657c478bd9Sstevel@tonic-gate 		return NULL;
17667c478bd9Sstevel@tonic-gate     }
17677c478bd9Sstevel@tonic-gate     return( ctl );
17687c478bd9Sstevel@tonic-gate }
17697c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
17707c478bd9Sstevel@tonic-gate 
17717c478bd9Sstevel@tonic-gate 
17727c478bd9Sstevel@tonic-gate void
17737c478bd9Sstevel@tonic-gate ldaptool_add_control_to_array( LDAPControl *ctrl, LDAPControl **array)
17747c478bd9Sstevel@tonic-gate {
177548bbca81SDaniel Hoffman 
17767c478bd9Sstevel@tonic-gate     int i;
17777c478bd9Sstevel@tonic-gate     for (i=0; i< CONTROL_REQUESTS; i++)
17787c478bd9Sstevel@tonic-gate     {
17797c478bd9Sstevel@tonic-gate 	if (*(array + i) == NULL)
17807c478bd9Sstevel@tonic-gate 	{
17817c478bd9Sstevel@tonic-gate 	    *(array + i +1) = NULL;
17827c478bd9Sstevel@tonic-gate 	    *(array + i) = ctrl;
17837c478bd9Sstevel@tonic-gate 	    return ;
17847c478bd9Sstevel@tonic-gate 	}
17857c478bd9Sstevel@tonic-gate     }
17867c478bd9Sstevel@tonic-gate     fprintf(stderr, gettext("%s: failed to store request control!!!!!!\n"),
17877c478bd9Sstevel@tonic-gate 	    ldaptool_progname);
17887c478bd9Sstevel@tonic-gate }
17897c478bd9Sstevel@tonic-gate 
17907c478bd9Sstevel@tonic-gate /*
17917c478bd9Sstevel@tonic-gate  * Dispose of all controls in array and prepare array for reuse.
17927c478bd9Sstevel@tonic-gate  */
17937c478bd9Sstevel@tonic-gate void
17947c478bd9Sstevel@tonic-gate ldaptool_reset_control_array( LDAPControl **array )
17957c478bd9Sstevel@tonic-gate {
17967c478bd9Sstevel@tonic-gate     int		i;
17977c478bd9Sstevel@tonic-gate 
17987c478bd9Sstevel@tonic-gate     for ( i = 0; i < CONTROL_REQUESTS; i++ ) {
17997c478bd9Sstevel@tonic-gate 	if ( array[i] != NULL ) {
18007c478bd9Sstevel@tonic-gate 	    ldap_control_free( array[i] );
18017c478bd9Sstevel@tonic-gate 	    array[i] = NULL;
18027c478bd9Sstevel@tonic-gate 	}
18037c478bd9Sstevel@tonic-gate     }
18047c478bd9Sstevel@tonic-gate }
18057c478bd9Sstevel@tonic-gate 
18067c478bd9Sstevel@tonic-gate /*
18077c478bd9Sstevel@tonic-gate  * This function calculates control value and its length. *value can
18087c478bd9Sstevel@tonic-gate  * be pointing to plain value, ":b64encoded value" or "<fileurl".
18097c478bd9Sstevel@tonic-gate  */
18107c478bd9Sstevel@tonic-gate static int
18117c478bd9Sstevel@tonic-gate calculate_ctrl_value( const char *value,
18127c478bd9Sstevel@tonic-gate 	char **ctrl_value, int *vlen)
18137c478bd9Sstevel@tonic-gate {
18147c478bd9Sstevel@tonic-gate     int b64;
18157c478bd9Sstevel@tonic-gate     if (*value == ':') {
18167c478bd9Sstevel@tonic-gate 	value++;
18177c478bd9Sstevel@tonic-gate 	b64 = 1;
18187c478bd9Sstevel@tonic-gate     } else {
18197c478bd9Sstevel@tonic-gate 	b64 = 0;
18207c478bd9Sstevel@tonic-gate     }
18217c478bd9Sstevel@tonic-gate     *ctrl_value = (char *)value;
18227c478bd9Sstevel@tonic-gate 
18237c478bd9Sstevel@tonic-gate     if ( b64 ) {
18247c478bd9Sstevel@tonic-gate 	if (( *vlen = ldif_base64_decode( (char *)value,
18257c478bd9Sstevel@tonic-gate 		(unsigned char *)value )) < 0 ) {
182648bbca81SDaniel Hoffman 	    fprintf( stderr,
18277c478bd9Sstevel@tonic-gate 		gettext("Unable to decode base64 control value \"%s\"\n"), value);
18287c478bd9Sstevel@tonic-gate 	    return( -1 );
18297c478bd9Sstevel@tonic-gate 	}
18307c478bd9Sstevel@tonic-gate     } else {
18317c478bd9Sstevel@tonic-gate 	*vlen = (int)strlen(*ctrl_value);
18327c478bd9Sstevel@tonic-gate     }
18337c478bd9Sstevel@tonic-gate     return( 0 );
18347c478bd9Sstevel@tonic-gate }
18357c478bd9Sstevel@tonic-gate 
18367c478bd9Sstevel@tonic-gate /*
18377c478bd9Sstevel@tonic-gate  * Parse the optarg from -J option of ldapsearch
183848bbca81SDaniel Hoffman  * and within LDIFfile for ldapmodify. Take ctrl_arg
18397c478bd9Sstevel@tonic-gate  * (the whole string) and divide it into oid, criticality
18407c478bd9Sstevel@tonic-gate  * and value. This function breaks down original ctrl_arg
18417c478bd9Sstevel@tonic-gate  * with '\0' in places. Also, calculate length of valuestring.
18427c478bd9Sstevel@tonic-gate  */
18437c478bd9Sstevel@tonic-gate int
18447c478bd9Sstevel@tonic-gate ldaptool_parse_ctrl_arg(char *ctrl_arg, char sep,
18457c478bd9Sstevel@tonic-gate 		char **ctrl_oid, int *ctrl_criticality,
18467c478bd9Sstevel@tonic-gate 		char **ctrl_value, int *vlen)
18477c478bd9Sstevel@tonic-gate {
18487c478bd9Sstevel@tonic-gate     char *s, *p;
18497c478bd9Sstevel@tonic-gate     int strict;
18507c478bd9Sstevel@tonic-gate 
18517c478bd9Sstevel@tonic-gate     /* Initialize passed variables with default values */
18527c478bd9Sstevel@tonic-gate     *ctrl_oid = *ctrl_value = NULL;
18537c478bd9Sstevel@tonic-gate     *ctrl_criticality = 0;
18547c478bd9Sstevel@tonic-gate     *vlen = 0;
18557c478bd9Sstevel@tonic-gate 
18567c478bd9Sstevel@tonic-gate     strict = (sep == ' ' ? 1 : 0);
18577c478bd9Sstevel@tonic-gate     if(!(s=strchr(ctrl_arg, sep))) {
185848bbca81SDaniel Hoffman 	/* Possible values of ctrl_arg are
18597c478bd9Sstevel@tonic-gate 	 * oid[:value|::b64value|:<fileurl] within LDIF, i.e. sep=' '
18607c478bd9Sstevel@tonic-gate 	 * oid from command line option, i.e. sep=':'
18617c478bd9Sstevel@tonic-gate 	 */
18627c478bd9Sstevel@tonic-gate 	if (sep == ' ') {
18637c478bd9Sstevel@tonic-gate 	    if (!(s=strchr(ctrl_arg, ':'))) {
18647c478bd9Sstevel@tonic-gate 		*ctrl_oid = ctrl_arg;
18657c478bd9Sstevel@tonic-gate 	    }
18667c478bd9Sstevel@tonic-gate 	    else {
18677c478bd9Sstevel@tonic-gate 		/* ctrl_arg is of oid:[value|:b64value|<fileurl]
18687c478bd9Sstevel@tonic-gate 		 * form in the LDIF record. So, grab the oid and then
18697c478bd9Sstevel@tonic-gate 		 * jump to continue the parsing of ctrl_arg.
18707c478bd9Sstevel@tonic-gate 		 * 's' is pointing just after oid ends.
18717c478bd9Sstevel@tonic-gate 		 */
18727c478bd9Sstevel@tonic-gate 		*s++ = '\0';
18737c478bd9Sstevel@tonic-gate 		*ctrl_oid = ctrl_arg;
18747c478bd9Sstevel@tonic-gate 		return (calculate_ctrl_value( s, ctrl_value, vlen ));
18757c478bd9Sstevel@tonic-gate 	    }
18767c478bd9Sstevel@tonic-gate 	} else {
18777c478bd9Sstevel@tonic-gate 		/* oid - from command line option, i.e. sep=':' */
18787c478bd9Sstevel@tonic-gate 		*ctrl_oid = ctrl_arg;
18797c478bd9Sstevel@tonic-gate 	}
18807c478bd9Sstevel@tonic-gate     }
18817c478bd9Sstevel@tonic-gate     else {
18827c478bd9Sstevel@tonic-gate 	/* Possible values of ctrl_arg are
18837c478bd9Sstevel@tonic-gate 	 * oid:criticality[:value|::b64value|:<fileurl] - command line
18847c478bd9Sstevel@tonic-gate 	 * oid criticality[:value|::b64value|:<fileurl] - LDIF
18857c478bd9Sstevel@tonic-gate 	 * And 's' is pointing just after oid ends.
18867c478bd9Sstevel@tonic-gate 	 */
18877c478bd9Sstevel@tonic-gate 
18887c478bd9Sstevel@tonic-gate 	if (*(s+1) == '\0') {
18897c478bd9Sstevel@tonic-gate 	    fprintf( stderr, gettext("missing value\n") );
18907c478bd9Sstevel@tonic-gate 	    return( -1 );
18917c478bd9Sstevel@tonic-gate 	}
18927c478bd9Sstevel@tonic-gate 	*s = '\0';
18937c478bd9Sstevel@tonic-gate 	*ctrl_oid = ctrl_arg;
18947c478bd9Sstevel@tonic-gate 	p = ++s;
18957c478bd9Sstevel@tonic-gate 	if(!(s=strchr(p, ':'))) {
18967c478bd9Sstevel@tonic-gate 	    if ( (*ctrl_criticality = ldaptool_boolean_str2value(p, strict))
18977c478bd9Sstevel@tonic-gate 			== -1 ) {
18987c478bd9Sstevel@tonic-gate 		fprintf( stderr, gettext("Invalid criticality value\n") );
18997c478bd9Sstevel@tonic-gate 		return( -1 );
19007c478bd9Sstevel@tonic-gate 	    }
19017c478bd9Sstevel@tonic-gate 	}
19027c478bd9Sstevel@tonic-gate 	else {
190348bbca81SDaniel Hoffman 	    if (*(s+1) == '\0') {
19047c478bd9Sstevel@tonic-gate 	        fprintf( stderr, gettext("missing value\n") );
19057c478bd9Sstevel@tonic-gate 	        return ( -1 );
19067c478bd9Sstevel@tonic-gate 	    }
19077c478bd9Sstevel@tonic-gate 	    *s++ = '\0';
19087c478bd9Sstevel@tonic-gate             if ( (*ctrl_criticality = ldaptool_boolean_str2value(p, strict))
19097c478bd9Sstevel@tonic-gate 			== -1 ) {
19107c478bd9Sstevel@tonic-gate 		fprintf( stderr, gettext("Invalid criticality value\n") );
19117c478bd9Sstevel@tonic-gate 		return ( -1 );
19127c478bd9Sstevel@tonic-gate 	    }
19137c478bd9Sstevel@tonic-gate 	    return (calculate_ctrl_value( s, ctrl_value, vlen ));
19147c478bd9Sstevel@tonic-gate 	}
19157c478bd9Sstevel@tonic-gate     }
19167c478bd9Sstevel@tonic-gate 
19177c478bd9Sstevel@tonic-gate     return( 0 );
19187c478bd9Sstevel@tonic-gate }
19197c478bd9Sstevel@tonic-gate 
19207c478bd9Sstevel@tonic-gate 
19217c478bd9Sstevel@tonic-gate /*
19227c478bd9Sstevel@tonic-gate  * callback function for LDAP bind credentials
19237c478bd9Sstevel@tonic-gate  */
19247c478bd9Sstevel@tonic-gate static int
19257c478bd9Sstevel@tonic-gate LDAP_CALL
19267c478bd9Sstevel@tonic-gate LDAP_CALLBACK
19277c478bd9Sstevel@tonic-gate get_rebind_credentials( LDAP *ld, char **whop, char **credp,
19287c478bd9Sstevel@tonic-gate         int *methodp, int freeit, void* arg )
19297c478bd9Sstevel@tonic-gate {
19307c478bd9Sstevel@tonic-gate     if ( !freeit ) {
19317c478bd9Sstevel@tonic-gate 	*whop = binddn;
19327c478bd9Sstevel@tonic-gate 	*credp = passwd;
19337c478bd9Sstevel@tonic-gate 	*methodp = LDAP_AUTH_SIMPLE;
19347c478bd9Sstevel@tonic-gate     }
19357c478bd9Sstevel@tonic-gate 
19367c478bd9Sstevel@tonic-gate     return( LDAP_SUCCESS );
19377c478bd9Sstevel@tonic-gate }
19387c478bd9Sstevel@tonic-gate 
19397c478bd9Sstevel@tonic-gate 
19407c478bd9Sstevel@tonic-gate /*
19417c478bd9Sstevel@tonic-gate  * return pointer to pathname to temporary directory.
19427c478bd9Sstevel@tonic-gate  * First we see if the environment variable "TEMP" is set and use it.
19437c478bd9Sstevel@tonic-gate  * Then we see if the environment variable "TMP" is set and use it.
19447c478bd9Sstevel@tonic-gate  * If this fails, we use "/tmp" on UNIX and fail on Windows.
19457c478bd9Sstevel@tonic-gate  */
19467c478bd9Sstevel@tonic-gate char *
19477c478bd9Sstevel@tonic-gate ldaptool_get_tmp_dir( void )
19487c478bd9Sstevel@tonic-gate {
19497c478bd9Sstevel@tonic-gate     char	*p;
19507c478bd9Sstevel@tonic-gate     int		offset;
19517c478bd9Sstevel@tonic-gate 
19527c478bd9Sstevel@tonic-gate     if (( p = getenv( "TEMP" )) == NULL && ( p = getenv( "TMP" )) == NULL ) {
19537c478bd9Sstevel@tonic-gate #ifdef _WINDOWS
19547c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: please set the TEMP environment variable.\n"),
19557c478bd9Sstevel@tonic-gate 		ldaptool_progname );
19567c478bd9Sstevel@tonic-gate 	exit( LDAP_LOCAL_ERROR );
19577c478bd9Sstevel@tonic-gate #else
19587c478bd9Sstevel@tonic-gate 	return( "/tmp" );	/* last resort on UNIX */
19597c478bd9Sstevel@tonic-gate #endif
19607c478bd9Sstevel@tonic-gate     }
19617c478bd9Sstevel@tonic-gate 
19627c478bd9Sstevel@tonic-gate     /*
19637c478bd9Sstevel@tonic-gate      * remove trailing slash if present
19647c478bd9Sstevel@tonic-gate      */
19657c478bd9Sstevel@tonic-gate     offset = strlen( p ) - 1;
19667c478bd9Sstevel@tonic-gate     if ( p[offset] == '/'
19677c478bd9Sstevel@tonic-gate #ifdef _WINDOWS
19687c478bd9Sstevel@tonic-gate 	    || p[offset] == '\\'
19697c478bd9Sstevel@tonic-gate #endif
19707c478bd9Sstevel@tonic-gate 	    ) {
19717c478bd9Sstevel@tonic-gate 	if (( p = strdup( p )) == NULL ) {
19727c478bd9Sstevel@tonic-gate 	    perror( "strdup" );
19737c478bd9Sstevel@tonic-gate 	    exit( LDAP_NO_MEMORY );
19747c478bd9Sstevel@tonic-gate 	}
19757c478bd9Sstevel@tonic-gate 
19767c478bd9Sstevel@tonic-gate 	p[offset] = '\0';
19777c478bd9Sstevel@tonic-gate     }
19787c478bd9Sstevel@tonic-gate 
19797c478bd9Sstevel@tonic-gate     return( p );
19807c478bd9Sstevel@tonic-gate }
19817c478bd9Sstevel@tonic-gate 
19827c478bd9Sstevel@tonic-gate 
19837c478bd9Sstevel@tonic-gate int
19847c478bd9Sstevel@tonic-gate ldaptool_berval_is_ascii( const struct berval *bvp )
19857c478bd9Sstevel@tonic-gate {
19867c478bd9Sstevel@tonic-gate     unsigned long	j;
19877c478bd9Sstevel@tonic-gate     int			is_ascii = 1;	 /* optimistic */
19887c478bd9Sstevel@tonic-gate 
19897c478bd9Sstevel@tonic-gate     for ( j = 0; j < bvp->bv_len; ++j ) {
19907c478bd9Sstevel@tonic-gate 	if ( !isascii( bvp->bv_val[ j ] )) {
19917c478bd9Sstevel@tonic-gate 	    is_ascii = 0;
19927c478bd9Sstevel@tonic-gate 	    break;
19937c478bd9Sstevel@tonic-gate 	}
19947c478bd9Sstevel@tonic-gate     }
19957c478bd9Sstevel@tonic-gate 
19967c478bd9Sstevel@tonic-gate     return( is_ascii );
19977c478bd9Sstevel@tonic-gate }
19987c478bd9Sstevel@tonic-gate 
19997c478bd9Sstevel@tonic-gate 
200048bbca81SDaniel Hoffman #ifdef LDAP_DEBUG_MEMORY
20017c478bd9Sstevel@tonic-gate #define LDAPTOOL_ALLOC_FREED	0xF001
20027c478bd9Sstevel@tonic-gate #define LDAPTOOL_ALLOC_INUSE	0xF002
20037c478bd9Sstevel@tonic-gate 
20047c478bd9Sstevel@tonic-gate static void *
20057c478bd9Sstevel@tonic-gate ldaptool_debug_alloc( void *ptr, size_t size )
20067c478bd9Sstevel@tonic-gate {
20077c478bd9Sstevel@tonic-gate     int		*statusp;
20087c478bd9Sstevel@tonic-gate     void	*systemptr;
20097c478bd9Sstevel@tonic-gate 
20107c478bd9Sstevel@tonic-gate     if ( ptr == NULL ) {
20117c478bd9Sstevel@tonic-gate 	systemptr = NULL;
20127c478bd9Sstevel@tonic-gate     } else {
20137c478bd9Sstevel@tonic-gate 	systemptr = (void *)((char *)ptr - sizeof(int));
20147c478bd9Sstevel@tonic-gate     }
20157c478bd9Sstevel@tonic-gate 
20167c478bd9Sstevel@tonic-gate     if (( statusp = (int *)realloc( systemptr, size + sizeof(int))) == NULL ) {
20177c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: realloc( 0x%x, %d) failed\n"),
20187c478bd9Sstevel@tonic-gate 		ldaptool_progname, systemptr, size );
20197c478bd9Sstevel@tonic-gate 	return( NULL );
20207c478bd9Sstevel@tonic-gate     }
20217c478bd9Sstevel@tonic-gate 
20227c478bd9Sstevel@tonic-gate     *statusp = LDAPTOOL_ALLOC_INUSE;
20237c478bd9Sstevel@tonic-gate 
20247c478bd9Sstevel@tonic-gate     return( (char *)statusp + sizeof(int));
20257c478bd9Sstevel@tonic-gate }
20267c478bd9Sstevel@tonic-gate 
20277c478bd9Sstevel@tonic-gate 
20287c478bd9Sstevel@tonic-gate static void *
20297c478bd9Sstevel@tonic-gate ldaptool_debug_realloc( void *ptr, size_t size )
20307c478bd9Sstevel@tonic-gate {
20317c478bd9Sstevel@tonic-gate     void	*p;
20327c478bd9Sstevel@tonic-gate 
20337c478bd9Sstevel@tonic-gate     if ( ldaptool_dbg_lvl & LDAP_DEBUG_TRACE ) {
20347c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: => realloc( 0x%x, %d )\n"),
20357c478bd9Sstevel@tonic-gate 		ldaptool_progname, ptr, size );
20367c478bd9Sstevel@tonic-gate     }
20377c478bd9Sstevel@tonic-gate 
20387c478bd9Sstevel@tonic-gate     p = ldaptool_debug_alloc( ptr, size );
20397c478bd9Sstevel@tonic-gate 
20407c478bd9Sstevel@tonic-gate     if ( ldaptool_dbg_lvl & LDAP_DEBUG_TRACE ) {
20417c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: 0x%x <= realloc()\n"), ldaptool_progname, p );
20427c478bd9Sstevel@tonic-gate     }
20437c478bd9Sstevel@tonic-gate 
20447c478bd9Sstevel@tonic-gate     return( p );
20457c478bd9Sstevel@tonic-gate }
20467c478bd9Sstevel@tonic-gate 
20477c478bd9Sstevel@tonic-gate 
20487c478bd9Sstevel@tonic-gate static void *
20497c478bd9Sstevel@tonic-gate ldaptool_debug_malloc( size_t size )
20507c478bd9Sstevel@tonic-gate {
20517c478bd9Sstevel@tonic-gate     void	*p;
20527c478bd9Sstevel@tonic-gate 
20537c478bd9Sstevel@tonic-gate     if ( ldaptool_dbg_lvl & LDAP_DEBUG_TRACE ) {
20547c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: => malloc( %d)\n"), ldaptool_progname, size );
20557c478bd9Sstevel@tonic-gate     }
20567c478bd9Sstevel@tonic-gate 
20577c478bd9Sstevel@tonic-gate     p = ldaptool_debug_alloc( NULL, size );
20587c478bd9Sstevel@tonic-gate 
20597c478bd9Sstevel@tonic-gate     if ( ldaptool_dbg_lvl & LDAP_DEBUG_TRACE ) {
20607c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: 0x%x <= malloc()\n"), ldaptool_progname, p );
20617c478bd9Sstevel@tonic-gate     }
20627c478bd9Sstevel@tonic-gate 
20637c478bd9Sstevel@tonic-gate     return( p );
20647c478bd9Sstevel@tonic-gate }
20657c478bd9Sstevel@tonic-gate 
20667c478bd9Sstevel@tonic-gate 
20677c478bd9Sstevel@tonic-gate static void *
20687c478bd9Sstevel@tonic-gate ldaptool_debug_calloc( size_t nelem, size_t elsize )
20697c478bd9Sstevel@tonic-gate {
20707c478bd9Sstevel@tonic-gate     void	*p;
20717c478bd9Sstevel@tonic-gate 
20727c478bd9Sstevel@tonic-gate     if ( ldaptool_dbg_lvl & LDAP_DEBUG_TRACE ) {
20737c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: => calloc( %d, %d )\n"),
20747c478bd9Sstevel@tonic-gate 		ldaptool_progname, nelem, elsize );
20757c478bd9Sstevel@tonic-gate     }
20767c478bd9Sstevel@tonic-gate 
20777c478bd9Sstevel@tonic-gate     if (( p = ldaptool_debug_alloc( NULL, nelem * elsize )) != NULL ) {
20787c478bd9Sstevel@tonic-gate 	memset( p, 0, nelem * elsize );
20797c478bd9Sstevel@tonic-gate     }
20807c478bd9Sstevel@tonic-gate 
20817c478bd9Sstevel@tonic-gate     if ( ldaptool_dbg_lvl & LDAP_DEBUG_TRACE ) {
20827c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: 0x%x <= calloc()\n"), ldaptool_progname, p );
20837c478bd9Sstevel@tonic-gate     }
20847c478bd9Sstevel@tonic-gate 
20857c478bd9Sstevel@tonic-gate     return( p );
20867c478bd9Sstevel@tonic-gate }
20877c478bd9Sstevel@tonic-gate 
20887c478bd9Sstevel@tonic-gate 
20897c478bd9Sstevel@tonic-gate static void
20907c478bd9Sstevel@tonic-gate ldaptool_debug_free( void *ptr )
20917c478bd9Sstevel@tonic-gate {
20927c478bd9Sstevel@tonic-gate     int		*statusp = (int *)((char *)ptr - sizeof(int));
20937c478bd9Sstevel@tonic-gate 
20947c478bd9Sstevel@tonic-gate     if ( ldaptool_dbg_lvl & LDAP_DEBUG_TRACE ) {
20957c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: => free( 0x%x )\n"), ldaptool_progname, ptr );
20967c478bd9Sstevel@tonic-gate     }
20977c478bd9Sstevel@tonic-gate 
20987c478bd9Sstevel@tonic-gate     if ( ptr == NULL ) {
20997c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: bad free( 0x0 ) attempted (NULL pointer)\n"),
21007c478bd9Sstevel@tonic-gate 		ldaptool_progname );
21017c478bd9Sstevel@tonic-gate     } else if ( *statusp != LDAPTOOL_ALLOC_INUSE ) {
21027c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: bad free( 0x%x ) attempted"
21037c478bd9Sstevel@tonic-gate 		" (block not in use; status is %d)\n"),
21047c478bd9Sstevel@tonic-gate 		ldaptool_progname, ptr, *statusp );
21057c478bd9Sstevel@tonic-gate     } else {
21067c478bd9Sstevel@tonic-gate 	*statusp = LDAPTOOL_ALLOC_FREED;
21077c478bd9Sstevel@tonic-gate 	free( statusp );
21087c478bd9Sstevel@tonic-gate     }
21097c478bd9Sstevel@tonic-gate }
21107c478bd9Sstevel@tonic-gate #endif /* LDAP_DEBUG_MEMORY */
21117c478bd9Sstevel@tonic-gate 
21127c478bd9Sstevel@tonic-gate 
21137c478bd9Sstevel@tonic-gate #if defined(NET_SSL)
21147c478bd9Sstevel@tonic-gate /*
21157c478bd9Sstevel@tonic-gate  * Derive key database path from certificate database path and return a
21167c478bd9Sstevel@tonic-gate  * malloc'd string.
21177c478bd9Sstevel@tonic-gate  *
21187c478bd9Sstevel@tonic-gate  * We just return an exact copy of "certdbpath" unless it ends in "cert.db",
21197c478bd9Sstevel@tonic-gate  * "cert5.db", or "cert7.db".  In those cases we strip off everything from
21207c478bd9Sstevel@tonic-gate  * "cert" on and append "key.db", "key5.db", or "key3.db" as appropriate.
21217c478bd9Sstevel@tonic-gate  * Strangely enough cert7.db and key3.db go together.
21227c478bd9Sstevel@tonic-gate  */
21237c478bd9Sstevel@tonic-gate static char *
21247c478bd9Sstevel@tonic-gate certpath2keypath( char *certdbpath )
21257c478bd9Sstevel@tonic-gate {
21267c478bd9Sstevel@tonic-gate     char	*keydbpath, *appendstr;
21277c478bd9Sstevel@tonic-gate     int		len, striplen;
21287c478bd9Sstevel@tonic-gate 
21297c478bd9Sstevel@tonic-gate     if ( certdbpath == NULL ) {
21307c478bd9Sstevel@tonic-gate 	return( NULL );
21317c478bd9Sstevel@tonic-gate     }
21327c478bd9Sstevel@tonic-gate 
21337c478bd9Sstevel@tonic-gate     if (( keydbpath = strdup( certdbpath )) == NULL ) {
21347c478bd9Sstevel@tonic-gate 	perror( "strdup" );
21357c478bd9Sstevel@tonic-gate 	exit( LDAP_NO_MEMORY );
21367c478bd9Sstevel@tonic-gate     }
21377c478bd9Sstevel@tonic-gate 
21387c478bd9Sstevel@tonic-gate     len = strlen( keydbpath );
21397c478bd9Sstevel@tonic-gate     if ( len > 7 &&
21407c478bd9Sstevel@tonic-gate 	    strcasecmp( "cert.db", keydbpath + len - 7 ) == 0 ) {
21417c478bd9Sstevel@tonic-gate 	striplen = 7;
21427c478bd9Sstevel@tonic-gate 	appendstr = "key.db";
214348bbca81SDaniel Hoffman 
21447c478bd9Sstevel@tonic-gate     } else if ( len > 8 &&
21457c478bd9Sstevel@tonic-gate 	    strcasecmp( "cert5.db", keydbpath + len - 8 ) == 0 ) {
21467c478bd9Sstevel@tonic-gate 	striplen = 8;
21477c478bd9Sstevel@tonic-gate 	appendstr = "key5.db";
21487c478bd9Sstevel@tonic-gate     } else if ( len > 8 &&
21497c478bd9Sstevel@tonic-gate 	    strcasecmp( "cert7.db", keydbpath + len - 8 ) == 0 ) {
21507c478bd9Sstevel@tonic-gate 	striplen = 8;
21517c478bd9Sstevel@tonic-gate 	appendstr = "key3.db";
21527c478bd9Sstevel@tonic-gate     } else {
21537c478bd9Sstevel@tonic-gate 	striplen = 0;
21547c478bd9Sstevel@tonic-gate     }
21557c478bd9Sstevel@tonic-gate 
21567c478bd9Sstevel@tonic-gate     if ( striplen > 0 ) {
21577c478bd9Sstevel@tonic-gate 	/*
21587c478bd9Sstevel@tonic-gate 	 * The following code assumes that strlen( appendstr ) < striplen!
21597c478bd9Sstevel@tonic-gate 	 */
21607c478bd9Sstevel@tonic-gate 	strcpy( keydbpath + len - striplen, appendstr );
21617c478bd9Sstevel@tonic-gate     }
21627c478bd9Sstevel@tonic-gate 
21637c478bd9Sstevel@tonic-gate     return( keydbpath );
21647c478bd9Sstevel@tonic-gate }
21657c478bd9Sstevel@tonic-gate 
21667c478bd9Sstevel@tonic-gate #ifdef LDAP_TOOL_PKCS11
216748bbca81SDaniel Hoffman static
216848bbca81SDaniel Hoffman char *
21697c478bd9Sstevel@tonic-gate buildTokenCertName( const char *tokenName, const char *certName)
21707c478bd9Sstevel@tonic-gate {
217148bbca81SDaniel Hoffman 
21727c478bd9Sstevel@tonic-gate     int tokenlen = strlen(tokenName);
21737c478bd9Sstevel@tonic-gate     int len = tokenlen + strlen(certName) +2;
21747c478bd9Sstevel@tonic-gate     char *result;
217548bbca81SDaniel Hoffman 
21767c478bd9Sstevel@tonic-gate     if (( result = malloc( len )) != NULL) {
21777c478bd9Sstevel@tonic-gate 	strcpy(result, tokenName);
21787c478bd9Sstevel@tonic-gate 	*(result+tokenlen) = ':';
21797c478bd9Sstevel@tonic-gate 	++tokenlen;
21807c478bd9Sstevel@tonic-gate 	strcpy(result+tokenlen, certName);
21817c478bd9Sstevel@tonic-gate     } else {
21827c478bd9Sstevel@tonic-gate 	perror("malloc");
21837c478bd9Sstevel@tonic-gate 	exit( LDAP_NO_MEMORY );
21847c478bd9Sstevel@tonic-gate     }
21857c478bd9Sstevel@tonic-gate     return result;
21867c478bd9Sstevel@tonic-gate }
21877c478bd9Sstevel@tonic-gate 
21887c478bd9Sstevel@tonic-gate 
21897c478bd9Sstevel@tonic-gate 
21907c478bd9Sstevel@tonic-gate static
21917c478bd9Sstevel@tonic-gate int
21927c478bd9Sstevel@tonic-gate ldaptool_getcertpath( void *context, char **certlocp )
21937c478bd9Sstevel@tonic-gate {
219448bbca81SDaniel Hoffman 
21957c478bd9Sstevel@tonic-gate     *certlocp = ssl_certdbpath;
21967c478bd9Sstevel@tonic-gate     if ( ldaptool_verbose ) {
21977c478bd9Sstevel@tonic-gate 	if (ssl_certdbpath)
21987c478bd9Sstevel@tonic-gate 	{
21997c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_getcertpath -- %s\n"), ssl_certdbpath );
22007c478bd9Sstevel@tonic-gate 	}
22017c478bd9Sstevel@tonic-gate 	else
22027c478bd9Sstevel@tonic-gate 	{
22037c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_getcertpath -- (null)\n"));
22047c478bd9Sstevel@tonic-gate 	}
220548bbca81SDaniel Hoffman 
22067c478bd9Sstevel@tonic-gate     }
22077c478bd9Sstevel@tonic-gate     return LDAP_SUCCESS;
22087c478bd9Sstevel@tonic-gate }
22097c478bd9Sstevel@tonic-gate 
22107c478bd9Sstevel@tonic-gate int
22117c478bd9Sstevel@tonic-gate ldaptool_getcertname( void *context, char **certnamep )
221248bbca81SDaniel Hoffman {
221348bbca81SDaniel Hoffman 
22147c478bd9Sstevel@tonic-gate    *certnamep = ssl_certname;
22157c478bd9Sstevel@tonic-gate     if ( ldaptool_verbose ) {
22167c478bd9Sstevel@tonic-gate 	if (ssl_certname)
22177c478bd9Sstevel@tonic-gate 	{
22187c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_getcertname -- %s\n"), *certnamep);
22197c478bd9Sstevel@tonic-gate 	}
22207c478bd9Sstevel@tonic-gate 	else
22217c478bd9Sstevel@tonic-gate 	{
22227c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_getcertname -- (null)\n"));
22237c478bd9Sstevel@tonic-gate 	}
22247c478bd9Sstevel@tonic-gate     }
22257c478bd9Sstevel@tonic-gate     return LDAP_SUCCESS;
22267c478bd9Sstevel@tonic-gate }
22277c478bd9Sstevel@tonic-gate 
22287c478bd9Sstevel@tonic-gate int
22297c478bd9Sstevel@tonic-gate ldaptool_getkeypath(void *context, char **keylocp )
22307c478bd9Sstevel@tonic-gate {
22317c478bd9Sstevel@tonic-gate     *keylocp = ssl_keydbpath;
22327c478bd9Sstevel@tonic-gate     if ( ldaptool_verbose ) {
22337c478bd9Sstevel@tonic-gate 	if (ssl_keydbpath)
22347c478bd9Sstevel@tonic-gate 	{
22357c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_getkeypath -- %s\n"),*keylocp);
22367c478bd9Sstevel@tonic-gate 	}
22377c478bd9Sstevel@tonic-gate 	else
22387c478bd9Sstevel@tonic-gate 	{
22397c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_getkeypath -- (null)\n"));
22407c478bd9Sstevel@tonic-gate 	}
22417c478bd9Sstevel@tonic-gate     }
224248bbca81SDaniel Hoffman 
22437c478bd9Sstevel@tonic-gate     return LDAP_SUCCESS;
22447c478bd9Sstevel@tonic-gate }
22457c478bd9Sstevel@tonic-gate 
22467c478bd9Sstevel@tonic-gate int
22477c478bd9Sstevel@tonic-gate ldaptool_gettokenname( void *context, char **tokennamep )
22487c478bd9Sstevel@tonic-gate {
224948bbca81SDaniel Hoffman 
22507c478bd9Sstevel@tonic-gate     *tokennamep = pkcs_token;
22517c478bd9Sstevel@tonic-gate     if ( ldaptool_verbose ) {
22527c478bd9Sstevel@tonic-gate 	if (pkcs_token)
22537c478bd9Sstevel@tonic-gate 	{
22547c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_gettokenname -- %s\n"),*tokennamep);
22557c478bd9Sstevel@tonic-gate 	}
22567c478bd9Sstevel@tonic-gate 	else
22577c478bd9Sstevel@tonic-gate 	{
22587c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_gettokenname -- (null)\n"));
22597c478bd9Sstevel@tonic-gate 	}
22607c478bd9Sstevel@tonic-gate     }
22617c478bd9Sstevel@tonic-gate 
22627c478bd9Sstevel@tonic-gate     return LDAP_SUCCESS;
22637c478bd9Sstevel@tonic-gate }
22647c478bd9Sstevel@tonic-gate int
22657c478bd9Sstevel@tonic-gate ldaptool_gettokenpin( void *context, const char *tokennamep, char **tokenpinp)
22667c478bd9Sstevel@tonic-gate {
226748bbca81SDaniel Hoffman 
22687c478bd9Sstevel@tonic-gate #if 0
22697c478bd9Sstevel@tonic-gate   char *localtoken;
22707c478bd9Sstevel@tonic-gate #endif
22717c478bd9Sstevel@tonic-gate 
227248bbca81SDaniel Hoffman /* XXXceb this stuff is removed for the time being.
22737c478bd9Sstevel@tonic-gate  * This function should return the pin from ssl_password
22747c478bd9Sstevel@tonic-gate  */
22757c478bd9Sstevel@tonic-gate 
22767c478bd9Sstevel@tonic-gate 
22777c478bd9Sstevel@tonic-gate   *tokenpinp = ssl_passwd;
22787c478bd9Sstevel@tonic-gate   return LDAP_SUCCESS;
227948bbca81SDaniel Hoffman 
22807c478bd9Sstevel@tonic-gate #if 0
22817c478bd9Sstevel@tonic-gate 
22827c478bd9Sstevel@tonic-gate   ldaptool_gettokenname( NULL, &localtoken);
22837c478bd9Sstevel@tonic-gate 
22847c478bd9Sstevel@tonic-gate   if (strcmp( localtoken, tokennamep))
22857c478bd9Sstevel@tonic-gate 
22867c478bd9Sstevel@tonic-gate       *tokenpinp = pkcs_pin;
228748bbca81SDaniel Hoffman    else
22887c478bd9Sstevel@tonic-gate       *tokenpinp = NULL;
22897c478bd9Sstevel@tonic-gate 
22907c478bd9Sstevel@tonic-gate     if ( ldaptool_verbose ) {
22917c478bd9Sstevel@tonic-gate 	if (pkcs_pin)
22927c478bd9Sstevel@tonic-gate 	{
22937c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_getokenpin --%s\n"), tokenpinp);
22947c478bd9Sstevel@tonic-gate 	}
22957c478bd9Sstevel@tonic-gate 	else
22967c478bd9Sstevel@tonic-gate 	{
22977c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_getokenpin -- (null)\n"));
22987c478bd9Sstevel@tonic-gate 	}
22997c478bd9Sstevel@tonic-gate     }
23007c478bd9Sstevel@tonic-gate     return LDAP_SUCCESS;
23017c478bd9Sstevel@tonic-gate #endif
23027c478bd9Sstevel@tonic-gate }
23037c478bd9Sstevel@tonic-gate 
23047c478bd9Sstevel@tonic-gate int
23057c478bd9Sstevel@tonic-gate ldaptool_getmodpath( void *context, char **modulep )
23067c478bd9Sstevel@tonic-gate {
23077c478bd9Sstevel@tonic-gate     *modulep = ssl_secmodpath;
23087c478bd9Sstevel@tonic-gate     if ( ldaptool_verbose ) {
23097c478bd9Sstevel@tonic-gate 	if (ssl_secmodpath)
23107c478bd9Sstevel@tonic-gate 	{
23117c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_getmodpath -- %s\n"), *modulep);
23127c478bd9Sstevel@tonic-gate 	}
23137c478bd9Sstevel@tonic-gate 	else
23147c478bd9Sstevel@tonic-gate 	{
23157c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_getmodpath -- (null)\n"));
23167c478bd9Sstevel@tonic-gate 	}
23177c478bd9Sstevel@tonic-gate     }
231848bbca81SDaniel Hoffman 
23197c478bd9Sstevel@tonic-gate     return LDAP_SUCCESS;
23207c478bd9Sstevel@tonic-gate }
23217c478bd9Sstevel@tonic-gate 
23227c478bd9Sstevel@tonic-gate int
23237c478bd9Sstevel@tonic-gate ldaptool_getdonglefilename( void *context, char **filename )
23247c478bd9Sstevel@tonic-gate {
23257c478bd9Sstevel@tonic-gate     *filename = ssl_donglefile;
23267c478bd9Sstevel@tonic-gate     if ( ldaptool_verbose ) {
23277c478bd9Sstevel@tonic-gate 	if (ssl_donglefile)
23287c478bd9Sstevel@tonic-gate 	{
23297c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_getdonglefilename -- %s\n"), *filename);
23307c478bd9Sstevel@tonic-gate 	}
23317c478bd9Sstevel@tonic-gate 	else
23327c478bd9Sstevel@tonic-gate 	{
23337c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_getdonglefilename -- (null)\n"));
23347c478bd9Sstevel@tonic-gate 	}
233548bbca81SDaniel Hoffman 
23367c478bd9Sstevel@tonic-gate     }
233748bbca81SDaniel Hoffman 
23387c478bd9Sstevel@tonic-gate     return LDAP_SUCCESS;
23397c478bd9Sstevel@tonic-gate }
23407c478bd9Sstevel@tonic-gate 
23417c478bd9Sstevel@tonic-gate static int
23427c478bd9Sstevel@tonic-gate ldaptool_setcallbacks( struct ldapssl_pkcs_fns *pfns)
23437c478bd9Sstevel@tonic-gate {
23447c478bd9Sstevel@tonic-gate   pfns->pkcs_getcertpath = (int (*)(void *, char **))ldaptool_getcertpath;
23457c478bd9Sstevel@tonic-gate   pfns->pkcs_getcertname =  (int (*)(void *, char **))ldaptool_getcertname;
23467c478bd9Sstevel@tonic-gate   pfns->pkcs_getkeypath =  (int (*)(void *, char **)) ldaptool_getkeypath;
23477c478bd9Sstevel@tonic-gate   pfns->pkcs_getmodpath =  (int (*)(void *, char **)) ldaptool_getmodpath;
23487c478bd9Sstevel@tonic-gate   pfns->pkcs_getpin =  (int (*)(void *, const char*, char **)) ldaptool_gettokenpin;
23497c478bd9Sstevel@tonic-gate   pfns->pkcs_gettokenname =  (int (*)(void *, char **)) ldaptool_gettokenname;
23507c478bd9Sstevel@tonic-gate   pfns->pkcs_getdonglefilename =  (int (*)(void *, char **)) ldaptool_getdonglefilename;
23517c478bd9Sstevel@tonic-gate   pfns->local_structure_id=PKCS_STRUCTURE_ID;
23527c478bd9Sstevel@tonic-gate   return LDAP_SUCCESS;
23537c478bd9Sstevel@tonic-gate }
23547c478bd9Sstevel@tonic-gate 
23557c478bd9Sstevel@tonic-gate 
23567c478bd9Sstevel@tonic-gate 
23577c478bd9Sstevel@tonic-gate #ifdef FORTEZZA
23587c478bd9Sstevel@tonic-gate static int
23597c478bd9Sstevel@tonic-gate ldaptool_fortezza_init( int exit_on_error )
23607c478bd9Sstevel@tonic-gate {
23617c478bd9Sstevel@tonic-gate     int		rc, errcode;
23627c478bd9Sstevel@tonic-gate 
23637c478bd9Sstevel@tonic-gate     if ( fortezza_personality == NULL && fortezza_cardmask == 0 ) { /* no FORTEZZA desired */
23647c478bd9Sstevel@tonic-gate 	SSL_EnableGroup( SSL_GroupFortezza, DSFalse );	/* disable FORTEZZA */
23657c478bd9Sstevel@tonic-gate 	return( 0 );
23667c478bd9Sstevel@tonic-gate     }
23677c478bd9Sstevel@tonic-gate 
23687c478bd9Sstevel@tonic-gate     if (( rc = FortezzaConfigureServer( ldaptool_fortezza_getpin, fortezza_cardmask,
23697c478bd9Sstevel@tonic-gate 	    fortezza_personality, ldaptool_fortezza_alert, NULL, &errcode,
23707c478bd9Sstevel@tonic-gate 	    fortezza_krlfile )) < 0 ) {
23717c478bd9Sstevel@tonic-gate 	fprintf( stderr,
23727c478bd9Sstevel@tonic-gate 		"%s: FORTEZZA initialization failed (error %d - %s)\n",
23737c478bd9Sstevel@tonic-gate 		ldaptool_progname, errcode,
23747c478bd9Sstevel@tonic-gate 		ldaptool_fortezza_err2string( errcode ));
23757c478bd9Sstevel@tonic-gate 	if ( exit_on_error ) {
23767c478bd9Sstevel@tonic-gate 	    exit( LDAP_LOCAL_ERROR );
23777c478bd9Sstevel@tonic-gate 	}
23787c478bd9Sstevel@tonic-gate 
23797c478bd9Sstevel@tonic-gate 	SSL_EnableGroup( SSL_GroupFortezza, DSFalse );	/* disable FORTEZZA */
23807c478bd9Sstevel@tonic-gate 	return( -1 );
23817c478bd9Sstevel@tonic-gate     }
23827c478bd9Sstevel@tonic-gate 
23837c478bd9Sstevel@tonic-gate     SSL_EnableGroup( SSL_GroupFortezza, DSTrue );	/* enable FORTEZZA */
23847c478bd9Sstevel@tonic-gate     return( 0 );
23857c478bd9Sstevel@tonic-gate }
23867c478bd9Sstevel@tonic-gate 
23877c478bd9Sstevel@tonic-gate 
23887c478bd9Sstevel@tonic-gate static int
23897c478bd9Sstevel@tonic-gate ldaptool_fortezza_alert( void *arg, PRBool onOpen, char *string,
23907c478bd9Sstevel@tonic-gate 	int value1, void *value2 )
23917c478bd9Sstevel@tonic-gate {
23927c478bd9Sstevel@tonic-gate     fprintf( stderr, "%s: FORTEZZA alert: ", ldaptool_progname );
23937c478bd9Sstevel@tonic-gate     fprintf( stderr, string, value1, value2 );
23947c478bd9Sstevel@tonic-gate     fprintf( stderr, "\n" );
23957c478bd9Sstevel@tonic-gate     return( 1 );
23967c478bd9Sstevel@tonic-gate }
23977c478bd9Sstevel@tonic-gate 
23987c478bd9Sstevel@tonic-gate 
23997c478bd9Sstevel@tonic-gate static void *
24007c478bd9Sstevel@tonic-gate ldaptool_fortezza_getpin( char **passwordp )
24017c478bd9Sstevel@tonic-gate {
24027c478bd9Sstevel@tonic-gate     *passwordp = fortezza_pin;
24037c478bd9Sstevel@tonic-gate     return( *passwordp );
24047c478bd9Sstevel@tonic-gate }
24057c478bd9Sstevel@tonic-gate 
24067c478bd9Sstevel@tonic-gate 
24077c478bd9Sstevel@tonic-gate /*
24087c478bd9Sstevel@tonic-gate  * convert a Fortezza error code (as returned by FortezzaConfigureServer()
24097c478bd9Sstevel@tonic-gate  * into a human-readable string.
24107c478bd9Sstevel@tonic-gate  *
24117c478bd9Sstevel@tonic-gate  * Error strings are intentionally similar to those found in
24127c478bd9Sstevel@tonic-gate  * ns/netsite/lib/libadmin/httpcon.c
24137c478bd9Sstevel@tonic-gate  */
24147c478bd9Sstevel@tonic-gate static char *
24157c478bd9Sstevel@tonic-gate ldaptool_fortezza_err2string( int err )
24167c478bd9Sstevel@tonic-gate {
24177c478bd9Sstevel@tonic-gate     char	*s;
24187c478bd9Sstevel@tonic-gate 
24197c478bd9Sstevel@tonic-gate     switch( err ) {
24207c478bd9Sstevel@tonic-gate     case FORTEZZA_BADPASSWD:
24217c478bd9Sstevel@tonic-gate 	s = "invalid pin number";
24227c478bd9Sstevel@tonic-gate 	break;
24237c478bd9Sstevel@tonic-gate     case FORTEZZA_BADCARD:
24247c478bd9Sstevel@tonic-gate 	s = "bad or missing card";
24257c478bd9Sstevel@tonic-gate 	break;
24267c478bd9Sstevel@tonic-gate     case FORTEZZA_MISSING_KRL:
24277c478bd9Sstevel@tonic-gate 	s = "bad or missing compromised key list";
24287c478bd9Sstevel@tonic-gate 	break;
24297c478bd9Sstevel@tonic-gate     case FORTEZZA_CERT_INIT_ERROR:
24307c478bd9Sstevel@tonic-gate 	s = "unable to initialize certificate cache.  either a cert on "
24317c478bd9Sstevel@tonic-gate 		"the card is bad, or an old FORTEZZA certificate is in a"
24327c478bd9Sstevel@tonic-gate 		 "readonly database";
24337c478bd9Sstevel@tonic-gate 	break;
24347c478bd9Sstevel@tonic-gate     case FORTEZZA_EXPIRED_CERT:
24357c478bd9Sstevel@tonic-gate 	s = "unable to verify certificate";
24367c478bd9Sstevel@tonic-gate 	break;
24377c478bd9Sstevel@tonic-gate     default:
24387c478bd9Sstevel@tonic-gate 	s = "unknown error";
24397c478bd9Sstevel@tonic-gate     }
24407c478bd9Sstevel@tonic-gate 
24417c478bd9Sstevel@tonic-gate     return( s );
24427c478bd9Sstevel@tonic-gate }
24437c478bd9Sstevel@tonic-gate 
24447c478bd9Sstevel@tonic-gate #endif /* FORTEZZA */
24457c478bd9Sstevel@tonic-gate #endif /* LDAP_TOOL_PKCS11 */
24467c478bd9Sstevel@tonic-gate #endif /* NET_SSL */
24477c478bd9Sstevel@tonic-gate 
24487c478bd9Sstevel@tonic-gate int
24497c478bd9Sstevel@tonic-gate ldaptool_boolean_str2value ( const char *ptr, int strict )
24507c478bd9Sstevel@tonic-gate {
24517c478bd9Sstevel@tonic-gate     if (strict) {
24527c478bd9Sstevel@tonic-gate 	if ( !(strcasecmp(ptr, "true"))) {
24537c478bd9Sstevel@tonic-gate 	    return 1;
24547c478bd9Sstevel@tonic-gate 	}
24557c478bd9Sstevel@tonic-gate 	else if ( !(strcasecmp(ptr, "false"))) {
24567c478bd9Sstevel@tonic-gate 	    return 0;
24577c478bd9Sstevel@tonic-gate 	}
24587c478bd9Sstevel@tonic-gate 	else {
24597c478bd9Sstevel@tonic-gate 	    return (-1);
24607c478bd9Sstevel@tonic-gate 	}
24617c478bd9Sstevel@tonic-gate     }
24627c478bd9Sstevel@tonic-gate     else {
24637c478bd9Sstevel@tonic-gate 	if ( !(strcasecmp(ptr, "true")) ||
24647c478bd9Sstevel@tonic-gate 	     !(strcasecmp(ptr, "t")) ||
24657c478bd9Sstevel@tonic-gate 	     !(strcmp(ptr, "1")) ) {
24667c478bd9Sstevel@tonic-gate 		return (1);
24677c478bd9Sstevel@tonic-gate 	}
24687c478bd9Sstevel@tonic-gate 	else if ( !(strcasecmp(ptr, "false")) ||
24697c478bd9Sstevel@tonic-gate 	     !(strcasecmp(ptr, "f")) ||
24707c478bd9Sstevel@tonic-gate 	     !(strcmp(ptr, "0")) ) {
24717c478bd9Sstevel@tonic-gate 	    	return (0);
24727c478bd9Sstevel@tonic-gate 	}
247348bbca81SDaniel Hoffman 	else {
24747c478bd9Sstevel@tonic-gate 	    return (-1);
247548bbca81SDaniel Hoffman 	}
24767c478bd9Sstevel@tonic-gate     }
247748bbca81SDaniel Hoffman }
24787c478bd9Sstevel@tonic-gate 
24797c478bd9Sstevel@tonic-gate FILE *
24807c478bd9Sstevel@tonic-gate ldaptool_open_file(const char *filename, const char *mode)
24817c478bd9Sstevel@tonic-gate {
24827c478bd9Sstevel@tonic-gate #ifdef _LARGEFILE64_SOURCE
24837c478bd9Sstevel@tonic-gate 	return fopen64(filename, mode);
24847c478bd9Sstevel@tonic-gate #else
24857c478bd9Sstevel@tonic-gate 	return fopen(filename, mode);
24867c478bd9Sstevel@tonic-gate #endif
24877c478bd9Sstevel@tonic-gate }
24887c478bd9Sstevel@tonic-gate 
24897c478bd9Sstevel@tonic-gate #ifdef later
24907c478bd9Sstevel@tonic-gate /* Functions for list in ldapdelete.c */
24917c478bd9Sstevel@tonic-gate 
24927c478bd9Sstevel@tonic-gate void L_Init(Head *list)
24937c478bd9Sstevel@tonic-gate {
24947c478bd9Sstevel@tonic-gate     if(list)
24957c478bd9Sstevel@tonic-gate     {
24967c478bd9Sstevel@tonic-gate         list->first = NULL;
24977c478bd9Sstevel@tonic-gate         list->last = NULL;
24987c478bd9Sstevel@tonic-gate         list->count = 0;
24997c478bd9Sstevel@tonic-gate     }
25007c478bd9Sstevel@tonic-gate }
25017c478bd9Sstevel@tonic-gate 
25027c478bd9Sstevel@tonic-gate void L_Insert(Element *Node, Head *HeadNode)
25037c478bd9Sstevel@tonic-gate {
25047c478bd9Sstevel@tonic-gate     if (!Node || !HeadNode)
25057c478bd9Sstevel@tonic-gate         return;
25067c478bd9Sstevel@tonic-gate 
25077c478bd9Sstevel@tonic-gate     Node->right = NULL;
25087c478bd9Sstevel@tonic-gate 
25097c478bd9Sstevel@tonic-gate     if (HeadNode->first == NULL)
25107c478bd9Sstevel@tonic-gate     {
25117c478bd9Sstevel@tonic-gate         Node->left= NULL;
25127c478bd9Sstevel@tonic-gate         HeadNode->last = HeadNode->first = Node;
25137c478bd9Sstevel@tonic-gate     }
25147c478bd9Sstevel@tonic-gate     else
25157c478bd9Sstevel@tonic-gate     {
25167c478bd9Sstevel@tonic-gate         Node->left = HeadNode->last;
25177c478bd9Sstevel@tonic-gate         HeadNode->last = Node->left->right = Node;
25187c478bd9Sstevel@tonic-gate     }
25197c478bd9Sstevel@tonic-gate     HeadNode->count++;
25207c478bd9Sstevel@tonic-gate }
25217c478bd9Sstevel@tonic-gate 
25227c478bd9Sstevel@tonic-gate void L_Remove(Element *Node, Head *HeadNode)
25237c478bd9Sstevel@tonic-gate {
25247c478bd9Sstevel@tonic-gate     Element *traverse = NULL;
25257c478bd9Sstevel@tonic-gate     Element *prevnode = NULL;
25267c478bd9Sstevel@tonic-gate 
25277c478bd9Sstevel@tonic-gate     if(!Node || !HeadNode)
25287c478bd9Sstevel@tonic-gate         return;
25297c478bd9Sstevel@tonic-gate 
25307c478bd9Sstevel@tonic-gate     for(traverse = HeadNode->first; traverse; traverse = traverse->right)
25317c478bd9Sstevel@tonic-gate     {
25327c478bd9Sstevel@tonic-gate         if(traverse == Node)
25337c478bd9Sstevel@tonic-gate         {
25347c478bd9Sstevel@tonic-gate             if(HeadNode->first == traverse)
25357c478bd9Sstevel@tonic-gate             {
25367c478bd9Sstevel@tonic-gate                 HeadNode->first = traverse->right;
25377c478bd9Sstevel@tonic-gate             }
25387c478bd9Sstevel@tonic-gate             if(HeadNode->last == traverse)
25397c478bd9Sstevel@tonic-gate             {
25407c478bd9Sstevel@tonic-gate                 HeadNode->last = prevnode;
25417c478bd9Sstevel@tonic-gate             }
25427c478bd9Sstevel@tonic-gate             traverse = traverse->right;
25437c478bd9Sstevel@tonic-gate             if(prevnode != NULL)
25447c478bd9Sstevel@tonic-gate             {
25457c478bd9Sstevel@tonic-gate                 prevnode->right = traverse;
25467c478bd9Sstevel@tonic-gate             }
25477c478bd9Sstevel@tonic-gate             if(traverse != NULL)
25487c478bd9Sstevel@tonic-gate             {
25497c478bd9Sstevel@tonic-gate                 traverse->left = prevnode;
25507c478bd9Sstevel@tonic-gate             }
25517c478bd9Sstevel@tonic-gate             HeadNode->count--;
25527c478bd9Sstevel@tonic-gate             return;
25537c478bd9Sstevel@tonic-gate         }
25547c478bd9Sstevel@tonic-gate         else /* traverse != node */
25557c478bd9Sstevel@tonic-gate         {
25567c478bd9Sstevel@tonic-gate             prevnode = traverse;
25577c478bd9Sstevel@tonic-gate         }
25587c478bd9Sstevel@tonic-gate     }
25597c478bd9Sstevel@tonic-gate }
25607c478bd9Sstevel@tonic-gate #endif
25617c478bd9Sstevel@tonic-gate 
25627c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
256348bbca81SDaniel Hoffman /*
25647c478bd9Sstevel@tonic-gate  * Function checks for valid args, returns an error if not found
25657c478bd9Sstevel@tonic-gate  * and sets SASL params from command line
25667c478bd9Sstevel@tonic-gate  */
25677c478bd9Sstevel@tonic-gate 
25687c478bd9Sstevel@tonic-gate static int
25697c478bd9Sstevel@tonic-gate saslSetParam(char *saslarg)
25707c478bd9Sstevel@tonic-gate {
25717c478bd9Sstevel@tonic-gate 	char *attr = NULL;
25727c478bd9Sstevel@tonic-gate 
25737c478bd9Sstevel@tonic-gate 	attr = strchr(saslarg, '=');
25747c478bd9Sstevel@tonic-gate 	if (attr == NULL) {
25757c478bd9Sstevel@tonic-gate            fprintf( stderr, gettext("Didn't find \"=\" character in %s\n"), saslarg);
25767c478bd9Sstevel@tonic-gate            return (-1);
25777c478bd9Sstevel@tonic-gate 	}
25787c478bd9Sstevel@tonic-gate 	*attr = '\0';
25797c478bd9Sstevel@tonic-gate 	attr++;
258048bbca81SDaniel Hoffman 
25817c478bd9Sstevel@tonic-gate 	if (!strcasecmp(saslarg, "secProp")) {
25827c478bd9Sstevel@tonic-gate 	     if ( sasl_secprops != NULL ) {
25837c478bd9Sstevel@tonic-gate                 fprintf( stderr, gettext("secProp previously specified\n"));
25847c478bd9Sstevel@tonic-gate                 return (-1);
25857c478bd9Sstevel@tonic-gate              }
25867c478bd9Sstevel@tonic-gate              if (( sasl_secprops = strdup(attr)) == NULL ) {
25877c478bd9Sstevel@tonic-gate 		perror ("malloc");
25887c478bd9Sstevel@tonic-gate                 exit (LDAP_NO_MEMORY);
25897c478bd9Sstevel@tonic-gate              }
25907c478bd9Sstevel@tonic-gate 	} else if (!strcasecmp(saslarg, "realm")) {
25917c478bd9Sstevel@tonic-gate 	     if ( sasl_realm != NULL ) {
25927c478bd9Sstevel@tonic-gate                 fprintf( stderr, gettext("Realm previously specified\n"));
25937c478bd9Sstevel@tonic-gate                 return (-1);
25947c478bd9Sstevel@tonic-gate              }
25957c478bd9Sstevel@tonic-gate              if (( sasl_realm = strdup(attr)) == NULL ) {
25967c478bd9Sstevel@tonic-gate 		perror ("malloc");
25977c478bd9Sstevel@tonic-gate                 exit (LDAP_NO_MEMORY);
25987c478bd9Sstevel@tonic-gate              }
25997c478bd9Sstevel@tonic-gate 	} else if (!strcasecmp(saslarg, "authzid")) {
26007c478bd9Sstevel@tonic-gate              if (sasl_username != NULL) {
26017c478bd9Sstevel@tonic-gate                 fprintf( stderr, gettext("Authorization name previously specified\n"));
26027c478bd9Sstevel@tonic-gate                 return (-1);
26037c478bd9Sstevel@tonic-gate              }
26047c478bd9Sstevel@tonic-gate              if (( sasl_username = strdup(attr)) == NULL ) {
26057c478bd9Sstevel@tonic-gate 		perror ("malloc");
26067c478bd9Sstevel@tonic-gate                 exit (LDAP_NO_MEMORY);
26077c478bd9Sstevel@tonic-gate              }
26087c478bd9Sstevel@tonic-gate 	} else if (!strcasecmp(saslarg, "authid")) {
26097c478bd9Sstevel@tonic-gate              if ( sasl_authid != NULL ) {
26107c478bd9Sstevel@tonic-gate                 fprintf( stderr, gettext("Authentication name previously specified\n"));
26117c478bd9Sstevel@tonic-gate                 return (-1);
26127c478bd9Sstevel@tonic-gate              }
26137c478bd9Sstevel@tonic-gate              if (( sasl_authid = strdup(attr)) == NULL) {
26147c478bd9Sstevel@tonic-gate 		perror ("malloc");
26157c478bd9Sstevel@tonic-gate                 exit (LDAP_NO_MEMORY);
26167c478bd9Sstevel@tonic-gate              }
26177c478bd9Sstevel@tonic-gate 	} else if (!strcasecmp(saslarg, "mech")) {
26187c478bd9Sstevel@tonic-gate 	     if ( sasl_mech != NULL ) {
26197c478bd9Sstevel@tonic-gate                 fprintf( stderr, gettext("Mech previously specified\n"));
26207c478bd9Sstevel@tonic-gate                 return (-1);
26217c478bd9Sstevel@tonic-gate              }
26227c478bd9Sstevel@tonic-gate 	     if (( sasl_mech = strdup(attr)) == NULL) {
26237c478bd9Sstevel@tonic-gate 		perror ("malloc");
26247c478bd9Sstevel@tonic-gate 		exit (LDAP_NO_MEMORY);
26257c478bd9Sstevel@tonic-gate 	     }
26267c478bd9Sstevel@tonic-gate 	} else {
26277c478bd9Sstevel@tonic-gate 	     fprintf (stderr, gettext("Invalid attribute name %s\n"), saslarg);
26287c478bd9Sstevel@tonic-gate 	     return (-1);
262948bbca81SDaniel Hoffman 	}
26307c478bd9Sstevel@tonic-gate 	return 0;
26317c478bd9Sstevel@tonic-gate }
26327c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
2633ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India 
2634ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India /*
2635ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India  * check for and report input or output error on named stream
2636ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India  * return ldap_err or ferror() (ldap_err takes precedence)
2637ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India  * assume that fflush() already has been called if needed.
2638ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India  * don't want to fflush() an input stream.
2639ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India  */
2640ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India int
2641ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India ldaptool_check_ferror(FILE * stream, const int ldap_err, const char *msg)
2642ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India {
2643ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India 	int err = 0;
2644ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India 	if ((err = ferror(stream)) != 0 ) {
2645ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India 		fprintf(stderr, gettext("%s: ERROR: "), ldaptool_progname);
2646ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India 		perror(msg);
2647ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India 		err = LDAP_LOCAL_ERROR;
2648ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India 	}
2649ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India 
2650ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India 	/*
2651ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India 	 * reporting LDAP error code is more important than
2652ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India 	 * reporting errors from ferror()
2653ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India 	 */
2654ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India 	if (ldap_err == LDAP_SUCCESS) {
2655ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India 		return(err);
2656ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India 	} else {
2657ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India 		return(ldap_err);
2658ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India 	}
2659ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India }
2660