10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate /*
230Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
280Sstevel@tonic-gate 
290Sstevel@tonic-gate /*
300Sstevel@tonic-gate  * ldapclient command. To make (initiailize) or uninitialize a machines as
310Sstevel@tonic-gate  * and LDAP client.  This command MUST be run as root (or it will simply exit).
320Sstevel@tonic-gate  *
330Sstevel@tonic-gate  *	-I	Install. No file_backup/recover for installing only (no doc).
340Sstevel@tonic-gate  *
350Sstevel@tonic-gate  *	init	Initialze (create) an LDAP client from a profile stored
360Sstevel@tonic-gate  *		in a directory-server.
370Sstevel@tonic-gate  *	manual	Initialze (create) an LDAP client by hand (-file option
380Sstevel@tonic-gate  *		reads from file).
390Sstevel@tonic-gate  *	mod	Modify the LDAP client configuration on this machine by hand.
400Sstevel@tonic-gate  *	list	List the contents of the LDAP client cache files.
410Sstevel@tonic-gate  *	uninit	Uninitialize this machine.
420Sstevel@tonic-gate  *
430Sstevel@tonic-gate  *	-v	Verbose flag.
440Sstevel@tonic-gate  *	-q	Quiet flag (mutually exclusive with -v).
450Sstevel@tonic-gate  *
460Sstevel@tonic-gate  *	-a attrName=attrVal
470Sstevel@tonic-gate  *	<attrName> can be one of the following:
480Sstevel@tonic-gate  *
490Sstevel@tonic-gate  *	attributeMap
500Sstevel@tonic-gate  *		Attribute map.  Can be multiple instances of this option.
510Sstevel@tonic-gate  *		(no former option)
520Sstevel@tonic-gate  *	authenticationMethod
530Sstevel@tonic-gate  *		Authentication method (formerly -a)
540Sstevel@tonic-gate  *	bindTimeLimit
550Sstevel@tonic-gate  *		Bind time limit. (no former option)
560Sstevel@tonic-gate  *	certificatePath
570Sstevel@tonic-gate  *		Path to certificates used for secure bind (no former option)
580Sstevel@tonic-gate  *	credentialLevel
590Sstevel@tonic-gate  *		Client credential level (no former option)
600Sstevel@tonic-gate  *	defaultServerList
610Sstevel@tonic-gate  *		Default server (no former option) Refer to DUA Config
620Sstevel@tonic-gate  *		Schema draft.
630Sstevel@tonic-gate  *	defaultSearchBase
640Sstevel@tonic-gate  *		Search Base DN. e.g. dc=eng,dc=sun,dc=com (formerly -b)
650Sstevel@tonic-gate  *	defaultSearchScope
660Sstevel@tonic-gate  *		Search scope. (formerly -s)
670Sstevel@tonic-gate  *	domainName
680Sstevel@tonic-gate  *		Hosts lookup domain (DNS)  Ex. eng.sun.com (formerly -d)
690Sstevel@tonic-gate  *	followReferrals
700Sstevel@tonic-gate  *		Search dereference. followref or noref (default followref)
710Sstevel@tonic-gate  *		(formerly -r)
720Sstevel@tonic-gate  *	objectclassMap
730Sstevel@tonic-gate  *		Objectclass map.  Can be multiple instances of this option.
740Sstevel@tonic-gate  *		(no former option)
750Sstevel@tonic-gate  *	preferredServerList
760Sstevel@tonic-gate  *		Server preference list. Comma ',' seperated list of IPaddr.
770Sstevel@tonic-gate  *		(formerly -p)
780Sstevel@tonic-gate  *	profileName
790Sstevel@tonic-gate  *		Profile name to use for init (ldapclient) or
800Sstevel@tonic-gate  *		generate (gen_profile). (formerly -P)
810Sstevel@tonic-gate  *	profileTTL
820Sstevel@tonic-gate  *		Client info TTL.  If set to 0 this information will not be
830Sstevel@tonic-gate  *		automatically updated by the ldap_cachemgr(1M).
840Sstevel@tonic-gate  *		(formerly -e)
850Sstevel@tonic-gate  *	proxyDN
860Sstevel@tonic-gate  *		Binding DN.  Ex. cn=client,ou=people,cd=eng,dc=sun,dc=com
870Sstevel@tonic-gate  *		(formerly -D)
880Sstevel@tonic-gate  *	proxyPassword
890Sstevel@tonic-gate  *		Client password not needed for authentication "none".
900Sstevel@tonic-gate  *		(formerly -w)
910Sstevel@tonic-gate  *	searchTimeLimit
920Sstevel@tonic-gate  *		Timeout value. (formerly -o)
930Sstevel@tonic-gate  *	serviceSearchDescriptor
940Sstevel@tonic-gate  *		Service search scope. (no former option)
950Sstevel@tonic-gate  *	serviceAuthenticationMethod
960Sstevel@tonic-gate  *		Service authenticaion method (no former option)
970Sstevel@tonic-gate  *	serviceCredentialLevel
980Sstevel@tonic-gate  *		Service credential level (no former option)
990Sstevel@tonic-gate  *
1000Sstevel@tonic-gate  */
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate #include <stdlib.h>
1030Sstevel@tonic-gate #include <stdio.h>
1040Sstevel@tonic-gate #include <unistd.h>
1050Sstevel@tonic-gate #include <errno.h>
1060Sstevel@tonic-gate #include <sys/types.h>
1070Sstevel@tonic-gate #include <time.h>
1080Sstevel@tonic-gate #include <sys/param.h>
1090Sstevel@tonic-gate #include <sys/stat.h>
1100Sstevel@tonic-gate #include <sys/systeminfo.h>
1110Sstevel@tonic-gate #include <fcntl.h>
1120Sstevel@tonic-gate #include <xti.h>
1130Sstevel@tonic-gate #include <strings.h>
1140Sstevel@tonic-gate #include <limits.h>
1150Sstevel@tonic-gate #include <locale.h>
1160Sstevel@tonic-gate #include <syslog.h>
1170Sstevel@tonic-gate #include "../../../lib/libsldap/common/ns_sldap.h"
1180Sstevel@tonic-gate #include <libscf.h>
1190Sstevel@tonic-gate #include <assert.h>
1200Sstevel@tonic-gate /*
1210Sstevel@tonic-gate  * We need ns_internal.h for the #defines of:
1220Sstevel@tonic-gate  *	NSCREDFILE, NSCONFIGFILE
1230Sstevel@tonic-gate  * and the function prototypes of:
1240Sstevel@tonic-gate  *	__ns_ldap_setServer(), __ns_ldap_LoadConfiguration(),
1250Sstevel@tonic-gate  *	__ns_ldap_DumpConfiguration(), __ns_ldap_DumpLdif()
1260Sstevel@tonic-gate  */
1270Sstevel@tonic-gate #include "../../../lib/libsldap/common/ns_internal.h"
1280Sstevel@tonic-gate 
1290Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
1300Sstevel@tonic-gate #define	TEXT_DOMAIN "SUNW_OST_OSCMD"
1310Sstevel@tonic-gate #endif
1320Sstevel@tonic-gate 
1330Sstevel@tonic-gate /* error codes */
1340Sstevel@tonic-gate /* The manpage doc only allows for SUCCESS(0), FAIL(1) and CRED(2) on exit */
1350Sstevel@tonic-gate #define	CLIENT_SUCCESS		0
1360Sstevel@tonic-gate #define	CLIENT_ERR_PARSE	-1
1370Sstevel@tonic-gate #define	CLIENT_ERR_FAIL		1
1380Sstevel@tonic-gate #define	CLIENT_ERR_CREDENTIAL	2
1390Sstevel@tonic-gate #define	CLIENT_ERR_MEMORY	3
1400Sstevel@tonic-gate #define	CLIENT_ERR_RESTORE	4
1410Sstevel@tonic-gate #define	CLIENT_ERR_RENAME	5
1420Sstevel@tonic-gate #define	CLIENT_ERR_RECOVER	6
1430Sstevel@tonic-gate #define	CLIENT_ERR_TIMEDOUT	7
1440Sstevel@tonic-gate #define	CLIENT_ERR_MAINTENANCE	8
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate /* Reset flag for start_services() */
1470Sstevel@tonic-gate #define	START_INIT	1
1480Sstevel@tonic-gate #define	START_RESET	2
1490Sstevel@tonic-gate #define	START_UNINIT	3
1500Sstevel@tonic-gate 
1510Sstevel@tonic-gate /* Reset flag for stop_services() */
1520Sstevel@tonic-gate #define	STATE_NOSAVE	0
1530Sstevel@tonic-gate #define	STATE_SAVE	1
1540Sstevel@tonic-gate 
1550Sstevel@tonic-gate /* files to (possibiliy) restore */
1560Sstevel@tonic-gate #define	LDAP_RESTORE_DIR	"/var/ldap/restore"
1570Sstevel@tonic-gate 
1580Sstevel@tonic-gate #define	DOMAINNAME_DIR		"/etc"
1590Sstevel@tonic-gate #define	DOMAINNAME_FILE		"defaultdomain"
1600Sstevel@tonic-gate #define	DOMAINNAME		DOMAINNAME_DIR "/" DOMAINNAME_FILE
1610Sstevel@tonic-gate #define	DOMAINNAME_BACK		LDAP_RESTORE_DIR "/" DOMAINNAME_FILE
1620Sstevel@tonic-gate 
1630Sstevel@tonic-gate #define	NSSWITCH_DIR		"/etc"
1640Sstevel@tonic-gate #define	NSSWITCH_FILE		"nsswitch.conf"
1650Sstevel@tonic-gate #define	NSSWITCH_CONF		NSSWITCH_DIR "/" NSSWITCH_FILE
1660Sstevel@tonic-gate #define	NSSWITCH_BACK		LDAP_RESTORE_DIR "/" NSSWITCH_FILE
1670Sstevel@tonic-gate #define	NSSWITCH_LDAP		"/etc/nsswitch.ldap"
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate #define	NIS_COLDSTART_DIR	"/var/nis"
1700Sstevel@tonic-gate #define	NIS_COLDSTART_FILE	"NIS_COLD_START"
1710Sstevel@tonic-gate #define	NIS_COLDSTART		NIS_COLDSTART_DIR "/" NIS_COLDSTART_FILE
1720Sstevel@tonic-gate #define	NIS_COLDSTART_BACK	LDAP_RESTORE_DIR "/" NIS_COLDSTART_FILE
1730Sstevel@tonic-gate 
1740Sstevel@tonic-gate #define	YP_BIND_DIR		"/var/yp/binding"
1750Sstevel@tonic-gate 
1760Sstevel@tonic-gate /* Define the service FMRIs */
1770Sstevel@tonic-gate #define	SENDMAIL_FMRI		"network/smtp:sendmail"
1780Sstevel@tonic-gate #define	NSCD_FMRI		"system/name-service-cache:default"
1790Sstevel@tonic-gate #define	AUTOFS_FMRI		"system/filesystem/autofs:default"
1800Sstevel@tonic-gate #define	LDAP_FMRI		"network/ldap/client:default"
1810Sstevel@tonic-gate #define	NISD_FMRI		"network/rpc/nisplus:default"
1820Sstevel@tonic-gate #define	YP_FMRI			"network/nis/client:default"
1830Sstevel@tonic-gate #define	NS_MILESTONE_FMRI	"milestone/name-services:default"
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate /* Define flags for checking if services were enabled */
1860Sstevel@tonic-gate #define	SENDMAIL_ON	0x1
1870Sstevel@tonic-gate #define	NSCD_ON		0x10
1880Sstevel@tonic-gate #define	AUTOFS_ON	0x100
1890Sstevel@tonic-gate 
1900Sstevel@tonic-gate #define	CMD_DOMAIN_START	"/usr/bin/domainname"
1910Sstevel@tonic-gate 
1920Sstevel@tonic-gate /* Command to copy files */
1930Sstevel@tonic-gate #define	CMD_CP			"/bin/cp -f"
1940Sstevel@tonic-gate #define	CMD_MV			"/bin/mv -f"
1950Sstevel@tonic-gate #define	CMD_RM			"/bin/rm -f"
1960Sstevel@tonic-gate 
1970Sstevel@tonic-gate #define	TO_DEV_NULL		" >/dev/null 2>&1"
1980Sstevel@tonic-gate 
1990Sstevel@tonic-gate /* Files that need to be just removed */
2000Sstevel@tonic-gate #define	NIS_PRIVATE_CACHE	"/var/nis/.NIS_PRIVATE_DIRCACHE"
2010Sstevel@tonic-gate #define	NIS_SHARED_CACHE	"/var/nis/NIS_SHARED_DIRCACHE"
2020Sstevel@tonic-gate #define	NIS_CLIENT_INFO		"/var/nis/client_info"
2030Sstevel@tonic-gate #define	LDAP_CACHE_LOG		"/var/ldap/cachemgr.log"
2040Sstevel@tonic-gate 
2050Sstevel@tonic-gate /* Output defines to supress if quiet mode set */
2060Sstevel@tonic-gate #define	CLIENT_FPUTS if (!mode_quiet) (void) fputs
2070Sstevel@tonic-gate #define	CLIENT_FPRINTF if (!mode_quiet) (void) fprintf
2080Sstevel@tonic-gate #define	CLIENT_FPUTC if (!mode_quiet) (void) fputc
2090Sstevel@tonic-gate 
2100Sstevel@tonic-gate #define	restart_service(fmri, waitflag)\
2110Sstevel@tonic-gate 		do_service(fmri, waitflag, RESTART_SERVICE,\
2120Sstevel@tonic-gate 		SCF_STATE_STRING_ONLINE)
2130Sstevel@tonic-gate #define	start_service(fmri, waitflag)	\
2140Sstevel@tonic-gate 		do_service(fmri, waitflag, START_SERVICE,\
2150Sstevel@tonic-gate 		SCF_STATE_STRING_ONLINE)
2160Sstevel@tonic-gate #define	disable_service(fmri, waitflag)	\
2170Sstevel@tonic-gate 		do_service(fmri, waitflag, STOP_SERVICE,\
2180Sstevel@tonic-gate 		SCF_STATE_STRING_DISABLED)
2190Sstevel@tonic-gate 
2200Sstevel@tonic-gate /*
2210Sstevel@tonic-gate  * There isn't a domainName defined as a param, so we set a value here
2220Sstevel@tonic-gate  * (1001) should be big enough
2230Sstevel@tonic-gate  */
2240Sstevel@tonic-gate #define	LOCAL_DOMAIN_P 1001
2250Sstevel@tonic-gate 
2260Sstevel@tonic-gate #define	START_SERVICE	1
2270Sstevel@tonic-gate #define	STOP_SERVICE	2
2280Sstevel@tonic-gate #define	RESTART_SERVICE	3
2290Sstevel@tonic-gate 
2300Sstevel@tonic-gate #define	DEFAULT_TIMEOUT	60000000
2310Sstevel@tonic-gate 
2320Sstevel@tonic-gate #define	INIT_WAIT_USECS	50000
2330Sstevel@tonic-gate 
2340Sstevel@tonic-gate /* Used to turn off profile checking */
2350Sstevel@tonic-gate #define	CACHETTL_OFF "0"
2360Sstevel@tonic-gate 
2370Sstevel@tonic-gate /* Globals */
2380Sstevel@tonic-gate static char *cmd;
2390Sstevel@tonic-gate 
2400Sstevel@tonic-gate static char *dname = NULL;
2410Sstevel@tonic-gate static char dname_buf[BUFSIZ];
2420Sstevel@tonic-gate 
2430Sstevel@tonic-gate static boolean_t sysid_install = B_FALSE;
2440Sstevel@tonic-gate 
2450Sstevel@tonic-gate static int mode_verbose = 0;
2460Sstevel@tonic-gate static int mode_quiet = 0;
2470Sstevel@tonic-gate static int gen = 0;
2480Sstevel@tonic-gate 
2490Sstevel@tonic-gate static int gStartLdap = 0;
2500Sstevel@tonic-gate static int gStartYp = 0;
2510Sstevel@tonic-gate static int gStartNisd = 0;
2520Sstevel@tonic-gate 
2530Sstevel@tonic-gate static int enableFlag = 0;
2540Sstevel@tonic-gate 
2550Sstevel@tonic-gate /* multival_t is used to hold params that can have more than one value */
2560Sstevel@tonic-gate typedef struct {
2570Sstevel@tonic-gate 	int count;
2580Sstevel@tonic-gate 	char **optlist;
2590Sstevel@tonic-gate } multival_t;
2600Sstevel@tonic-gate 
2610Sstevel@tonic-gate static multival_t *multival_new();
2620Sstevel@tonic-gate static int multival_add(multival_t *list, char *opt);
2630Sstevel@tonic-gate static void multival_free(multival_t *list);
2640Sstevel@tonic-gate 
2650Sstevel@tonic-gate /*
2660Sstevel@tonic-gate  * clientopts_t is used to hold and pass around the param values from
2670Sstevel@tonic-gate  * the cmd line
2680Sstevel@tonic-gate  */
2690Sstevel@tonic-gate typedef struct {
2700Sstevel@tonic-gate 	multival_t	*attributeMap;
2710Sstevel@tonic-gate 	char		*authenticationMethod;
2720Sstevel@tonic-gate 	char		*bindTimeLimit;
2730Sstevel@tonic-gate 	char		*certificatePath;
2740Sstevel@tonic-gate 	char		*credentialLevel;
2750Sstevel@tonic-gate 	char		*defaultSearchBase;
2760Sstevel@tonic-gate 	char		*defaultServerList;
2770Sstevel@tonic-gate 	char		*domainName;
2780Sstevel@tonic-gate 	char		*followReferrals;
2790Sstevel@tonic-gate 	multival_t	*objectclassMap;
2800Sstevel@tonic-gate 	char		*preferredServerList;
2810Sstevel@tonic-gate 	char		*profileName;
2820Sstevel@tonic-gate 	char		*profileTTL;
2830Sstevel@tonic-gate 	char		*proxyDN;
2840Sstevel@tonic-gate 	char		*proxyPassword;
2850Sstevel@tonic-gate 	char		*defaultSearchScope;
2860Sstevel@tonic-gate 	char		*searchTimeLimit;
2870Sstevel@tonic-gate 	multival_t	*serviceAuthenticationMethod;
2880Sstevel@tonic-gate 	multival_t	*serviceCredentialLevel;
2890Sstevel@tonic-gate 	multival_t	*serviceSearchDescriptor;
2900Sstevel@tonic-gate } clientopts_t;
2910Sstevel@tonic-gate 
2920Sstevel@tonic-gate static clientopts_t *clientopts_new();
2930Sstevel@tonic-gate static void clientopts_free(clientopts_t *list);
2940Sstevel@tonic-gate 
2950Sstevel@tonic-gate extern ns_ldap_error_t *__ns_ldap_print_config(int);
2960Sstevel@tonic-gate extern void __ns_ldap_default_config();
2970Sstevel@tonic-gate extern int __ns_ldap_download(char *, char *, char *, ns_ldap_error_t **);
2980Sstevel@tonic-gate 
2990Sstevel@tonic-gate /* Function prototypes (these could be static) */
3000Sstevel@tonic-gate static void usage(void);
3010Sstevel@tonic-gate 
3020Sstevel@tonic-gate static int credCheck(clientopts_t *arglist);
3030Sstevel@tonic-gate static char *findBaseDN(char *);
3040Sstevel@tonic-gate static int clientSetParam(clientopts_t *optlist, int paramFlag, char *attrVal);
3050Sstevel@tonic-gate static int parseParam(char *param, char **paramVal);
3060Sstevel@tonic-gate static void dumpargs(clientopts_t *arglist);
3070Sstevel@tonic-gate static int num_args(clientopts_t *arglist);
3080Sstevel@tonic-gate 
3090Sstevel@tonic-gate static int file_backup(void);
3100Sstevel@tonic-gate static int recover(int saveState);
3110Sstevel@tonic-gate static int mod_backup(void);
3120Sstevel@tonic-gate static int mod_recover(void);
3130Sstevel@tonic-gate static void mod_cleanup(void);
3140Sstevel@tonic-gate 
3150Sstevel@tonic-gate static int client_list(clientopts_t *arglist);
3160Sstevel@tonic-gate static int client_manual(clientopts_t *arglist);
3170Sstevel@tonic-gate static int client_mod(clientopts_t *arglist);
3180Sstevel@tonic-gate static int client_uninit(clientopts_t *arglist);
3190Sstevel@tonic-gate static int client_genProfile(clientopts_t *arglist);
3200Sstevel@tonic-gate static int client_init(clientopts_t *arglist);
3210Sstevel@tonic-gate static boolean_t is_config_ok(const clientopts_t *list, boolean_t get_config);
3220Sstevel@tonic-gate static int file_move(const char *from, const char *to);
3230Sstevel@tonic-gate 
3240Sstevel@tonic-gate static int start_services(int flag);
3250Sstevel@tonic-gate static int stop_services(int saveState);
3260Sstevel@tonic-gate static boolean_t is_service(const char *fmri, const char *state);
3270Sstevel@tonic-gate static int wait_till(const char *fmri, const char *state, useconds_t max,
3280Sstevel@tonic-gate 		const char *what, boolean_t check_maint);
3290Sstevel@tonic-gate static int do_service(const char *fmri, boolean_t waitflag, int dowhat,
3300Sstevel@tonic-gate 		const char *state);
3310Sstevel@tonic-gate static useconds_t get_timeout_value(int dowhat, const char *fmri,
3320Sstevel@tonic-gate 		useconds_t default_val);
3330Sstevel@tonic-gate 
334*702Sth160488 int
335*702Sth160488 main(int argc, char **argv)
3360Sstevel@tonic-gate {
3370Sstevel@tonic-gate 	char *ret_locale, *ret_textdomain;
3380Sstevel@tonic-gate 	int retcode;
3390Sstevel@tonic-gate 	int paramFlag;
3400Sstevel@tonic-gate 	char *attrVal;
3410Sstevel@tonic-gate 	int sysinfostatus;
3420Sstevel@tonic-gate 	clientopts_t *optlist = NULL;
3430Sstevel@tonic-gate 	int op_manual = 0, op_mod = 0, op_uninit = 0;
3440Sstevel@tonic-gate 	int op_list = 0, op_init = 0, op_genprofile = 0;
3450Sstevel@tonic-gate 	extern char *optarg;
3460Sstevel@tonic-gate 	extern int optind;
3470Sstevel@tonic-gate 	int option;
3480Sstevel@tonic-gate 
3490Sstevel@tonic-gate 
3500Sstevel@tonic-gate 	ret_locale = setlocale(LC_ALL, "");
3510Sstevel@tonic-gate 	if (ret_locale == NULL) {
3520Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Unable to set locale.\n"), stderr);
3530Sstevel@tonic-gate 	}
3540Sstevel@tonic-gate 	ret_textdomain = textdomain(TEXT_DOMAIN);
3550Sstevel@tonic-gate 	if (ret_textdomain == NULL) {
3560Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Unable to set textdomain.\n"), stderr);
3570Sstevel@tonic-gate 	}
3580Sstevel@tonic-gate 
3590Sstevel@tonic-gate 	openlog("ldapclient", LOG_PID, LOG_USER);
3600Sstevel@tonic-gate 
3610Sstevel@tonic-gate 	/* get name that invoked us */
3620Sstevel@tonic-gate 	if (cmd = strrchr(argv[0], '/'))
3630Sstevel@tonic-gate 		++cmd;
3640Sstevel@tonic-gate 	else
3650Sstevel@tonic-gate 		cmd = argv[0];
3660Sstevel@tonic-gate 
3670Sstevel@tonic-gate 	sysinfostatus = sysinfo(SI_SRPC_DOMAIN, dname_buf, BUFSIZ);
3680Sstevel@tonic-gate 	if (0 < sysinfostatus)
3690Sstevel@tonic-gate 		dname = &dname_buf[0];
3700Sstevel@tonic-gate 
3710Sstevel@tonic-gate 	optlist = clientopts_new();
3720Sstevel@tonic-gate 	if (optlist == NULL) {
3730Sstevel@tonic-gate 		CLIENT_FPUTS(
3740Sstevel@tonic-gate 			gettext("Error getting optlist (malloc fail)\n"),
3750Sstevel@tonic-gate 			stderr);
3760Sstevel@tonic-gate 		exit(CLIENT_ERR_FAIL);
3770Sstevel@tonic-gate 	}
3780Sstevel@tonic-gate 
3790Sstevel@tonic-gate 	optind = 1;
3800Sstevel@tonic-gate 	while (optind < argc) {
3810Sstevel@tonic-gate 		option = getopt(argc, argv, "vqa:I");
3820Sstevel@tonic-gate 
3830Sstevel@tonic-gate 		switch (option) {
3840Sstevel@tonic-gate 		case 'v':
3850Sstevel@tonic-gate 			mode_verbose = 1;
3860Sstevel@tonic-gate 			break;
3870Sstevel@tonic-gate 		case 'q':
3880Sstevel@tonic-gate 			mode_quiet = 1;
3890Sstevel@tonic-gate 			break;
3900Sstevel@tonic-gate 		case 'a':
3910Sstevel@tonic-gate 			attrVal = NULL;
3920Sstevel@tonic-gate 			paramFlag = parseParam(optarg, &attrVal);
3930Sstevel@tonic-gate 			if (paramFlag == CLIENT_ERR_PARSE) {
3940Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
3950Sstevel@tonic-gate 					gettext("Unrecognized "
3960Sstevel@tonic-gate 						"parameter \"%s\"\n"),
3970Sstevel@tonic-gate 					optarg);
3980Sstevel@tonic-gate 				usage();
3990Sstevel@tonic-gate 				exit(CLIENT_ERR_FAIL);
4000Sstevel@tonic-gate 			}
4010Sstevel@tonic-gate 			retcode = clientSetParam(optlist, paramFlag, attrVal);
4020Sstevel@tonic-gate 			if (retcode != CLIENT_SUCCESS) {
4030Sstevel@tonic-gate 				CLIENT_FPRINTF(
4040Sstevel@tonic-gate 					stderr,
4050Sstevel@tonic-gate 					gettext("Error (%d) setting "
4060Sstevel@tonic-gate 						"param \"%s\"\n"),
4070Sstevel@tonic-gate 					retcode, optarg);
4080Sstevel@tonic-gate 				usage();
4090Sstevel@tonic-gate 				exit(CLIENT_ERR_FAIL);
4100Sstevel@tonic-gate 			}
4110Sstevel@tonic-gate 			break;
4120Sstevel@tonic-gate 		case EOF:
4130Sstevel@tonic-gate 			if (strcmp(argv[optind], "init") == 0) {
4140Sstevel@tonic-gate 				op_init = 1;
4150Sstevel@tonic-gate 			} else if (strcmp(argv[optind], "manual") == 0) {
4160Sstevel@tonic-gate 				op_manual = 1;
4170Sstevel@tonic-gate 			} else if (strcmp(argv[optind], "mod") == 0) {
4180Sstevel@tonic-gate 				op_mod = 1;
4190Sstevel@tonic-gate 			} else if (strcmp(argv[optind], "list") == 0) {
4200Sstevel@tonic-gate 				op_list = 1;
4210Sstevel@tonic-gate 			} else if (strcmp(argv[optind], "uninit") == 0) {
4220Sstevel@tonic-gate 				op_uninit = 1;
4230Sstevel@tonic-gate 			} else if (strcmp(argv[optind], "genprofile") == 0) {
4240Sstevel@tonic-gate 				gen = 1;
4250Sstevel@tonic-gate 				op_genprofile = 1;
4260Sstevel@tonic-gate 			} else if (optind == argc-1) {
4270Sstevel@tonic-gate 				retcode = clientSetParam(
4280Sstevel@tonic-gate 					optlist,
4290Sstevel@tonic-gate 					NS_LDAP_SERVERS_P,
4300Sstevel@tonic-gate 					argv[optind]);	/* ipAddr */
4310Sstevel@tonic-gate 				if (retcode != CLIENT_SUCCESS) {
4320Sstevel@tonic-gate 					CLIENT_FPRINTF(
4330Sstevel@tonic-gate 						stderr,
4340Sstevel@tonic-gate 						gettext("Error (%d) setting "
4350Sstevel@tonic-gate 							"serverList param.\n"),
4360Sstevel@tonic-gate 						retcode);
4370Sstevel@tonic-gate 					usage();
4380Sstevel@tonic-gate 					exit(CLIENT_ERR_FAIL);
4390Sstevel@tonic-gate 				}
4400Sstevel@tonic-gate 			} else {
4410Sstevel@tonic-gate 				CLIENT_FPUTS(
4420Sstevel@tonic-gate 					gettext("Error parsing "
4430Sstevel@tonic-gate 						"command line\n"),
4440Sstevel@tonic-gate 					stderr);
4450Sstevel@tonic-gate 				usage();
4460Sstevel@tonic-gate 				exit(CLIENT_ERR_FAIL);
4470Sstevel@tonic-gate 			}
4480Sstevel@tonic-gate 			optind++;	/* get past the verb and keep trying */
4490Sstevel@tonic-gate 			break;
4500Sstevel@tonic-gate 		/* Backwards compatibility to support system install */
4510Sstevel@tonic-gate 		case 'I':
4520Sstevel@tonic-gate 			sysid_install = B_TRUE;
4530Sstevel@tonic-gate 			op_init = 1;
4540Sstevel@tonic-gate 			mode_quiet = 1;
4550Sstevel@tonic-gate 			break;
4560Sstevel@tonic-gate 		case '?':
4570Sstevel@tonic-gate 			usage();
4580Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("\nOr\n\n"), stderr);
4590Sstevel@tonic-gate 			gen = 1;
4600Sstevel@tonic-gate 			usage();
4610Sstevel@tonic-gate 			exit(CLIENT_ERR_FAIL);
4620Sstevel@tonic-gate 			break;
4630Sstevel@tonic-gate 		}
4640Sstevel@tonic-gate 
4650Sstevel@tonic-gate 	}
4660Sstevel@tonic-gate 
4670Sstevel@tonic-gate 	if ((getuid() != 0) && (!op_genprofile)) {
4680Sstevel@tonic-gate 		(void) puts(
4690Sstevel@tonic-gate 			"You must be root (SuperUser) to run this command.");
4700Sstevel@tonic-gate 		usage();
4710Sstevel@tonic-gate 		exit(CLIENT_ERR_FAIL);
4720Sstevel@tonic-gate 	}
4730Sstevel@tonic-gate 
4740Sstevel@tonic-gate /*
4750Sstevel@tonic-gate  *	All command line arguments are finished being parsed now
4760Sstevel@tonic-gate  */
4770Sstevel@tonic-gate 
4780Sstevel@tonic-gate /* *** Do semantic checking here *** */
4790Sstevel@tonic-gate 
4800Sstevel@tonic-gate /* if gen and no no searchBase then err */
4810Sstevel@tonic-gate 	if (gen && !optlist->defaultSearchBase) {
4820Sstevel@tonic-gate 		CLIENT_FPUTS(
4830Sstevel@tonic-gate 			gettext("ldapclient: Missing required attrName "
4840Sstevel@tonic-gate 				"defaultSearchBase\n"),
4850Sstevel@tonic-gate 			stderr);
4860Sstevel@tonic-gate 		usage();
4870Sstevel@tonic-gate 		clientopts_free(optlist);
4880Sstevel@tonic-gate 		exit(CLIENT_ERR_FAIL);
4890Sstevel@tonic-gate 	}
4900Sstevel@tonic-gate 
4910Sstevel@tonic-gate /* Only one verb can be specified */
4920Sstevel@tonic-gate 	if ((op_init + op_manual + op_mod + op_uninit +
4930Sstevel@tonic-gate 		op_list + op_genprofile) != 1) {
4940Sstevel@tonic-gate 		usage();
4950Sstevel@tonic-gate 		clientopts_free(optlist);
4960Sstevel@tonic-gate 		exit(CLIENT_ERR_FAIL);
4970Sstevel@tonic-gate 	}
4980Sstevel@tonic-gate 
4990Sstevel@tonic-gate /* *** We passed semantic checking, so now do the operation *** */
5000Sstevel@tonic-gate 
5010Sstevel@tonic-gate 	if (mode_verbose) {
5020Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Arguments parsed:\n"), stderr);
5030Sstevel@tonic-gate 		dumpargs(optlist);
5040Sstevel@tonic-gate 	}
5050Sstevel@tonic-gate 
5060Sstevel@tonic-gate 
5070Sstevel@tonic-gate /* handle "ldapclient list" here.  err checking done in func */
5080Sstevel@tonic-gate 	if (op_list) {
5090Sstevel@tonic-gate 		if (mode_verbose)
5100Sstevel@tonic-gate 			CLIENT_FPUTS(
5110Sstevel@tonic-gate 				gettext("Handling list option\n"),
5120Sstevel@tonic-gate 				stderr);
5130Sstevel@tonic-gate 		retcode = client_list(optlist);
5140Sstevel@tonic-gate 	}
5150Sstevel@tonic-gate 
5160Sstevel@tonic-gate /* handle "ldapclient uninit" here */
5170Sstevel@tonic-gate 	if (op_uninit) {
5180Sstevel@tonic-gate 		if (mode_verbose)
5190Sstevel@tonic-gate 			CLIENT_FPUTS(
5200Sstevel@tonic-gate 				gettext("Handling uninit option\n"),
5210Sstevel@tonic-gate 				stderr);
5220Sstevel@tonic-gate 		retcode = client_uninit(optlist);
5230Sstevel@tonic-gate 	}
5240Sstevel@tonic-gate 
5250Sstevel@tonic-gate /* handle "ldapclient init" (profile) */
5260Sstevel@tonic-gate 	if (op_init) {
5270Sstevel@tonic-gate 		if (mode_verbose)
5280Sstevel@tonic-gate 			CLIENT_FPUTS(
5290Sstevel@tonic-gate 				gettext("Handling init option\n"),
5300Sstevel@tonic-gate 				stderr);
5310Sstevel@tonic-gate 		retcode = client_init(optlist);
5320Sstevel@tonic-gate 	}
5330Sstevel@tonic-gate 
5340Sstevel@tonic-gate /* handle "genprofile" here */
5350Sstevel@tonic-gate 	if (op_genprofile) {
5360Sstevel@tonic-gate 		if (mode_verbose)
5370Sstevel@tonic-gate 			CLIENT_FPUTS(
5380Sstevel@tonic-gate 				gettext("Handling genProfile\n"),
5390Sstevel@tonic-gate 				stderr);
5400Sstevel@tonic-gate 		retcode = client_genProfile(optlist);
5410Sstevel@tonic-gate 	}
5420Sstevel@tonic-gate 
5430Sstevel@tonic-gate /* handle "ldapclient manual" here */
5440Sstevel@tonic-gate 	if (op_manual) {
5450Sstevel@tonic-gate 		if (mode_verbose)
5460Sstevel@tonic-gate 			CLIENT_FPUTS(
5470Sstevel@tonic-gate 				gettext("Handling manual option\n"),
5480Sstevel@tonic-gate 				stderr);
5490Sstevel@tonic-gate 		retcode = client_manual(optlist);
5500Sstevel@tonic-gate 	}
5510Sstevel@tonic-gate 
5520Sstevel@tonic-gate /* handle "ldapclient mod" here */
5530Sstevel@tonic-gate 	if (op_mod) {
5540Sstevel@tonic-gate 		if (mode_verbose)
5550Sstevel@tonic-gate 			CLIENT_FPUTS(
5560Sstevel@tonic-gate 				gettext("Handling mod option\n"),
5570Sstevel@tonic-gate 				stderr);
5580Sstevel@tonic-gate 		retcode = client_mod(optlist);
5590Sstevel@tonic-gate 	}
5600Sstevel@tonic-gate 
5610Sstevel@tonic-gate 	clientopts_free(optlist);
5620Sstevel@tonic-gate 	if ((retcode == CLIENT_SUCCESS) ||
5630Sstevel@tonic-gate 			(retcode == CLIENT_ERR_FAIL) ||
5640Sstevel@tonic-gate 			(retcode == CLIENT_ERR_CREDENTIAL))
5650Sstevel@tonic-gate 		exit(retcode);
5660Sstevel@tonic-gate 	else
5670Sstevel@tonic-gate 		exit(CLIENT_ERR_FAIL);
5680Sstevel@tonic-gate }
5690Sstevel@tonic-gate 
5700Sstevel@tonic-gate static int
5710Sstevel@tonic-gate client_list(clientopts_t *arglist)
5720Sstevel@tonic-gate {
5730Sstevel@tonic-gate 	ns_ldap_error_t *errorp;
5740Sstevel@tonic-gate 	int retcode = CLIENT_SUCCESS;
5750Sstevel@tonic-gate 
5760Sstevel@tonic-gate 	if (num_args(arglist) > 0) {
5770Sstevel@tonic-gate 		CLIENT_FPUTS(
5780Sstevel@tonic-gate 			gettext("No args supported with \"list\" option\n"),
5790Sstevel@tonic-gate 			stderr);
5800Sstevel@tonic-gate 		usage();
5810Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);	/* exit code here ? */
5820Sstevel@tonic-gate 	}
5830Sstevel@tonic-gate 	if ((errorp = __ns_ldap_print_config(mode_verbose)) != NULL) {
5840Sstevel@tonic-gate 		retcode = CLIENT_ERR_FAIL;
5850Sstevel@tonic-gate 		CLIENT_FPUTS(
5860Sstevel@tonic-gate 			gettext("Cannot get print configuration\n"),
5870Sstevel@tonic-gate 			stderr);
5880Sstevel@tonic-gate 		CLIENT_FPUTS(errorp->message, stderr);
5890Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
5900Sstevel@tonic-gate 		CLIENT_FPUTC('\n', stderr);
5910Sstevel@tonic-gate 	}
5920Sstevel@tonic-gate 
5930Sstevel@tonic-gate 	return (retcode);
5940Sstevel@tonic-gate }
5950Sstevel@tonic-gate 
5960Sstevel@tonic-gate static int
5970Sstevel@tonic-gate client_uninit(clientopts_t *arglist)
5980Sstevel@tonic-gate {
5990Sstevel@tonic-gate 	int retcode = CLIENT_SUCCESS;
6000Sstevel@tonic-gate 
6010Sstevel@tonic-gate 	if (mode_verbose) {
6020Sstevel@tonic-gate 		CLIENT_FPUTS(
6030Sstevel@tonic-gate 			gettext("Restoring machine to previous "
6040Sstevel@tonic-gate 				"configuration state\n"),
6050Sstevel@tonic-gate 			stderr);
6060Sstevel@tonic-gate 	}
6070Sstevel@tonic-gate 
6080Sstevel@tonic-gate 	if (num_args(arglist) > 0) {
6090Sstevel@tonic-gate 		CLIENT_FPUTS(
6100Sstevel@tonic-gate 			gettext("No args supported with \"uninit\" option\n"),
6110Sstevel@tonic-gate 			stderr);
6120Sstevel@tonic-gate 		usage();
6130Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
6140Sstevel@tonic-gate 	}
6150Sstevel@tonic-gate 
6160Sstevel@tonic-gate 	retcode = stop_services(STATE_SAVE);
6170Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
6180Sstevel@tonic-gate 		CLIENT_FPUTS(
6190Sstevel@tonic-gate 			gettext("Errors stopping network services.\n"), stderr);
6200Sstevel@tonic-gate 		/* restart whatever services we can */
6210Sstevel@tonic-gate 		(void) start_services(START_RESET);
6220Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
6230Sstevel@tonic-gate 	}
6240Sstevel@tonic-gate 
6250Sstevel@tonic-gate 	retcode = recover(STATE_SAVE);
6260Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
6270Sstevel@tonic-gate 		CLIENT_FPUTS(
6280Sstevel@tonic-gate 			gettext("Cannot recover the configuration on "
6290Sstevel@tonic-gate 				"this machine.\n"),
6300Sstevel@tonic-gate 			stderr);
6310Sstevel@tonic-gate 		(void) start_services(START_RESET);
6320Sstevel@tonic-gate 	} else {
6330Sstevel@tonic-gate 		retcode = start_services(START_UNINIT);
6340Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
6350Sstevel@tonic-gate 			CLIENT_FPUTS(
6360Sstevel@tonic-gate 				gettext("Config restored but problems "
6370Sstevel@tonic-gate 					"encountered resetting network "
6380Sstevel@tonic-gate 					"services.\n"),
6390Sstevel@tonic-gate 				stderr);
6400Sstevel@tonic-gate 		}
6410Sstevel@tonic-gate 	}
6420Sstevel@tonic-gate 
6430Sstevel@tonic-gate 	if (retcode == CLIENT_SUCCESS) {
6440Sstevel@tonic-gate 		CLIENT_FPUTS(
6450Sstevel@tonic-gate 			gettext("System successfully recovered\n"),
6460Sstevel@tonic-gate 			stderr);
6470Sstevel@tonic-gate 	}
6480Sstevel@tonic-gate 
6490Sstevel@tonic-gate 	return (retcode);
6500Sstevel@tonic-gate }
6510Sstevel@tonic-gate 
6520Sstevel@tonic-gate /*
6530Sstevel@tonic-gate  * The following macro is used to do a __ns_ldap_setParam().
6540Sstevel@tonic-gate  * On every call, the return code is checked, and if there was
6550Sstevel@tonic-gate  * a problem then the error message is printed, the ldaperr
6560Sstevel@tonic-gate  * is freed and we return from the function with the offending
6570Sstevel@tonic-gate  * error return code.  This macro keeps us from having to
6580Sstevel@tonic-gate  * repeat this code for every call to setParam as was done
6590Sstevel@tonic-gate  * in the previous incarnation of ldapclient.
6600Sstevel@tonic-gate  *
6610Sstevel@tonic-gate  * assumes a "retcode" variable is available for status
6620Sstevel@tonic-gate  */
6630Sstevel@tonic-gate #define	LDAP_SET_PARAM(argval, argdef)	\
6640Sstevel@tonic-gate retcode = 0;	\
6650Sstevel@tonic-gate if (NULL != argval) {	\
6660Sstevel@tonic-gate 	ns_ldap_error_t *ldaperr;	\
6670Sstevel@tonic-gate 	retcode = __ns_ldap_setParam(argdef, (void *)argval, &ldaperr);	\
6680Sstevel@tonic-gate 	if (retcode != NS_LDAP_SUCCESS) {	\
6690Sstevel@tonic-gate 		if (NULL != ldaperr) {	\
6700Sstevel@tonic-gate 			CLIENT_FPUTS(ldaperr->message, stderr);	\
6710Sstevel@tonic-gate 			CLIENT_FPUTC('\n', stderr);	\
6720Sstevel@tonic-gate 			(void) __ns_ldap_freeError(&ldaperr);	\
6730Sstevel@tonic-gate 		}	\
6740Sstevel@tonic-gate 		return (retcode ? CLIENT_ERR_FAIL : CLIENT_SUCCESS);	\
6750Sstevel@tonic-gate 	}	\
6760Sstevel@tonic-gate }
6770Sstevel@tonic-gate 
6780Sstevel@tonic-gate static int
6790Sstevel@tonic-gate client_manual(clientopts_t *arglist)
6800Sstevel@tonic-gate {
6810Sstevel@tonic-gate 	int counter;
6820Sstevel@tonic-gate 	int domain_fp;
6830Sstevel@tonic-gate 	ns_ldap_error_t *errorp;
6840Sstevel@tonic-gate 	int ret_copy;
6850Sstevel@tonic-gate 	int reset_ret;
6860Sstevel@tonic-gate 	int retcode = CLIENT_SUCCESS;
6870Sstevel@tonic-gate 
6880Sstevel@tonic-gate 	if (dname == NULL) {
6890Sstevel@tonic-gate 		CLIENT_FPUTS(
6900Sstevel@tonic-gate 			gettext("Manual failed: System domain not set and "
6910Sstevel@tonic-gate 				"no domainName specified.\n"),
6920Sstevel@tonic-gate 			stderr);
6930Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
6940Sstevel@tonic-gate 	}
6950Sstevel@tonic-gate 
6960Sstevel@tonic-gate 	if (arglist->defaultSearchBase == NULL) {
6970Sstevel@tonic-gate 		CLIENT_FPUTS(
6980Sstevel@tonic-gate 			gettext("Manual failed: Missing required "
6990Sstevel@tonic-gate 				"defaultSearchBase attribute.\n"),
7000Sstevel@tonic-gate 			stderr);
7010Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
7020Sstevel@tonic-gate 	}
7030Sstevel@tonic-gate 
7040Sstevel@tonic-gate 	if ((arglist->defaultServerList == NULL) &&
7050Sstevel@tonic-gate 		(arglist->preferredServerList == NULL)) {
7060Sstevel@tonic-gate 		CLIENT_FPUTS(
7070Sstevel@tonic-gate 			gettext("Manual failed: Missing required "
7080Sstevel@tonic-gate 				"defaultServerList or preferredServerList "
7090Sstevel@tonic-gate 				"attribute.\n"),
7100Sstevel@tonic-gate 			stderr);
7110Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
7120Sstevel@tonic-gate 	}
7130Sstevel@tonic-gate 
7140Sstevel@tonic-gate 	if (arglist->profileTTL != NULL) {
7150Sstevel@tonic-gate 		CLIENT_FPUTS(
7160Sstevel@tonic-gate 			gettext("Manual aborted: profileTTL is not supported "
7170Sstevel@tonic-gate 				"in manual mode.\n"),
7180Sstevel@tonic-gate 			stderr);
7190Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
7200Sstevel@tonic-gate 	}
7210Sstevel@tonic-gate 
7220Sstevel@tonic-gate 	if (arglist->profileName != NULL) {
7230Sstevel@tonic-gate 		CLIENT_FPUTS(
7240Sstevel@tonic-gate 			gettext("Manual aborted: profileName is not supported "
7250Sstevel@tonic-gate 				"in manual mode.\n"),
7260Sstevel@tonic-gate 			stderr);
7270Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
7280Sstevel@tonic-gate 	}
7290Sstevel@tonic-gate 
7300Sstevel@tonic-gate 	if (!is_config_ok(arglist, B_FALSE)) {
7310Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
7320Sstevel@tonic-gate 			gettext("Cannot specify LDAP port with tls\n"));
7330Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
7340Sstevel@tonic-gate 	}
7350Sstevel@tonic-gate 
7360Sstevel@tonic-gate 	__ns_ldap_setServer(TRUE);	/* Need this for _ns_setParam() */
7370Sstevel@tonic-gate 	__ns_ldap_default_config();
7380Sstevel@tonic-gate 
7390Sstevel@tonic-gate 	/* Set version to latest (not version 1) */
7400Sstevel@tonic-gate 	LDAP_SET_PARAM(NS_LDAP_VERSION, NS_LDAP_FILE_VERSION_P);
7410Sstevel@tonic-gate 
7420Sstevel@tonic-gate 	/* Set profileTTL to 0 since NO profile on manual */
7430Sstevel@tonic-gate 	LDAP_SET_PARAM(CACHETTL_OFF, NS_LDAP_CACHETTL_P);
7440Sstevel@tonic-gate 
7450Sstevel@tonic-gate 	/* Set additional valid params from command line */
7460Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->authenticationMethod, NS_LDAP_AUTH_P);
7470Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultSearchBase, NS_LDAP_SEARCH_BASEDN_P);
7480Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->credentialLevel, NS_LDAP_CREDENTIAL_LEVEL_P);
7490Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->proxyDN, NS_LDAP_BINDDN_P);
7500Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->searchTimeLimit, NS_LDAP_SEARCH_TIME_P);
7510Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->preferredServerList, NS_LDAP_SERVER_PREF_P);
7520Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->profileName, NS_LDAP_PROFILE_P);
7530Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->followReferrals, NS_LDAP_SEARCH_REF_P);
7540Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultSearchScope, NS_LDAP_SEARCH_SCOPE_P);
7550Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->bindTimeLimit, NS_LDAP_BIND_TIME_P);
7560Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->proxyPassword, NS_LDAP_BINDPASSWD_P);
7570Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultServerList, NS_LDAP_SERVERS_P);
7580Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->certificatePath, NS_LDAP_HOST_CERTPATH_P);
7590Sstevel@tonic-gate 
7600Sstevel@tonic-gate 	for (counter = 0;
7610Sstevel@tonic-gate 		counter < arglist->serviceAuthenticationMethod->count;
7620Sstevel@tonic-gate 		counter++) {
7630Sstevel@tonic-gate 
7640Sstevel@tonic-gate 		LDAP_SET_PARAM(
7650Sstevel@tonic-gate 			arglist->serviceAuthenticationMethod->optlist[counter],
7660Sstevel@tonic-gate 			NS_LDAP_SERVICE_AUTH_METHOD_P);
7670Sstevel@tonic-gate 	}
7680Sstevel@tonic-gate 	for (counter = 0;
7690Sstevel@tonic-gate 		counter < arglist->serviceCredentialLevel->count;
7700Sstevel@tonic-gate 		counter++) {
7710Sstevel@tonic-gate 
7720Sstevel@tonic-gate 		LDAP_SET_PARAM(
7730Sstevel@tonic-gate 			arglist->serviceCredentialLevel->optlist[counter],
7740Sstevel@tonic-gate 			NS_LDAP_SERVICE_CRED_LEVEL_P);
7750Sstevel@tonic-gate 	}
7760Sstevel@tonic-gate 	for (counter = 0;
7770Sstevel@tonic-gate 		counter < arglist->objectclassMap->count;
7780Sstevel@tonic-gate 		counter++) {
7790Sstevel@tonic-gate 
7800Sstevel@tonic-gate 		LDAP_SET_PARAM(arglist->objectclassMap->optlist[counter],
7810Sstevel@tonic-gate 			NS_LDAP_OBJECTCLASSMAP_P);
7820Sstevel@tonic-gate 	}
7830Sstevel@tonic-gate 	for (counter = 0; counter < arglist->attributeMap->count; counter++) {
7840Sstevel@tonic-gate 		LDAP_SET_PARAM(arglist->attributeMap->optlist[counter],
7850Sstevel@tonic-gate 			NS_LDAP_ATTRIBUTEMAP_P);
7860Sstevel@tonic-gate 	}
7870Sstevel@tonic-gate 	for (counter = 0;
7880Sstevel@tonic-gate 		counter < arglist->serviceSearchDescriptor->count;
7890Sstevel@tonic-gate 		counter++) {
7900Sstevel@tonic-gate 
7910Sstevel@tonic-gate 		LDAP_SET_PARAM(
7920Sstevel@tonic-gate 			arglist->serviceSearchDescriptor->optlist[counter],
7930Sstevel@tonic-gate 			NS_LDAP_SERVICE_SEARCH_DESC_P);
7940Sstevel@tonic-gate 	}
7950Sstevel@tonic-gate 
7960Sstevel@tonic-gate 	retcode = credCheck(arglist);
7970Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
7980Sstevel@tonic-gate 		CLIENT_FPUTS(
7990Sstevel@tonic-gate 			gettext("Error in setting up credentials\n"),
8000Sstevel@tonic-gate 			stderr);
8010Sstevel@tonic-gate 		return (retcode);
8020Sstevel@tonic-gate 	}
8030Sstevel@tonic-gate 
8040Sstevel@tonic-gate 	if (mode_verbose)
8050Sstevel@tonic-gate 		CLIENT_FPUTS(
8060Sstevel@tonic-gate 			gettext("About to modify this machines "
8070Sstevel@tonic-gate 				"configuration by writing the files\n"),
8080Sstevel@tonic-gate 			stderr);
8090Sstevel@tonic-gate 
8100Sstevel@tonic-gate 	/* get ready to start playing with files */
8110Sstevel@tonic-gate 	retcode = stop_services(STATE_SAVE);
8120Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
8130Sstevel@tonic-gate 		CLIENT_FPUTS(
8140Sstevel@tonic-gate 			gettext("Errors stopping network services.\n"), stderr);
8150Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
8160Sstevel@tonic-gate 	}
8170Sstevel@tonic-gate 
8180Sstevel@tonic-gate 	/* Save orig versions of files */
8190Sstevel@tonic-gate 	retcode = file_backup();
8200Sstevel@tonic-gate 	if (retcode == CLIENT_ERR_RESTORE) {
8210Sstevel@tonic-gate 		CLIENT_FPUTS(
8220Sstevel@tonic-gate 			gettext("System not in state to enable ldap client.\n"),
8230Sstevel@tonic-gate 			stderr);
8240Sstevel@tonic-gate 
8250Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
8260Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
8270Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
8280Sstevel@tonic-gate 					"starting services during reset\n"),
8290Sstevel@tonic-gate 					reset_ret);
8300Sstevel@tonic-gate 		}
8310Sstevel@tonic-gate 		return (retcode);
8320Sstevel@tonic-gate 	} else if (retcode != CLIENT_SUCCESS) {
8330Sstevel@tonic-gate 		CLIENT_FPUTS(
8340Sstevel@tonic-gate 			gettext("Save of system configuration failed!  "
8350Sstevel@tonic-gate 				"Attempting recovery.\n"),
8360Sstevel@tonic-gate 			stderr);
8370Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
8380Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
8390Sstevel@tonic-gate 			CLIENT_FPUTS(
8400Sstevel@tonic-gate 				gettext("Recovery of systems configuration "
8410Sstevel@tonic-gate 					"failed.  Manual intervention of "
8420Sstevel@tonic-gate 					"config files is required.\n"),
8430Sstevel@tonic-gate 				stderr);
8440Sstevel@tonic-gate 			return (retcode);
8450Sstevel@tonic-gate 		}
8460Sstevel@tonic-gate 
8470Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
8480Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
8490Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
8500Sstevel@tonic-gate 					"starting services during reset\n"),
8510Sstevel@tonic-gate 					reset_ret);
8520Sstevel@tonic-gate 		}
8530Sstevel@tonic-gate 
8540Sstevel@tonic-gate 		return (retcode);
8550Sstevel@tonic-gate 	}
8560Sstevel@tonic-gate 
8570Sstevel@tonic-gate 	/* Dump new files */
8580Sstevel@tonic-gate 	errorp = __ns_ldap_DumpConfiguration(NSCONFIGFILE);
8590Sstevel@tonic-gate 	if (errorp != NULL) {
8600Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
8610Sstevel@tonic-gate 			gettext("%s manual: errorp is not NULL; %s\n"),
8620Sstevel@tonic-gate 			cmd, errorp->message);
8630Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
8640Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
8650Sstevel@tonic-gate 			CLIENT_FPUTS(
8660Sstevel@tonic-gate 				gettext("Recovery of systems configuration "
8670Sstevel@tonic-gate 					"failed.  Manual intervention of "
8680Sstevel@tonic-gate 					"config files is required.\n"),
8690Sstevel@tonic-gate 				stderr);
8700Sstevel@tonic-gate 			return (retcode);
8710Sstevel@tonic-gate 		}
8720Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
8730Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
8740Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
8750Sstevel@tonic-gate 					"starting services during reset\n"),
8760Sstevel@tonic-gate 					reset_ret);
8770Sstevel@tonic-gate 		}
8780Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
8790Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
8800Sstevel@tonic-gate 	}
8810Sstevel@tonic-gate 
8820Sstevel@tonic-gate 	/* if (credargs(arglist)) */
8830Sstevel@tonic-gate 	errorp = __ns_ldap_DumpConfiguration(NSCREDFILE);
8840Sstevel@tonic-gate 	if (errorp != NULL) {
8850Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
8860Sstevel@tonic-gate 			gettext("%s init: errorp is not NULL; %s\n"),
8870Sstevel@tonic-gate 			cmd, errorp->message);
8880Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
8890Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
8900Sstevel@tonic-gate 			CLIENT_FPUTS(
8910Sstevel@tonic-gate 				gettext("Recovery of systems configuration "
8920Sstevel@tonic-gate 					"failed.  Manual intervention of "
8930Sstevel@tonic-gate 					"config files is required.\n"),
8940Sstevel@tonic-gate 				stderr);
8950Sstevel@tonic-gate 			return (retcode);
8960Sstevel@tonic-gate 		}
8970Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
8980Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
8990Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
9000Sstevel@tonic-gate 					"starting services during reset\n"),
9010Sstevel@tonic-gate 					reset_ret);
9020Sstevel@tonic-gate 		}
9030Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
9040Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
9050Sstevel@tonic-gate 	}
9060Sstevel@tonic-gate 
9070Sstevel@tonic-gate 	ret_copy = system(CMD_CP " " NSSWITCH_LDAP " " NSSWITCH_CONF);
9080Sstevel@tonic-gate 	if (ret_copy != 0) {
9090Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
9100Sstevel@tonic-gate 			gettext("Error %d copying (%s) -> (%s)\n"),
9110Sstevel@tonic-gate 			ret_copy, NSSWITCH_LDAP, NSSWITCH_CONF);
9120Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
9130Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
9140Sstevel@tonic-gate 			CLIENT_FPUTS(
9150Sstevel@tonic-gate 				gettext("Recovery of systems configuration "
9160Sstevel@tonic-gate 					"failed.  Manual intervention of "
9170Sstevel@tonic-gate 					"config files is required.\n"),
9180Sstevel@tonic-gate 				stderr);
9190Sstevel@tonic-gate 		}
9200Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
9210Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
9220Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
9230Sstevel@tonic-gate 					"starting services during reset\n"),
9240Sstevel@tonic-gate 					reset_ret);
9250Sstevel@tonic-gate 		}
9260Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
9270Sstevel@tonic-gate 	}
9280Sstevel@tonic-gate 
9290Sstevel@tonic-gate 	if ((domain_fp = open(DOMAINNAME, O_WRONLY|O_CREAT|O_TRUNC,
9300Sstevel@tonic-gate 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) { /* 0644 */
9310Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr, gettext("Cannot open %s\n"), DOMAINNAME);
9320Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
9330Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
9340Sstevel@tonic-gate 			CLIENT_FPUTS(
9350Sstevel@tonic-gate 				gettext("Recovery of systems configuration "
9360Sstevel@tonic-gate 					"failed.  Manual intervention of "
9370Sstevel@tonic-gate 					"config files is required.\n"),
9380Sstevel@tonic-gate 				stderr);
9390Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
9400Sstevel@tonic-gate 		}
9410Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
9420Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
9430Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
9440Sstevel@tonic-gate 					"starting services during reset\n"),
9450Sstevel@tonic-gate 					reset_ret);
9460Sstevel@tonic-gate 		}
9470Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
9480Sstevel@tonic-gate 	}
9490Sstevel@tonic-gate 	(void) write(domain_fp, dname, strlen(dname));
9500Sstevel@tonic-gate 	(void) write(domain_fp, "\n", 1);
9510Sstevel@tonic-gate 	(void) close(domain_fp);
9520Sstevel@tonic-gate 
9530Sstevel@tonic-gate 	retcode = start_services(START_INIT);
9540Sstevel@tonic-gate 
9550Sstevel@tonic-gate 	if (retcode == CLIENT_SUCCESS) {
9560Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("System successfully configured\n"),
9570Sstevel@tonic-gate 								stderr);
9580Sstevel@tonic-gate 	} else {
9590Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error resetting system.\n"
9600Sstevel@tonic-gate 			"Recovering old system settings.\n"), stderr),
9610Sstevel@tonic-gate 
9620Sstevel@tonic-gate 		/* stop any started services for recover */
9630Sstevel@tonic-gate 		/* don't stomp on history of saved services state */
9640Sstevel@tonic-gate 		reset_ret = stop_services(STATE_NOSAVE);
9650Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
9660Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
9670Sstevel@tonic-gate 					"stopping services during reset\n"),
9680Sstevel@tonic-gate 					reset_ret);
9690Sstevel@tonic-gate 			/* Coninue and try to recover what we can */
9700Sstevel@tonic-gate 		}
9710Sstevel@tonic-gate 		reset_ret = recover(STATE_NOSAVE);
9720Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
9730Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
9740Sstevel@tonic-gate 					"recovering service files during "
9750Sstevel@tonic-gate 					"reset\n"), reset_ret);
9760Sstevel@tonic-gate 			/* Continue and start what we can */
9770Sstevel@tonic-gate 		}
9780Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
9790Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
9800Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
9810Sstevel@tonic-gate 					"starting services during reset\n"),
9820Sstevel@tonic-gate 					reset_ret);
9830Sstevel@tonic-gate 		}
9840Sstevel@tonic-gate 	}
9850Sstevel@tonic-gate 
9860Sstevel@tonic-gate 	return (retcode);
9870Sstevel@tonic-gate }
9880Sstevel@tonic-gate 
9890Sstevel@tonic-gate static int
9900Sstevel@tonic-gate client_mod(clientopts_t *arglist)
9910Sstevel@tonic-gate {
9920Sstevel@tonic-gate 	int counter;
9930Sstevel@tonic-gate 	int domain_fp;
9940Sstevel@tonic-gate 	ns_ldap_error_t *errorp;
9950Sstevel@tonic-gate 	int reset_ret;
9960Sstevel@tonic-gate 	int retcode = CLIENT_SUCCESS;
9970Sstevel@tonic-gate 
9980Sstevel@tonic-gate 	__ns_ldap_setServer(TRUE);	/* Need this for _ns_setParam() */
9990Sstevel@tonic-gate 	if ((errorp = __ns_ldap_LoadConfiguration()) != NULL) {
10000Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Cannot get load configuration\n"),
10010Sstevel@tonic-gate 			stderr);
10020Sstevel@tonic-gate 		CLIENT_FPUTS(errorp->message, stderr);
10030Sstevel@tonic-gate 		CLIENT_FPUTC('\n', stderr);
10040Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
10050Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
10060Sstevel@tonic-gate 	}
10070Sstevel@tonic-gate 
10080Sstevel@tonic-gate 	if (arglist->profileTTL != NULL) {
10090Sstevel@tonic-gate 		CLIENT_FPUTS(
10100Sstevel@tonic-gate 			gettext("Mod aborted: profileTTL modification is "
10110Sstevel@tonic-gate 				"not allowed in mod mode.\n"),
10120Sstevel@tonic-gate 			stderr);
10130Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
10140Sstevel@tonic-gate 	}
10150Sstevel@tonic-gate 
10160Sstevel@tonic-gate 	if (arglist->profileName != NULL) {
10170Sstevel@tonic-gate 		CLIENT_FPUTS(
10180Sstevel@tonic-gate 			gettext("Mod aborted: profileName modification is "
10190Sstevel@tonic-gate 				"not allowed.  If you want to use profiles "
10200Sstevel@tonic-gate 				"generate one with genProfile and load it "
10210Sstevel@tonic-gate 				"on the server with ldapadd.\n"),
10220Sstevel@tonic-gate 			stderr);
10230Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
10240Sstevel@tonic-gate 	}
10250Sstevel@tonic-gate 
10260Sstevel@tonic-gate 	if (!is_config_ok(arglist, B_TRUE)) {
10270Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
10280Sstevel@tonic-gate 			gettext("Cannot specify LDAP port with tls\n"));
10290Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
10300Sstevel@tonic-gate 	}
10310Sstevel@tonic-gate 
10320Sstevel@tonic-gate 	/* Set additional valid params from command line */
10330Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->authenticationMethod, NS_LDAP_AUTH_P);
10340Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultSearchBase, NS_LDAP_SEARCH_BASEDN_P);
10350Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->credentialLevel, NS_LDAP_CREDENTIAL_LEVEL_P);
10360Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->proxyDN, NS_LDAP_BINDDN_P);
10370Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->profileTTL, NS_LDAP_CACHETTL_P);
10380Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->searchTimeLimit, NS_LDAP_SEARCH_TIME_P);
10390Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->preferredServerList, NS_LDAP_SERVER_PREF_P);
10400Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->profileName, NS_LDAP_PROFILE_P);
10410Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->followReferrals, NS_LDAP_SEARCH_REF_P);
10420Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultSearchScope, NS_LDAP_SEARCH_SCOPE_P);
10430Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->bindTimeLimit, NS_LDAP_BIND_TIME_P);
10440Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->proxyPassword, NS_LDAP_BINDPASSWD_P);
10450Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultServerList, NS_LDAP_SERVERS_P);
10460Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->certificatePath, NS_LDAP_HOST_CERTPATH_P);
10470Sstevel@tonic-gate 
10480Sstevel@tonic-gate 	for (counter = 0;
10490Sstevel@tonic-gate 		counter < arglist->serviceAuthenticationMethod->count;
10500Sstevel@tonic-gate 		counter++) {
10510Sstevel@tonic-gate 
10520Sstevel@tonic-gate 		LDAP_SET_PARAM(
10530Sstevel@tonic-gate 			arglist->serviceAuthenticationMethod->optlist[counter],
10540Sstevel@tonic-gate 			NS_LDAP_SERVICE_AUTH_METHOD_P);
10550Sstevel@tonic-gate 	}
10560Sstevel@tonic-gate 	for (counter = 0;
10570Sstevel@tonic-gate 		counter < arglist->serviceCredentialLevel->count;
10580Sstevel@tonic-gate 		counter++) {
10590Sstevel@tonic-gate 
10600Sstevel@tonic-gate 		LDAP_SET_PARAM(
10610Sstevel@tonic-gate 			arglist->serviceCredentialLevel->optlist[counter],
10620Sstevel@tonic-gate 			NS_LDAP_SERVICE_CRED_LEVEL_P);
10630Sstevel@tonic-gate 	}
10640Sstevel@tonic-gate 	for (counter = 0;
10650Sstevel@tonic-gate 		counter < arglist->objectclassMap->count;
10660Sstevel@tonic-gate 		counter++) {
10670Sstevel@tonic-gate 
10680Sstevel@tonic-gate 		LDAP_SET_PARAM(
10690Sstevel@tonic-gate 			arglist->objectclassMap->optlist[counter],
10700Sstevel@tonic-gate 			NS_LDAP_OBJECTCLASSMAP_P);
10710Sstevel@tonic-gate 	}
10720Sstevel@tonic-gate 	for (counter = 0;
10730Sstevel@tonic-gate 		counter < arglist->attributeMap->count;
10740Sstevel@tonic-gate 		counter++) {
10750Sstevel@tonic-gate 
10760Sstevel@tonic-gate 		LDAP_SET_PARAM(
10770Sstevel@tonic-gate 			arglist->attributeMap->optlist[counter],
10780Sstevel@tonic-gate 			NS_LDAP_ATTRIBUTEMAP_P);
10790Sstevel@tonic-gate 	}
10800Sstevel@tonic-gate 	for (counter = 0;
10810Sstevel@tonic-gate 		counter < arglist->serviceSearchDescriptor->count;
10820Sstevel@tonic-gate 		counter++) {
10830Sstevel@tonic-gate 
10840Sstevel@tonic-gate 		LDAP_SET_PARAM(
10850Sstevel@tonic-gate 			arglist->serviceSearchDescriptor->optlist[counter],
10860Sstevel@tonic-gate 			NS_LDAP_SERVICE_SEARCH_DESC_P);
10870Sstevel@tonic-gate 	}
10880Sstevel@tonic-gate 
10890Sstevel@tonic-gate 	retcode = credCheck(arglist);
10900Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
10910Sstevel@tonic-gate 		CLIENT_FPUTS(
10920Sstevel@tonic-gate 			gettext("Error in setting up credentials\n"),
10930Sstevel@tonic-gate 			stderr);
10940Sstevel@tonic-gate 		return (retcode);
10950Sstevel@tonic-gate 	}
10960Sstevel@tonic-gate 
10970Sstevel@tonic-gate 	if (mode_verbose)
10980Sstevel@tonic-gate 		CLIENT_FPUTS(
10990Sstevel@tonic-gate 			gettext("About to modify this machines configuration "
11000Sstevel@tonic-gate 				"by writing the files\n"),
11010Sstevel@tonic-gate 			stderr);
11020Sstevel@tonic-gate 
11030Sstevel@tonic-gate 	/* get ready to start playing with files */
11040Sstevel@tonic-gate 	retcode = stop_services(STATE_SAVE);
11050Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
11060Sstevel@tonic-gate 		CLIENT_FPUTS(
11070Sstevel@tonic-gate 			gettext("Errors stopping network services.\n"), stderr);
11080Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
11090Sstevel@tonic-gate 	}
11100Sstevel@tonic-gate 
11110Sstevel@tonic-gate 	/* Temporarily save orig versions of files */
11120Sstevel@tonic-gate 	retcode = mod_backup();
11130Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
11140Sstevel@tonic-gate 		CLIENT_FPUTS(
11150Sstevel@tonic-gate 			gettext("Unable to backup the ldap client files!\n"),
11160Sstevel@tonic-gate 			stderr);
11170Sstevel@tonic-gate 
11180Sstevel@tonic-gate 		return (retcode);
11190Sstevel@tonic-gate 
11200Sstevel@tonic-gate 	}
11210Sstevel@tonic-gate 
11220Sstevel@tonic-gate 	/* Dump new files */
11230Sstevel@tonic-gate 	errorp = __ns_ldap_DumpConfiguration(NSCONFIGFILE);
11240Sstevel@tonic-gate 	if (errorp != NULL) {
11250Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
11260Sstevel@tonic-gate 			gettext("%s mod: errorp is not NULL; %s\n"),
11270Sstevel@tonic-gate 			cmd, errorp->message);
11280Sstevel@tonic-gate 		retcode = mod_recover();
11290Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
11300Sstevel@tonic-gate 			CLIENT_FPUTS(
11310Sstevel@tonic-gate 				gettext("Recovery of systems configuration "
11320Sstevel@tonic-gate 					"failed.  Manual intervention of "
11330Sstevel@tonic-gate 					"config files is required.\n"),
11340Sstevel@tonic-gate 				stderr);
11350Sstevel@tonic-gate 		}
11360Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
11370Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
11380Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
11390Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
11400Sstevel@tonic-gate 					"starting services during reset\n"),
11410Sstevel@tonic-gate 					reset_ret);
11420Sstevel@tonic-gate 		}
11430Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
11440Sstevel@tonic-gate 	}
11450Sstevel@tonic-gate 
11460Sstevel@tonic-gate 	/* if (credargs(arglist)) */
11470Sstevel@tonic-gate 	errorp = __ns_ldap_DumpConfiguration(NSCREDFILE);
11480Sstevel@tonic-gate 	if (errorp != NULL) {
11490Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
11500Sstevel@tonic-gate 			gettext("%s mod: errorp is not NULL; %s\n"),
11510Sstevel@tonic-gate 			cmd, errorp->message);
11520Sstevel@tonic-gate 		retcode = mod_recover();
11530Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
11540Sstevel@tonic-gate 			CLIENT_FPUTS(
11550Sstevel@tonic-gate 				gettext("Recovery of systems configuration "
11560Sstevel@tonic-gate 					"failed.  Manual intervention of "
11570Sstevel@tonic-gate 					"config files is required.\n"),
11580Sstevel@tonic-gate 				stderr);
11590Sstevel@tonic-gate 		}
11600Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
11610Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
11620Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
11630Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
11640Sstevel@tonic-gate 					"starting services during reset\n"),
11650Sstevel@tonic-gate 					reset_ret);
11660Sstevel@tonic-gate 		}
11670Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
11680Sstevel@tonic-gate 	}
11690Sstevel@tonic-gate 
11700Sstevel@tonic-gate 	if ((domain_fp = open(DOMAINNAME, O_WRONLY|O_CREAT|O_TRUNC,
11710Sstevel@tonic-gate 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) { /* 0644 */
11720Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr, gettext("Cannot open %s\n"), DOMAINNAME);
11730Sstevel@tonic-gate 		retcode = mod_recover();
11740Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
11750Sstevel@tonic-gate 			CLIENT_FPUTS(
11760Sstevel@tonic-gate 				gettext("Recovery of systems configuration "
11770Sstevel@tonic-gate 					"failed!  Machine needs to be "
11780Sstevel@tonic-gate 					"fixed!\n"),
11790Sstevel@tonic-gate 				stderr);
11800Sstevel@tonic-gate 		}
11810Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
11820Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
11830Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
11840Sstevel@tonic-gate 					"starting services during reset\n"),
11850Sstevel@tonic-gate 					reset_ret);
11860Sstevel@tonic-gate 		}
11870Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
11880Sstevel@tonic-gate 	}
11890Sstevel@tonic-gate 	(void) write(domain_fp, dname, strlen(dname));
11900Sstevel@tonic-gate 	(void) write(domain_fp, "\n", 1);
11910Sstevel@tonic-gate 	(void) close(domain_fp);
11920Sstevel@tonic-gate 
11930Sstevel@tonic-gate 	retcode = start_services(START_INIT);
11940Sstevel@tonic-gate 
11950Sstevel@tonic-gate 	if (retcode == CLIENT_SUCCESS) {
11960Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("System successfully configured\n"),
11970Sstevel@tonic-gate 								stderr);
11980Sstevel@tonic-gate 	} else {
11990Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error resetting system.\n"
12000Sstevel@tonic-gate 			"Recovering old system settings.\n"), stderr),
12010Sstevel@tonic-gate 
12020Sstevel@tonic-gate 		/* stop any started services for recover */
12030Sstevel@tonic-gate 		/* don't stomp on history of saved services state */
12040Sstevel@tonic-gate 		reset_ret = stop_services(STATE_NOSAVE);
12050Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
12060Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
12070Sstevel@tonic-gate 					"stopping services during reset\n"),
12080Sstevel@tonic-gate 					reset_ret);
12090Sstevel@tonic-gate 			/* Coninue and try to recover what we can */
12100Sstevel@tonic-gate 		}
12110Sstevel@tonic-gate 		reset_ret = mod_recover();
12120Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
12130Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
12140Sstevel@tonic-gate 					"recovering service files during "
12150Sstevel@tonic-gate 					"reset\n"), reset_ret);
12160Sstevel@tonic-gate 			/* Continue and start what we can */
12170Sstevel@tonic-gate 		}
12180Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
12190Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
12200Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
12210Sstevel@tonic-gate 					"starting services during reset\n"),
12220Sstevel@tonic-gate 					reset_ret);
12230Sstevel@tonic-gate 		}
12240Sstevel@tonic-gate 	}
12250Sstevel@tonic-gate 
12260Sstevel@tonic-gate 	/* Cleanup temporary files created by mod_backup() */
12270Sstevel@tonic-gate 	mod_cleanup();
12280Sstevel@tonic-gate 
12290Sstevel@tonic-gate 	return (retcode);
12300Sstevel@tonic-gate }
12310Sstevel@tonic-gate 
12320Sstevel@tonic-gate 
12330Sstevel@tonic-gate /*
12340Sstevel@tonic-gate  * The following macro is used to check if an arg has already been set
12350Sstevel@tonic-gate  * and issues an error message, a usage message and then returns an error.
12360Sstevel@tonic-gate  * This was made into a macro to avoid the duplication of this code many
12370Sstevel@tonic-gate  * times in the function below.
12380Sstevel@tonic-gate  */
12390Sstevel@tonic-gate #define	LDAP_CHECK_INVALID(arg, param)	\
12400Sstevel@tonic-gate if (arg) {	\
12410Sstevel@tonic-gate 	CLIENT_FPRINTF(stderr, gettext("Invalid parameter (%s) " \
12420Sstevel@tonic-gate 		"specified\n"), param);	\
12430Sstevel@tonic-gate 	usage();	\
12440Sstevel@tonic-gate 	return (CLIENT_ERR_FAIL);	\
12450Sstevel@tonic-gate }
12460Sstevel@tonic-gate 
12470Sstevel@tonic-gate static int
12480Sstevel@tonic-gate client_genProfile(clientopts_t *arglist)
12490Sstevel@tonic-gate {
12500Sstevel@tonic-gate 	int counter;
12510Sstevel@tonic-gate 	int retcode;	/* required for LDAP_SET_PARAM macro */
12520Sstevel@tonic-gate 	ns_ldap_error_t *errorp;
12530Sstevel@tonic-gate 
12540Sstevel@tonic-gate 	if (mode_verbose)
12550Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("About to generate a profile\n"), stderr);
12560Sstevel@tonic-gate 
12570Sstevel@tonic-gate 	/* *** Check for invalid args *** */
12580Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->proxyDN, "proxyDN");
12590Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->proxyPassword, "proxyPassword");
12600Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->certificatePath, "certificatePath");
12610Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->domainName, "domainName");
12620Sstevel@tonic-gate 	/* *** End check for invalid args *** */
12630Sstevel@tonic-gate 
12640Sstevel@tonic-gate 	if (arglist->profileName == NULL) {
12650Sstevel@tonic-gate 		if (mode_verbose)
12660Sstevel@tonic-gate 			CLIENT_FPUTS(
12670Sstevel@tonic-gate 				gettext("No profile specified. "
12680Sstevel@tonic-gate 					"Using \"default\"\n"),
12690Sstevel@tonic-gate 				stderr);
12700Sstevel@tonic-gate 		arglist->profileName = "default";
12710Sstevel@tonic-gate 	}
12720Sstevel@tonic-gate 
12730Sstevel@tonic-gate 	__ns_ldap_setServer(TRUE);
12740Sstevel@tonic-gate 	__ns_ldap_default_config();
12750Sstevel@tonic-gate 
12760Sstevel@tonic-gate 	/* Set version to latest (not version 1) */
12770Sstevel@tonic-gate 	LDAP_SET_PARAM(NS_LDAP_VERSION, NS_LDAP_FILE_VERSION_P);
12780Sstevel@tonic-gate 
12790Sstevel@tonic-gate 	/* Set additional valid params from command line */
12800Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->authenticationMethod, NS_LDAP_AUTH_P);
12810Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultSearchBase, NS_LDAP_SEARCH_BASEDN_P);
12820Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->credentialLevel, NS_LDAP_CREDENTIAL_LEVEL_P);
12830Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->profileTTL, NS_LDAP_CACHETTL_P);
12840Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->searchTimeLimit, NS_LDAP_SEARCH_TIME_P);
12850Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->preferredServerList, NS_LDAP_SERVER_PREF_P);
12860Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->profileName, NS_LDAP_PROFILE_P);
12870Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->followReferrals, NS_LDAP_SEARCH_REF_P);
12880Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultSearchScope, NS_LDAP_SEARCH_SCOPE_P);
12890Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->bindTimeLimit, NS_LDAP_BIND_TIME_P);
12900Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultServerList, NS_LDAP_SERVERS_P);
12910Sstevel@tonic-gate 
12920Sstevel@tonic-gate 	for (counter = 0;
12930Sstevel@tonic-gate 		counter < arglist->serviceAuthenticationMethod->count;
12940Sstevel@tonic-gate 		counter++) {
12950Sstevel@tonic-gate 
12960Sstevel@tonic-gate 		LDAP_SET_PARAM(
12970Sstevel@tonic-gate 			arglist->serviceAuthenticationMethod->optlist[counter],
12980Sstevel@tonic-gate 			NS_LDAP_SERVICE_AUTH_METHOD_P);
12990Sstevel@tonic-gate 	}
13000Sstevel@tonic-gate 	for (counter = 0;
13010Sstevel@tonic-gate 		counter < arglist->serviceCredentialLevel->count;
13020Sstevel@tonic-gate 		counter++) {
13030Sstevel@tonic-gate 
13040Sstevel@tonic-gate 		LDAP_SET_PARAM(
13050Sstevel@tonic-gate 			arglist->serviceCredentialLevel->optlist[counter],
13060Sstevel@tonic-gate 			NS_LDAP_SERVICE_CRED_LEVEL_P);
13070Sstevel@tonic-gate 	}
13080Sstevel@tonic-gate 	for (counter = 0;
13090Sstevel@tonic-gate 		counter < arglist->objectclassMap->count;
13100Sstevel@tonic-gate 		counter++) {
13110Sstevel@tonic-gate 
13120Sstevel@tonic-gate 		LDAP_SET_PARAM(
13130Sstevel@tonic-gate 			arglist->objectclassMap->optlist[counter],
13140Sstevel@tonic-gate 			NS_LDAP_OBJECTCLASSMAP_P);
13150Sstevel@tonic-gate 	}
13160Sstevel@tonic-gate 	for (counter = 0;
13170Sstevel@tonic-gate 		counter < arglist->attributeMap->count;
13180Sstevel@tonic-gate 		counter++) {
13190Sstevel@tonic-gate 
13200Sstevel@tonic-gate 		LDAP_SET_PARAM(
13210Sstevel@tonic-gate 			arglist->attributeMap->optlist[counter],
13220Sstevel@tonic-gate 			NS_LDAP_ATTRIBUTEMAP_P);
13230Sstevel@tonic-gate 	}
13240Sstevel@tonic-gate 	for (counter = 0;
13250Sstevel@tonic-gate 		counter < arglist->serviceSearchDescriptor->count;
13260Sstevel@tonic-gate 		counter++) {
13270Sstevel@tonic-gate 
13280Sstevel@tonic-gate 		LDAP_SET_PARAM(
13290Sstevel@tonic-gate 			arglist->serviceSearchDescriptor->optlist[counter],
13300Sstevel@tonic-gate 			NS_LDAP_SERVICE_SEARCH_DESC_P);
13310Sstevel@tonic-gate 	}
13320Sstevel@tonic-gate 
13330Sstevel@tonic-gate 	if (!is_config_ok(arglist, B_FALSE)) {
13340Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
13350Sstevel@tonic-gate 			gettext("WARNING: some clients do not support an LDAP "
13360Sstevel@tonic-gate 				"port with tls\n"));
13370Sstevel@tonic-gate 	}
13380Sstevel@tonic-gate 
13390Sstevel@tonic-gate 	errorp = __ns_ldap_DumpLdif(NULL);
13400Sstevel@tonic-gate 	if (errorp != NULL) {
13410Sstevel@tonic-gate 		CLIENT_FPUTS(errorp->message, stderr);
13420Sstevel@tonic-gate 		CLIENT_FPUTC('\n', stderr);
13430Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
13440Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
13450Sstevel@tonic-gate 	}
13460Sstevel@tonic-gate 
13470Sstevel@tonic-gate 	return (CLIENT_SUCCESS);
13480Sstevel@tonic-gate }
13490Sstevel@tonic-gate 
13500Sstevel@tonic-gate static int
13510Sstevel@tonic-gate client_init(clientopts_t *arglist)
13520Sstevel@tonic-gate {
13530Sstevel@tonic-gate 	int profile_fp;
13540Sstevel@tonic-gate 	int retcode = CLIENT_SUCCESS;
13550Sstevel@tonic-gate 	char *nisBaseDN = NULL;
13560Sstevel@tonic-gate 	ns_ldap_error_t *errorp;
13570Sstevel@tonic-gate 	int reset_ret;
13580Sstevel@tonic-gate 	int ret_copy;
13590Sstevel@tonic-gate 
13600Sstevel@tonic-gate 	if (mode_verbose)
13610Sstevel@tonic-gate 		CLIENT_FPUTS(
13620Sstevel@tonic-gate 			gettext("About to configure machine by downloading "
13630Sstevel@tonic-gate 				"a profile\n"),
13640Sstevel@tonic-gate 			stderr);
13650Sstevel@tonic-gate 
13660Sstevel@tonic-gate 	if (dname == NULL) {
13670Sstevel@tonic-gate 		CLIENT_FPUTS(
13680Sstevel@tonic-gate 			gettext("Init failed: System domain not set and "
13690Sstevel@tonic-gate 				"no domainName specified.\n"),
13700Sstevel@tonic-gate 			stderr);
13710Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
13720Sstevel@tonic-gate 	}
13730Sstevel@tonic-gate 
13740Sstevel@tonic-gate 	if (!arglist->defaultServerList) {
13750Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Missing LDAP server address\n"), stderr);
13760Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
13770Sstevel@tonic-gate 	}
13780Sstevel@tonic-gate 
13790Sstevel@tonic-gate 	/* *** Check for invalid args *** */
13800Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->authenticationMethod,
13810Sstevel@tonic-gate 		"authenticationMethod");
13820Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->defaultSearchBase,
13830Sstevel@tonic-gate 		"defaultSearchBase");
13840Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->credentialLevel,
13850Sstevel@tonic-gate 		"credentialLevel");
13860Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->profileTTL,
13870Sstevel@tonic-gate 		"profileTTL");
13880Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->searchTimeLimit,
13890Sstevel@tonic-gate 		"searchTimeLimit");
13900Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->preferredServerList,
13910Sstevel@tonic-gate 		"preferredServerList");
13920Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->followReferrals,
13930Sstevel@tonic-gate 		"followReferrals");
13940Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->defaultSearchScope,
13950Sstevel@tonic-gate 		"defaultSearchScope");
13960Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->bindTimeLimit,
13970Sstevel@tonic-gate 		"bindTimeLimit");
13980Sstevel@tonic-gate 
13990Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->objectclassMap->count,
14000Sstevel@tonic-gate 		"objectclassMap");
14010Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->attributeMap->count,
14020Sstevel@tonic-gate 		"attributeMap");
14030Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->serviceAuthenticationMethod->count,
14040Sstevel@tonic-gate 		"serviceAuthenticationMethod");
14050Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->serviceCredentialLevel->count,
14060Sstevel@tonic-gate 		"serviceCredentialLevel");
14070Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->serviceSearchDescriptor->count,
14080Sstevel@tonic-gate 		"serviceSearchDescriptor");
14090Sstevel@tonic-gate 	/* *** End check for invalid args *** */
14100Sstevel@tonic-gate 
14110Sstevel@tonic-gate 	__ns_ldap_setServer(TRUE);
14120Sstevel@tonic-gate 
14130Sstevel@tonic-gate 	if (arglist->profileName == NULL) {
14140Sstevel@tonic-gate 		if (mode_verbose)
14150Sstevel@tonic-gate 			CLIENT_FPUTS(
14160Sstevel@tonic-gate 				gettext("No profile specified. "
14170Sstevel@tonic-gate 					"Using \"default\"\n"),
14180Sstevel@tonic-gate 				stderr);
14190Sstevel@tonic-gate 		arglist->profileName = "default";
14200Sstevel@tonic-gate 	}
14210Sstevel@tonic-gate 
14220Sstevel@tonic-gate 	/* need to free nisBaseDN */
14230Sstevel@tonic-gate 	nisBaseDN = findBaseDN(arglist->defaultServerList);
14240Sstevel@tonic-gate 	if (nisBaseDN == NULL) {
14250Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
14260Sstevel@tonic-gate 			gettext("Failed to find defaultSearchBase for "
14270Sstevel@tonic-gate 				"domain %s\n"),
14280Sstevel@tonic-gate 			dname);
14290Sstevel@tonic-gate 
14300Sstevel@tonic-gate 		if (gStartLdap == START_RESET)
14310Sstevel@tonic-gate 			(void) start_service(LDAP_FMRI, B_TRUE);
14320Sstevel@tonic-gate 
14330Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
14340Sstevel@tonic-gate 	}
14350Sstevel@tonic-gate 	retcode = __ns_ldap_setParam(
14360Sstevel@tonic-gate 			NS_LDAP_SEARCH_BASEDN_P,
14370Sstevel@tonic-gate 			(void *)nisBaseDN,
14380Sstevel@tonic-gate 			&errorp);
14390Sstevel@tonic-gate 	if (retcode != 0) {
14400Sstevel@tonic-gate 		CLIENT_FPUTS(
14410Sstevel@tonic-gate 			gettext("Unable to set search baseDN.\n"), stderr);
14420Sstevel@tonic-gate 		/* non-fatal */
14430Sstevel@tonic-gate 	}
14440Sstevel@tonic-gate 
14450Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultServerList, NS_LDAP_SERVERS_P);
14460Sstevel@tonic-gate 	if (retcode != 0) {
14470Sstevel@tonic-gate 		CLIENT_FPUTS(
14480Sstevel@tonic-gate 			gettext("Unable to set server address.\n"), stderr);
14490Sstevel@tonic-gate 		/* non-fatal */
14500Sstevel@tonic-gate 	}
14510Sstevel@tonic-gate 
14520Sstevel@tonic-gate 	/* Get and set profile params */
14530Sstevel@tonic-gate 	retcode = __ns_ldap_download(
14540Sstevel@tonic-gate 			arglist->profileName,
14550Sstevel@tonic-gate 			arglist->defaultServerList,
14560Sstevel@tonic-gate 			nisBaseDN,
14570Sstevel@tonic-gate 			&errorp);
14580Sstevel@tonic-gate 	if (retcode != NS_LDAP_SUCCESS) {
14590Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
14600Sstevel@tonic-gate 			gettext("The download of the profile failed.\n"));
14610Sstevel@tonic-gate 		if (errorp != NULL) {
14620Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, "%s\n", errorp->message);
14630Sstevel@tonic-gate 			(void) __ns_ldap_freeError(&errorp);
14640Sstevel@tonic-gate 		} else if (retcode == NS_LDAP_NOTFOUND) {
14650Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
14660Sstevel@tonic-gate 			gettext("Could not read the profile '%s'.\n"
14670Sstevel@tonic-gate 				"Perhaps it does not exist or you don't "
14680Sstevel@tonic-gate 				"have sufficient rights to read it.\n"),
14690Sstevel@tonic-gate 				arglist->profileName);
14700Sstevel@tonic-gate 		}
14710Sstevel@tonic-gate 
14720Sstevel@tonic-gate 		if (gStartLdap == START_RESET)
14730Sstevel@tonic-gate 			(void) start_service(LDAP_FMRI, B_TRUE);
14740Sstevel@tonic-gate 
14750Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
14760Sstevel@tonic-gate 	}
14770Sstevel@tonic-gate 
14780Sstevel@tonic-gate 	/* Set additional valid params from command line */
14790Sstevel@tonic-gate 	/* note that the domainName is not used in setParam */
14800Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->proxyDN, NS_LDAP_BINDDN_P);
14810Sstevel@tonic-gate 	if (retcode != 0) {
14820Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("setParam proxyDN failed.\n"), stderr);
14830Sstevel@tonic-gate 		/* non-fatal */
14840Sstevel@tonic-gate 	}
14850Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->proxyPassword, NS_LDAP_BINDPASSWD_P);
14860Sstevel@tonic-gate 	if (retcode != 0) {
14870Sstevel@tonic-gate 		CLIENT_FPUTS(
14880Sstevel@tonic-gate 			gettext("setParam proxyPassword failed.\n"), stderr);
14890Sstevel@tonic-gate 		/* non-fatal */
14900Sstevel@tonic-gate 	}
14910Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->certificatePath, NS_LDAP_HOST_CERTPATH_P);
14920Sstevel@tonic-gate 
14930Sstevel@tonic-gate 	retcode = credCheck(arglist);
14940Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
14950Sstevel@tonic-gate 		CLIENT_FPUTS(
14960Sstevel@tonic-gate 			gettext("Error in setting up credentials\n"), stderr);
14970Sstevel@tonic-gate 
14980Sstevel@tonic-gate 		if (gStartLdap == START_RESET)
14990Sstevel@tonic-gate 			(void) start_service(LDAP_FMRI, B_TRUE);
15000Sstevel@tonic-gate 
15010Sstevel@tonic-gate 		return (retcode);
15020Sstevel@tonic-gate 	}
15030Sstevel@tonic-gate 
15040Sstevel@tonic-gate 	if (mode_verbose)
15050Sstevel@tonic-gate 		CLIENT_FPUTS(
15060Sstevel@tonic-gate 			gettext("About to modify this machines configuration "
15070Sstevel@tonic-gate 				"by writing the files\n"),
15080Sstevel@tonic-gate 			stderr);
15090Sstevel@tonic-gate 
15100Sstevel@tonic-gate 	/* get ready to start playing with files */
15110Sstevel@tonic-gate 	retcode = stop_services(STATE_SAVE);
15120Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
15130Sstevel@tonic-gate 		CLIENT_FPUTS(
15140Sstevel@tonic-gate 			gettext("Errors stopping network services.\n"), stderr);
15150Sstevel@tonic-gate 
15160Sstevel@tonic-gate 		if (gStartLdap == START_RESET)
15170Sstevel@tonic-gate 			(void) start_service(LDAP_FMRI, B_TRUE);
15180Sstevel@tonic-gate 
15190Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
15200Sstevel@tonic-gate 	}
15210Sstevel@tonic-gate 
15220Sstevel@tonic-gate 	/* Save orig versions of files */
15230Sstevel@tonic-gate 	retcode = file_backup();
15240Sstevel@tonic-gate 	if (retcode == CLIENT_ERR_RESTORE) {
15250Sstevel@tonic-gate 		CLIENT_FPUTS(
15260Sstevel@tonic-gate 			gettext("System not in state to enable ldap client.\n"),
15270Sstevel@tonic-gate 			stderr);
15280Sstevel@tonic-gate 
15290Sstevel@tonic-gate 		return (retcode);
15300Sstevel@tonic-gate 
15310Sstevel@tonic-gate 	} else if (retcode != CLIENT_SUCCESS) {
15320Sstevel@tonic-gate 		CLIENT_FPUTS(
15330Sstevel@tonic-gate 			gettext("Save of system configuration failed.  "
15340Sstevel@tonic-gate 				"Attempting recovery.\n"),
15350Sstevel@tonic-gate 			stderr);
15360Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
15370Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
15380Sstevel@tonic-gate 			CLIENT_FPUTS(
15390Sstevel@tonic-gate 				gettext("Recovery of systems configuration "
15400Sstevel@tonic-gate 					"failed.  Manual intervention of "
15410Sstevel@tonic-gate 					"config files is required.\n"),
15420Sstevel@tonic-gate 				stderr);
15430Sstevel@tonic-gate 		}
15440Sstevel@tonic-gate 
15450Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
15460Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
15470Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
15480Sstevel@tonic-gate 					"starting services during reset\n"),
15490Sstevel@tonic-gate 					reset_ret);
15500Sstevel@tonic-gate 		}
15510Sstevel@tonic-gate 
15520Sstevel@tonic-gate 		return (retcode);
15530Sstevel@tonic-gate 	}
15540Sstevel@tonic-gate 
15550Sstevel@tonic-gate 	/* Dump new files */
15560Sstevel@tonic-gate 	errorp = __ns_ldap_DumpConfiguration(NSCONFIGFILE);
15570Sstevel@tonic-gate 	if (NULL != errorp) {
15580Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
15590Sstevel@tonic-gate 			gettext("%s init: errorp is not NULL; %s\n"),
15600Sstevel@tonic-gate 			cmd, errorp->message);
15610Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
15620Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
15630Sstevel@tonic-gate 			CLIENT_FPUTS(
15640Sstevel@tonic-gate 				gettext("Recovery of systems configuration "
15650Sstevel@tonic-gate 					"failed.  Manual intervention of "
15660Sstevel@tonic-gate 					"config files is required.\n"),
15670Sstevel@tonic-gate 				stderr);
15680Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
15690Sstevel@tonic-gate 		}
15700Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
15710Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
15720Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
15730Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
15740Sstevel@tonic-gate 					"starting services during reset\n"),
15750Sstevel@tonic-gate 					reset_ret);
15760Sstevel@tonic-gate 		}
15770Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
15780Sstevel@tonic-gate 	}
15790Sstevel@tonic-gate 
15800Sstevel@tonic-gate 	/* if (credargs(arglist)) */
15810Sstevel@tonic-gate 	errorp = __ns_ldap_DumpConfiguration(NSCREDFILE);
15820Sstevel@tonic-gate 	if (NULL != errorp) {
15830Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
15840Sstevel@tonic-gate 			gettext("%s init: errorp is not NULL; %s\n"),
15850Sstevel@tonic-gate 			cmd, errorp->message);
15860Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
15870Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
15880Sstevel@tonic-gate 			CLIENT_FPUTS(
15890Sstevel@tonic-gate 				gettext("Recovery of systems configuration "
15900Sstevel@tonic-gate 					"failed.  Manual intervention of "
15910Sstevel@tonic-gate 					"config files is required.\n"),
15920Sstevel@tonic-gate 				stderr);
15930Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
15940Sstevel@tonic-gate 		}
15950Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
15960Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
15970Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
15980Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
15990Sstevel@tonic-gate 					"starting services during reset\n"),
16000Sstevel@tonic-gate 					reset_ret);
16010Sstevel@tonic-gate 		}
16020Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
16030Sstevel@tonic-gate 	}
16040Sstevel@tonic-gate 
16050Sstevel@tonic-gate 	ret_copy = system(CMD_CP " " NSSWITCH_LDAP " " NSSWITCH_CONF);
16060Sstevel@tonic-gate 	if (ret_copy != 0) {
16070Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
16080Sstevel@tonic-gate 			gettext("Error %d copying (%s) -> (%s)\n"),
16090Sstevel@tonic-gate 			ret_copy, NSSWITCH_LDAP, NSSWITCH_CONF);
16100Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
16110Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
16120Sstevel@tonic-gate 			CLIENT_FPUTS(
16130Sstevel@tonic-gate 				gettext("Recovery of systems configuration "
16140Sstevel@tonic-gate 					"failed.  Manual intervention of "
16150Sstevel@tonic-gate 					"config files is required.\n"),
16160Sstevel@tonic-gate 				stderr);
16170Sstevel@tonic-gate 		}
16180Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
16190Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
16200Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
16210Sstevel@tonic-gate 					"starting services during reset\n"),
16220Sstevel@tonic-gate 					reset_ret);
16230Sstevel@tonic-gate 		}
16240Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
16250Sstevel@tonic-gate 	}
16260Sstevel@tonic-gate 
16270Sstevel@tonic-gate 	if ((profile_fp = open(DOMAINNAME, O_WRONLY|O_CREAT|O_TRUNC,
16280Sstevel@tonic-gate 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) { /* 0644 */
16290Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr, gettext("Cannot open %s\n"), DOMAINNAME);
16300Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
16310Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
16320Sstevel@tonic-gate 			CLIENT_FPUTS(
16330Sstevel@tonic-gate 				gettext("Recovery of systems configuration "
16340Sstevel@tonic-gate 					"failed.  Manual intervention of "
16350Sstevel@tonic-gate 					"config files is required.\n"),
16360Sstevel@tonic-gate 				stderr);
16370Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
16380Sstevel@tonic-gate 		}
16390Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
16400Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
16410Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
16420Sstevel@tonic-gate 					"starting services during reset\n"),
16430Sstevel@tonic-gate 					reset_ret);
16440Sstevel@tonic-gate 		}
16450Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
16460Sstevel@tonic-gate 	}
16470Sstevel@tonic-gate 	(void) write(profile_fp, dname, strlen(dname));
16480Sstevel@tonic-gate 	(void) write(profile_fp, "\n", 1);
16490Sstevel@tonic-gate 	(void) close(profile_fp);
16500Sstevel@tonic-gate 
16510Sstevel@tonic-gate 	retcode = start_services(START_INIT);
16520Sstevel@tonic-gate 
16530Sstevel@tonic-gate 	if (retcode == CLIENT_SUCCESS) {
16540Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("System successfully configured\n"),
16550Sstevel@tonic-gate 								stderr);
16560Sstevel@tonic-gate 	} else {
16570Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error resetting system.\n"
16580Sstevel@tonic-gate 			"Recovering old system settings.\n"), stderr),
16590Sstevel@tonic-gate 
16600Sstevel@tonic-gate 		/* stop any started services for recover */
16610Sstevel@tonic-gate 		/* don't stomp on history of saved services state */
16620Sstevel@tonic-gate 		reset_ret = stop_services(STATE_NOSAVE);
16630Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
16640Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
16650Sstevel@tonic-gate 					"stopping services during reset\n"),
16660Sstevel@tonic-gate 					reset_ret);
16670Sstevel@tonic-gate 			/* Coninue and try to recover what we can */
16680Sstevel@tonic-gate 		}
16690Sstevel@tonic-gate 		reset_ret = recover(STATE_NOSAVE);
16700Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
16710Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
16720Sstevel@tonic-gate 					"recovering service files during "
16730Sstevel@tonic-gate 					"reset\n"), reset_ret);
16740Sstevel@tonic-gate 			/* Continue and start what we can */
16750Sstevel@tonic-gate 		}
16760Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
16770Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
16780Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
16790Sstevel@tonic-gate 					"starting services during reset\n"),
16800Sstevel@tonic-gate 					reset_ret);
16810Sstevel@tonic-gate 		}
16820Sstevel@tonic-gate 	}
16830Sstevel@tonic-gate 
16840Sstevel@tonic-gate 	return (retcode);
16850Sstevel@tonic-gate }
16860Sstevel@tonic-gate 
16870Sstevel@tonic-gate 
16880Sstevel@tonic-gate static void
16890Sstevel@tonic-gate usage(void)
16900Sstevel@tonic-gate {
16910Sstevel@tonic-gate 	if (mode_quiet)
16920Sstevel@tonic-gate 		return;
16930Sstevel@tonic-gate 
16940Sstevel@tonic-gate 	if (gen == 0) {
16950Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
16960Sstevel@tonic-gate 			gettext("Usage: %s [-v | -q] init | manual | mod | "
16970Sstevel@tonic-gate 				"list | uninit [<args>]\n"),
16980Sstevel@tonic-gate 			cmd);
16990Sstevel@tonic-gate 
17000Sstevel@tonic-gate 		CLIENT_FPUTS(
17010Sstevel@tonic-gate 			gettext("\nSet up a server or workstation as a "
17020Sstevel@tonic-gate 				"client of an LDAP namespace.\n"),
17030Sstevel@tonic-gate 			stderr);
17040Sstevel@tonic-gate 	} else {	/* genprofile */
17050Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
17060Sstevel@tonic-gate 			gettext("Usage: %s [-v | -q] genprofile "
17070Sstevel@tonic-gate 				"-a profileName=<name> "
17080Sstevel@tonic-gate 				"-a defaultSearchBase=<base> <args>\n"),
17090Sstevel@tonic-gate 			cmd);
17100Sstevel@tonic-gate 
17110Sstevel@tonic-gate 		CLIENT_FPUTS(
17120Sstevel@tonic-gate 			gettext("\nGenerate a profile used to set up clients "
17130Sstevel@tonic-gate 				"of an LDAP namespace.\n"),
17140Sstevel@tonic-gate 			stderr);
17150Sstevel@tonic-gate 	}
17160Sstevel@tonic-gate 	CLIENT_FPUTS(
17170Sstevel@tonic-gate 		gettext("<args> take the form of \'-a attrName=attrVal\' as "
17180Sstevel@tonic-gate 			"described in the\n"),
17190Sstevel@tonic-gate 		stderr);
17200Sstevel@tonic-gate 	CLIENT_FPUTS(gettext("man page: ldapclient(1M)\n"), stderr);
17210Sstevel@tonic-gate }
17220Sstevel@tonic-gate 
17230Sstevel@tonic-gate 
17240Sstevel@tonic-gate /*
17250Sstevel@tonic-gate  * stop_services is called to stop network services prior to their
17260Sstevel@tonic-gate  * config files being moved/changed.  In case a later recovery is needed
17270Sstevel@tonic-gate  * (an error occurs during config), we detect whether the service is
17280Sstevel@tonic-gate  * running and store that info so that a reset will only start services
17290Sstevel@tonic-gate  * that were stopped here.
17300Sstevel@tonic-gate  *
17310Sstevel@tonic-gate  * In terms of SMF, this translates to disabling the services. So we
17320Sstevel@tonic-gate  * try to disable them if they are in any other state
17330Sstevel@tonic-gate  *
17340Sstevel@tonic-gate  * Stop order :
17350Sstevel@tonic-gate  * sendmail, nscd, autofs, ldap.client, nisd (rpc), inetinit(domainname)
17360Sstevel@tonic-gate  */
17370Sstevel@tonic-gate static int
17380Sstevel@tonic-gate stop_services(int saveState)
17390Sstevel@tonic-gate {
17400Sstevel@tonic-gate 	int ret;
17410Sstevel@tonic-gate 
17420Sstevel@tonic-gate 	if (mode_verbose) {
17430Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Stopping network services\n"), stderr);
17440Sstevel@tonic-gate 	}
17450Sstevel@tonic-gate 
17460Sstevel@tonic-gate 	if (!is_service(SENDMAIL_FMRI, SCF_STATE_STRING_DISABLED)) {
17470Sstevel@tonic-gate 		if (mode_verbose)
17480Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Stopping sendmail\n"), stderr);
17490Sstevel@tonic-gate 		ret = disable_service(SENDMAIL_FMRI, B_TRUE);
17500Sstevel@tonic-gate 		if (ret != CLIENT_SUCCESS) {
17510Sstevel@tonic-gate 			/* Not serious, but tell user what to do */
17520Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Stopping sendmail "
17530Sstevel@tonic-gate 				"failed with (%d). You may need to restart "
17540Sstevel@tonic-gate 				"it manually for changes to take effect.\n"),
17550Sstevel@tonic-gate 				ret);
17560Sstevel@tonic-gate 		} else enableFlag |= SENDMAIL_ON;
17570Sstevel@tonic-gate 	} else {
17580Sstevel@tonic-gate 		if (mode_verbose)
17590Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("sendmail not running\n"), stderr);
17600Sstevel@tonic-gate 	}
17610Sstevel@tonic-gate 
17620Sstevel@tonic-gate 	if (!is_service(NSCD_FMRI, SCF_STATE_STRING_DISABLED)) {
17630Sstevel@tonic-gate 		if (mode_verbose)
17640Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Stopping nscd\n"), stderr);
17650Sstevel@tonic-gate 		ret = disable_service(NSCD_FMRI, B_TRUE);
17660Sstevel@tonic-gate 		if (ret != CLIENT_SUCCESS) {
17670Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Stopping nscd "
17680Sstevel@tonic-gate 			    "failed with (%d)\n"), ret);
17690Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
17700Sstevel@tonic-gate 		} else enableFlag |= NSCD_ON;
17710Sstevel@tonic-gate 	} else {
17720Sstevel@tonic-gate 		if (mode_verbose)
17730Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("nscd not running\n"), stderr);
17740Sstevel@tonic-gate 	}
17750Sstevel@tonic-gate 
17760Sstevel@tonic-gate 	if (!is_service(AUTOFS_FMRI, SCF_STATE_STRING_DISABLED)) {
17770Sstevel@tonic-gate 		if (mode_verbose)
17780Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Stopping autofs\n"), stderr);
17790Sstevel@tonic-gate 		ret = disable_service(AUTOFS_FMRI, B_TRUE);
17800Sstevel@tonic-gate 		if (ret != CLIENT_SUCCESS) {
17810Sstevel@tonic-gate 			/* Not serious, but tell user what to do */
17820Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Stopping autofs "
17830Sstevel@tonic-gate 				"failed with (%d). You may need to restart "
17840Sstevel@tonic-gate 				"it manually for changes to take effect.\n"),
17850Sstevel@tonic-gate 				ret);
17860Sstevel@tonic-gate 		} else enableFlag |= AUTOFS_ON;
17870Sstevel@tonic-gate 	} else {
17880Sstevel@tonic-gate 		if (mode_verbose)
17890Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("autofs not running\n"), stderr);
17900Sstevel@tonic-gate 	}
17910Sstevel@tonic-gate 
17920Sstevel@tonic-gate 	if (!is_service(LDAP_FMRI, SCF_STATE_STRING_DISABLED)) {
17930Sstevel@tonic-gate 		if (saveState)
17940Sstevel@tonic-gate 			gStartLdap = START_RESET;
17950Sstevel@tonic-gate 		if (mode_verbose)
17960Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Stopping ldap\n"), stderr);
17970Sstevel@tonic-gate 		ret = disable_service(LDAP_FMRI, B_TRUE);
17980Sstevel@tonic-gate 		if (ret != CLIENT_SUCCESS) {
17990Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Stopping ldap "
18000Sstevel@tonic-gate 			    "failed with (%d)\n"), ret);
18010Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
18020Sstevel@tonic-gate 		}
18030Sstevel@tonic-gate 	} else {
18040Sstevel@tonic-gate 		if (mode_verbose)
18050Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("ldap not running\n"),
18060Sstevel@tonic-gate 								stderr);
18070Sstevel@tonic-gate 	}
18080Sstevel@tonic-gate 
18090Sstevel@tonic-gate 	if (!is_service(NISD_FMRI, SCF_STATE_STRING_DISABLED)) {
18100Sstevel@tonic-gate 		if (mode_verbose)
18110Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Stopping nisd\n"), stderr);
18120Sstevel@tonic-gate 		ret = disable_service(NISD_FMRI, B_TRUE);
18130Sstevel@tonic-gate 		if (ret != CLIENT_SUCCESS) {
18140Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Stopping nisd "
18150Sstevel@tonic-gate 			    "failed with (%d)\n"), ret);
18160Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
18170Sstevel@tonic-gate 		}
18180Sstevel@tonic-gate 	} else {
18190Sstevel@tonic-gate 		if (mode_verbose)
18200Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("nisd not running\n"),
18210Sstevel@tonic-gate 								stderr);
18220Sstevel@tonic-gate 	}
18230Sstevel@tonic-gate 
18240Sstevel@tonic-gate 	if (!is_service(YP_FMRI, SCF_STATE_STRING_DISABLED)) {
18250Sstevel@tonic-gate 		if (saveState)
18260Sstevel@tonic-gate 			gStartYp = START_RESET;
18270Sstevel@tonic-gate 		if (mode_verbose)
18280Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Stopping nis(yp)\n"), stderr);
18290Sstevel@tonic-gate 		ret = disable_service(YP_FMRI, B_TRUE);
18300Sstevel@tonic-gate 		if (ret != 0) {
18310Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Stopping nis(yp) "
18320Sstevel@tonic-gate 			    "failed with (%d)\n"), ret);
18330Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
18340Sstevel@tonic-gate 		}
18350Sstevel@tonic-gate 	} else {
18360Sstevel@tonic-gate 		if (mode_verbose)
18370Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("nis(yp) not running\n"),
18380Sstevel@tonic-gate 								stderr);
18390Sstevel@tonic-gate 	}
18400Sstevel@tonic-gate 
18410Sstevel@tonic-gate 	return (CLIENT_SUCCESS);
18420Sstevel@tonic-gate }
18430Sstevel@tonic-gate 
18440Sstevel@tonic-gate /*
18450Sstevel@tonic-gate  * start_services is called to start up network services after config
18460Sstevel@tonic-gate  * files have all been setup or recovered.  In the case of an error, the
18470Sstevel@tonic-gate  * files will be recovered and start_services will be called with the
18480Sstevel@tonic-gate  * "reset" flag set so that only those services that were earlier stopped
18490Sstevel@tonic-gate  * will be started.  If it is not a reset, then the services associated
18500Sstevel@tonic-gate  * with files "recovered" will attempt to be started.
18510Sstevel@tonic-gate  */
18520Sstevel@tonic-gate static int
18530Sstevel@tonic-gate start_services(int flag)
18540Sstevel@tonic-gate {
18550Sstevel@tonic-gate 	int sysret, retcode = CLIENT_SUCCESS;
18560Sstevel@tonic-gate 	FILE *domain_fp;
18570Sstevel@tonic-gate 	char domainname[BUFSIZ];
18580Sstevel@tonic-gate 	char cmd_domain_start[BUFSIZ];
18590Sstevel@tonic-gate 	int domainlen;
18600Sstevel@tonic-gate 
18610Sstevel@tonic-gate 	if (mode_verbose) {
18620Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Starting network services\n"), stderr);
18630Sstevel@tonic-gate 	}
18640Sstevel@tonic-gate 
18650Sstevel@tonic-gate 	/* Read in current defaultdomain so we can set it */
18660Sstevel@tonic-gate 	domain_fp = fopen(DOMAINNAME, "r");
18670Sstevel@tonic-gate 	if (domain_fp == NULL) {
18680Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr, gettext("Error opening defaultdomain "
18690Sstevel@tonic-gate 							"(%d)\n"), errno);
18700Sstevel@tonic-gate 		/* if we did an ldap init, we must have domain */
18710Sstevel@tonic-gate 		if (flag == START_INIT)
18720Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
18730Sstevel@tonic-gate 	} else {
18740Sstevel@tonic-gate 		if (fgets(domainname, BUFSIZ, domain_fp) == NULL) {
18750Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Error reading defaultdomain\n"),
18760Sstevel@tonic-gate 				stderr);
18770Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
18780Sstevel@tonic-gate 		}
18790Sstevel@tonic-gate 
18800Sstevel@tonic-gate 		if (fclose(domain_fp) != 0) {
18810Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
18820Sstevel@tonic-gate 				gettext("Error closing defaultdomain (%d)\n"),
18830Sstevel@tonic-gate 				errno);
18840Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
18850Sstevel@tonic-gate 		}
18860Sstevel@tonic-gate 		domainlen = strlen(domainname);
18870Sstevel@tonic-gate 		/* sanity check to make sure sprintf will fit */
18880Sstevel@tonic-gate 		if (domainlen > (BUFSIZE - sizeof (CMD_DOMAIN_START) -
18890Sstevel@tonic-gate 						sizeof (TO_DEV_NULL) - 3)) {
18900Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Specified domainname is "
18910Sstevel@tonic-gate 						"too large\n"), stderr);
18920Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
18930Sstevel@tonic-gate 		}
18940Sstevel@tonic-gate 		if (domainname[domainlen-1] == '\n')
18950Sstevel@tonic-gate 			domainname[domainlen-1] = 0;
18960Sstevel@tonic-gate 		/* buffer size is checked above */
18970Sstevel@tonic-gate 		(void) sprintf(cmd_domain_start, "%s %s %s", CMD_DOMAIN_START,
18980Sstevel@tonic-gate 						domainname, TO_DEV_NULL);
18990Sstevel@tonic-gate 	}
19000Sstevel@tonic-gate 
19010Sstevel@tonic-gate 	/*
19020Sstevel@tonic-gate 	 * We can be starting services after an init in which case
19030Sstevel@tonic-gate 	 * we want to start ldap and not start yp or nis+.
19040Sstevel@tonic-gate 	 */
19050Sstevel@tonic-gate 	if (flag == START_INIT) {
19060Sstevel@tonic-gate 		sysret = system(cmd_domain_start);
19070Sstevel@tonic-gate 		if (mode_verbose)
19080Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, "start: %s %s... %s\n",
19090Sstevel@tonic-gate 					CMD_DOMAIN_START, domainname,
19100Sstevel@tonic-gate 					(sysret == 0) ? gettext("success") :
19110Sstevel@tonic-gate 							gettext("failed"));
19120Sstevel@tonic-gate 		if (sysret != 0) {
19130Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("\"%s\" returned: %d\n"),
19140Sstevel@tonic-gate 					CMD_DOMAIN_START, sysret);
19150Sstevel@tonic-gate 
19160Sstevel@tonic-gate 			retcode = CLIENT_ERR_FAIL;
19170Sstevel@tonic-gate 		}
19180Sstevel@tonic-gate 
19190Sstevel@tonic-gate 		if (start_service(LDAP_FMRI, B_TRUE) != CLIENT_SUCCESS)
19200Sstevel@tonic-gate 			retcode = CLIENT_ERR_FAIL;
19210Sstevel@tonic-gate 
19220Sstevel@tonic-gate 		/* No YP or NIS+ after init */
19230Sstevel@tonic-gate 	/*
19240Sstevel@tonic-gate 	 * Or we can be starting services after an uninit or error
19250Sstevel@tonic-gate 	 * recovery.  We want to start whatever services were running
19260Sstevel@tonic-gate 	 * before.  In the case of error recovery, it is the services
19270Sstevel@tonic-gate 	 * that were running before we stopped them (flags set in
19280Sstevel@tonic-gate 	 * stop_services).  If it is an uninit then we determine
19290Sstevel@tonic-gate 	 * which services to start based on the files we recovered
19300Sstevel@tonic-gate 	 * (flags set in recover).
19310Sstevel@tonic-gate 	 */
19320Sstevel@tonic-gate 	} else {
19330Sstevel@tonic-gate 		/* uninit and recover should set flags of what to start */
19340Sstevel@tonic-gate 		if (domain_fp) {
19350Sstevel@tonic-gate 			sysret = system(cmd_domain_start);
19360Sstevel@tonic-gate 			if (mode_verbose)
19370Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr, "start: %s %s... %s\n",
19380Sstevel@tonic-gate 					CMD_DOMAIN_START, domainname,
19390Sstevel@tonic-gate 					(sysret == 0) ? gettext("success") :
19400Sstevel@tonic-gate 							gettext("failed"));
19410Sstevel@tonic-gate 			if (sysret != 0) {
19420Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr, gettext("\"%s\" "
19430Sstevel@tonic-gate 						"returned: %d\n"),
19440Sstevel@tonic-gate 						CMD_DOMAIN_START, sysret);
19450Sstevel@tonic-gate 
19460Sstevel@tonic-gate 				retcode = CLIENT_ERR_FAIL;
19470Sstevel@tonic-gate 			}
19480Sstevel@tonic-gate 		}
19490Sstevel@tonic-gate 
19500Sstevel@tonic-gate 		if (gStartLdap == flag) {
19510Sstevel@tonic-gate 			if (!(is_service(LDAP_FMRI, SCF_STATE_STRING_ONLINE)))
19520Sstevel@tonic-gate 				if (start_service(LDAP_FMRI, B_TRUE)
19530Sstevel@tonic-gate 							!= CLIENT_SUCCESS)
19540Sstevel@tonic-gate 					retcode = CLIENT_ERR_FAIL;
19550Sstevel@tonic-gate 		}
19560Sstevel@tonic-gate 
19570Sstevel@tonic-gate 		if (gStartYp == flag) {
19580Sstevel@tonic-gate 			if (!(is_service(YP_FMRI, SCF_STATE_STRING_ONLINE)))
19590Sstevel@tonic-gate 				(void) start_service(YP_FMRI, B_TRUE);
19600Sstevel@tonic-gate 		}
19610Sstevel@tonic-gate 
19620Sstevel@tonic-gate 		if (gStartNisd == flag) {
19630Sstevel@tonic-gate 			if (!(is_service(NISD_FMRI, SCF_STATE_STRING_ONLINE)))
19640Sstevel@tonic-gate 				(void) start_service(NISD_FMRI, B_TRUE);
19650Sstevel@tonic-gate 		}
19660Sstevel@tonic-gate 
19670Sstevel@tonic-gate 	}
19680Sstevel@tonic-gate 	if ((enableFlag & AUTOFS_ON) &&
19690Sstevel@tonic-gate 	    !(is_service(AUTOFS_FMRI, SCF_STATE_STRING_ONLINE)))
19700Sstevel@tonic-gate 		(void) start_service(AUTOFS_FMRI, B_TRUE);
19710Sstevel@tonic-gate 
19720Sstevel@tonic-gate 	if ((enableFlag & NSCD_ON) &&
19730Sstevel@tonic-gate 	    !(is_service(NSCD_FMRI, SCF_STATE_STRING_ONLINE)))
19740Sstevel@tonic-gate 		(void) start_service(NSCD_FMRI, B_TRUE);
19750Sstevel@tonic-gate 
19760Sstevel@tonic-gate 	if ((enableFlag & SENDMAIL_ON) &&
19770Sstevel@tonic-gate 	    !(is_service(SENDMAIL_FMRI, SCF_STATE_STRING_ONLINE)))
19780Sstevel@tonic-gate 		(void) start_service(SENDMAIL_FMRI, B_TRUE);
19790Sstevel@tonic-gate 
19800Sstevel@tonic-gate 	/*
19810Sstevel@tonic-gate 	 * Restart name-service milestone so that any consumer
19820Sstevel@tonic-gate 	 * which depends on it will be restarted.
19830Sstevel@tonic-gate 	 */
19840Sstevel@tonic-gate 	(void) restart_service(NS_MILESTONE_FMRI, B_TRUE);
19850Sstevel@tonic-gate 	return (retcode);
19860Sstevel@tonic-gate }
19870Sstevel@tonic-gate 
19880Sstevel@tonic-gate /*
19890Sstevel@tonic-gate  * credCheck is called to check if credentials are required for this
19900Sstevel@tonic-gate  * configuration.  Currently, this means that if any credentialLevel is
19910Sstevel@tonic-gate  * proxy and any authenticationMethod is something other than none, then
19920Sstevel@tonic-gate  * credential info is required (proxyDN and proxyPassword).
19930Sstevel@tonic-gate  */
19940Sstevel@tonic-gate static int
19950Sstevel@tonic-gate credCheck(clientopts_t *arglist)
19960Sstevel@tonic-gate {
19970Sstevel@tonic-gate 	int counter;
19980Sstevel@tonic-gate 	int **credLevel;
19990Sstevel@tonic-gate 	ns_auth_t **authMethod;
20000Sstevel@tonic-gate 	char **proxyDN, **proxyPassword;
20010Sstevel@tonic-gate 	ns_ldap_error_t *errorp;
20020Sstevel@tonic-gate 	int credProxy, authNotNone;
20030Sstevel@tonic-gate 	int retcode;
20040Sstevel@tonic-gate 
20050Sstevel@tonic-gate /* If credentialLevel is proxy, make sure we have proxyDN and proxyPassword */
20060Sstevel@tonic-gate 	retcode = __ns_ldap_getParam(NS_LDAP_CREDENTIAL_LEVEL_P,
20070Sstevel@tonic-gate 			(void ***)&credLevel, &errorp);
20080Sstevel@tonic-gate 	if (retcode != 0) {
20090Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
20100Sstevel@tonic-gate 			gettext("Error %d while trying to retrieve "
20110Sstevel@tonic-gate 				"credLevel\n"),
20120Sstevel@tonic-gate 			retcode);
20130Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
20140Sstevel@tonic-gate 	}
20150Sstevel@tonic-gate 	retcode = __ns_ldap_getParam(NS_LDAP_AUTH_P,
20160Sstevel@tonic-gate 			(void ***)&authMethod, &errorp);
20170Sstevel@tonic-gate 	if (retcode != 0) {
20180Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
20190Sstevel@tonic-gate 			gettext("Error %d while trying to retrieve "
20200Sstevel@tonic-gate 				"authMethod\n"), retcode);
20210Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
20220Sstevel@tonic-gate 	}
20230Sstevel@tonic-gate 	retcode = __ns_ldap_getParam(NS_LDAP_BINDDN_P,
20240Sstevel@tonic-gate 			(void ***)&proxyDN, &errorp);
20250Sstevel@tonic-gate 	if (retcode != 0) {
20260Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
20270Sstevel@tonic-gate 			gettext("Error %d while trying to retrieve proxyDN\n"),
20280Sstevel@tonic-gate 			retcode);
20290Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
20300Sstevel@tonic-gate 	}
20310Sstevel@tonic-gate 	retcode = __ns_ldap_getParam(NS_LDAP_BINDPASSWD_P,
20320Sstevel@tonic-gate 			(void ***)&proxyPassword, &errorp);
20330Sstevel@tonic-gate 	if (retcode != 0) {
20340Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
20350Sstevel@tonic-gate 			gettext("Error %d while trying to retrieve "
20360Sstevel@tonic-gate 				"proxyPassword\n"), retcode);
20370Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
20380Sstevel@tonic-gate 	}
20390Sstevel@tonic-gate 
20400Sstevel@tonic-gate 	if (mode_verbose) {
20410Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
20420Sstevel@tonic-gate 			gettext("Proxy DN: %s\n"),
20430Sstevel@tonic-gate 			(proxyDN && proxyDN[0]) ? proxyDN[0] : "NULL");
20440Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
20450Sstevel@tonic-gate 			gettext("Proxy password: %s\n"),
20460Sstevel@tonic-gate 			(proxyPassword && proxyPassword[0]) ?
20470Sstevel@tonic-gate 				proxyPassword[0] : "NULL");
20480Sstevel@tonic-gate 	}
20490Sstevel@tonic-gate 
20500Sstevel@tonic-gate 	credProxy = 0;	/* flag to indicate if we have a credLevel of proxy */
20510Sstevel@tonic-gate 	for (counter = 0; credLevel && credLevel[counter] != NULL; counter++) {
20520Sstevel@tonic-gate 		if (mode_verbose)
20530Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
20540Sstevel@tonic-gate 				gettext("Credential level: %d\n"),
20550Sstevel@tonic-gate 				*credLevel[counter]);
20560Sstevel@tonic-gate 		if (*credLevel[counter] == NS_LDAP_CRED_PROXY) {
20570Sstevel@tonic-gate 			credProxy = 1;
20580Sstevel@tonic-gate 			break;
20590Sstevel@tonic-gate 		}
20600Sstevel@tonic-gate 	}
20610Sstevel@tonic-gate 
20620Sstevel@tonic-gate 	authNotNone = 0;	/* flag for authMethod other than none */
20630Sstevel@tonic-gate 	for (counter = 0;
20640Sstevel@tonic-gate 		authMethod && authMethod[counter] != NULL;
20650Sstevel@tonic-gate 		counter++) {
20660Sstevel@tonic-gate 
20670Sstevel@tonic-gate 		if (mode_verbose)
20680Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
20690Sstevel@tonic-gate 				gettext("Authentication method: %d\n"),
20700Sstevel@tonic-gate 				authMethod[counter]->type);
20710Sstevel@tonic-gate 		if (authMethod[counter]->type != NS_LDAP_AUTH_NONE &&
20720Sstevel@tonic-gate 		    !(authMethod[counter]->type == NS_LDAP_AUTH_TLS &&
20730Sstevel@tonic-gate 		    authMethod[counter]->tlstype == NS_LDAP_TLS_NONE)) {
20740Sstevel@tonic-gate 			authNotNone = 1;
20750Sstevel@tonic-gate 			break;
20760Sstevel@tonic-gate 		}
20770Sstevel@tonic-gate 	}
20780Sstevel@tonic-gate 
20790Sstevel@tonic-gate 	/* First, if we don't need proxyDN/Password then just return ok */
20800Sstevel@tonic-gate 	if (!(credProxy && authNotNone)) {
20810Sstevel@tonic-gate 		if (mode_verbose)
20820Sstevel@tonic-gate 			CLIENT_FPUTS(
20830Sstevel@tonic-gate 				gettext("No proxyDN/proxyPassword required\n"),
20840Sstevel@tonic-gate 				stderr);
20850Sstevel@tonic-gate 		return (CLIENT_SUCCESS);
20860Sstevel@tonic-gate 	}
20870Sstevel@tonic-gate 
20880Sstevel@tonic-gate 	/* Now let's check if we have the cred stuff we need */
20890Sstevel@tonic-gate 	if (!proxyDN || !proxyDN[0]) {
20900Sstevel@tonic-gate 		CLIENT_FPUTS(
20910Sstevel@tonic-gate 			gettext("credentialLevel is proxy and no proxyDN "
20920Sstevel@tonic-gate 				"specified\n"),
20930Sstevel@tonic-gate 			stderr);
20940Sstevel@tonic-gate 		return (CLIENT_ERR_CREDENTIAL);
20950Sstevel@tonic-gate 	}
20960Sstevel@tonic-gate 
20970Sstevel@tonic-gate 	/* If we need proxyPassword (prompt) */
20980Sstevel@tonic-gate 	if (!proxyPassword || !proxyPassword[0]) {
20990Sstevel@tonic-gate 		CLIENT_FPUTS(
21000Sstevel@tonic-gate 			gettext("credentialLevel requires proxyPassword\n"),
21010Sstevel@tonic-gate 			stderr);
21020Sstevel@tonic-gate 		arglist->proxyPassword = getpassphrase("Proxy Bind Password:");
21030Sstevel@tonic-gate 		if (arglist->proxyPassword == NULL) {
21040Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Get password failed\n"), stderr);
21050Sstevel@tonic-gate 			return (CLIENT_ERR_CREDENTIAL);
21060Sstevel@tonic-gate 		}
21070Sstevel@tonic-gate 		LDAP_SET_PARAM(arglist->proxyPassword, NS_LDAP_BINDPASSWD_P);
21080Sstevel@tonic-gate 		if (retcode != 0) {
21090Sstevel@tonic-gate 			CLIENT_FPUTS(
21100Sstevel@tonic-gate 				gettext("setParam proxyPassword failed.\n"),
21110Sstevel@tonic-gate 				stderr);
21120Sstevel@tonic-gate 			return (CLIENT_ERR_CREDENTIAL);
21130Sstevel@tonic-gate 		}
21140Sstevel@tonic-gate 	}
21150Sstevel@tonic-gate 
21160Sstevel@tonic-gate 	return (CLIENT_SUCCESS);
21170Sstevel@tonic-gate }
21180Sstevel@tonic-gate 
21190Sstevel@tonic-gate /*
21200Sstevel@tonic-gate  * try to restore the previous name space on this machine
21210Sstevel@tonic-gate  */
21220Sstevel@tonic-gate static int
21230Sstevel@tonic-gate recover(int saveState)
21240Sstevel@tonic-gate {
21250Sstevel@tonic-gate 	struct stat buf;
21260Sstevel@tonic-gate 	int stat_ret, retcode, fd;
21270Sstevel@tonic-gate 	int domain = 0, domainlen;
21280Sstevel@tonic-gate 	char yp_dir[BUFSIZE], yp_dir_back[BUFSIZE];
21290Sstevel@tonic-gate 	char name[BUFSIZ];
21300Sstevel@tonic-gate 	char *ldap_conf_file, *ldap_cred_file;
21310Sstevel@tonic-gate 	char ldap_file_back[BUFSIZE], ldap_cred_back[BUFSIZE];
21320Sstevel@tonic-gate 
21330Sstevel@tonic-gate 	/* If running as Sysid Install become a no-op */
21340Sstevel@tonic-gate 	if (sysid_install == B_TRUE)
21350Sstevel@tonic-gate 		return (CLIENT_SUCCESS);
21360Sstevel@tonic-gate 
21370Sstevel@tonic-gate 	stat_ret = stat(LDAP_RESTORE_DIR, &buf);
21380Sstevel@tonic-gate 	if (stat_ret != 0) {
21390Sstevel@tonic-gate 		CLIENT_FPUTS(
21400Sstevel@tonic-gate 			gettext("Cannot recover.  No backup files "
21410Sstevel@tonic-gate 				"found.\n"),
21420Sstevel@tonic-gate 			stderr);
21430Sstevel@tonic-gate 		CLIENT_FPUTS(
21440Sstevel@tonic-gate 			gettext("\t Either this machine was not initialized\n"),
21450Sstevel@tonic-gate 			stderr);
21460Sstevel@tonic-gate 		CLIENT_FPUTS(
21470Sstevel@tonic-gate 			gettext("\t by ldapclient or the backup files "
21480Sstevel@tonic-gate 				"have been\n"),
21490Sstevel@tonic-gate 			stderr);
21500Sstevel@tonic-gate 		CLIENT_FPUTS(
21510Sstevel@tonic-gate 			gettext("\t removed manually or with an \"uninit\"\n"),
21520Sstevel@tonic-gate 			stderr);
21530Sstevel@tonic-gate 		return (CLIENT_ERR_RESTORE);	/* invalid backup */
21540Sstevel@tonic-gate 	}
21550Sstevel@tonic-gate 
21560Sstevel@tonic-gate 	/*
21570Sstevel@tonic-gate 	 * Get domainname.  Allow no domainname for the case where "files"
21580Sstevel@tonic-gate 	 * config was backed up.
21590Sstevel@tonic-gate 	 */
21600Sstevel@tonic-gate 	stat_ret = stat(DOMAINNAME_BACK, &buf);
21610Sstevel@tonic-gate 	if (mode_verbose)
21620Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
21630Sstevel@tonic-gate 			gettext("recover: stat(%s)=%d\n"),
21640Sstevel@tonic-gate 			DOMAINNAME_BACK, stat_ret);
21650Sstevel@tonic-gate 	if (stat_ret == 0) {
21660Sstevel@tonic-gate 		if (mode_verbose)
21670Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
21680Sstevel@tonic-gate 				gettext("recover: open(%s)\n"),
21690Sstevel@tonic-gate 					DOMAINNAME_BACK);
21700Sstevel@tonic-gate 		fd = open(DOMAINNAME_BACK, O_RDONLY);
21710Sstevel@tonic-gate 		if (mode_verbose)
21720Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
21730Sstevel@tonic-gate 				gettext("recover: read(%s)\n"),
21740Sstevel@tonic-gate 					DOMAINNAME_BACK);
21750Sstevel@tonic-gate 		domainlen = read(fd, &(name[0]), BUFSIZ-1);
21760Sstevel@tonic-gate 		(void) close(fd);
21770Sstevel@tonic-gate 		if (domainlen < 0) {
21780Sstevel@tonic-gate 			CLIENT_FPUTS(
21790Sstevel@tonic-gate 				gettext("Cannot recover.  Cannot determine "
21800Sstevel@tonic-gate 					"previous domain name.\n"),
21810Sstevel@tonic-gate 				stderr);
21820Sstevel@tonic-gate 			return (CLIENT_ERR_RESTORE);	/* invalid backup */
21830Sstevel@tonic-gate 		} else 	{
21840Sstevel@tonic-gate 			char *ptr;
21850Sstevel@tonic-gate 
21860Sstevel@tonic-gate 			ptr = strchr(&(name[0]), '\n');
21870Sstevel@tonic-gate 			if (ptr != NULL)
21880Sstevel@tonic-gate 				*ptr = '\0';
21890Sstevel@tonic-gate 			else
21900Sstevel@tonic-gate 				name[domainlen] = '\0';
21910Sstevel@tonic-gate 
21920Sstevel@tonic-gate 			if (mode_verbose)
21930Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
21940Sstevel@tonic-gate 					gettext("recover: old domainname "
21950Sstevel@tonic-gate 						"\"%s\"\n"), name);
21960Sstevel@tonic-gate 
21970Sstevel@tonic-gate 			if (strlen(name) == 0)
21980Sstevel@tonic-gate 				domain = 0;
21990Sstevel@tonic-gate 			else
22000Sstevel@tonic-gate 				domain = 1;	/* flag that we have domain */
22010Sstevel@tonic-gate 
22020Sstevel@tonic-gate 		}
22030Sstevel@tonic-gate 	}
22040Sstevel@tonic-gate 
22050Sstevel@tonic-gate 
22060Sstevel@tonic-gate 	/*
22070Sstevel@tonic-gate 	 * we can recover at this point
22080Sstevel@tonic-gate 	 * remove LDAP config files before restore
22090Sstevel@tonic-gate 	 */
22100Sstevel@tonic-gate 	(void) unlink(NSCONFIGFILE);
22110Sstevel@tonic-gate 	(void) unlink(NSCREDFILE);
22120Sstevel@tonic-gate 
22130Sstevel@tonic-gate 	ldap_conf_file = strrchr(NSCONFIGFILE, '/') + 1;
22140Sstevel@tonic-gate 	ldap_cred_file = strrchr(NSCREDFILE, '/') + 1;
22150Sstevel@tonic-gate 
22160Sstevel@tonic-gate 	(void) strlcpy(ldap_file_back, LDAP_RESTORE_DIR "/", BUFSIZE);
22170Sstevel@tonic-gate 	(void) strlcat(ldap_file_back, ldap_conf_file, BUFSIZE);
22180Sstevel@tonic-gate 
22190Sstevel@tonic-gate 	stat_ret = stat(ldap_file_back, &buf);
22200Sstevel@tonic-gate 	if (mode_verbose)
22210Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
22220Sstevel@tonic-gate 			gettext("recover: stat(%s)=%d\n"),
22230Sstevel@tonic-gate 			ldap_file_back, stat_ret);
22240Sstevel@tonic-gate 	if (stat_ret == 0) {
22250Sstevel@tonic-gate 		if (saveState)
22260Sstevel@tonic-gate 			gStartLdap = START_UNINIT;
22270Sstevel@tonic-gate 		retcode = file_move(ldap_file_back, NSCONFIGFILE);
22280Sstevel@tonic-gate 		if (mode_verbose)
22290Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
22300Sstevel@tonic-gate 				gettext("recover: file_move(%s, %s)=%d\n"),
22310Sstevel@tonic-gate 				ldap_file_back, NSCONFIGFILE, retcode);
22320Sstevel@tonic-gate 		if (retcode != 0)
22330Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
22340Sstevel@tonic-gate 				gettext("recover: file_move(%s, %s) failed\n"),
22350Sstevel@tonic-gate 				ldap_file_back, NSCONFIGFILE);
22360Sstevel@tonic-gate 	}
22370Sstevel@tonic-gate 
22380Sstevel@tonic-gate 	(void) strlcpy(ldap_cred_back, LDAP_RESTORE_DIR "/", BUFSIZE);
22390Sstevel@tonic-gate 	(void) strlcat(ldap_cred_back, ldap_cred_file, BUFSIZE);
22400Sstevel@tonic-gate 
22410Sstevel@tonic-gate 	stat_ret = stat(ldap_cred_back, &buf);
22420Sstevel@tonic-gate 	if (mode_verbose)
22430Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
22440Sstevel@tonic-gate 			gettext("recover: stat(%s)=%d\n"),
22450Sstevel@tonic-gate 			ldap_cred_back, stat_ret);
22460Sstevel@tonic-gate 	if (stat_ret == 0) {
22470Sstevel@tonic-gate 		retcode = file_move(ldap_cred_back, NSCREDFILE);
22480Sstevel@tonic-gate 		if (mode_verbose)
22490Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
22500Sstevel@tonic-gate 				gettext("recover: file_move(%s, %s)=%d\n"),
22510Sstevel@tonic-gate 				ldap_cred_back, NSCREDFILE, retcode);
22520Sstevel@tonic-gate 		if (retcode != 0)
22530Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
22540Sstevel@tonic-gate 				gettext("recover: file_move(%s, %s) failed\n"),
22550Sstevel@tonic-gate 				ldap_cred_back, NSCREDFILE);
22560Sstevel@tonic-gate 	}
22570Sstevel@tonic-gate 
22580Sstevel@tonic-gate 	/* Check for recovery of NIS+ */
22590Sstevel@tonic-gate 	stat_ret = stat(NIS_COLDSTART_BACK, &buf);
22600Sstevel@tonic-gate 	if (mode_verbose)
22610Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
22620Sstevel@tonic-gate 			gettext("recover: stat(%s)=%d\n"),
22630Sstevel@tonic-gate 			NIS_COLDSTART_BACK, stat_ret);
22640Sstevel@tonic-gate 	if (stat_ret == 0) {
22650Sstevel@tonic-gate 		if (saveState) {
22660Sstevel@tonic-gate 			gStartNisd = START_UNINIT;
22670Sstevel@tonic-gate 		}
22680Sstevel@tonic-gate 		if (mode_verbose)
22690Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
22700Sstevel@tonic-gate 				gettext("recover: file_move(%s, %s)\n"),
22710Sstevel@tonic-gate 				NIS_COLDSTART_BACK, NIS_COLDSTART);
22720Sstevel@tonic-gate 		retcode = file_move(NIS_COLDSTART_BACK, NIS_COLDSTART);
22730Sstevel@tonic-gate 		if (retcode != 0)
22740Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
22750Sstevel@tonic-gate 				gettext("recover: file_move(%s, %s) failed!\n"),
22760Sstevel@tonic-gate 				NIS_COLDSTART_BACK, NIS_COLDSTART);
22770Sstevel@tonic-gate 	}
22780Sstevel@tonic-gate 
22790Sstevel@tonic-gate 	/* Check for recovery of NIS(YP) if we have a domainname */
22800Sstevel@tonic-gate 	if (domain) {
22810Sstevel@tonic-gate 		/* "name" would have to be huge for this, but just in case */
22820Sstevel@tonic-gate 		if (strlen(name) >= (BUFSIZE - strlen(LDAP_RESTORE_DIR)))
22830Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
22840Sstevel@tonic-gate 		if (strlen(name) >= (BUFSIZE - strlen(YP_BIND_DIR)))
22850Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
22860Sstevel@tonic-gate 
22870Sstevel@tonic-gate 		(void) strlcpy(yp_dir_back, LDAP_RESTORE_DIR "/", BUFSIZE);
22880Sstevel@tonic-gate 		(void) strlcat(yp_dir_back, name, BUFSIZE);
22890Sstevel@tonic-gate 		stat_ret = stat(yp_dir_back, &buf);
22900Sstevel@tonic-gate 		if (mode_verbose)
22910Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
22920Sstevel@tonic-gate 				gettext("recover: stat(%s)=%d\n"),
22930Sstevel@tonic-gate 				yp_dir_back, stat_ret);
22940Sstevel@tonic-gate 		if (stat_ret == 0) {
22950Sstevel@tonic-gate 			(void) strlcpy(yp_dir, YP_BIND_DIR "/", BUFSIZE);
22960Sstevel@tonic-gate 			(void) strlcat(yp_dir, name, BUFSIZE);
22970Sstevel@tonic-gate 			retcode = file_move(yp_dir_back, yp_dir);
22980Sstevel@tonic-gate 			if (mode_verbose)
22990Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
23000Sstevel@tonic-gate 					gettext("recover: file_move(%s, "
23010Sstevel@tonic-gate 						"%s)=%d\n"),
23020Sstevel@tonic-gate 					yp_dir_back, yp_dir, retcode);
23030Sstevel@tonic-gate 			if (retcode != 0) {
23040Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
23050Sstevel@tonic-gate 					gettext("recover: file_move(%s, "
23060Sstevel@tonic-gate 						"%s) failed!\n"),
23070Sstevel@tonic-gate 					yp_dir_back, yp_dir);
23080Sstevel@tonic-gate 			} else {
23090Sstevel@tonic-gate 				if (saveState)
23100Sstevel@tonic-gate 					gStartYp = START_UNINIT;
23110Sstevel@tonic-gate 			}
23120Sstevel@tonic-gate 		}
23130Sstevel@tonic-gate 	}
23140Sstevel@tonic-gate 
23150Sstevel@tonic-gate 	/* restore machine configuration */
23160Sstevel@tonic-gate 	stat_ret = stat(NSSWITCH_BACK, &buf);
23170Sstevel@tonic-gate 	if (mode_verbose)
23180Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
23190Sstevel@tonic-gate 			gettext("recover: stat(%s)=%d\n"),
23200Sstevel@tonic-gate 			NSSWITCH_BACK, stat_ret);
23210Sstevel@tonic-gate 	if (stat_ret == 0) {
23220Sstevel@tonic-gate 		retcode = file_move(NSSWITCH_BACK, NSSWITCH_CONF);
23230Sstevel@tonic-gate 		if (mode_verbose)
23240Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
23250Sstevel@tonic-gate 				gettext("recover: file_move(%s, %s)=%d\n"),
23260Sstevel@tonic-gate 				NSSWITCH_BACK, NSSWITCH_CONF, retcode);
23270Sstevel@tonic-gate 		if (retcode != 0)
23280Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
23290Sstevel@tonic-gate 				gettext("recover: file_move(%s, %s) failed\n"),
23300Sstevel@tonic-gate 				NSSWITCH_BACK, NSSWITCH_CONF);
23310Sstevel@tonic-gate 	}
23320Sstevel@tonic-gate 
23330Sstevel@tonic-gate 	stat_ret = stat(DOMAINNAME_BACK, &buf);
23340Sstevel@tonic-gate 	if (mode_verbose)
23350Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
23360Sstevel@tonic-gate 			gettext("recover: stat(%s)=%d\n"),
23370Sstevel@tonic-gate 			DOMAINNAME_BACK, stat_ret);
23380Sstevel@tonic-gate 	if (stat_ret == 0) {
23390Sstevel@tonic-gate 		retcode = file_move(DOMAINNAME_BACK, DOMAINNAME);
23400Sstevel@tonic-gate 		if (mode_verbose)
23410Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
23420Sstevel@tonic-gate 				gettext("recover: file_move(%s, %s)=%d\n"),
23430Sstevel@tonic-gate 				DOMAINNAME_BACK, DOMAINNAME, retcode);
23440Sstevel@tonic-gate 		if (retcode != 0)
23450Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
23460Sstevel@tonic-gate 				gettext("recover: file_move(%s, %s) failed\n"),
23470Sstevel@tonic-gate 				DOMAINNAME_BACK, DOMAINNAME);
23480Sstevel@tonic-gate 	}
23490Sstevel@tonic-gate 
23500Sstevel@tonic-gate 	retcode = rmdir(LDAP_RESTORE_DIR);
23510Sstevel@tonic-gate 	if (retcode != 0) {
23520Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
23530Sstevel@tonic-gate 			gettext("Error removing \"%s\" directory.\n"),
23540Sstevel@tonic-gate 			LDAP_RESTORE_DIR);
23550Sstevel@tonic-gate 	}
23560Sstevel@tonic-gate 
23570Sstevel@tonic-gate 	return (CLIENT_SUCCESS);
23580Sstevel@tonic-gate }
23590Sstevel@tonic-gate 
23600Sstevel@tonic-gate /*
23610Sstevel@tonic-gate  * try to save the current state of this machine.
23620Sstevel@tonic-gate  * this just overwrites any old saved configration files.
23630Sstevel@tonic-gate  *
23640Sstevel@tonic-gate  * This function should only be called after network services have been stopped.
23650Sstevel@tonic-gate  *
23660Sstevel@tonic-gate  * Returns 0 on successful save
23670Sstevel@tonic-gate  * Otherwise returns -1
23680Sstevel@tonic-gate  */
23690Sstevel@tonic-gate static int
23700Sstevel@tonic-gate file_backup(void)
23710Sstevel@tonic-gate {
23720Sstevel@tonic-gate 	struct stat buf;
23730Sstevel@tonic-gate 	int domain_stat, conf_stat, ldap_stat;
23740Sstevel@tonic-gate 	int nis_stat, yp_stat, restore_stat;
23750Sstevel@tonic-gate 	int retcode, namelen, ret;
23760Sstevel@tonic-gate 	char yp_dir[BUFSIZ], yp_dir_back[BUFSIZ];
23770Sstevel@tonic-gate 	char name[BUFSIZ];
23780Sstevel@tonic-gate 	char *ldap_conf_file, *ldap_cred_file;
23790Sstevel@tonic-gate 	char ldap_file_back[BUFSIZE], ldap_cred_back[BUFSIZE];
23800Sstevel@tonic-gate 
23810Sstevel@tonic-gate 	ret = CLIENT_SUCCESS;
23820Sstevel@tonic-gate 	/* If running as Sysid Install become a no-op */
23830Sstevel@tonic-gate 	if (sysid_install == B_TRUE)
23840Sstevel@tonic-gate 		return (CLIENT_SUCCESS);
23850Sstevel@tonic-gate 
23860Sstevel@tonic-gate 	/* If existing backup files, clear for this run */
23870Sstevel@tonic-gate 	restore_stat = stat(LDAP_RESTORE_DIR, &buf);
23880Sstevel@tonic-gate 	if (restore_stat == 0) {
23890Sstevel@tonic-gate 		if (mode_verbose) {
23900Sstevel@tonic-gate 			CLIENT_FPUTS(
23910Sstevel@tonic-gate 				gettext("Removing existing restore "
23920Sstevel@tonic-gate 					"directory\n"),
23930Sstevel@tonic-gate 				stderr);
23940Sstevel@tonic-gate 		}
23950Sstevel@tonic-gate 		(void) system("/bin/rm -fr " LDAP_RESTORE_DIR);
23960Sstevel@tonic-gate 		restore_stat = stat(LDAP_RESTORE_DIR, &buf);
23970Sstevel@tonic-gate 		if (restore_stat == 0) {
23980Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
23990Sstevel@tonic-gate 				gettext("Unable to remove backup "
24000Sstevel@tonic-gate 					"directory (%s)\n"),
24010Sstevel@tonic-gate 				LDAP_RESTORE_DIR);
24020Sstevel@tonic-gate 			return (CLIENT_ERR_RESTORE);
24030Sstevel@tonic-gate 		}
24040Sstevel@tonic-gate 	}
24050Sstevel@tonic-gate 
24060Sstevel@tonic-gate 	retcode = mkdir(LDAP_RESTORE_DIR, 0755);
24070Sstevel@tonic-gate 	if (retcode != 0) {
24080Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
24090Sstevel@tonic-gate 			gettext("file_backup: Failed to make %s backup "
24100Sstevel@tonic-gate 				"directory. mkdir=%d\n"),
24110Sstevel@tonic-gate 			LDAP_RESTORE_DIR, retcode);
24120Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
24130Sstevel@tonic-gate 	}
24140Sstevel@tonic-gate 
24150Sstevel@tonic-gate 	conf_stat = stat(NSSWITCH_CONF, &buf);
24160Sstevel@tonic-gate 	if (mode_verbose)
24170Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
24180Sstevel@tonic-gate 			gettext("file_backup: stat(%s)=%d\n"),
24190Sstevel@tonic-gate 			NSSWITCH_CONF, conf_stat);
24200Sstevel@tonic-gate 	if (conf_stat == 0) {
24210Sstevel@tonic-gate 		if (mode_verbose)
24220Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
24230Sstevel@tonic-gate 				gettext("file_backup: (%s -> %s)\n"),
24240Sstevel@tonic-gate 				NSSWITCH_CONF, NSSWITCH_BACK);
24250Sstevel@tonic-gate 		retcode = file_move(NSSWITCH_CONF, NSSWITCH_BACK);
24260Sstevel@tonic-gate 		if (retcode != 0) {
24270Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
24280Sstevel@tonic-gate 				gettext("file_backup: file_move(%s, %s) failed "
24290Sstevel@tonic-gate 					"with %d\n"),
24300Sstevel@tonic-gate 				NSSWITCH_CONF, NSSWITCH_BACK, retcode);
24310Sstevel@tonic-gate 			ret = CLIENT_ERR_RENAME;
24320Sstevel@tonic-gate 		}
24330Sstevel@tonic-gate 	} else {
24340Sstevel@tonic-gate 		if (mode_verbose)
24350Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
24360Sstevel@tonic-gate 				gettext("file_backup: No %s file.\n"),
24370Sstevel@tonic-gate 				NSSWITCH_CONF);
24380Sstevel@tonic-gate 	}
24390Sstevel@tonic-gate 
24400Sstevel@tonic-gate 	domain_stat = stat(DOMAINNAME, &buf);
24410Sstevel@tonic-gate 	if (mode_verbose)
24420Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
24430Sstevel@tonic-gate 			gettext("file_backup: stat(%s)=%d\n"),
24440Sstevel@tonic-gate 			DOMAINNAME, domain_stat);
24450Sstevel@tonic-gate 	if ((domain_stat == 0) && (buf.st_size > 0)) {
24460Sstevel@tonic-gate 		if (mode_verbose)
24470Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
24480Sstevel@tonic-gate 				gettext("file_backup: (%s -> %s)\n"),
24490Sstevel@tonic-gate 				DOMAINNAME, DOMAINNAME_BACK);
24500Sstevel@tonic-gate 		retcode = file_move(DOMAINNAME, DOMAINNAME_BACK);
24510Sstevel@tonic-gate 		if (retcode != 0) {
24520Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
24530Sstevel@tonic-gate 				gettext("file_backup: file_move(%s, %s) failed "
24540Sstevel@tonic-gate 					"with %d\n"),
24550Sstevel@tonic-gate 				DOMAINNAME, DOMAINNAME_BACK, retcode);
24560Sstevel@tonic-gate 			ret = CLIENT_ERR_RENAME;
24570Sstevel@tonic-gate 		}
24580Sstevel@tonic-gate 	} else {
24590Sstevel@tonic-gate 		if (mode_verbose)
24600Sstevel@tonic-gate 			if (domain_stat != 0) {
24610Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
24620Sstevel@tonic-gate 					gettext("file_backup: No %s file.\n"),
24630Sstevel@tonic-gate 					DOMAINNAME);
24640Sstevel@tonic-gate 			} else {
24650Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
24660Sstevel@tonic-gate 					gettext("file_backup: Empty %s "
24670Sstevel@tonic-gate 								"file.\n"),
24680Sstevel@tonic-gate 					DOMAINNAME);
24690Sstevel@tonic-gate 			}
24700Sstevel@tonic-gate 	}
24710Sstevel@tonic-gate 
24720Sstevel@tonic-gate 	nis_stat = stat(NIS_COLDSTART, &buf);
24730Sstevel@tonic-gate 	if (mode_verbose)
24740Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
24750Sstevel@tonic-gate 			gettext("file_backup: stat(%s)=%d\n"),
24760Sstevel@tonic-gate 			NIS_COLDSTART, nis_stat);
24770Sstevel@tonic-gate 	if (nis_stat == 0) {
24780Sstevel@tonic-gate 		if (mode_verbose)
24790Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
24800Sstevel@tonic-gate 				gettext("file_backup: (%s -> %s)\n"),
24810Sstevel@tonic-gate 				NIS_COLDSTART, NIS_COLDSTART_BACK);
24820Sstevel@tonic-gate 		retcode = file_move(NIS_COLDSTART, NIS_COLDSTART_BACK);
24830Sstevel@tonic-gate 		if (retcode != 0) {
24840Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
24850Sstevel@tonic-gate 				gettext("file_backup: file_move(%s, %s) failed "
24860Sstevel@tonic-gate 					"with %d\n"),
24870Sstevel@tonic-gate 				NIS_COLDSTART, NIS_COLDSTART_BACK, retcode);
24880Sstevel@tonic-gate 			ret = CLIENT_ERR_RENAME;
24890Sstevel@tonic-gate 		}
24900Sstevel@tonic-gate 	} else {
24910Sstevel@tonic-gate 		if (mode_verbose)
24920Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
24930Sstevel@tonic-gate 				gettext("file_backup: No %s file.\n"),
24940Sstevel@tonic-gate 				NIS_COLDSTART);
24950Sstevel@tonic-gate 	}
24960Sstevel@tonic-gate 
24970Sstevel@tonic-gate 	namelen = BUFSIZ;
24980Sstevel@tonic-gate 	(void) sysinfo(SI_SRPC_DOMAIN, &(name[0]), namelen);
24990Sstevel@tonic-gate 	namelen = strlen(name);
25000Sstevel@tonic-gate 
25010Sstevel@tonic-gate 	if (mode_verbose)
25020Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
25030Sstevel@tonic-gate 			gettext("file_backup: nis domain is \"%s\"\n"),
25040Sstevel@tonic-gate 			(namelen > 0) ? name : "EMPTY");
25050Sstevel@tonic-gate 	/* check for domain name if not set cannot save NIS(YP) state */
25060Sstevel@tonic-gate 	if (namelen > 0) {
25070Sstevel@tonic-gate 		/* moving /var/yp/binding will cause ypbind to core dump */
25080Sstevel@tonic-gate 		(void) strlcpy(yp_dir, YP_BIND_DIR "/", BUFSIZE);
25090Sstevel@tonic-gate 		(void) strlcat(yp_dir, name, BUFSIZE);
25100Sstevel@tonic-gate 		yp_stat = stat(yp_dir, &buf);
25110Sstevel@tonic-gate 		if (mode_verbose)
25120Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
25130Sstevel@tonic-gate 				gettext("file_backup: stat(%s)=%d\n"),
25140Sstevel@tonic-gate 				yp_dir, yp_stat);
25150Sstevel@tonic-gate 		if (yp_stat == 0) {
25160Sstevel@tonic-gate 			(void) strlcpy(yp_dir_back, LDAP_RESTORE_DIR "/",
25170Sstevel@tonic-gate 				BUFSIZE);
25180Sstevel@tonic-gate 			(void) strlcat(yp_dir_back, name, BUFSIZE);
25190Sstevel@tonic-gate 			if (mode_verbose)
25200Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
25210Sstevel@tonic-gate 					gettext("file_backup: (%s -> %s)\n"),
25220Sstevel@tonic-gate 					yp_dir, yp_dir_back);
25230Sstevel@tonic-gate 			retcode = file_move(yp_dir, yp_dir_back);
25240Sstevel@tonic-gate 			if (retcode != 0) {
25250Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
25260Sstevel@tonic-gate 					gettext("file_backup: file_move(%s, %s)"
25270Sstevel@tonic-gate 						" failed with %d\n"),
25280Sstevel@tonic-gate 					yp_dir, yp_dir_back, retcode);
25290Sstevel@tonic-gate 				ret = CLIENT_ERR_RENAME;
25300Sstevel@tonic-gate 			}
25310Sstevel@tonic-gate 		} else {
25320Sstevel@tonic-gate 			if (mode_verbose)
25330Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
25340Sstevel@tonic-gate 					gettext("file_backup: No %s "
25350Sstevel@tonic-gate 						"directory.\n"), yp_dir);
25360Sstevel@tonic-gate 		}
25370Sstevel@tonic-gate 	}
25380Sstevel@tonic-gate 
25390Sstevel@tonic-gate 
25400Sstevel@tonic-gate 	/* point to file name, not path delim (/) */
25410Sstevel@tonic-gate 	ldap_conf_file = strrchr(NSCONFIGFILE, '/') + 1;
25420Sstevel@tonic-gate 	ldap_cred_file = strrchr(NSCREDFILE, '/') + 1;
25430Sstevel@tonic-gate 
25440Sstevel@tonic-gate 	ldap_stat = stat(NSCONFIGFILE, &buf);
25450Sstevel@tonic-gate 	if (mode_verbose)
25460Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
25470Sstevel@tonic-gate 			gettext("file_backup: stat(%s)=%d\n"),
25480Sstevel@tonic-gate 			NSCONFIGFILE, ldap_stat);
25490Sstevel@tonic-gate 	if (ldap_stat == 0) {
25500Sstevel@tonic-gate 		(void) strlcpy(ldap_file_back, LDAP_RESTORE_DIR "/", BUFSIZE);
25510Sstevel@tonic-gate 		(void) strlcat(ldap_file_back, ldap_conf_file, BUFSIZE);
25520Sstevel@tonic-gate 		if (mode_verbose)
25530Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
25540Sstevel@tonic-gate 				gettext("file_backup: (%s -> %s)\n"),
25550Sstevel@tonic-gate 				NSCONFIGFILE, ldap_file_back);
25560Sstevel@tonic-gate 		retcode = file_move(NSCONFIGFILE, ldap_file_back);
25570Sstevel@tonic-gate 		if (retcode != 0) {
25580Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
25590Sstevel@tonic-gate 				gettext("file_backup: file_move(%s, %s) failed "
25600Sstevel@tonic-gate 					"with %d\n"),
25610Sstevel@tonic-gate 				NSCONFIGFILE, ldap_file_back, retcode);
25620Sstevel@tonic-gate 			ret = CLIENT_ERR_RENAME;
25630Sstevel@tonic-gate 		}
25640Sstevel@tonic-gate 
25650Sstevel@tonic-gate 		(void) strlcpy(ldap_cred_back, LDAP_RESTORE_DIR "/", BUFSIZE);
25660Sstevel@tonic-gate 		(void) strlcat(ldap_cred_back, ldap_cred_file, BUFSIZE);
25670Sstevel@tonic-gate 		if (mode_verbose)
25680Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
25690Sstevel@tonic-gate 				gettext("file_backup: (%s -> %s)\n"),
25700Sstevel@tonic-gate 				NSCREDFILE, ldap_cred_back);
25710Sstevel@tonic-gate 		retcode = file_move(NSCREDFILE, ldap_cred_back);
25720Sstevel@tonic-gate 		if (retcode != 0) {
25730Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
25740Sstevel@tonic-gate 				gettext("file_backup: file_move(%s, %s) failed "
25750Sstevel@tonic-gate 					"with %d\n"),
25760Sstevel@tonic-gate 				NSCREDFILE, ldap_cred_back, retcode);
25770Sstevel@tonic-gate 			ret = CLIENT_ERR_RENAME;
25780Sstevel@tonic-gate 		}
25790Sstevel@tonic-gate 	} else {
25800Sstevel@tonic-gate 		if (mode_verbose)
25810Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
25820Sstevel@tonic-gate 				gettext("file_backup: No %s file.\n"),
25830Sstevel@tonic-gate 				NSCONFIGFILE);
25840Sstevel@tonic-gate 	}
25850Sstevel@tonic-gate 
25860Sstevel@tonic-gate 	return (ret);
25870Sstevel@tonic-gate }
25880Sstevel@tonic-gate 
25890Sstevel@tonic-gate /*
25900Sstevel@tonic-gate  * mod_backup()
25910Sstevel@tonic-gate  *
25920Sstevel@tonic-gate  * This function is used to temporily backup the LDAP client files in /var/ldap
25930Sstevel@tonic-gate  * that the "mod" operation needs to update.  If an error occurs then the
25940Sstevel@tonic-gate  * function mod_recover() can be invoke to recover the unmodified files.
25950Sstevel@tonic-gate  */
25960Sstevel@tonic-gate static int
25970Sstevel@tonic-gate mod_backup(void)
25980Sstevel@tonic-gate {
25990Sstevel@tonic-gate 	int rc;
26000Sstevel@tonic-gate 	int retcode = CLIENT_SUCCESS;
26010Sstevel@tonic-gate 
26020Sstevel@tonic-gate 	rc = system(CMD_CP " " NSCONFIGFILE " " NSCONFIGFILE ".mod");
26030Sstevel@tonic-gate 	retcode += rc;
26040Sstevel@tonic-gate 	if (mode_verbose)
26050Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
26060Sstevel@tonic-gate 		    gettext("mod_backup: backup %s for %s\n"),
26070Sstevel@tonic-gate 		    rc ? "failed" : "successful", NSCONFIGFILE);
26080Sstevel@tonic-gate 
26090Sstevel@tonic-gate 	rc = system(CMD_CP " " NSCREDFILE " " NSCREDFILE ".mod");
26100Sstevel@tonic-gate 	retcode += rc;
26110Sstevel@tonic-gate 	if (mode_verbose)
26120Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
26130Sstevel@tonic-gate 		    gettext("mod_backup: backup %s for %s\n"),
26140Sstevel@tonic-gate 		    rc ? "failed" : "successful", NSCREDFILE);
26150Sstevel@tonic-gate 
26160Sstevel@tonic-gate 	rc = system(CMD_CP " " DOMAINNAME " " DOMAINNAME ".mod");
26170Sstevel@tonic-gate 	retcode += rc;
26180Sstevel@tonic-gate 	if (mode_verbose)
26190Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
26200Sstevel@tonic-gate 		    gettext("mod_backup: backup %s for %s\n"),
26210Sstevel@tonic-gate 		    rc ? "failed" : "successful", DOMAINNAME);
26220Sstevel@tonic-gate 
26230Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS)
26240Sstevel@tonic-gate 		retcode = CLIENT_ERR_RENAME;
26250Sstevel@tonic-gate 	return (retcode);
26260Sstevel@tonic-gate }
26270Sstevel@tonic-gate 
26280Sstevel@tonic-gate /*
26290Sstevel@tonic-gate  * mod_recover()
26300Sstevel@tonic-gate  *
26310Sstevel@tonic-gate  * This function is used to recover the temporily backed up files by
26320Sstevel@tonic-gate  * the mod_backup() function if an error occurs during the "mod"
26330Sstevel@tonic-gate  * operation.
26340Sstevel@tonic-gate  */
26350Sstevel@tonic-gate static int
26360Sstevel@tonic-gate mod_recover(void)
26370Sstevel@tonic-gate {
26380Sstevel@tonic-gate 	int rc;
26390Sstevel@tonic-gate 	int retcode = CLIENT_SUCCESS;
26400Sstevel@tonic-gate 
26410Sstevel@tonic-gate 	rc = system(CMD_MV " " NSCONFIGFILE ".mod " NSCONFIGFILE);
26420Sstevel@tonic-gate 	retcode += rc;
26430Sstevel@tonic-gate 	if (mode_verbose)
26440Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
26450Sstevel@tonic-gate 		    gettext("mod_recover: recovery %s for %s\n"),
26460Sstevel@tonic-gate 		    rc ? "failed" : "successful", NSCONFIGFILE);
26470Sstevel@tonic-gate 
26480Sstevel@tonic-gate 	rc = system(CMD_MV " " NSCREDFILE ".mod " NSCREDFILE);
26490Sstevel@tonic-gate 	retcode += rc;
26500Sstevel@tonic-gate 	if (mode_verbose)
26510Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
26520Sstevel@tonic-gate 		    gettext("mod_recover: recovery %s for %s\n"),
26530Sstevel@tonic-gate 		    rc ? "failed" : "successful", NSCREDFILE);
26540Sstevel@tonic-gate 
26550Sstevel@tonic-gate 	rc = system(CMD_MV " " DOMAINNAME ".mod " DOMAINNAME);
26560Sstevel@tonic-gate 	retcode += rc;
26570Sstevel@tonic-gate 	if (mode_verbose)
26580Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
26590Sstevel@tonic-gate 		    gettext("mod_recover: recovery %s for %s\n"),
26600Sstevel@tonic-gate 		    rc ? "failed" : "successful", DOMAINNAME);
26610Sstevel@tonic-gate 
26620Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS)
26630Sstevel@tonic-gate 		retcode = CLIENT_ERR_RENAME;
26640Sstevel@tonic-gate 	return (retcode);
26650Sstevel@tonic-gate }
26660Sstevel@tonic-gate 
26670Sstevel@tonic-gate /*
26680Sstevel@tonic-gate  * mod_cleanup()
26690Sstevel@tonic-gate  *
26700Sstevel@tonic-gate  * This function removes the .mod files in /var/ldap.
26710Sstevel@tonic-gate  */
26720Sstevel@tonic-gate static void
26730Sstevel@tonic-gate mod_cleanup(void)
26740Sstevel@tonic-gate {
26750Sstevel@tonic-gate 	(void) system(CMD_RM " " NSCONFIGFILE ".mod " TO_DEV_NULL);
26760Sstevel@tonic-gate 	(void) system(CMD_RM " " NSCREDFILE ".mod " TO_DEV_NULL);
26770Sstevel@tonic-gate 	(void) system(CMD_RM " " DOMAINNAME ".mod " TO_DEV_NULL);
26780Sstevel@tonic-gate }
26790Sstevel@tonic-gate 
26800Sstevel@tonic-gate #define	MAX_DN_ARRAY 100
26810Sstevel@tonic-gate #define	LDAP_NAMINGCONTEXTS	"namingcontexts"
26820Sstevel@tonic-gate 
26830Sstevel@tonic-gate static char *
26840Sstevel@tonic-gate findBaseDN(char *server)
26850Sstevel@tonic-gate {
26860Sstevel@tonic-gate 	int ret;
26870Sstevel@tonic-gate 	ns_ldap_entry_t *entry;
26880Sstevel@tonic-gate 	ns_ldap_result_t *resultp;
26890Sstevel@tonic-gate 	ns_ldap_error_t *errorp = NULL;
26900Sstevel@tonic-gate 	char filter[BUFSIZ], *rootDN[MAX_DN_ARRAY], *nisBaseDN;
26910Sstevel@tonic-gate 	char *attribute[] = { LDAP_NAMINGCONTEXTS, NULL };
26920Sstevel@tonic-gate 	int root_cnt, found_cxt;
26930Sstevel@tonic-gate 	int i, j, k, retcode;
26940Sstevel@tonic-gate 
26950Sstevel@tonic-gate 	if (mode_verbose)
26960Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("findBaseDN: begins\n"), stderr);
26970Sstevel@tonic-gate 
26980Sstevel@tonic-gate 	if (dname == NULL)
26990Sstevel@tonic-gate 		return (NULL);
27000Sstevel@tonic-gate 
27010Sstevel@tonic-gate 	if (is_service(LDAP_FMRI, SCF_STATE_STRING_ONLINE)) {
27020Sstevel@tonic-gate 		gStartLdap = START_RESET; /* reset flag for err cases */
27030Sstevel@tonic-gate 		if (mode_verbose)
27040Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("findBaseDN: Stopping ldap\n"),
27050Sstevel@tonic-gate 								stderr);
27060Sstevel@tonic-gate 		ret = disable_service(LDAP_FMRI, B_TRUE);
27070Sstevel@tonic-gate 		if (ret != 0) {
27080Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("findBaseDN: Stopping "
27090Sstevel@tonic-gate 					"ldap failed with (%d)\n"), ret);
27100Sstevel@tonic-gate 			return (NULL);
27110Sstevel@tonic-gate 		}
27120Sstevel@tonic-gate 		(void) unlink(LDAP_CACHE_LOG);
27130Sstevel@tonic-gate 	} else {
27140Sstevel@tonic-gate 		if (mode_verbose)
27150Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("findBaseDN: ldap not running\n"),
27160Sstevel@tonic-gate 			    stderr);
27170Sstevel@tonic-gate 	}
27180Sstevel@tonic-gate 
27190Sstevel@tonic-gate 	if (mode_verbose)
27200Sstevel@tonic-gate 		CLIENT_FPUTS(
27210Sstevel@tonic-gate 			gettext("findBaseDN: calling "
27220Sstevel@tonic-gate 				"__ns_ldap_default_config()\n"),
27230Sstevel@tonic-gate 			stderr);
27240Sstevel@tonic-gate 	__ns_ldap_default_config();
27250Sstevel@tonic-gate 
27260Sstevel@tonic-gate 	retcode = __ns_ldap_setParam(NS_LDAP_SERVERS_P,
27270Sstevel@tonic-gate 				(void *)server, &errorp);
27280Sstevel@tonic-gate 	if (retcode != NS_LDAP_SUCCESS) {
27290Sstevel@tonic-gate 		goto findDN_err_exit;
27300Sstevel@tonic-gate 	}
27310Sstevel@tonic-gate 
27320Sstevel@tonic-gate 	retcode = __ns_ldap_setParam(NS_LDAP_AUTH_P,
27330Sstevel@tonic-gate 			(void *)"NS_LDAP_AUTH_NONE", &errorp);
27340Sstevel@tonic-gate 	if (retcode != NS_LDAP_SUCCESS) {
27350Sstevel@tonic-gate 		goto findDN_err_exit;
27360Sstevel@tonic-gate 	}
27370Sstevel@tonic-gate 
27380Sstevel@tonic-gate 	retcode = __ns_ldap_setParam(NS_LDAP_TRANSPORT_SEC_P,
27390Sstevel@tonic-gate 			(void *)"NS_LDAP_SEC_NONE", &errorp);
27400Sstevel@tonic-gate 	if (retcode != NS_LDAP_SUCCESS) {
27410Sstevel@tonic-gate 		goto findDN_err_exit;
27420Sstevel@tonic-gate 	}
27430Sstevel@tonic-gate 
27440Sstevel@tonic-gate 	retcode = __ns_ldap_setParam(NS_LDAP_SEARCH_BASEDN_P,
27450Sstevel@tonic-gate 			(void *)"", &errorp);
27460Sstevel@tonic-gate 	if (retcode != NS_LDAP_SUCCESS) {
27470Sstevel@tonic-gate 		goto findDN_err_exit;
27480Sstevel@tonic-gate 	}
27490Sstevel@tonic-gate 
27500Sstevel@tonic-gate 	retcode = __ns_ldap_setParam(NS_LDAP_SEARCH_SCOPE_P,
27510Sstevel@tonic-gate 			(void *)"NS_LDAP_SCOPE_BASE", &errorp);
27520Sstevel@tonic-gate 	if (retcode != NS_LDAP_SUCCESS) {
27530Sstevel@tonic-gate 		goto findDN_err_exit;
27540Sstevel@tonic-gate 	}
27550Sstevel@tonic-gate 
27560Sstevel@tonic-gate 	(void) strcpy(&filter[0], "(objectclass=*)");
27570Sstevel@tonic-gate 
27580Sstevel@tonic-gate 	ret = __ns_ldap_list(NULL, filter, NULL, (const char **)attribute,
27590Sstevel@tonic-gate 				NULL, 0, &resultp, &errorp, NULL, NULL);
27600Sstevel@tonic-gate 	if (NULL == resultp) {
27610Sstevel@tonic-gate 		if (mode_verbose)
27620Sstevel@tonic-gate 			CLIENT_FPUTS(
27630Sstevel@tonic-gate 				gettext("__ns_ldap_list return NULL resultp\n"),
27640Sstevel@tonic-gate 				stderr);
27650Sstevel@tonic-gate 
27660Sstevel@tonic-gate 		goto findDN_err_exit;
27670Sstevel@tonic-gate 	}
27680Sstevel@tonic-gate 
27690Sstevel@tonic-gate 	for (i = 0; i < MAX_DN_ARRAY; i++)
27700Sstevel@tonic-gate 		rootDN[i] = NULL;
27710Sstevel@tonic-gate 	root_cnt = 0;
27720Sstevel@tonic-gate 	entry = resultp->entry;
27730Sstevel@tonic-gate 	for (i = 0; i < resultp->entries_count; i++) {
27740Sstevel@tonic-gate 	    for (j = 0; j < entry->attr_count; j++) {
27750Sstevel@tonic-gate 		char *cp;
27760Sstevel@tonic-gate 
27770Sstevel@tonic-gate 		cp = entry->attr_pair[j]->attrname;
27780Sstevel@tonic-gate 		if (0 != j) {
27790Sstevel@tonic-gate 		    for (k = 0; entry->attr_pair[j]->attrvalue[k]; k++)
27800Sstevel@tonic-gate 			if (0 == strcasecmp(cp, LDAP_NAMINGCONTEXTS)) {
27810Sstevel@tonic-gate 			    if (NULL == rootDN[root_cnt])
27820Sstevel@tonic-gate 				rootDN[root_cnt++] = strdup(entry->attr_pair[j]
27830Sstevel@tonic-gate 							->attrvalue[k]);
27840Sstevel@tonic-gate 				if (rootDN[root_cnt-1] == NULL) {
27850Sstevel@tonic-gate 					root_cnt--;
27860Sstevel@tonic-gate 					CLIENT_FPUTS(gettext("Memory "
27870Sstevel@tonic-gate 						"allocation error.\n"), stderr);
27880Sstevel@tonic-gate 			/*
27890Sstevel@tonic-gate 			 * fall through and let processing happen on the
27900Sstevel@tonic-gate 			 * rootDNs found to this point.  Most likely
27910Sstevel@tonic-gate 			 * things will fall apart if we are out of memory!
27920Sstevel@tonic-gate 			 */
27930Sstevel@tonic-gate 					break;
27940Sstevel@tonic-gate 				}
27950Sstevel@tonic-gate 			}
27960Sstevel@tonic-gate 		}
27970Sstevel@tonic-gate 	    }
27980Sstevel@tonic-gate 	    entry = entry->next;
27990Sstevel@tonic-gate 	}
28000Sstevel@tonic-gate 	(void) __ns_ldap_freeResult(&resultp);
28010Sstevel@tonic-gate 	if (mode_verbose)
28020Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
28030Sstevel@tonic-gate 			gettext("found %d namingcontexts\n"), root_cnt);
28040Sstevel@tonic-gate 	if (root_cnt == 0) {
28050Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Cannot find the rootDN\n"), stderr);
28060Sstevel@tonic-gate 		goto findDN_err_exit;
28070Sstevel@tonic-gate 	}
28080Sstevel@tonic-gate 	found_cxt = -1;
28090Sstevel@tonic-gate 	for (i = 0; i < root_cnt; i++) {
28100Sstevel@tonic-gate 		retcode = __ns_ldap_setParam(NS_LDAP_SEARCH_BASEDN_P,
28110Sstevel@tonic-gate 						(void *)rootDN[i], &errorp);
28120Sstevel@tonic-gate 		if (NS_LDAP_SUCCESS != retcode) {
28130Sstevel@tonic-gate 			CLIENT_FPUTS(
28140Sstevel@tonic-gate 				gettext("Error setting param "
28150Sstevel@tonic-gate 					"NS_LDAP_SEARCH_BASEDN_P\n"), stderr);
28160Sstevel@tonic-gate 			goto findDN_err_exit;
28170Sstevel@tonic-gate 		}
28180Sstevel@tonic-gate 		retcode = __ns_ldap_setParam(NS_LDAP_SEARCH_SCOPE_P,
28190Sstevel@tonic-gate 				(void *)"NS_LDAP_SCOPE_SUBTREE", &errorp);
28200Sstevel@tonic-gate 		if (NS_LDAP_SUCCESS != retcode) {
28210Sstevel@tonic-gate 			CLIENT_FPUTS(
28220Sstevel@tonic-gate 				gettext("Error setting param "
28230Sstevel@tonic-gate 					"NS_LDAP_SEARCH_SCOPE_P\n"),
28240Sstevel@tonic-gate 				stderr);
28250Sstevel@tonic-gate 			goto findDN_err_exit;
28260Sstevel@tonic-gate 		}
28270Sstevel@tonic-gate 		(void) snprintf(&filter[0], BUFSIZ,
28280Sstevel@tonic-gate 			"(&(objectclass=nisDomainObject)(nisdomain=%s))",
28290Sstevel@tonic-gate 			dname);
28300Sstevel@tonic-gate 		if (mode_verbose) {
28310Sstevel@tonic-gate 		    CLIENT_FPRINTF(stderr,
28320Sstevel@tonic-gate 			gettext("findBaseDN: __ns_ldap_list(NULL, \"%s\"\n"),
28330Sstevel@tonic-gate 			filter);
28340Sstevel@tonic-gate 		    CLIENT_FPRINTF(stderr,
28350Sstevel@tonic-gate 			gettext("rootDN[%d] %s\n"), i, rootDN[i]);
28360Sstevel@tonic-gate 		}
28370Sstevel@tonic-gate 		ret = __ns_ldap_list(NULL, filter, NULL, (const char **)NULL,
28380Sstevel@tonic-gate 					NULL, 0, &resultp, &errorp, NULL, NULL);
28390Sstevel@tonic-gate 		if (ret == NS_LDAP_SUCCESS) {
28400Sstevel@tonic-gate 			found_cxt = i;
28410Sstevel@tonic-gate 			break;
28420Sstevel@tonic-gate 		} else {
28430Sstevel@tonic-gate 		    if (mode_verbose)
28440Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
28450Sstevel@tonic-gate 				gettext("NOTFOUND:Could not find the "
28460Sstevel@tonic-gate 					"nisDomainObject for DN %s\n"),
28470Sstevel@tonic-gate 				rootDN[i]);
28480Sstevel@tonic-gate 		}
28490Sstevel@tonic-gate 	}
28500Sstevel@tonic-gate 	if (-1 == found_cxt) {
28510Sstevel@tonic-gate 		if (mode_verbose)
28520Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("found_cxt = -1\n"), stderr);
28530Sstevel@tonic-gate 		goto findDN_err_exit;
28540Sstevel@tonic-gate 	}
28550Sstevel@tonic-gate 	if (resultp == NULL) {
28560Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("resultp is NULL\n"), stderr);
28570Sstevel@tonic-gate 		goto findDN_err_exit;
28580Sstevel@tonic-gate 	}
28590Sstevel@tonic-gate 	entry = resultp->entry;
28600Sstevel@tonic-gate 	if (entry == NULL) {
28610Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("entry is NULL\n"), stderr);
28620Sstevel@tonic-gate 		goto findDN_err_exit;
28630Sstevel@tonic-gate 	}
28640Sstevel@tonic-gate 
28650Sstevel@tonic-gate 	nisBaseDN = strdup(entry->attr_pair[0]->attrvalue[0]);
28660Sstevel@tonic-gate 
28670Sstevel@tonic-gate 	(void) __ns_ldap_freeResult(&resultp);
28680Sstevel@tonic-gate 
28690Sstevel@tonic-gate 	if (mode_verbose)
28700Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
28710Sstevel@tonic-gate 			gettext("found baseDN %s for domain %s\n"),
28720Sstevel@tonic-gate 			nisBaseDN ? nisBaseDN : "NULL", dname);
28730Sstevel@tonic-gate 
28740Sstevel@tonic-gate 	return (nisBaseDN);
28750Sstevel@tonic-gate 
28760Sstevel@tonic-gate findDN_err_exit:
28770Sstevel@tonic-gate 	if (mode_verbose) {
28780Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("findBaseDN: Err exit\n"), stderr);
28790Sstevel@tonic-gate 	}
28800Sstevel@tonic-gate 	if (NULL != errorp) {
28810Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr, gettext("\t%s\n"), errorp->message);
28820Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
28830Sstevel@tonic-gate 	}
28840Sstevel@tonic-gate 	return (NULL);
28850Sstevel@tonic-gate }
28860Sstevel@tonic-gate 
28870Sstevel@tonic-gate static multival_t *
28880Sstevel@tonic-gate multival_new()
28890Sstevel@tonic-gate {
28900Sstevel@tonic-gate 	multival_t *hold;
28910Sstevel@tonic-gate 
28920Sstevel@tonic-gate 	hold = calloc(1, sizeof (multival_t));
28930Sstevel@tonic-gate 	if (hold == NULL) {
28940Sstevel@tonic-gate 		CLIENT_FPUTS(
28950Sstevel@tonic-gate 			gettext("multival_new: Memory allocation error\n"),
28960Sstevel@tonic-gate 			stderr);
28970Sstevel@tonic-gate 	}
28980Sstevel@tonic-gate 	return (hold);	/* NULL -> error */
28990Sstevel@tonic-gate }
29000Sstevel@tonic-gate 
29010Sstevel@tonic-gate static int
29020Sstevel@tonic-gate multival_add(multival_t *list, char *opt)
29030Sstevel@tonic-gate {
29040Sstevel@tonic-gate 	if (opt == NULL) {
29050Sstevel@tonic-gate 		CLIENT_FPUTS(
29060Sstevel@tonic-gate 			gettext("Empty value passed to multival_add\n"),
29070Sstevel@tonic-gate 			stderr);
29080Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
29090Sstevel@tonic-gate 	}
29100Sstevel@tonic-gate 
29110Sstevel@tonic-gate 	if (list->count == 0) {
29120Sstevel@tonic-gate 		list->optlist = (char **)malloc(sizeof (char **));
29130Sstevel@tonic-gate 	} else {
29140Sstevel@tonic-gate 		list->optlist = (char **)realloc(list->optlist,
29150Sstevel@tonic-gate 			(list->count + 1) * sizeof (char **));
29160Sstevel@tonic-gate 	}
29170Sstevel@tonic-gate 
29180Sstevel@tonic-gate 	if (list->optlist == NULL) {
29190Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error allocating memory\n"), stderr);
29200Sstevel@tonic-gate 		return (CLIENT_ERR_MEMORY);	/* 0 is success */
29210Sstevel@tonic-gate 	}
29220Sstevel@tonic-gate 
29230Sstevel@tonic-gate 	list->optlist[list->count] = opt;
29240Sstevel@tonic-gate 	list->count++;
29250Sstevel@tonic-gate 
29260Sstevel@tonic-gate 	return (CLIENT_SUCCESS);
29270Sstevel@tonic-gate }
29280Sstevel@tonic-gate 
29290Sstevel@tonic-gate static void
29300Sstevel@tonic-gate multival_free(multival_t *list)
29310Sstevel@tonic-gate {
29320Sstevel@tonic-gate 	if (list == NULL)
29330Sstevel@tonic-gate 		return;
29340Sstevel@tonic-gate 
29350Sstevel@tonic-gate 	if (list->optlist != NULL)
29360Sstevel@tonic-gate 		free(list->optlist);
29370Sstevel@tonic-gate 	free(list);
29380Sstevel@tonic-gate }
29390Sstevel@tonic-gate 
29400Sstevel@tonic-gate static clientopts_t *
29410Sstevel@tonic-gate clientopts_new()
29420Sstevel@tonic-gate {
29430Sstevel@tonic-gate 	clientopts_t *hold;
29440Sstevel@tonic-gate 
29450Sstevel@tonic-gate 	hold = calloc(1, sizeof (clientopts_t));
29460Sstevel@tonic-gate 	if (NULL == hold) {
29470Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error allocating memory for "
29480Sstevel@tonic-gate 				"clientopts structure\n"), stderr);
29490Sstevel@tonic-gate 		return (hold);	/* NULL -> error */
29500Sstevel@tonic-gate 	}
29510Sstevel@tonic-gate 
29520Sstevel@tonic-gate 	hold->serviceAuthenticationMethod = multival_new();
29530Sstevel@tonic-gate 	if (NULL == hold->serviceAuthenticationMethod) {
29540Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error allocating memory for "
29550Sstevel@tonic-gate 				"serviceAuthenticationMethod\n"), stderr);
29560Sstevel@tonic-gate 		free(hold);
29570Sstevel@tonic-gate 		return (NULL);	/* NULL -> error */
29580Sstevel@tonic-gate 	}
29590Sstevel@tonic-gate 
29600Sstevel@tonic-gate 	hold->serviceCredentialLevel = multival_new();
29610Sstevel@tonic-gate 	if (NULL == hold->serviceCredentialLevel) {
29620Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error allocating memory for "
29630Sstevel@tonic-gate 				"serviceCredentialLevel\n"), stderr);
29640Sstevel@tonic-gate 		multival_free(hold->serviceAuthenticationMethod);
29650Sstevel@tonic-gate 		free(hold);
29660Sstevel@tonic-gate 		return (NULL);	/* NULL -> error */
29670Sstevel@tonic-gate 	}
29680Sstevel@tonic-gate 
29690Sstevel@tonic-gate 	hold->objectclassMap = multival_new();
29700Sstevel@tonic-gate 	if (NULL == hold->objectclassMap) {
29710Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error allocating memory for "
29720Sstevel@tonic-gate 				"objectclassMap\n"), stderr);
29730Sstevel@tonic-gate 		multival_free(hold->serviceAuthenticationMethod);
29740Sstevel@tonic-gate 		multival_free(hold->serviceCredentialLevel);
29750Sstevel@tonic-gate 		free(hold);
29760Sstevel@tonic-gate 		return (NULL);	/* NULL -> error */
29770Sstevel@tonic-gate 	}
29780Sstevel@tonic-gate 
29790Sstevel@tonic-gate 	hold->attributeMap = multival_new();
29800Sstevel@tonic-gate 	if (NULL == hold->attributeMap) {
29810Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error allocating memory for "
29820Sstevel@tonic-gate 				"attributeMap\n"), stderr);
29830Sstevel@tonic-gate 		multival_free(hold->serviceAuthenticationMethod);
29840Sstevel@tonic-gate 		multival_free(hold->serviceCredentialLevel);
29850Sstevel@tonic-gate 		multival_free(hold->objectclassMap);
29860Sstevel@tonic-gate 		free(hold);
29870Sstevel@tonic-gate 		return (NULL);	/* NULL -> error */
29880Sstevel@tonic-gate 	}
29890Sstevel@tonic-gate 
29900Sstevel@tonic-gate 	hold->serviceSearchDescriptor = multival_new();
29910Sstevel@tonic-gate 	if (NULL == hold->serviceSearchDescriptor) {
29920Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error allocating memory for "
29930Sstevel@tonic-gate 				"serviceSearchDescriptor\n"), stderr);
29940Sstevel@tonic-gate 		multival_free(hold->serviceAuthenticationMethod);
29950Sstevel@tonic-gate 		multival_free(hold->serviceCredentialLevel);
29960Sstevel@tonic-gate 		multival_free(hold->objectclassMap);
29970Sstevel@tonic-gate 		multival_free(hold->attributeMap);
29980Sstevel@tonic-gate 		free(hold);
29990Sstevel@tonic-gate 		return (NULL);	/* NULL -> error */
30000Sstevel@tonic-gate 	}
30010Sstevel@tonic-gate 
30020Sstevel@tonic-gate 	return (hold);
30030Sstevel@tonic-gate }
30040Sstevel@tonic-gate 
30050Sstevel@tonic-gate static void
30060Sstevel@tonic-gate clientopts_free(clientopts_t *list)
30070Sstevel@tonic-gate {
30080Sstevel@tonic-gate 	if (NULL == list)
30090Sstevel@tonic-gate 		return;
30100Sstevel@tonic-gate 
30110Sstevel@tonic-gate 	multival_free(list->serviceAuthenticationMethod);
30120Sstevel@tonic-gate 	multival_free(list->serviceCredentialLevel);
30130Sstevel@tonic-gate 	multival_free(list->objectclassMap);
30140Sstevel@tonic-gate 	multival_free(list->attributeMap);
30150Sstevel@tonic-gate 	multival_free(list->serviceSearchDescriptor);
30160Sstevel@tonic-gate 
30170Sstevel@tonic-gate 	free(list);
30180Sstevel@tonic-gate 
30190Sstevel@tonic-gate }
30200Sstevel@tonic-gate 
30210Sstevel@tonic-gate static void
30220Sstevel@tonic-gate multival_list(char *opt, multival_t *list)
30230Sstevel@tonic-gate {
30240Sstevel@tonic-gate 	int i;
30250Sstevel@tonic-gate 
30260Sstevel@tonic-gate 	if (list->count == 0)
30270Sstevel@tonic-gate 		return;
30280Sstevel@tonic-gate 
30290Sstevel@tonic-gate 	(void) puts(opt);
30300Sstevel@tonic-gate 	for (i = 0; i < list->count; i++) {
30310Sstevel@tonic-gate 		(void) printf("\t\targ[%d]: %s\n", i, list->optlist[i]);
30320Sstevel@tonic-gate 	}
30330Sstevel@tonic-gate }
30340Sstevel@tonic-gate 
30350Sstevel@tonic-gate /* return the number of arguments specified in the command line */
30360Sstevel@tonic-gate static int
30370Sstevel@tonic-gate num_args(clientopts_t *list)
30380Sstevel@tonic-gate {
30390Sstevel@tonic-gate 	int arg_count = 0;
30400Sstevel@tonic-gate 
30410Sstevel@tonic-gate 	arg_count += list->authenticationMethod ? 1 : 0;
30420Sstevel@tonic-gate 	arg_count += list->serviceAuthenticationMethod->count;
30430Sstevel@tonic-gate 	arg_count += list->defaultSearchBase ? 1 : 0;
30440Sstevel@tonic-gate 	arg_count += list->credentialLevel ? 1 : 0;
30450Sstevel@tonic-gate 	arg_count += list->serviceCredentialLevel->count;
30460Sstevel@tonic-gate 	arg_count += list->domainName ? 1 : 0;
30470Sstevel@tonic-gate 	arg_count += list->proxyDN ? 1 : 0;
30480Sstevel@tonic-gate 	arg_count += list->profileTTL ? 1 : 0;
30490Sstevel@tonic-gate 	arg_count += list->objectclassMap->count;
30500Sstevel@tonic-gate 	arg_count += list->searchTimeLimit ? 1 : 0;
30510Sstevel@tonic-gate 	arg_count += list->preferredServerList ? 1 : 0;
30520Sstevel@tonic-gate 	arg_count += list->profileName ? 1 : 0;
30530Sstevel@tonic-gate 	arg_count += list->followReferrals ? 1 : 0;
30540Sstevel@tonic-gate 	arg_count += list->attributeMap->count;
30550Sstevel@tonic-gate 	arg_count += list->defaultSearchScope ? 1 : 0;
30560Sstevel@tonic-gate 	arg_count += list->serviceSearchDescriptor->count;
30570Sstevel@tonic-gate 	arg_count += list->bindTimeLimit ? 1 : 0;
30580Sstevel@tonic-gate 	arg_count += list->proxyPassword ? 1 : 0;
30590Sstevel@tonic-gate 	arg_count += list->defaultServerList ? 1 : 0;
30600Sstevel@tonic-gate 	arg_count += list->certificatePath ? 1 : 0;
30610Sstevel@tonic-gate 
30620Sstevel@tonic-gate 	return (arg_count);
30630Sstevel@tonic-gate }
30640Sstevel@tonic-gate 
30650Sstevel@tonic-gate #define	CLIENT_PRINT(opt, str) if (str) \
30660Sstevel@tonic-gate 		(void) printf("%s%s\n", (opt), (str))
30670Sstevel@tonic-gate 
30680Sstevel@tonic-gate static void
30690Sstevel@tonic-gate dumpargs(clientopts_t *list)
30700Sstevel@tonic-gate {
30710Sstevel@tonic-gate 	CLIENT_PRINT("\tauthenticationMethod: ", list->authenticationMethod);
30720Sstevel@tonic-gate 	multival_list("\tserviceAuthenticationMethod: ",
30730Sstevel@tonic-gate 		list->serviceAuthenticationMethod);
30740Sstevel@tonic-gate 	CLIENT_PRINT("\tdefaultSearchBase: ", list->defaultSearchBase);
30750Sstevel@tonic-gate 	CLIENT_PRINT("\tcredentialLevel: ", list->credentialLevel);
30760Sstevel@tonic-gate 	multival_list("\tserviceCredentialLevel: ",
30770Sstevel@tonic-gate 		list->serviceCredentialLevel);
30780Sstevel@tonic-gate 	CLIENT_PRINT("\tdomainName: ", list->domainName);
30790Sstevel@tonic-gate 	CLIENT_PRINT("\tproxyDN: ", list->proxyDN);
30800Sstevel@tonic-gate 	CLIENT_PRINT("\tprofileTTL: ", list->profileTTL);
30810Sstevel@tonic-gate 	multival_list("\tobjectclassMap: ", list->objectclassMap);
30820Sstevel@tonic-gate 	CLIENT_PRINT("\tsearchTimeLimit: ", list->searchTimeLimit);
30830Sstevel@tonic-gate 	CLIENT_PRINT("\tpreferredServerList: ", list->preferredServerList);
30840Sstevel@tonic-gate 	CLIENT_PRINT("\tprofileName: ", list->profileName);
30850Sstevel@tonic-gate 	CLIENT_PRINT("\tfollowReferrals: ", list->followReferrals);
30860Sstevel@tonic-gate 	multival_list("\tattributeMap: ", list->attributeMap);
30870Sstevel@tonic-gate 	CLIENT_PRINT("\tdefaultSearchScope: ", list->defaultSearchScope);
30880Sstevel@tonic-gate 	multival_list("\tserviceSearchDescriptor: ",
30890Sstevel@tonic-gate 		list->serviceSearchDescriptor);
30900Sstevel@tonic-gate 	CLIENT_PRINT("\tbindTimeLimit: ", list->bindTimeLimit);
30910Sstevel@tonic-gate 	CLIENT_PRINT("\tproxyPassword: ", list->proxyPassword);
30920Sstevel@tonic-gate 	CLIENT_PRINT("\tdefaultServerList: ", list->defaultServerList);
30930Sstevel@tonic-gate 	CLIENT_PRINT("\tcertificatePath: ", list->certificatePath);
30940Sstevel@tonic-gate }
30950Sstevel@tonic-gate 
30960Sstevel@tonic-gate 
30970Sstevel@tonic-gate /* These definitions are only used in parseParam() below. */
30980Sstevel@tonic-gate struct param {
30990Sstevel@tonic-gate 	char	*name;
31000Sstevel@tonic-gate 	int	index;
31010Sstevel@tonic-gate };
31020Sstevel@tonic-gate 
31030Sstevel@tonic-gate static struct param paramArray[] = {
31040Sstevel@tonic-gate 	{"proxyDN", NS_LDAP_BINDDN_P},
31050Sstevel@tonic-gate 	{"proxyPassword", NS_LDAP_BINDPASSWD_P},
31060Sstevel@tonic-gate 	{"defaultServerList", NS_LDAP_SERVERS_P},
31070Sstevel@tonic-gate 	{"defaultSearchBase", NS_LDAP_SEARCH_BASEDN_P},
31080Sstevel@tonic-gate 	{"authenticationMethod", NS_LDAP_AUTH_P},
31090Sstevel@tonic-gate 	{"followReferrals", NS_LDAP_SEARCH_REF_P},
31100Sstevel@tonic-gate 	{"profileTTL", NS_LDAP_CACHETTL_P},
31110Sstevel@tonic-gate 	{"certificatePath", NS_LDAP_HOST_CERTPATH_P},
31120Sstevel@tonic-gate 	{"defaultSearchScope", NS_LDAP_SEARCH_SCOPE_P},
31130Sstevel@tonic-gate 	{"bindTimeLimit", NS_LDAP_BIND_TIME_P},
31140Sstevel@tonic-gate 	{"searchTimeLimit", NS_LDAP_SEARCH_TIME_P},
31150Sstevel@tonic-gate 	{"preferredServerList", NS_LDAP_SERVER_PREF_P},
31160Sstevel@tonic-gate 	{"profileName", NS_LDAP_PROFILE_P},
31170Sstevel@tonic-gate 	{"credentialLevel", NS_LDAP_CREDENTIAL_LEVEL_P},
31180Sstevel@tonic-gate 	{"serviceSearchDescriptor", NS_LDAP_SERVICE_SEARCH_DESC_P},
31190Sstevel@tonic-gate 	{"attributeMap", NS_LDAP_ATTRIBUTEMAP_P},
31200Sstevel@tonic-gate 	{"objectclassMap", NS_LDAP_OBJECTCLASSMAP_P},
31210Sstevel@tonic-gate 	{"serviceAuthenticationMethod", NS_LDAP_SERVICE_AUTH_METHOD_P},
31220Sstevel@tonic-gate 	{"serviceCredentialLevel", NS_LDAP_SERVICE_CRED_LEVEL_P},
31230Sstevel@tonic-gate 	{"domainName", LOCAL_DOMAIN_P},
31240Sstevel@tonic-gate 	{NULL, 0}
31250Sstevel@tonic-gate };
31260Sstevel@tonic-gate 
31270Sstevel@tonic-gate static int
31280Sstevel@tonic-gate parseParam(char *param, char **paramVal)
31290Sstevel@tonic-gate {
31300Sstevel@tonic-gate 	char *val = NULL;
31310Sstevel@tonic-gate 	int counter;
31320Sstevel@tonic-gate 
31330Sstevel@tonic-gate 	if (mode_verbose) {
31340Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr, gettext("Parsing %s\n"), param);
31350Sstevel@tonic-gate 	}
31360Sstevel@tonic-gate 
31370Sstevel@tonic-gate 	val = strchr(param, '=');
31380Sstevel@tonic-gate 	if (val == NULL) {
31390Sstevel@tonic-gate 		CLIENT_FPUTS(
31400Sstevel@tonic-gate 			gettext("Didn\'t find \'=\' character in string\n"),
31410Sstevel@tonic-gate 			stderr);
31420Sstevel@tonic-gate 		paramVal = NULL;
31430Sstevel@tonic-gate 		return (CLIENT_ERR_PARSE);
31440Sstevel@tonic-gate 	}
31450Sstevel@tonic-gate 
31460Sstevel@tonic-gate 	*val = '\0';
31470Sstevel@tonic-gate 
31480Sstevel@tonic-gate 	for (counter = 0; paramArray[counter].name != NULL; counter++) {
31490Sstevel@tonic-gate 		if (strcasecmp(paramArray[counter].name, param) == 0) {
31500Sstevel@tonic-gate 			*paramVal = val+1;
31510Sstevel@tonic-gate 			*val = '=';	/* restore original param */
31520Sstevel@tonic-gate 			return (paramArray[counter].index);
31530Sstevel@tonic-gate 		}
31540Sstevel@tonic-gate 	}
31550Sstevel@tonic-gate 
31560Sstevel@tonic-gate 	/* Not found */
31570Sstevel@tonic-gate 	*val = '=';	/* restore original param */
31580Sstevel@tonic-gate 	*paramVal = NULL;
31590Sstevel@tonic-gate 	return (CLIENT_ERR_PARSE);
31600Sstevel@tonic-gate }
31610Sstevel@tonic-gate 
31620Sstevel@tonic-gate /*
31630Sstevel@tonic-gate  * The following macro checks if an option has already been specified
31640Sstevel@tonic-gate  * and errs out with usage if so
31650Sstevel@tonic-gate  */
31660Sstevel@tonic-gate #define	CLIENT_OPT_CHECK(opt, optarg)	\
31670Sstevel@tonic-gate if (optarg) {			\
31680Sstevel@tonic-gate 	CLIENT_FPUTS(gettext("Invalid use of option\n"), stderr);	\
31690Sstevel@tonic-gate 	usage();		\
31700Sstevel@tonic-gate 	clientopts_free(optlist); \
31710Sstevel@tonic-gate 	return (CLIENT_ERR_FAIL);		\
31720Sstevel@tonic-gate }
31730Sstevel@tonic-gate 
31740Sstevel@tonic-gate static int
31750Sstevel@tonic-gate clientSetParam(clientopts_t *optlist, int paramFlag, char *attrVal)
31760Sstevel@tonic-gate {
31770Sstevel@tonic-gate 	int retcode = 0;
31780Sstevel@tonic-gate 	int counter;
31790Sstevel@tonic-gate 
31800Sstevel@tonic-gate 
31810Sstevel@tonic-gate 	switch (paramFlag) {
31820Sstevel@tonic-gate 	case NS_LDAP_AUTH_P:
31830Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->authenticationMethod);
31840Sstevel@tonic-gate 		optlist->authenticationMethod = attrVal;
31850Sstevel@tonic-gate 		break;
31860Sstevel@tonic-gate 
31870Sstevel@tonic-gate 	case NS_LDAP_SERVICE_AUTH_METHOD_P:	/* multiple allowed */
31880Sstevel@tonic-gate 		retcode = multival_add(optlist->serviceAuthenticationMethod,
31890Sstevel@tonic-gate 				attrVal);
31900Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
31910Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
31920Sstevel@tonic-gate 				gettext("Error processing attrVal %s\n"),
31930Sstevel@tonic-gate 				attrVal?attrVal:"NULL");
31940Sstevel@tonic-gate 			usage();
31950Sstevel@tonic-gate 			clientopts_free(optlist);
31960Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
31970Sstevel@tonic-gate 		}
31980Sstevel@tonic-gate 		break;
31990Sstevel@tonic-gate 
32000Sstevel@tonic-gate 	case NS_LDAP_SEARCH_BASEDN_P:
32010Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->defaultSearchBase);
32020Sstevel@tonic-gate 		optlist->defaultSearchBase = attrVal;
32030Sstevel@tonic-gate 		break;
32040Sstevel@tonic-gate 
32050Sstevel@tonic-gate 	case NS_LDAP_CREDENTIAL_LEVEL_P:
32060Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->credentialLevel);
32070Sstevel@tonic-gate 		optlist->credentialLevel = attrVal;
32080Sstevel@tonic-gate 		break;
32090Sstevel@tonic-gate 
32100Sstevel@tonic-gate 	case NS_LDAP_SERVICE_CRED_LEVEL_P:	/* multiple allowed */
32110Sstevel@tonic-gate 		retcode = multival_add(optlist->serviceCredentialLevel,
32120Sstevel@tonic-gate 				attrVal);
32130Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
32140Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
32150Sstevel@tonic-gate 				gettext("Error processing attrVal %s\n"),
32160Sstevel@tonic-gate 				attrVal?attrVal:"NULL");
32170Sstevel@tonic-gate 			usage();
32180Sstevel@tonic-gate 			clientopts_free(optlist);
32190Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
32200Sstevel@tonic-gate 		}
32210Sstevel@tonic-gate 		break;
32220Sstevel@tonic-gate 
32230Sstevel@tonic-gate 	case LOCAL_DOMAIN_P:
32240Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->domainName);
32250Sstevel@tonic-gate 		optlist->domainName = attrVal;
32260Sstevel@tonic-gate 		dname = optlist->domainName;
32270Sstevel@tonic-gate 		break;
32280Sstevel@tonic-gate 
32290Sstevel@tonic-gate 	case NS_LDAP_BINDDN_P:
32300Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->proxyDN);
32310Sstevel@tonic-gate 		optlist->proxyDN = attrVal;
32320Sstevel@tonic-gate 		break;
32330Sstevel@tonic-gate 
32340Sstevel@tonic-gate 	case NS_LDAP_CACHETTL_P:
32350Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->profileTTL);
32360Sstevel@tonic-gate 		optlist->profileTTL = attrVal;
32370Sstevel@tonic-gate 		break;
32380Sstevel@tonic-gate 
32390Sstevel@tonic-gate 	case NS_LDAP_OBJECTCLASSMAP_P:	/* multiple allowed */
32400Sstevel@tonic-gate 		retcode = multival_add(optlist->objectclassMap, attrVal);
32410Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
32420Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
32430Sstevel@tonic-gate 				gettext("Error processing attrVal %s\n"),
32440Sstevel@tonic-gate 				attrVal?attrVal:"NULL");
32450Sstevel@tonic-gate 			usage();
32460Sstevel@tonic-gate 			clientopts_free(optlist);
32470Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
32480Sstevel@tonic-gate 		}
32490Sstevel@tonic-gate 		break;
32500Sstevel@tonic-gate 
32510Sstevel@tonic-gate 	case NS_LDAP_SEARCH_TIME_P:
32520Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->searchTimeLimit);
32530Sstevel@tonic-gate 		optlist->searchTimeLimit = attrVal;
32540Sstevel@tonic-gate 		break;
32550Sstevel@tonic-gate 
32560Sstevel@tonic-gate 	case NS_LDAP_SERVER_PREF_P:
32570Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->preferredServerList);
32580Sstevel@tonic-gate 		optlist->preferredServerList = attrVal;
32590Sstevel@tonic-gate 		/* replace ',' chars with ' ' for proper syntax */
32600Sstevel@tonic-gate 		for (counter = 0;
32610Sstevel@tonic-gate 			counter < strlen(optlist->preferredServerList);
32620Sstevel@tonic-gate 			counter++) {
32630Sstevel@tonic-gate 
32640Sstevel@tonic-gate 			if (optlist->preferredServerList[counter] == ',')
32650Sstevel@tonic-gate 				optlist->preferredServerList[counter] = ' ';
32660Sstevel@tonic-gate 		}
32670Sstevel@tonic-gate 		break;
32680Sstevel@tonic-gate 
32690Sstevel@tonic-gate 	case NS_LDAP_PROFILE_P:
32700Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->profileName);
32710Sstevel@tonic-gate 		optlist->profileName = attrVal;
32720Sstevel@tonic-gate 		break;
32730Sstevel@tonic-gate 
32740Sstevel@tonic-gate 	case NS_LDAP_SEARCH_REF_P:
32750Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->followReferrals);
32760Sstevel@tonic-gate 		if (0 == strcasecmp(attrVal, "followref"))
32770Sstevel@tonic-gate 			optlist->followReferrals = "TRUE";
32780Sstevel@tonic-gate 		else if (0 == strcasecmp(attrVal, "noref"))
32790Sstevel@tonic-gate 			optlist->followReferrals = "FALSE";
32800Sstevel@tonic-gate 		else
32810Sstevel@tonic-gate 			optlist->followReferrals = attrVal;
32820Sstevel@tonic-gate 		break;
32830Sstevel@tonic-gate 
32840Sstevel@tonic-gate 	case NS_LDAP_ATTRIBUTEMAP_P:	/* multiple allowed */
32850Sstevel@tonic-gate 		retcode = multival_add(optlist->attributeMap, attrVal);
32860Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
32870Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
32880Sstevel@tonic-gate 				gettext("Error processing attrVal %s\n"),
32890Sstevel@tonic-gate 				attrVal?attrVal:"NULL");
32900Sstevel@tonic-gate 			usage();
32910Sstevel@tonic-gate 			clientopts_free(optlist);
32920Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
32930Sstevel@tonic-gate 		}
32940Sstevel@tonic-gate 		break;
32950Sstevel@tonic-gate 
32960Sstevel@tonic-gate 	case NS_LDAP_SEARCH_SCOPE_P:
32970Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->defaultSearchScope);
32980Sstevel@tonic-gate 		optlist->defaultSearchScope = attrVal;
32990Sstevel@tonic-gate 		break;
33000Sstevel@tonic-gate 
33010Sstevel@tonic-gate 	case NS_LDAP_SERVICE_SEARCH_DESC_P:	/* multiple allowed */
33020Sstevel@tonic-gate 		retcode = multival_add(optlist->serviceSearchDescriptor,
33030Sstevel@tonic-gate 				attrVal);
33040Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
33050Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
33060Sstevel@tonic-gate 				gettext("Error processing attrVal %s\n"),
33070Sstevel@tonic-gate 				attrVal?attrVal:"NULL");
33080Sstevel@tonic-gate 			usage();
33090Sstevel@tonic-gate 			clientopts_free(optlist);
33100Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
33110Sstevel@tonic-gate 		}
33120Sstevel@tonic-gate 		break;
33130Sstevel@tonic-gate 
33140Sstevel@tonic-gate 	case NS_LDAP_BIND_TIME_P:
33150Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->bindTimeLimit);
33160Sstevel@tonic-gate 		optlist->bindTimeLimit = attrVal;
33170Sstevel@tonic-gate 		break;
33180Sstevel@tonic-gate 
33190Sstevel@tonic-gate 	case NS_LDAP_BINDPASSWD_P:
33200Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->proxyPassword);
33210Sstevel@tonic-gate 		optlist->proxyPassword = attrVal;
33220Sstevel@tonic-gate 		break;
33230Sstevel@tonic-gate 
33240Sstevel@tonic-gate 	case NS_LDAP_HOST_CERTPATH_P:
33250Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->certificatePath);
33260Sstevel@tonic-gate 		optlist->certificatePath = attrVal;
33270Sstevel@tonic-gate 		break;
33280Sstevel@tonic-gate 
33290Sstevel@tonic-gate 	case NS_LDAP_SERVERS_P:
33300Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->defaultServerList);
33310Sstevel@tonic-gate 		optlist->defaultServerList = attrVal;
33320Sstevel@tonic-gate 		break;
33330Sstevel@tonic-gate 
33340Sstevel@tonic-gate 	default:
33350Sstevel@tonic-gate 		usage();
33360Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
33370Sstevel@tonic-gate 		/* break;  lint doesn't like break before end of switch */
33380Sstevel@tonic-gate 	}
33390Sstevel@tonic-gate 
33400Sstevel@tonic-gate 	return (retcode);
33410Sstevel@tonic-gate }
33420Sstevel@tonic-gate 
33430Sstevel@tonic-gate /*
33440Sstevel@tonic-gate  * file_move() - Used to move a config file (backup/restore).
33450Sstevel@tonic-gate  *
33460Sstevel@tonic-gate  * This function uses a system() call with /bin/mv to handle the
33470Sstevel@tonic-gate  * case where the backup directory (/var) is on a different file
33480Sstevel@tonic-gate  * system than the config file (typically /etc).
33490Sstevel@tonic-gate  */
33500Sstevel@tonic-gate static int
33510Sstevel@tonic-gate file_move(const char *from, const char *to)
33520Sstevel@tonic-gate {
33530Sstevel@tonic-gate 	int retcode;
33540Sstevel@tonic-gate 	char mvCommand[] = CMD_MV;
33550Sstevel@tonic-gate 	char cmd_buffer[(2 * MAXPATHLEN) + sizeof (mvCommand) + 3];
33560Sstevel@tonic-gate 
33570Sstevel@tonic-gate 	(void) snprintf(cmd_buffer, sizeof (cmd_buffer), "%s %s %s",
33580Sstevel@tonic-gate 					mvCommand, from, to);
33590Sstevel@tonic-gate 
33600Sstevel@tonic-gate 	/*
33610Sstevel@tonic-gate 	 * This function should only be used internally to move
33620Sstevel@tonic-gate 	 * system files to/from the backup directory.  For security
33630Sstevel@tonic-gate 	 * reasons (this is run as root), don't use this function
33640Sstevel@tonic-gate 	 * with arguments passed into the program.
33650Sstevel@tonic-gate 	 */
33660Sstevel@tonic-gate 	retcode = system(cmd_buffer);
33670Sstevel@tonic-gate 
33680Sstevel@tonic-gate 	return (retcode);
33690Sstevel@tonic-gate }
33700Sstevel@tonic-gate 
33710Sstevel@tonic-gate 
33720Sstevel@tonic-gate static boolean_t
33730Sstevel@tonic-gate has_port(const char *server)
33740Sstevel@tonic-gate {
33750Sstevel@tonic-gate 	const char	*s;
33760Sstevel@tonic-gate 	const char	*end;
33770Sstevel@tonic-gate 
33780Sstevel@tonic-gate 	/*
33790Sstevel@tonic-gate 	 * Don't check that address is legal - only determine
33800Sstevel@tonic-gate 	 * if there is a port specified - works for both ipv4 and ipv6
33810Sstevel@tonic-gate 	 */
33820Sstevel@tonic-gate 
33830Sstevel@tonic-gate 	while (server != NULL) {
33840Sstevel@tonic-gate 		end = strchr(server, ',');
33850Sstevel@tonic-gate 		if (end == NULL)
33860Sstevel@tonic-gate 			s = server + strlen(server);
33870Sstevel@tonic-gate 		else {
33880Sstevel@tonic-gate 			s = end;
33890Sstevel@tonic-gate 			end = end + 1;
33900Sstevel@tonic-gate 		}
33910Sstevel@tonic-gate 
33920Sstevel@tonic-gate 		while (s >= server) {
33930Sstevel@tonic-gate 			if (*s == ']')
33940Sstevel@tonic-gate 				break;
33950Sstevel@tonic-gate 			else if (*s == ':')
33960Sstevel@tonic-gate 				return (B_TRUE);
33970Sstevel@tonic-gate 			s--;
33980Sstevel@tonic-gate 		}
33990Sstevel@tonic-gate 		server = end;
34000Sstevel@tonic-gate 	}
34010Sstevel@tonic-gate 	return (B_FALSE);
34020Sstevel@tonic-gate }
34030Sstevel@tonic-gate 
34040Sstevel@tonic-gate 
34050Sstevel@tonic-gate /*
34060Sstevel@tonic-gate  * Check to see if configured to use tls and some server has a port number
34070Sstevel@tonic-gate  * configured. The goal is to help prevent users from configuring impossible
34080Sstevel@tonic-gate  * profiles
34090Sstevel@tonic-gate  */
34100Sstevel@tonic-gate 
34110Sstevel@tonic-gate static boolean_t
34120Sstevel@tonic-gate is_config_ok(const clientopts_t *list, boolean_t get_config)
34130Sstevel@tonic-gate {
34140Sstevel@tonic-gate 	boolean_t	has_tls = B_FALSE;
34150Sstevel@tonic-gate 	boolean_t	is_ok = B_TRUE;
34160Sstevel@tonic-gate 	multival_t	*m_val;
34170Sstevel@tonic-gate 	int		i, j, len;
34180Sstevel@tonic-gate 	const char	*begin;
34190Sstevel@tonic-gate 	const char	*end;
34200Sstevel@tonic-gate 	ns_auth_t	**authMethod;
34210Sstevel@tonic-gate 	char		**servers;
34220Sstevel@tonic-gate 	char		**sam;
34230Sstevel@tonic-gate 	ns_ldap_error_t	*errorp = NULL;
34240Sstevel@tonic-gate 	int		rc;
34250Sstevel@tonic-gate 
34260Sstevel@tonic-gate 	if (list->authenticationMethod != NULL) {
34270Sstevel@tonic-gate 		begin = list->authenticationMethod;
34280Sstevel@tonic-gate 		len = strlen(begin) - 3;
34290Sstevel@tonic-gate 		for (i = 0; i < len; i++)
34300Sstevel@tonic-gate 			if (strncasecmp(begin + i, "tls:", 4) == 0)
34310Sstevel@tonic-gate 				break;
34320Sstevel@tonic-gate 		has_tls = i < len;
34330Sstevel@tonic-gate 	} else if (get_config) {
34340Sstevel@tonic-gate 		rc = __ns_ldap_getParam(NS_LDAP_AUTH_P,
34350Sstevel@tonic-gate 			(void ***)&authMethod, &errorp);
34360Sstevel@tonic-gate 		if (rc == NS_LDAP_SUCCESS && authMethod != NULL) {
34370Sstevel@tonic-gate 			for (i = 0; authMethod[i] != NULL && !has_tls; i++)
34380Sstevel@tonic-gate 			    has_tls = authMethod[i]->type == NS_LDAP_AUTH_TLS;
34390Sstevel@tonic-gate 			(void) __ns_ldap_freeParam((void ***) &authMethod);
34400Sstevel@tonic-gate 		}
34410Sstevel@tonic-gate 		if (errorp != NULL)
34420Sstevel@tonic-gate 			(void) __ns_ldap_freeError(&errorp);
34430Sstevel@tonic-gate 		errorp = NULL;
34440Sstevel@tonic-gate 	}
34450Sstevel@tonic-gate 
34460Sstevel@tonic-gate 	m_val = list->serviceAuthenticationMethod;
34470Sstevel@tonic-gate 	if (!has_tls && m_val != NULL) {
34480Sstevel@tonic-gate 		for (j = 0; j < m_val->count && !has_tls; j++) {
34490Sstevel@tonic-gate 			begin = m_val->optlist[j];
34500Sstevel@tonic-gate 			/* skip over service tag */
34510Sstevel@tonic-gate 			if (begin != NULL)
34520Sstevel@tonic-gate 				begin = strchr(begin, ':');
34530Sstevel@tonic-gate 			if (begin == NULL)
34540Sstevel@tonic-gate 				continue;
34550Sstevel@tonic-gate 			len = strlen(begin) - 3;
34560Sstevel@tonic-gate 			for (i = 0; i < len; i++)
34570Sstevel@tonic-gate 				if (strncasecmp(begin + i, "tls:", 4) == 0)
34580Sstevel@tonic-gate 					break;
34590Sstevel@tonic-gate 			has_tls = i < len;
34600Sstevel@tonic-gate 		}
34610Sstevel@tonic-gate 	}
34620Sstevel@tonic-gate 	if (!has_tls && get_config) {
34630Sstevel@tonic-gate 		rc = __ns_ldap_getParam(NS_LDAP_SERVICE_AUTH_METHOD_P,
34640Sstevel@tonic-gate 			(void ***)&sam, &errorp);
34650Sstevel@tonic-gate 		if (rc == NS_LDAP_SUCCESS && sam != NULL) {
34660Sstevel@tonic-gate 		    for (i = 0; sam[i] != NULL && !has_tls; i++) {
34670Sstevel@tonic-gate 			if (m_val != NULL) {
34680Sstevel@tonic-gate 			    /* check to see if a new service is replacing */
34690Sstevel@tonic-gate 			    for (j = 0; j < m_val->count; j++) {
34700Sstevel@tonic-gate 				begin = m_val->optlist[j];
34710Sstevel@tonic-gate 				if (begin == NULL)
34720Sstevel@tonic-gate 					continue;
34730Sstevel@tonic-gate 				end = strchr(begin, ':');
34740Sstevel@tonic-gate 				if (end == NULL)
34750Sstevel@tonic-gate 					continue;
34760Sstevel@tonic-gate 				len = end - begin + 1;
34770Sstevel@tonic-gate 				if (strncasecmp(sam[i], begin, len) == 0)
34780Sstevel@tonic-gate 					break;
34790Sstevel@tonic-gate 			    }
34800Sstevel@tonic-gate 			    if (j != m_val->count)
34810Sstevel@tonic-gate 				continue;
34820Sstevel@tonic-gate 			}
34830Sstevel@tonic-gate 			begin = sam[i];
34840Sstevel@tonic-gate 			/* skip over service tag */
34850Sstevel@tonic-gate 			if (begin != NULL)
34860Sstevel@tonic-gate 				begin = strchr(begin, ':');
34870Sstevel@tonic-gate 			if (begin != NULL) {
34880Sstevel@tonic-gate 			    len = strlen(begin) - 3;
34890Sstevel@tonic-gate 			    for (i = 0; i < len; i++)
34900Sstevel@tonic-gate 				if (strncasecmp(begin + i, "tls:", 4) == 0)
34910Sstevel@tonic-gate 					break;
34920Sstevel@tonic-gate 			    has_tls = i < len;
34930Sstevel@tonic-gate 			}
34940Sstevel@tonic-gate 		    }
34950Sstevel@tonic-gate 		    (void) __ns_ldap_freeParam((void ***) &sam);
34960Sstevel@tonic-gate 		}
34970Sstevel@tonic-gate 		if (errorp != NULL)
34980Sstevel@tonic-gate 			(void) __ns_ldap_freeError(&errorp);
34990Sstevel@tonic-gate 		errorp = NULL;
35000Sstevel@tonic-gate 	}
35010Sstevel@tonic-gate 
35020Sstevel@tonic-gate 	if (has_tls) {
35030Sstevel@tonic-gate 		/*
35040Sstevel@tonic-gate 		 * Don't check that address is legal - only determine
35050Sstevel@tonic-gate 		 * if there is a port specified
35060Sstevel@tonic-gate 		 */
35070Sstevel@tonic-gate 		if (list->defaultServerList != NULL)
35080Sstevel@tonic-gate 			is_ok = !has_port(list->defaultServerList);
35090Sstevel@tonic-gate 		else if (get_config && is_ok) {
35100Sstevel@tonic-gate 			rc = __ns_ldap_getParam(NS_LDAP_SERVERS_P,
35110Sstevel@tonic-gate 				(void ***) &servers, &errorp);
35120Sstevel@tonic-gate 			if (rc == NS_LDAP_SUCCESS && servers != NULL) {
35130Sstevel@tonic-gate 				for (i = 0; servers[i] != NULL && is_ok; i++)
35140Sstevel@tonic-gate 					is_ok = !has_port(servers[i]);
35150Sstevel@tonic-gate 				(void) __ns_ldap_freeParam((void ***) &servers);
35160Sstevel@tonic-gate 			}
35170Sstevel@tonic-gate 		}
35180Sstevel@tonic-gate 		if (errorp != NULL)
35190Sstevel@tonic-gate 			(void) __ns_ldap_freeError(&errorp);
35200Sstevel@tonic-gate 		errorp = NULL;
35210Sstevel@tonic-gate 
35220Sstevel@tonic-gate 		if (is_ok)
35230Sstevel@tonic-gate 			is_ok = !has_port(list->preferredServerList);
35240Sstevel@tonic-gate 		else if (get_config && is_ok) {
35250Sstevel@tonic-gate 			rc = __ns_ldap_getParam(NS_LDAP_SERVER_PREF_P,
35260Sstevel@tonic-gate 				(void ***) &servers, &errorp);
35270Sstevel@tonic-gate 			if (rc == NS_LDAP_SUCCESS && servers != NULL) {
35280Sstevel@tonic-gate 				for (i = 0; servers[i] != NULL && is_ok; i++)
35290Sstevel@tonic-gate 					is_ok = !has_port(servers[i]);
35300Sstevel@tonic-gate 				(void) __ns_ldap_freeParam((void ***) &servers);
35310Sstevel@tonic-gate 			}
35320Sstevel@tonic-gate 			if (errorp != NULL)
35330Sstevel@tonic-gate 				(void) __ns_ldap_freeError(&errorp);
35340Sstevel@tonic-gate 		}
35350Sstevel@tonic-gate 	}
35360Sstevel@tonic-gate 
35370Sstevel@tonic-gate 	return (is_ok);
35380Sstevel@tonic-gate }
35390Sstevel@tonic-gate 
35400Sstevel@tonic-gate 
35410Sstevel@tonic-gate /*
35420Sstevel@tonic-gate  * Manipulate the service as instructed by "dowhat"
35430Sstevel@tonic-gate  */
35440Sstevel@tonic-gate static int
35450Sstevel@tonic-gate do_service(const char *fmri, boolean_t waitflag, int dowhat,
35460Sstevel@tonic-gate 		const char *state) {
35470Sstevel@tonic-gate 
35480Sstevel@tonic-gate 	int		status;
35490Sstevel@tonic-gate 	boolean_t	is_maint;
35500Sstevel@tonic-gate 	const char	*what = gettext("not set");
35510Sstevel@tonic-gate 	useconds_t	max;
35520Sstevel@tonic-gate 
35530Sstevel@tonic-gate 	/* Check if we are in maintenance */
35540Sstevel@tonic-gate 	is_maint = is_service(fmri, SCF_STATE_STRING_MAINT);
35550Sstevel@tonic-gate 
35560Sstevel@tonic-gate 	switch (dowhat) {
35570Sstevel@tonic-gate 	case START_SERVICE:
35580Sstevel@tonic-gate 		what = gettext("start");
35590Sstevel@tonic-gate 		status = smf_enable_instance(fmri,
35600Sstevel@tonic-gate 			(sysid_install == B_TRUE)?SMF_TEMPORARY:0);
35610Sstevel@tonic-gate 		break;
35620Sstevel@tonic-gate 	case STOP_SERVICE:
35630Sstevel@tonic-gate 		what = gettext("stop");
35640Sstevel@tonic-gate 		status = smf_disable_instance(fmri,
35650Sstevel@tonic-gate 			(sysid_install == B_TRUE)?SMF_TEMPORARY:0);
35660Sstevel@tonic-gate 		break;
35670Sstevel@tonic-gate 	case RESTART_SERVICE:
35680Sstevel@tonic-gate 		what = gettext("restart");
35690Sstevel@tonic-gate 		status = smf_restart_instance(fmri);
35700Sstevel@tonic-gate 		break;
35710Sstevel@tonic-gate 	default:
35720Sstevel@tonic-gate 		/* coding error; will not happen */
35730Sstevel@tonic-gate 		assert(0);
35740Sstevel@tonic-gate 	}
35750Sstevel@tonic-gate 
35760Sstevel@tonic-gate 	/*
35770Sstevel@tonic-gate 	 * If the service was previously in maintenance then we need to
35780Sstevel@tonic-gate 	 * clear it immediately.  The "dowhat" action will set the
35790Sstevel@tonic-gate 	 * enabled property of the service as intended by the caller while
35800Sstevel@tonic-gate 	 * clear will actually cause it to be enabled/disabled.
35810Sstevel@tonic-gate 	 * We assume that the caller has called us after taking some
35820Sstevel@tonic-gate 	 * recovery action. Even if it's not the case, we don't lose
35830Sstevel@tonic-gate 	 * anything.
35840Sstevel@tonic-gate 	 */
35850Sstevel@tonic-gate 	if (status == 0 && is_maint == B_TRUE) {
35860Sstevel@tonic-gate 		if (mode_verbose)
35870Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
35880Sstevel@tonic-gate 				"%s: %s... %s\n",
35890Sstevel@tonic-gate 				what,
35900Sstevel@tonic-gate 				fmri,
35910Sstevel@tonic-gate 				gettext("restoring from maintenance state"));
35920Sstevel@tonic-gate 		status = smf_restore_instance(fmri);
35930Sstevel@tonic-gate 	}
35940Sstevel@tonic-gate 
35950Sstevel@tonic-gate 	if (status == 0) {
35960Sstevel@tonic-gate 		/* Check if we need to wait ? */
35970Sstevel@tonic-gate 		if (waitflag == B_FALSE) {
35980Sstevel@tonic-gate 			if (mode_verbose)
35990Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
36000Sstevel@tonic-gate 					"%s: %s... %s\n",
36010Sstevel@tonic-gate 					what,
36020Sstevel@tonic-gate 					fmri,
36030Sstevel@tonic-gate 					gettext("success"));
36040Sstevel@tonic-gate 			return (CLIENT_SUCCESS);
36050Sstevel@tonic-gate 		}
36060Sstevel@tonic-gate 
36070Sstevel@tonic-gate 		/* Otherwise wait for max seconds (from the manifest) */
36080Sstevel@tonic-gate 		max = get_timeout_value(dowhat, fmri, DEFAULT_TIMEOUT);
36090Sstevel@tonic-gate 		status = wait_till(fmri, state, max, what, !is_maint);
36100Sstevel@tonic-gate 		if (status == CLIENT_SUCCESS)
36110Sstevel@tonic-gate 			return (CLIENT_SUCCESS);
36120Sstevel@tonic-gate 		/* For error fall through for corrective action */
36130Sstevel@tonic-gate 	} else {
36140Sstevel@tonic-gate 		/* Well, service failed ... */
36150Sstevel@tonic-gate 		if (mode_verbose)
36160Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, "%s: %s... %s: %s\n",
36170Sstevel@tonic-gate 				what,
36180Sstevel@tonic-gate 				fmri,
36190Sstevel@tonic-gate 				gettext("failed"),
36200Sstevel@tonic-gate 				scf_strerror(scf_error()));
36210Sstevel@tonic-gate 		status = CLIENT_ERR_FAIL;
36220Sstevel@tonic-gate 		/* For error fall through for corrective action */
36230Sstevel@tonic-gate 	}
36240Sstevel@tonic-gate 
36250Sstevel@tonic-gate 	/*
36260Sstevel@tonic-gate 	 * If service is still offline after start/restart, then transitioning
36270Sstevel@tonic-gate 	 * failed and guess is restarter failed to apply the timeout as well.
36280Sstevel@tonic-gate 	 * So instead of leaving it offline, let's just disable it until we have
36290Sstevel@tonic-gate 	 * some other mechanism available from smf to handle such situation.
36300Sstevel@tonic-gate 	 */
36310Sstevel@tonic-gate 	if (dowhat != STOP_SERVICE)
36320Sstevel@tonic-gate 		if (is_service(fmri, SCF_STATE_STRING_OFFLINE)) {
36330Sstevel@tonic-gate 			if (mode_verbose)
36340Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
36350Sstevel@tonic-gate 					"%s: %s... %s\n",
36360Sstevel@tonic-gate 					what,
36370Sstevel@tonic-gate 					fmri,
36380Sstevel@tonic-gate 					gettext("offline to disable"));
36390Sstevel@tonic-gate 			(void) disable_service(fmri, waitflag);
36400Sstevel@tonic-gate 		}
36410Sstevel@tonic-gate 
36420Sstevel@tonic-gate 	return (status);
36430Sstevel@tonic-gate }
36440Sstevel@tonic-gate 
36450Sstevel@tonic-gate 
36460Sstevel@tonic-gate /*
36470Sstevel@tonic-gate  * Wait for "max" usecs for the service described by "fmri" to change
36480Sstevel@tonic-gate  * to "state". If check_maint is true then return immediately if
36490Sstevel@tonic-gate  * service goes into maintenance
36500Sstevel@tonic-gate  */
36510Sstevel@tonic-gate static int
36520Sstevel@tonic-gate wait_till(const char *fmri, const char *state, useconds_t max,
36530Sstevel@tonic-gate 		const char *what, boolean_t check_maint) {
36540Sstevel@tonic-gate 	char *st;
36550Sstevel@tonic-gate 	useconds_t usecs = INIT_WAIT_USECS;
36560Sstevel@tonic-gate 
36570Sstevel@tonic-gate 	for (; max > 0; max -= usecs) {
36580Sstevel@tonic-gate 		/* incremental wait */
36590Sstevel@tonic-gate 		usecs *= 2;
36600Sstevel@tonic-gate 		usecs = (usecs > max)?max:usecs;
36610Sstevel@tonic-gate 		if (mode_verbose)
36620Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
36630Sstevel@tonic-gate 				"%s: %s %u %s\n",
36640Sstevel@tonic-gate 				what, gettext("sleep"), usecs,
36650Sstevel@tonic-gate 				gettext("microseconds"));
36660Sstevel@tonic-gate 		(void) usleep(usecs);
36670Sstevel@tonic-gate 
36680Sstevel@tonic-gate 		/* Check state after the wait */
36690Sstevel@tonic-gate 		if ((st = smf_get_state(fmri)) != NULL) {
36700Sstevel@tonic-gate 			if (strcmp(st, state) == 0) {
36710Sstevel@tonic-gate 				if (mode_verbose)
36720Sstevel@tonic-gate 					CLIENT_FPRINTF(stderr,
36730Sstevel@tonic-gate 						"%s: %s... %s\n",
36740Sstevel@tonic-gate 						what,
36750Sstevel@tonic-gate 						fmri,
36760Sstevel@tonic-gate 						gettext("success"));
36770Sstevel@tonic-gate 				free(st);
36780Sstevel@tonic-gate 				return (CLIENT_SUCCESS);
36790Sstevel@tonic-gate 			}
36800Sstevel@tonic-gate 
36810Sstevel@tonic-gate 			/*
36820Sstevel@tonic-gate 			 * If service has gone into maintenance then
36830Sstevel@tonic-gate 			 * we will time out anyway, so we are better
36840Sstevel@tonic-gate 			 * off returning now
36850Sstevel@tonic-gate 			 */
36860Sstevel@tonic-gate 			if (check_maint &&
36870Sstevel@tonic-gate 				strcmp(st, SCF_STATE_STRING_MAINT) == 0) {
36880Sstevel@tonic-gate 				if (mode_verbose)
36890Sstevel@tonic-gate 					CLIENT_FPRINTF(stderr,
36900Sstevel@tonic-gate 						"%s: %s... %s\n",
36910Sstevel@tonic-gate 						what,
36920Sstevel@tonic-gate 						fmri,
36930Sstevel@tonic-gate 						gettext("maintenance"));
36940Sstevel@tonic-gate 				free(st);
36950Sstevel@tonic-gate 				return (CLIENT_ERR_MAINTENANCE);
36960Sstevel@tonic-gate 			}
36970Sstevel@tonic-gate 			free(st);
36980Sstevel@tonic-gate 		} else {
36990Sstevel@tonic-gate 			if (mode_verbose)
37000Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
37010Sstevel@tonic-gate 						"%s: %s... %s: %s\n",
37020Sstevel@tonic-gate 						what,
37030Sstevel@tonic-gate 						fmri,
37040Sstevel@tonic-gate 						gettext("failed"),
37050Sstevel@tonic-gate 						scf_strerror(scf_error()));
37060Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
37070Sstevel@tonic-gate 		}
37080Sstevel@tonic-gate 	}
37090Sstevel@tonic-gate 
37100Sstevel@tonic-gate 	/* Timed out waiting */
37110Sstevel@tonic-gate 	if (mode_verbose)
37120Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
37130Sstevel@tonic-gate 			"%s: %s... %s\n",
37140Sstevel@tonic-gate 			what,
37150Sstevel@tonic-gate 			fmri,
37160Sstevel@tonic-gate 			gettext("timed out"));
37170Sstevel@tonic-gate 	return (CLIENT_ERR_TIMEDOUT);
37180Sstevel@tonic-gate }
37190Sstevel@tonic-gate 
37200Sstevel@tonic-gate 
37210Sstevel@tonic-gate static boolean_t
37220Sstevel@tonic-gate is_service(const char *fmri, const char *state) {
37230Sstevel@tonic-gate 	char		*st;
37240Sstevel@tonic-gate 	boolean_t	result = B_FALSE;
37250Sstevel@tonic-gate 
37260Sstevel@tonic-gate 	if ((st = smf_get_state(fmri)) != NULL) {
37270Sstevel@tonic-gate 		if (strcmp(st, state) == 0)
37280Sstevel@tonic-gate 			result = B_TRUE;
37290Sstevel@tonic-gate 		free(st);
37300Sstevel@tonic-gate 	}
37310Sstevel@tonic-gate 	return (result);
37320Sstevel@tonic-gate }
37330Sstevel@tonic-gate 
37340Sstevel@tonic-gate 
37350Sstevel@tonic-gate /*
37360Sstevel@tonic-gate  *
37370Sstevel@tonic-gate  * get_timeout_val : returns the timeout value set in fmri manifest
37380Sstevel@tonic-gate  * 	inputs	: action(start/stop)
37390Sstevel@tonic-gate  *	fmri(defined fmri string)
37400Sstevel@tonic-gate  *	Returns default if error, the timeout val otherwise
37410Sstevel@tonic-gate  *
37420Sstevel@tonic-gate  */
37430Sstevel@tonic-gate 
37440Sstevel@tonic-gate static useconds_t
37450Sstevel@tonic-gate get_timeout_value(int dowhat, const char *fmri, useconds_t default_val)
37460Sstevel@tonic-gate {
37470Sstevel@tonic-gate 	scf_simple_prop_t	*sp = NULL;
37480Sstevel@tonic-gate 	uint64_t		*cp = NULL;
37490Sstevel@tonic-gate 	int			timeout = default_val/1000000;
37500Sstevel@tonic-gate 	char			*action = NULL;
37510Sstevel@tonic-gate 	const char		*actionstr = NULL;
37520Sstevel@tonic-gate 
37530Sstevel@tonic-gate 	switch (dowhat)  {
37540Sstevel@tonic-gate 		case START_SERVICE:
37550Sstevel@tonic-gate 		case RESTART_SERVICE:
37560Sstevel@tonic-gate 				action = "start";
37570Sstevel@tonic-gate 				actionstr = gettext("start");
37580Sstevel@tonic-gate 				break;
37590Sstevel@tonic-gate 		case STOP_SERVICE:
37600Sstevel@tonic-gate 				action = "stop";
37610Sstevel@tonic-gate 				actionstr = gettext("stop");
37620Sstevel@tonic-gate 				break;
37630Sstevel@tonic-gate 		default:
37640Sstevel@tonic-gate 			assert(0);
37650Sstevel@tonic-gate 	}
37660Sstevel@tonic-gate 
37670Sstevel@tonic-gate 
37680Sstevel@tonic-gate 	sp = scf_simple_prop_get(NULL, fmri, action, SCF_PROPERTY_TIMEOUT);
37690Sstevel@tonic-gate 	if (sp == NULL) {
37700Sstevel@tonic-gate 		if (mode_verbose)
37710Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, "%s: %s... %s: %s\n",
37720Sstevel@tonic-gate 				actionstr,
37730Sstevel@tonic-gate 				fmri,
37740Sstevel@tonic-gate 				gettext("failed to retrieve timeout property"),
37750Sstevel@tonic-gate 				scf_strerror(scf_error()));
37760Sstevel@tonic-gate 		return (default_val);
37770Sstevel@tonic-gate 	}
37780Sstevel@tonic-gate 
37790Sstevel@tonic-gate 	cp = scf_simple_prop_next_count(sp);
37800Sstevel@tonic-gate 	if (cp == NULL) {
37810Sstevel@tonic-gate 		if (mode_verbose)
37820Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, "%s: %s... %s: %s\n",
37830Sstevel@tonic-gate 				actionstr,
37840Sstevel@tonic-gate 				fmri,
37850Sstevel@tonic-gate 				gettext("failed to retrieve timeout value"),
37860Sstevel@tonic-gate 				scf_strerror(scf_error()));
37870Sstevel@tonic-gate 		scf_simple_prop_free(sp);
37880Sstevel@tonic-gate 		return (default_val);
37890Sstevel@tonic-gate 	}
37900Sstevel@tonic-gate 
37910Sstevel@tonic-gate 	if (*cp != 0)
37920Sstevel@tonic-gate 		timeout = *cp;
37930Sstevel@tonic-gate 	scf_simple_prop_free(sp);
37940Sstevel@tonic-gate 	return (timeout * 1000000);
37950Sstevel@tonic-gate }
3796