xref: /illumos-gate/usr/src/cmd/ldap/common/common.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
3*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
4*7c478bd9Sstevel@tonic-gate  */
5*7c478bd9Sstevel@tonic-gate 
6*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
7*7c478bd9Sstevel@tonic-gate 
8*7c478bd9Sstevel@tonic-gate /*
9*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the Netscape Public
10*7c478bd9Sstevel@tonic-gate  * License Version 1.1 (the "License"); you may not use this file
11*7c478bd9Sstevel@tonic-gate  * except in compliance with the License. You may obtain a copy of
12*7c478bd9Sstevel@tonic-gate  * the License at http://www.mozilla.org/NPL/
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * Software distributed under the License is distributed on an "AS
15*7c478bd9Sstevel@tonic-gate  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
16*7c478bd9Sstevel@tonic-gate  * implied. See the License for the specific language governing
17*7c478bd9Sstevel@tonic-gate  * rights and limitations under the License.
18*7c478bd9Sstevel@tonic-gate  *
19*7c478bd9Sstevel@tonic-gate  * The Original Code is Mozilla Communicator client code, released
20*7c478bd9Sstevel@tonic-gate  * March 31, 1998.
21*7c478bd9Sstevel@tonic-gate  *
22*7c478bd9Sstevel@tonic-gate  * The Initial Developer of the Original Code is Netscape
23*7c478bd9Sstevel@tonic-gate  * Communications Corporation. Portions created by Netscape are
24*7c478bd9Sstevel@tonic-gate  * Copyright (C) 1998-1999 Netscape Communications Corporation. All
25*7c478bd9Sstevel@tonic-gate  * Rights Reserved.
26*7c478bd9Sstevel@tonic-gate  *
27*7c478bd9Sstevel@tonic-gate  * Contributor(s):
28*7c478bd9Sstevel@tonic-gate  */
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate /*
31*7c478bd9Sstevel@tonic-gate  * code that is shared by two or more of the LDAP command line tools
32*7c478bd9Sstevel@tonic-gate  */
33*7c478bd9Sstevel@tonic-gate 
34*7c478bd9Sstevel@tonic-gate #include "ldaptool.h"
35*7c478bd9Sstevel@tonic-gate #include "fileurl.h"
36*7c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
37*7c478bd9Sstevel@tonic-gate #include "solaris-int.h"
38*7c478bd9Sstevel@tonic-gate #include <ldap.h>
39*7c478bd9Sstevel@tonic-gate #include <locale.h>
40*7c478bd9Sstevel@tonic-gate #include <libgen.h>
41*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
42*7c478bd9Sstevel@tonic-gate #include <sys/stat.h>
43*7c478bd9Sstevel@tonic-gate #include <limits.h>
44*7c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
45*7c478bd9Sstevel@tonic-gate 
46*7c478bd9Sstevel@tonic-gate #ifdef LDAP_TOOL_ARGPIN
47*7c478bd9Sstevel@tonic-gate #include "argpin.h"
48*7c478bd9Sstevel@tonic-gate #include "ntuserpin.h"
49*7c478bd9Sstevel@tonic-gate #endif /* LDAP_TOOL_ARGPIN */
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
52*7c478bd9Sstevel@tonic-gate #include <nspr.h> /* for PR_Cleanup() */
53*7c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
54*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
55*7c478bd9Sstevel@tonic-gate #include <time.h>	/* for time() and ctime() */
56*7c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
57*7c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
58*7c478bd9Sstevel@tonic-gate #include <sasl/sasl.h>
59*7c478bd9Sstevel@tonic-gate #else
60*7c478bd9Sstevel@tonic-gate #include <sasl.h>
61*7c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
62*7c478bd9Sstevel@tonic-gate #include "ldaptool-sasl.h"
63*7c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
64*7c478bd9Sstevel@tonic-gate 
65*7c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
66*7c478bd9Sstevel@tonic-gate #define gettext(s) s
67*7c478bd9Sstevel@tonic-gate #endif
68*7c478bd9Sstevel@tonic-gate 
69*7c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
70*7c478bd9Sstevel@tonic-gate #define	PATH_BUF_SIZE	(PATH_MAX + 1)
71*7c478bd9Sstevel@tonic-gate #endif
72*7c478bd9Sstevel@tonic-gate 
73*7c478bd9Sstevel@tonic-gate static LDAP_REBINDPROC_CALLBACK get_rebind_credentials;
74*7c478bd9Sstevel@tonic-gate static void print_library_info( const LDAPAPIInfo *aip, FILE *fp );
75*7c478bd9Sstevel@tonic-gate static int wait4result( LDAP *ld, int msgid, struct berval **servercredp,
76*7c478bd9Sstevel@tonic-gate 	char *msg );
77*7c478bd9Sstevel@tonic-gate static int parse_result( LDAP *ld, LDAPMessage *res,
78*7c478bd9Sstevel@tonic-gate 	struct berval **servercredp, char *msg, int freeit );
79*7c478bd9Sstevel@tonic-gate 
80*7c478bd9Sstevel@tonic-gate #ifdef LDAPTOOL_DEBUG_MEMORY
81*7c478bd9Sstevel@tonic-gate static void *ldaptool_debug_malloc( size_t size );
82*7c478bd9Sstevel@tonic-gate static void *ldaptool_debug_calloc( size_t nelem, size_t elsize );
83*7c478bd9Sstevel@tonic-gate static void *ldaptool_debug_realloc( void *ptr, size_t size );
84*7c478bd9Sstevel@tonic-gate static void ldaptool_debug_free( void *ptr );
85*7c478bd9Sstevel@tonic-gate #endif /* LDAPTOOL_DEBUG_MEMORY */
86*7c478bd9Sstevel@tonic-gate 
87*7c478bd9Sstevel@tonic-gate #if defined(NET_SSL)
88*7c478bd9Sstevel@tonic-gate static char *certpath2keypath( char *certdbpath );
89*7c478bd9Sstevel@tonic-gate static int ldaptool_setcallbacks( struct ldapssl_pkcs_fns *pfns);
90*7c478bd9Sstevel@tonic-gate static char * buildTokenCertName( const char *tokenName, const char *certName);
91*7c478bd9Sstevel@tonic-gate #ifdef FORTEZZA
92*7c478bd9Sstevel@tonic-gate static int ldaptool_fortezza_init( int exit_on_error );
93*7c478bd9Sstevel@tonic-gate static int ldaptool_fortezza_alert( void *arg, PRBool onOpen,
94*7c478bd9Sstevel@tonic-gate 	char *string, int value1, void *value2 );
95*7c478bd9Sstevel@tonic-gate static void * ldaptool_fortezza_getpin( char **passwordp );
96*7c478bd9Sstevel@tonic-gate static char * ldaptool_fortezza_err2string( int err );
97*7c478bd9Sstevel@tonic-gate #endif /* FORTEZZA */
98*7c478bd9Sstevel@tonic-gate #endif
99*7c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
100*7c478bd9Sstevel@tonic-gate static int saslSetParam(char *saslarg);
101*7c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
102*7c478bd9Sstevel@tonic-gate 
103*7c478bd9Sstevel@tonic-gate /*
104*7c478bd9Sstevel@tonic-gate  * display usage for common options with one exception: -f is not included
105*7c478bd9Sstevel@tonic-gate  * since the description tends to be tool-specific.
106*7c478bd9Sstevel@tonic-gate  *
107*7c478bd9Sstevel@tonic-gate  * As of 1-Jul-1998, of the characters in the set [A-Za-z] the following are
108*7c478bd9Sstevel@tonic-gate  * not currently used by any of the tools: EJgjqr
109*7c478bd9Sstevel@tonic-gate  */
110*7c478bd9Sstevel@tonic-gate void
111*7c478bd9Sstevel@tonic-gate ldaptool_common_usage( int two_hosts )
112*7c478bd9Sstevel@tonic-gate {
113*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -n\t\tshow what would be done but don't actually do it\n") );
114*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -v\t\trun in verbose mode (diagnostics to standard output)\n") );
115*7c478bd9Sstevel@tonic-gate     if ( two_hosts ) {
116*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("    -h host\tLDAP server1 name or IP address (default: %s)\n"), LDAPTOOL_DEFHOST );
117*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("    -p port\tLDAP server1 TCP port number (default: %d)\n"), LDAP_PORT );
118*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("    -h host\tLDAP server2 name or IP address (default: %s)\n"), LDAPTOOL_DEFHOST );
119*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("    -p port\tLDAP server2 TCP port number (default: %d)\n"), LDAP_PORT );
120*7c478bd9Sstevel@tonic-gate     } else {
121*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("    -h host\tLDAP server name or IP address (default: %s)\n"), LDAPTOOL_DEFHOST );
122*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("    -p port\tLDAP server TCP port number (default: %d)\n"), LDAP_PORT );
123*7c478bd9Sstevel@tonic-gate     }
124*7c478bd9Sstevel@tonic-gate     fprintf( stderr,
125*7c478bd9Sstevel@tonic-gate 	    gettext("    -V n\tLDAP protocol version number (%d or %d; default: %d)\n"),
126*7c478bd9Sstevel@tonic-gate 	    LDAP_VERSION2, LDAP_VERSION3, LDAP_VERSION3 );
127*7c478bd9Sstevel@tonic-gate #if defined(NET_SSL)
128*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -Z\t\tmake an SSL-encrypted connection\n") );
129*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -P pathname\tpath to SSL certificate database (default: current directory)\n") );
130*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -N\t\tname of certificate to use for SSL client authentication\n") );
131*7c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
132*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -K pathname\tpath to key database to use for SSL client authentication\n") );
133*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    \t\t(default: path to certificate database provided with -P option)\n") );
134*7c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
135*7c478bd9Sstevel@tonic-gate #ifdef LDAP_TOOL_PKCS11
136*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -m pathname\tpath to security module database\n"));
137*7c478bd9Sstevel@tonic-gate #endif /* LDAP_TOOL_PKCS11 */
138*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -W\t\tSSL key password\n") );
139*7c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
140*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -3\t\tcheck hostnames in SSL certificates\n") );
141*7c478bd9Sstevel@tonic-gate #endif	/SOLARIS_LDAP_CMD */
142*7c478bd9Sstevel@tonic-gate 
143*7c478bd9Sstevel@tonic-gate #ifdef LDAP_TOOL_PKCS11
144*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -Q [token][:certificate name]\tPKCS 11\n") );
145*7c478bd9Sstevel@tonic-gate     /*    fprintf( stderr, "    -X pathname\tFORTEZZA compromised key list (CKL)\n" ); */
146*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -I pin\tcard password file\n") );
147*7c478bd9Sstevel@tonic-gate #endif /* LDAP_TOOL_PKCS11 */
148*7c478bd9Sstevel@tonic-gate 
149*7c478bd9Sstevel@tonic-gate #endif /* NET_SSL */
150*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -D binddn\tbind dn\n") );
151*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -w passwd\tbind passwd (for simple authentication)\n") );
152*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -w - \tprompt for bind passwd (for simple authentication)\n") );
153*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -j file\tread bind passwd (for simple authentication)\n") );
154*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("      \t\tor SSL key password from 'file'\n") );
155*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -E\t\task server to expose (report) bind identity\n") );
156*7c478bd9Sstevel@tonic-gate #ifdef LDAP_DEBUG
157*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -d level\tset LDAP debugging level to `level'\n") );
158*7c478bd9Sstevel@tonic-gate #endif
159*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -R\t\tdo not automatically follow referrals\n") );
160*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -O limit\tmaximum number of referral hops to traverse (default: %d)\n"), LDAPTOOL_DEFREFHOPLIMIT );
161*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -M\t\tmanage references (treat them as regular entries)\n") );
162*7c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
163*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -0\t\tignore LDAP library version mismatches\n") );
164*7c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
165*7c478bd9Sstevel@tonic-gate 
166*7c478bd9Sstevel@tonic-gate #ifndef NO_LIBLCACHE
167*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -C cfgfile\tuse local database described by cfgfile\n") );
168*7c478bd9Sstevel@tonic-gate #endif
169*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -i charset\tcharacter set for command line input (default taken from locale)\n") );
170*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -k dir\tconversion routine directory (default: current directory)\n") );
171*7c478bd9Sstevel@tonic-gate #if 0
172*7c478bd9Sstevel@tonic-gate /*
173*7c478bd9Sstevel@tonic-gate  * Suppress usage for -y (old proxied authorization control) even though
174*7c478bd9Sstevel@tonic-gate  * we still support it.  We want to encourage people to use -Y instead (the
175*7c478bd9Sstevel@tonic-gate  * new proxied authorization control).
176*7c478bd9Sstevel@tonic-gate  */
177*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -y proxydn\tDN used for proxy authorization\n") );
178*7c478bd9Sstevel@tonic-gate #endif
179*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -Y proxyid\tproxied authorization id,\n") );
180*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("              \te.g, dn:uid=bjensen,dc=example,dc=com\n") );
181*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -H\t\tdisplay usage information\n") );
182*7c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
183*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -?\t\tdisplay usage information\n") );
184*7c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
185*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -J controloid[:criticality[:value|::b64value|:<fileurl]]\n") );
186*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("\t\tcriticality is a boolean value (default is false)\n") );
187*7c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
188*7c478bd9Sstevel@tonic-gate     fprintf( stderr, gettext("    -o attrName=attrVal\tSASL options which are described in the man page\n"));
189*7c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
190*7c478bd9Sstevel@tonic-gate }
191*7c478bd9Sstevel@tonic-gate 
192*7c478bd9Sstevel@tonic-gate /* globals */
193*7c478bd9Sstevel@tonic-gate char			*ldaptool_charset = "";
194*7c478bd9Sstevel@tonic-gate char			*ldaptool_host = LDAPTOOL_DEFHOST;
195*7c478bd9Sstevel@tonic-gate char			*ldaptool_host2 = LDAPTOOL_DEFHOST;
196*7c478bd9Sstevel@tonic-gate int			ldaptool_port = LDAP_PORT;
197*7c478bd9Sstevel@tonic-gate int			ldaptool_port2 = LDAP_PORT;
198*7c478bd9Sstevel@tonic-gate int			ldaptool_verbose = 0;
199*7c478bd9Sstevel@tonic-gate int			ldaptool_not = 0;
200*7c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
201*7c478bd9Sstevel@tonic-gate int			ldaptool_require_binddn = 1;
202*7c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
203*7c478bd9Sstevel@tonic-gate FILE			*ldaptool_fp = NULL;
204*7c478bd9Sstevel@tonic-gate FILE			*password_fp = NULL;
205*7c478bd9Sstevel@tonic-gate char			*ldaptool_progname = "";
206*7c478bd9Sstevel@tonic-gate char			*ldaptool_nls_lang = NULL;
207*7c478bd9Sstevel@tonic-gate char                    *proxyauth_id = NULL;
208*7c478bd9Sstevel@tonic-gate int			proxyauth_version = 2;	/* use newer proxy control */
209*7c478bd9Sstevel@tonic-gate LDAPControl		*ldaptool_request_ctrls[CONTROL_REQUESTS] = {0};
210*7c478bd9Sstevel@tonic-gate #ifdef LDAP_DEBUG
211*7c478bd9Sstevel@tonic-gate int			ldaptool_dbg_lvl = 0;
212*7c478bd9Sstevel@tonic-gate #endif /* LDAP_DEBUG */
213*7c478bd9Sstevel@tonic-gate 
214*7c478bd9Sstevel@tonic-gate /* statics */
215*7c478bd9Sstevel@tonic-gate static char		*binddn = NULL;
216*7c478bd9Sstevel@tonic-gate static char		*passwd = NULL;
217*7c478bd9Sstevel@tonic-gate static int		send_auth_response_ctrl = 0;
218*7c478bd9Sstevel@tonic-gate static int		user_specified_port = 0;
219*7c478bd9Sstevel@tonic-gate static int		user_specified_port2 = 0;
220*7c478bd9Sstevel@tonic-gate static int		chase_referrals = 1;
221*7c478bd9Sstevel@tonic-gate static int		lib_version_mismatch_is_fatal = 1;
222*7c478bd9Sstevel@tonic-gate static int		ldversion = -1;	/* use default */
223*7c478bd9Sstevel@tonic-gate static int		refhoplim = LDAPTOOL_DEFREFHOPLIMIT;
224*7c478bd9Sstevel@tonic-gate static int		send_manage_dsait_ctrl = 0;
225*7c478bd9Sstevel@tonic-gate static int		prompt_password = 0;
226*7c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
227*7c478bd9Sstevel@tonic-gate static unsigned		sasl_flags = LDAP_SASL_INTERACTIVE;
228*7c478bd9Sstevel@tonic-gate static char		*sasl_mech = NULL;
229*7c478bd9Sstevel@tonic-gate static char		*sasl_authid = NULL;
230*7c478bd9Sstevel@tonic-gate static char		*sasl_mode = NULL;
231*7c478bd9Sstevel@tonic-gate static char		*sasl_realm = NULL;
232*7c478bd9Sstevel@tonic-gate static char		*sasl_username = NULL;
233*7c478bd9Sstevel@tonic-gate static char		*sasl_secprops = NULL;
234*7c478bd9Sstevel@tonic-gate static int		ldapauth = -1;
235*7c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
236*7c478bd9Sstevel@tonic-gate 
237*7c478bd9Sstevel@tonic-gate #ifndef NO_LIBLCACHE
238*7c478bd9Sstevel@tonic-gate static char		*cache_config_file = NULL;
239*7c478bd9Sstevel@tonic-gate #endif /* !NO_LIBLCACHE */
240*7c478bd9Sstevel@tonic-gate #if defined(NET_SSL)
241*7c478bd9Sstevel@tonic-gate static int		secure = 0;
242*7c478bd9Sstevel@tonic-gate static int		isZ = 0;
243*7c478bd9Sstevel@tonic-gate static int		isN = 0;
244*7c478bd9Sstevel@tonic-gate static int		isW = 0;
245*7c478bd9Sstevel@tonic-gate static int		isw = 0;
246*7c478bd9Sstevel@tonic-gate static int		isD = 0;
247*7c478bd9Sstevel@tonic-gate static int		isj = 0;
248*7c478bd9Sstevel@tonic-gate static int		ssl_strength = LDAPTOOL_DEFSSLSTRENGTH;
249*7c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
250*7c478bd9Sstevel@tonic-gate static char		pathname[PATH_BUF_SIZE];
251*7c478bd9Sstevel@tonic-gate #endif
252*7c478bd9Sstevel@tonic-gate static char		*ssl_certdbpath = NULL;
253*7c478bd9Sstevel@tonic-gate static char		*ssl_keydbpath = NULL;
254*7c478bd9Sstevel@tonic-gate static char		*ssl_keyname = NULL;
255*7c478bd9Sstevel@tonic-gate static char		*ssl_certname = NULL;
256*7c478bd9Sstevel@tonic-gate static char		*ssl_passwd = NULL;
257*7c478bd9Sstevel@tonic-gate 
258*7c478bd9Sstevel@tonic-gate #ifdef LDAP_TOOL_PKCS11
259*7c478bd9Sstevel@tonic-gate static char     	*ssl_secmodpath = NULL;
260*7c478bd9Sstevel@tonic-gate 
261*7c478bd9Sstevel@tonic-gate static char             *pkcs_token = NULL;
262*7c478bd9Sstevel@tonic-gate 
263*7c478bd9Sstevel@tonic-gate static char             *ssl_donglefile = NULL;
264*7c478bd9Sstevel@tonic-gate 
265*7c478bd9Sstevel@tonic-gate #if 0
266*7c478bd9Sstevel@tonic-gate static char             *pkcs_pin = NULL;
267*7c478bd9Sstevel@tonic-gate #endif
268*7c478bd9Sstevel@tonic-gate static struct ldapssl_pkcs_fns local_pkcs_fns =
269*7c478bd9Sstevel@tonic-gate     {0,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL };
270*7c478bd9Sstevel@tonic-gate 
271*7c478bd9Sstevel@tonic-gate #ifdef FORTEZZA
272*7c478bd9Sstevel@tonic-gate static uint32		fortezza_cardmask = 0;
273*7c478bd9Sstevel@tonic-gate static char		*fortezza_personality = NULL;
274*7c478bd9Sstevel@tonic-gate static char		*fortezza_krlfile = NULL;
275*7c478bd9Sstevel@tonic-gate static char		*fortezza_pin = NULL;
276*7c478bd9Sstevel@tonic-gate #endif /* FORTEZZA */
277*7c478bd9Sstevel@tonic-gate #endif /* LDAP_TOOL_PKCS11 */
278*7c478bd9Sstevel@tonic-gate #endif /* NET_SSL */
279*7c478bd9Sstevel@tonic-gate 
280*7c478bd9Sstevel@tonic-gate /*
281*7c478bd9Sstevel@tonic-gate  * Handle general initialization and options that are common to all of
282*7c478bd9Sstevel@tonic-gate  * the LDAP tools.
283*7c478bd9Sstevel@tonic-gate  * Handle options that are common to all of the LDAP tools.
284*7c478bd9Sstevel@tonic-gate  * Note the the H option is included here but handled via the
285*7c478bd9Sstevel@tonic-gate  * extra_opt_callback function (along with any "extra_opts" ).
286*7c478bd9Sstevel@tonic-gate  *
287*7c478bd9Sstevel@tonic-gate  * Return: final value for optind or -1 if usage should be displayed (for
288*7c478bd9Sstevel@tonic-gate  * some fatal errors, we call exit here).
289*7c478bd9Sstevel@tonic-gate  */
290*7c478bd9Sstevel@tonic-gate int
291*7c478bd9Sstevel@tonic-gate ldaptool_process_args( int argc, char **argv, char *extra_opts,
292*7c478bd9Sstevel@tonic-gate 	int two_hosts, void (*extra_opt_callback)( int option, char *optarg ))
293*7c478bd9Sstevel@tonic-gate {
294*7c478bd9Sstevel@tonic-gate     int		rc, i, hostnum;
295*7c478bd9Sstevel@tonic-gate     char	*optstring, *common_opts;
296*7c478bd9Sstevel@tonic-gate     extern char	*optarg;
297*7c478bd9Sstevel@tonic-gate     extern int	optind;
298*7c478bd9Sstevel@tonic-gate     LDAPAPIInfo	ldai;
299*7c478bd9Sstevel@tonic-gate     char *ctrl_arg, *ctrl_oid=NULL, *ctrl_value=NULL;
300*7c478bd9Sstevel@tonic-gate     int ctrl_criticality=0, vlen;
301*7c478bd9Sstevel@tonic-gate     LDAPControl *ldctrl;
302*7c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
303*7c478bd9Sstevel@tonic-gate 	struct stat st;
304*7c478bd9Sstevel@tonic-gate #endif
305*7c478bd9Sstevel@tonic-gate 
306*7c478bd9Sstevel@tonic-gate 
307*7c478bd9Sstevel@tonic-gate     /*
308*7c478bd9Sstevel@tonic-gate      * Set program name global based on argv[0].
309*7c478bd9Sstevel@tonic-gate      */
310*7c478bd9Sstevel@tonic-gate     if (( ldaptool_progname = strrchr( argv[ 0 ], '/' )) == NULL ) {
311*7c478bd9Sstevel@tonic-gate         ldaptool_progname = argv[ 0 ];
312*7c478bd9Sstevel@tonic-gate     } else {
313*7c478bd9Sstevel@tonic-gate         ++ldaptool_progname;
314*7c478bd9Sstevel@tonic-gate     }
315*7c478bd9Sstevel@tonic-gate 
316*7c478bd9Sstevel@tonic-gate #ifdef LDAPTOOL_DEBUG_MEMORY
317*7c478bd9Sstevel@tonic-gate     {
318*7c478bd9Sstevel@tonic-gate 	struct ldap_memalloc_fns mafns = {
319*7c478bd9Sstevel@tonic-gate 		ldaptool_debug_malloc,
320*7c478bd9Sstevel@tonic-gate 		ldaptool_debug_calloc,
321*7c478bd9Sstevel@tonic-gate 		ldaptool_debug_realloc,
322*7c478bd9Sstevel@tonic-gate 		ldaptool_debug_free
323*7c478bd9Sstevel@tonic-gate 	};
324*7c478bd9Sstevel@tonic-gate 
325*7c478bd9Sstevel@tonic-gate 	ldap_set_option( NULL, LDAP_OPT_MEMALLOC_FN_PTRS, &mafns );
326*7c478bd9Sstevel@tonic-gate     }
327*7c478bd9Sstevel@tonic-gate #endif	/* LDAPTOOL_DEBUG_MEMORY */
328*7c478bd9Sstevel@tonic-gate 
329*7c478bd9Sstevel@tonic-gate #ifdef LDAP_DEBUG
330*7c478bd9Sstevel@tonic-gate     i = LDAP_DEBUG_ANY;
331*7c478bd9Sstevel@tonic-gate     ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, (void *) &i);
332*7c478bd9Sstevel@tonic-gate #endif
333*7c478bd9Sstevel@tonic-gate 
334*7c478bd9Sstevel@tonic-gate     /*
335*7c478bd9Sstevel@tonic-gate      * Perform a sanity check on the revision of the LDAP API library to
336*7c478bd9Sstevel@tonic-gate      * make sure it is at least as new as the one we were compiled against.
337*7c478bd9Sstevel@tonic-gate      * If the API implementation is from the same vendor as we were compiled
338*7c478bd9Sstevel@tonic-gate      * against, we also check to make sure the vendor version is at least
339*7c478bd9Sstevel@tonic-gate      * as new as the library we were compiled against.
340*7c478bd9Sstevel@tonic-gate      *
341*7c478bd9Sstevel@tonic-gate      * Version differences are fatal unless the -0 option is passed on the
342*7c478bd9Sstevel@tonic-gate      * tool command line (that's a zero, not an oh).  We check for the
343*7c478bd9Sstevel@tonic-gate      * presence of -0 in a crude way to it must appear by itself in argv.
344*7c478bd9Sstevel@tonic-gate      */
345*7c478bd9Sstevel@tonic-gate     for ( i = 1; i < argc; ++i ) {
346*7c478bd9Sstevel@tonic-gate 	if ( strcmp( argv[i], "-0" ) == 0 ) {
347*7c478bd9Sstevel@tonic-gate 	    lib_version_mismatch_is_fatal = 0;
348*7c478bd9Sstevel@tonic-gate 	    break;
349*7c478bd9Sstevel@tonic-gate 	}
350*7c478bd9Sstevel@tonic-gate     }
351*7c478bd9Sstevel@tonic-gate 
352*7c478bd9Sstevel@tonic-gate     memset( &ldai, 0, sizeof(ldai));
353*7c478bd9Sstevel@tonic-gate     ldai.ldapai_info_version = LDAP_API_INFO_VERSION;
354*7c478bd9Sstevel@tonic-gate     if (( rc = ldap_get_option( NULL, LDAP_OPT_API_INFO, &ldai )) != 0 ) {
355*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: unable to retrieve LDAP library version"
356*7c478bd9Sstevel@tonic-gate 		" information;\n\tthis program requires an LDAP library that"
357*7c478bd9Sstevel@tonic-gate 		" implements revision\n\t%d or greater of the LDAP API.\n"),
358*7c478bd9Sstevel@tonic-gate 		ldaptool_progname, LDAP_API_VERSION );
359*7c478bd9Sstevel@tonic-gate 	if ( lib_version_mismatch_is_fatal ) {
360*7c478bd9Sstevel@tonic-gate 	    exit( LDAP_LOCAL_ERROR );
361*7c478bd9Sstevel@tonic-gate 	}
362*7c478bd9Sstevel@tonic-gate     } else if ( ldai.ldapai_api_version < LDAP_API_VERSION ) {
363*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: this program requires an LDAP library that"
364*7c478bd9Sstevel@tonic-gate 		" implements revision\n\t%d or greater of the LDAP API;"
365*7c478bd9Sstevel@tonic-gate 		" running with revision %d.\n"),
366*7c478bd9Sstevel@tonic-gate 		ldaptool_progname, LDAP_API_VERSION, ldai.ldapai_api_version );
367*7c478bd9Sstevel@tonic-gate 	if ( lib_version_mismatch_is_fatal ) {
368*7c478bd9Sstevel@tonic-gate 	    exit( LDAP_LOCAL_ERROR );
369*7c478bd9Sstevel@tonic-gate 	}
370*7c478bd9Sstevel@tonic-gate     } else if ( strcmp( ldai.ldapai_vendor_name, LDAP_VENDOR_NAME ) != 0) {
371*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: this program requires %s's LDAP\n"
372*7c478bd9Sstevel@tonic-gate 		"\tlibrary version %2.2f or greater; running with\n"
373*7c478bd9Sstevel@tonic-gate 		"\t%s's version %2.2f.\n"),
374*7c478bd9Sstevel@tonic-gate 		ldaptool_progname, LDAP_VENDOR_NAME,
375*7c478bd9Sstevel@tonic-gate 		(float)LDAP_VENDOR_VERSION / 100,
376*7c478bd9Sstevel@tonic-gate 		ldai.ldapai_vendor_name,
377*7c478bd9Sstevel@tonic-gate 		(float)ldai.ldapai_vendor_version / 100 );
378*7c478bd9Sstevel@tonic-gate 	if ( lib_version_mismatch_is_fatal ) {
379*7c478bd9Sstevel@tonic-gate 	    exit( LDAP_LOCAL_ERROR );
380*7c478bd9Sstevel@tonic-gate 	}
381*7c478bd9Sstevel@tonic-gate     } else if (ldai.ldapai_vendor_version < LDAP_VENDOR_VERSION ) {
382*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: this program requires %s's LDAP\n"
383*7c478bd9Sstevel@tonic-gate 		"\tlibrary version %2.2f or greater; running with"
384*7c478bd9Sstevel@tonic-gate 		" version %2.2f.\n"),
385*7c478bd9Sstevel@tonic-gate 		ldaptool_progname, LDAP_VENDOR_NAME,
386*7c478bd9Sstevel@tonic-gate 		(float)LDAP_VENDOR_VERSION / 100,
387*7c478bd9Sstevel@tonic-gate 		(float)ldai.ldapai_vendor_version / 100 );
388*7c478bd9Sstevel@tonic-gate 	if ( lib_version_mismatch_is_fatal ) {
389*7c478bd9Sstevel@tonic-gate 	    exit( LDAP_LOCAL_ERROR );
390*7c478bd9Sstevel@tonic-gate 	}
391*7c478bd9Sstevel@tonic-gate     }
392*7c478bd9Sstevel@tonic-gate 
393*7c478bd9Sstevel@tonic-gate     /*
394*7c478bd9Sstevel@tonic-gate      * Process command line options.
395*7c478bd9Sstevel@tonic-gate      */
396*7c478bd9Sstevel@tonic-gate     if ( extra_opts == NULL ) {
397*7c478bd9Sstevel@tonic-gate 	extra_opts = "";
398*7c478bd9Sstevel@tonic-gate     }
399*7c478bd9Sstevel@tonic-gate 
400*7c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
401*7c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
402*7c478bd9Sstevel@tonic-gate     common_opts = "nvEMRH?Zd:D:f:h:j:N:O:o:P:p:W:w:V:i:k:y:Y:J:";
403*7c478bd9Sstevel@tonic-gate #else
404*7c478bd9Sstevel@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:";
405*7c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
406*7c478bd9Sstevel@tonic-gate #else
407*7c478bd9Sstevel@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:";
408*7c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
409*7c478bd9Sstevel@tonic-gate 
410*7c478bd9Sstevel@tonic-gate     /* note: optstring must include room for liblcache "C:" option */
411*7c478bd9Sstevel@tonic-gate     if (( optstring = (char *) malloc( strlen( extra_opts ) + strlen( common_opts )
412*7c478bd9Sstevel@tonic-gate 	    + 3 )) == NULL ) {
413*7c478bd9Sstevel@tonic-gate 	perror( "malloc" );
414*7c478bd9Sstevel@tonic-gate 	exit( LDAP_NO_MEMORY );
415*7c478bd9Sstevel@tonic-gate     }
416*7c478bd9Sstevel@tonic-gate 
417*7c478bd9Sstevel@tonic-gate #ifdef NO_LIBLCACHE
418*7c478bd9Sstevel@tonic-gate     sprintf( optstring, "%s%s", common_opts, extra_opts );
419*7c478bd9Sstevel@tonic-gate #else
420*7c478bd9Sstevel@tonic-gate     sprintf( optstring, "%s%sC:", common_opts, extra_opts );
421*7c478bd9Sstevel@tonic-gate #endif
422*7c478bd9Sstevel@tonic-gate 
423*7c478bd9Sstevel@tonic-gate     hostnum = 0;
424*7c478bd9Sstevel@tonic-gate     while ( (i = getopt( argc, argv, optstring )) != EOF ) {
425*7c478bd9Sstevel@tonic-gate 	switch( i ) {
426*7c478bd9Sstevel@tonic-gate 	case 'n':	/* do Not do any LDAP operations */
427*7c478bd9Sstevel@tonic-gate 	    ++ldaptool_not;
428*7c478bd9Sstevel@tonic-gate 	    break;
429*7c478bd9Sstevel@tonic-gate 	case 'v':	/* verbose mode */
430*7c478bd9Sstevel@tonic-gate 	    ++ldaptool_verbose;
431*7c478bd9Sstevel@tonic-gate 	    break;
432*7c478bd9Sstevel@tonic-gate 	case 'd':
433*7c478bd9Sstevel@tonic-gate #ifdef LDAP_DEBUG
434*7c478bd9Sstevel@tonic-gate 	    ldaptool_dbg_lvl = atoi( optarg );	/* */
435*7c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
436*7c478bd9Sstevel@tonic-gate 	    ldap_set_option(NULL, LBER_OPT_DEBUG_LEVEL,
437*7c478bd9Sstevel@tonic-gate 		    (void *)&ldaptool_dbg_lvl);
438*7c478bd9Sstevel@tonic-gate #else
439*7c478bd9Sstevel@tonic-gate 	    ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL,
440*7c478bd9Sstevel@tonic-gate 		    (void *)&ldaptool_dbg_lvl);
441*7c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
442*7c478bd9Sstevel@tonic-gate 	    ldaptool_dbg_lvl |= LDAP_DEBUG_ANY;
443*7c478bd9Sstevel@tonic-gate 	    ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL,
444*7c478bd9Sstevel@tonic-gate 		    (void *)&ldaptool_dbg_lvl);
445*7c478bd9Sstevel@tonic-gate #else /* LDAP_DEBUG */
446*7c478bd9Sstevel@tonic-gate 	    fprintf( stderr, gettext("compile with -DLDAP_DEBUG for debugging\n") );
447*7c478bd9Sstevel@tonic-gate #endif /* LDAP_DEBUG */
448*7c478bd9Sstevel@tonic-gate 	    break;
449*7c478bd9Sstevel@tonic-gate 	case 'R':	/* don't automatically chase referrals */
450*7c478bd9Sstevel@tonic-gate 	    chase_referrals = 0;
451*7c478bd9Sstevel@tonic-gate 	    break;
452*7c478bd9Sstevel@tonic-gate #ifndef NO_LIBLCACHE
453*7c478bd9Sstevel@tonic-gate 	case 'C':	/* search local database */
454*7c478bd9Sstevel@tonic-gate 	    cache_config_file = strdup( optarg );
455*7c478bd9Sstevel@tonic-gate 	    break;
456*7c478bd9Sstevel@tonic-gate #endif
457*7c478bd9Sstevel@tonic-gate 	case 'f':	/* input file */
458*7c478bd9Sstevel@tonic-gate 	    if ( optarg[0] == '-' && optarg[1] == '\0' ) {
459*7c478bd9Sstevel@tonic-gate 		ldaptool_fp = stdin;
460*7c478bd9Sstevel@tonic-gate 	    } else if (( ldaptool_fp = ldaptool_open_file( optarg, "r" )) == NULL ) {
461*7c478bd9Sstevel@tonic-gate 		perror( optarg );
462*7c478bd9Sstevel@tonic-gate 		exit( LDAP_PARAM_ERROR );
463*7c478bd9Sstevel@tonic-gate 	    }
464*7c478bd9Sstevel@tonic-gate 	    break;
465*7c478bd9Sstevel@tonic-gate 	case 'h':	/* ldap host */
466*7c478bd9Sstevel@tonic-gate 	    if ( hostnum == 0 ) {
467*7c478bd9Sstevel@tonic-gate 		ldaptool_host = strdup( optarg );
468*7c478bd9Sstevel@tonic-gate 	    } else {
469*7c478bd9Sstevel@tonic-gate 		ldaptool_host2 = strdup( optarg );
470*7c478bd9Sstevel@tonic-gate 	    }
471*7c478bd9Sstevel@tonic-gate 	    ++hostnum;
472*7c478bd9Sstevel@tonic-gate 	    break;
473*7c478bd9Sstevel@tonic-gate 	case 'D':	/* bind DN */
474*7c478bd9Sstevel@tonic-gate 	    isD = 1;
475*7c478bd9Sstevel@tonic-gate 	    binddn = strdup( optarg );
476*7c478bd9Sstevel@tonic-gate 	    break;
477*7c478bd9Sstevel@tonic-gate 	case 'E':	/* expose bind identity via auth. response control */
478*7c478bd9Sstevel@tonic-gate 	    ++send_auth_response_ctrl;
479*7c478bd9Sstevel@tonic-gate 	    break;
480*7c478bd9Sstevel@tonic-gate 
481*7c478bd9Sstevel@tonic-gate 	case 'p':	/* ldap port */
482*7c478bd9Sstevel@tonic-gate 	    if ( !user_specified_port ) {
483*7c478bd9Sstevel@tonic-gate 		++user_specified_port;
484*7c478bd9Sstevel@tonic-gate 		ldaptool_port = atoi( optarg );
485*7c478bd9Sstevel@tonic-gate 	    } else {
486*7c478bd9Sstevel@tonic-gate 		++user_specified_port2;
487*7c478bd9Sstevel@tonic-gate 		ldaptool_port2 = atoi( optarg );
488*7c478bd9Sstevel@tonic-gate 	    }
489*7c478bd9Sstevel@tonic-gate 	    break;
490*7c478bd9Sstevel@tonic-gate #if defined(NET_SSL)
491*7c478bd9Sstevel@tonic-gate 	case 'P':	/* path to security database */
492*7c478bd9Sstevel@tonic-gate 	    secure = 1; /* do SSL encryption */
493*7c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
494*7c478bd9Sstevel@tonic-gate 	    ssl_certdbpath = strdup(optarg);
495*7c478bd9Sstevel@tonic-gate 	    if (NULL == ssl_certdbpath) {
496*7c478bd9Sstevel@tonic-gate 		perror("malloc");
497*7c478bd9Sstevel@tonic-gate 		exit( LDAP_NO_MEMORY );
498*7c478bd9Sstevel@tonic-gate 	    }
499*7c478bd9Sstevel@tonic-gate #else
500*7c478bd9Sstevel@tonic-gate 		/*
501*7c478bd9Sstevel@tonic-gate 		 * Verify whether it's a base directory or a cert db file.
502*7c478bd9Sstevel@tonic-gate 		 * If it is not a directory, truncate the file name as
503*7c478bd9Sstevel@tonic-gate 		 * the revised NSS_Init() doesn't take file name any longer.
504*7c478bd9Sstevel@tonic-gate 		 */
505*7c478bd9Sstevel@tonic-gate 		if (strlcpy(pathname, optarg, PATH_BUF_SIZE) >= PATH_BUF_SIZE) {
506*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, gettext("\"-P\": Path name is too "
507*7c478bd9Sstevel@tonic-gate 				"long\n"));
508*7c478bd9Sstevel@tonic-gate 			exit(LDAP_PARAM_ERROR);
509*7c478bd9Sstevel@tonic-gate 		}
510*7c478bd9Sstevel@tonic-gate 
511*7c478bd9Sstevel@tonic-gate 		if (stat(pathname, &st) != 0) {
512*7c478bd9Sstevel@tonic-gate 			perror("stat");
513*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, gettext("\"-P\": Path name is "
514*7c478bd9Sstevel@tonic-gate 				"invalid\n"));
515*7c478bd9Sstevel@tonic-gate 			exit(LDAP_PARAM_ERROR);
516*7c478bd9Sstevel@tonic-gate 		} else {
517*7c478bd9Sstevel@tonic-gate 			if (S_ISREG(st.st_mode)) {
518*7c478bd9Sstevel@tonic-gate 				/* redir to a regular file's dir name */
519*7c478bd9Sstevel@tonic-gate 				ssl_certdbpath = dirname(pathname);
520*7c478bd9Sstevel@tonic-gate 			} else
521*7c478bd9Sstevel@tonic-gate 				ssl_certdbpath = pathname;
522*7c478bd9Sstevel@tonic-gate 		}
523*7c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */
524*7c478bd9Sstevel@tonic-gate 	    break;
525*7c478bd9Sstevel@tonic-gate 	case 'Z':	/* do SSL encryption */
526*7c478bd9Sstevel@tonic-gate 	    secure = 1;
527*7c478bd9Sstevel@tonic-gate 	    isZ = 1;
528*7c478bd9Sstevel@tonic-gate 	    break;
529*7c478bd9Sstevel@tonic-gate 	case 'N':	/* nickname of cert. to use for client auth. */
530*7c478bd9Sstevel@tonic-gate 	    ssl_certname = strdup( optarg );
531*7c478bd9Sstevel@tonic-gate 	    if (NULL == ssl_certname)
532*7c478bd9Sstevel@tonic-gate 	    {
533*7c478bd9Sstevel@tonic-gate 		perror("malloc");
534*7c478bd9Sstevel@tonic-gate 		exit( LDAP_NO_MEMORY );
535*7c478bd9Sstevel@tonic-gate 	    }
536*7c478bd9Sstevel@tonic-gate 	    isN = 1;
537*7c478bd9Sstevel@tonic-gate 	    break;
538*7c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
539*7c478bd9Sstevel@tonic-gate 	case 'K':	/* location of key database */
540*7c478bd9Sstevel@tonic-gate 	    ssl_keydbpath = strdup( optarg );
541*7c478bd9Sstevel@tonic-gate 	    if (NULL == ssl_keydbpath)
542*7c478bd9Sstevel@tonic-gate 	    {
543*7c478bd9Sstevel@tonic-gate 		perror("malloc");
544*7c478bd9Sstevel@tonic-gate 		exit( LDAP_NO_MEMORY );
545*7c478bd9Sstevel@tonic-gate 	    }
546*7c478bd9Sstevel@tonic-gate 	    break;
547*7c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
548*7c478bd9Sstevel@tonic-gate 
549*7c478bd9Sstevel@tonic-gate 	case 'W':	/* SSL key password */
550*7c478bd9Sstevel@tonic-gate 	    ssl_passwd = strdup( optarg );
551*7c478bd9Sstevel@tonic-gate 	    if (NULL == ssl_passwd)
552*7c478bd9Sstevel@tonic-gate 	    {
553*7c478bd9Sstevel@tonic-gate 		perror("malloc");
554*7c478bd9Sstevel@tonic-gate 		exit( LDAP_NO_MEMORY );
555*7c478bd9Sstevel@tonic-gate 	    }
556*7c478bd9Sstevel@tonic-gate 	    isW = 1;
557*7c478bd9Sstevel@tonic-gate 	    break;
558*7c478bd9Sstevel@tonic-gate 
559*7c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
560*7c478bd9Sstevel@tonic-gate 	case '3': /* check hostnames in SSL certificates ("no third") */
561*7c478bd9Sstevel@tonic-gate 	    ssl_strength = LDAPSSL_AUTH_CNCHECK;
562*7c478bd9Sstevel@tonic-gate 	    break;
563*7c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
564*7c478bd9Sstevel@tonic-gate 
565*7c478bd9Sstevel@tonic-gate #ifdef LDAP_TOOL_PKCS11
566*7c478bd9Sstevel@tonic-gate 	case 'm':	/* SSL secmod path */
567*7c478bd9Sstevel@tonic-gate 	    ssl_secmodpath = strdup( optarg);
568*7c478bd9Sstevel@tonic-gate 	    if (NULL == ssl_secmodpath)
569*7c478bd9Sstevel@tonic-gate 	    {
570*7c478bd9Sstevel@tonic-gate 		perror("malloc");
571*7c478bd9Sstevel@tonic-gate 		exit( LDAP_NO_MEMORY );
572*7c478bd9Sstevel@tonic-gate 	    }
573*7c478bd9Sstevel@tonic-gate 	    break;
574*7c478bd9Sstevel@tonic-gate 
575*7c478bd9Sstevel@tonic-gate 	case 'Q': 	/* FORTEZZA [card][:personality] */
576*7c478bd9Sstevel@tonic-gate 	    pkcs_token = strdup(optarg);
577*7c478bd9Sstevel@tonic-gate 	    if (NULL == pkcs_token)
578*7c478bd9Sstevel@tonic-gate 	    {
579*7c478bd9Sstevel@tonic-gate 		perror("malloc");
580*7c478bd9Sstevel@tonic-gate 		exit( LDAP_NO_MEMORY );
581*7c478bd9Sstevel@tonic-gate 	    }
582*7c478bd9Sstevel@tonic-gate 
583*7c478bd9Sstevel@tonic-gate 	    break;
584*7c478bd9Sstevel@tonic-gate 	    /* This option removed to prevent interference
585*7c478bd9Sstevel@tonic-gate 	       with the getEffectiveRights option, also -X
586*7c478bd9Sstevel@tonic-gate 	       case 'X':	* path to FORTEZZA CKL file *
587*7c478bd9Sstevel@tonic-gate 
588*7c478bd9Sstevel@tonic-gate 	       fortezza_krlfile = strdup( optarg );
589*7c478bd9Sstevel@tonic-gate 
590*7c478bd9Sstevel@tonic-gate 
591*7c478bd9Sstevel@tonic-gate 	       break;
592*7c478bd9Sstevel@tonic-gate 	    */
593*7c478bd9Sstevel@tonic-gate 	case 'I':	/* FORTEZZA PIN (password file) */
594*7c478bd9Sstevel@tonic-gate 	    ssl_donglefile = strdup( optarg );
595*7c478bd9Sstevel@tonic-gate 
596*7c478bd9Sstevel@tonic-gate 	    break;
597*7c478bd9Sstevel@tonic-gate #endif /* LDAP_TOOL_PKCS11 */
598*7c478bd9Sstevel@tonic-gate 
599*7c478bd9Sstevel@tonic-gate #endif /* NET_SSL */
600*7c478bd9Sstevel@tonic-gate 	case 'w':	/* bind password */
601*7c478bd9Sstevel@tonic-gate 	    isw = 1;
602*7c478bd9Sstevel@tonic-gate 	    if ( optarg[0] == '-' && optarg[1] == '\0' )
603*7c478bd9Sstevel@tonic-gate 		prompt_password = 1;
604*7c478bd9Sstevel@tonic-gate 	    else
605*7c478bd9Sstevel@tonic-gate 		passwd = strdup( optarg );
606*7c478bd9Sstevel@tonic-gate 	    break;
607*7c478bd9Sstevel@tonic-gate 	    case 'j':       /* bind password or SSL key password from file */
608*7c478bd9Sstevel@tonic-gate 	    isj = 1;
609*7c478bd9Sstevel@tonic-gate 	    if ((password_fp = fopen( optarg, "r" )) == NULL ) {
610*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("%s: Unable to open '%s' file\n"),
611*7c478bd9Sstevel@tonic-gate 			ldaptool_progname, optarg);
612*7c478bd9Sstevel@tonic-gate 		exit( LDAP_PARAM_ERROR );
613*7c478bd9Sstevel@tonic-gate 	    }
614*7c478bd9Sstevel@tonic-gate             break;
615*7c478bd9Sstevel@tonic-gate 	case 'O':	/* referral hop limit */
616*7c478bd9Sstevel@tonic-gate 	    refhoplim = atoi( optarg );
617*7c478bd9Sstevel@tonic-gate 	    break;
618*7c478bd9Sstevel@tonic-gate 	case 'V':	/* protocol version */
619*7c478bd9Sstevel@tonic-gate 	    ldversion = atoi (optarg);
620*7c478bd9Sstevel@tonic-gate 	    if ( ldversion != LDAP_VERSION2 && ldversion != LDAP_VERSION3 ) {
621*7c478bd9Sstevel@tonic-gate 		fprintf( stderr, gettext("%s: LDAP protocol version %d is not "
622*7c478bd9Sstevel@tonic-gate 			"supported (use -V%d or -V%d)\n"),
623*7c478bd9Sstevel@tonic-gate 			ldaptool_progname, ldversion, LDAP_VERSION2,
624*7c478bd9Sstevel@tonic-gate 			LDAP_VERSION3 );
625*7c478bd9Sstevel@tonic-gate 		exit( LDAP_PARAM_ERROR );
626*7c478bd9Sstevel@tonic-gate 	    }
627*7c478bd9Sstevel@tonic-gate 	    break;
628*7c478bd9Sstevel@tonic-gate 	case 'M':	/* send a manageDsaIT control */
629*7c478bd9Sstevel@tonic-gate 	    send_manage_dsait_ctrl = 1;
630*7c478bd9Sstevel@tonic-gate 	    break;
631*7c478bd9Sstevel@tonic-gate 
632*7c478bd9Sstevel@tonic-gate 	case 'i':   /* character set specified */
633*7c478bd9Sstevel@tonic-gate 	    ldaptool_charset = strdup( optarg );
634*7c478bd9Sstevel@tonic-gate 	    if (NULL == ldaptool_charset)
635*7c478bd9Sstevel@tonic-gate 	    {
636*7c478bd9Sstevel@tonic-gate 		perror( "malloc" );
637*7c478bd9Sstevel@tonic-gate 		exit( LDAP_NO_MEMORY );
638*7c478bd9Sstevel@tonic-gate 	    }
639*7c478bd9Sstevel@tonic-gate 
640*7c478bd9Sstevel@tonic-gate 	    break;
641*7c478bd9Sstevel@tonic-gate 	case 'k':   /* conversion directory */
642*7c478bd9Sstevel@tonic-gate 	    ldaptool_convdir = strdup( optarg );
643*7c478bd9Sstevel@tonic-gate 	    if (NULL == ldaptool_convdir)
644*7c478bd9Sstevel@tonic-gate 	    {
645*7c478bd9Sstevel@tonic-gate 		perror( "malloc" );
646*7c478bd9Sstevel@tonic-gate 		exit( LDAP_NO_MEMORY );
647*7c478bd9Sstevel@tonic-gate 	    }
648*7c478bd9Sstevel@tonic-gate 	    break;
649*7c478bd9Sstevel@tonic-gate 	case 'y':   /* old (version 1) proxied authorization control */
650*7c478bd9Sstevel@tonic-gate 		proxyauth_version = 1;
651*7c478bd9Sstevel@tonic-gate 	case 'Y':   /* new (version 2 ) proxied authorization control */
652*7c478bd9Sstevel@tonic-gate 		/*FALLTHRU*/
653*7c478bd9Sstevel@tonic-gate 	    proxyauth_id = strdup(optarg);
654*7c478bd9Sstevel@tonic-gate 	    if (NULL == proxyauth_id)
655*7c478bd9Sstevel@tonic-gate 	    {
656*7c478bd9Sstevel@tonic-gate 		perror( "malloc" );
657*7c478bd9Sstevel@tonic-gate 		exit( LDAP_NO_MEMORY );
658*7c478bd9Sstevel@tonic-gate 	    }
659*7c478bd9Sstevel@tonic-gate 
660*7c478bd9Sstevel@tonic-gate 	    break;
661*7c478bd9Sstevel@tonic-gate 
662*7c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
663*7c478bd9Sstevel@tonic-gate  	case '0':	/* zero -- override LDAP library version check */
664*7c478bd9Sstevel@tonic-gate 	    break;	/* already handled above */
665*7c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
666*7c478bd9Sstevel@tonic-gate 	case 'J':	 /* send an arbitrary control */
667*7c478bd9Sstevel@tonic-gate 	    if ( (ctrl_arg = strdup( optarg)) == NULL ) {
668*7c478bd9Sstevel@tonic-gate 		perror ("strdup");
669*7c478bd9Sstevel@tonic-gate 		exit (LDAP_NO_MEMORY);
670*7c478bd9Sstevel@tonic-gate 	    }
671*7c478bd9Sstevel@tonic-gate 	    if (ldaptool_parse_ctrl_arg(ctrl_arg, ':', &ctrl_oid,
672*7c478bd9Sstevel@tonic-gate 		    &ctrl_criticality, &ctrl_value, &vlen)) {
673*7c478bd9Sstevel@tonic-gate 		return (-1);
674*7c478bd9Sstevel@tonic-gate 	    }
675*7c478bd9Sstevel@tonic-gate 	    ldctrl = calloc(1,sizeof(LDAPControl));
676*7c478bd9Sstevel@tonic-gate 	    if (ctrl_value) {
677*7c478bd9Sstevel@tonic-gate 		rc = ldaptool_berval_from_ldif_value( ctrl_value,
678*7c478bd9Sstevel@tonic-gate 			vlen, &(ldctrl->ldctl_value),
679*7c478bd9Sstevel@tonic-gate 			1 /* recognize file URLs */,
680*7c478bd9Sstevel@tonic-gate 			0 /* always try file */,
681*7c478bd9Sstevel@tonic-gate 			1 /* report errors */ );
682*7c478bd9Sstevel@tonic-gate 		if ((rc = ldaptool_fileurlerr2ldaperr( rc )) != LDAP_SUCCESS) {
683*7c478bd9Sstevel@tonic-gate 		    fprintf( stderr, gettext("Unable to parse %s\n"), ctrl_value);
684*7c478bd9Sstevel@tonic-gate 		    return (-1);
685*7c478bd9Sstevel@tonic-gate 		}
686*7c478bd9Sstevel@tonic-gate 	    }
687*7c478bd9Sstevel@tonic-gate 	    ldctrl->ldctl_oid = ctrl_oid;
688*7c478bd9Sstevel@tonic-gate 	    ldctrl->ldctl_iscritical = ctrl_criticality;
689*7c478bd9Sstevel@tonic-gate 	    ldaptool_add_control_to_array(ldctrl, ldaptool_request_ctrls);
690*7c478bd9Sstevel@tonic-gate 	    break;
691*7c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
692*7c478bd9Sstevel@tonic-gate 	case 'o':	/* attribute assignment */
693*7c478bd9Sstevel@tonic-gate 	      if ((rc = saslSetParam(optarg)) == -1) {
694*7c478bd9Sstevel@tonic-gate 	      	  return (-1);
695*7c478bd9Sstevel@tonic-gate 	      }
696*7c478bd9Sstevel@tonic-gate 	      ldapauth = LDAP_AUTH_SASL;
697*7c478bd9Sstevel@tonic-gate 	      ldversion = LDAP_VERSION3;
698*7c478bd9Sstevel@tonic-gate 	      break;
699*7c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
700*7c478bd9Sstevel@tonic-gate 	default:
701*7c478bd9Sstevel@tonic-gate 	    (*extra_opt_callback)( i, optarg );
702*7c478bd9Sstevel@tonic-gate 	}
703*7c478bd9Sstevel@tonic-gate     }
704*7c478bd9Sstevel@tonic-gate 
705*7c478bd9Sstevel@tonic-gate 
706*7c478bd9Sstevel@tonic-gate     /* If '-Z' is specified, check if '-P' is specified too. */
707*7c478bd9Sstevel@tonic-gate     if ( isN || isW ) {
708*7c478bd9Sstevel@tonic-gate 	if ( !isZ ) {
709*7c478bd9Sstevel@tonic-gate 		fprintf( stderr, gettext("%s: with -N, -W options, please specify -Z\n\n"), ldaptool_progname );
710*7c478bd9Sstevel@tonic-gate 		return (-1);
711*7c478bd9Sstevel@tonic-gate 	}
712*7c478bd9Sstevel@tonic-gate     }
713*7c478bd9Sstevel@tonic-gate 
714*7c478bd9Sstevel@tonic-gate     /* if '-N' is specified, -W is needed too */
715*7c478bd9Sstevel@tonic-gate     if ( isN && NULL == ssl_passwd ) {
716*7c478bd9Sstevel@tonic-gate         fprintf( stderr, gettext("%s: with the -N option, please specify -W also\n\n"),
717*7c478bd9Sstevel@tonic-gate 		ldaptool_progname );
718*7c478bd9Sstevel@tonic-gate         return (-1);
719*7c478bd9Sstevel@tonic-gate     }
720*7c478bd9Sstevel@tonic-gate 
721*7c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
722*7c478bd9Sstevel@tonic-gate     if ( isj && ( isw || isW )) {
723*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, gettext("%s: -j and -w or -W options cannot be specified simultaneously\n\n"), ldaptool_progname );
724*7c478bd9Sstevel@tonic-gate #else
725*7c478bd9Sstevel@tonic-gate     if ( isj && isw ) {
726*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, gettext("%s: -j and -w options cannot be specified simultaneously\n\n"), ldaptool_progname );
727*7c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
728*7c478bd9Sstevel@tonic-gate 	return (-1);
729*7c478bd9Sstevel@tonic-gate     }
730*7c478bd9Sstevel@tonic-gate 
731*7c478bd9Sstevel@tonic-gate     /* complain if -j or -w does not also have -D, unless using SASL */
732*7c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
733*7c478bd9Sstevel@tonic-gate     if ( (isj || isw) && !isD && (  ldapauth != LDAP_AUTH_SASL ) ) {
734*7c478bd9Sstevel@tonic-gate #else
735*7c478bd9Sstevel@tonic-gate     if ( (isj || isw) && !isD ) {
736*7c478bd9Sstevel@tonic-gate #endif
737*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, gettext("%s: with -j, -w options, please specify -D\n\n"), ldaptool_progname );
738*7c478bd9Sstevel@tonic-gate 	return (-1);
739*7c478bd9Sstevel@tonic-gate     }
740*7c478bd9Sstevel@tonic-gate 
741*7c478bd9Sstevel@tonic-gate     /* use default key and cert DB paths if not set on the command line */
742*7c478bd9Sstevel@tonic-gate     if ( NULL == ssl_keydbpath ) {
743*7c478bd9Sstevel@tonic-gate         if ( NULL == ssl_certdbpath ) {
744*7c478bd9Sstevel@tonic-gate             ssl_keydbpath = LDAPTOOL_DEFKEYDBPATH;
745*7c478bd9Sstevel@tonic-gate         } else {
746*7c478bd9Sstevel@tonic-gate             ssl_keydbpath = certpath2keypath( ssl_certdbpath );
747*7c478bd9Sstevel@tonic-gate         }
748*7c478bd9Sstevel@tonic-gate     }
749*7c478bd9Sstevel@tonic-gate     if ( NULL == ssl_certdbpath ) {
750*7c478bd9Sstevel@tonic-gate         ssl_certdbpath = LDAPTOOL_DEFCERTDBPATH;
751*7c478bd9Sstevel@tonic-gate     }
752*7c478bd9Sstevel@tonic-gate 
753*7c478bd9Sstevel@tonic-gate     if (prompt_password != 0) {
754*7c478bd9Sstevel@tonic-gate 	char *password_string = "Enter bind password: ";
755*7c478bd9Sstevel@tonic-gate 
756*7c478bd9Sstevel@tonic-gate #if defined(_WIN32)
757*7c478bd9Sstevel@tonic-gate 	char pbuf[257];
758*7c478bd9Sstevel@tonic-gate 	fputs(password_string,stdout);
759*7c478bd9Sstevel@tonic-gate 	fflush(stdout);
760*7c478bd9Sstevel@tonic-gate 	if (fgets(pbuf,256,stdin) == NULL) {
761*7c478bd9Sstevel@tonic-gate 	    passwd = NULL;
762*7c478bd9Sstevel@tonic-gate 	} else {
763*7c478bd9Sstevel@tonic-gate 	    char *tmp;
764*7c478bd9Sstevel@tonic-gate 
765*7c478bd9Sstevel@tonic-gate 	    tmp = strchr(pbuf,'\n');
766*7c478bd9Sstevel@tonic-gate 	    if (tmp) *tmp = '\0';
767*7c478bd9Sstevel@tonic-gate 	    tmp = strchr(pbuf,'\r');
768*7c478bd9Sstevel@tonic-gate 	    if (tmp) *tmp = '\0';
769*7c478bd9Sstevel@tonic-gate 	    passwd = strdup(pbuf);
770*7c478bd9Sstevel@tonic-gate 	}
771*7c478bd9Sstevel@tonic-gate #else
772*7c478bd9Sstevel@tonic-gate #if defined(SOLARIS)
773*7c478bd9Sstevel@tonic-gate 	/* 256 characters on Solaris */
774*7c478bd9Sstevel@tonic-gate 	passwd = getpassphrase(password_string);
775*7c478bd9Sstevel@tonic-gate #else
776*7c478bd9Sstevel@tonic-gate 	/* limited to 16 chars on Tru64, 32 on AIX */
777*7c478bd9Sstevel@tonic-gate 	passwd = getpass(password_string);
778*7c478bd9Sstevel@tonic-gate #endif
779*7c478bd9Sstevel@tonic-gate #endif
780*7c478bd9Sstevel@tonic-gate 
781*7c478bd9Sstevel@tonic-gate     } else if (password_fp != NULL) {
782*7c478bd9Sstevel@tonic-gate 	char *linep = NULL;
783*7c478bd9Sstevel@tonic-gate 	int   increment = 0;
784*7c478bd9Sstevel@tonic-gate 	int   c, index;
785*7c478bd9Sstevel@tonic-gate 
786*7c478bd9Sstevel@tonic-gate 	/* allocate initial block of memory */
787*7c478bd9Sstevel@tonic-gate 	if ((linep = (char *)malloc(BUFSIZ)) == NULL) {
788*7c478bd9Sstevel@tonic-gate 	    fprintf( stderr, gettext("%s: not enough memory to read password from file\n"), ldaptool_progname );
789*7c478bd9Sstevel@tonic-gate 	    exit( LDAP_NO_MEMORY );
790*7c478bd9Sstevel@tonic-gate 	}
791*7c478bd9Sstevel@tonic-gate 	increment++;
792*7c478bd9Sstevel@tonic-gate 	index = 0;
793*7c478bd9Sstevel@tonic-gate 	while ((c = fgetc( password_fp )) != '\n' && c != EOF) {
794*7c478bd9Sstevel@tonic-gate 
795*7c478bd9Sstevel@tonic-gate 	    /* check if we will overflow the buffer */
796*7c478bd9Sstevel@tonic-gate 	    if ((c != EOF) && (index == ((increment * BUFSIZ) -1))) {
797*7c478bd9Sstevel@tonic-gate 
798*7c478bd9Sstevel@tonic-gate 		/* if we did, add another BUFSIZ worth of bytes */
799*7c478bd9Sstevel@tonic-gate 		if ((linep = (char *)
800*7c478bd9Sstevel@tonic-gate 		    realloc(linep, (increment + 1) * BUFSIZ)) == NULL) {
801*7c478bd9Sstevel@tonic-gate 			fprintf( stderr, gettext("%s: not enough memory to read password from file\n"), ldaptool_progname );
802*7c478bd9Sstevel@tonic-gate 			exit( LDAP_NO_MEMORY );
803*7c478bd9Sstevel@tonic-gate 		}
804*7c478bd9Sstevel@tonic-gate 	 	increment++;
805*7c478bd9Sstevel@tonic-gate 	    }
806*7c478bd9Sstevel@tonic-gate 	    linep[index++] = c;
807*7c478bd9Sstevel@tonic-gate 	}
808*7c478bd9Sstevel@tonic-gate 	linep[index] = '\0';
809*7c478bd9Sstevel@tonic-gate 	passwd = linep;
810*7c478bd9Sstevel@tonic-gate     }
811*7c478bd9Sstevel@tonic-gate 
812*7c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
813*7c478bd9Sstevel@tonic-gate     if (binddn != NULL && passwd == NULL) {
814*7c478bd9Sstevel@tonic-gate 	char *password_string = gettext("Enter bind password: ");
815*7c478bd9Sstevel@tonic-gate 	passwd = getpassphrase(password_string);
816*7c478bd9Sstevel@tonic-gate     }
817*7c478bd9Sstevel@tonic-gate 
818*7c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
819*7c478bd9Sstevel@tonic-gate     if (ldapauth == LDAP_AUTH_SASL) {
820*7c478bd9Sstevel@tonic-gate 	/* BindDN not required for SASL */
821*7c478bd9Sstevel@tonic-gate 	ldaptool_require_binddn = 0;
822*7c478bd9Sstevel@tonic-gate     }
823*7c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
824*7c478bd9Sstevel@tonic-gate 
825*7c478bd9Sstevel@tonic-gate #ifdef NET_SSL
826*7c478bd9Sstevel@tonic-gate     if (secure == 1) {
827*7c478bd9Sstevel@tonic-gate 	/* BindDN not required for SSL */
828*7c478bd9Sstevel@tonic-gate 	ldaptool_require_binddn = 0;
829*7c478bd9Sstevel@tonic-gate     }
830*7c478bd9Sstevel@tonic-gate #endif	/* NET_SSL */
831*7c478bd9Sstevel@tonic-gate 
832*7c478bd9Sstevel@tonic-gate     if (ldaptool_require_binddn && binddn == NULL && passwd == NULL) {
833*7c478bd9Sstevel@tonic-gate 		fprintf(stderr,
834*7c478bd9Sstevel@tonic-gate 			gettext("%s: DN and Bind Password are required.\n"),
835*7c478bd9Sstevel@tonic-gate 			ldaptool_progname );
836*7c478bd9Sstevel@tonic-gate 		exit(1);
837*7c478bd9Sstevel@tonic-gate     }
838*7c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
839*7c478bd9Sstevel@tonic-gate 
840*7c478bd9Sstevel@tonic-gate     /*
841*7c478bd9Sstevel@tonic-gate      * If verbose (-v) flag was passed in, display program name and start time.
842*7c478bd9Sstevel@tonic-gate      * If the verbose flag was passed at least twice (-vv), also display
843*7c478bd9Sstevel@tonic-gate      * information about the API library we are running with.
844*7c478bd9Sstevel@tonic-gate      */
845*7c478bd9Sstevel@tonic-gate     if ( ldaptool_verbose ) {
846*7c478bd9Sstevel@tonic-gate 	time_t	curtime;
847*7c478bd9Sstevel@tonic-gate 
848*7c478bd9Sstevel@tonic-gate 	curtime = time( NULL );
849*7c478bd9Sstevel@tonic-gate 	printf( gettext("%s: started %s\n"), ldaptool_progname, ctime( &curtime ));
850*7c478bd9Sstevel@tonic-gate 	if ( ldaptool_verbose > 1 ) {
851*7c478bd9Sstevel@tonic-gate 	    print_library_info( &ldai, stdout );
852*7c478bd9Sstevel@tonic-gate 	}
853*7c478bd9Sstevel@tonic-gate     }
854*7c478bd9Sstevel@tonic-gate 
855*7c478bd9Sstevel@tonic-gate #ifdef LDAP_TOOL_PKCS11
856*7c478bd9Sstevel@tonic-gate     if ((NULL != pkcs_token) && (NULL != ssl_certname)) {
857*7c478bd9Sstevel@tonic-gate 	char *result;
858*7c478bd9Sstevel@tonic-gate 
859*7c478bd9Sstevel@tonic-gate 	if ( (result = buildTokenCertName( pkcs_token, ssl_certname)) != NULL){
860*7c478bd9Sstevel@tonic-gate 	    free( ssl_certname );
861*7c478bd9Sstevel@tonic-gate 	    ssl_certname = result;
862*7c478bd9Sstevel@tonic-gate 	}
863*7c478bd9Sstevel@tonic-gate     }
864*7c478bd9Sstevel@tonic-gate #endif /* LDAP_TOOL_PKCS11 */
865*7c478bd9Sstevel@tonic-gate 
866*7c478bd9Sstevel@tonic-gate     free( optstring );
867*7c478bd9Sstevel@tonic-gate 
868*7c478bd9Sstevel@tonic-gate     /*
869*7c478bd9Sstevel@tonic-gate      * Clean up and return index of first non-option argument.
870*7c478bd9Sstevel@tonic-gate      */
871*7c478bd9Sstevel@tonic-gate     if ( ldai.ldapai_extensions != NULL ) {
872*7c478bd9Sstevel@tonic-gate 	ldap_value_free( ldai.ldapai_extensions );
873*7c478bd9Sstevel@tonic-gate     }
874*7c478bd9Sstevel@tonic-gate     if ( ldai.ldapai_vendor_name != NULL ) {
875*7c478bd9Sstevel@tonic-gate 	ldap_memfree( ldai.ldapai_vendor_name );
876*7c478bd9Sstevel@tonic-gate     }
877*7c478bd9Sstevel@tonic-gate 
878*7c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
879*7c478bd9Sstevel@tonic-gate     if (ldversion == LDAP_VERSION2 && ldapauth == LDAP_AUTH_SASL) {
880*7c478bd9Sstevel@tonic-gate        fprintf( stderr, gettext("Incompatible with version %d\n"), ldversion);
881*7c478bd9Sstevel@tonic-gate        return (-1);
882*7c478bd9Sstevel@tonic-gate     }
883*7c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
884*7c478bd9Sstevel@tonic-gate     return( optind );
885*7c478bd9Sstevel@tonic-gate }
886*7c478bd9Sstevel@tonic-gate 
887*7c478bd9Sstevel@tonic-gate 
888*7c478bd9Sstevel@tonic-gate /*
889*7c478bd9Sstevel@tonic-gate  * Write detailed information about the API library we are running with to fp.
890*7c478bd9Sstevel@tonic-gate  */
891*7c478bd9Sstevel@tonic-gate static void
892*7c478bd9Sstevel@tonic-gate print_library_info( const LDAPAPIInfo *aip, FILE *fp )
893*7c478bd9Sstevel@tonic-gate {
894*7c478bd9Sstevel@tonic-gate     int                 i;
895*7c478bd9Sstevel@tonic-gate     LDAPAPIFeatureInfo  fi;
896*7c478bd9Sstevel@tonic-gate 
897*7c478bd9Sstevel@tonic-gate     fprintf( fp, gettext("LDAP Library Information -\n"
898*7c478bd9Sstevel@tonic-gate 	    "    Highest supported protocol version: %d\n"
899*7c478bd9Sstevel@tonic-gate 	    "    LDAP API revision:                  %d\n"
900*7c478bd9Sstevel@tonic-gate 	    "    API vendor name:                    %s\n"
901*7c478bd9Sstevel@tonic-gate 	    "    Vendor-specific version:            %.2f\n"),
902*7c478bd9Sstevel@tonic-gate 	    aip->ldapai_protocol_version, aip->ldapai_api_version,
903*7c478bd9Sstevel@tonic-gate 	    aip->ldapai_vendor_name,
904*7c478bd9Sstevel@tonic-gate 	    (float)aip->ldapai_vendor_version / 100.0 );
905*7c478bd9Sstevel@tonic-gate 
906*7c478bd9Sstevel@tonic-gate     if ( aip->ldapai_extensions != NULL ) {
907*7c478bd9Sstevel@tonic-gate 	fputs( gettext("    LDAP API Extensions:\n"), fp );
908*7c478bd9Sstevel@tonic-gate 
909*7c478bd9Sstevel@tonic-gate 	for ( i = 0; aip->ldapai_extensions[i] != NULL; i++ )  {
910*7c478bd9Sstevel@tonic-gate 	    fprintf( fp, gettext("        %s"), aip->ldapai_extensions[i] );
911*7c478bd9Sstevel@tonic-gate 	    fi.ldapaif_info_version = LDAP_FEATURE_INFO_VERSION;
912*7c478bd9Sstevel@tonic-gate 	    fi.ldapaif_name = aip->ldapai_extensions[i];
913*7c478bd9Sstevel@tonic-gate 	    fi.ldapaif_version = 0;
914*7c478bd9Sstevel@tonic-gate 
915*7c478bd9Sstevel@tonic-gate 	    if ( ldap_get_option( NULL, LDAP_OPT_API_FEATURE_INFO, &fi )
916*7c478bd9Sstevel@tonic-gate 		    != 0 ) {
917*7c478bd9Sstevel@tonic-gate 		fprintf( fp, gettext(" %s: ldap_get_option( NULL,"
918*7c478bd9Sstevel@tonic-gate 			" LDAP_OPT_API_FEATURE_INFO, ... ) for %s failed"
919*7c478bd9Sstevel@tonic-gate 			" (Feature Info version: %d)\n"), ldaptool_progname,
920*7c478bd9Sstevel@tonic-gate 			fi.ldapaif_name, fi.ldapaif_info_version );
921*7c478bd9Sstevel@tonic-gate 	    } else {
922*7c478bd9Sstevel@tonic-gate 		fprintf( fp, gettext(" (revision %d)\n"), fi.ldapaif_version);
923*7c478bd9Sstevel@tonic-gate 	    }
924*7c478bd9Sstevel@tonic-gate 	}
925*7c478bd9Sstevel@tonic-gate     }
926*7c478bd9Sstevel@tonic-gate    fputc( '\n', fp );
927*7c478bd9Sstevel@tonic-gate }
928*7c478bd9Sstevel@tonic-gate 
929*7c478bd9Sstevel@tonic-gate 
930*7c478bd9Sstevel@tonic-gate 
931*7c478bd9Sstevel@tonic-gate #ifdef LDAP_TOOL_ARGPIN
932*7c478bd9Sstevel@tonic-gate static int PinArgRegistration( void )
933*7c478bd9Sstevel@tonic-gate {
934*7c478bd9Sstevel@tonic-gate 
935*7c478bd9Sstevel@tonic-gate     /* pkcs_init was successful  register the pin args */
936*7c478bd9Sstevel@tonic-gate 
937*7c478bd9Sstevel@tonic-gate     SVRCOREArgPinObj *ArgPinObj;
938*7c478bd9Sstevel@tonic-gate     char *tokenName;
939*7c478bd9Sstevel@tonic-gate #ifndef _WIN32
940*7c478bd9Sstevel@tonic-gate     SVRCOREStdPinObj *StdPinObj;
941*7c478bd9Sstevel@tonic-gate #else
942*7c478bd9Sstevel@tonic-gate     SVRCOREFilePinObj *FilePinObj;
943*7c478bd9Sstevel@tonic-gate     SVRCOREAltPinObj *AltPinObj;
944*7c478bd9Sstevel@tonic-gate     SVRCORENTUserPinObj *NTUserPinObj;
945*7c478bd9Sstevel@tonic-gate     int err;
946*7c478bd9Sstevel@tonic-gate #endif
947*7c478bd9Sstevel@tonic-gate     char *pin;
948*7c478bd9Sstevel@tonic-gate     char *filename;
949*7c478bd9Sstevel@tonic-gate     /* Create and register the pin object for PKCS 11 */
950*7c478bd9Sstevel@tonic-gate     local_pkcs_fns.pkcs_getdonglefilename(NULL, &filename);
951*7c478bd9Sstevel@tonic-gate     local_pkcs_fns.pkcs_getpin(NULL, "", &pin);
952*7c478bd9Sstevel@tonic-gate #ifndef _WIN32
953*7c478bd9Sstevel@tonic-gate     if ( SVRCORE_CreateStdPinObj(&StdPinObj, filename, PR_TRUE) !=
954*7c478bd9Sstevel@tonic-gate 	 SVRCORE_Success) {
955*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, gettext("Security Initialization: Unable to create PinObj "
956*7c478bd9Sstevel@tonic-gate 	       "(%d)"), PR_GetError());
957*7c478bd9Sstevel@tonic-gate 	return -1;
958*7c478bd9Sstevel@tonic-gate     }
959*7c478bd9Sstevel@tonic-gate     if (pin != NULL)
960*7c478bd9Sstevel@tonic-gate     {
961*7c478bd9Sstevel@tonic-gate 	local_pkcs_fns.pkcs_gettokenname(NULL, &tokenName);
962*7c478bd9Sstevel@tonic-gate 	SVRCORE_CreateArgPinObj(&ArgPinObj, tokenName, pin, (SVRCOREPinObj *)StdPinObj);
963*7c478bd9Sstevel@tonic-gate 	SVRCORE_RegisterPinObj((SVRCOREPinObj *)ArgPinObj);
964*7c478bd9Sstevel@tonic-gate     }
965*7c478bd9Sstevel@tonic-gate     else
966*7c478bd9Sstevel@tonic-gate     {
967*7c478bd9Sstevel@tonic-gate 	SVRCORE_RegisterPinObj((SVRCOREPinObj *)StdPinObj);
968*7c478bd9Sstevel@tonic-gate     }
969*7c478bd9Sstevel@tonic-gate #else
970*7c478bd9Sstevel@tonic-gate     if (NULL != pin)
971*7c478bd9Sstevel@tonic-gate     {
972*7c478bd9Sstevel@tonic-gate 	local_pkcs_fns.pkcs_gettokenname(NULL, &tokenName);
973*7c478bd9Sstevel@tonic-gate 	if ((err = SVRCORE_CreateNTUserPinObj(&NTUserPinObj)) != SVRCORE_Success){
974*7c478bd9Sstevel@tonic-gate 	    fprintf(stderr, gettext("Security Initialization: Unable to create NTUserPinObj "
975*7c478bd9Sstevel@tonic-gate 		   "(%d)"), PR_GetError());
976*7c478bd9Sstevel@tonic-gate 	    exit( LDAP_LOCAL_ERROR );
977*7c478bd9Sstevel@tonic-gate 	}
978*7c478bd9Sstevel@tonic-gate 	if ((err = SVRCORE_CreateArgPinObj(&ArgPinObj, tokenName, pin,
979*7c478bd9Sstevel@tonic-gate 					   (SVRCOREPinObj *)NTUserPinObj)) != SVRCORE_Success)
980*7c478bd9Sstevel@tonic-gate 	{
981*7c478bd9Sstevel@tonic-gate 	    fprintf(stderr, gettext("Security Initialization: Unable to create ArgPinObj "
982*7c478bd9Sstevel@tonic-gate 		   "(%d)"), PR_GetError());
983*7c478bd9Sstevel@tonic-gate 	    return -1;
984*7c478bd9Sstevel@tonic-gate 
985*7c478bd9Sstevel@tonic-gate 	}
986*7c478bd9Sstevel@tonic-gate 	SVRCORE_RegisterPinObj((SVRCOREPinObj *)ArgPinObj);
987*7c478bd9Sstevel@tonic-gate 
988*7c478bd9Sstevel@tonic-gate     }
989*7c478bd9Sstevel@tonic-gate     else
990*7c478bd9Sstevel@tonic-gate     {
991*7c478bd9Sstevel@tonic-gate 	if ((err = SVRCORE_CreateNTUserPinObj(&NTUserPinObj)) != SVRCORE_Success){
992*7c478bd9Sstevel@tonic-gate 	    fprintf(stderr, gettext("Security Initialization: Unable to create NTUserPinObj "
993*7c478bd9Sstevel@tonic-gate 		   "(%d)"), PR_GetError());
994*7c478bd9Sstevel@tonic-gate 		return -1;
995*7c478bd9Sstevel@tonic-gate 	}
996*7c478bd9Sstevel@tonic-gate 	if (filename && *filename)
997*7c478bd9Sstevel@tonic-gate 	{
998*7c478bd9Sstevel@tonic-gate 	    if ((err = SVRCORE_CreateFilePinObj(&FilePinObj, filename)) !=
999*7c478bd9Sstevel@tonic-gate 		SVRCORE_Success) {
1000*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("Security Initialization: Unable to create FilePinObj "
1001*7c478bd9Sstevel@tonic-gate 		       "(%d)"), PR_GetError());
1002*7c478bd9Sstevel@tonic-gate 		return -1;
1003*7c478bd9Sstevel@tonic-gate 
1004*7c478bd9Sstevel@tonic-gate 	    }
1005*7c478bd9Sstevel@tonic-gate 	    if ((err = SVRCORE_CreateAltPinObj(&AltPinObj, (SVRCOREPinObj *)FilePinObj,
1006*7c478bd9Sstevel@tonic-gate 					       (SVRCOREPinObj *)NTUserPinObj)) != SVRCORE_Success) {
1007*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("Security Initialization: Unable to create AltPinObj "
1008*7c478bd9Sstevel@tonic-gate 		       "(%d)"), PR_GetError());
1009*7c478bd9Sstevel@tonic-gate 		return -1;
1010*7c478bd9Sstevel@tonic-gate 	    }
1011*7c478bd9Sstevel@tonic-gate 	    SVRCORE_RegisterPinObj((SVRCOREPinObj *)AltPinObj);
1012*7c478bd9Sstevel@tonic-gate 	}
1013*7c478bd9Sstevel@tonic-gate 	else
1014*7c478bd9Sstevel@tonic-gate 	{
1015*7c478bd9Sstevel@tonic-gate 	    SVRCORE_RegisterPinObj((SVRCOREPinObj *)NTUserPinObj);
1016*7c478bd9Sstevel@tonic-gate 	}
1017*7c478bd9Sstevel@tonic-gate     }
1018*7c478bd9Sstevel@tonic-gate #endif
1019*7c478bd9Sstevel@tonic-gate     return LDAP_SUCCESS;
1020*7c478bd9Sstevel@tonic-gate 
1021*7c478bd9Sstevel@tonic-gate }
1022*7c478bd9Sstevel@tonic-gate #endif /* LDAP_TOOL_ARGPIN */
1023*7c478bd9Sstevel@tonic-gate 
1024*7c478bd9Sstevel@tonic-gate 
1025*7c478bd9Sstevel@tonic-gate /*
1026*7c478bd9Sstevel@tonic-gate  * initialize and return an LDAP session handle.
1027*7c478bd9Sstevel@tonic-gate  * if errors occur, we exit here.
1028*7c478bd9Sstevel@tonic-gate  */
1029*7c478bd9Sstevel@tonic-gate LDAP *
1030*7c478bd9Sstevel@tonic-gate ldaptool_ldap_init( int second_host )
1031*7c478bd9Sstevel@tonic-gate {
1032*7c478bd9Sstevel@tonic-gate     LDAP	*ld = NULL;
1033*7c478bd9Sstevel@tonic-gate     char	*host;
1034*7c478bd9Sstevel@tonic-gate     int		port, rc, user_port;
1035*7c478bd9Sstevel@tonic-gate 
1036*7c478bd9Sstevel@tonic-gate     if ( ldaptool_not ) {
1037*7c478bd9Sstevel@tonic-gate 	return( NULL );
1038*7c478bd9Sstevel@tonic-gate     }
1039*7c478bd9Sstevel@tonic-gate 
1040*7c478bd9Sstevel@tonic-gate     if ( second_host ) {
1041*7c478bd9Sstevel@tonic-gate 	host = ldaptool_host2;
1042*7c478bd9Sstevel@tonic-gate 	port = ldaptool_port2;
1043*7c478bd9Sstevel@tonic-gate 	user_port = user_specified_port2;
1044*7c478bd9Sstevel@tonic-gate     } else {
1045*7c478bd9Sstevel@tonic-gate 	host = ldaptool_host;
1046*7c478bd9Sstevel@tonic-gate 	port = ldaptool_port;
1047*7c478bd9Sstevel@tonic-gate 	user_port = user_specified_port;
1048*7c478bd9Sstevel@tonic-gate     }
1049*7c478bd9Sstevel@tonic-gate 
1050*7c478bd9Sstevel@tonic-gate 
1051*7c478bd9Sstevel@tonic-gate     if ( ldaptool_verbose ) {
1052*7c478bd9Sstevel@tonic-gate 	printf( gettext("ldap_init( %s, %d )\n"), host, port );
1053*7c478bd9Sstevel@tonic-gate     }
1054*7c478bd9Sstevel@tonic-gate 
1055*7c478bd9Sstevel@tonic-gate #if defined(NET_SSL)
1056*7c478bd9Sstevel@tonic-gate     /*
1057*7c478bd9Sstevel@tonic-gate      * Initialize security libraries and databases and LDAP session.  If
1058*7c478bd9Sstevel@tonic-gate      * ssl_certname is not NULL, then we will attempt to use client auth.
1059*7c478bd9Sstevel@tonic-gate      * if the server supports it.
1060*7c478bd9Sstevel@tonic-gate      */
1061*7c478bd9Sstevel@tonic-gate #ifdef LDAP_TOOL_PKCS11
1062*7c478bd9Sstevel@tonic-gate     ldaptool_setcallbacks( &local_pkcs_fns );
1063*7c478bd9Sstevel@tonic-gate 
1064*7c478bd9Sstevel@tonic-gate     if ( !second_host 	&& secure
1065*7c478bd9Sstevel@tonic-gate 	 &&(rc = ldapssl_pkcs_init( &local_pkcs_fns))  < 0) {
1066*7c478bd9Sstevel@tonic-gate 	    /* secure connection requested -- fail if no SSL */
1067*7c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
1068*7c478bd9Sstevel@tonic-gate 	    rc = PORT_GetError();
1069*7c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
1070*7c478bd9Sstevel@tonic-gate 	    fprintf( stderr, gettext("SSL initialization failed: error %d (%s)\n"),
1071*7c478bd9Sstevel@tonic-gate 		    rc, ldapssl_err2string( rc ));
1072*7c478bd9Sstevel@tonic-gate 	    exit( LDAP_LOCAL_ERROR );
1073*7c478bd9Sstevel@tonic-gate     }
1074*7c478bd9Sstevel@tonic-gate 
1075*7c478bd9Sstevel@tonic-gate #ifdef LDAP_TOOL_ARGPIN
1076*7c478bd9Sstevel@tonic-gate     if (secure) {
1077*7c478bd9Sstevel@tonic-gate 	if (PinArgRegistration( )) {
1078*7c478bd9Sstevel@tonic-gate 	    exit( LDAP_LOCAL_ERROR);
1079*7c478bd9Sstevel@tonic-gate 	}
1080*7c478bd9Sstevel@tonic-gate     }
1081*7c478bd9Sstevel@tonic-gate #endif /* LDAP_TOOL_ARGPIN */
1082*7c478bd9Sstevel@tonic-gate 
1083*7c478bd9Sstevel@tonic-gate #else /* LDAP_TOOL_PKCS11 */
1084*7c478bd9Sstevel@tonic-gate     if ( !second_host 	&& secure
1085*7c478bd9Sstevel@tonic-gate 	 &&(rc = ldapssl_client_init( ssl_certdbpath, NULL )) < 0) {
1086*7c478bd9Sstevel@tonic-gate 	    /* secure connection requested -- fail if no SSL */
1087*7c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
1088*7c478bd9Sstevel@tonic-gate 	    rc = PORT_GetError();
1089*7c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
1090*7c478bd9Sstevel@tonic-gate 	    fprintf( stderr, gettext("SSL initialization failed: error %d (%s)\n"),
1091*7c478bd9Sstevel@tonic-gate 		    rc, ldapssl_err2string( rc ));
1092*7c478bd9Sstevel@tonic-gate 	    exit( LDAP_LOCAL_ERROR );
1093*7c478bd9Sstevel@tonic-gate     }
1094*7c478bd9Sstevel@tonic-gate #endif /* LDAP_TOOL_PKCS11 */
1095*7c478bd9Sstevel@tonic-gate 
1096*7c478bd9Sstevel@tonic-gate     /* set the default SSL strength (used for all future ld's we create) */
1097*7c478bd9Sstevel@tonic-gate     if ( ldapssl_set_strength( NULL, ssl_strength ) < 0 ) {
1098*7c478bd9Sstevel@tonic-gate         perror( "ldapssl_set_strength" );
1099*7c478bd9Sstevel@tonic-gate         exit( LDAP_LOCAL_ERROR );
1100*7c478bd9Sstevel@tonic-gate     }
1101*7c478bd9Sstevel@tonic-gate 
1102*7c478bd9Sstevel@tonic-gate 
1103*7c478bd9Sstevel@tonic-gate     if (secure) {
1104*7c478bd9Sstevel@tonic-gate 	if ( !user_port ) {
1105*7c478bd9Sstevel@tonic-gate 	    port = LDAPS_PORT;
1106*7c478bd9Sstevel@tonic-gate 	}
1107*7c478bd9Sstevel@tonic-gate 
1108*7c478bd9Sstevel@tonic-gate 	if (( ld = ldapssl_init( host, port,
1109*7c478bd9Sstevel@tonic-gate 		secure )) != NULL && ssl_certname != NULL )
1110*7c478bd9Sstevel@tonic-gate 	    if (ldapssl_enable_clientauth( ld, ssl_keydbpath, ssl_passwd,
1111*7c478bd9Sstevel@tonic-gate 		ssl_certname ) != 0 ) {
1112*7c478bd9Sstevel@tonic-gate 		exit ( ldaptool_print_lderror( ld, "ldapssl_enable_clientauth",
1113*7c478bd9Sstevel@tonic-gate 		    LDAPTOOL_CHECK4SSL_ALWAYS ));
1114*7c478bd9Sstevel@tonic-gate 	    }
1115*7c478bd9Sstevel@tonic-gate     } else {
1116*7c478bd9Sstevel@tonic-gate 	/* In order to support IPv6, we use NSPR I/O */
1117*7c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
1118*7c478bd9Sstevel@tonic-gate 	ld = ldap_init( host, port );
1119*7c478bd9Sstevel@tonic-gate #else
1120*7c478bd9Sstevel@tonic-gate 	ld = prldap_init( host, port, 0 /* not shared across threads */ );
1121*7c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */
1122*7c478bd9Sstevel@tonic-gate     }
1123*7c478bd9Sstevel@tonic-gate 
1124*7c478bd9Sstevel@tonic-gate #else /* NET_SSL */
1125*7c478bd9Sstevel@tonic-gate     /* In order to support IPv6, we use NSPR I/O */
1126*7c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
1127*7c478bd9Sstevel@tonic-gate     ld = ldap_init( host, port );
1128*7c478bd9Sstevel@tonic-gate #else
1129*7c478bd9Sstevel@tonic-gate     ld = prldap_init( host, port, 0 /* not shared across threads */ );
1130*7c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */
1131*7c478bd9Sstevel@tonic-gate #endif /* NET_SSL */
1132*7c478bd9Sstevel@tonic-gate 
1133*7c478bd9Sstevel@tonic-gate     if ( ld == NULL ) {
1134*7c478bd9Sstevel@tonic-gate 	perror( "ldap_init" );
1135*7c478bd9Sstevel@tonic-gate 	exit( LDAP_LOCAL_ERROR );
1136*7c478bd9Sstevel@tonic-gate     }
1137*7c478bd9Sstevel@tonic-gate 
1138*7c478bd9Sstevel@tonic-gate #ifndef NO_LIBLCACHE
1139*7c478bd9Sstevel@tonic-gate     if ( cache_config_file != NULL ) {
1140*7c478bd9Sstevel@tonic-gate 	int	opt;
1141*7c478bd9Sstevel@tonic-gate 
1142*7c478bd9Sstevel@tonic-gate 	if ( lcache_init( ld, cache_config_file ) != 0 ) {
1143*7c478bd9Sstevel@tonic-gate 		exit( ldaptool_print_lderror( ld, cache_config_file,
1144*7c478bd9Sstevel@tonic-gate 			LDAPTOOL_CHECK4SSL_NEVER ));
1145*7c478bd9Sstevel@tonic-gate 	}
1146*7c478bd9Sstevel@tonic-gate 	opt = 1;
1147*7c478bd9Sstevel@tonic-gate 	(void) ldap_set_option( ld, LDAP_OPT_CACHE_ENABLE, &opt );
1148*7c478bd9Sstevel@tonic-gate 	opt = LDAP_CACHE_LOCALDB;
1149*7c478bd9Sstevel@tonic-gate 	(void) ldap_set_option( ld, LDAP_OPT_CACHE_STRATEGY, &opt );
1150*7c478bd9Sstevel@tonic-gate 	if ( ldversion == -1 ) {	/* not set with -V */
1151*7c478bd9Sstevel@tonic-gate 	    ldversion = LDAP_VERSION2;	/* local db only supports v2 */
1152*7c478bd9Sstevel@tonic-gate 	}
1153*7c478bd9Sstevel@tonic-gate     }
1154*7c478bd9Sstevel@tonic-gate #endif
1155*7c478bd9Sstevel@tonic-gate 
1156*7c478bd9Sstevel@tonic-gate 
1157*7c478bd9Sstevel@tonic-gate     ldap_set_option( ld, LDAP_OPT_REFERRALS, chase_referrals ? LDAP_OPT_ON:
1158*7c478bd9Sstevel@tonic-gate 	LDAP_OPT_OFF );
1159*7c478bd9Sstevel@tonic-gate     if ( chase_referrals ) {
1160*7c478bd9Sstevel@tonic-gate 	ldap_set_rebind_proc( ld, get_rebind_credentials, NULL );
1161*7c478bd9Sstevel@tonic-gate 	ldap_set_option( ld, LDAP_OPT_REFERRAL_HOP_LIMIT, &refhoplim );
1162*7c478bd9Sstevel@tonic-gate     }
1163*7c478bd9Sstevel@tonic-gate 
1164*7c478bd9Sstevel@tonic-gate     if ( ldversion == -1 ) {	/* not set with -V and not using local db */
1165*7c478bd9Sstevel@tonic-gate 	ldversion = LDAP_VERSION3;
1166*7c478bd9Sstevel@tonic-gate     }
1167*7c478bd9Sstevel@tonic-gate     ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &ldversion );
1168*7c478bd9Sstevel@tonic-gate 
1169*7c478bd9Sstevel@tonic-gate     return( ld );
1170*7c478bd9Sstevel@tonic-gate }
1171*7c478bd9Sstevel@tonic-gate 
1172*7c478bd9Sstevel@tonic-gate 
1173*7c478bd9Sstevel@tonic-gate /*
1174*7c478bd9Sstevel@tonic-gate  * perform a bind to the LDAP server if needed.
1175*7c478bd9Sstevel@tonic-gate  * if an error occurs, we exit here.
1176*7c478bd9Sstevel@tonic-gate  */
1177*7c478bd9Sstevel@tonic-gate void
1178*7c478bd9Sstevel@tonic-gate ldaptool_bind( LDAP *ld )
1179*7c478bd9Sstevel@tonic-gate {
1180*7c478bd9Sstevel@tonic-gate     int		rc;
1181*7c478bd9Sstevel@tonic-gate     char	*conv;
1182*7c478bd9Sstevel@tonic-gate     LDAPControl	auth_resp_ctrl, *ctrl_array[ 2 ], **bindctrls;
1183*7c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
1184*7c478bd9Sstevel@tonic-gate     void *defaults;
1185*7c478bd9Sstevel@tonic-gate #endif
1186*7c478bd9Sstevel@tonic-gate 
1187*7c478bd9Sstevel@tonic-gate     if ( ldaptool_not ) {
1188*7c478bd9Sstevel@tonic-gate 	return;
1189*7c478bd9Sstevel@tonic-gate     }
1190*7c478bd9Sstevel@tonic-gate 
1191*7c478bd9Sstevel@tonic-gate     if ( send_auth_response_ctrl ) {
1192*7c478bd9Sstevel@tonic-gate 	auth_resp_ctrl.ldctl_oid = LDAP_CONTROL_AUTH_REQUEST;
1193*7c478bd9Sstevel@tonic-gate 	auth_resp_ctrl.ldctl_value.bv_val = NULL;
1194*7c478bd9Sstevel@tonic-gate 	auth_resp_ctrl.ldctl_value.bv_len = 0;
1195*7c478bd9Sstevel@tonic-gate 	auth_resp_ctrl.ldctl_iscritical = 0;
1196*7c478bd9Sstevel@tonic-gate 
1197*7c478bd9Sstevel@tonic-gate 	ctrl_array[0] = &auth_resp_ctrl;
1198*7c478bd9Sstevel@tonic-gate 	ctrl_array[1] = NULL;
1199*7c478bd9Sstevel@tonic-gate 	bindctrls = ctrl_array;
1200*7c478bd9Sstevel@tonic-gate     } else {
1201*7c478bd9Sstevel@tonic-gate 	bindctrls = NULL;
1202*7c478bd9Sstevel@tonic-gate     }
1203*7c478bd9Sstevel@tonic-gate 
1204*7c478bd9Sstevel@tonic-gate     /*
1205*7c478bd9Sstevel@tonic-gate      * if using LDAPv3 and not using client auth., omit NULL bind for
1206*7c478bd9Sstevel@tonic-gate      * efficiency.
1207*7c478bd9Sstevel@tonic-gate      */
1208*7c478bd9Sstevel@tonic-gate     if ( ldversion > LDAP_VERSION2 && binddn == NULL && passwd == NULL
1209*7c478bd9Sstevel@tonic-gate 	    && ssl_certname == NULL ) {
1210*7c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
1211*7c478bd9Sstevel@tonic-gate 	if ( ldapauth != LDAP_AUTH_SASL ) {
1212*7c478bd9Sstevel@tonic-gate 	   return;
1213*7c478bd9Sstevel@tonic-gate 	}
1214*7c478bd9Sstevel@tonic-gate #else
1215*7c478bd9Sstevel@tonic-gate 	return;
1216*7c478bd9Sstevel@tonic-gate #endif
1217*7c478bd9Sstevel@tonic-gate     }
1218*7c478bd9Sstevel@tonic-gate 
1219*7c478bd9Sstevel@tonic-gate     /*
1220*7c478bd9Sstevel@tonic-gate      * do the bind, backing off one LDAP version if necessary
1221*7c478bd9Sstevel@tonic-gate      */
1222*7c478bd9Sstevel@tonic-gate     conv = ldaptool_local2UTF8( binddn );
1223*7c478bd9Sstevel@tonic-gate 
1224*7c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
1225*7c478bd9Sstevel@tonic-gate     if ( ldapauth == LDAP_AUTH_SASL) {
1226*7c478bd9Sstevel@tonic-gate 	if ( sasl_mech == NULL) {
1227*7c478bd9Sstevel@tonic-gate 	   fprintf( stderr, gettext("Please specify the SASL mechanism name when "
1228*7c478bd9Sstevel@tonic-gate 				"using SASL options\n"));
1229*7c478bd9Sstevel@tonic-gate 	   return;
1230*7c478bd9Sstevel@tonic-gate 	}
1231*7c478bd9Sstevel@tonic-gate 
1232*7c478bd9Sstevel@tonic-gate         if ( sasl_secprops != NULL) {
1233*7c478bd9Sstevel@tonic-gate            rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
1234*7c478bd9Sstevel@tonic-gate                                 (void *) sasl_secprops );
1235*7c478bd9Sstevel@tonic-gate 
1236*7c478bd9Sstevel@tonic-gate            if ( rc != LDAP_SUCCESS ) {
1237*7c478bd9Sstevel@tonic-gate               fprintf( stderr, gettext("Unable to set LDAP_OPT_X_SASL_SECPROPS: %s\n"),
1238*7c478bd9Sstevel@tonic-gate 				sasl_secprops );
1239*7c478bd9Sstevel@tonic-gate               return;
1240*7c478bd9Sstevel@tonic-gate            }
1241*7c478bd9Sstevel@tonic-gate         }
1242*7c478bd9Sstevel@tonic-gate 
1243*7c478bd9Sstevel@tonic-gate         defaults = ldaptool_set_sasl_defaults( ld, sasl_mech, sasl_authid, sasl_username, passwd, sasl_realm );
1244*7c478bd9Sstevel@tonic-gate         if (defaults == NULL) {
1245*7c478bd9Sstevel@tonic-gate 	   perror ("malloc");
1246*7c478bd9Sstevel@tonic-gate 	   exit (LDAP_NO_MEMORY);
1247*7c478bd9Sstevel@tonic-gate 	}
1248*7c478bd9Sstevel@tonic-gate 
1249*7c478bd9Sstevel@tonic-gate         rc = ldap_sasl_interactive_bind_s( ld, binddn, sasl_mech, NULL, NULL,
1250*7c478bd9Sstevel@tonic-gate                         sasl_flags, ldaptool_sasl_interact, defaults );
1251*7c478bd9Sstevel@tonic-gate 
1252*7c478bd9Sstevel@tonic-gate         if (rc != LDAP_SUCCESS ) {
1253*7c478bd9Sstevel@tonic-gate            ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
1254*7c478bd9Sstevel@tonic-gate         }
1255*7c478bd9Sstevel@tonic-gate     } else
1256*7c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
1257*7c478bd9Sstevel@tonic-gate         /*
1258*7c478bd9Sstevel@tonic-gate          * if using LDAPv3 and client auth., try a SASL EXTERNAL bind
1259*7c478bd9Sstevel@tonic-gate          */
1260*7c478bd9Sstevel@tonic-gate          if ( ldversion > LDAP_VERSION2 && binddn == NULL && passwd == NULL
1261*7c478bd9Sstevel@tonic-gate 	    	&& ssl_certname != NULL ) {
1262*7c478bd9Sstevel@tonic-gate 	     rc = ldaptool_sasl_bind_s( ld, NULL, LDAP_SASL_EXTERNAL, NULL,
1263*7c478bd9Sstevel@tonic-gate 			bindctrls, NULL, NULL, "ldap_sasl_bind" );
1264*7c478bd9Sstevel@tonic-gate     	 }
1265*7c478bd9Sstevel@tonic-gate          else {
1266*7c478bd9Sstevel@tonic-gate 	     rc = ldaptool_simple_bind_s( ld, conv, passwd, bindctrls, NULL,
1267*7c478bd9Sstevel@tonic-gate 		    "ldap_simple_bind" );
1268*7c478bd9Sstevel@tonic-gate 	  }
1269*7c478bd9Sstevel@tonic-gate 
1270*7c478bd9Sstevel@tonic-gate     if ( rc == LDAP_SUCCESS ) {
1271*7c478bd9Sstevel@tonic-gate         if ( conv != NULL ) {
1272*7c478bd9Sstevel@tonic-gate            free( conv );
1273*7c478bd9Sstevel@tonic-gate 	}
1274*7c478bd9Sstevel@tonic-gate 	return;			/* success */
1275*7c478bd9Sstevel@tonic-gate     }
1276*7c478bd9Sstevel@tonic-gate 
1277*7c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
1278*7c478bd9Sstevel@tonic-gate   if (ldapauth != LDAP_AUTH_SASL) {
1279*7c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
1280*7c478bd9Sstevel@tonic-gate     if ( rc == LDAP_PROTOCOL_ERROR && ldversion > LDAP_VERSION2 ) {
1281*7c478bd9Sstevel@tonic-gate 	/*
1282*7c478bd9Sstevel@tonic-gate 	 * try again, backing off one LDAP version
1283*7c478bd9Sstevel@tonic-gate 	 * this is okay even for client auth. because the way to achieve
1284*7c478bd9Sstevel@tonic-gate 	 * client auth. with LDAPv2 is to perform a NULL simple bind.
1285*7c478bd9Sstevel@tonic-gate 	 */
1286*7c478bd9Sstevel@tonic-gate 	--ldversion;
1287*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: the server doesn't understand LDAPv%d;"
1288*7c478bd9Sstevel@tonic-gate 		" trying LDAPv%d instead...\n"), ldaptool_progname,
1289*7c478bd9Sstevel@tonic-gate 		ldversion + 1, ldversion );
1290*7c478bd9Sstevel@tonic-gate 	ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &ldversion );
1291*7c478bd9Sstevel@tonic-gate 	if (( rc = ldaptool_simple_bind_s( ld, conv, passwd,
1292*7c478bd9Sstevel@tonic-gate 		bindctrls, NULL, "ldap_simple_bind" )) == LDAP_SUCCESS ) {
1293*7c478bd9Sstevel@tonic-gate             if( conv != NULL )
1294*7c478bd9Sstevel@tonic-gate                 free( conv );
1295*7c478bd9Sstevel@tonic-gate 	    return;		/* a qualified success */
1296*7c478bd9Sstevel@tonic-gate 	}
1297*7c478bd9Sstevel@tonic-gate     }
1298*7c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
1299*7c478bd9Sstevel@tonic-gate   }
1300*7c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
1301*7c478bd9Sstevel@tonic-gate 
1302*7c478bd9Sstevel@tonic-gate     if ( conv != NULL ) {
1303*7c478bd9Sstevel@tonic-gate         free( conv );
1304*7c478bd9Sstevel@tonic-gate     }
1305*7c478bd9Sstevel@tonic-gate 
1306*7c478bd9Sstevel@tonic-gate     /*
1307*7c478bd9Sstevel@tonic-gate      * bind(s) failed -- fatal error
1308*7c478bd9Sstevel@tonic-gate      */
1309*7c478bd9Sstevel@tonic-gate     ldap_unbind( ld );
1310*7c478bd9Sstevel@tonic-gate     exit( rc );
1311*7c478bd9Sstevel@tonic-gate }
1312*7c478bd9Sstevel@tonic-gate 
1313*7c478bd9Sstevel@tonic-gate 
1314*7c478bd9Sstevel@tonic-gate /*
1315*7c478bd9Sstevel@tonic-gate  * close open files, unbind, etc.
1316*7c478bd9Sstevel@tonic-gate  */
1317*7c478bd9Sstevel@tonic-gate void
1318*7c478bd9Sstevel@tonic-gate ldaptool_cleanup( LDAP *ld )
1319*7c478bd9Sstevel@tonic-gate {
1320*7c478bd9Sstevel@tonic-gate     if ( ld != NULL ) {
1321*7c478bd9Sstevel@tonic-gate 	ldap_unbind( ld );
1322*7c478bd9Sstevel@tonic-gate     }
1323*7c478bd9Sstevel@tonic-gate 
1324*7c478bd9Sstevel@tonic-gate     if ( ldaptool_fp != NULL && ldaptool_fp != stdin ) {
1325*7c478bd9Sstevel@tonic-gate 	fclose( ldaptool_fp );
1326*7c478bd9Sstevel@tonic-gate 	ldaptool_fp = NULL;
1327*7c478bd9Sstevel@tonic-gate     }
1328*7c478bd9Sstevel@tonic-gate }
1329*7c478bd9Sstevel@tonic-gate 
1330*7c478bd9Sstevel@tonic-gate 
1331*7c478bd9Sstevel@tonic-gate /*
1332*7c478bd9Sstevel@tonic-gate  * Retrieve and print an LDAP error message.  Returns the LDAP error code.
1333*7c478bd9Sstevel@tonic-gate  */
1334*7c478bd9Sstevel@tonic-gate int
1335*7c478bd9Sstevel@tonic-gate ldaptool_print_lderror( LDAP *ld, char *msg, int check4ssl )
1336*7c478bd9Sstevel@tonic-gate {
1337*7c478bd9Sstevel@tonic-gate     int		lderr = ldap_get_lderrno( ld, NULL, NULL );
1338*7c478bd9Sstevel@tonic-gate 
1339*7c478bd9Sstevel@tonic-gate     ldap_perror( ld, msg );
1340*7c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
1341*7c478bd9Sstevel@tonic-gate     if ( secure && check4ssl != LDAPTOOL_CHECK4SSL_NEVER ) {
1342*7c478bd9Sstevel@tonic-gate 	if ( check4ssl == LDAPTOOL_CHECK4SSL_ALWAYS
1343*7c478bd9Sstevel@tonic-gate 		|| ( lderr == LDAP_SERVER_DOWN )) {
1344*7c478bd9Sstevel@tonic-gate 	    int		sslerr = PORT_GetError();
1345*7c478bd9Sstevel@tonic-gate 
1346*7c478bd9Sstevel@tonic-gate 	    fprintf( stderr, gettext("\tSSL error %d (%s)\n"), sslerr,
1347*7c478bd9Sstevel@tonic-gate 		    ldapssl_err2string( sslerr ));
1348*7c478bd9Sstevel@tonic-gate 	}
1349*7c478bd9Sstevel@tonic-gate     }
1350*7c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
1351*7c478bd9Sstevel@tonic-gate 
1352*7c478bd9Sstevel@tonic-gate     return( lderr );
1353*7c478bd9Sstevel@tonic-gate }
1354*7c478bd9Sstevel@tonic-gate 
1355*7c478bd9Sstevel@tonic-gate 
1356*7c478bd9Sstevel@tonic-gate /*
1357*7c478bd9Sstevel@tonic-gate  * print referrals to stderr
1358*7c478bd9Sstevel@tonic-gate  */
1359*7c478bd9Sstevel@tonic-gate void
1360*7c478bd9Sstevel@tonic-gate ldaptool_print_referrals( char **refs )
1361*7c478bd9Sstevel@tonic-gate {
1362*7c478bd9Sstevel@tonic-gate     int		i;
1363*7c478bd9Sstevel@tonic-gate 
1364*7c478bd9Sstevel@tonic-gate     if ( refs != NULL ) {
1365*7c478bd9Sstevel@tonic-gate 	for ( i = 0; refs[ i ] != NULL; ++i ) {
1366*7c478bd9Sstevel@tonic-gate 	    fprintf( stderr, gettext("Referral: %s\n"), refs[ i ] );
1367*7c478bd9Sstevel@tonic-gate 	}
1368*7c478bd9Sstevel@tonic-gate     }
1369*7c478bd9Sstevel@tonic-gate }
1370*7c478bd9Sstevel@tonic-gate 
1371*7c478bd9Sstevel@tonic-gate 
1372*7c478bd9Sstevel@tonic-gate /*
1373*7c478bd9Sstevel@tonic-gate  * print contents of an extended response to stderr
1374*7c478bd9Sstevel@tonic-gate  * this is mainly to support unsolicited notifications
1375*7c478bd9Sstevel@tonic-gate  * Returns an LDAP error code (from the extended result).
1376*7c478bd9Sstevel@tonic-gate  */
1377*7c478bd9Sstevel@tonic-gate int
1378*7c478bd9Sstevel@tonic-gate ldaptool_print_extended_response( LDAP *ld, LDAPMessage *res, char *msg )
1379*7c478bd9Sstevel@tonic-gate {
1380*7c478bd9Sstevel@tonic-gate     char		*oid;
1381*7c478bd9Sstevel@tonic-gate     struct berval	*data;
1382*7c478bd9Sstevel@tonic-gate 
1383*7c478bd9Sstevel@tonic-gate     if ( ldap_parse_extended_result( ld, res, &oid, &data, 0 )
1384*7c478bd9Sstevel@tonic-gate 	    != LDAP_SUCCESS ) {
1385*7c478bd9Sstevel@tonic-gate 	ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP );
1386*7c478bd9Sstevel@tonic-gate     } else {
1387*7c478bd9Sstevel@tonic-gate 	if ( oid != NULL ) {
1388*7c478bd9Sstevel@tonic-gate 	    if ( strcmp ( oid, LDAP_NOTICE_OF_DISCONNECTION ) == 0 ) {
1389*7c478bd9Sstevel@tonic-gate 		fprintf( stderr, gettext("%s: Notice of Disconnection\n"), msg );
1390*7c478bd9Sstevel@tonic-gate 	    } else {
1391*7c478bd9Sstevel@tonic-gate 		fprintf( stderr, gettext("%s: OID %s\n"), msg, oid );
1392*7c478bd9Sstevel@tonic-gate 	    }
1393*7c478bd9Sstevel@tonic-gate 	    ldap_memfree( oid );
1394*7c478bd9Sstevel@tonic-gate 	} else {
1395*7c478bd9Sstevel@tonic-gate 	    fprintf( stderr, gettext("%s: missing OID\n"), msg );
1396*7c478bd9Sstevel@tonic-gate 	}
1397*7c478bd9Sstevel@tonic-gate 
1398*7c478bd9Sstevel@tonic-gate 	if ( data != NULL ) {
1399*7c478bd9Sstevel@tonic-gate 	    fprintf( stderr, gettext("%s: Data (length %ld):\n"), msg, data->bv_len );
1400*7c478bd9Sstevel@tonic-gate #if 0
1401*7c478bd9Sstevel@tonic-gate /* XXXmcs: maybe we should display the actual data? */
1402*7c478bd9Sstevel@tonic-gate 	    lber_bprint( data->bv_val, data->bv_len );
1403*7c478bd9Sstevel@tonic-gate #endif
1404*7c478bd9Sstevel@tonic-gate 	    ber_bvfree( data );
1405*7c478bd9Sstevel@tonic-gate 	}
1406*7c478bd9Sstevel@tonic-gate     }
1407*7c478bd9Sstevel@tonic-gate 
1408*7c478bd9Sstevel@tonic-gate     return parse_result( ld, res, NULL, msg, 1 );
1409*7c478bd9Sstevel@tonic-gate }
1410*7c478bd9Sstevel@tonic-gate 
1411*7c478bd9Sstevel@tonic-gate 
1412*7c478bd9Sstevel@tonic-gate /*
1413*7c478bd9Sstevel@tonic-gate  * Like ldap_sasl_bind_s() but calls wait4result() to display
1414*7c478bd9Sstevel@tonic-gate  * any referrals returned and report errors in a consistent way.
1415*7c478bd9Sstevel@tonic-gate  */
1416*7c478bd9Sstevel@tonic-gate int
1417*7c478bd9Sstevel@tonic-gate ldaptool_sasl_bind_s( LDAP *ld, const char *dn, const char *mechanism,
1418*7c478bd9Sstevel@tonic-gate 	const struct berval *cred, LDAPControl **serverctrls,
1419*7c478bd9Sstevel@tonic-gate 	LDAPControl **clientctrls, struct berval **servercredp, char *msg )
1420*7c478bd9Sstevel@tonic-gate {
1421*7c478bd9Sstevel@tonic-gate     int		rc, msgid;
1422*7c478bd9Sstevel@tonic-gate 
1423*7c478bd9Sstevel@tonic-gate     if ( servercredp != NULL ) {
1424*7c478bd9Sstevel@tonic-gate 	    *servercredp = NULL;
1425*7c478bd9Sstevel@tonic-gate     }
1426*7c478bd9Sstevel@tonic-gate 
1427*7c478bd9Sstevel@tonic-gate     if (( rc = ldap_sasl_bind( ld, dn, mechanism, cred, serverctrls,
1428*7c478bd9Sstevel@tonic-gate 	    clientctrls, &msgid )) != LDAP_SUCCESS ) {
1429*7c478bd9Sstevel@tonic-gate 	ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP );
1430*7c478bd9Sstevel@tonic-gate     } else {
1431*7c478bd9Sstevel@tonic-gate 	rc = wait4result( ld, msgid, servercredp, msg );
1432*7c478bd9Sstevel@tonic-gate     }
1433*7c478bd9Sstevel@tonic-gate 
1434*7c478bd9Sstevel@tonic-gate     return( rc );
1435*7c478bd9Sstevel@tonic-gate }
1436*7c478bd9Sstevel@tonic-gate 
1437*7c478bd9Sstevel@tonic-gate 
1438*7c478bd9Sstevel@tonic-gate /*
1439*7c478bd9Sstevel@tonic-gate  * Like ldap_simple_bind_s() but calls wait4result() to display
1440*7c478bd9Sstevel@tonic-gate  * any referrals returned and report errors in a consistent way.
1441*7c478bd9Sstevel@tonic-gate  */
1442*7c478bd9Sstevel@tonic-gate int
1443*7c478bd9Sstevel@tonic-gate ldaptool_simple_bind_s( LDAP *ld, const char *dn, const char *passwd,
1444*7c478bd9Sstevel@tonic-gate 	LDAPControl **serverctrls, LDAPControl **clientctrls, char *msg )
1445*7c478bd9Sstevel@tonic-gate {
1446*7c478bd9Sstevel@tonic-gate     struct berval	bv;
1447*7c478bd9Sstevel@tonic-gate 
1448*7c478bd9Sstevel@tonic-gate     bv.bv_val = (char *)passwd;		/* XXXmcs: had to cast away const */
1449*7c478bd9Sstevel@tonic-gate     bv.bv_len = ( passwd == NULL ? 0 : strlen( passwd ));
1450*7c478bd9Sstevel@tonic-gate     return( ldaptool_sasl_bind_s( ld, dn, LDAP_SASL_SIMPLE, &bv, serverctrls,
1451*7c478bd9Sstevel@tonic-gate 	    clientctrls, NULL, msg ));
1452*7c478bd9Sstevel@tonic-gate }
1453*7c478bd9Sstevel@tonic-gate 
1454*7c478bd9Sstevel@tonic-gate 
1455*7c478bd9Sstevel@tonic-gate /*
1456*7c478bd9Sstevel@tonic-gate  * Like ldap_add_ext_s() but calls wait4result() to display
1457*7c478bd9Sstevel@tonic-gate  * any referrals returned and report errors in a consistent way.
1458*7c478bd9Sstevel@tonic-gate  */
1459*7c478bd9Sstevel@tonic-gate int
1460*7c478bd9Sstevel@tonic-gate ldaptool_add_ext_s( LDAP *ld, const char *dn, LDAPMod **attrs,
1461*7c478bd9Sstevel@tonic-gate 	LDAPControl **serverctrls, LDAPControl **clientctrls, char *msg )
1462*7c478bd9Sstevel@tonic-gate {
1463*7c478bd9Sstevel@tonic-gate     int		rc, msgid;
1464*7c478bd9Sstevel@tonic-gate 
1465*7c478bd9Sstevel@tonic-gate     if (( rc = ldap_add_ext( ld, dn, attrs, serverctrls, clientctrls, &msgid ))
1466*7c478bd9Sstevel@tonic-gate 	    != LDAP_SUCCESS ) {
1467*7c478bd9Sstevel@tonic-gate 	ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP );
1468*7c478bd9Sstevel@tonic-gate     } else {
1469*7c478bd9Sstevel@tonic-gate 	/*
1470*7c478bd9Sstevel@tonic-gate 	 * 25-April-2000 Note: the next line used to read:
1471*7c478bd9Sstevel@tonic-gate 	 *	rc = wait4result( ld, msgid, NULL, msg );
1472*7c478bd9Sstevel@tonic-gate 	 * 'msgid' it was changed to 'LDAP_RES_ANY' in order to receive
1473*7c478bd9Sstevel@tonic-gate 	 * unsolicited notifications.
1474*7c478bd9Sstevel@tonic-gate 	 */
1475*7c478bd9Sstevel@tonic-gate 	rc = wait4result( ld, LDAP_RES_ANY, NULL, msg );
1476*7c478bd9Sstevel@tonic-gate     }
1477*7c478bd9Sstevel@tonic-gate 
1478*7c478bd9Sstevel@tonic-gate     return( rc );
1479*7c478bd9Sstevel@tonic-gate }
1480*7c478bd9Sstevel@tonic-gate 
1481*7c478bd9Sstevel@tonic-gate 
1482*7c478bd9Sstevel@tonic-gate /*
1483*7c478bd9Sstevel@tonic-gate  * Like ldap_modify_ext_s() but calls wait4result() to display
1484*7c478bd9Sstevel@tonic-gate  * any referrals returned and report errors in a consistent way.
1485*7c478bd9Sstevel@tonic-gate  */
1486*7c478bd9Sstevel@tonic-gate int
1487*7c478bd9Sstevel@tonic-gate ldaptool_modify_ext_s( LDAP *ld, const char *dn, LDAPMod **mods,
1488*7c478bd9Sstevel@tonic-gate 	LDAPControl **serverctrls, LDAPControl **clientctrls, char *msg )
1489*7c478bd9Sstevel@tonic-gate {
1490*7c478bd9Sstevel@tonic-gate     int		rc, msgid;
1491*7c478bd9Sstevel@tonic-gate 
1492*7c478bd9Sstevel@tonic-gate     if (( rc = ldap_modify_ext( ld, dn, mods, serverctrls, clientctrls,
1493*7c478bd9Sstevel@tonic-gate 	    &msgid )) != LDAP_SUCCESS ) {
1494*7c478bd9Sstevel@tonic-gate 	ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP );
1495*7c478bd9Sstevel@tonic-gate     } else {
1496*7c478bd9Sstevel@tonic-gate 	rc = wait4result( ld, msgid, NULL, msg );
1497*7c478bd9Sstevel@tonic-gate     }
1498*7c478bd9Sstevel@tonic-gate 
1499*7c478bd9Sstevel@tonic-gate     return( rc );
1500*7c478bd9Sstevel@tonic-gate }
1501*7c478bd9Sstevel@tonic-gate 
1502*7c478bd9Sstevel@tonic-gate 
1503*7c478bd9Sstevel@tonic-gate /*
1504*7c478bd9Sstevel@tonic-gate  * Like ldap_delete_ext_s() but calls wait4result() to display
1505*7c478bd9Sstevel@tonic-gate  * any referrals returned and report errors in a consistent way.
1506*7c478bd9Sstevel@tonic-gate  */
1507*7c478bd9Sstevel@tonic-gate int
1508*7c478bd9Sstevel@tonic-gate ldaptool_delete_ext_s( LDAP *ld, const char *dn, LDAPControl **serverctrls,
1509*7c478bd9Sstevel@tonic-gate 	LDAPControl **clientctrls, char *msg )
1510*7c478bd9Sstevel@tonic-gate {
1511*7c478bd9Sstevel@tonic-gate     int		rc, msgid;
1512*7c478bd9Sstevel@tonic-gate 
1513*7c478bd9Sstevel@tonic-gate     if (( rc = ldap_delete_ext( ld, dn, serverctrls, clientctrls, &msgid ))
1514*7c478bd9Sstevel@tonic-gate 	    != LDAP_SUCCESS ) {
1515*7c478bd9Sstevel@tonic-gate 	ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP );
1516*7c478bd9Sstevel@tonic-gate     } else {
1517*7c478bd9Sstevel@tonic-gate 	rc = wait4result( ld, msgid, NULL, msg );
1518*7c478bd9Sstevel@tonic-gate     }
1519*7c478bd9Sstevel@tonic-gate 
1520*7c478bd9Sstevel@tonic-gate     return( rc );
1521*7c478bd9Sstevel@tonic-gate }
1522*7c478bd9Sstevel@tonic-gate 
1523*7c478bd9Sstevel@tonic-gate 
1524*7c478bd9Sstevel@tonic-gate /*
1525*7c478bd9Sstevel@tonic-gate  * Like ldap_compare_ext_s() but calls wait4result() to display
1526*7c478bd9Sstevel@tonic-gate  * any referrals returned and report errors in a consistent way.
1527*7c478bd9Sstevel@tonic-gate  */
1528*7c478bd9Sstevel@tonic-gate int ldaptool_compare_ext_s( LDAP *ld, const char *dn, const char *attrtype,
1529*7c478bd9Sstevel@tonic-gate 	    const struct berval *bvalue, LDAPControl **serverctrls,
1530*7c478bd9Sstevel@tonic-gate 	    LDAPControl **clientctrls, char *msg )
1531*7c478bd9Sstevel@tonic-gate {
1532*7c478bd9Sstevel@tonic-gate     int		rc, msgid;
1533*7c478bd9Sstevel@tonic-gate 
1534*7c478bd9Sstevel@tonic-gate     if (( rc = ldap_compare_ext( ld, dn, attrtype, bvalue, serverctrls,
1535*7c478bd9Sstevel@tonic-gate 	    clientctrls, &msgid )) != LDAP_SUCCESS ) {
1536*7c478bd9Sstevel@tonic-gate 	ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP );
1537*7c478bd9Sstevel@tonic-gate     } else {
1538*7c478bd9Sstevel@tonic-gate 	rc = wait4result( ld, msgid, NULL, msg );
1539*7c478bd9Sstevel@tonic-gate     }
1540*7c478bd9Sstevel@tonic-gate 
1541*7c478bd9Sstevel@tonic-gate     return( rc );
1542*7c478bd9Sstevel@tonic-gate }
1543*7c478bd9Sstevel@tonic-gate 
1544*7c478bd9Sstevel@tonic-gate 
1545*7c478bd9Sstevel@tonic-gate /*
1546*7c478bd9Sstevel@tonic-gate  * Like ldap_rename_s() but calls wait4result() to display
1547*7c478bd9Sstevel@tonic-gate  * any referrals returned and report errors in a consistent way.
1548*7c478bd9Sstevel@tonic-gate  */
1549*7c478bd9Sstevel@tonic-gate int
1550*7c478bd9Sstevel@tonic-gate ldaptool_rename_s(  LDAP *ld, const char *dn, const char *newrdn,
1551*7c478bd9Sstevel@tonic-gate 	const char *newparent, int deleteoldrdn, LDAPControl **serverctrls,
1552*7c478bd9Sstevel@tonic-gate 	LDAPControl **clientctrls, char *msg )
1553*7c478bd9Sstevel@tonic-gate {
1554*7c478bd9Sstevel@tonic-gate     int		rc, msgid;
1555*7c478bd9Sstevel@tonic-gate 
1556*7c478bd9Sstevel@tonic-gate     if (( rc = ldap_rename( ld, dn, newrdn, newparent, deleteoldrdn,
1557*7c478bd9Sstevel@tonic-gate 	    serverctrls, clientctrls, &msgid )) != LDAP_SUCCESS ) {
1558*7c478bd9Sstevel@tonic-gate 	ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP );
1559*7c478bd9Sstevel@tonic-gate     } else {
1560*7c478bd9Sstevel@tonic-gate 	rc = wait4result( ld, msgid, NULL, msg );
1561*7c478bd9Sstevel@tonic-gate     }
1562*7c478bd9Sstevel@tonic-gate 
1563*7c478bd9Sstevel@tonic-gate     return( rc );
1564*7c478bd9Sstevel@tonic-gate }
1565*7c478bd9Sstevel@tonic-gate 
1566*7c478bd9Sstevel@tonic-gate 
1567*7c478bd9Sstevel@tonic-gate /*
1568*7c478bd9Sstevel@tonic-gate  * Wait for a result, check for and display errors and referrals.
1569*7c478bd9Sstevel@tonic-gate  * Also recognize and display "Unsolicited notification" messages.
1570*7c478bd9Sstevel@tonic-gate  * Returns an LDAP error code.
1571*7c478bd9Sstevel@tonic-gate  */
1572*7c478bd9Sstevel@tonic-gate static int
1573*7c478bd9Sstevel@tonic-gate wait4result( LDAP *ld, int msgid, struct berval **servercredp, char *msg )
1574*7c478bd9Sstevel@tonic-gate {
1575*7c478bd9Sstevel@tonic-gate     LDAPMessage	*res;
1576*7c478bd9Sstevel@tonic-gate     int		rc, received_only_unsolicited = 1;
1577*7c478bd9Sstevel@tonic-gate 
1578*7c478bd9Sstevel@tonic-gate     while ( received_only_unsolicited ) {
1579*7c478bd9Sstevel@tonic-gate 	res = NULL;
1580*7c478bd9Sstevel@tonic-gate 	if (( rc = ldap_result( ld, msgid, 1, (struct timeval *)NULL, &res ))
1581*7c478bd9Sstevel@tonic-gate 		    == -1 ) {
1582*7c478bd9Sstevel@tonic-gate 	    ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP );
1583*7c478bd9Sstevel@tonic-gate 	    return( ldap_get_lderrno( ld, NULL, NULL ));
1584*7c478bd9Sstevel@tonic-gate 	}
1585*7c478bd9Sstevel@tonic-gate 
1586*7c478bd9Sstevel@tonic-gate 	/*
1587*7c478bd9Sstevel@tonic-gate 	 * Special handling for unsolicited notifications:
1588*7c478bd9Sstevel@tonic-gate 	 *    1. Parse and display contents.
1589*7c478bd9Sstevel@tonic-gate 	 *    2. go back and wait for another (real) result.
1590*7c478bd9Sstevel@tonic-gate 	 */
1591*7c478bd9Sstevel@tonic-gate 	if ( rc == LDAP_RES_EXTENDED
1592*7c478bd9Sstevel@tonic-gate 		    && ldap_msgid( res ) == LDAP_RES_UNSOLICITED ) {
1593*7c478bd9Sstevel@tonic-gate 	    rc = ldaptool_print_extended_response( ld, res,
1594*7c478bd9Sstevel@tonic-gate 		    "Unsolicited response" );
1595*7c478bd9Sstevel@tonic-gate 	} else {
1596*7c478bd9Sstevel@tonic-gate 	    rc = parse_result( ld, res, servercredp, msg, 1 );
1597*7c478bd9Sstevel@tonic-gate 	    received_only_unsolicited = 0;	/* we're done */
1598*7c478bd9Sstevel@tonic-gate 	}
1599*7c478bd9Sstevel@tonic-gate     }
1600*7c478bd9Sstevel@tonic-gate 
1601*7c478bd9Sstevel@tonic-gate     return( rc );
1602*7c478bd9Sstevel@tonic-gate }
1603*7c478bd9Sstevel@tonic-gate 
1604*7c478bd9Sstevel@tonic-gate 
1605*7c478bd9Sstevel@tonic-gate static int
1606*7c478bd9Sstevel@tonic-gate parse_result( LDAP *ld, LDAPMessage *res, struct berval **servercredp,
1607*7c478bd9Sstevel@tonic-gate 	char *msg, int freeit )
1608*7c478bd9Sstevel@tonic-gate {
1609*7c478bd9Sstevel@tonic-gate     int		rc, lderr, errno;
1610*7c478bd9Sstevel@tonic-gate     int		pw_days=0, pw_hrs=0, pw_mins=0, pw_secs=0; /* for pwpolicy */
1611*7c478bd9Sstevel@tonic-gate     char	**refs = NULL;
1612*7c478bd9Sstevel@tonic-gate     LDAPControl	**ctrls;
1613*7c478bd9Sstevel@tonic-gate 
1614*7c478bd9Sstevel@tonic-gate     if (( rc = ldap_parse_result( ld, res, &lderr, NULL, NULL, &refs,
1615*7c478bd9Sstevel@tonic-gate 	    &ctrls, 0 )) != LDAP_SUCCESS ) {
1616*7c478bd9Sstevel@tonic-gate 	ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP );
1617*7c478bd9Sstevel@tonic-gate 	ldap_msgfree( res );
1618*7c478bd9Sstevel@tonic-gate 	return( rc );
1619*7c478bd9Sstevel@tonic-gate     }
1620*7c478bd9Sstevel@tonic-gate 
1621*7c478bd9Sstevel@tonic-gate     /* check for authentication response control & PWPOLICY control*/
1622*7c478bd9Sstevel@tonic-gate     if ( NULL != ctrls ) {
1623*7c478bd9Sstevel@tonic-gate 	int		i;
1624*7c478bd9Sstevel@tonic-gate 	char		*s;
1625*7c478bd9Sstevel@tonic-gate 
1626*7c478bd9Sstevel@tonic-gate 	for ( i = 0; NULL != ctrls[i]; ++i ) {
1627*7c478bd9Sstevel@tonic-gate 	    if ( 0 == strcmp( ctrls[i]->ldctl_oid,
1628*7c478bd9Sstevel@tonic-gate 			LDAP_CONTROL_AUTH_RESPONSE )) {
1629*7c478bd9Sstevel@tonic-gate 		    s = ctrls[i]->ldctl_value.bv_val;
1630*7c478bd9Sstevel@tonic-gate 		    if ( NULL == s ) {
1631*7c478bd9Sstevel@tonic-gate 			s = "Null";
1632*7c478bd9Sstevel@tonic-gate 		    } else if ( *s == '\0' ) {
1633*7c478bd9Sstevel@tonic-gate 			s = "Anonymous";
1634*7c478bd9Sstevel@tonic-gate 		    }
1635*7c478bd9Sstevel@tonic-gate 		fprintf( stderr, gettext("%s: bound as %s\n"), ldaptool_progname, s );
1636*7c478bd9Sstevel@tonic-gate 	    }
1637*7c478bd9Sstevel@tonic-gate 
1638*7c478bd9Sstevel@tonic-gate 	    if ( 0 == strcmp( ctrls[i]->ldctl_oid,
1639*7c478bd9Sstevel@tonic-gate 			LDAP_CONTROL_PWEXPIRING )) {
1640*7c478bd9Sstevel@tonic-gate 
1641*7c478bd9Sstevel@tonic-gate 		    /* Warn the user his passwd is to expire */
1642*7c478bd9Sstevel@tonic-gate 		    errno = 0;
1643*7c478bd9Sstevel@tonic-gate 		    pw_secs = atoi(ctrls[i]->ldctl_value.bv_val);
1644*7c478bd9Sstevel@tonic-gate 		    if ( pw_secs > 0  && errno != ERANGE ) {
1645*7c478bd9Sstevel@tonic-gate 			if ( pw_secs > 86400 ) {
1646*7c478bd9Sstevel@tonic-gate 				pw_days = ( pw_secs / 86400 );
1647*7c478bd9Sstevel@tonic-gate 				pw_secs = ( pw_secs % 86400 );
1648*7c478bd9Sstevel@tonic-gate 			}
1649*7c478bd9Sstevel@tonic-gate 			if ( pw_secs > 3600 ) {
1650*7c478bd9Sstevel@tonic-gate 				pw_hrs = ( pw_secs / 3600 );
1651*7c478bd9Sstevel@tonic-gate 				pw_secs = ( pw_secs % 3600 );
1652*7c478bd9Sstevel@tonic-gate 			}
1653*7c478bd9Sstevel@tonic-gate 			if ( pw_secs > 60 ) {
1654*7c478bd9Sstevel@tonic-gate 				pw_mins = ( pw_secs / 60 );
1655*7c478bd9Sstevel@tonic-gate 				pw_secs = ( pw_secs % 60 );
1656*7c478bd9Sstevel@tonic-gate 			}
1657*7c478bd9Sstevel@tonic-gate 
1658*7c478bd9Sstevel@tonic-gate 			printf(gettext("%s: Warning ! Your password will expire after "), ldaptool_progname);
1659*7c478bd9Sstevel@tonic-gate 			if ( pw_days ) {
1660*7c478bd9Sstevel@tonic-gate 				printf (gettext("%d days, "), pw_days);
1661*7c478bd9Sstevel@tonic-gate 			}
1662*7c478bd9Sstevel@tonic-gate 			if ( pw_hrs ) {
1663*7c478bd9Sstevel@tonic-gate 				printf (gettext("%d hrs, "), pw_hrs);
1664*7c478bd9Sstevel@tonic-gate 			}
1665*7c478bd9Sstevel@tonic-gate 			if ( pw_mins ) {
1666*7c478bd9Sstevel@tonic-gate 				printf (gettext("%d mins, "), pw_mins);
1667*7c478bd9Sstevel@tonic-gate 			}
1668*7c478bd9Sstevel@tonic-gate 			printf(gettext("%d seconds.\n"), pw_secs);
1669*7c478bd9Sstevel@tonic-gate 
1670*7c478bd9Sstevel@tonic-gate 		   }
1671*7c478bd9Sstevel@tonic-gate 		}
1672*7c478bd9Sstevel@tonic-gate 	}
1673*7c478bd9Sstevel@tonic-gate 	ldap_controls_free( ctrls );
1674*7c478bd9Sstevel@tonic-gate     }
1675*7c478bd9Sstevel@tonic-gate 
1676*7c478bd9Sstevel@tonic-gate     if ( servercredp != NULL && ( rc = ldap_parse_sasl_bind_result( ld, res,
1677*7c478bd9Sstevel@tonic-gate 	    servercredp, 0 )) != LDAP_SUCCESS ) {
1678*7c478bd9Sstevel@tonic-gate 	ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP );
1679*7c478bd9Sstevel@tonic-gate 	ldap_msgfree( res );
1680*7c478bd9Sstevel@tonic-gate 	return( rc );
1681*7c478bd9Sstevel@tonic-gate     }
1682*7c478bd9Sstevel@tonic-gate 
1683*7c478bd9Sstevel@tonic-gate     if ( freeit ) {
1684*7c478bd9Sstevel@tonic-gate 	ldap_msgfree( res );
1685*7c478bd9Sstevel@tonic-gate     }
1686*7c478bd9Sstevel@tonic-gate 
1687*7c478bd9Sstevel@tonic-gate     if ( LDAPTOOL_RESULT_IS_AN_ERROR( lderr )) {
1688*7c478bd9Sstevel@tonic-gate 	ldaptool_print_lderror( ld, msg, LDAPTOOL_CHECK4SSL_IF_APPROP );
1689*7c478bd9Sstevel@tonic-gate     }
1690*7c478bd9Sstevel@tonic-gate 
1691*7c478bd9Sstevel@tonic-gate     if ( refs != NULL ) {
1692*7c478bd9Sstevel@tonic-gate 	ldaptool_print_referrals( refs );
1693*7c478bd9Sstevel@tonic-gate 	ldap_value_free( refs );
1694*7c478bd9Sstevel@tonic-gate     }
1695*7c478bd9Sstevel@tonic-gate 
1696*7c478bd9Sstevel@tonic-gate     return( lderr );
1697*7c478bd9Sstevel@tonic-gate }
1698*7c478bd9Sstevel@tonic-gate 
1699*7c478bd9Sstevel@tonic-gate 
1700*7c478bd9Sstevel@tonic-gate /*
1701*7c478bd9Sstevel@tonic-gate  * if -M was passed on the command line, create and return a "Manage DSA IT"
1702*7c478bd9Sstevel@tonic-gate  * LDAPv3 control.  If not, return NULL.
1703*7c478bd9Sstevel@tonic-gate  */
1704*7c478bd9Sstevel@tonic-gate LDAPControl *
1705*7c478bd9Sstevel@tonic-gate ldaptool_create_manage_dsait_control( void )
1706*7c478bd9Sstevel@tonic-gate {
1707*7c478bd9Sstevel@tonic-gate     LDAPControl	*ctl;
1708*7c478bd9Sstevel@tonic-gate 
1709*7c478bd9Sstevel@tonic-gate     if ( !send_manage_dsait_ctrl ) {
1710*7c478bd9Sstevel@tonic-gate 	return( NULL );
1711*7c478bd9Sstevel@tonic-gate     }
1712*7c478bd9Sstevel@tonic-gate 
1713*7c478bd9Sstevel@tonic-gate     if (( ctl = (LDAPControl *)calloc( 1, sizeof( LDAPControl ))) == NULL ||
1714*7c478bd9Sstevel@tonic-gate 	    ( ctl->ldctl_oid = strdup( LDAP_CONTROL_MANAGEDSAIT )) == NULL ) {
1715*7c478bd9Sstevel@tonic-gate 	perror( "calloc" );
1716*7c478bd9Sstevel@tonic-gate 	exit( LDAP_NO_MEMORY );
1717*7c478bd9Sstevel@tonic-gate     }
1718*7c478bd9Sstevel@tonic-gate 
1719*7c478bd9Sstevel@tonic-gate     ctl->ldctl_iscritical = 1;
1720*7c478bd9Sstevel@tonic-gate 
1721*7c478bd9Sstevel@tonic-gate     return( ctl );
1722*7c478bd9Sstevel@tonic-gate }
1723*7c478bd9Sstevel@tonic-gate 
1724*7c478bd9Sstevel@tonic-gate /*
1725*7c478bd9Sstevel@tonic-gate  * if -y "dn" was supplied on the command line, create the control
1726*7c478bd9Sstevel@tonic-gate  */
1727*7c478bd9Sstevel@tonic-gate LDAPControl *
1728*7c478bd9Sstevel@tonic-gate ldaptool_create_proxyauth_control( LDAP *ld )
1729*7c478bd9Sstevel@tonic-gate {
1730*7c478bd9Sstevel@tonic-gate     LDAPControl	*ctl = NULL;
1731*7c478bd9Sstevel@tonic-gate     int rc;
1732*7c478bd9Sstevel@tonic-gate 
1733*7c478bd9Sstevel@tonic-gate 
1734*7c478bd9Sstevel@tonic-gate     if ( !proxyauth_id)
1735*7c478bd9Sstevel@tonic-gate 	return( NULL );
1736*7c478bd9Sstevel@tonic-gate 
1737*7c478bd9Sstevel@tonic-gate     if ( 2 == proxyauth_version ) {
1738*7c478bd9Sstevel@tonic-gate 	rc = ldap_create_proxiedauth_control( ld, proxyauth_id, &ctl);
1739*7c478bd9Sstevel@tonic-gate     } else {
1740*7c478bd9Sstevel@tonic-gate 	rc = ldap_create_proxyauth_control( ld, proxyauth_id, 1, &ctl);
1741*7c478bd9Sstevel@tonic-gate     }
1742*7c478bd9Sstevel@tonic-gate     if ( rc != LDAP_SUCCESS)
1743*7c478bd9Sstevel@tonic-gate     {
1744*7c478bd9Sstevel@tonic-gate 	if (ctl)
1745*7c478bd9Sstevel@tonic-gate 	    ldap_control_free( ctl);
1746*7c478bd9Sstevel@tonic-gate 	return NULL;
1747*7c478bd9Sstevel@tonic-gate     }
1748*7c478bd9Sstevel@tonic-gate     return( ctl );
1749*7c478bd9Sstevel@tonic-gate }
1750*7c478bd9Sstevel@tonic-gate 
1751*7c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
1752*7c478bd9Sstevel@tonic-gate LDAPControl *
1753*7c478bd9Sstevel@tonic-gate ldaptool_create_geteffectiveRights_control ( LDAP *ld, const char *authzid,
1754*7c478bd9Sstevel@tonic-gate 											const char **attrlist)
1755*7c478bd9Sstevel@tonic-gate {
1756*7c478bd9Sstevel@tonic-gate     LDAPControl	*ctl = NULL;
1757*7c478bd9Sstevel@tonic-gate     int rc;
1758*7c478bd9Sstevel@tonic-gate 
1759*7c478bd9Sstevel@tonic-gate 	rc = ldap_create_geteffectiveRights_control( ld, authzid, attrlist, 1,
1760*7c478bd9Sstevel@tonic-gate 							&ctl);
1761*7c478bd9Sstevel@tonic-gate 
1762*7c478bd9Sstevel@tonic-gate     if ( rc != LDAP_SUCCESS)
1763*7c478bd9Sstevel@tonic-gate     {
1764*7c478bd9Sstevel@tonic-gate 		if (ctl)
1765*7c478bd9Sstevel@tonic-gate 	    	ldap_control_free( ctl);
1766*7c478bd9Sstevel@tonic-gate 		return NULL;
1767*7c478bd9Sstevel@tonic-gate     }
1768*7c478bd9Sstevel@tonic-gate     return( ctl );
1769*7c478bd9Sstevel@tonic-gate }
1770*7c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
1771*7c478bd9Sstevel@tonic-gate 
1772*7c478bd9Sstevel@tonic-gate 
1773*7c478bd9Sstevel@tonic-gate void
1774*7c478bd9Sstevel@tonic-gate ldaptool_add_control_to_array( LDAPControl *ctrl, LDAPControl **array)
1775*7c478bd9Sstevel@tonic-gate {
1776*7c478bd9Sstevel@tonic-gate 
1777*7c478bd9Sstevel@tonic-gate     int i;
1778*7c478bd9Sstevel@tonic-gate     for (i=0; i< CONTROL_REQUESTS; i++)
1779*7c478bd9Sstevel@tonic-gate     {
1780*7c478bd9Sstevel@tonic-gate 	if (*(array + i) == NULL)
1781*7c478bd9Sstevel@tonic-gate 	{
1782*7c478bd9Sstevel@tonic-gate 	    *(array + i +1) = NULL;
1783*7c478bd9Sstevel@tonic-gate 	    *(array + i) = ctrl;
1784*7c478bd9Sstevel@tonic-gate 	    return ;
1785*7c478bd9Sstevel@tonic-gate 	}
1786*7c478bd9Sstevel@tonic-gate     }
1787*7c478bd9Sstevel@tonic-gate     fprintf(stderr, gettext("%s: failed to store request control!!!!!!\n"),
1788*7c478bd9Sstevel@tonic-gate 	    ldaptool_progname);
1789*7c478bd9Sstevel@tonic-gate }
1790*7c478bd9Sstevel@tonic-gate 
1791*7c478bd9Sstevel@tonic-gate /*
1792*7c478bd9Sstevel@tonic-gate  * Dispose of all controls in array and prepare array for reuse.
1793*7c478bd9Sstevel@tonic-gate  */
1794*7c478bd9Sstevel@tonic-gate void
1795*7c478bd9Sstevel@tonic-gate ldaptool_reset_control_array( LDAPControl **array )
1796*7c478bd9Sstevel@tonic-gate {
1797*7c478bd9Sstevel@tonic-gate     int		i;
1798*7c478bd9Sstevel@tonic-gate 
1799*7c478bd9Sstevel@tonic-gate     for ( i = 0; i < CONTROL_REQUESTS; i++ ) {
1800*7c478bd9Sstevel@tonic-gate 	if ( array[i] != NULL ) {
1801*7c478bd9Sstevel@tonic-gate 	    ldap_control_free( array[i] );
1802*7c478bd9Sstevel@tonic-gate 	    array[i] = NULL;
1803*7c478bd9Sstevel@tonic-gate 	}
1804*7c478bd9Sstevel@tonic-gate     }
1805*7c478bd9Sstevel@tonic-gate }
1806*7c478bd9Sstevel@tonic-gate 
1807*7c478bd9Sstevel@tonic-gate /*
1808*7c478bd9Sstevel@tonic-gate  * This function calculates control value and its length. *value can
1809*7c478bd9Sstevel@tonic-gate  * be pointing to plain value, ":b64encoded value" or "<fileurl".
1810*7c478bd9Sstevel@tonic-gate  */
1811*7c478bd9Sstevel@tonic-gate static int
1812*7c478bd9Sstevel@tonic-gate calculate_ctrl_value( const char *value,
1813*7c478bd9Sstevel@tonic-gate 	char **ctrl_value, int *vlen)
1814*7c478bd9Sstevel@tonic-gate {
1815*7c478bd9Sstevel@tonic-gate     int b64;
1816*7c478bd9Sstevel@tonic-gate     if (*value == ':') {
1817*7c478bd9Sstevel@tonic-gate 	value++;
1818*7c478bd9Sstevel@tonic-gate 	b64 = 1;
1819*7c478bd9Sstevel@tonic-gate     } else {
1820*7c478bd9Sstevel@tonic-gate 	b64 = 0;
1821*7c478bd9Sstevel@tonic-gate     }
1822*7c478bd9Sstevel@tonic-gate     *ctrl_value = (char *)value;
1823*7c478bd9Sstevel@tonic-gate 
1824*7c478bd9Sstevel@tonic-gate     if ( b64 ) {
1825*7c478bd9Sstevel@tonic-gate 	if (( *vlen = ldif_base64_decode( (char *)value,
1826*7c478bd9Sstevel@tonic-gate 		(unsigned char *)value )) < 0 ) {
1827*7c478bd9Sstevel@tonic-gate 	    fprintf( stderr,
1828*7c478bd9Sstevel@tonic-gate 		gettext("Unable to decode base64 control value \"%s\"\n"), value);
1829*7c478bd9Sstevel@tonic-gate 	    return( -1 );
1830*7c478bd9Sstevel@tonic-gate 	}
1831*7c478bd9Sstevel@tonic-gate     } else {
1832*7c478bd9Sstevel@tonic-gate 	*vlen = (int)strlen(*ctrl_value);
1833*7c478bd9Sstevel@tonic-gate     }
1834*7c478bd9Sstevel@tonic-gate     return( 0 );
1835*7c478bd9Sstevel@tonic-gate }
1836*7c478bd9Sstevel@tonic-gate 
1837*7c478bd9Sstevel@tonic-gate /*
1838*7c478bd9Sstevel@tonic-gate  * Parse the optarg from -J option of ldapsearch
1839*7c478bd9Sstevel@tonic-gate  * and within LDIFfile for ldapmodify. Take ctrl_arg
1840*7c478bd9Sstevel@tonic-gate  * (the whole string) and divide it into oid, criticality
1841*7c478bd9Sstevel@tonic-gate  * and value. This function breaks down original ctrl_arg
1842*7c478bd9Sstevel@tonic-gate  * with '\0' in places. Also, calculate length of valuestring.
1843*7c478bd9Sstevel@tonic-gate  */
1844*7c478bd9Sstevel@tonic-gate int
1845*7c478bd9Sstevel@tonic-gate ldaptool_parse_ctrl_arg(char *ctrl_arg, char sep,
1846*7c478bd9Sstevel@tonic-gate 		char **ctrl_oid, int *ctrl_criticality,
1847*7c478bd9Sstevel@tonic-gate 		char **ctrl_value, int *vlen)
1848*7c478bd9Sstevel@tonic-gate {
1849*7c478bd9Sstevel@tonic-gate     char *s, *p;
1850*7c478bd9Sstevel@tonic-gate     int strict;
1851*7c478bd9Sstevel@tonic-gate 
1852*7c478bd9Sstevel@tonic-gate     /* Initialize passed variables with default values */
1853*7c478bd9Sstevel@tonic-gate     *ctrl_oid = *ctrl_value = NULL;
1854*7c478bd9Sstevel@tonic-gate     *ctrl_criticality = 0;
1855*7c478bd9Sstevel@tonic-gate     *vlen = 0;
1856*7c478bd9Sstevel@tonic-gate 
1857*7c478bd9Sstevel@tonic-gate     strict = (sep == ' ' ? 1 : 0);
1858*7c478bd9Sstevel@tonic-gate     if(!(s=strchr(ctrl_arg, sep))) {
1859*7c478bd9Sstevel@tonic-gate 	/* Possible values of ctrl_arg are
1860*7c478bd9Sstevel@tonic-gate 	 * oid[:value|::b64value|:<fileurl] within LDIF, i.e. sep=' '
1861*7c478bd9Sstevel@tonic-gate 	 * oid from command line option, i.e. sep=':'
1862*7c478bd9Sstevel@tonic-gate 	 */
1863*7c478bd9Sstevel@tonic-gate 	if (sep == ' ') {
1864*7c478bd9Sstevel@tonic-gate 	    if (!(s=strchr(ctrl_arg, ':'))) {
1865*7c478bd9Sstevel@tonic-gate 		*ctrl_oid = ctrl_arg;
1866*7c478bd9Sstevel@tonic-gate 	    }
1867*7c478bd9Sstevel@tonic-gate 	    else {
1868*7c478bd9Sstevel@tonic-gate 		/* ctrl_arg is of oid:[value|:b64value|<fileurl]
1869*7c478bd9Sstevel@tonic-gate 		 * form in the LDIF record. So, grab the oid and then
1870*7c478bd9Sstevel@tonic-gate 		 * jump to continue the parsing of ctrl_arg.
1871*7c478bd9Sstevel@tonic-gate 		 * 's' is pointing just after oid ends.
1872*7c478bd9Sstevel@tonic-gate 		 */
1873*7c478bd9Sstevel@tonic-gate 		*s++ = '\0';
1874*7c478bd9Sstevel@tonic-gate 		*ctrl_oid = ctrl_arg;
1875*7c478bd9Sstevel@tonic-gate 		return (calculate_ctrl_value( s, ctrl_value, vlen ));
1876*7c478bd9Sstevel@tonic-gate 	    }
1877*7c478bd9Sstevel@tonic-gate 	} else {
1878*7c478bd9Sstevel@tonic-gate 		/* oid - from command line option, i.e. sep=':' */
1879*7c478bd9Sstevel@tonic-gate 		*ctrl_oid = ctrl_arg;
1880*7c478bd9Sstevel@tonic-gate 	}
1881*7c478bd9Sstevel@tonic-gate     }
1882*7c478bd9Sstevel@tonic-gate     else {
1883*7c478bd9Sstevel@tonic-gate 	/* Possible values of ctrl_arg are
1884*7c478bd9Sstevel@tonic-gate 	 * oid:criticality[:value|::b64value|:<fileurl] - command line
1885*7c478bd9Sstevel@tonic-gate 	 * oid criticality[:value|::b64value|:<fileurl] - LDIF
1886*7c478bd9Sstevel@tonic-gate 	 * And 's' is pointing just after oid ends.
1887*7c478bd9Sstevel@tonic-gate 	 */
1888*7c478bd9Sstevel@tonic-gate 
1889*7c478bd9Sstevel@tonic-gate 	if (*(s+1) == '\0') {
1890*7c478bd9Sstevel@tonic-gate 	    fprintf( stderr, gettext("missing value\n") );
1891*7c478bd9Sstevel@tonic-gate 	    return( -1 );
1892*7c478bd9Sstevel@tonic-gate 	}
1893*7c478bd9Sstevel@tonic-gate 	*s = '\0';
1894*7c478bd9Sstevel@tonic-gate 	*ctrl_oid = ctrl_arg;
1895*7c478bd9Sstevel@tonic-gate 	p = ++s;
1896*7c478bd9Sstevel@tonic-gate 	if(!(s=strchr(p, ':'))) {
1897*7c478bd9Sstevel@tonic-gate 	    if ( (*ctrl_criticality = ldaptool_boolean_str2value(p, strict))
1898*7c478bd9Sstevel@tonic-gate 			== -1 ) {
1899*7c478bd9Sstevel@tonic-gate 		fprintf( stderr, gettext("Invalid criticality value\n") );
1900*7c478bd9Sstevel@tonic-gate 		return( -1 );
1901*7c478bd9Sstevel@tonic-gate 	    }
1902*7c478bd9Sstevel@tonic-gate 	}
1903*7c478bd9Sstevel@tonic-gate 	else {
1904*7c478bd9Sstevel@tonic-gate 	    if (*(s+1) == '\0') {
1905*7c478bd9Sstevel@tonic-gate 	        fprintf( stderr, gettext("missing value\n") );
1906*7c478bd9Sstevel@tonic-gate 	        return ( -1 );
1907*7c478bd9Sstevel@tonic-gate 	    }
1908*7c478bd9Sstevel@tonic-gate 	    *s++ = '\0';
1909*7c478bd9Sstevel@tonic-gate             if ( (*ctrl_criticality = ldaptool_boolean_str2value(p, strict))
1910*7c478bd9Sstevel@tonic-gate 			== -1 ) {
1911*7c478bd9Sstevel@tonic-gate 		fprintf( stderr, gettext("Invalid criticality value\n") );
1912*7c478bd9Sstevel@tonic-gate 		return ( -1 );
1913*7c478bd9Sstevel@tonic-gate 	    }
1914*7c478bd9Sstevel@tonic-gate 	    return (calculate_ctrl_value( s, ctrl_value, vlen ));
1915*7c478bd9Sstevel@tonic-gate 	}
1916*7c478bd9Sstevel@tonic-gate     }
1917*7c478bd9Sstevel@tonic-gate 
1918*7c478bd9Sstevel@tonic-gate     return( 0 );
1919*7c478bd9Sstevel@tonic-gate }
1920*7c478bd9Sstevel@tonic-gate 
1921*7c478bd9Sstevel@tonic-gate 
1922*7c478bd9Sstevel@tonic-gate /*
1923*7c478bd9Sstevel@tonic-gate  * callback function for LDAP bind credentials
1924*7c478bd9Sstevel@tonic-gate  */
1925*7c478bd9Sstevel@tonic-gate static int
1926*7c478bd9Sstevel@tonic-gate LDAP_CALL
1927*7c478bd9Sstevel@tonic-gate LDAP_CALLBACK
1928*7c478bd9Sstevel@tonic-gate get_rebind_credentials( LDAP *ld, char **whop, char **credp,
1929*7c478bd9Sstevel@tonic-gate         int *methodp, int freeit, void* arg )
1930*7c478bd9Sstevel@tonic-gate {
1931*7c478bd9Sstevel@tonic-gate     if ( !freeit ) {
1932*7c478bd9Sstevel@tonic-gate 	*whop = binddn;
1933*7c478bd9Sstevel@tonic-gate 	*credp = passwd;
1934*7c478bd9Sstevel@tonic-gate 	*methodp = LDAP_AUTH_SIMPLE;
1935*7c478bd9Sstevel@tonic-gate     }
1936*7c478bd9Sstevel@tonic-gate 
1937*7c478bd9Sstevel@tonic-gate     return( LDAP_SUCCESS );
1938*7c478bd9Sstevel@tonic-gate }
1939*7c478bd9Sstevel@tonic-gate 
1940*7c478bd9Sstevel@tonic-gate 
1941*7c478bd9Sstevel@tonic-gate /*
1942*7c478bd9Sstevel@tonic-gate  * return pointer to pathname to temporary directory.
1943*7c478bd9Sstevel@tonic-gate  * First we see if the environment variable "TEMP" is set and use it.
1944*7c478bd9Sstevel@tonic-gate  * Then we see if the environment variable "TMP" is set and use it.
1945*7c478bd9Sstevel@tonic-gate  * If this fails, we use "/tmp" on UNIX and fail on Windows.
1946*7c478bd9Sstevel@tonic-gate  */
1947*7c478bd9Sstevel@tonic-gate char *
1948*7c478bd9Sstevel@tonic-gate ldaptool_get_tmp_dir( void )
1949*7c478bd9Sstevel@tonic-gate {
1950*7c478bd9Sstevel@tonic-gate     char	*p;
1951*7c478bd9Sstevel@tonic-gate     int		offset;
1952*7c478bd9Sstevel@tonic-gate 
1953*7c478bd9Sstevel@tonic-gate     if (( p = getenv( "TEMP" )) == NULL && ( p = getenv( "TMP" )) == NULL ) {
1954*7c478bd9Sstevel@tonic-gate #ifdef _WINDOWS
1955*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: please set the TEMP environment variable.\n"),
1956*7c478bd9Sstevel@tonic-gate 		ldaptool_progname );
1957*7c478bd9Sstevel@tonic-gate 	exit( LDAP_LOCAL_ERROR );
1958*7c478bd9Sstevel@tonic-gate #else
1959*7c478bd9Sstevel@tonic-gate 	return( "/tmp" );	/* last resort on UNIX */
1960*7c478bd9Sstevel@tonic-gate #endif
1961*7c478bd9Sstevel@tonic-gate     }
1962*7c478bd9Sstevel@tonic-gate 
1963*7c478bd9Sstevel@tonic-gate     /*
1964*7c478bd9Sstevel@tonic-gate      * remove trailing slash if present
1965*7c478bd9Sstevel@tonic-gate      */
1966*7c478bd9Sstevel@tonic-gate     offset = strlen( p ) - 1;
1967*7c478bd9Sstevel@tonic-gate     if ( p[offset] == '/'
1968*7c478bd9Sstevel@tonic-gate #ifdef _WINDOWS
1969*7c478bd9Sstevel@tonic-gate 	    || p[offset] == '\\'
1970*7c478bd9Sstevel@tonic-gate #endif
1971*7c478bd9Sstevel@tonic-gate 	    ) {
1972*7c478bd9Sstevel@tonic-gate 	if (( p = strdup( p )) == NULL ) {
1973*7c478bd9Sstevel@tonic-gate 	    perror( "strdup" );
1974*7c478bd9Sstevel@tonic-gate 	    exit( LDAP_NO_MEMORY );
1975*7c478bd9Sstevel@tonic-gate 	}
1976*7c478bd9Sstevel@tonic-gate 
1977*7c478bd9Sstevel@tonic-gate 	p[offset] = '\0';
1978*7c478bd9Sstevel@tonic-gate     }
1979*7c478bd9Sstevel@tonic-gate 
1980*7c478bd9Sstevel@tonic-gate     return( p );
1981*7c478bd9Sstevel@tonic-gate }
1982*7c478bd9Sstevel@tonic-gate 
1983*7c478bd9Sstevel@tonic-gate 
1984*7c478bd9Sstevel@tonic-gate int
1985*7c478bd9Sstevel@tonic-gate ldaptool_berval_is_ascii( const struct berval *bvp )
1986*7c478bd9Sstevel@tonic-gate {
1987*7c478bd9Sstevel@tonic-gate     unsigned long	j;
1988*7c478bd9Sstevel@tonic-gate     int			is_ascii = 1;	 /* optimistic */
1989*7c478bd9Sstevel@tonic-gate 
1990*7c478bd9Sstevel@tonic-gate     for ( j = 0; j < bvp->bv_len; ++j ) {
1991*7c478bd9Sstevel@tonic-gate 	if ( !isascii( bvp->bv_val[ j ] )) {
1992*7c478bd9Sstevel@tonic-gate 	    is_ascii = 0;
1993*7c478bd9Sstevel@tonic-gate 	    break;
1994*7c478bd9Sstevel@tonic-gate 	}
1995*7c478bd9Sstevel@tonic-gate     }
1996*7c478bd9Sstevel@tonic-gate 
1997*7c478bd9Sstevel@tonic-gate     return( is_ascii );
1998*7c478bd9Sstevel@tonic-gate }
1999*7c478bd9Sstevel@tonic-gate 
2000*7c478bd9Sstevel@tonic-gate 
2001*7c478bd9Sstevel@tonic-gate #ifdef LDAP_DEBUG_MEMORY
2002*7c478bd9Sstevel@tonic-gate #define LDAPTOOL_ALLOC_FREED	0xF001
2003*7c478bd9Sstevel@tonic-gate #define LDAPTOOL_ALLOC_INUSE	0xF002
2004*7c478bd9Sstevel@tonic-gate 
2005*7c478bd9Sstevel@tonic-gate static void *
2006*7c478bd9Sstevel@tonic-gate ldaptool_debug_alloc( void *ptr, size_t size )
2007*7c478bd9Sstevel@tonic-gate {
2008*7c478bd9Sstevel@tonic-gate     int		*statusp;
2009*7c478bd9Sstevel@tonic-gate     void	*systemptr;
2010*7c478bd9Sstevel@tonic-gate 
2011*7c478bd9Sstevel@tonic-gate     if ( ptr == NULL ) {
2012*7c478bd9Sstevel@tonic-gate 	systemptr = NULL;
2013*7c478bd9Sstevel@tonic-gate     } else {
2014*7c478bd9Sstevel@tonic-gate 	systemptr = (void *)((char *)ptr - sizeof(int));
2015*7c478bd9Sstevel@tonic-gate     }
2016*7c478bd9Sstevel@tonic-gate 
2017*7c478bd9Sstevel@tonic-gate     if (( statusp = (int *)realloc( systemptr, size + sizeof(int))) == NULL ) {
2018*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: realloc( 0x%x, %d) failed\n"),
2019*7c478bd9Sstevel@tonic-gate 		ldaptool_progname, systemptr, size );
2020*7c478bd9Sstevel@tonic-gate 	return( NULL );
2021*7c478bd9Sstevel@tonic-gate     }
2022*7c478bd9Sstevel@tonic-gate 
2023*7c478bd9Sstevel@tonic-gate     *statusp = LDAPTOOL_ALLOC_INUSE;
2024*7c478bd9Sstevel@tonic-gate 
2025*7c478bd9Sstevel@tonic-gate     return( (char *)statusp + sizeof(int));
2026*7c478bd9Sstevel@tonic-gate }
2027*7c478bd9Sstevel@tonic-gate 
2028*7c478bd9Sstevel@tonic-gate 
2029*7c478bd9Sstevel@tonic-gate static void *
2030*7c478bd9Sstevel@tonic-gate ldaptool_debug_realloc( void *ptr, size_t size )
2031*7c478bd9Sstevel@tonic-gate {
2032*7c478bd9Sstevel@tonic-gate     void	*p;
2033*7c478bd9Sstevel@tonic-gate 
2034*7c478bd9Sstevel@tonic-gate     if ( ldaptool_dbg_lvl & LDAP_DEBUG_TRACE ) {
2035*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: => realloc( 0x%x, %d )\n"),
2036*7c478bd9Sstevel@tonic-gate 		ldaptool_progname, ptr, size );
2037*7c478bd9Sstevel@tonic-gate     }
2038*7c478bd9Sstevel@tonic-gate 
2039*7c478bd9Sstevel@tonic-gate     p = ldaptool_debug_alloc( ptr, size );
2040*7c478bd9Sstevel@tonic-gate 
2041*7c478bd9Sstevel@tonic-gate     if ( ldaptool_dbg_lvl & LDAP_DEBUG_TRACE ) {
2042*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: 0x%x <= realloc()\n"), ldaptool_progname, p );
2043*7c478bd9Sstevel@tonic-gate     }
2044*7c478bd9Sstevel@tonic-gate 
2045*7c478bd9Sstevel@tonic-gate     return( p );
2046*7c478bd9Sstevel@tonic-gate }
2047*7c478bd9Sstevel@tonic-gate 
2048*7c478bd9Sstevel@tonic-gate 
2049*7c478bd9Sstevel@tonic-gate static void *
2050*7c478bd9Sstevel@tonic-gate ldaptool_debug_malloc( size_t size )
2051*7c478bd9Sstevel@tonic-gate {
2052*7c478bd9Sstevel@tonic-gate     void	*p;
2053*7c478bd9Sstevel@tonic-gate 
2054*7c478bd9Sstevel@tonic-gate     if ( ldaptool_dbg_lvl & LDAP_DEBUG_TRACE ) {
2055*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: => malloc( %d)\n"), ldaptool_progname, size );
2056*7c478bd9Sstevel@tonic-gate     }
2057*7c478bd9Sstevel@tonic-gate 
2058*7c478bd9Sstevel@tonic-gate     p = ldaptool_debug_alloc( NULL, size );
2059*7c478bd9Sstevel@tonic-gate 
2060*7c478bd9Sstevel@tonic-gate     if ( ldaptool_dbg_lvl & LDAP_DEBUG_TRACE ) {
2061*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: 0x%x <= malloc()\n"), ldaptool_progname, p );
2062*7c478bd9Sstevel@tonic-gate     }
2063*7c478bd9Sstevel@tonic-gate 
2064*7c478bd9Sstevel@tonic-gate     return( p );
2065*7c478bd9Sstevel@tonic-gate }
2066*7c478bd9Sstevel@tonic-gate 
2067*7c478bd9Sstevel@tonic-gate 
2068*7c478bd9Sstevel@tonic-gate static void *
2069*7c478bd9Sstevel@tonic-gate ldaptool_debug_calloc( size_t nelem, size_t elsize )
2070*7c478bd9Sstevel@tonic-gate {
2071*7c478bd9Sstevel@tonic-gate     void	*p;
2072*7c478bd9Sstevel@tonic-gate 
2073*7c478bd9Sstevel@tonic-gate     if ( ldaptool_dbg_lvl & LDAP_DEBUG_TRACE ) {
2074*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: => calloc( %d, %d )\n"),
2075*7c478bd9Sstevel@tonic-gate 		ldaptool_progname, nelem, elsize );
2076*7c478bd9Sstevel@tonic-gate     }
2077*7c478bd9Sstevel@tonic-gate 
2078*7c478bd9Sstevel@tonic-gate     if (( p = ldaptool_debug_alloc( NULL, nelem * elsize )) != NULL ) {
2079*7c478bd9Sstevel@tonic-gate 	memset( p, 0, nelem * elsize );
2080*7c478bd9Sstevel@tonic-gate     }
2081*7c478bd9Sstevel@tonic-gate 
2082*7c478bd9Sstevel@tonic-gate     if ( ldaptool_dbg_lvl & LDAP_DEBUG_TRACE ) {
2083*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: 0x%x <= calloc()\n"), ldaptool_progname, p );
2084*7c478bd9Sstevel@tonic-gate     }
2085*7c478bd9Sstevel@tonic-gate 
2086*7c478bd9Sstevel@tonic-gate     return( p );
2087*7c478bd9Sstevel@tonic-gate }
2088*7c478bd9Sstevel@tonic-gate 
2089*7c478bd9Sstevel@tonic-gate 
2090*7c478bd9Sstevel@tonic-gate static void
2091*7c478bd9Sstevel@tonic-gate ldaptool_debug_free( void *ptr )
2092*7c478bd9Sstevel@tonic-gate {
2093*7c478bd9Sstevel@tonic-gate     int		*statusp = (int *)((char *)ptr - sizeof(int));
2094*7c478bd9Sstevel@tonic-gate 
2095*7c478bd9Sstevel@tonic-gate     if ( ldaptool_dbg_lvl & LDAP_DEBUG_TRACE ) {
2096*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: => free( 0x%x )\n"), ldaptool_progname, ptr );
2097*7c478bd9Sstevel@tonic-gate     }
2098*7c478bd9Sstevel@tonic-gate 
2099*7c478bd9Sstevel@tonic-gate     if ( ptr == NULL ) {
2100*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: bad free( 0x0 ) attempted (NULL pointer)\n"),
2101*7c478bd9Sstevel@tonic-gate 		ldaptool_progname );
2102*7c478bd9Sstevel@tonic-gate     } else if ( *statusp != LDAPTOOL_ALLOC_INUSE ) {
2103*7c478bd9Sstevel@tonic-gate 	fprintf( stderr, gettext("%s: bad free( 0x%x ) attempted"
2104*7c478bd9Sstevel@tonic-gate 		" (block not in use; status is %d)\n"),
2105*7c478bd9Sstevel@tonic-gate 		ldaptool_progname, ptr, *statusp );
2106*7c478bd9Sstevel@tonic-gate     } else {
2107*7c478bd9Sstevel@tonic-gate 	*statusp = LDAPTOOL_ALLOC_FREED;
2108*7c478bd9Sstevel@tonic-gate 	free( statusp );
2109*7c478bd9Sstevel@tonic-gate     }
2110*7c478bd9Sstevel@tonic-gate }
2111*7c478bd9Sstevel@tonic-gate #endif /* LDAP_DEBUG_MEMORY */
2112*7c478bd9Sstevel@tonic-gate 
2113*7c478bd9Sstevel@tonic-gate 
2114*7c478bd9Sstevel@tonic-gate #if defined(NET_SSL)
2115*7c478bd9Sstevel@tonic-gate /*
2116*7c478bd9Sstevel@tonic-gate  * Derive key database path from certificate database path and return a
2117*7c478bd9Sstevel@tonic-gate  * malloc'd string.
2118*7c478bd9Sstevel@tonic-gate  *
2119*7c478bd9Sstevel@tonic-gate  * We just return an exact copy of "certdbpath" unless it ends in "cert.db",
2120*7c478bd9Sstevel@tonic-gate  * "cert5.db", or "cert7.db".  In those cases we strip off everything from
2121*7c478bd9Sstevel@tonic-gate  * "cert" on and append "key.db", "key5.db", or "key3.db" as appropriate.
2122*7c478bd9Sstevel@tonic-gate  * Strangely enough cert7.db and key3.db go together.
2123*7c478bd9Sstevel@tonic-gate  */
2124*7c478bd9Sstevel@tonic-gate static char *
2125*7c478bd9Sstevel@tonic-gate certpath2keypath( char *certdbpath )
2126*7c478bd9Sstevel@tonic-gate {
2127*7c478bd9Sstevel@tonic-gate     char	*keydbpath, *appendstr;
2128*7c478bd9Sstevel@tonic-gate     int		len, striplen;
2129*7c478bd9Sstevel@tonic-gate 
2130*7c478bd9Sstevel@tonic-gate     if ( certdbpath == NULL ) {
2131*7c478bd9Sstevel@tonic-gate 	return( NULL );
2132*7c478bd9Sstevel@tonic-gate     }
2133*7c478bd9Sstevel@tonic-gate 
2134*7c478bd9Sstevel@tonic-gate     if (( keydbpath = strdup( certdbpath )) == NULL ) {
2135*7c478bd9Sstevel@tonic-gate 	perror( "strdup" );
2136*7c478bd9Sstevel@tonic-gate 	exit( LDAP_NO_MEMORY );
2137*7c478bd9Sstevel@tonic-gate     }
2138*7c478bd9Sstevel@tonic-gate 
2139*7c478bd9Sstevel@tonic-gate     len = strlen( keydbpath );
2140*7c478bd9Sstevel@tonic-gate     if ( len > 7 &&
2141*7c478bd9Sstevel@tonic-gate 	    strcasecmp( "cert.db", keydbpath + len - 7 ) == 0 ) {
2142*7c478bd9Sstevel@tonic-gate 	striplen = 7;
2143*7c478bd9Sstevel@tonic-gate 	appendstr = "key.db";
2144*7c478bd9Sstevel@tonic-gate 
2145*7c478bd9Sstevel@tonic-gate     } else if ( len > 8 &&
2146*7c478bd9Sstevel@tonic-gate 	    strcasecmp( "cert5.db", keydbpath + len - 8 ) == 0 ) {
2147*7c478bd9Sstevel@tonic-gate 	striplen = 8;
2148*7c478bd9Sstevel@tonic-gate 	appendstr = "key5.db";
2149*7c478bd9Sstevel@tonic-gate     } else if ( len > 8 &&
2150*7c478bd9Sstevel@tonic-gate 	    strcasecmp( "cert7.db", keydbpath + len - 8 ) == 0 ) {
2151*7c478bd9Sstevel@tonic-gate 	striplen = 8;
2152*7c478bd9Sstevel@tonic-gate 	appendstr = "key3.db";
2153*7c478bd9Sstevel@tonic-gate     } else {
2154*7c478bd9Sstevel@tonic-gate 	striplen = 0;
2155*7c478bd9Sstevel@tonic-gate     }
2156*7c478bd9Sstevel@tonic-gate 
2157*7c478bd9Sstevel@tonic-gate     if ( striplen > 0 ) {
2158*7c478bd9Sstevel@tonic-gate 	/*
2159*7c478bd9Sstevel@tonic-gate 	 * The following code assumes that strlen( appendstr ) < striplen!
2160*7c478bd9Sstevel@tonic-gate 	 */
2161*7c478bd9Sstevel@tonic-gate 	strcpy( keydbpath + len - striplen, appendstr );
2162*7c478bd9Sstevel@tonic-gate     }
2163*7c478bd9Sstevel@tonic-gate 
2164*7c478bd9Sstevel@tonic-gate     return( keydbpath );
2165*7c478bd9Sstevel@tonic-gate }
2166*7c478bd9Sstevel@tonic-gate 
2167*7c478bd9Sstevel@tonic-gate #ifdef LDAP_TOOL_PKCS11
2168*7c478bd9Sstevel@tonic-gate static
2169*7c478bd9Sstevel@tonic-gate char *
2170*7c478bd9Sstevel@tonic-gate buildTokenCertName( const char *tokenName, const char *certName)
2171*7c478bd9Sstevel@tonic-gate {
2172*7c478bd9Sstevel@tonic-gate 
2173*7c478bd9Sstevel@tonic-gate     int tokenlen = strlen(tokenName);
2174*7c478bd9Sstevel@tonic-gate     int len = tokenlen + strlen(certName) +2;
2175*7c478bd9Sstevel@tonic-gate     char *result;
2176*7c478bd9Sstevel@tonic-gate 
2177*7c478bd9Sstevel@tonic-gate     if (( result = malloc( len )) != NULL) {
2178*7c478bd9Sstevel@tonic-gate 	strcpy(result, tokenName);
2179*7c478bd9Sstevel@tonic-gate 	*(result+tokenlen) = ':';
2180*7c478bd9Sstevel@tonic-gate 	++tokenlen;
2181*7c478bd9Sstevel@tonic-gate 	strcpy(result+tokenlen, certName);
2182*7c478bd9Sstevel@tonic-gate     } else {
2183*7c478bd9Sstevel@tonic-gate 	perror("malloc");
2184*7c478bd9Sstevel@tonic-gate 	exit( LDAP_NO_MEMORY );
2185*7c478bd9Sstevel@tonic-gate     }
2186*7c478bd9Sstevel@tonic-gate     return result;
2187*7c478bd9Sstevel@tonic-gate }
2188*7c478bd9Sstevel@tonic-gate 
2189*7c478bd9Sstevel@tonic-gate 
2190*7c478bd9Sstevel@tonic-gate 
2191*7c478bd9Sstevel@tonic-gate static
2192*7c478bd9Sstevel@tonic-gate int
2193*7c478bd9Sstevel@tonic-gate ldaptool_getcertpath( void *context, char **certlocp )
2194*7c478bd9Sstevel@tonic-gate {
2195*7c478bd9Sstevel@tonic-gate 
2196*7c478bd9Sstevel@tonic-gate     *certlocp = ssl_certdbpath;
2197*7c478bd9Sstevel@tonic-gate     if ( ldaptool_verbose ) {
2198*7c478bd9Sstevel@tonic-gate 	if (ssl_certdbpath)
2199*7c478bd9Sstevel@tonic-gate 	{
2200*7c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_getcertpath -- %s\n"), ssl_certdbpath );
2201*7c478bd9Sstevel@tonic-gate 	}
2202*7c478bd9Sstevel@tonic-gate 	else
2203*7c478bd9Sstevel@tonic-gate 	{
2204*7c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_getcertpath -- (null)\n"));
2205*7c478bd9Sstevel@tonic-gate 	}
2206*7c478bd9Sstevel@tonic-gate 
2207*7c478bd9Sstevel@tonic-gate     }
2208*7c478bd9Sstevel@tonic-gate     return LDAP_SUCCESS;
2209*7c478bd9Sstevel@tonic-gate }
2210*7c478bd9Sstevel@tonic-gate 
2211*7c478bd9Sstevel@tonic-gate int
2212*7c478bd9Sstevel@tonic-gate ldaptool_getcertname( void *context, char **certnamep )
2213*7c478bd9Sstevel@tonic-gate {
2214*7c478bd9Sstevel@tonic-gate 
2215*7c478bd9Sstevel@tonic-gate    *certnamep = ssl_certname;
2216*7c478bd9Sstevel@tonic-gate     if ( ldaptool_verbose ) {
2217*7c478bd9Sstevel@tonic-gate 	if (ssl_certname)
2218*7c478bd9Sstevel@tonic-gate 	{
2219*7c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_getcertname -- %s\n"), *certnamep);
2220*7c478bd9Sstevel@tonic-gate 	}
2221*7c478bd9Sstevel@tonic-gate 	else
2222*7c478bd9Sstevel@tonic-gate 	{
2223*7c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_getcertname -- (null)\n"));
2224*7c478bd9Sstevel@tonic-gate 	}
2225*7c478bd9Sstevel@tonic-gate     }
2226*7c478bd9Sstevel@tonic-gate     return LDAP_SUCCESS;
2227*7c478bd9Sstevel@tonic-gate }
2228*7c478bd9Sstevel@tonic-gate 
2229*7c478bd9Sstevel@tonic-gate int
2230*7c478bd9Sstevel@tonic-gate ldaptool_getkeypath(void *context, char **keylocp )
2231*7c478bd9Sstevel@tonic-gate {
2232*7c478bd9Sstevel@tonic-gate     *keylocp = ssl_keydbpath;
2233*7c478bd9Sstevel@tonic-gate     if ( ldaptool_verbose ) {
2234*7c478bd9Sstevel@tonic-gate 	if (ssl_keydbpath)
2235*7c478bd9Sstevel@tonic-gate 	{
2236*7c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_getkeypath -- %s\n"),*keylocp);
2237*7c478bd9Sstevel@tonic-gate 	}
2238*7c478bd9Sstevel@tonic-gate 	else
2239*7c478bd9Sstevel@tonic-gate 	{
2240*7c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_getkeypath -- (null)\n"));
2241*7c478bd9Sstevel@tonic-gate 	}
2242*7c478bd9Sstevel@tonic-gate     }
2243*7c478bd9Sstevel@tonic-gate 
2244*7c478bd9Sstevel@tonic-gate     return LDAP_SUCCESS;
2245*7c478bd9Sstevel@tonic-gate }
2246*7c478bd9Sstevel@tonic-gate 
2247*7c478bd9Sstevel@tonic-gate int
2248*7c478bd9Sstevel@tonic-gate ldaptool_gettokenname( void *context, char **tokennamep )
2249*7c478bd9Sstevel@tonic-gate {
2250*7c478bd9Sstevel@tonic-gate 
2251*7c478bd9Sstevel@tonic-gate     *tokennamep = pkcs_token;
2252*7c478bd9Sstevel@tonic-gate     if ( ldaptool_verbose ) {
2253*7c478bd9Sstevel@tonic-gate 	if (pkcs_token)
2254*7c478bd9Sstevel@tonic-gate 	{
2255*7c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_gettokenname -- %s\n"),*tokennamep);
2256*7c478bd9Sstevel@tonic-gate 	}
2257*7c478bd9Sstevel@tonic-gate 	else
2258*7c478bd9Sstevel@tonic-gate 	{
2259*7c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_gettokenname -- (null)\n"));
2260*7c478bd9Sstevel@tonic-gate 	}
2261*7c478bd9Sstevel@tonic-gate     }
2262*7c478bd9Sstevel@tonic-gate 
2263*7c478bd9Sstevel@tonic-gate     return LDAP_SUCCESS;
2264*7c478bd9Sstevel@tonic-gate }
2265*7c478bd9Sstevel@tonic-gate int
2266*7c478bd9Sstevel@tonic-gate ldaptool_gettokenpin( void *context, const char *tokennamep, char **tokenpinp)
2267*7c478bd9Sstevel@tonic-gate {
2268*7c478bd9Sstevel@tonic-gate 
2269*7c478bd9Sstevel@tonic-gate #if 0
2270*7c478bd9Sstevel@tonic-gate   char *localtoken;
2271*7c478bd9Sstevel@tonic-gate #endif
2272*7c478bd9Sstevel@tonic-gate 
2273*7c478bd9Sstevel@tonic-gate /* XXXceb this stuff is removed for the time being.
2274*7c478bd9Sstevel@tonic-gate  * This function should return the pin from ssl_password
2275*7c478bd9Sstevel@tonic-gate  */
2276*7c478bd9Sstevel@tonic-gate 
2277*7c478bd9Sstevel@tonic-gate 
2278*7c478bd9Sstevel@tonic-gate   *tokenpinp = ssl_passwd;
2279*7c478bd9Sstevel@tonic-gate   return LDAP_SUCCESS;
2280*7c478bd9Sstevel@tonic-gate 
2281*7c478bd9Sstevel@tonic-gate #if 0
2282*7c478bd9Sstevel@tonic-gate 
2283*7c478bd9Sstevel@tonic-gate   ldaptool_gettokenname( NULL, &localtoken);
2284*7c478bd9Sstevel@tonic-gate 
2285*7c478bd9Sstevel@tonic-gate   if (strcmp( localtoken, tokennamep))
2286*7c478bd9Sstevel@tonic-gate 
2287*7c478bd9Sstevel@tonic-gate       *tokenpinp = pkcs_pin;
2288*7c478bd9Sstevel@tonic-gate    else
2289*7c478bd9Sstevel@tonic-gate       *tokenpinp = NULL;
2290*7c478bd9Sstevel@tonic-gate 
2291*7c478bd9Sstevel@tonic-gate     if ( ldaptool_verbose ) {
2292*7c478bd9Sstevel@tonic-gate 	if (pkcs_pin)
2293*7c478bd9Sstevel@tonic-gate 	{
2294*7c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_getokenpin --%s\n"), tokenpinp);
2295*7c478bd9Sstevel@tonic-gate 	}
2296*7c478bd9Sstevel@tonic-gate 	else
2297*7c478bd9Sstevel@tonic-gate 	{
2298*7c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_getokenpin -- (null)\n"));
2299*7c478bd9Sstevel@tonic-gate 	}
2300*7c478bd9Sstevel@tonic-gate     }
2301*7c478bd9Sstevel@tonic-gate     return LDAP_SUCCESS;
2302*7c478bd9Sstevel@tonic-gate #endif
2303*7c478bd9Sstevel@tonic-gate }
2304*7c478bd9Sstevel@tonic-gate 
2305*7c478bd9Sstevel@tonic-gate int
2306*7c478bd9Sstevel@tonic-gate ldaptool_getmodpath( void *context, char **modulep )
2307*7c478bd9Sstevel@tonic-gate {
2308*7c478bd9Sstevel@tonic-gate     *modulep = ssl_secmodpath;
2309*7c478bd9Sstevel@tonic-gate     if ( ldaptool_verbose ) {
2310*7c478bd9Sstevel@tonic-gate 	if (ssl_secmodpath)
2311*7c478bd9Sstevel@tonic-gate 	{
2312*7c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_getmodpath -- %s\n"), *modulep);
2313*7c478bd9Sstevel@tonic-gate 	}
2314*7c478bd9Sstevel@tonic-gate 	else
2315*7c478bd9Sstevel@tonic-gate 	{
2316*7c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_getmodpath -- (null)\n"));
2317*7c478bd9Sstevel@tonic-gate 	}
2318*7c478bd9Sstevel@tonic-gate     }
2319*7c478bd9Sstevel@tonic-gate 
2320*7c478bd9Sstevel@tonic-gate     return LDAP_SUCCESS;
2321*7c478bd9Sstevel@tonic-gate }
2322*7c478bd9Sstevel@tonic-gate 
2323*7c478bd9Sstevel@tonic-gate int
2324*7c478bd9Sstevel@tonic-gate ldaptool_getdonglefilename( void *context, char **filename )
2325*7c478bd9Sstevel@tonic-gate {
2326*7c478bd9Sstevel@tonic-gate     *filename = ssl_donglefile;
2327*7c478bd9Sstevel@tonic-gate     if ( ldaptool_verbose ) {
2328*7c478bd9Sstevel@tonic-gate 	if (ssl_donglefile)
2329*7c478bd9Sstevel@tonic-gate 	{
2330*7c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_getdonglefilename -- %s\n"), *filename);
2331*7c478bd9Sstevel@tonic-gate 	}
2332*7c478bd9Sstevel@tonic-gate 	else
2333*7c478bd9Sstevel@tonic-gate 	{
2334*7c478bd9Sstevel@tonic-gate 	    printf(gettext("ldaptool_getdonglefilename -- (null)\n"));
2335*7c478bd9Sstevel@tonic-gate 	}
2336*7c478bd9Sstevel@tonic-gate 
2337*7c478bd9Sstevel@tonic-gate     }
2338*7c478bd9Sstevel@tonic-gate 
2339*7c478bd9Sstevel@tonic-gate     return LDAP_SUCCESS;
2340*7c478bd9Sstevel@tonic-gate }
2341*7c478bd9Sstevel@tonic-gate 
2342*7c478bd9Sstevel@tonic-gate static int
2343*7c478bd9Sstevel@tonic-gate ldaptool_setcallbacks( struct ldapssl_pkcs_fns *pfns)
2344*7c478bd9Sstevel@tonic-gate {
2345*7c478bd9Sstevel@tonic-gate   pfns->pkcs_getcertpath = (int (*)(void *, char **))ldaptool_getcertpath;
2346*7c478bd9Sstevel@tonic-gate   pfns->pkcs_getcertname =  (int (*)(void *, char **))ldaptool_getcertname;
2347*7c478bd9Sstevel@tonic-gate   pfns->pkcs_getkeypath =  (int (*)(void *, char **)) ldaptool_getkeypath;
2348*7c478bd9Sstevel@tonic-gate   pfns->pkcs_getmodpath =  (int (*)(void *, char **)) ldaptool_getmodpath;
2349*7c478bd9Sstevel@tonic-gate   pfns->pkcs_getpin =  (int (*)(void *, const char*, char **)) ldaptool_gettokenpin;
2350*7c478bd9Sstevel@tonic-gate   pfns->pkcs_gettokenname =  (int (*)(void *, char **)) ldaptool_gettokenname;
2351*7c478bd9Sstevel@tonic-gate   pfns->pkcs_getdonglefilename =  (int (*)(void *, char **)) ldaptool_getdonglefilename;
2352*7c478bd9Sstevel@tonic-gate   pfns->local_structure_id=PKCS_STRUCTURE_ID;
2353*7c478bd9Sstevel@tonic-gate   return LDAP_SUCCESS;
2354*7c478bd9Sstevel@tonic-gate }
2355*7c478bd9Sstevel@tonic-gate 
2356*7c478bd9Sstevel@tonic-gate 
2357*7c478bd9Sstevel@tonic-gate 
2358*7c478bd9Sstevel@tonic-gate #ifdef FORTEZZA
2359*7c478bd9Sstevel@tonic-gate static int
2360*7c478bd9Sstevel@tonic-gate ldaptool_fortezza_init( int exit_on_error )
2361*7c478bd9Sstevel@tonic-gate {
2362*7c478bd9Sstevel@tonic-gate     int		rc, errcode;
2363*7c478bd9Sstevel@tonic-gate 
2364*7c478bd9Sstevel@tonic-gate     if ( fortezza_personality == NULL && fortezza_cardmask == 0 ) { /* no FORTEZZA desired */
2365*7c478bd9Sstevel@tonic-gate 	SSL_EnableGroup( SSL_GroupFortezza, DSFalse );	/* disable FORTEZZA */
2366*7c478bd9Sstevel@tonic-gate 	return( 0 );
2367*7c478bd9Sstevel@tonic-gate     }
2368*7c478bd9Sstevel@tonic-gate 
2369*7c478bd9Sstevel@tonic-gate     if (( rc = FortezzaConfigureServer( ldaptool_fortezza_getpin, fortezza_cardmask,
2370*7c478bd9Sstevel@tonic-gate 	    fortezza_personality, ldaptool_fortezza_alert, NULL, &errcode,
2371*7c478bd9Sstevel@tonic-gate 	    fortezza_krlfile )) < 0 ) {
2372*7c478bd9Sstevel@tonic-gate 	fprintf( stderr,
2373*7c478bd9Sstevel@tonic-gate 		"%s: FORTEZZA initialization failed (error %d - %s)\n",
2374*7c478bd9Sstevel@tonic-gate 		ldaptool_progname, errcode,
2375*7c478bd9Sstevel@tonic-gate 		ldaptool_fortezza_err2string( errcode ));
2376*7c478bd9Sstevel@tonic-gate 	if ( exit_on_error ) {
2377*7c478bd9Sstevel@tonic-gate 	    exit( LDAP_LOCAL_ERROR );
2378*7c478bd9Sstevel@tonic-gate 	}
2379*7c478bd9Sstevel@tonic-gate 
2380*7c478bd9Sstevel@tonic-gate 	SSL_EnableGroup( SSL_GroupFortezza, DSFalse );	/* disable FORTEZZA */
2381*7c478bd9Sstevel@tonic-gate 	return( -1 );
2382*7c478bd9Sstevel@tonic-gate     }
2383*7c478bd9Sstevel@tonic-gate 
2384*7c478bd9Sstevel@tonic-gate     SSL_EnableGroup( SSL_GroupFortezza, DSTrue );	/* enable FORTEZZA */
2385*7c478bd9Sstevel@tonic-gate     return( 0 );
2386*7c478bd9Sstevel@tonic-gate }
2387*7c478bd9Sstevel@tonic-gate 
2388*7c478bd9Sstevel@tonic-gate 
2389*7c478bd9Sstevel@tonic-gate static int
2390*7c478bd9Sstevel@tonic-gate ldaptool_fortezza_alert( void *arg, PRBool onOpen, char *string,
2391*7c478bd9Sstevel@tonic-gate 	int value1, void *value2 )
2392*7c478bd9Sstevel@tonic-gate {
2393*7c478bd9Sstevel@tonic-gate     fprintf( stderr, "%s: FORTEZZA alert: ", ldaptool_progname );
2394*7c478bd9Sstevel@tonic-gate     fprintf( stderr, string, value1, value2 );
2395*7c478bd9Sstevel@tonic-gate     fprintf( stderr, "\n" );
2396*7c478bd9Sstevel@tonic-gate     return( 1 );
2397*7c478bd9Sstevel@tonic-gate }
2398*7c478bd9Sstevel@tonic-gate 
2399*7c478bd9Sstevel@tonic-gate 
2400*7c478bd9Sstevel@tonic-gate static void *
2401*7c478bd9Sstevel@tonic-gate ldaptool_fortezza_getpin( char **passwordp )
2402*7c478bd9Sstevel@tonic-gate {
2403*7c478bd9Sstevel@tonic-gate     *passwordp = fortezza_pin;
2404*7c478bd9Sstevel@tonic-gate     return( *passwordp );
2405*7c478bd9Sstevel@tonic-gate }
2406*7c478bd9Sstevel@tonic-gate 
2407*7c478bd9Sstevel@tonic-gate 
2408*7c478bd9Sstevel@tonic-gate /*
2409*7c478bd9Sstevel@tonic-gate  * convert a Fortezza error code (as returned by FortezzaConfigureServer()
2410*7c478bd9Sstevel@tonic-gate  * into a human-readable string.
2411*7c478bd9Sstevel@tonic-gate  *
2412*7c478bd9Sstevel@tonic-gate  * Error strings are intentionally similar to those found in
2413*7c478bd9Sstevel@tonic-gate  * ns/netsite/lib/libadmin/httpcon.c
2414*7c478bd9Sstevel@tonic-gate  */
2415*7c478bd9Sstevel@tonic-gate static char *
2416*7c478bd9Sstevel@tonic-gate ldaptool_fortezza_err2string( int err )
2417*7c478bd9Sstevel@tonic-gate {
2418*7c478bd9Sstevel@tonic-gate     char	*s;
2419*7c478bd9Sstevel@tonic-gate 
2420*7c478bd9Sstevel@tonic-gate     switch( err ) {
2421*7c478bd9Sstevel@tonic-gate     case FORTEZZA_BADPASSWD:
2422*7c478bd9Sstevel@tonic-gate 	s = "invalid pin number";
2423*7c478bd9Sstevel@tonic-gate 	break;
2424*7c478bd9Sstevel@tonic-gate     case FORTEZZA_BADCARD:
2425*7c478bd9Sstevel@tonic-gate 	s = "bad or missing card";
2426*7c478bd9Sstevel@tonic-gate 	break;
2427*7c478bd9Sstevel@tonic-gate     case FORTEZZA_MISSING_KRL:
2428*7c478bd9Sstevel@tonic-gate 	s = "bad or missing compromised key list";
2429*7c478bd9Sstevel@tonic-gate 	break;
2430*7c478bd9Sstevel@tonic-gate     case FORTEZZA_CERT_INIT_ERROR:
2431*7c478bd9Sstevel@tonic-gate 	s = "unable to initialize certificate cache.  either a cert on "
2432*7c478bd9Sstevel@tonic-gate 		"the card is bad, or an old FORTEZZA certificate is in a"
2433*7c478bd9Sstevel@tonic-gate 		 "readonly database";
2434*7c478bd9Sstevel@tonic-gate 	break;
2435*7c478bd9Sstevel@tonic-gate     case FORTEZZA_EXPIRED_CERT:
2436*7c478bd9Sstevel@tonic-gate 	s = "unable to verify certificate";
2437*7c478bd9Sstevel@tonic-gate 	break;
2438*7c478bd9Sstevel@tonic-gate     default:
2439*7c478bd9Sstevel@tonic-gate 	s = "unknown error";
2440*7c478bd9Sstevel@tonic-gate     }
2441*7c478bd9Sstevel@tonic-gate 
2442*7c478bd9Sstevel@tonic-gate     return( s );
2443*7c478bd9Sstevel@tonic-gate }
2444*7c478bd9Sstevel@tonic-gate 
2445*7c478bd9Sstevel@tonic-gate #endif /* FORTEZZA */
2446*7c478bd9Sstevel@tonic-gate #endif /* LDAP_TOOL_PKCS11 */
2447*7c478bd9Sstevel@tonic-gate #endif /* NET_SSL */
2448*7c478bd9Sstevel@tonic-gate 
2449*7c478bd9Sstevel@tonic-gate int
2450*7c478bd9Sstevel@tonic-gate ldaptool_boolean_str2value ( const char *ptr, int strict )
2451*7c478bd9Sstevel@tonic-gate {
2452*7c478bd9Sstevel@tonic-gate     if (strict) {
2453*7c478bd9Sstevel@tonic-gate 	if ( !(strcasecmp(ptr, "true"))) {
2454*7c478bd9Sstevel@tonic-gate 	    return 1;
2455*7c478bd9Sstevel@tonic-gate 	}
2456*7c478bd9Sstevel@tonic-gate 	else if ( !(strcasecmp(ptr, "false"))) {
2457*7c478bd9Sstevel@tonic-gate 	    return 0;
2458*7c478bd9Sstevel@tonic-gate 	}
2459*7c478bd9Sstevel@tonic-gate 	else {
2460*7c478bd9Sstevel@tonic-gate 	    return (-1);
2461*7c478bd9Sstevel@tonic-gate 	}
2462*7c478bd9Sstevel@tonic-gate     }
2463*7c478bd9Sstevel@tonic-gate     else {
2464*7c478bd9Sstevel@tonic-gate 	if ( !(strcasecmp(ptr, "true")) ||
2465*7c478bd9Sstevel@tonic-gate 	     !(strcasecmp(ptr, "t")) ||
2466*7c478bd9Sstevel@tonic-gate 	     !(strcmp(ptr, "1")) ) {
2467*7c478bd9Sstevel@tonic-gate 		return (1);
2468*7c478bd9Sstevel@tonic-gate 	}
2469*7c478bd9Sstevel@tonic-gate 	else if ( !(strcasecmp(ptr, "false")) ||
2470*7c478bd9Sstevel@tonic-gate 	     !(strcasecmp(ptr, "f")) ||
2471*7c478bd9Sstevel@tonic-gate 	     !(strcmp(ptr, "0")) ) {
2472*7c478bd9Sstevel@tonic-gate 	    	return (0);
2473*7c478bd9Sstevel@tonic-gate 	}
2474*7c478bd9Sstevel@tonic-gate 	else {
2475*7c478bd9Sstevel@tonic-gate 	    return (-1);
2476*7c478bd9Sstevel@tonic-gate 	}
2477*7c478bd9Sstevel@tonic-gate     }
2478*7c478bd9Sstevel@tonic-gate }
2479*7c478bd9Sstevel@tonic-gate 
2480*7c478bd9Sstevel@tonic-gate FILE *
2481*7c478bd9Sstevel@tonic-gate ldaptool_open_file(const char *filename, const char *mode)
2482*7c478bd9Sstevel@tonic-gate {
2483*7c478bd9Sstevel@tonic-gate #ifdef _LARGEFILE64_SOURCE
2484*7c478bd9Sstevel@tonic-gate 	return fopen64(filename, mode);
2485*7c478bd9Sstevel@tonic-gate #else
2486*7c478bd9Sstevel@tonic-gate 	return fopen(filename, mode);
2487*7c478bd9Sstevel@tonic-gate #endif
2488*7c478bd9Sstevel@tonic-gate }
2489*7c478bd9Sstevel@tonic-gate 
2490*7c478bd9Sstevel@tonic-gate #ifdef later
2491*7c478bd9Sstevel@tonic-gate /* Functions for list in ldapdelete.c */
2492*7c478bd9Sstevel@tonic-gate 
2493*7c478bd9Sstevel@tonic-gate void L_Init(Head *list)
2494*7c478bd9Sstevel@tonic-gate {
2495*7c478bd9Sstevel@tonic-gate     if(list)
2496*7c478bd9Sstevel@tonic-gate     {
2497*7c478bd9Sstevel@tonic-gate         list->first = NULL;
2498*7c478bd9Sstevel@tonic-gate         list->last = NULL;
2499*7c478bd9Sstevel@tonic-gate         list->count = 0;
2500*7c478bd9Sstevel@tonic-gate     }
2501*7c478bd9Sstevel@tonic-gate }
2502*7c478bd9Sstevel@tonic-gate 
2503*7c478bd9Sstevel@tonic-gate void L_Insert(Element *Node, Head *HeadNode)
2504*7c478bd9Sstevel@tonic-gate {
2505*7c478bd9Sstevel@tonic-gate     if (!Node || !HeadNode)
2506*7c478bd9Sstevel@tonic-gate         return;
2507*7c478bd9Sstevel@tonic-gate 
2508*7c478bd9Sstevel@tonic-gate     Node->right = NULL;
2509*7c478bd9Sstevel@tonic-gate 
2510*7c478bd9Sstevel@tonic-gate     if (HeadNode->first == NULL)
2511*7c478bd9Sstevel@tonic-gate     {
2512*7c478bd9Sstevel@tonic-gate         Node->left= NULL;
2513*7c478bd9Sstevel@tonic-gate         HeadNode->last = HeadNode->first = Node;
2514*7c478bd9Sstevel@tonic-gate     }
2515*7c478bd9Sstevel@tonic-gate     else
2516*7c478bd9Sstevel@tonic-gate     {
2517*7c478bd9Sstevel@tonic-gate         Node->left = HeadNode->last;
2518*7c478bd9Sstevel@tonic-gate         HeadNode->last = Node->left->right = Node;
2519*7c478bd9Sstevel@tonic-gate     }
2520*7c478bd9Sstevel@tonic-gate     HeadNode->count++;
2521*7c478bd9Sstevel@tonic-gate }
2522*7c478bd9Sstevel@tonic-gate 
2523*7c478bd9Sstevel@tonic-gate void L_Remove(Element *Node, Head *HeadNode)
2524*7c478bd9Sstevel@tonic-gate {
2525*7c478bd9Sstevel@tonic-gate     Element *traverse = NULL;
2526*7c478bd9Sstevel@tonic-gate     Element *prevnode = NULL;
2527*7c478bd9Sstevel@tonic-gate 
2528*7c478bd9Sstevel@tonic-gate     if(!Node || !HeadNode)
2529*7c478bd9Sstevel@tonic-gate         return;
2530*7c478bd9Sstevel@tonic-gate 
2531*7c478bd9Sstevel@tonic-gate     for(traverse = HeadNode->first; traverse; traverse = traverse->right)
2532*7c478bd9Sstevel@tonic-gate     {
2533*7c478bd9Sstevel@tonic-gate         if(traverse == Node)
2534*7c478bd9Sstevel@tonic-gate         {
2535*7c478bd9Sstevel@tonic-gate             if(HeadNode->first == traverse)
2536*7c478bd9Sstevel@tonic-gate             {
2537*7c478bd9Sstevel@tonic-gate                 HeadNode->first = traverse->right;
2538*7c478bd9Sstevel@tonic-gate             }
2539*7c478bd9Sstevel@tonic-gate             if(HeadNode->last == traverse)
2540*7c478bd9Sstevel@tonic-gate             {
2541*7c478bd9Sstevel@tonic-gate                 HeadNode->last = prevnode;
2542*7c478bd9Sstevel@tonic-gate             }
2543*7c478bd9Sstevel@tonic-gate             traverse = traverse->right;
2544*7c478bd9Sstevel@tonic-gate             if(prevnode != NULL)
2545*7c478bd9Sstevel@tonic-gate             {
2546*7c478bd9Sstevel@tonic-gate                 prevnode->right = traverse;
2547*7c478bd9Sstevel@tonic-gate             }
2548*7c478bd9Sstevel@tonic-gate             if(traverse != NULL)
2549*7c478bd9Sstevel@tonic-gate             {
2550*7c478bd9Sstevel@tonic-gate                 traverse->left = prevnode;
2551*7c478bd9Sstevel@tonic-gate             }
2552*7c478bd9Sstevel@tonic-gate             HeadNode->count--;
2553*7c478bd9Sstevel@tonic-gate             return;
2554*7c478bd9Sstevel@tonic-gate         }
2555*7c478bd9Sstevel@tonic-gate         else /* traverse != node */
2556*7c478bd9Sstevel@tonic-gate         {
2557*7c478bd9Sstevel@tonic-gate             prevnode = traverse;
2558*7c478bd9Sstevel@tonic-gate         }
2559*7c478bd9Sstevel@tonic-gate     }
2560*7c478bd9Sstevel@tonic-gate }
2561*7c478bd9Sstevel@tonic-gate #endif
2562*7c478bd9Sstevel@tonic-gate 
2563*7c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
2564*7c478bd9Sstevel@tonic-gate /*
2565*7c478bd9Sstevel@tonic-gate  * Function checks for valid args, returns an error if not found
2566*7c478bd9Sstevel@tonic-gate  * and sets SASL params from command line
2567*7c478bd9Sstevel@tonic-gate  */
2568*7c478bd9Sstevel@tonic-gate 
2569*7c478bd9Sstevel@tonic-gate static int
2570*7c478bd9Sstevel@tonic-gate saslSetParam(char *saslarg)
2571*7c478bd9Sstevel@tonic-gate {
2572*7c478bd9Sstevel@tonic-gate 	char *attr = NULL;
2573*7c478bd9Sstevel@tonic-gate 
2574*7c478bd9Sstevel@tonic-gate 	attr = strchr(saslarg, '=');
2575*7c478bd9Sstevel@tonic-gate 	if (attr == NULL) {
2576*7c478bd9Sstevel@tonic-gate            fprintf( stderr, gettext("Didn't find \"=\" character in %s\n"), saslarg);
2577*7c478bd9Sstevel@tonic-gate            return (-1);
2578*7c478bd9Sstevel@tonic-gate 	}
2579*7c478bd9Sstevel@tonic-gate 	*attr = '\0';
2580*7c478bd9Sstevel@tonic-gate 	attr++;
2581*7c478bd9Sstevel@tonic-gate 
2582*7c478bd9Sstevel@tonic-gate 	if (!strcasecmp(saslarg, "secProp")) {
2583*7c478bd9Sstevel@tonic-gate 	     if ( sasl_secprops != NULL ) {
2584*7c478bd9Sstevel@tonic-gate                 fprintf( stderr, gettext("secProp previously specified\n"));
2585*7c478bd9Sstevel@tonic-gate                 return (-1);
2586*7c478bd9Sstevel@tonic-gate              }
2587*7c478bd9Sstevel@tonic-gate              if (( sasl_secprops = strdup(attr)) == NULL ) {
2588*7c478bd9Sstevel@tonic-gate 		perror ("malloc");
2589*7c478bd9Sstevel@tonic-gate                 exit (LDAP_NO_MEMORY);
2590*7c478bd9Sstevel@tonic-gate              }
2591*7c478bd9Sstevel@tonic-gate 	} else if (!strcasecmp(saslarg, "realm")) {
2592*7c478bd9Sstevel@tonic-gate 	     if ( sasl_realm != NULL ) {
2593*7c478bd9Sstevel@tonic-gate                 fprintf( stderr, gettext("Realm previously specified\n"));
2594*7c478bd9Sstevel@tonic-gate                 return (-1);
2595*7c478bd9Sstevel@tonic-gate              }
2596*7c478bd9Sstevel@tonic-gate              if (( sasl_realm = strdup(attr)) == NULL ) {
2597*7c478bd9Sstevel@tonic-gate 		perror ("malloc");
2598*7c478bd9Sstevel@tonic-gate                 exit (LDAP_NO_MEMORY);
2599*7c478bd9Sstevel@tonic-gate              }
2600*7c478bd9Sstevel@tonic-gate 	} else if (!strcasecmp(saslarg, "authzid")) {
2601*7c478bd9Sstevel@tonic-gate              if (sasl_username != NULL) {
2602*7c478bd9Sstevel@tonic-gate                 fprintf( stderr, gettext("Authorization name previously specified\n"));
2603*7c478bd9Sstevel@tonic-gate                 return (-1);
2604*7c478bd9Sstevel@tonic-gate              }
2605*7c478bd9Sstevel@tonic-gate              if (( sasl_username = strdup(attr)) == NULL ) {
2606*7c478bd9Sstevel@tonic-gate 		perror ("malloc");
2607*7c478bd9Sstevel@tonic-gate                 exit (LDAP_NO_MEMORY);
2608*7c478bd9Sstevel@tonic-gate              }
2609*7c478bd9Sstevel@tonic-gate 	} else if (!strcasecmp(saslarg, "authid")) {
2610*7c478bd9Sstevel@tonic-gate              if ( sasl_authid != NULL ) {
2611*7c478bd9Sstevel@tonic-gate                 fprintf( stderr, gettext("Authentication name previously specified\n"));
2612*7c478bd9Sstevel@tonic-gate                 return (-1);
2613*7c478bd9Sstevel@tonic-gate              }
2614*7c478bd9Sstevel@tonic-gate              if (( sasl_authid = strdup(attr)) == NULL) {
2615*7c478bd9Sstevel@tonic-gate 		perror ("malloc");
2616*7c478bd9Sstevel@tonic-gate                 exit (LDAP_NO_MEMORY);
2617*7c478bd9Sstevel@tonic-gate              }
2618*7c478bd9Sstevel@tonic-gate 	} else if (!strcasecmp(saslarg, "mech")) {
2619*7c478bd9Sstevel@tonic-gate 	     if ( sasl_mech != NULL ) {
2620*7c478bd9Sstevel@tonic-gate                 fprintf( stderr, gettext("Mech previously specified\n"));
2621*7c478bd9Sstevel@tonic-gate                 return (-1);
2622*7c478bd9Sstevel@tonic-gate              }
2623*7c478bd9Sstevel@tonic-gate 	     if (( sasl_mech = strdup(attr)) == NULL) {
2624*7c478bd9Sstevel@tonic-gate 		perror ("malloc");
2625*7c478bd9Sstevel@tonic-gate 		exit (LDAP_NO_MEMORY);
2626*7c478bd9Sstevel@tonic-gate 	     }
2627*7c478bd9Sstevel@tonic-gate 	} else {
2628*7c478bd9Sstevel@tonic-gate 	     fprintf (stderr, gettext("Invalid attribute name %s\n"), saslarg);
2629*7c478bd9Sstevel@tonic-gate 	     return (-1);
2630*7c478bd9Sstevel@tonic-gate 	}
2631*7c478bd9Sstevel@tonic-gate 	return 0;
2632*7c478bd9Sstevel@tonic-gate }
2633*7c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
2634