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
52830Sdjl  * Common Development and Distribution License (the "License").
62830Sdjl  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*6842Sth160488  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate  * ldapclient command. To make (initiailize) or uninitialize a machines as
300Sstevel@tonic-gate  * and LDAP client.  This command MUST be run as root (or it will simply exit).
310Sstevel@tonic-gate  *
320Sstevel@tonic-gate  *	-I	Install. No file_backup/recover for installing only (no doc).
330Sstevel@tonic-gate  *
340Sstevel@tonic-gate  *	init	Initialze (create) an LDAP client from a profile stored
350Sstevel@tonic-gate  *		in a directory-server.
360Sstevel@tonic-gate  *	manual	Initialze (create) an LDAP client by hand (-file option
370Sstevel@tonic-gate  *		reads from file).
380Sstevel@tonic-gate  *	mod	Modify the LDAP client configuration on this machine by hand.
390Sstevel@tonic-gate  *	list	List the contents of the LDAP client cache files.
400Sstevel@tonic-gate  *	uninit	Uninitialize this machine.
410Sstevel@tonic-gate  *
420Sstevel@tonic-gate  *	-v	Verbose flag.
430Sstevel@tonic-gate  *	-q	Quiet flag (mutually exclusive with -v).
440Sstevel@tonic-gate  *
450Sstevel@tonic-gate  *	-a attrName=attrVal
460Sstevel@tonic-gate  *	<attrName> can be one of the following:
470Sstevel@tonic-gate  *
480Sstevel@tonic-gate  *	attributeMap
490Sstevel@tonic-gate  *		Attribute map.  Can be multiple instances of this option.
500Sstevel@tonic-gate  *		(no former option)
510Sstevel@tonic-gate  *	authenticationMethod
520Sstevel@tonic-gate  *		Authentication method (formerly -a)
530Sstevel@tonic-gate  *	bindTimeLimit
540Sstevel@tonic-gate  *		Bind time limit. (no former option)
550Sstevel@tonic-gate  *	certificatePath
560Sstevel@tonic-gate  *		Path to certificates used for secure bind (no former option)
570Sstevel@tonic-gate  *	credentialLevel
580Sstevel@tonic-gate  *		Client credential level (no former option)
590Sstevel@tonic-gate  *	defaultServerList
600Sstevel@tonic-gate  *		Default server (no former option) Refer to DUA Config
610Sstevel@tonic-gate  *		Schema draft.
620Sstevel@tonic-gate  *	defaultSearchBase
630Sstevel@tonic-gate  *		Search Base DN. e.g. dc=eng,dc=sun,dc=com (formerly -b)
640Sstevel@tonic-gate  *	defaultSearchScope
650Sstevel@tonic-gate  *		Search scope. (formerly -s)
660Sstevel@tonic-gate  *	domainName
670Sstevel@tonic-gate  *		Hosts lookup domain (DNS)  Ex. eng.sun.com (formerly -d)
680Sstevel@tonic-gate  *	followReferrals
690Sstevel@tonic-gate  *		Search dereference. followref or noref (default followref)
700Sstevel@tonic-gate  *		(formerly -r)
710Sstevel@tonic-gate  *	objectclassMap
720Sstevel@tonic-gate  *		Objectclass map.  Can be multiple instances of this option.
730Sstevel@tonic-gate  *		(no former option)
740Sstevel@tonic-gate  *	preferredServerList
750Sstevel@tonic-gate  *		Server preference list. Comma ',' seperated list of IPaddr.
760Sstevel@tonic-gate  *		(formerly -p)
770Sstevel@tonic-gate  *	profileName
780Sstevel@tonic-gate  *		Profile name to use for init (ldapclient) or
790Sstevel@tonic-gate  *		generate (gen_profile). (formerly -P)
800Sstevel@tonic-gate  *	profileTTL
810Sstevel@tonic-gate  *		Client info TTL.  If set to 0 this information will not be
820Sstevel@tonic-gate  *		automatically updated by the ldap_cachemgr(1M).
830Sstevel@tonic-gate  *		(formerly -e)
840Sstevel@tonic-gate  *	proxyDN
850Sstevel@tonic-gate  *		Binding DN.  Ex. cn=client,ou=people,cd=eng,dc=sun,dc=com
860Sstevel@tonic-gate  *		(formerly -D)
870Sstevel@tonic-gate  *	proxyPassword
880Sstevel@tonic-gate  *		Client password not needed for authentication "none".
890Sstevel@tonic-gate  *		(formerly -w)
900Sstevel@tonic-gate  *	searchTimeLimit
910Sstevel@tonic-gate  *		Timeout value. (formerly -o)
920Sstevel@tonic-gate  *	serviceSearchDescriptor
930Sstevel@tonic-gate  *		Service search scope. (no former option)
940Sstevel@tonic-gate  *	serviceAuthenticationMethod
950Sstevel@tonic-gate  *		Service authenticaion method (no former option)
960Sstevel@tonic-gate  *	serviceCredentialLevel
970Sstevel@tonic-gate  *		Service credential level (no former option)
980Sstevel@tonic-gate  *
990Sstevel@tonic-gate  */
1000Sstevel@tonic-gate 
1010Sstevel@tonic-gate #include <stdlib.h>
1020Sstevel@tonic-gate #include <stdio.h>
1030Sstevel@tonic-gate #include <unistd.h>
1040Sstevel@tonic-gate #include <errno.h>
1050Sstevel@tonic-gate #include <sys/types.h>
1060Sstevel@tonic-gate #include <time.h>
1070Sstevel@tonic-gate #include <sys/param.h>
1080Sstevel@tonic-gate #include <sys/stat.h>
1090Sstevel@tonic-gate #include <sys/systeminfo.h>
1100Sstevel@tonic-gate #include <fcntl.h>
1110Sstevel@tonic-gate #include <xti.h>
1120Sstevel@tonic-gate #include <strings.h>
1130Sstevel@tonic-gate #include <limits.h>
1140Sstevel@tonic-gate #include <locale.h>
1150Sstevel@tonic-gate #include <syslog.h>
1160Sstevel@tonic-gate #include <libscf.h>
1170Sstevel@tonic-gate #include <assert.h>
118*6842Sth160488 
119*6842Sth160488 #include "standalone.h"
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
1220Sstevel@tonic-gate #define	TEXT_DOMAIN "SUNW_OST_OSCMD"
1230Sstevel@tonic-gate #endif
1240Sstevel@tonic-gate 
1250Sstevel@tonic-gate /* error codes */
1260Sstevel@tonic-gate /* The manpage doc only allows for SUCCESS(0), FAIL(1) and CRED(2) on exit */
1270Sstevel@tonic-gate #define	CLIENT_SUCCESS		0
1280Sstevel@tonic-gate #define	CLIENT_ERR_PARSE	-1
1290Sstevel@tonic-gate #define	CLIENT_ERR_FAIL		1
1300Sstevel@tonic-gate #define	CLIENT_ERR_CREDENTIAL	2
1310Sstevel@tonic-gate #define	CLIENT_ERR_MEMORY	3
1320Sstevel@tonic-gate #define	CLIENT_ERR_RESTORE	4
1330Sstevel@tonic-gate #define	CLIENT_ERR_RENAME	5
1340Sstevel@tonic-gate #define	CLIENT_ERR_RECOVER	6
1350Sstevel@tonic-gate #define	CLIENT_ERR_TIMEDOUT	7
1360Sstevel@tonic-gate #define	CLIENT_ERR_MAINTENANCE	8
1370Sstevel@tonic-gate 
1380Sstevel@tonic-gate /* Reset flag for start_services() */
1390Sstevel@tonic-gate #define	START_INIT	1
1400Sstevel@tonic-gate #define	START_RESET	2
1410Sstevel@tonic-gate #define	START_UNINIT	3
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate /* Reset flag for stop_services() */
1440Sstevel@tonic-gate #define	STATE_NOSAVE	0
1450Sstevel@tonic-gate #define	STATE_SAVE	1
1460Sstevel@tonic-gate 
1470Sstevel@tonic-gate /* files to (possibiliy) restore */
1480Sstevel@tonic-gate #define	LDAP_RESTORE_DIR	"/var/ldap/restore"
1490Sstevel@tonic-gate 
1500Sstevel@tonic-gate #define	DOMAINNAME_DIR		"/etc"
1510Sstevel@tonic-gate #define	DOMAINNAME_FILE		"defaultdomain"
1520Sstevel@tonic-gate #define	DOMAINNAME		DOMAINNAME_DIR "/" DOMAINNAME_FILE
1530Sstevel@tonic-gate #define	DOMAINNAME_BACK		LDAP_RESTORE_DIR "/" DOMAINNAME_FILE
1540Sstevel@tonic-gate 
1550Sstevel@tonic-gate #define	NSSWITCH_DIR		"/etc"
1560Sstevel@tonic-gate #define	NSSWITCH_FILE		"nsswitch.conf"
1570Sstevel@tonic-gate #define	NSSWITCH_CONF		NSSWITCH_DIR "/" NSSWITCH_FILE
1580Sstevel@tonic-gate #define	NSSWITCH_BACK		LDAP_RESTORE_DIR "/" NSSWITCH_FILE
1590Sstevel@tonic-gate #define	NSSWITCH_LDAP		"/etc/nsswitch.ldap"
1600Sstevel@tonic-gate 
1610Sstevel@tonic-gate #define	NIS_COLDSTART_DIR	"/var/nis"
1620Sstevel@tonic-gate #define	NIS_COLDSTART_FILE	"NIS_COLD_START"
1630Sstevel@tonic-gate #define	NIS_COLDSTART		NIS_COLDSTART_DIR "/" NIS_COLDSTART_FILE
1640Sstevel@tonic-gate #define	NIS_COLDSTART_BACK	LDAP_RESTORE_DIR "/" NIS_COLDSTART_FILE
1650Sstevel@tonic-gate 
1660Sstevel@tonic-gate #define	YP_BIND_DIR		"/var/yp/binding"
1670Sstevel@tonic-gate 
1680Sstevel@tonic-gate /* Define the service FMRIs */
1690Sstevel@tonic-gate #define	SENDMAIL_FMRI		"network/smtp:sendmail"
1700Sstevel@tonic-gate #define	NSCD_FMRI		"system/name-service-cache:default"
1710Sstevel@tonic-gate #define	AUTOFS_FMRI		"system/filesystem/autofs:default"
1720Sstevel@tonic-gate #define	LDAP_FMRI		"network/ldap/client:default"
1730Sstevel@tonic-gate #define	NISD_FMRI		"network/rpc/nisplus:default"
1740Sstevel@tonic-gate #define	YP_FMRI			"network/nis/client:default"
1750Sstevel@tonic-gate #define	NS_MILESTONE_FMRI	"milestone/name-services:default"
1760Sstevel@tonic-gate 
1770Sstevel@tonic-gate /* Define flags for checking if services were enabled */
1780Sstevel@tonic-gate #define	SENDMAIL_ON	0x1
1790Sstevel@tonic-gate #define	NSCD_ON		0x10
1800Sstevel@tonic-gate #define	AUTOFS_ON	0x100
1810Sstevel@tonic-gate 
1820Sstevel@tonic-gate #define	CMD_DOMAIN_START	"/usr/bin/domainname"
1830Sstevel@tonic-gate 
1840Sstevel@tonic-gate /* Command to copy files */
1850Sstevel@tonic-gate #define	CMD_CP			"/bin/cp -f"
1860Sstevel@tonic-gate #define	CMD_MV			"/bin/mv -f"
1870Sstevel@tonic-gate #define	CMD_RM			"/bin/rm -f"
1880Sstevel@tonic-gate 
1890Sstevel@tonic-gate #define	TO_DEV_NULL		" >/dev/null 2>&1"
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate /* Files that need to be just removed */
1920Sstevel@tonic-gate #define	NIS_PRIVATE_CACHE	"/var/nis/.NIS_PRIVATE_DIRCACHE"
1930Sstevel@tonic-gate #define	NIS_SHARED_CACHE	"/var/nis/NIS_SHARED_DIRCACHE"
1940Sstevel@tonic-gate #define	NIS_CLIENT_INFO		"/var/nis/client_info"
1950Sstevel@tonic-gate #define	LDAP_CACHE_LOG		"/var/ldap/cachemgr.log"
1960Sstevel@tonic-gate 
1970Sstevel@tonic-gate /* Output defines to supress if quiet mode set */
1980Sstevel@tonic-gate #define	CLIENT_FPUTS if (!mode_quiet) (void) fputs
1990Sstevel@tonic-gate #define	CLIENT_FPRINTF if (!mode_quiet) (void) fprintf
2000Sstevel@tonic-gate #define	CLIENT_FPUTC if (!mode_quiet) (void) fputc
2010Sstevel@tonic-gate 
2020Sstevel@tonic-gate #define	restart_service(fmri, waitflag)\
2030Sstevel@tonic-gate 		do_service(fmri, waitflag, RESTART_SERVICE,\
2040Sstevel@tonic-gate 		SCF_STATE_STRING_ONLINE)
2050Sstevel@tonic-gate #define	start_service(fmri, waitflag)	\
2060Sstevel@tonic-gate 		do_service(fmri, waitflag, START_SERVICE,\
2070Sstevel@tonic-gate 		SCF_STATE_STRING_ONLINE)
2080Sstevel@tonic-gate #define	disable_service(fmri, waitflag)	\
2090Sstevel@tonic-gate 		do_service(fmri, waitflag, STOP_SERVICE,\
2100Sstevel@tonic-gate 		SCF_STATE_STRING_DISABLED)
2110Sstevel@tonic-gate 
2120Sstevel@tonic-gate /*
2130Sstevel@tonic-gate  * There isn't a domainName defined as a param, so we set a value here
2140Sstevel@tonic-gate  * (1001) should be big enough
2150Sstevel@tonic-gate  */
2160Sstevel@tonic-gate #define	LOCAL_DOMAIN_P 1001
2170Sstevel@tonic-gate 
2180Sstevel@tonic-gate #define	START_SERVICE	1
2190Sstevel@tonic-gate #define	STOP_SERVICE	2
2200Sstevel@tonic-gate #define	RESTART_SERVICE	3
2210Sstevel@tonic-gate 
2220Sstevel@tonic-gate #define	DEFAULT_TIMEOUT	60000000
2230Sstevel@tonic-gate 
2240Sstevel@tonic-gate #define	INIT_WAIT_USECS	50000
2250Sstevel@tonic-gate 
2260Sstevel@tonic-gate /* Used to turn off profile checking */
2270Sstevel@tonic-gate #define	CACHETTL_OFF "0"
2280Sstevel@tonic-gate 
2290Sstevel@tonic-gate /* Globals */
2300Sstevel@tonic-gate static char *cmd;
2310Sstevel@tonic-gate 
2320Sstevel@tonic-gate static char *dname = NULL;
2330Sstevel@tonic-gate static char dname_buf[BUFSIZ];
2340Sstevel@tonic-gate 
2350Sstevel@tonic-gate static boolean_t sysid_install = B_FALSE;
2360Sstevel@tonic-gate 
2370Sstevel@tonic-gate static int mode_verbose = 0;
2380Sstevel@tonic-gate static int mode_quiet = 0;
2390Sstevel@tonic-gate static int gen = 0;
2400Sstevel@tonic-gate 
2410Sstevel@tonic-gate static int gStartLdap = 0;
2420Sstevel@tonic-gate static int gStartYp = 0;
2430Sstevel@tonic-gate static int gStartNisd = 0;
2440Sstevel@tonic-gate 
2450Sstevel@tonic-gate static int enableFlag = 0;
2460Sstevel@tonic-gate 
2470Sstevel@tonic-gate /* multival_t is used to hold params that can have more than one value */
2480Sstevel@tonic-gate typedef struct {
2490Sstevel@tonic-gate 	int count;
2500Sstevel@tonic-gate 	char **optlist;
2510Sstevel@tonic-gate } multival_t;
2520Sstevel@tonic-gate 
2530Sstevel@tonic-gate static multival_t *multival_new();
2540Sstevel@tonic-gate static int multival_add(multival_t *list, char *opt);
2550Sstevel@tonic-gate static void multival_free(multival_t *list);
2560Sstevel@tonic-gate 
2570Sstevel@tonic-gate /*
2580Sstevel@tonic-gate  * clientopts_t is used to hold and pass around the param values from
2590Sstevel@tonic-gate  * the cmd line
2600Sstevel@tonic-gate  */
2610Sstevel@tonic-gate typedef struct {
2620Sstevel@tonic-gate 	multival_t	*attributeMap;
2630Sstevel@tonic-gate 	char		*authenticationMethod;
2640Sstevel@tonic-gate 	char		*bindTimeLimit;
2650Sstevel@tonic-gate 	char		*certificatePath;
2660Sstevel@tonic-gate 	char		*credentialLevel;
2670Sstevel@tonic-gate 	char		*defaultSearchBase;
2680Sstevel@tonic-gate 	char		*defaultServerList;
2690Sstevel@tonic-gate 	char		*domainName;
2700Sstevel@tonic-gate 	char		*followReferrals;
2710Sstevel@tonic-gate 	multival_t	*objectclassMap;
2720Sstevel@tonic-gate 	char		*preferredServerList;
2730Sstevel@tonic-gate 	char		*profileName;
2740Sstevel@tonic-gate 	char		*profileTTL;
2750Sstevel@tonic-gate 	char		*proxyDN;
2760Sstevel@tonic-gate 	char		*proxyPassword;
277*6842Sth160488 	char		*bindDN;
278*6842Sth160488 	char		*bindPasswd;
2790Sstevel@tonic-gate 	char		*defaultSearchScope;
2800Sstevel@tonic-gate 	char		*searchTimeLimit;
2810Sstevel@tonic-gate 	multival_t	*serviceAuthenticationMethod;
2820Sstevel@tonic-gate 	multival_t	*serviceCredentialLevel;
2830Sstevel@tonic-gate 	multival_t	*serviceSearchDescriptor;
2840Sstevel@tonic-gate } clientopts_t;
2850Sstevel@tonic-gate 
2860Sstevel@tonic-gate static clientopts_t *clientopts_new();
2870Sstevel@tonic-gate static void clientopts_free(clientopts_t *list);
2880Sstevel@tonic-gate 
2890Sstevel@tonic-gate extern ns_ldap_error_t *__ns_ldap_print_config(int);
2900Sstevel@tonic-gate extern void __ns_ldap_default_config();
2912830Sdjl extern int __ns_ldap_download(const char *, char *, char *, ns_ldap_error_t **);
2920Sstevel@tonic-gate 
2930Sstevel@tonic-gate /* Function prototypes (these could be static) */
2940Sstevel@tonic-gate static void usage(void);
2950Sstevel@tonic-gate 
2960Sstevel@tonic-gate static int credCheck(clientopts_t *arglist);
2970Sstevel@tonic-gate static int clientSetParam(clientopts_t *optlist, int paramFlag, char *attrVal);
2980Sstevel@tonic-gate static int parseParam(char *param, char **paramVal);
2990Sstevel@tonic-gate static void dumpargs(clientopts_t *arglist);
3000Sstevel@tonic-gate static int num_args(clientopts_t *arglist);
3010Sstevel@tonic-gate 
3020Sstevel@tonic-gate static int file_backup(void);
3030Sstevel@tonic-gate static int recover(int saveState);
3040Sstevel@tonic-gate static int mod_backup(void);
3050Sstevel@tonic-gate static int mod_recover(void);
3060Sstevel@tonic-gate static void mod_cleanup(void);
3070Sstevel@tonic-gate 
3080Sstevel@tonic-gate static int client_list(clientopts_t *arglist);
3090Sstevel@tonic-gate static int client_manual(clientopts_t *arglist);
3100Sstevel@tonic-gate static int client_mod(clientopts_t *arglist);
3110Sstevel@tonic-gate static int client_uninit(clientopts_t *arglist);
3120Sstevel@tonic-gate static int client_genProfile(clientopts_t *arglist);
3130Sstevel@tonic-gate static int client_init(clientopts_t *arglist);
3140Sstevel@tonic-gate static int file_move(const char *from, const char *to);
3150Sstevel@tonic-gate 
3160Sstevel@tonic-gate static int start_services(int flag);
3170Sstevel@tonic-gate static int stop_services(int saveState);
3180Sstevel@tonic-gate static boolean_t is_service(const char *fmri, const char *state);
3190Sstevel@tonic-gate static int wait_till(const char *fmri, const char *state, useconds_t max,
3200Sstevel@tonic-gate 		const char *what, boolean_t check_maint);
3210Sstevel@tonic-gate static int do_service(const char *fmri, boolean_t waitflag, int dowhat,
3220Sstevel@tonic-gate 		const char *state);
3230Sstevel@tonic-gate static useconds_t get_timeout_value(int dowhat, const char *fmri,
3240Sstevel@tonic-gate 		useconds_t default_val);
3250Sstevel@tonic-gate 
326702Sth160488 int
327702Sth160488 main(int argc, char **argv)
3280Sstevel@tonic-gate {
329*6842Sth160488 	char		*ret_locale, *ret_textdomain;
330*6842Sth160488 	int		retcode;
331*6842Sth160488 	int		paramFlag;
332*6842Sth160488 	char		*attrVal;
333*6842Sth160488 	int		sysinfostatus;
334*6842Sth160488 	clientopts_t	*optlist = NULL;
335*6842Sth160488 	int		op_manual = 0, op_mod = 0, op_uninit = 0;
336*6842Sth160488 	int		op_list = 0, op_init = 0, op_genprofile = 0;
337*6842Sth160488 	extern char	*optarg;
338*6842Sth160488 	extern int	optind;
339*6842Sth160488 	int		option;
3400Sstevel@tonic-gate 
3410Sstevel@tonic-gate 	ret_locale = setlocale(LC_ALL, "");
3420Sstevel@tonic-gate 	if (ret_locale == NULL) {
3430Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Unable to set locale.\n"), stderr);
3440Sstevel@tonic-gate 	}
3450Sstevel@tonic-gate 	ret_textdomain = textdomain(TEXT_DOMAIN);
3460Sstevel@tonic-gate 	if (ret_textdomain == NULL) {
3470Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Unable to set textdomain.\n"), stderr);
3480Sstevel@tonic-gate 	}
3490Sstevel@tonic-gate 
3500Sstevel@tonic-gate 	openlog("ldapclient", LOG_PID, LOG_USER);
3510Sstevel@tonic-gate 
3520Sstevel@tonic-gate 	/* get name that invoked us */
3530Sstevel@tonic-gate 	if (cmd = strrchr(argv[0], '/'))
3540Sstevel@tonic-gate 		++cmd;
3550Sstevel@tonic-gate 	else
3560Sstevel@tonic-gate 		cmd = argv[0];
3570Sstevel@tonic-gate 
3580Sstevel@tonic-gate 	sysinfostatus = sysinfo(SI_SRPC_DOMAIN, dname_buf, BUFSIZ);
3590Sstevel@tonic-gate 	if (0 < sysinfostatus)
3600Sstevel@tonic-gate 		dname = &dname_buf[0];
3610Sstevel@tonic-gate 
3620Sstevel@tonic-gate 	optlist = clientopts_new();
3630Sstevel@tonic-gate 	if (optlist == NULL) {
3640Sstevel@tonic-gate 		CLIENT_FPUTS(
365*6842Sth160488 		    gettext("Error getting optlist (malloc fail)\n"),
366*6842Sth160488 		    stderr);
3670Sstevel@tonic-gate 		exit(CLIENT_ERR_FAIL);
3680Sstevel@tonic-gate 	}
3690Sstevel@tonic-gate 
3700Sstevel@tonic-gate 	optind = 1;
3710Sstevel@tonic-gate 	while (optind < argc) {
372*6842Sth160488 		option = getopt(argc, argv, "vqa:ID:w:j:y:");
3730Sstevel@tonic-gate 
3740Sstevel@tonic-gate 		switch (option) {
3750Sstevel@tonic-gate 		case 'v':
3760Sstevel@tonic-gate 			mode_verbose = 1;
3770Sstevel@tonic-gate 			break;
3780Sstevel@tonic-gate 		case 'q':
3790Sstevel@tonic-gate 			mode_quiet = 1;
3800Sstevel@tonic-gate 			break;
3810Sstevel@tonic-gate 		case 'a':
3820Sstevel@tonic-gate 			attrVal = NULL;
3830Sstevel@tonic-gate 			paramFlag = parseParam(optarg, &attrVal);
3840Sstevel@tonic-gate 			if (paramFlag == CLIENT_ERR_PARSE) {
3850Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
386*6842Sth160488 				    gettext("Unrecognized "
387*6842Sth160488 				    "parameter \"%s\"\n"),
388*6842Sth160488 				    optarg);
3890Sstevel@tonic-gate 				usage();
3900Sstevel@tonic-gate 				exit(CLIENT_ERR_FAIL);
3910Sstevel@tonic-gate 			}
392*6842Sth160488 			if (paramFlag == NS_LDAP_BINDPASSWD_P &&
393*6842Sth160488 			    optlist->proxyPassword != NULL) {
394*6842Sth160488 				(void) fprintf(stderr,
395*6842Sth160488 				    gettext("The -a proxyPassword option is "
396*6842Sth160488 				    "mutually exclusive of -y. "
397*6842Sth160488 				    "-a proxyPassword is ignored.\n"));
398*6842Sth160488 				break;
399*6842Sth160488 			}
4000Sstevel@tonic-gate 			retcode = clientSetParam(optlist, paramFlag, attrVal);
4010Sstevel@tonic-gate 			if (retcode != CLIENT_SUCCESS) {
4020Sstevel@tonic-gate 				CLIENT_FPRINTF(
403*6842Sth160488 				    stderr,
404*6842Sth160488 				    gettext("Error (%d) setting "
405*6842Sth160488 				    "param \"%s\"\n"),
406*6842Sth160488 				    retcode, optarg);
4070Sstevel@tonic-gate 				usage();
4080Sstevel@tonic-gate 				exit(CLIENT_ERR_FAIL);
4090Sstevel@tonic-gate 			}
4100Sstevel@tonic-gate 			break;
411*6842Sth160488 		case 'D':
412*6842Sth160488 			optlist->bindDN = strdup(optarg);
413*6842Sth160488 			break;
414*6842Sth160488 		case 'w':
415*6842Sth160488 			if (optlist->bindPasswd != NULL) {
416*6842Sth160488 				CLIENT_FPRINTF(stderr,
417*6842Sth160488 				    gettext("The -w option is mutually "
418*6842Sth160488 				    "exclusive of -j. -w is ignored."));
419*6842Sth160488 				break;
420*6842Sth160488 			}
421*6842Sth160488 
422*6842Sth160488 			if (optarg[0] == '-' && optarg[1] == '\0') {
423*6842Sth160488 				/* Ask for a password later */
424*6842Sth160488 				break;
425*6842Sth160488 			}
426*6842Sth160488 
427*6842Sth160488 			optlist->bindPasswd = strdup(optarg);
428*6842Sth160488 			break;
429*6842Sth160488 		case 'j':
430*6842Sth160488 			if (optlist->bindPasswd != NULL) {
431*6842Sth160488 				(void) fprintf(stderr,
432*6842Sth160488 				    gettext("The -w option is mutually "
433*6842Sth160488 				    "exclusive of -j. -w is ignored.\n"));
434*6842Sth160488 				free(optlist->bindPasswd);
435*6842Sth160488 			}
436*6842Sth160488 			optlist->bindPasswd = readPwd(optarg);
437*6842Sth160488 			if (optlist->bindPasswd == NULL) {
438*6842Sth160488 				exit(CLIENT_ERR_FAIL);
439*6842Sth160488 			}
440*6842Sth160488 			break;
441*6842Sth160488 		case 'y':
442*6842Sth160488 			if (optlist->proxyPassword != NULL) {
443*6842Sth160488 				(void) fprintf(stderr,
444*6842Sth160488 				    gettext("The -a proxyPassword option is "
445*6842Sth160488 				    "mutually exclusive of -y. "
446*6842Sth160488 				    "-a proxyPassword is ignored.\n"));
447*6842Sth160488 				free(optlist->proxyPassword);
448*6842Sth160488 			}
449*6842Sth160488 			optlist->proxyPassword = readPwd(optarg);
450*6842Sth160488 			if (optlist->proxyPassword == NULL) {
451*6842Sth160488 				exit(CLIENT_ERR_FAIL);
452*6842Sth160488 			}
453*6842Sth160488 			break;
4540Sstevel@tonic-gate 		case EOF:
4550Sstevel@tonic-gate 			if (strcmp(argv[optind], "init") == 0) {
4560Sstevel@tonic-gate 				op_init = 1;
4570Sstevel@tonic-gate 			} else if (strcmp(argv[optind], "manual") == 0) {
4580Sstevel@tonic-gate 				op_manual = 1;
4590Sstevel@tonic-gate 			} else if (strcmp(argv[optind], "mod") == 0) {
4600Sstevel@tonic-gate 				op_mod = 1;
4610Sstevel@tonic-gate 			} else if (strcmp(argv[optind], "list") == 0) {
4620Sstevel@tonic-gate 				op_list = 1;
4630Sstevel@tonic-gate 			} else if (strcmp(argv[optind], "uninit") == 0) {
4640Sstevel@tonic-gate 				op_uninit = 1;
4650Sstevel@tonic-gate 			} else if (strcmp(argv[optind], "genprofile") == 0) {
4660Sstevel@tonic-gate 				gen = 1;
4670Sstevel@tonic-gate 				op_genprofile = 1;
4680Sstevel@tonic-gate 			} else if (optind == argc-1) {
4690Sstevel@tonic-gate 				retcode = clientSetParam(
470*6842Sth160488 				    optlist,
471*6842Sth160488 				    NS_LDAP_SERVERS_P,
472*6842Sth160488 				    argv[optind]);	/* ipAddr */
4730Sstevel@tonic-gate 				if (retcode != CLIENT_SUCCESS) {
4740Sstevel@tonic-gate 					CLIENT_FPRINTF(
475*6842Sth160488 					    stderr,
476*6842Sth160488 					    gettext("Error (%d) setting "
477*6842Sth160488 					    "serverList param.\n"),
478*6842Sth160488 					    retcode);
4790Sstevel@tonic-gate 					usage();
4800Sstevel@tonic-gate 					exit(CLIENT_ERR_FAIL);
4810Sstevel@tonic-gate 				}
4820Sstevel@tonic-gate 			} else {
4830Sstevel@tonic-gate 				CLIENT_FPUTS(
484*6842Sth160488 				    gettext("Error parsing "
485*6842Sth160488 				    "command line\n"),
486*6842Sth160488 				    stderr);
4870Sstevel@tonic-gate 				usage();
4880Sstevel@tonic-gate 				exit(CLIENT_ERR_FAIL);
4890Sstevel@tonic-gate 			}
4900Sstevel@tonic-gate 			optind++;	/* get past the verb and keep trying */
4910Sstevel@tonic-gate 			break;
4920Sstevel@tonic-gate 		/* Backwards compatibility to support system install */
4930Sstevel@tonic-gate 		case 'I':
4940Sstevel@tonic-gate 			sysid_install = B_TRUE;
4950Sstevel@tonic-gate 			op_init = 1;
4960Sstevel@tonic-gate 			mode_quiet = 1;
4970Sstevel@tonic-gate 			break;
4980Sstevel@tonic-gate 		case '?':
4990Sstevel@tonic-gate 			usage();
5000Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("\nOr\n\n"), stderr);
5010Sstevel@tonic-gate 			gen = 1;
5020Sstevel@tonic-gate 			usage();
5030Sstevel@tonic-gate 			exit(CLIENT_ERR_FAIL);
5040Sstevel@tonic-gate 			break;
5050Sstevel@tonic-gate 		}
5060Sstevel@tonic-gate 
5070Sstevel@tonic-gate 	}
5080Sstevel@tonic-gate 
5090Sstevel@tonic-gate 	if ((getuid() != 0) && (!op_genprofile)) {
5100Sstevel@tonic-gate 		(void) puts(
511*6842Sth160488 		    "You must be root (SuperUser) to run this command.");
5120Sstevel@tonic-gate 		usage();
5130Sstevel@tonic-gate 		exit(CLIENT_ERR_FAIL);
5140Sstevel@tonic-gate 	}
5150Sstevel@tonic-gate 
5160Sstevel@tonic-gate /*
5170Sstevel@tonic-gate  *	All command line arguments are finished being parsed now
5180Sstevel@tonic-gate  */
5190Sstevel@tonic-gate 
5200Sstevel@tonic-gate /* *** Do semantic checking here *** */
5210Sstevel@tonic-gate 
5220Sstevel@tonic-gate /* if gen and no no searchBase then err */
5230Sstevel@tonic-gate 	if (gen && !optlist->defaultSearchBase) {
5240Sstevel@tonic-gate 		CLIENT_FPUTS(
525*6842Sth160488 		    gettext("ldapclient: Missing required attrName "
526*6842Sth160488 		    "defaultSearchBase\n"),
527*6842Sth160488 		    stderr);
5280Sstevel@tonic-gate 		usage();
5290Sstevel@tonic-gate 		clientopts_free(optlist);
5300Sstevel@tonic-gate 		exit(CLIENT_ERR_FAIL);
5310Sstevel@tonic-gate 	}
5320Sstevel@tonic-gate 
5330Sstevel@tonic-gate /* Only one verb can be specified */
5340Sstevel@tonic-gate 	if ((op_init + op_manual + op_mod + op_uninit +
535*6842Sth160488 	    op_list + op_genprofile) != 1) {
5360Sstevel@tonic-gate 		usage();
5370Sstevel@tonic-gate 		clientopts_free(optlist);
5380Sstevel@tonic-gate 		exit(CLIENT_ERR_FAIL);
5390Sstevel@tonic-gate 	}
5400Sstevel@tonic-gate 
5410Sstevel@tonic-gate /* *** We passed semantic checking, so now do the operation *** */
5420Sstevel@tonic-gate 
5430Sstevel@tonic-gate 	if (mode_verbose) {
5440Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Arguments parsed:\n"), stderr);
5450Sstevel@tonic-gate 		dumpargs(optlist);
5460Sstevel@tonic-gate 	}
5470Sstevel@tonic-gate 
5480Sstevel@tonic-gate 
5490Sstevel@tonic-gate /* handle "ldapclient list" here.  err checking done in func */
5500Sstevel@tonic-gate 	if (op_list) {
5510Sstevel@tonic-gate 		if (mode_verbose)
5520Sstevel@tonic-gate 			CLIENT_FPUTS(
553*6842Sth160488 			    gettext("Handling list option\n"),
554*6842Sth160488 			    stderr);
5550Sstevel@tonic-gate 		retcode = client_list(optlist);
5560Sstevel@tonic-gate 	}
5570Sstevel@tonic-gate 
5580Sstevel@tonic-gate /* handle "ldapclient uninit" here */
5590Sstevel@tonic-gate 	if (op_uninit) {
5600Sstevel@tonic-gate 		if (mode_verbose)
5610Sstevel@tonic-gate 			CLIENT_FPUTS(
562*6842Sth160488 			    gettext("Handling uninit option\n"),
563*6842Sth160488 			    stderr);
5640Sstevel@tonic-gate 		retcode = client_uninit(optlist);
5650Sstevel@tonic-gate 	}
5660Sstevel@tonic-gate 
5670Sstevel@tonic-gate /* handle "ldapclient init" (profile) */
5680Sstevel@tonic-gate 	if (op_init) {
5690Sstevel@tonic-gate 		if (mode_verbose)
5700Sstevel@tonic-gate 			CLIENT_FPUTS(
571*6842Sth160488 			    gettext("Handling init option\n"),
572*6842Sth160488 			    stderr);
5730Sstevel@tonic-gate 		retcode = client_init(optlist);
5740Sstevel@tonic-gate 	}
5750Sstevel@tonic-gate 
5760Sstevel@tonic-gate /* handle "genprofile" here */
5770Sstevel@tonic-gate 	if (op_genprofile) {
5780Sstevel@tonic-gate 		if (mode_verbose)
5790Sstevel@tonic-gate 			CLIENT_FPUTS(
580*6842Sth160488 			    gettext("Handling genProfile\n"),
581*6842Sth160488 			    stderr);
5820Sstevel@tonic-gate 		retcode = client_genProfile(optlist);
5830Sstevel@tonic-gate 	}
5840Sstevel@tonic-gate 
5850Sstevel@tonic-gate /* handle "ldapclient manual" here */
5860Sstevel@tonic-gate 	if (op_manual) {
5870Sstevel@tonic-gate 		if (mode_verbose)
5880Sstevel@tonic-gate 			CLIENT_FPUTS(
589*6842Sth160488 			    gettext("Handling manual option\n"),
590*6842Sth160488 			    stderr);
5910Sstevel@tonic-gate 		retcode = client_manual(optlist);
5920Sstevel@tonic-gate 	}
5930Sstevel@tonic-gate 
5940Sstevel@tonic-gate /* handle "ldapclient mod" here */
5950Sstevel@tonic-gate 	if (op_mod) {
5960Sstevel@tonic-gate 		if (mode_verbose)
5970Sstevel@tonic-gate 			CLIENT_FPUTS(
598*6842Sth160488 			    gettext("Handling mod option\n"),
599*6842Sth160488 			    stderr);
6000Sstevel@tonic-gate 		retcode = client_mod(optlist);
6010Sstevel@tonic-gate 	}
6020Sstevel@tonic-gate 
6030Sstevel@tonic-gate 	clientopts_free(optlist);
6040Sstevel@tonic-gate 	if ((retcode == CLIENT_SUCCESS) ||
605*6842Sth160488 	    (retcode == CLIENT_ERR_FAIL) ||
606*6842Sth160488 	    (retcode == CLIENT_ERR_CREDENTIAL))
6072830Sdjl 		return (retcode);
6080Sstevel@tonic-gate 	else
6092830Sdjl 		return (CLIENT_ERR_FAIL);
6100Sstevel@tonic-gate }
6110Sstevel@tonic-gate 
6120Sstevel@tonic-gate static int
6130Sstevel@tonic-gate client_list(clientopts_t *arglist)
6140Sstevel@tonic-gate {
6150Sstevel@tonic-gate 	ns_ldap_error_t *errorp;
6160Sstevel@tonic-gate 	int retcode = CLIENT_SUCCESS;
6170Sstevel@tonic-gate 
6180Sstevel@tonic-gate 	if (num_args(arglist) > 0) {
6190Sstevel@tonic-gate 		CLIENT_FPUTS(
620*6842Sth160488 		    gettext("No args supported with \"list\" option\n"),
621*6842Sth160488 		    stderr);
6220Sstevel@tonic-gate 		usage();
6230Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);	/* exit code here ? */
6240Sstevel@tonic-gate 	}
6250Sstevel@tonic-gate 	if ((errorp = __ns_ldap_print_config(mode_verbose)) != NULL) {
6260Sstevel@tonic-gate 		retcode = CLIENT_ERR_FAIL;
6270Sstevel@tonic-gate 		CLIENT_FPUTS(
628*6842Sth160488 		    gettext("Cannot get print configuration\n"),
629*6842Sth160488 		    stderr);
6300Sstevel@tonic-gate 		CLIENT_FPUTS(errorp->message, stderr);
6310Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
6320Sstevel@tonic-gate 		CLIENT_FPUTC('\n', stderr);
6330Sstevel@tonic-gate 	}
6340Sstevel@tonic-gate 
6350Sstevel@tonic-gate 	return (retcode);
6360Sstevel@tonic-gate }
6370Sstevel@tonic-gate 
6380Sstevel@tonic-gate static int
6390Sstevel@tonic-gate client_uninit(clientopts_t *arglist)
6400Sstevel@tonic-gate {
6410Sstevel@tonic-gate 	int retcode = CLIENT_SUCCESS;
6422830Sdjl 	ns_ldap_self_gssapi_config_t config = NS_LDAP_SELF_GSSAPI_CONFIG_NONE;
6430Sstevel@tonic-gate 
6440Sstevel@tonic-gate 	if (mode_verbose) {
6450Sstevel@tonic-gate 		CLIENT_FPUTS(
646*6842Sth160488 		    gettext("Restoring machine to previous "
647*6842Sth160488 		    "configuration state\n"),
648*6842Sth160488 		    stderr);
6490Sstevel@tonic-gate 	}
6500Sstevel@tonic-gate 
6510Sstevel@tonic-gate 	if (num_args(arglist) > 0) {
6520Sstevel@tonic-gate 		CLIENT_FPUTS(
653*6842Sth160488 		    gettext("No args supported with \"uninit\" option\n"),
654*6842Sth160488 		    stderr);
6550Sstevel@tonic-gate 		usage();
6560Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
6570Sstevel@tonic-gate 	}
6580Sstevel@tonic-gate 
6592830Sdjl 	(void) __ns_ldap_self_gssapi_config(&config);
6602830Sdjl 
6610Sstevel@tonic-gate 	retcode = stop_services(STATE_SAVE);
6622830Sdjl 
6632830Sdjl 	if (config != NS_LDAP_SELF_GSSAPI_CONFIG_NONE)
6642830Sdjl 		(void) system("/usr/sbin/cryptoadm enable metaslot");
6652830Sdjl 
6660Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
6670Sstevel@tonic-gate 		CLIENT_FPUTS(
668*6842Sth160488 		    gettext("Errors stopping network services.\n"), stderr);
6690Sstevel@tonic-gate 		/* restart whatever services we can */
6700Sstevel@tonic-gate 		(void) start_services(START_RESET);
6710Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
6720Sstevel@tonic-gate 	}
6730Sstevel@tonic-gate 
6740Sstevel@tonic-gate 	retcode = recover(STATE_SAVE);
6750Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
6760Sstevel@tonic-gate 		CLIENT_FPUTS(
677*6842Sth160488 		    gettext("Cannot recover the configuration on "
678*6842Sth160488 		    "this machine.\n"),
679*6842Sth160488 		    stderr);
6800Sstevel@tonic-gate 		(void) start_services(START_RESET);
6810Sstevel@tonic-gate 	} else {
6820Sstevel@tonic-gate 		retcode = start_services(START_UNINIT);
6830Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
6840Sstevel@tonic-gate 			CLIENT_FPUTS(
685*6842Sth160488 			    gettext("Config restored but problems "
686*6842Sth160488 			    "encountered resetting network "
687*6842Sth160488 			    "services.\n"),
688*6842Sth160488 			    stderr);
6890Sstevel@tonic-gate 		}
6900Sstevel@tonic-gate 	}
6910Sstevel@tonic-gate 
6920Sstevel@tonic-gate 	if (retcode == CLIENT_SUCCESS) {
6930Sstevel@tonic-gate 		CLIENT_FPUTS(
694*6842Sth160488 		    gettext("System successfully recovered\n"),
695*6842Sth160488 		    stderr);
6960Sstevel@tonic-gate 	}
6970Sstevel@tonic-gate 
6980Sstevel@tonic-gate 	return (retcode);
6990Sstevel@tonic-gate }
7000Sstevel@tonic-gate 
7010Sstevel@tonic-gate /*
7020Sstevel@tonic-gate  * The following macro is used to do a __ns_ldap_setParam().
7030Sstevel@tonic-gate  * On every call, the return code is checked, and if there was
7040Sstevel@tonic-gate  * a problem then the error message is printed, the ldaperr
7050Sstevel@tonic-gate  * is freed and we return from the function with the offending
7060Sstevel@tonic-gate  * error return code.  This macro keeps us from having to
7070Sstevel@tonic-gate  * repeat this code for every call to setParam as was done
7080Sstevel@tonic-gate  * in the previous incarnation of ldapclient.
7090Sstevel@tonic-gate  *
7100Sstevel@tonic-gate  * assumes a "retcode" variable is available for status
7110Sstevel@tonic-gate  */
7120Sstevel@tonic-gate #define	LDAP_SET_PARAM(argval, argdef)	\
7130Sstevel@tonic-gate retcode = 0;	\
7140Sstevel@tonic-gate if (NULL != argval) {	\
7150Sstevel@tonic-gate 	ns_ldap_error_t *ldaperr;	\
7160Sstevel@tonic-gate 	retcode = __ns_ldap_setParam(argdef, (void *)argval, &ldaperr);	\
7170Sstevel@tonic-gate 	if (retcode != NS_LDAP_SUCCESS) {	\
7180Sstevel@tonic-gate 		if (NULL != ldaperr) {	\
7190Sstevel@tonic-gate 			CLIENT_FPUTS(ldaperr->message, stderr);	\
7200Sstevel@tonic-gate 			CLIENT_FPUTC('\n', stderr);	\
7210Sstevel@tonic-gate 			(void) __ns_ldap_freeError(&ldaperr);	\
7220Sstevel@tonic-gate 		}	\
7230Sstevel@tonic-gate 		return (retcode ? CLIENT_ERR_FAIL : CLIENT_SUCCESS);	\
7240Sstevel@tonic-gate 	}	\
7250Sstevel@tonic-gate }
7260Sstevel@tonic-gate 
727*6842Sth160488 /*
728*6842Sth160488  * The following macro is used to check if an arg has already been set
729*6842Sth160488  * and issues an error message, a usage message and then returns an error.
730*6842Sth160488  * This was made into a macro to avoid the duplication of this code many
731*6842Sth160488  * times in the function below.
732*6842Sth160488  */
733*6842Sth160488 #define	LDAP_CHECK_INVALID(arg, param)	\
734*6842Sth160488 if (arg) {	\
735*6842Sth160488 	CLIENT_FPRINTF(stderr, gettext("Invalid parameter (%s) " \
736*6842Sth160488 	    "specified\n"), param);	\
737*6842Sth160488 	usage();	\
738*6842Sth160488 	return (CLIENT_ERR_FAIL);	\
739*6842Sth160488 }
740*6842Sth160488 
7410Sstevel@tonic-gate static int
7420Sstevel@tonic-gate client_manual(clientopts_t *arglist)
7430Sstevel@tonic-gate {
7440Sstevel@tonic-gate 	int counter;
7450Sstevel@tonic-gate 	int domain_fp;
7460Sstevel@tonic-gate 	ns_ldap_error_t *errorp;
7470Sstevel@tonic-gate 	int ret_copy;
7480Sstevel@tonic-gate 	int reset_ret;
7490Sstevel@tonic-gate 	int retcode = CLIENT_SUCCESS;
7500Sstevel@tonic-gate 
7510Sstevel@tonic-gate 	if (dname == NULL) {
7520Sstevel@tonic-gate 		CLIENT_FPUTS(
753*6842Sth160488 		    gettext("Manual failed: System domain not set and "
754*6842Sth160488 		    "no domainName specified.\n"),
755*6842Sth160488 		    stderr);
7560Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
7570Sstevel@tonic-gate 	}
7580Sstevel@tonic-gate 
7590Sstevel@tonic-gate 	if (arglist->defaultSearchBase == NULL) {
7600Sstevel@tonic-gate 		CLIENT_FPUTS(
761*6842Sth160488 		    gettext("Manual failed: Missing required "
762*6842Sth160488 		    "defaultSearchBase attribute.\n"),
763*6842Sth160488 		    stderr);
7640Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
7650Sstevel@tonic-gate 	}
7660Sstevel@tonic-gate 
7670Sstevel@tonic-gate 	if ((arglist->defaultServerList == NULL) &&
768*6842Sth160488 	    (arglist->preferredServerList == NULL)) {
7690Sstevel@tonic-gate 		CLIENT_FPUTS(
770*6842Sth160488 		    gettext("Manual failed: Missing required "
771*6842Sth160488 		    "defaultServerList or preferredServerList "
772*6842Sth160488 		    "attribute.\n"),
773*6842Sth160488 		    stderr);
7740Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
7750Sstevel@tonic-gate 	}
7760Sstevel@tonic-gate 
7770Sstevel@tonic-gate 	if (arglist->profileTTL != NULL) {
7780Sstevel@tonic-gate 		CLIENT_FPUTS(
779*6842Sth160488 		    gettext("Manual aborted: profileTTL is not supported "
780*6842Sth160488 		    "in manual mode.\n"),
781*6842Sth160488 		    stderr);
7820Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
7830Sstevel@tonic-gate 	}
7840Sstevel@tonic-gate 
7850Sstevel@tonic-gate 	if (arglist->profileName != NULL) {
7860Sstevel@tonic-gate 		CLIENT_FPUTS(
787*6842Sth160488 		    gettext("Manual aborted: profileName is not supported "
788*6842Sth160488 		    "in manual mode.\n"),
789*6842Sth160488 		    stderr);
7900Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
7910Sstevel@tonic-gate 	}
7920Sstevel@tonic-gate 
793*6842Sth160488 	LDAP_CHECK_INVALID(arglist->bindDN, "bind DN");
794*6842Sth160488 	LDAP_CHECK_INVALID(arglist->bindPasswd, "bind password");
7950Sstevel@tonic-gate 
7960Sstevel@tonic-gate 	__ns_ldap_setServer(TRUE);	/* Need this for _ns_setParam() */
7970Sstevel@tonic-gate 	__ns_ldap_default_config();
7980Sstevel@tonic-gate 
7990Sstevel@tonic-gate 	/* Set version to latest (not version 1) */
8000Sstevel@tonic-gate 	LDAP_SET_PARAM(NS_LDAP_VERSION, NS_LDAP_FILE_VERSION_P);
8010Sstevel@tonic-gate 
8020Sstevel@tonic-gate 	/* Set profileTTL to 0 since NO profile on manual */
8030Sstevel@tonic-gate 	LDAP_SET_PARAM(CACHETTL_OFF, NS_LDAP_CACHETTL_P);
8040Sstevel@tonic-gate 
8050Sstevel@tonic-gate 	/* Set additional valid params from command line */
8060Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->authenticationMethod, NS_LDAP_AUTH_P);
8070Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultSearchBase, NS_LDAP_SEARCH_BASEDN_P);
8080Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->credentialLevel, NS_LDAP_CREDENTIAL_LEVEL_P);
8090Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->proxyDN, NS_LDAP_BINDDN_P);
8100Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->searchTimeLimit, NS_LDAP_SEARCH_TIME_P);
8110Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->preferredServerList, NS_LDAP_SERVER_PREF_P);
8120Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->profileName, NS_LDAP_PROFILE_P);
8130Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->followReferrals, NS_LDAP_SEARCH_REF_P);
8140Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultSearchScope, NS_LDAP_SEARCH_SCOPE_P);
8150Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->bindTimeLimit, NS_LDAP_BIND_TIME_P);
8160Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->proxyPassword, NS_LDAP_BINDPASSWD_P);
8170Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultServerList, NS_LDAP_SERVERS_P);
8180Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->certificatePath, NS_LDAP_HOST_CERTPATH_P);
8190Sstevel@tonic-gate 
8200Sstevel@tonic-gate 	for (counter = 0;
821*6842Sth160488 	    counter < arglist->serviceAuthenticationMethod->count;
822*6842Sth160488 	    counter++) {
8230Sstevel@tonic-gate 
8240Sstevel@tonic-gate 		LDAP_SET_PARAM(
825*6842Sth160488 		    arglist->serviceAuthenticationMethod->optlist[counter],
826*6842Sth160488 		    NS_LDAP_SERVICE_AUTH_METHOD_P);
8270Sstevel@tonic-gate 	}
8280Sstevel@tonic-gate 	for (counter = 0;
829*6842Sth160488 	    counter < arglist->serviceCredentialLevel->count;
830*6842Sth160488 	    counter++) {
8310Sstevel@tonic-gate 
8320Sstevel@tonic-gate 		LDAP_SET_PARAM(
833*6842Sth160488 		    arglist->serviceCredentialLevel->optlist[counter],
834*6842Sth160488 		    NS_LDAP_SERVICE_CRED_LEVEL_P);
8350Sstevel@tonic-gate 	}
8360Sstevel@tonic-gate 	for (counter = 0;
837*6842Sth160488 	    counter < arglist->objectclassMap->count;
838*6842Sth160488 	    counter++) {
8390Sstevel@tonic-gate 
8400Sstevel@tonic-gate 		LDAP_SET_PARAM(arglist->objectclassMap->optlist[counter],
841*6842Sth160488 		    NS_LDAP_OBJECTCLASSMAP_P);
8420Sstevel@tonic-gate 	}
8430Sstevel@tonic-gate 	for (counter = 0; counter < arglist->attributeMap->count; counter++) {
8440Sstevel@tonic-gate 		LDAP_SET_PARAM(arglist->attributeMap->optlist[counter],
845*6842Sth160488 		    NS_LDAP_ATTRIBUTEMAP_P);
8460Sstevel@tonic-gate 	}
8470Sstevel@tonic-gate 	for (counter = 0;
848*6842Sth160488 	    counter < arglist->serviceSearchDescriptor->count;
849*6842Sth160488 	    counter++) {
8500Sstevel@tonic-gate 
8510Sstevel@tonic-gate 		LDAP_SET_PARAM(
852*6842Sth160488 		    arglist->serviceSearchDescriptor->optlist[counter],
853*6842Sth160488 		    NS_LDAP_SERVICE_SEARCH_DESC_P);
8540Sstevel@tonic-gate 	}
8550Sstevel@tonic-gate 
8560Sstevel@tonic-gate 	retcode = credCheck(arglist);
8570Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
8580Sstevel@tonic-gate 		CLIENT_FPUTS(
859*6842Sth160488 		    gettext("Error in setting up credentials\n"),
860*6842Sth160488 		    stderr);
8610Sstevel@tonic-gate 		return (retcode);
8620Sstevel@tonic-gate 	}
8630Sstevel@tonic-gate 
8640Sstevel@tonic-gate 	if (mode_verbose)
8650Sstevel@tonic-gate 		CLIENT_FPUTS(
866*6842Sth160488 		    gettext("About to modify this machines "
867*6842Sth160488 		    "configuration by writing the files\n"),
868*6842Sth160488 		    stderr);
8690Sstevel@tonic-gate 
8700Sstevel@tonic-gate 	/* get ready to start playing with files */
8710Sstevel@tonic-gate 	retcode = stop_services(STATE_SAVE);
8720Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
8730Sstevel@tonic-gate 		CLIENT_FPUTS(
874*6842Sth160488 		    gettext("Errors stopping network services.\n"), stderr);
8750Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
8760Sstevel@tonic-gate 	}
8770Sstevel@tonic-gate 
8780Sstevel@tonic-gate 	/* Save orig versions of files */
8790Sstevel@tonic-gate 	retcode = file_backup();
8800Sstevel@tonic-gate 	if (retcode == CLIENT_ERR_RESTORE) {
8810Sstevel@tonic-gate 		CLIENT_FPUTS(
882*6842Sth160488 		    gettext("System not in state to enable ldap client.\n"),
883*6842Sth160488 		    stderr);
8840Sstevel@tonic-gate 
8850Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
8860Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
8870Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
888*6842Sth160488 			    "starting services during reset\n"),
889*6842Sth160488 			    reset_ret);
8900Sstevel@tonic-gate 		}
8910Sstevel@tonic-gate 		return (retcode);
8920Sstevel@tonic-gate 	} else if (retcode != CLIENT_SUCCESS) {
8930Sstevel@tonic-gate 		CLIENT_FPUTS(
894*6842Sth160488 		    gettext("Save of system configuration failed!  "
895*6842Sth160488 		    "Attempting recovery.\n"),
896*6842Sth160488 		    stderr);
8970Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
8980Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
8990Sstevel@tonic-gate 			CLIENT_FPUTS(
900*6842Sth160488 			    gettext("Recovery of systems configuration "
901*6842Sth160488 			    "failed.  Manual intervention of "
902*6842Sth160488 			    "config files is required.\n"),
903*6842Sth160488 			    stderr);
9040Sstevel@tonic-gate 			return (retcode);
9050Sstevel@tonic-gate 		}
9060Sstevel@tonic-gate 
9070Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
9080Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
9090Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
910*6842Sth160488 			    "starting services during reset\n"),
911*6842Sth160488 			    reset_ret);
9120Sstevel@tonic-gate 		}
9130Sstevel@tonic-gate 
9140Sstevel@tonic-gate 		return (retcode);
9150Sstevel@tonic-gate 	}
9160Sstevel@tonic-gate 
9170Sstevel@tonic-gate 	/* Dump new files */
9180Sstevel@tonic-gate 	errorp = __ns_ldap_DumpConfiguration(NSCONFIGFILE);
9190Sstevel@tonic-gate 	if (errorp != NULL) {
9200Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
921*6842Sth160488 		    gettext("%s manual: errorp is not NULL; %s\n"),
922*6842Sth160488 		    cmd, errorp->message);
9230Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
9240Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
9250Sstevel@tonic-gate 			CLIENT_FPUTS(
926*6842Sth160488 			    gettext("Recovery of systems configuration "
927*6842Sth160488 			    "failed.  Manual intervention of "
928*6842Sth160488 			    "config files is required.\n"),
929*6842Sth160488 			    stderr);
9300Sstevel@tonic-gate 			return (retcode);
9310Sstevel@tonic-gate 		}
9320Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
9330Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
9340Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
935*6842Sth160488 			    "starting services during reset\n"),
936*6842Sth160488 			    reset_ret);
9370Sstevel@tonic-gate 		}
9380Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
9390Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
9400Sstevel@tonic-gate 	}
9410Sstevel@tonic-gate 
9420Sstevel@tonic-gate 	/* if (credargs(arglist)) */
9430Sstevel@tonic-gate 	errorp = __ns_ldap_DumpConfiguration(NSCREDFILE);
9440Sstevel@tonic-gate 	if (errorp != NULL) {
9450Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
946*6842Sth160488 		    gettext("%s init: errorp is not NULL; %s\n"),
947*6842Sth160488 		    cmd, errorp->message);
9480Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
9490Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
9500Sstevel@tonic-gate 			CLIENT_FPUTS(
951*6842Sth160488 			    gettext("Recovery of systems configuration "
952*6842Sth160488 			    "failed.  Manual intervention of "
953*6842Sth160488 			    "config files is required.\n"),
954*6842Sth160488 			    stderr);
9550Sstevel@tonic-gate 			return (retcode);
9560Sstevel@tonic-gate 		}
9570Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
9580Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
9590Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
960*6842Sth160488 			    "starting services during reset\n"),
961*6842Sth160488 			    reset_ret);
9620Sstevel@tonic-gate 		}
9630Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
9640Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
9650Sstevel@tonic-gate 	}
9660Sstevel@tonic-gate 
9670Sstevel@tonic-gate 	ret_copy = system(CMD_CP " " NSSWITCH_LDAP " " NSSWITCH_CONF);
9680Sstevel@tonic-gate 	if (ret_copy != 0) {
9690Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
970*6842Sth160488 		    gettext("Error %d copying (%s) -> (%s)\n"),
971*6842Sth160488 		    ret_copy, NSSWITCH_LDAP, NSSWITCH_CONF);
9720Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
9730Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
9740Sstevel@tonic-gate 			CLIENT_FPUTS(
975*6842Sth160488 			    gettext("Recovery of systems configuration "
976*6842Sth160488 			    "failed.  Manual intervention of "
977*6842Sth160488 			    "config files is required.\n"),
978*6842Sth160488 			    stderr);
9790Sstevel@tonic-gate 		}
9800Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
9810Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
9820Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
983*6842Sth160488 			    "starting services during reset\n"),
984*6842Sth160488 			    reset_ret);
9850Sstevel@tonic-gate 		}
9860Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
9870Sstevel@tonic-gate 	}
9880Sstevel@tonic-gate 
9890Sstevel@tonic-gate 	if ((domain_fp = open(DOMAINNAME, O_WRONLY|O_CREAT|O_TRUNC,
990*6842Sth160488 	    S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) { /* 0644 */
9910Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr, gettext("Cannot open %s\n"), DOMAINNAME);
9920Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
9930Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
9940Sstevel@tonic-gate 			CLIENT_FPUTS(
995*6842Sth160488 			    gettext("Recovery of systems configuration "
996*6842Sth160488 			    "failed.  Manual intervention of "
997*6842Sth160488 			    "config files is required.\n"),
998*6842Sth160488 			    stderr);
9990Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
10000Sstevel@tonic-gate 		}
10010Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
10020Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
10030Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1004*6842Sth160488 			    "starting services during reset\n"),
1005*6842Sth160488 			    reset_ret);
10060Sstevel@tonic-gate 		}
10070Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
10080Sstevel@tonic-gate 	}
10090Sstevel@tonic-gate 	(void) write(domain_fp, dname, strlen(dname));
10100Sstevel@tonic-gate 	(void) write(domain_fp, "\n", 1);
10110Sstevel@tonic-gate 	(void) close(domain_fp);
10120Sstevel@tonic-gate 
10130Sstevel@tonic-gate 	retcode = start_services(START_INIT);
10140Sstevel@tonic-gate 
10150Sstevel@tonic-gate 	if (retcode == CLIENT_SUCCESS) {
10160Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("System successfully configured\n"),
1017*6842Sth160488 		    stderr);
10180Sstevel@tonic-gate 	} else {
10190Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error resetting system.\n"
1020*6842Sth160488 		    "Recovering old system settings.\n"), stderr),
1021*6842Sth160488 
1022*6842Sth160488 		    /* stop any started services for recover */
1023*6842Sth160488 		    /* don't stomp on history of saved services state */
1024*6842Sth160488 		    reset_ret = stop_services(STATE_NOSAVE);
10250Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
10260Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1027*6842Sth160488 			    "stopping services during reset\n"),
1028*6842Sth160488 			    reset_ret);
10290Sstevel@tonic-gate 			/* Coninue and try to recover what we can */
10300Sstevel@tonic-gate 		}
10310Sstevel@tonic-gate 		reset_ret = recover(STATE_NOSAVE);
10320Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
10330Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1034*6842Sth160488 			    "recovering service files during "
1035*6842Sth160488 			    "reset\n"), reset_ret);
10360Sstevel@tonic-gate 			/* Continue and start what we can */
10370Sstevel@tonic-gate 		}
10380Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
10390Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
10400Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1041*6842Sth160488 			    "starting services during reset\n"),
1042*6842Sth160488 			    reset_ret);
10430Sstevel@tonic-gate 		}
10440Sstevel@tonic-gate 	}
10450Sstevel@tonic-gate 
10460Sstevel@tonic-gate 	return (retcode);
10470Sstevel@tonic-gate }
10480Sstevel@tonic-gate 
10490Sstevel@tonic-gate static int
10500Sstevel@tonic-gate client_mod(clientopts_t *arglist)
10510Sstevel@tonic-gate {
10520Sstevel@tonic-gate 	int counter;
10530Sstevel@tonic-gate 	int domain_fp;
10540Sstevel@tonic-gate 	ns_ldap_error_t *errorp;
10550Sstevel@tonic-gate 	int reset_ret;
10560Sstevel@tonic-gate 	int retcode = CLIENT_SUCCESS;
10570Sstevel@tonic-gate 
10580Sstevel@tonic-gate 	__ns_ldap_setServer(TRUE);	/* Need this for _ns_setParam() */
10590Sstevel@tonic-gate 	if ((errorp = __ns_ldap_LoadConfiguration()) != NULL) {
10600Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Cannot get load configuration\n"),
1061*6842Sth160488 		    stderr);
10620Sstevel@tonic-gate 		CLIENT_FPUTS(errorp->message, stderr);
10630Sstevel@tonic-gate 		CLIENT_FPUTC('\n', stderr);
10640Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
10650Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
10660Sstevel@tonic-gate 	}
10670Sstevel@tonic-gate 
10680Sstevel@tonic-gate 	if (arglist->profileTTL != NULL) {
10690Sstevel@tonic-gate 		CLIENT_FPUTS(
1070*6842Sth160488 		    gettext("Mod aborted: profileTTL modification is "
1071*6842Sth160488 		    "not allowed in mod mode.\n"),
1072*6842Sth160488 		    stderr);
10730Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
10740Sstevel@tonic-gate 	}
10750Sstevel@tonic-gate 
10760Sstevel@tonic-gate 	if (arglist->profileName != NULL) {
10770Sstevel@tonic-gate 		CLIENT_FPUTS(
1078*6842Sth160488 		    gettext("Mod aborted: profileName modification is "
1079*6842Sth160488 		    "not allowed.  If you want to use profiles "
1080*6842Sth160488 		    "generate one with genProfile and load it "
1081*6842Sth160488 		    "on the server with ldapadd.\n"),
1082*6842Sth160488 		    stderr);
10830Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
10840Sstevel@tonic-gate 	}
10850Sstevel@tonic-gate 
1086*6842Sth160488 	LDAP_CHECK_INVALID(arglist->bindDN, "bind DN");
1087*6842Sth160488 	LDAP_CHECK_INVALID(arglist->bindPasswd, "bind password");
10880Sstevel@tonic-gate 
10890Sstevel@tonic-gate 	/* Set additional valid params from command line */
10900Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->authenticationMethod, NS_LDAP_AUTH_P);
10910Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultSearchBase, NS_LDAP_SEARCH_BASEDN_P);
10920Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->credentialLevel, NS_LDAP_CREDENTIAL_LEVEL_P);
10930Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->proxyDN, NS_LDAP_BINDDN_P);
10940Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->profileTTL, NS_LDAP_CACHETTL_P);
10950Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->searchTimeLimit, NS_LDAP_SEARCH_TIME_P);
10960Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->preferredServerList, NS_LDAP_SERVER_PREF_P);
10970Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->profileName, NS_LDAP_PROFILE_P);
10980Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->followReferrals, NS_LDAP_SEARCH_REF_P);
10990Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultSearchScope, NS_LDAP_SEARCH_SCOPE_P);
11000Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->bindTimeLimit, NS_LDAP_BIND_TIME_P);
11010Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->proxyPassword, NS_LDAP_BINDPASSWD_P);
11020Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultServerList, NS_LDAP_SERVERS_P);
11030Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->certificatePath, NS_LDAP_HOST_CERTPATH_P);
11040Sstevel@tonic-gate 
11050Sstevel@tonic-gate 	for (counter = 0;
1106*6842Sth160488 	    counter < arglist->serviceAuthenticationMethod->count;
1107*6842Sth160488 	    counter++) {
11080Sstevel@tonic-gate 
11090Sstevel@tonic-gate 		LDAP_SET_PARAM(
1110*6842Sth160488 		    arglist->serviceAuthenticationMethod->optlist[counter],
1111*6842Sth160488 		    NS_LDAP_SERVICE_AUTH_METHOD_P);
11120Sstevel@tonic-gate 	}
11130Sstevel@tonic-gate 	for (counter = 0;
1114*6842Sth160488 	    counter < arglist->serviceCredentialLevel->count;
1115*6842Sth160488 	    counter++) {
11160Sstevel@tonic-gate 
11170Sstevel@tonic-gate 		LDAP_SET_PARAM(
1118*6842Sth160488 		    arglist->serviceCredentialLevel->optlist[counter],
1119*6842Sth160488 		    NS_LDAP_SERVICE_CRED_LEVEL_P);
11200Sstevel@tonic-gate 	}
11210Sstevel@tonic-gate 	for (counter = 0;
1122*6842Sth160488 	    counter < arglist->objectclassMap->count;
1123*6842Sth160488 	    counter++) {
11240Sstevel@tonic-gate 
11250Sstevel@tonic-gate 		LDAP_SET_PARAM(
1126*6842Sth160488 		    arglist->objectclassMap->optlist[counter],
1127*6842Sth160488 		    NS_LDAP_OBJECTCLASSMAP_P);
11280Sstevel@tonic-gate 	}
11290Sstevel@tonic-gate 	for (counter = 0;
1130*6842Sth160488 	    counter < arglist->attributeMap->count;
1131*6842Sth160488 	    counter++) {
11320Sstevel@tonic-gate 
11330Sstevel@tonic-gate 		LDAP_SET_PARAM(
1134*6842Sth160488 		    arglist->attributeMap->optlist[counter],
1135*6842Sth160488 		    NS_LDAP_ATTRIBUTEMAP_P);
11360Sstevel@tonic-gate 	}
11370Sstevel@tonic-gate 	for (counter = 0;
1138*6842Sth160488 	    counter < arglist->serviceSearchDescriptor->count;
1139*6842Sth160488 	    counter++) {
11400Sstevel@tonic-gate 
11410Sstevel@tonic-gate 		LDAP_SET_PARAM(
1142*6842Sth160488 		    arglist->serviceSearchDescriptor->optlist[counter],
1143*6842Sth160488 		    NS_LDAP_SERVICE_SEARCH_DESC_P);
11440Sstevel@tonic-gate 	}
11450Sstevel@tonic-gate 
11460Sstevel@tonic-gate 	retcode = credCheck(arglist);
11470Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
11480Sstevel@tonic-gate 		CLIENT_FPUTS(
1149*6842Sth160488 		    gettext("Error in setting up credentials\n"),
1150*6842Sth160488 		    stderr);
11510Sstevel@tonic-gate 		return (retcode);
11520Sstevel@tonic-gate 	}
11530Sstevel@tonic-gate 
11540Sstevel@tonic-gate 	if (mode_verbose)
11550Sstevel@tonic-gate 		CLIENT_FPUTS(
1156*6842Sth160488 		    gettext("About to modify this machines configuration "
1157*6842Sth160488 		    "by writing the files\n"),
1158*6842Sth160488 		    stderr);
11590Sstevel@tonic-gate 
11600Sstevel@tonic-gate 	/* get ready to start playing with files */
11610Sstevel@tonic-gate 	retcode = stop_services(STATE_SAVE);
11620Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
11630Sstevel@tonic-gate 		CLIENT_FPUTS(
1164*6842Sth160488 		    gettext("Errors stopping network services.\n"), stderr);
11650Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
11660Sstevel@tonic-gate 	}
11670Sstevel@tonic-gate 
11680Sstevel@tonic-gate 	/* Temporarily save orig versions of files */
11690Sstevel@tonic-gate 	retcode = mod_backup();
11700Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
11710Sstevel@tonic-gate 		CLIENT_FPUTS(
1172*6842Sth160488 		    gettext("Unable to backup the ldap client files!\n"),
1173*6842Sth160488 		    stderr);
11740Sstevel@tonic-gate 
11750Sstevel@tonic-gate 		return (retcode);
11760Sstevel@tonic-gate 
11770Sstevel@tonic-gate 	}
11780Sstevel@tonic-gate 
11790Sstevel@tonic-gate 	/* Dump new files */
11800Sstevel@tonic-gate 	errorp = __ns_ldap_DumpConfiguration(NSCONFIGFILE);
11810Sstevel@tonic-gate 	if (errorp != NULL) {
11820Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
1183*6842Sth160488 		    gettext("%s mod: errorp is not NULL; %s\n"),
1184*6842Sth160488 		    cmd, errorp->message);
11850Sstevel@tonic-gate 		retcode = mod_recover();
11860Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
11870Sstevel@tonic-gate 			CLIENT_FPUTS(
1188*6842Sth160488 			    gettext("Recovery of systems configuration "
1189*6842Sth160488 			    "failed.  Manual intervention of "
1190*6842Sth160488 			    "config files is required.\n"),
1191*6842Sth160488 			    stderr);
11920Sstevel@tonic-gate 		}
11930Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
11940Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
11950Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
11960Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1197*6842Sth160488 			    "starting services during reset\n"),
1198*6842Sth160488 			    reset_ret);
11990Sstevel@tonic-gate 		}
12000Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
12010Sstevel@tonic-gate 	}
12020Sstevel@tonic-gate 
12030Sstevel@tonic-gate 	/* if (credargs(arglist)) */
12040Sstevel@tonic-gate 	errorp = __ns_ldap_DumpConfiguration(NSCREDFILE);
12050Sstevel@tonic-gate 	if (errorp != NULL) {
12060Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
1207*6842Sth160488 		    gettext("%s mod: errorp is not NULL; %s\n"),
1208*6842Sth160488 		    cmd, errorp->message);
12090Sstevel@tonic-gate 		retcode = mod_recover();
12100Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
12110Sstevel@tonic-gate 			CLIENT_FPUTS(
1212*6842Sth160488 			    gettext("Recovery of systems configuration "
1213*6842Sth160488 			    "failed.  Manual intervention of "
1214*6842Sth160488 			    "config files is required.\n"),
1215*6842Sth160488 			    stderr);
12160Sstevel@tonic-gate 		}
12170Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
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 "
1221*6842Sth160488 			    "starting services during reset\n"),
1222*6842Sth160488 			    reset_ret);
12230Sstevel@tonic-gate 		}
12240Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
12250Sstevel@tonic-gate 	}
12260Sstevel@tonic-gate 
12270Sstevel@tonic-gate 	if ((domain_fp = open(DOMAINNAME, O_WRONLY|O_CREAT|O_TRUNC,
1228*6842Sth160488 	    S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) { /* 0644 */
12290Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr, gettext("Cannot open %s\n"), DOMAINNAME);
12300Sstevel@tonic-gate 		retcode = mod_recover();
12310Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
12320Sstevel@tonic-gate 			CLIENT_FPUTS(
1233*6842Sth160488 			    gettext("Recovery of systems configuration "
1234*6842Sth160488 			    "failed!  Machine needs to be "
1235*6842Sth160488 			    "fixed!\n"),
1236*6842Sth160488 			    stderr);
12370Sstevel@tonic-gate 		}
12380Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
12390Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
12400Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1241*6842Sth160488 			    "starting services during reset\n"),
1242*6842Sth160488 			    reset_ret);
12430Sstevel@tonic-gate 		}
12440Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
12450Sstevel@tonic-gate 	}
12460Sstevel@tonic-gate 	(void) write(domain_fp, dname, strlen(dname));
12470Sstevel@tonic-gate 	(void) write(domain_fp, "\n", 1);
12480Sstevel@tonic-gate 	(void) close(domain_fp);
12490Sstevel@tonic-gate 
12500Sstevel@tonic-gate 	retcode = start_services(START_INIT);
12510Sstevel@tonic-gate 
12520Sstevel@tonic-gate 	if (retcode == CLIENT_SUCCESS) {
12530Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("System successfully configured\n"),
1254*6842Sth160488 		    stderr);
12550Sstevel@tonic-gate 	} else {
12560Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error resetting system.\n"
1257*6842Sth160488 		    "Recovering old system settings.\n"), stderr),
1258*6842Sth160488 
1259*6842Sth160488 		    /* stop any started services for recover */
1260*6842Sth160488 		    /* don't stomp on history of saved services state */
1261*6842Sth160488 		    reset_ret = stop_services(STATE_NOSAVE);
12620Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
12630Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1264*6842Sth160488 			    "stopping services during reset\n"),
1265*6842Sth160488 			    reset_ret);
12660Sstevel@tonic-gate 			/* Coninue and try to recover what we can */
12670Sstevel@tonic-gate 		}
12680Sstevel@tonic-gate 		reset_ret = mod_recover();
12690Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
12700Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1271*6842Sth160488 			    "recovering service files during "
1272*6842Sth160488 			    "reset\n"), reset_ret);
12730Sstevel@tonic-gate 			/* Continue and start what we can */
12740Sstevel@tonic-gate 		}
12750Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
12760Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
12770Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1278*6842Sth160488 			    "starting services during reset\n"),
1279*6842Sth160488 			    reset_ret);
12800Sstevel@tonic-gate 		}
12810Sstevel@tonic-gate 	}
12820Sstevel@tonic-gate 
12830Sstevel@tonic-gate 	/* Cleanup temporary files created by mod_backup() */
12840Sstevel@tonic-gate 	mod_cleanup();
12850Sstevel@tonic-gate 
12860Sstevel@tonic-gate 	return (retcode);
12870Sstevel@tonic-gate }
12880Sstevel@tonic-gate 
12890Sstevel@tonic-gate 
12900Sstevel@tonic-gate static int
12910Sstevel@tonic-gate client_genProfile(clientopts_t *arglist)
12920Sstevel@tonic-gate {
12930Sstevel@tonic-gate 	int counter;
12940Sstevel@tonic-gate 	int retcode;	/* required for LDAP_SET_PARAM macro */
12950Sstevel@tonic-gate 	ns_ldap_error_t *errorp;
12960Sstevel@tonic-gate 
12970Sstevel@tonic-gate 	if (mode_verbose)
12980Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("About to generate a profile\n"), stderr);
12990Sstevel@tonic-gate 
13000Sstevel@tonic-gate 	/* *** Check for invalid args *** */
13010Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->proxyDN, "proxyDN");
13020Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->proxyPassword, "proxyPassword");
13030Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->certificatePath, "certificatePath");
13040Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->domainName, "domainName");
1305*6842Sth160488 	LDAP_CHECK_INVALID(arglist->bindDN, "bind DN");
1306*6842Sth160488 	LDAP_CHECK_INVALID(arglist->bindPasswd, "bind password");
13070Sstevel@tonic-gate 	/* *** End check for invalid args *** */
13080Sstevel@tonic-gate 
13090Sstevel@tonic-gate 	if (arglist->profileName == NULL) {
13100Sstevel@tonic-gate 		if (mode_verbose)
13110Sstevel@tonic-gate 			CLIENT_FPUTS(
1312*6842Sth160488 			    gettext("No profile specified. "
1313*6842Sth160488 			    "Using \"default\"\n"),
1314*6842Sth160488 			    stderr);
13150Sstevel@tonic-gate 		arglist->profileName = "default";
13160Sstevel@tonic-gate 	}
13170Sstevel@tonic-gate 
13180Sstevel@tonic-gate 	__ns_ldap_setServer(TRUE);
13190Sstevel@tonic-gate 	__ns_ldap_default_config();
13200Sstevel@tonic-gate 
13210Sstevel@tonic-gate 	/* Set version to latest (not version 1) */
13220Sstevel@tonic-gate 	LDAP_SET_PARAM(NS_LDAP_VERSION, NS_LDAP_FILE_VERSION_P);
13230Sstevel@tonic-gate 
13240Sstevel@tonic-gate 	/* Set additional valid params from command line */
13250Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->authenticationMethod, NS_LDAP_AUTH_P);
13260Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultSearchBase, NS_LDAP_SEARCH_BASEDN_P);
13270Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->credentialLevel, NS_LDAP_CREDENTIAL_LEVEL_P);
13280Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->profileTTL, NS_LDAP_CACHETTL_P);
13290Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->searchTimeLimit, NS_LDAP_SEARCH_TIME_P);
13300Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->preferredServerList, NS_LDAP_SERVER_PREF_P);
13310Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->profileName, NS_LDAP_PROFILE_P);
13320Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->followReferrals, NS_LDAP_SEARCH_REF_P);
13330Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultSearchScope, NS_LDAP_SEARCH_SCOPE_P);
13340Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->bindTimeLimit, NS_LDAP_BIND_TIME_P);
13350Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultServerList, NS_LDAP_SERVERS_P);
13360Sstevel@tonic-gate 
13370Sstevel@tonic-gate 	for (counter = 0;
1338*6842Sth160488 	    counter < arglist->serviceAuthenticationMethod->count;
1339*6842Sth160488 	    counter++) {
13400Sstevel@tonic-gate 
13410Sstevel@tonic-gate 		LDAP_SET_PARAM(
1342*6842Sth160488 		    arglist->serviceAuthenticationMethod->optlist[counter],
1343*6842Sth160488 		    NS_LDAP_SERVICE_AUTH_METHOD_P);
13440Sstevel@tonic-gate 	}
13450Sstevel@tonic-gate 	for (counter = 0;
1346*6842Sth160488 	    counter < arglist->serviceCredentialLevel->count;
1347*6842Sth160488 	    counter++) {
13480Sstevel@tonic-gate 
13490Sstevel@tonic-gate 		LDAP_SET_PARAM(
1350*6842Sth160488 		    arglist->serviceCredentialLevel->optlist[counter],
1351*6842Sth160488 		    NS_LDAP_SERVICE_CRED_LEVEL_P);
13520Sstevel@tonic-gate 	}
13530Sstevel@tonic-gate 	for (counter = 0;
1354*6842Sth160488 	    counter < arglist->objectclassMap->count;
1355*6842Sth160488 	    counter++) {
13560Sstevel@tonic-gate 
13570Sstevel@tonic-gate 		LDAP_SET_PARAM(
1358*6842Sth160488 		    arglist->objectclassMap->optlist[counter],
1359*6842Sth160488 		    NS_LDAP_OBJECTCLASSMAP_P);
13600Sstevel@tonic-gate 	}
13610Sstevel@tonic-gate 	for (counter = 0;
1362*6842Sth160488 	    counter < arglist->attributeMap->count;
1363*6842Sth160488 	    counter++) {
13640Sstevel@tonic-gate 
13650Sstevel@tonic-gate 		LDAP_SET_PARAM(
1366*6842Sth160488 		    arglist->attributeMap->optlist[counter],
1367*6842Sth160488 		    NS_LDAP_ATTRIBUTEMAP_P);
13680Sstevel@tonic-gate 	}
1369*6842Sth160488 	for (counter = 0;
1370*6842Sth160488 	    counter < arglist->serviceSearchDescriptor->count;
1371*6842Sth160488 	    counter++) {
1372*6842Sth160488 
1373*6842Sth160488 		LDAP_SET_PARAM(
1374*6842Sth160488 		    arglist->serviceSearchDescriptor->optlist[counter],
1375*6842Sth160488 		    NS_LDAP_SERVICE_SEARCH_DESC_P);
13760Sstevel@tonic-gate 	}
13770Sstevel@tonic-gate 
13780Sstevel@tonic-gate 	errorp = __ns_ldap_DumpLdif(NULL);
13790Sstevel@tonic-gate 	if (errorp != NULL) {
13800Sstevel@tonic-gate 		CLIENT_FPUTS(errorp->message, stderr);
13810Sstevel@tonic-gate 		CLIENT_FPUTC('\n', stderr);
13820Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
13830Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
13840Sstevel@tonic-gate 	}
13850Sstevel@tonic-gate 
13860Sstevel@tonic-gate 	return (CLIENT_SUCCESS);
13870Sstevel@tonic-gate }
13880Sstevel@tonic-gate 
1389*6842Sth160488 /* INET6_ADDRSTRLEN + ":" + <5-digit port> + some round-up */
1390*6842Sth160488 #define	MAX_HOSTADDR_LEN (INET6_ADDRSTRLEN + 6 + 12)
1391*6842Sth160488 
13920Sstevel@tonic-gate static int
13930Sstevel@tonic-gate client_init(clientopts_t *arglist)
13940Sstevel@tonic-gate {
1395*6842Sth160488 	int			profile_fp;
1396*6842Sth160488 	int			retcode = CLIENT_SUCCESS;
1397*6842Sth160488 	ns_ldap_error_t		*errorp;
1398*6842Sth160488 	int			reset_ret;
1399*6842Sth160488 	int			ret_copy;
1400*6842Sth160488 	ns_standalone_conf_t	cfg = standaloneDefaults;
1401*6842Sth160488 	ns_auth_t		auth = {NS_LDAP_AUTH_NONE,
1402*6842Sth160488 					NS_LDAP_TLS_NONE,
1403*6842Sth160488 					NS_LDAP_SASL_NONE,
1404*6842Sth160488 					NS_LDAP_SASLOPT_NONE};
1405*6842Sth160488 	char			peer[MAX_HOSTADDR_LEN];
1406*6842Sth160488 	ns_auth_t		**authMethod;
1407*6842Sth160488 	int			**credLevel, i;
1408*6842Sth160488 	char			*cred;
14090Sstevel@tonic-gate 
14100Sstevel@tonic-gate 	if (mode_verbose)
14110Sstevel@tonic-gate 		CLIENT_FPUTS(
1412*6842Sth160488 		    gettext("About to configure machine by downloading "
1413*6842Sth160488 		    "a profile\n"),
1414*6842Sth160488 		    stderr);
14150Sstevel@tonic-gate 
14160Sstevel@tonic-gate 	if (dname == NULL) {
14170Sstevel@tonic-gate 		CLIENT_FPUTS(
1418*6842Sth160488 		    gettext("Init failed: System domain not set and "
1419*6842Sth160488 		    "no domainName specified.\n"),
1420*6842Sth160488 		    stderr);
14210Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
14220Sstevel@tonic-gate 	}
14230Sstevel@tonic-gate 
14240Sstevel@tonic-gate 	if (!arglist->defaultServerList) {
14250Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Missing LDAP server address\n"), stderr);
14260Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
14270Sstevel@tonic-gate 	}
14280Sstevel@tonic-gate 
14290Sstevel@tonic-gate 	/* *** Check for invalid args *** */
14300Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->defaultSearchBase,
1431*6842Sth160488 	    "defaultSearchBase");
14320Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->profileTTL,
1433*6842Sth160488 	    "profileTTL");
14340Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->searchTimeLimit,
1435*6842Sth160488 	    "searchTimeLimit");
14360Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->preferredServerList,
1437*6842Sth160488 	    "preferredServerList");
14380Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->followReferrals,
1439*6842Sth160488 	    "followReferrals");
14400Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->defaultSearchScope,
1441*6842Sth160488 	    "defaultSearchScope");
14420Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->bindTimeLimit,
1443*6842Sth160488 	    "bindTimeLimit");
14440Sstevel@tonic-gate 
14450Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->objectclassMap->count,
1446*6842Sth160488 	    "objectclassMap");
14470Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->attributeMap->count,
1448*6842Sth160488 	    "attributeMap");
14490Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->serviceAuthenticationMethod->count,
1450*6842Sth160488 	    "serviceAuthenticationMethod");
14510Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->serviceCredentialLevel->count,
1452*6842Sth160488 	    "serviceCredentialLevel");
14530Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->serviceSearchDescriptor->count,
1454*6842Sth160488 	    "serviceSearchDescriptor");
14550Sstevel@tonic-gate 	/* *** End check for invalid args *** */
14560Sstevel@tonic-gate 
14570Sstevel@tonic-gate 	if (arglist->profileName == NULL) {
14580Sstevel@tonic-gate 		if (mode_verbose)
14590Sstevel@tonic-gate 			CLIENT_FPUTS(
1460*6842Sth160488 			    gettext("No profile specified. "
1461*6842Sth160488 			    "Using \"default\"\n"),
1462*6842Sth160488 			    stderr);
14630Sstevel@tonic-gate 		arglist->profileName = "default";
14640Sstevel@tonic-gate 	}
14650Sstevel@tonic-gate 
1466*6842Sth160488 	(void) strncpy(peer, arglist->defaultServerList, MAX_HOSTADDR_LEN - 1);
1467*6842Sth160488 	if (separatePort(peer, &cfg.SA_SERVER, &cfg.SA_PORT) > 0) {
14680Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
14690Sstevel@tonic-gate 	}
1470*6842Sth160488 
1471*6842Sth160488 	if (arglist->bindDN != NULL) {
1472*6842Sth160488 		cfg.SA_CRED = "proxy";
1473*6842Sth160488 		/*
1474*6842Sth160488 		 * We don't want to force users to always specify authentication
1475*6842Sth160488 		 * method when we can infer it. If users wants SSL, he/she would
1476*6842Sth160488 		 * have to specify appropriate -a though.
1477*6842Sth160488 		 */
1478*6842Sth160488 		auth.type = NS_LDAP_AUTH_SIMPLE;
1479*6842Sth160488 		if (arglist->bindPasswd == NULL) {
1480*6842Sth160488 			arglist->bindPasswd =
1481*6842Sth160488 			    getpassphrase("Bind Password:");
1482*6842Sth160488 			if (arglist->bindPasswd == NULL) {
1483*6842Sth160488 				CLIENT_FPUTS(gettext("Get password failed\n"),
1484*6842Sth160488 				    stderr);
1485*6842Sth160488 
1486*6842Sth160488 				if (gStartLdap == START_RESET)
1487*6842Sth160488 					(void) start_service(LDAP_FMRI, B_TRUE);
1488*6842Sth160488 
1489*6842Sth160488 				return (CLIENT_ERR_CREDENTIAL);
1490*6842Sth160488 			}
1491*6842Sth160488 		}
14920Sstevel@tonic-gate 	}
1493*6842Sth160488 	cfg.SA_BIND_DN = arglist->bindDN;
1494*6842Sth160488 	cfg.SA_BIND_PWD = arglist->bindPasswd;
1495*6842Sth160488 
1496*6842Sth160488 	if (arglist->authenticationMethod != NULL) {
1497*6842Sth160488 		if (__ns_ldap_initAuth(arglist->authenticationMethod,
1498*6842Sth160488 		    &auth, &errorp) != NS_LDAP_SUCCESS) {
1499*6842Sth160488 			if (errorp != NULL) {
1500*6842Sth160488 				CLIENT_FPRINTF(stderr, "%s", errorp->message);
1501*6842Sth160488 				(void) __ns_ldap_freeError(&errorp);
1502*6842Sth160488 			}
1503*6842Sth160488 
1504*6842Sth160488 			if (gStartLdap == START_RESET)
1505*6842Sth160488 				(void) start_service(LDAP_FMRI, B_TRUE);
1506*6842Sth160488 
1507*6842Sth160488 			return (CLIENT_ERR_FAIL);
1508*6842Sth160488 		}
1509*6842Sth160488 		cfg.SA_AUTH = &auth;
1510*6842Sth160488 	}
1511*6842Sth160488 	cfg.SA_CRED = arglist->credentialLevel;
1512*6842Sth160488 
1513*6842Sth160488 	cfg.SA_DOMAIN = arglist->domainName;
1514*6842Sth160488 	cfg.SA_PROFILE_NAME = arglist->profileName;
1515*6842Sth160488 	cfg.SA_CERT_PATH = arglist->certificatePath;
1516*6842Sth160488 
1517*6842Sth160488 	cfg.type = NS_LDAP_SERVER;
1518*6842Sth160488 
1519*6842Sth160488 	if (__ns_ldap_initStandalone(&cfg, &errorp) != NS_LDAP_SUCCESS) {
15200Sstevel@tonic-gate 		if (errorp != NULL) {
1521*6842Sth160488 			CLIENT_FPRINTF(stderr, "%s", errorp->message);
15220Sstevel@tonic-gate 			(void) __ns_ldap_freeError(&errorp);
15230Sstevel@tonic-gate 		}
15240Sstevel@tonic-gate 
15250Sstevel@tonic-gate 		if (gStartLdap == START_RESET)
15260Sstevel@tonic-gate 			(void) start_service(LDAP_FMRI, B_TRUE);
15270Sstevel@tonic-gate 
15280Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
15290Sstevel@tonic-gate 	}
15300Sstevel@tonic-gate 
1531*6842Sth160488 	if (arglist->proxyDN != NULL && arglist->proxyPassword == NULL) {
1532*6842Sth160488 		arglist->proxyPassword = getpassphrase("Proxy Bind Password:");
1533*6842Sth160488 		if (arglist->proxyPassword == NULL) {
1534*6842Sth160488 			CLIENT_FPUTS(gettext("Get password failed\n"), stderr);
1535*6842Sth160488 
1536*6842Sth160488 			if (gStartLdap == START_RESET)
1537*6842Sth160488 				(void) start_service(LDAP_FMRI, B_TRUE);
1538*6842Sth160488 
1539*6842Sth160488 			return (CLIENT_ERR_CREDENTIAL);
1540*6842Sth160488 		}
1541*6842Sth160488 	}
1542*6842Sth160488 	if (arglist->proxyDN != NULL && arglist->proxyPassword != NULL) {
1543*6842Sth160488 		if (__ns_ldap_setParam(NS_LDAP_BINDDN_P,
1544*6842Sth160488 		    arglist->proxyDN, &errorp) != NS_LDAP_SUCCESS) {
1545*6842Sth160488 			if (errorp != NULL) {
1546*6842Sth160488 				CLIENT_FPRINTF(stderr, "%s", errorp->message);
1547*6842Sth160488 				(void) __ns_ldap_freeError(&errorp);
1548*6842Sth160488 			}
1549*6842Sth160488 			return (CLIENT_ERR_CREDENTIAL);
1550*6842Sth160488 		}
1551*6842Sth160488 		if (__ns_ldap_setParam(NS_LDAP_BINDPASSWD_P,
1552*6842Sth160488 		    arglist->proxyPassword, &errorp) != NS_LDAP_SUCCESS) {
1553*6842Sth160488 			if (errorp != NULL) {
1554*6842Sth160488 				CLIENT_FPRINTF(stderr, "%s", errorp->message);
1555*6842Sth160488 				(void) __ns_ldap_freeError(&errorp);
1556*6842Sth160488 			}
1557*6842Sth160488 			return (CLIENT_ERR_CREDENTIAL);
1558*6842Sth160488 		}
15590Sstevel@tonic-gate 	}
1560*6842Sth160488 
1561*6842Sth160488 	if (arglist->authenticationMethod != NULL) {
1562*6842Sth160488 		if (__ns_ldap_getParam(NS_LDAP_AUTH_P,
1563*6842Sth160488 		    (void ***)&authMethod, &errorp) != NS_LDAP_SUCCESS) {
1564*6842Sth160488 			if (errorp != NULL) {
1565*6842Sth160488 				CLIENT_FPRINTF(stderr, "%s", errorp->message);
1566*6842Sth160488 				(void) __ns_ldap_freeError(&errorp);
1567*6842Sth160488 			}
1568*6842Sth160488 			return (CLIENT_ERR_CREDENTIAL);
1569*6842Sth160488 		}
1570*6842Sth160488 
1571*6842Sth160488 		if (authMethod != NULL) {
1572*6842Sth160488 			for (i = 0; authMethod[i] != NULL; ++i) {
1573*6842Sth160488 				if (authMethod[i]->type == auth.type) {
1574*6842Sth160488 					break;
1575*6842Sth160488 				}
1576*6842Sth160488 			}
1577*6842Sth160488 
1578*6842Sth160488 			if (authMethod[i] == NULL) {
1579*6842Sth160488 				CLIENT_FPRINTF(stderr, gettext(
1580*6842Sth160488 				    "Warning: init authentication method "
1581*6842Sth160488 				    "not found in DUAConfigProfile.\n"));
1582*6842Sth160488 			} else {
1583*6842Sth160488 				if (i != 0) {
1584*6842Sth160488 					CLIENT_FPRINTF(stderr,
1585*6842Sth160488 					    gettext(
1586*6842Sth160488 					    "Warning: init authentication"
1587*6842Sth160488 					    "method using secondary "
1588*6842Sth160488 					    "authentication method from "
1589*6842Sth160488 					    "DUAConfigProfile.\n"));
1590*6842Sth160488 				}
1591*6842Sth160488 			}
1592*6842Sth160488 			(void) __ns_ldap_freeParam((void ***) &authMethod);
1593*6842Sth160488 		}
15940Sstevel@tonic-gate 	}
1595*6842Sth160488 
1596*6842Sth160488 	if (arglist->credentialLevel != NULL) {
1597*6842Sth160488 		if (__ns_ldap_getParam(NS_LDAP_CREDENTIAL_LEVEL_P,
1598*6842Sth160488 		    (void ***)&credLevel, &errorp) != NS_LDAP_SUCCESS) {
1599*6842Sth160488 			if (errorp != NULL) {
1600*6842Sth160488 				CLIENT_FPRINTF(stderr, "%s", errorp->message);
1601*6842Sth160488 				(void) __ns_ldap_freeError(&errorp);
1602*6842Sth160488 			}
1603*6842Sth160488 			return (CLIENT_ERR_CREDENTIAL);
1604*6842Sth160488 		}
1605*6842Sth160488 		if (credLevel != NULL) {
1606*6842Sth160488 			for (i = 0; credLevel[i] != NULL; ++i) {
1607*6842Sth160488 				switch (*credLevel[i]) {
1608*6842Sth160488 				case NS_LDAP_CRED_ANON :
1609*6842Sth160488 					cred = "none";
1610*6842Sth160488 					break;
1611*6842Sth160488 				case NS_LDAP_CRED_PROXY :
1612*6842Sth160488 					cred = "proxy";
1613*6842Sth160488 					break;
1614*6842Sth160488 				case NS_LDAP_CRED_SELF :
1615*6842Sth160488 					cred = "self";
1616*6842Sth160488 					break;
1617*6842Sth160488 				default:
1618*6842Sth160488 					continue;
1619*6842Sth160488 					break;
1620*6842Sth160488 				}
1621*6842Sth160488 				if (strcmp(cred,
1622*6842Sth160488 				    arglist->credentialLevel) == 0) {
1623*6842Sth160488 					break;
1624*6842Sth160488 				}
1625*6842Sth160488 			}
1626*6842Sth160488 			if (credLevel[i] == NULL) {
1627*6842Sth160488 				CLIENT_FPRINTF(stderr, gettext(
1628*6842Sth160488 				    "Warning: init credential level not found "
1629*6842Sth160488 				    "in DUAConfigProfile.\n"));
1630*6842Sth160488 			} else {
1631*6842Sth160488 				if (i != 0) {
1632*6842Sth160488 					CLIENT_FPRINTF(stderr,
1633*6842Sth160488 					    gettext("Warning: "
1634*6842Sth160488 					    "init credential level using "
1635*6842Sth160488 					    "secondary credential level from "
1636*6842Sth160488 					    "DUAConfigProfile.\n"));
1637*6842Sth160488 				}
1638*6842Sth160488 			}
1639*6842Sth160488 			(void) __ns_ldap_freeParam((void ***) &credLevel);
1640*6842Sth160488 		}
1641*6842Sth160488 	}
16420Sstevel@tonic-gate 
16430Sstevel@tonic-gate 	retcode = credCheck(arglist);
16440Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
16450Sstevel@tonic-gate 		CLIENT_FPUTS(
1646*6842Sth160488 		    gettext("Error in setting up credentials\n"), stderr);
16470Sstevel@tonic-gate 
16480Sstevel@tonic-gate 		if (gStartLdap == START_RESET)
16490Sstevel@tonic-gate 			(void) start_service(LDAP_FMRI, B_TRUE);
16500Sstevel@tonic-gate 
16510Sstevel@tonic-gate 		return (retcode);
16520Sstevel@tonic-gate 	}
16530Sstevel@tonic-gate 
16540Sstevel@tonic-gate 	if (mode_verbose)
16550Sstevel@tonic-gate 		CLIENT_FPUTS(
1656*6842Sth160488 		    gettext("About to modify this machines configuration "
1657*6842Sth160488 		    "by writing the files\n"),
1658*6842Sth160488 		    stderr);
16590Sstevel@tonic-gate 
16600Sstevel@tonic-gate 	/* get ready to start playing with files */
16610Sstevel@tonic-gate 	retcode = stop_services(STATE_SAVE);
16620Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
16630Sstevel@tonic-gate 		CLIENT_FPUTS(
1664*6842Sth160488 		    gettext("Errors stopping network services.\n"), stderr);
16650Sstevel@tonic-gate 
16660Sstevel@tonic-gate 		if (gStartLdap == START_RESET)
16670Sstevel@tonic-gate 			(void) start_service(LDAP_FMRI, B_TRUE);
16680Sstevel@tonic-gate 
16690Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
16700Sstevel@tonic-gate 	}
16710Sstevel@tonic-gate 
16720Sstevel@tonic-gate 	/* Save orig versions of files */
16730Sstevel@tonic-gate 	retcode = file_backup();
16740Sstevel@tonic-gate 	if (retcode == CLIENT_ERR_RESTORE) {
16750Sstevel@tonic-gate 		CLIENT_FPUTS(
1676*6842Sth160488 		    gettext("System not in state to enable ldap client.\n"),
1677*6842Sth160488 		    stderr);
16780Sstevel@tonic-gate 
16790Sstevel@tonic-gate 		return (retcode);
16800Sstevel@tonic-gate 
16810Sstevel@tonic-gate 	} else if (retcode != CLIENT_SUCCESS) {
16820Sstevel@tonic-gate 		CLIENT_FPUTS(
1683*6842Sth160488 		    gettext("Save of system configuration failed.  "
1684*6842Sth160488 		    "Attempting recovery.\n"),
1685*6842Sth160488 		    stderr);
16860Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
16870Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
16880Sstevel@tonic-gate 			CLIENT_FPUTS(
1689*6842Sth160488 			    gettext("Recovery of systems configuration "
1690*6842Sth160488 			    "failed.  Manual intervention of "
1691*6842Sth160488 			    "config files is required.\n"),
1692*6842Sth160488 			    stderr);
16930Sstevel@tonic-gate 		}
16940Sstevel@tonic-gate 
16950Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
16960Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
16970Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1698*6842Sth160488 			    "starting services during reset\n"),
1699*6842Sth160488 			    reset_ret);
17000Sstevel@tonic-gate 		}
17010Sstevel@tonic-gate 
17020Sstevel@tonic-gate 		return (retcode);
17030Sstevel@tonic-gate 	}
17040Sstevel@tonic-gate 
17050Sstevel@tonic-gate 	/* Dump new files */
17060Sstevel@tonic-gate 	errorp = __ns_ldap_DumpConfiguration(NSCONFIGFILE);
17070Sstevel@tonic-gate 	if (NULL != errorp) {
17080Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
1709*6842Sth160488 		    gettext("%s init: errorp is not NULL; %s\n"),
1710*6842Sth160488 		    cmd, errorp->message);
17110Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
17120Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
17130Sstevel@tonic-gate 			CLIENT_FPUTS(
1714*6842Sth160488 			    gettext("Recovery of systems configuration "
1715*6842Sth160488 			    "failed.  Manual intervention of "
1716*6842Sth160488 			    "config files is required.\n"),
1717*6842Sth160488 			    stderr);
17180Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
17190Sstevel@tonic-gate 		}
17200Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
17210Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
17220Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
17230Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1724*6842Sth160488 			    "starting services during reset\n"),
1725*6842Sth160488 			    reset_ret);
17260Sstevel@tonic-gate 		}
17270Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
17280Sstevel@tonic-gate 	}
17290Sstevel@tonic-gate 
17300Sstevel@tonic-gate 	/* if (credargs(arglist)) */
17310Sstevel@tonic-gate 	errorp = __ns_ldap_DumpConfiguration(NSCREDFILE);
17320Sstevel@tonic-gate 	if (NULL != errorp) {
17330Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
1734*6842Sth160488 		    gettext("%s init: errorp is not NULL; %s\n"),
1735*6842Sth160488 		    cmd, errorp->message);
17360Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
17370Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
17380Sstevel@tonic-gate 			CLIENT_FPUTS(
1739*6842Sth160488 			    gettext("Recovery of systems configuration "
1740*6842Sth160488 			    "failed.  Manual intervention of "
1741*6842Sth160488 			    "config files is required.\n"),
1742*6842Sth160488 			    stderr);
17430Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
17440Sstevel@tonic-gate 		}
17450Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
17460Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
17470Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
17480Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1749*6842Sth160488 			    "starting services during reset\n"),
1750*6842Sth160488 			    reset_ret);
17510Sstevel@tonic-gate 		}
17520Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
17530Sstevel@tonic-gate 	}
17540Sstevel@tonic-gate 
17550Sstevel@tonic-gate 	ret_copy = system(CMD_CP " " NSSWITCH_LDAP " " NSSWITCH_CONF);
17560Sstevel@tonic-gate 	if (ret_copy != 0) {
17570Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
1758*6842Sth160488 		    gettext("Error %d copying (%s) -> (%s)\n"),
1759*6842Sth160488 		    ret_copy, NSSWITCH_LDAP, NSSWITCH_CONF);
17600Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
17610Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
17620Sstevel@tonic-gate 			CLIENT_FPUTS(
1763*6842Sth160488 			    gettext("Recovery of systems configuration "
1764*6842Sth160488 			    "failed.  Manual intervention of "
1765*6842Sth160488 			    "config files is required.\n"),
1766*6842Sth160488 			    stderr);
17670Sstevel@tonic-gate 		}
17680Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
17690Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
17700Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1771*6842Sth160488 			    "starting services during reset\n"),
1772*6842Sth160488 			    reset_ret);
17730Sstevel@tonic-gate 		}
17740Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
17750Sstevel@tonic-gate 	}
17760Sstevel@tonic-gate 
17770Sstevel@tonic-gate 	if ((profile_fp = open(DOMAINNAME, O_WRONLY|O_CREAT|O_TRUNC,
1778*6842Sth160488 	    S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) { /* 0644 */
17790Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr, gettext("Cannot open %s\n"), DOMAINNAME);
17800Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
17810Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
17820Sstevel@tonic-gate 			CLIENT_FPUTS(
1783*6842Sth160488 			    gettext("Recovery of systems configuration "
1784*6842Sth160488 			    "failed.  Manual intervention of "
1785*6842Sth160488 			    "config files is required.\n"),
1786*6842Sth160488 			    stderr);
17870Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
17880Sstevel@tonic-gate 		}
17890Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
17900Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
17910Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1792*6842Sth160488 			    "starting services during reset\n"),
1793*6842Sth160488 			    reset_ret);
17940Sstevel@tonic-gate 		}
17950Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
17960Sstevel@tonic-gate 	}
17970Sstevel@tonic-gate 	(void) write(profile_fp, dname, strlen(dname));
17980Sstevel@tonic-gate 	(void) write(profile_fp, "\n", 1);
17990Sstevel@tonic-gate 	(void) close(profile_fp);
18000Sstevel@tonic-gate 
18010Sstevel@tonic-gate 	retcode = start_services(START_INIT);
18020Sstevel@tonic-gate 
18030Sstevel@tonic-gate 	if (retcode == CLIENT_SUCCESS) {
18040Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("System successfully configured\n"),
1805*6842Sth160488 		    stderr);
18060Sstevel@tonic-gate 	} else {
18070Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error resetting system.\n"
1808*6842Sth160488 		    "Recovering old system settings.\n"), stderr),
1809*6842Sth160488 
1810*6842Sth160488 		    /* stop any started services for recover */
1811*6842Sth160488 		    /* don't stomp on history of saved services state */
1812*6842Sth160488 		    reset_ret = stop_services(STATE_NOSAVE);
18130Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
18140Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1815*6842Sth160488 			    "stopping services during reset\n"),
1816*6842Sth160488 			    reset_ret);
18170Sstevel@tonic-gate 			/* Coninue and try to recover what we can */
18180Sstevel@tonic-gate 		}
18190Sstevel@tonic-gate 		reset_ret = recover(STATE_NOSAVE);
18200Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
18210Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1822*6842Sth160488 			    "recovering service files during "
1823*6842Sth160488 			    "reset\n"), reset_ret);
18240Sstevel@tonic-gate 			/* Continue and start what we can */
18250Sstevel@tonic-gate 		}
18260Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
18270Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
18280Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1829*6842Sth160488 			    "starting services during reset\n"),
1830*6842Sth160488 			    reset_ret);
18310Sstevel@tonic-gate 		}
18320Sstevel@tonic-gate 	}
18330Sstevel@tonic-gate 
18340Sstevel@tonic-gate 	return (retcode);
18350Sstevel@tonic-gate }
18360Sstevel@tonic-gate 
18370Sstevel@tonic-gate 
18380Sstevel@tonic-gate static void
18390Sstevel@tonic-gate usage(void)
18400Sstevel@tonic-gate {
18410Sstevel@tonic-gate 	if (mode_quiet)
18420Sstevel@tonic-gate 		return;
18430Sstevel@tonic-gate 
18440Sstevel@tonic-gate 	if (gen == 0) {
18450Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
1846*6842Sth160488 		    gettext("Usage: %s [-v | -q] init | manual | mod | "
1847*6842Sth160488 		    "list | uninit [<args>]\n"),
1848*6842Sth160488 		    cmd);
1849*6842Sth160488 
1850*6842Sth160488 		CLIENT_FPRINTF(stderr,
1851*6842Sth160488 		    gettext("\n       %s [-v | -q] [-a authenticationMethod]"
1852*6842Sth160488 		    " [-D bindDN]\n\t[-w bindPassword] [-j passswdFile]"
1853*6842Sth160488 		    " [-y proxyPasswordFile] init [<args>]\n"),
1854*6842Sth160488 		    cmd);
18550Sstevel@tonic-gate 
18560Sstevel@tonic-gate 		CLIENT_FPUTS(
1857*6842Sth160488 		    gettext("\nSet up a server or workstation as a "
1858*6842Sth160488 		    "client of an LDAP namespace.\n"),
1859*6842Sth160488 		    stderr);
18600Sstevel@tonic-gate 	} else {	/* genprofile */
18610Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
1862*6842Sth160488 		    gettext("Usage: %s [-v | -q] genprofile "
1863*6842Sth160488 		    "-a profileName=<name> "
1864*6842Sth160488 		    "-a defaultSearchBase=<base> <args>\n"),
1865*6842Sth160488 		    cmd);
18660Sstevel@tonic-gate 
18670Sstevel@tonic-gate 		CLIENT_FPUTS(
1868*6842Sth160488 		    gettext("\nGenerate a profile used to set up clients "
1869*6842Sth160488 		    "of an LDAP namespace.\n"),
1870*6842Sth160488 		    stderr);
18710Sstevel@tonic-gate 	}
18720Sstevel@tonic-gate 	CLIENT_FPUTS(
1873*6842Sth160488 	    gettext("<args> take the form of \'-a attrName=attrVal\' as "
1874*6842Sth160488 	    "described in the\n"),
1875*6842Sth160488 	    stderr);
18760Sstevel@tonic-gate 	CLIENT_FPUTS(gettext("man page: ldapclient(1M)\n"), stderr);
18770Sstevel@tonic-gate }
18780Sstevel@tonic-gate 
18790Sstevel@tonic-gate 
18800Sstevel@tonic-gate /*
18810Sstevel@tonic-gate  * stop_services is called to stop network services prior to their
18820Sstevel@tonic-gate  * config files being moved/changed.  In case a later recovery is needed
18830Sstevel@tonic-gate  * (an error occurs during config), we detect whether the service is
18840Sstevel@tonic-gate  * running and store that info so that a reset will only start services
18850Sstevel@tonic-gate  * that were stopped here.
18860Sstevel@tonic-gate  *
18870Sstevel@tonic-gate  * In terms of SMF, this translates to disabling the services. So we
18880Sstevel@tonic-gate  * try to disable them if they are in any other state
18890Sstevel@tonic-gate  *
18900Sstevel@tonic-gate  * Stop order :
18910Sstevel@tonic-gate  * sendmail, nscd, autofs, ldap.client, nisd (rpc), inetinit(domainname)
18920Sstevel@tonic-gate  */
18930Sstevel@tonic-gate static int
18940Sstevel@tonic-gate stop_services(int saveState)
18950Sstevel@tonic-gate {
18960Sstevel@tonic-gate 	int ret;
18970Sstevel@tonic-gate 
18980Sstevel@tonic-gate 	if (mode_verbose) {
18990Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Stopping network services\n"), stderr);
19000Sstevel@tonic-gate 	}
19010Sstevel@tonic-gate 
19020Sstevel@tonic-gate 	if (!is_service(SENDMAIL_FMRI, SCF_STATE_STRING_DISABLED)) {
19030Sstevel@tonic-gate 		if (mode_verbose)
19040Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Stopping sendmail\n"), stderr);
19050Sstevel@tonic-gate 		ret = disable_service(SENDMAIL_FMRI, B_TRUE);
19060Sstevel@tonic-gate 		if (ret != CLIENT_SUCCESS) {
19070Sstevel@tonic-gate 			/* Not serious, but tell user what to do */
19080Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Stopping sendmail "
1909*6842Sth160488 			    "failed with (%d). You may need to restart "
1910*6842Sth160488 			    "it manually for changes to take effect.\n"),
1911*6842Sth160488 			    ret);
19120Sstevel@tonic-gate 		} else enableFlag |= SENDMAIL_ON;
19130Sstevel@tonic-gate 	} else {
19140Sstevel@tonic-gate 		if (mode_verbose)
19150Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("sendmail not running\n"), stderr);
19160Sstevel@tonic-gate 	}
19170Sstevel@tonic-gate 
19180Sstevel@tonic-gate 	if (!is_service(NSCD_FMRI, SCF_STATE_STRING_DISABLED)) {
19190Sstevel@tonic-gate 		if (mode_verbose)
19200Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Stopping nscd\n"), stderr);
19210Sstevel@tonic-gate 		ret = disable_service(NSCD_FMRI, B_TRUE);
19220Sstevel@tonic-gate 		if (ret != CLIENT_SUCCESS) {
19230Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Stopping nscd "
19240Sstevel@tonic-gate 			    "failed with (%d)\n"), ret);
19250Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
19260Sstevel@tonic-gate 		} else enableFlag |= NSCD_ON;
19270Sstevel@tonic-gate 	} else {
19280Sstevel@tonic-gate 		if (mode_verbose)
19290Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("nscd not running\n"), stderr);
19300Sstevel@tonic-gate 	}
19310Sstevel@tonic-gate 
19320Sstevel@tonic-gate 	if (!is_service(AUTOFS_FMRI, SCF_STATE_STRING_DISABLED)) {
19330Sstevel@tonic-gate 		if (mode_verbose)
19340Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Stopping autofs\n"), stderr);
19350Sstevel@tonic-gate 		ret = disable_service(AUTOFS_FMRI, B_TRUE);
19360Sstevel@tonic-gate 		if (ret != CLIENT_SUCCESS) {
19370Sstevel@tonic-gate 			/* Not serious, but tell user what to do */
19380Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Stopping autofs "
1939*6842Sth160488 			    "failed with (%d). You may need to restart "
1940*6842Sth160488 			    "it manually for changes to take effect.\n"),
1941*6842Sth160488 			    ret);
19420Sstevel@tonic-gate 		} else enableFlag |= AUTOFS_ON;
19430Sstevel@tonic-gate 	} else {
19440Sstevel@tonic-gate 		if (mode_verbose)
19450Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("autofs not running\n"), stderr);
19460Sstevel@tonic-gate 	}
19470Sstevel@tonic-gate 
19480Sstevel@tonic-gate 	if (!is_service(LDAP_FMRI, SCF_STATE_STRING_DISABLED)) {
19490Sstevel@tonic-gate 		if (saveState)
19500Sstevel@tonic-gate 			gStartLdap = START_RESET;
19510Sstevel@tonic-gate 		if (mode_verbose)
19520Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Stopping ldap\n"), stderr);
19530Sstevel@tonic-gate 		ret = disable_service(LDAP_FMRI, B_TRUE);
19540Sstevel@tonic-gate 		if (ret != CLIENT_SUCCESS) {
19550Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Stopping ldap "
19560Sstevel@tonic-gate 			    "failed with (%d)\n"), ret);
19570Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
19580Sstevel@tonic-gate 		}
19590Sstevel@tonic-gate 	} else {
19600Sstevel@tonic-gate 		if (mode_verbose)
19610Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("ldap not running\n"),
1962*6842Sth160488 			    stderr);
19630Sstevel@tonic-gate 	}
19640Sstevel@tonic-gate 
19650Sstevel@tonic-gate 	if (!is_service(NISD_FMRI, SCF_STATE_STRING_DISABLED)) {
19660Sstevel@tonic-gate 		if (mode_verbose)
19670Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Stopping nisd\n"), stderr);
19680Sstevel@tonic-gate 		ret = disable_service(NISD_FMRI, B_TRUE);
19690Sstevel@tonic-gate 		if (ret != CLIENT_SUCCESS) {
19700Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Stopping nisd "
19710Sstevel@tonic-gate 			    "failed with (%d)\n"), ret);
19720Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
19730Sstevel@tonic-gate 		}
19740Sstevel@tonic-gate 	} else {
19750Sstevel@tonic-gate 		if (mode_verbose)
19760Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("nisd not running\n"),
1977*6842Sth160488 			    stderr);
19780Sstevel@tonic-gate 	}
19790Sstevel@tonic-gate 
19800Sstevel@tonic-gate 	if (!is_service(YP_FMRI, SCF_STATE_STRING_DISABLED)) {
19810Sstevel@tonic-gate 		if (saveState)
19820Sstevel@tonic-gate 			gStartYp = START_RESET;
19830Sstevel@tonic-gate 		if (mode_verbose)
19840Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Stopping nis(yp)\n"), stderr);
19850Sstevel@tonic-gate 		ret = disable_service(YP_FMRI, B_TRUE);
19860Sstevel@tonic-gate 		if (ret != 0) {
19870Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Stopping nis(yp) "
19880Sstevel@tonic-gate 			    "failed with (%d)\n"), ret);
19890Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
19900Sstevel@tonic-gate 		}
19910Sstevel@tonic-gate 	} else {
19920Sstevel@tonic-gate 		if (mode_verbose)
19930Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("nis(yp) not running\n"),
1994*6842Sth160488 			    stderr);
19950Sstevel@tonic-gate 	}
19960Sstevel@tonic-gate 
19970Sstevel@tonic-gate 	return (CLIENT_SUCCESS);
19980Sstevel@tonic-gate }
19990Sstevel@tonic-gate 
20000Sstevel@tonic-gate /*
20010Sstevel@tonic-gate  * start_services is called to start up network services after config
20020Sstevel@tonic-gate  * files have all been setup or recovered.  In the case of an error, the
20030Sstevel@tonic-gate  * files will be recovered and start_services will be called with the
20040Sstevel@tonic-gate  * "reset" flag set so that only those services that were earlier stopped
20050Sstevel@tonic-gate  * will be started.  If it is not a reset, then the services associated
20060Sstevel@tonic-gate  * with files "recovered" will attempt to be started.
20070Sstevel@tonic-gate  */
20080Sstevel@tonic-gate static int
20090Sstevel@tonic-gate start_services(int flag)
20100Sstevel@tonic-gate {
20112830Sdjl 	int sysret, retcode = CLIENT_SUCCESS, rc = NS_LDAP_SUCCESS;
20120Sstevel@tonic-gate 	FILE *domain_fp;
20130Sstevel@tonic-gate 	char domainname[BUFSIZ];
20140Sstevel@tonic-gate 	char cmd_domain_start[BUFSIZ];
20150Sstevel@tonic-gate 	int domainlen;
20162830Sdjl 	ns_ldap_self_gssapi_config_t config = NS_LDAP_SELF_GSSAPI_CONFIG_NONE;
20172830Sdjl 	ns_ldap_error_t		*errorp = NULL;
20180Sstevel@tonic-gate 
20190Sstevel@tonic-gate 	if (mode_verbose) {
20200Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Starting network services\n"), stderr);
20210Sstevel@tonic-gate 	}
20220Sstevel@tonic-gate 
20230Sstevel@tonic-gate 	/* Read in current defaultdomain so we can set it */
20240Sstevel@tonic-gate 	domain_fp = fopen(DOMAINNAME, "r");
20250Sstevel@tonic-gate 	if (domain_fp == NULL) {
20260Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr, gettext("Error opening defaultdomain "
2027*6842Sth160488 		    "(%d)\n"), errno);
20280Sstevel@tonic-gate 		/* if we did an ldap init, we must have domain */
20290Sstevel@tonic-gate 		if (flag == START_INIT)
20300Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
20310Sstevel@tonic-gate 	} else {
20320Sstevel@tonic-gate 		if (fgets(domainname, BUFSIZ, domain_fp) == NULL) {
20330Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Error reading defaultdomain\n"),
2034*6842Sth160488 			    stderr);
20350Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
20360Sstevel@tonic-gate 		}
20370Sstevel@tonic-gate 
20380Sstevel@tonic-gate 		if (fclose(domain_fp) != 0) {
20390Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2040*6842Sth160488 			    gettext("Error closing defaultdomain (%d)\n"),
2041*6842Sth160488 			    errno);
20420Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
20430Sstevel@tonic-gate 		}
20440Sstevel@tonic-gate 		domainlen = strlen(domainname);
20450Sstevel@tonic-gate 		/* sanity check to make sure sprintf will fit */
20460Sstevel@tonic-gate 		if (domainlen > (BUFSIZE - sizeof (CMD_DOMAIN_START) -
2047*6842Sth160488 		    sizeof (TO_DEV_NULL) - 3)) {
20480Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Specified domainname is "
2049*6842Sth160488 			    "too large\n"), stderr);
20500Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
20510Sstevel@tonic-gate 		}
20520Sstevel@tonic-gate 		if (domainname[domainlen-1] == '\n')
20530Sstevel@tonic-gate 			domainname[domainlen-1] = 0;
20540Sstevel@tonic-gate 		/* buffer size is checked above */
20552830Sdjl 		(void) snprintf(cmd_domain_start, BUFSIZ, "%s %s %s",
2056*6842Sth160488 		    CMD_DOMAIN_START, domainname, TO_DEV_NULL);
20570Sstevel@tonic-gate 	}
20580Sstevel@tonic-gate 
20590Sstevel@tonic-gate 	/*
20600Sstevel@tonic-gate 	 * We can be starting services after an init in which case
20610Sstevel@tonic-gate 	 * we want to start ldap and not start yp or nis+.
20620Sstevel@tonic-gate 	 */
20630Sstevel@tonic-gate 	if (flag == START_INIT) {
20640Sstevel@tonic-gate 		sysret = system(cmd_domain_start);
20650Sstevel@tonic-gate 		if (mode_verbose)
20660Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, "start: %s %s... %s\n",
2067*6842Sth160488 			    CMD_DOMAIN_START, domainname,
2068*6842Sth160488 			    (sysret == 0) ? gettext("success") :
2069*6842Sth160488 			    gettext("failed"));
20700Sstevel@tonic-gate 		if (sysret != 0) {
20710Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("\"%s\" returned: %d\n"),
2072*6842Sth160488 			    CMD_DOMAIN_START, sysret);
20730Sstevel@tonic-gate 
20740Sstevel@tonic-gate 			retcode = CLIENT_ERR_FAIL;
20750Sstevel@tonic-gate 		}
20760Sstevel@tonic-gate 
20772830Sdjl 		if ((rc = __ns_ldap_self_gssapi_config(&config)) !=
2078*6842Sth160488 		    NS_LDAP_SUCCESS) {
20792830Sdjl 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
2080*6842Sth160488 			    "checking sasl/GSSAPI configuration\n"),
2081*6842Sth160488 			    rc);
20820Sstevel@tonic-gate 			retcode = CLIENT_ERR_FAIL;
20832830Sdjl 		}
20842830Sdjl 
20852830Sdjl 		if (config != NS_LDAP_SELF_GSSAPI_CONFIG_NONE) {
20862830Sdjl 
20872830Sdjl 			rc = __ns_ldap_check_dns_preq(
2088*6842Sth160488 			    1, mode_verbose, mode_quiet,
2089*6842Sth160488 			    NSSWITCH_LDAP, config, &errorp);
20902830Sdjl 			if (errorp)
20912830Sdjl 				(void) __ns_ldap_freeError(&errorp);
20922830Sdjl 
20932830Sdjl 			if (rc != NS_LDAP_SUCCESS)
20942830Sdjl 				retcode = CLIENT_ERR_FAIL;
20952830Sdjl 		}
20962830Sdjl 
20972830Sdjl 		if (rc == NS_LDAP_SUCCESS &&
2098*6842Sth160488 		    start_service(LDAP_FMRI, B_TRUE) != CLIENT_SUCCESS)
20992830Sdjl 			retcode = CLIENT_ERR_FAIL;
21002830Sdjl 
21012830Sdjl 		if (config != NS_LDAP_SELF_GSSAPI_CONFIG_NONE &&
2102*6842Sth160488 		    rc == NS_LDAP_SUCCESS && retcode == CLIENT_SUCCESS) {
21032830Sdjl 			rc = __ns_ldap_check_gssapi_preq(
2104*6842Sth160488 			    1, mode_verbose, mode_quiet, config,
2105*6842Sth160488 			    &errorp);
21062830Sdjl 			if (errorp)
21072830Sdjl 				(void) __ns_ldap_freeError(&errorp);
21082830Sdjl 
21092830Sdjl 			if (rc != NS_LDAP_SUCCESS)
21102830Sdjl 				retcode = CLIENT_ERR_FAIL;
21112830Sdjl 
21122830Sdjl 		}
21130Sstevel@tonic-gate 		/* No YP or NIS+ after init */
21140Sstevel@tonic-gate 	/*
21150Sstevel@tonic-gate 	 * Or we can be starting services after an uninit or error
21160Sstevel@tonic-gate 	 * recovery.  We want to start whatever services were running
21170Sstevel@tonic-gate 	 * before.  In the case of error recovery, it is the services
21180Sstevel@tonic-gate 	 * that were running before we stopped them (flags set in
21190Sstevel@tonic-gate 	 * stop_services).  If it is an uninit then we determine
21200Sstevel@tonic-gate 	 * which services to start based on the files we recovered
21210Sstevel@tonic-gate 	 * (flags set in recover).
21220Sstevel@tonic-gate 	 */
21230Sstevel@tonic-gate 	} else {
21240Sstevel@tonic-gate 		/* uninit and recover should set flags of what to start */
21250Sstevel@tonic-gate 		if (domain_fp) {
21260Sstevel@tonic-gate 			sysret = system(cmd_domain_start);
21270Sstevel@tonic-gate 			if (mode_verbose)
21280Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr, "start: %s %s... %s\n",
2129*6842Sth160488 				    CMD_DOMAIN_START, domainname,
2130*6842Sth160488 				    (sysret == 0) ? gettext("success") :
2131*6842Sth160488 				    gettext("failed"));
21320Sstevel@tonic-gate 			if (sysret != 0) {
21330Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr, gettext("\"%s\" "
2134*6842Sth160488 				    "returned: %d\n"),
2135*6842Sth160488 				    CMD_DOMAIN_START, sysret);
21360Sstevel@tonic-gate 
21370Sstevel@tonic-gate 				retcode = CLIENT_ERR_FAIL;
21380Sstevel@tonic-gate 			}
21390Sstevel@tonic-gate 		}
21400Sstevel@tonic-gate 
21410Sstevel@tonic-gate 		if (gStartLdap == flag) {
21420Sstevel@tonic-gate 			if (!(is_service(LDAP_FMRI, SCF_STATE_STRING_ONLINE)))
21430Sstevel@tonic-gate 				if (start_service(LDAP_FMRI, B_TRUE)
2144*6842Sth160488 				    != CLIENT_SUCCESS)
21450Sstevel@tonic-gate 					retcode = CLIENT_ERR_FAIL;
21460Sstevel@tonic-gate 		}
21470Sstevel@tonic-gate 
21480Sstevel@tonic-gate 		if (gStartYp == flag) {
21490Sstevel@tonic-gate 			if (!(is_service(YP_FMRI, SCF_STATE_STRING_ONLINE)))
21500Sstevel@tonic-gate 				(void) start_service(YP_FMRI, B_TRUE);
21510Sstevel@tonic-gate 		}
21520Sstevel@tonic-gate 
21530Sstevel@tonic-gate 		if (gStartNisd == flag) {
21540Sstevel@tonic-gate 			if (!(is_service(NISD_FMRI, SCF_STATE_STRING_ONLINE)))
21550Sstevel@tonic-gate 				(void) start_service(NISD_FMRI, B_TRUE);
21560Sstevel@tonic-gate 		}
21570Sstevel@tonic-gate 
21580Sstevel@tonic-gate 	}
21590Sstevel@tonic-gate 	if ((enableFlag & AUTOFS_ON) &&
21600Sstevel@tonic-gate 	    !(is_service(AUTOFS_FMRI, SCF_STATE_STRING_ONLINE)))
21610Sstevel@tonic-gate 		(void) start_service(AUTOFS_FMRI, B_TRUE);
21620Sstevel@tonic-gate 
21630Sstevel@tonic-gate 	if ((enableFlag & NSCD_ON) &&
21640Sstevel@tonic-gate 	    !(is_service(NSCD_FMRI, SCF_STATE_STRING_ONLINE)))
21650Sstevel@tonic-gate 		(void) start_service(NSCD_FMRI, B_TRUE);
21660Sstevel@tonic-gate 
21672830Sdjl #if 0
21682830Sdjl 	if (flag == START_INIT && config != NS_LDAP_SELF_GSSAPI_CONFIG_NONE &&
21692830Sdjl 	    retcode == CLIENT_SUCCESS &&
21702830Sdjl 	    !(is_service(NSCD_FMRI, SCF_STATE_STRING_ONLINE))) {
21712830Sdjl 		CLIENT_FPRINTF(stderr, "start: %s\n",
2172*6842Sth160488 		    gettext("self/sasl/GSSAPI is configured"
2173*6842Sth160488 		    " but nscd is not online"));
21742830Sdjl 		retcode = CLIENT_ERR_FAIL;
21752830Sdjl 	}
21762830Sdjl #endif
21772830Sdjl 
21780Sstevel@tonic-gate 	if ((enableFlag & SENDMAIL_ON) &&
21790Sstevel@tonic-gate 	    !(is_service(SENDMAIL_FMRI, SCF_STATE_STRING_ONLINE)))
21800Sstevel@tonic-gate 		(void) start_service(SENDMAIL_FMRI, B_TRUE);
21810Sstevel@tonic-gate 
21820Sstevel@tonic-gate 	/*
21830Sstevel@tonic-gate 	 * Restart name-service milestone so that any consumer
21840Sstevel@tonic-gate 	 * which depends on it will be restarted.
21850Sstevel@tonic-gate 	 */
21860Sstevel@tonic-gate 	(void) restart_service(NS_MILESTONE_FMRI, B_TRUE);
21870Sstevel@tonic-gate 	return (retcode);
21880Sstevel@tonic-gate }
21890Sstevel@tonic-gate 
21900Sstevel@tonic-gate /*
21910Sstevel@tonic-gate  * credCheck is called to check if credentials are required for this
21920Sstevel@tonic-gate  * configuration.  Currently, this means that if any credentialLevel is
21930Sstevel@tonic-gate  * proxy and any authenticationMethod is something other than none, then
21940Sstevel@tonic-gate  * credential info is required (proxyDN and proxyPassword).
21950Sstevel@tonic-gate  */
21960Sstevel@tonic-gate static int
21970Sstevel@tonic-gate credCheck(clientopts_t *arglist)
21980Sstevel@tonic-gate {
21990Sstevel@tonic-gate 	int counter;
22000Sstevel@tonic-gate 	int **credLevel;
22010Sstevel@tonic-gate 	ns_auth_t **authMethod;
22020Sstevel@tonic-gate 	char **proxyDN, **proxyPassword;
22030Sstevel@tonic-gate 	ns_ldap_error_t *errorp;
22040Sstevel@tonic-gate 	int credProxy, authNotNone;
22050Sstevel@tonic-gate 	int retcode;
22060Sstevel@tonic-gate 
22070Sstevel@tonic-gate /* If credentialLevel is proxy, make sure we have proxyDN and proxyPassword */
22080Sstevel@tonic-gate 	retcode = __ns_ldap_getParam(NS_LDAP_CREDENTIAL_LEVEL_P,
2209*6842Sth160488 	    (void ***)&credLevel, &errorp);
22100Sstevel@tonic-gate 	if (retcode != 0) {
22110Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2212*6842Sth160488 		    gettext("Error %d while trying to retrieve "
2213*6842Sth160488 		    "credLevel\n"),
2214*6842Sth160488 		    retcode);
22150Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
22160Sstevel@tonic-gate 	}
22170Sstevel@tonic-gate 	retcode = __ns_ldap_getParam(NS_LDAP_AUTH_P,
2218*6842Sth160488 	    (void ***)&authMethod, &errorp);
22190Sstevel@tonic-gate 	if (retcode != 0) {
22200Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2221*6842Sth160488 		    gettext("Error %d while trying to retrieve "
2222*6842Sth160488 		    "authMethod\n"), retcode);
22230Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
22240Sstevel@tonic-gate 	}
22250Sstevel@tonic-gate 	retcode = __ns_ldap_getParam(NS_LDAP_BINDDN_P,
2226*6842Sth160488 	    (void ***)&proxyDN, &errorp);
22270Sstevel@tonic-gate 	if (retcode != 0) {
22280Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2229*6842Sth160488 		    gettext("Error %d while trying to retrieve proxyDN\n"),
2230*6842Sth160488 		    retcode);
22310Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
22320Sstevel@tonic-gate 	}
22330Sstevel@tonic-gate 	retcode = __ns_ldap_getParam(NS_LDAP_BINDPASSWD_P,
2234*6842Sth160488 	    (void ***)&proxyPassword, &errorp);
22350Sstevel@tonic-gate 	if (retcode != 0) {
22360Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2237*6842Sth160488 		    gettext("Error %d while trying to retrieve "
2238*6842Sth160488 		    "proxyPassword\n"), retcode);
22390Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
22400Sstevel@tonic-gate 	}
22410Sstevel@tonic-gate 
22420Sstevel@tonic-gate 	if (mode_verbose) {
22430Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2244*6842Sth160488 		    gettext("Proxy DN: %s\n"),
2245*6842Sth160488 		    (proxyDN && proxyDN[0]) ? proxyDN[0] : "NULL");
22460Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2247*6842Sth160488 		    gettext("Proxy password: %s\n"),
2248*6842Sth160488 		    (proxyPassword && proxyPassword[0]) ?
2249*6842Sth160488 		    proxyPassword[0] : "NULL");
22500Sstevel@tonic-gate 	}
22510Sstevel@tonic-gate 
22520Sstevel@tonic-gate 	credProxy = 0;	/* flag to indicate if we have a credLevel of proxy */
22530Sstevel@tonic-gate 	for (counter = 0; credLevel && credLevel[counter] != NULL; counter++) {
22540Sstevel@tonic-gate 		if (mode_verbose)
22550Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2256*6842Sth160488 			    gettext("Credential level: %d\n"),
2257*6842Sth160488 			    *credLevel[counter]);
22580Sstevel@tonic-gate 		if (*credLevel[counter] == NS_LDAP_CRED_PROXY) {
22590Sstevel@tonic-gate 			credProxy = 1;
22600Sstevel@tonic-gate 			break;
22610Sstevel@tonic-gate 		}
22620Sstevel@tonic-gate 	}
22630Sstevel@tonic-gate 
22640Sstevel@tonic-gate 	authNotNone = 0;	/* flag for authMethod other than none */
22650Sstevel@tonic-gate 	for (counter = 0;
2266*6842Sth160488 	    authMethod && authMethod[counter] != NULL;
2267*6842Sth160488 	    counter++) {
22680Sstevel@tonic-gate 
22690Sstevel@tonic-gate 		if (mode_verbose)
22700Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2271*6842Sth160488 			    gettext("Authentication method: %d\n"),
2272*6842Sth160488 			    authMethod[counter]->type);
22730Sstevel@tonic-gate 		if (authMethod[counter]->type != NS_LDAP_AUTH_NONE &&
22740Sstevel@tonic-gate 		    !(authMethod[counter]->type == NS_LDAP_AUTH_TLS &&
22750Sstevel@tonic-gate 		    authMethod[counter]->tlstype == NS_LDAP_TLS_NONE)) {
22760Sstevel@tonic-gate 			authNotNone = 1;
22770Sstevel@tonic-gate 			break;
22780Sstevel@tonic-gate 		}
22790Sstevel@tonic-gate 	}
22800Sstevel@tonic-gate 
22810Sstevel@tonic-gate 	/* First, if we don't need proxyDN/Password then just return ok */
22820Sstevel@tonic-gate 	if (!(credProxy && authNotNone)) {
22830Sstevel@tonic-gate 		if (mode_verbose)
22840Sstevel@tonic-gate 			CLIENT_FPUTS(
2285*6842Sth160488 			    gettext("No proxyDN/proxyPassword required\n"),
2286*6842Sth160488 			    stderr);
22870Sstevel@tonic-gate 		return (CLIENT_SUCCESS);
22880Sstevel@tonic-gate 	}
22890Sstevel@tonic-gate 
22900Sstevel@tonic-gate 	/* Now let's check if we have the cred stuff we need */
22910Sstevel@tonic-gate 	if (!proxyDN || !proxyDN[0]) {
22920Sstevel@tonic-gate 		CLIENT_FPUTS(
2293*6842Sth160488 		    gettext("credentialLevel is proxy and no proxyDN "
2294*6842Sth160488 		    "specified\n"),
2295*6842Sth160488 		    stderr);
22960Sstevel@tonic-gate 		return (CLIENT_ERR_CREDENTIAL);
22970Sstevel@tonic-gate 	}
22980Sstevel@tonic-gate 
22990Sstevel@tonic-gate 	/* If we need proxyPassword (prompt) */
23000Sstevel@tonic-gate 	if (!proxyPassword || !proxyPassword[0]) {
23010Sstevel@tonic-gate 		CLIENT_FPUTS(
2302*6842Sth160488 		    gettext("credentialLevel requires proxyPassword\n"),
2303*6842Sth160488 		    stderr);
23040Sstevel@tonic-gate 		arglist->proxyPassword = getpassphrase("Proxy Bind Password:");
23050Sstevel@tonic-gate 		if (arglist->proxyPassword == NULL) {
23060Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Get password failed\n"), stderr);
23070Sstevel@tonic-gate 			return (CLIENT_ERR_CREDENTIAL);
23080Sstevel@tonic-gate 		}
23090Sstevel@tonic-gate 		LDAP_SET_PARAM(arglist->proxyPassword, NS_LDAP_BINDPASSWD_P);
23100Sstevel@tonic-gate 		if (retcode != 0) {
23110Sstevel@tonic-gate 			CLIENT_FPUTS(
2312*6842Sth160488 			    gettext("setParam proxyPassword failed.\n"),
2313*6842Sth160488 			    stderr);
23140Sstevel@tonic-gate 			return (CLIENT_ERR_CREDENTIAL);
23150Sstevel@tonic-gate 		}
23160Sstevel@tonic-gate 	}
23170Sstevel@tonic-gate 
23180Sstevel@tonic-gate 	return (CLIENT_SUCCESS);
23190Sstevel@tonic-gate }
23200Sstevel@tonic-gate 
23210Sstevel@tonic-gate /*
23220Sstevel@tonic-gate  * try to restore the previous name space on this machine
23230Sstevel@tonic-gate  */
23240Sstevel@tonic-gate static int
23250Sstevel@tonic-gate recover(int saveState)
23260Sstevel@tonic-gate {
23270Sstevel@tonic-gate 	struct stat buf;
23280Sstevel@tonic-gate 	int stat_ret, retcode, fd;
23290Sstevel@tonic-gate 	int domain = 0, domainlen;
23300Sstevel@tonic-gate 	char yp_dir[BUFSIZE], yp_dir_back[BUFSIZE];
23310Sstevel@tonic-gate 	char name[BUFSIZ];
23320Sstevel@tonic-gate 	char *ldap_conf_file, *ldap_cred_file;
23330Sstevel@tonic-gate 	char ldap_file_back[BUFSIZE], ldap_cred_back[BUFSIZE];
23340Sstevel@tonic-gate 
23350Sstevel@tonic-gate 	/* If running as Sysid Install become a no-op */
23360Sstevel@tonic-gate 	if (sysid_install == B_TRUE)
23370Sstevel@tonic-gate 		return (CLIENT_SUCCESS);
23380Sstevel@tonic-gate 
23390Sstevel@tonic-gate 	stat_ret = stat(LDAP_RESTORE_DIR, &buf);
23400Sstevel@tonic-gate 	if (stat_ret != 0) {
23410Sstevel@tonic-gate 		CLIENT_FPUTS(
2342*6842Sth160488 		    gettext("Cannot recover.  No backup files "
2343*6842Sth160488 		    "found.\n"),
2344*6842Sth160488 		    stderr);
23450Sstevel@tonic-gate 		CLIENT_FPUTS(
2346*6842Sth160488 		    gettext("\t Either this machine was not initialized\n"),
2347*6842Sth160488 		    stderr);
23480Sstevel@tonic-gate 		CLIENT_FPUTS(
2349*6842Sth160488 		    gettext("\t by ldapclient or the backup files "
2350*6842Sth160488 		    "have been\n"),
2351*6842Sth160488 		    stderr);
23520Sstevel@tonic-gate 		CLIENT_FPUTS(
2353*6842Sth160488 		    gettext("\t removed manually or with an \"uninit\"\n"),
2354*6842Sth160488 		    stderr);
23550Sstevel@tonic-gate 		return (CLIENT_ERR_RESTORE);	/* invalid backup */
23560Sstevel@tonic-gate 	}
23570Sstevel@tonic-gate 
23580Sstevel@tonic-gate 	/*
23590Sstevel@tonic-gate 	 * Get domainname.  Allow no domainname for the case where "files"
23600Sstevel@tonic-gate 	 * config was backed up.
23610Sstevel@tonic-gate 	 */
23620Sstevel@tonic-gate 	stat_ret = stat(DOMAINNAME_BACK, &buf);
23630Sstevel@tonic-gate 	if (mode_verbose)
23640Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2365*6842Sth160488 		    gettext("recover: stat(%s)=%d\n"),
2366*6842Sth160488 		    DOMAINNAME_BACK, stat_ret);
23670Sstevel@tonic-gate 	if (stat_ret == 0) {
23680Sstevel@tonic-gate 		if (mode_verbose)
23690Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2370*6842Sth160488 			    gettext("recover: open(%s)\n"),
2371*6842Sth160488 			    DOMAINNAME_BACK);
23720Sstevel@tonic-gate 		fd = open(DOMAINNAME_BACK, O_RDONLY);
23730Sstevel@tonic-gate 		if (mode_verbose)
23740Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2375*6842Sth160488 			    gettext("recover: read(%s)\n"),
2376*6842Sth160488 			    DOMAINNAME_BACK);
23770Sstevel@tonic-gate 		domainlen = read(fd, &(name[0]), BUFSIZ-1);
23780Sstevel@tonic-gate 		(void) close(fd);
23790Sstevel@tonic-gate 		if (domainlen < 0) {
23800Sstevel@tonic-gate 			CLIENT_FPUTS(
2381*6842Sth160488 			    gettext("Cannot recover.  Cannot determine "
2382*6842Sth160488 			    "previous domain name.\n"),
2383*6842Sth160488 			    stderr);
23840Sstevel@tonic-gate 			return (CLIENT_ERR_RESTORE);	/* invalid backup */
23850Sstevel@tonic-gate 		} else 	{
23860Sstevel@tonic-gate 			char *ptr;
23870Sstevel@tonic-gate 
23880Sstevel@tonic-gate 			ptr = strchr(&(name[0]), '\n');
23890Sstevel@tonic-gate 			if (ptr != NULL)
23900Sstevel@tonic-gate 				*ptr = '\0';
23910Sstevel@tonic-gate 			else
23920Sstevel@tonic-gate 				name[domainlen] = '\0';
23930Sstevel@tonic-gate 
23940Sstevel@tonic-gate 			if (mode_verbose)
23950Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
2396*6842Sth160488 				    gettext("recover: old domainname "
2397*6842Sth160488 				    "\"%s\"\n"), name);
23980Sstevel@tonic-gate 
23990Sstevel@tonic-gate 			if (strlen(name) == 0)
24000Sstevel@tonic-gate 				domain = 0;
24010Sstevel@tonic-gate 			else
24020Sstevel@tonic-gate 				domain = 1;	/* flag that we have domain */
24030Sstevel@tonic-gate 
24040Sstevel@tonic-gate 		}
24050Sstevel@tonic-gate 	}
24060Sstevel@tonic-gate 
24070Sstevel@tonic-gate 
24080Sstevel@tonic-gate 	/*
24090Sstevel@tonic-gate 	 * we can recover at this point
24100Sstevel@tonic-gate 	 * remove LDAP config files before restore
24110Sstevel@tonic-gate 	 */
24120Sstevel@tonic-gate 	(void) unlink(NSCONFIGFILE);
24130Sstevel@tonic-gate 	(void) unlink(NSCREDFILE);
24140Sstevel@tonic-gate 
24150Sstevel@tonic-gate 	ldap_conf_file = strrchr(NSCONFIGFILE, '/') + 1;
24160Sstevel@tonic-gate 	ldap_cred_file = strrchr(NSCREDFILE, '/') + 1;
24170Sstevel@tonic-gate 
24180Sstevel@tonic-gate 	(void) strlcpy(ldap_file_back, LDAP_RESTORE_DIR "/", BUFSIZE);
24190Sstevel@tonic-gate 	(void) strlcat(ldap_file_back, ldap_conf_file, BUFSIZE);
24200Sstevel@tonic-gate 
24210Sstevel@tonic-gate 	stat_ret = stat(ldap_file_back, &buf);
24220Sstevel@tonic-gate 	if (mode_verbose)
24230Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2424*6842Sth160488 		    gettext("recover: stat(%s)=%d\n"),
2425*6842Sth160488 		    ldap_file_back, stat_ret);
24260Sstevel@tonic-gate 	if (stat_ret == 0) {
24270Sstevel@tonic-gate 		if (saveState)
24280Sstevel@tonic-gate 			gStartLdap = START_UNINIT;
24290Sstevel@tonic-gate 		retcode = file_move(ldap_file_back, NSCONFIGFILE);
24300Sstevel@tonic-gate 		if (mode_verbose)
24310Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2432*6842Sth160488 			    gettext("recover: file_move(%s, %s)=%d\n"),
2433*6842Sth160488 			    ldap_file_back, NSCONFIGFILE, retcode);
24340Sstevel@tonic-gate 		if (retcode != 0)
24350Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2436*6842Sth160488 			    gettext("recover: file_move(%s, %s) failed\n"),
2437*6842Sth160488 			    ldap_file_back, NSCONFIGFILE);
24380Sstevel@tonic-gate 	}
24390Sstevel@tonic-gate 
24400Sstevel@tonic-gate 	(void) strlcpy(ldap_cred_back, LDAP_RESTORE_DIR "/", BUFSIZE);
24410Sstevel@tonic-gate 	(void) strlcat(ldap_cred_back, ldap_cred_file, BUFSIZE);
24420Sstevel@tonic-gate 
24430Sstevel@tonic-gate 	stat_ret = stat(ldap_cred_back, &buf);
24440Sstevel@tonic-gate 	if (mode_verbose)
24450Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2446*6842Sth160488 		    gettext("recover: stat(%s)=%d\n"),
2447*6842Sth160488 		    ldap_cred_back, stat_ret);
24480Sstevel@tonic-gate 	if (stat_ret == 0) {
24490Sstevel@tonic-gate 		retcode = file_move(ldap_cred_back, NSCREDFILE);
24500Sstevel@tonic-gate 		if (mode_verbose)
24510Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2452*6842Sth160488 			    gettext("recover: file_move(%s, %s)=%d\n"),
2453*6842Sth160488 			    ldap_cred_back, NSCREDFILE, retcode);
24540Sstevel@tonic-gate 		if (retcode != 0)
24550Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2456*6842Sth160488 			    gettext("recover: file_move(%s, %s) failed\n"),
2457*6842Sth160488 			    ldap_cred_back, NSCREDFILE);
24580Sstevel@tonic-gate 	}
24590Sstevel@tonic-gate 
24600Sstevel@tonic-gate 	/* Check for recovery of NIS+ */
24610Sstevel@tonic-gate 	stat_ret = stat(NIS_COLDSTART_BACK, &buf);
24620Sstevel@tonic-gate 	if (mode_verbose)
24630Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2464*6842Sth160488 		    gettext("recover: stat(%s)=%d\n"),
2465*6842Sth160488 		    NIS_COLDSTART_BACK, stat_ret);
24660Sstevel@tonic-gate 	if (stat_ret == 0) {
24670Sstevel@tonic-gate 		if (saveState) {
24680Sstevel@tonic-gate 			gStartNisd = START_UNINIT;
24690Sstevel@tonic-gate 		}
24700Sstevel@tonic-gate 		if (mode_verbose)
24710Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2472*6842Sth160488 			    gettext("recover: file_move(%s, %s)\n"),
2473*6842Sth160488 			    NIS_COLDSTART_BACK, NIS_COLDSTART);
24740Sstevel@tonic-gate 		retcode = file_move(NIS_COLDSTART_BACK, NIS_COLDSTART);
24750Sstevel@tonic-gate 		if (retcode != 0)
24760Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2477*6842Sth160488 			    gettext("recover: file_move(%s, %s) failed!\n"),
2478*6842Sth160488 			    NIS_COLDSTART_BACK, NIS_COLDSTART);
24790Sstevel@tonic-gate 	}
24800Sstevel@tonic-gate 
24810Sstevel@tonic-gate 	/* Check for recovery of NIS(YP) if we have a domainname */
24820Sstevel@tonic-gate 	if (domain) {
24830Sstevel@tonic-gate 		/* "name" would have to be huge for this, but just in case */
24840Sstevel@tonic-gate 		if (strlen(name) >= (BUFSIZE - strlen(LDAP_RESTORE_DIR)))
24850Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
24860Sstevel@tonic-gate 		if (strlen(name) >= (BUFSIZE - strlen(YP_BIND_DIR)))
24870Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
24880Sstevel@tonic-gate 
24890Sstevel@tonic-gate 		(void) strlcpy(yp_dir_back, LDAP_RESTORE_DIR "/", BUFSIZE);
24900Sstevel@tonic-gate 		(void) strlcat(yp_dir_back, name, BUFSIZE);
24910Sstevel@tonic-gate 		stat_ret = stat(yp_dir_back, &buf);
24920Sstevel@tonic-gate 		if (mode_verbose)
24930Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2494*6842Sth160488 			    gettext("recover: stat(%s)=%d\n"),
2495*6842Sth160488 			    yp_dir_back, stat_ret);
24960Sstevel@tonic-gate 		if (stat_ret == 0) {
24970Sstevel@tonic-gate 			(void) strlcpy(yp_dir, YP_BIND_DIR "/", BUFSIZE);
24980Sstevel@tonic-gate 			(void) strlcat(yp_dir, name, BUFSIZE);
24990Sstevel@tonic-gate 			retcode = file_move(yp_dir_back, yp_dir);
25000Sstevel@tonic-gate 			if (mode_verbose)
25010Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
2502*6842Sth160488 				    gettext("recover: file_move(%s, "
2503*6842Sth160488 				    "%s)=%d\n"),
2504*6842Sth160488 				    yp_dir_back, yp_dir, retcode);
25050Sstevel@tonic-gate 			if (retcode != 0) {
25060Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
2507*6842Sth160488 				    gettext("recover: file_move(%s, "
2508*6842Sth160488 				    "%s) failed!\n"),
2509*6842Sth160488 				    yp_dir_back, yp_dir);
25100Sstevel@tonic-gate 			} else {
25110Sstevel@tonic-gate 				if (saveState)
25120Sstevel@tonic-gate 					gStartYp = START_UNINIT;
25130Sstevel@tonic-gate 			}
25140Sstevel@tonic-gate 		}
25150Sstevel@tonic-gate 	}
25160Sstevel@tonic-gate 
25170Sstevel@tonic-gate 	/* restore machine configuration */
25180Sstevel@tonic-gate 	stat_ret = stat(NSSWITCH_BACK, &buf);
25190Sstevel@tonic-gate 	if (mode_verbose)
25200Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2521*6842Sth160488 		    gettext("recover: stat(%s)=%d\n"),
2522*6842Sth160488 		    NSSWITCH_BACK, stat_ret);
25230Sstevel@tonic-gate 	if (stat_ret == 0) {
25240Sstevel@tonic-gate 		retcode = file_move(NSSWITCH_BACK, NSSWITCH_CONF);
25250Sstevel@tonic-gate 		if (mode_verbose)
25260Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2527*6842Sth160488 			    gettext("recover: file_move(%s, %s)=%d\n"),
2528*6842Sth160488 			    NSSWITCH_BACK, NSSWITCH_CONF, retcode);
25290Sstevel@tonic-gate 		if (retcode != 0)
25300Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2531*6842Sth160488 			    gettext("recover: file_move(%s, %s) failed\n"),
2532*6842Sth160488 			    NSSWITCH_BACK, NSSWITCH_CONF);
25330Sstevel@tonic-gate 	}
25340Sstevel@tonic-gate 
25350Sstevel@tonic-gate 	stat_ret = stat(DOMAINNAME_BACK, &buf);
25360Sstevel@tonic-gate 	if (mode_verbose)
25370Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2538*6842Sth160488 		    gettext("recover: stat(%s)=%d\n"),
2539*6842Sth160488 		    DOMAINNAME_BACK, stat_ret);
25400Sstevel@tonic-gate 	if (stat_ret == 0) {
25410Sstevel@tonic-gate 		retcode = file_move(DOMAINNAME_BACK, DOMAINNAME);
25420Sstevel@tonic-gate 		if (mode_verbose)
25430Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2544*6842Sth160488 			    gettext("recover: file_move(%s, %s)=%d\n"),
2545*6842Sth160488 			    DOMAINNAME_BACK, DOMAINNAME, retcode);
25460Sstevel@tonic-gate 		if (retcode != 0)
25470Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2548*6842Sth160488 			    gettext("recover: file_move(%s, %s) failed\n"),
2549*6842Sth160488 			    DOMAINNAME_BACK, DOMAINNAME);
25500Sstevel@tonic-gate 	}
25510Sstevel@tonic-gate 
25520Sstevel@tonic-gate 	retcode = rmdir(LDAP_RESTORE_DIR);
25530Sstevel@tonic-gate 	if (retcode != 0) {
25540Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2555*6842Sth160488 		    gettext("Error removing \"%s\" directory.\n"),
2556*6842Sth160488 		    LDAP_RESTORE_DIR);
25570Sstevel@tonic-gate 	}
25580Sstevel@tonic-gate 
25590Sstevel@tonic-gate 	return (CLIENT_SUCCESS);
25600Sstevel@tonic-gate }
25610Sstevel@tonic-gate 
25620Sstevel@tonic-gate /*
25630Sstevel@tonic-gate  * try to save the current state of this machine.
25640Sstevel@tonic-gate  * this just overwrites any old saved configration files.
25650Sstevel@tonic-gate  *
25660Sstevel@tonic-gate  * This function should only be called after network services have been stopped.
25670Sstevel@tonic-gate  *
25680Sstevel@tonic-gate  * Returns 0 on successful save
25690Sstevel@tonic-gate  * Otherwise returns -1
25700Sstevel@tonic-gate  */
25710Sstevel@tonic-gate static int
25720Sstevel@tonic-gate file_backup(void)
25730Sstevel@tonic-gate {
25740Sstevel@tonic-gate 	struct stat buf;
25750Sstevel@tonic-gate 	int domain_stat, conf_stat, ldap_stat;
25760Sstevel@tonic-gate 	int nis_stat, yp_stat, restore_stat;
25770Sstevel@tonic-gate 	int retcode, namelen, ret;
25780Sstevel@tonic-gate 	char yp_dir[BUFSIZ], yp_dir_back[BUFSIZ];
25790Sstevel@tonic-gate 	char name[BUFSIZ];
25800Sstevel@tonic-gate 	char *ldap_conf_file, *ldap_cred_file;
25810Sstevel@tonic-gate 	char ldap_file_back[BUFSIZE], ldap_cred_back[BUFSIZE];
25820Sstevel@tonic-gate 
25830Sstevel@tonic-gate 	ret = CLIENT_SUCCESS;
25840Sstevel@tonic-gate 	/* If running as Sysid Install become a no-op */
25850Sstevel@tonic-gate 	if (sysid_install == B_TRUE)
25860Sstevel@tonic-gate 		return (CLIENT_SUCCESS);
25870Sstevel@tonic-gate 
25880Sstevel@tonic-gate 	/* If existing backup files, clear for this run */
25890Sstevel@tonic-gate 	restore_stat = stat(LDAP_RESTORE_DIR, &buf);
25900Sstevel@tonic-gate 	if (restore_stat == 0) {
25910Sstevel@tonic-gate 		if (mode_verbose) {
25920Sstevel@tonic-gate 			CLIENT_FPUTS(
2593*6842Sth160488 			    gettext("Removing existing restore "
2594*6842Sth160488 			    "directory\n"),
2595*6842Sth160488 			    stderr);
25960Sstevel@tonic-gate 		}
25970Sstevel@tonic-gate 		(void) system("/bin/rm -fr " LDAP_RESTORE_DIR);
25980Sstevel@tonic-gate 		restore_stat = stat(LDAP_RESTORE_DIR, &buf);
25990Sstevel@tonic-gate 		if (restore_stat == 0) {
26000Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2601*6842Sth160488 			    gettext("Unable to remove backup "
2602*6842Sth160488 			    "directory (%s)\n"),
2603*6842Sth160488 			    LDAP_RESTORE_DIR);
26040Sstevel@tonic-gate 			return (CLIENT_ERR_RESTORE);
26050Sstevel@tonic-gate 		}
26060Sstevel@tonic-gate 	}
26070Sstevel@tonic-gate 
26080Sstevel@tonic-gate 	retcode = mkdir(LDAP_RESTORE_DIR, 0755);
26090Sstevel@tonic-gate 	if (retcode != 0) {
26100Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2611*6842Sth160488 		    gettext("file_backup: Failed to make %s backup "
2612*6842Sth160488 		    "directory. mkdir=%d\n"),
2613*6842Sth160488 		    LDAP_RESTORE_DIR, retcode);
26140Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
26150Sstevel@tonic-gate 	}
26160Sstevel@tonic-gate 
26170Sstevel@tonic-gate 	conf_stat = stat(NSSWITCH_CONF, &buf);
26180Sstevel@tonic-gate 	if (mode_verbose)
26190Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2620*6842Sth160488 		    gettext("file_backup: stat(%s)=%d\n"),
2621*6842Sth160488 		    NSSWITCH_CONF, conf_stat);
26220Sstevel@tonic-gate 	if (conf_stat == 0) {
26230Sstevel@tonic-gate 		if (mode_verbose)
26240Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2625*6842Sth160488 			    gettext("file_backup: (%s -> %s)\n"),
2626*6842Sth160488 			    NSSWITCH_CONF, NSSWITCH_BACK);
26270Sstevel@tonic-gate 		retcode = file_move(NSSWITCH_CONF, NSSWITCH_BACK);
26280Sstevel@tonic-gate 		if (retcode != 0) {
26290Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2630*6842Sth160488 			    gettext("file_backup: file_move(%s, %s) failed "
2631*6842Sth160488 			    "with %d\n"),
2632*6842Sth160488 			    NSSWITCH_CONF, NSSWITCH_BACK, retcode);
26330Sstevel@tonic-gate 			ret = CLIENT_ERR_RENAME;
26340Sstevel@tonic-gate 		}
26350Sstevel@tonic-gate 	} else {
26360Sstevel@tonic-gate 		if (mode_verbose)
26370Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2638*6842Sth160488 			    gettext("file_backup: No %s file.\n"),
2639*6842Sth160488 			    NSSWITCH_CONF);
26400Sstevel@tonic-gate 	}
26410Sstevel@tonic-gate 
26420Sstevel@tonic-gate 	domain_stat = stat(DOMAINNAME, &buf);
26430Sstevel@tonic-gate 	if (mode_verbose)
26440Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2645*6842Sth160488 		    gettext("file_backup: stat(%s)=%d\n"),
2646*6842Sth160488 		    DOMAINNAME, domain_stat);
26470Sstevel@tonic-gate 	if ((domain_stat == 0) && (buf.st_size > 0)) {
26480Sstevel@tonic-gate 		if (mode_verbose)
26490Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2650*6842Sth160488 			    gettext("file_backup: (%s -> %s)\n"),
2651*6842Sth160488 			    DOMAINNAME, DOMAINNAME_BACK);
26520Sstevel@tonic-gate 		retcode = file_move(DOMAINNAME, DOMAINNAME_BACK);
26530Sstevel@tonic-gate 		if (retcode != 0) {
26540Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2655*6842Sth160488 			    gettext("file_backup: file_move(%s, %s) failed "
2656*6842Sth160488 			    "with %d\n"),
2657*6842Sth160488 			    DOMAINNAME, DOMAINNAME_BACK, retcode);
26580Sstevel@tonic-gate 			ret = CLIENT_ERR_RENAME;
26590Sstevel@tonic-gate 		}
26600Sstevel@tonic-gate 	} else {
26610Sstevel@tonic-gate 		if (mode_verbose)
26620Sstevel@tonic-gate 			if (domain_stat != 0) {
26630Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
2664*6842Sth160488 				    gettext("file_backup: No %s file.\n"),
2665*6842Sth160488 				    DOMAINNAME);
26660Sstevel@tonic-gate 			} else {
26670Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
2668*6842Sth160488 				    gettext("file_backup: Empty %s "
2669*6842Sth160488 				    "file.\n"),
2670*6842Sth160488 				    DOMAINNAME);
26710Sstevel@tonic-gate 			}
26720Sstevel@tonic-gate 	}
26730Sstevel@tonic-gate 
26740Sstevel@tonic-gate 	nis_stat = stat(NIS_COLDSTART, &buf);
26750Sstevel@tonic-gate 	if (mode_verbose)
26760Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2677*6842Sth160488 		    gettext("file_backup: stat(%s)=%d\n"),
2678*6842Sth160488 		    NIS_COLDSTART, nis_stat);
26790Sstevel@tonic-gate 	if (nis_stat == 0) {
26800Sstevel@tonic-gate 		if (mode_verbose)
26810Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2682*6842Sth160488 			    gettext("file_backup: (%s -> %s)\n"),
2683*6842Sth160488 			    NIS_COLDSTART, NIS_COLDSTART_BACK);
26840Sstevel@tonic-gate 		retcode = file_move(NIS_COLDSTART, NIS_COLDSTART_BACK);
26850Sstevel@tonic-gate 		if (retcode != 0) {
26860Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2687*6842Sth160488 			    gettext("file_backup: file_move(%s, %s) failed "
2688*6842Sth160488 			    "with %d\n"),
2689*6842Sth160488 			    NIS_COLDSTART, NIS_COLDSTART_BACK, retcode);
26900Sstevel@tonic-gate 			ret = CLIENT_ERR_RENAME;
26910Sstevel@tonic-gate 		}
26920Sstevel@tonic-gate 	} else {
26930Sstevel@tonic-gate 		if (mode_verbose)
26940Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2695*6842Sth160488 			    gettext("file_backup: No %s file.\n"),
2696*6842Sth160488 			    NIS_COLDSTART);
26970Sstevel@tonic-gate 	}
26980Sstevel@tonic-gate 
26990Sstevel@tonic-gate 	namelen = BUFSIZ;
27000Sstevel@tonic-gate 	(void) sysinfo(SI_SRPC_DOMAIN, &(name[0]), namelen);
27010Sstevel@tonic-gate 	namelen = strlen(name);
27020Sstevel@tonic-gate 
27030Sstevel@tonic-gate 	if (mode_verbose)
27040Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2705*6842Sth160488 		    gettext("file_backup: nis domain is \"%s\"\n"),
2706*6842Sth160488 		    (namelen > 0) ? name : "EMPTY");
27070Sstevel@tonic-gate 	/* check for domain name if not set cannot save NIS(YP) state */
27080Sstevel@tonic-gate 	if (namelen > 0) {
27090Sstevel@tonic-gate 		/* moving /var/yp/binding will cause ypbind to core dump */
27100Sstevel@tonic-gate 		(void) strlcpy(yp_dir, YP_BIND_DIR "/", BUFSIZE);
27110Sstevel@tonic-gate 		(void) strlcat(yp_dir, name, BUFSIZE);
27120Sstevel@tonic-gate 		yp_stat = stat(yp_dir, &buf);
27130Sstevel@tonic-gate 		if (mode_verbose)
27140Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2715*6842Sth160488 			    gettext("file_backup: stat(%s)=%d\n"),
2716*6842Sth160488 			    yp_dir, yp_stat);
27170Sstevel@tonic-gate 		if (yp_stat == 0) {
27180Sstevel@tonic-gate 			(void) strlcpy(yp_dir_back, LDAP_RESTORE_DIR "/",
2719*6842Sth160488 			    BUFSIZE);
27200Sstevel@tonic-gate 			(void) strlcat(yp_dir_back, name, BUFSIZE);
27210Sstevel@tonic-gate 			if (mode_verbose)
27220Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
2723*6842Sth160488 				    gettext("file_backup: (%s -> %s)\n"),
2724*6842Sth160488 				    yp_dir, yp_dir_back);
27250Sstevel@tonic-gate 			retcode = file_move(yp_dir, yp_dir_back);
27260Sstevel@tonic-gate 			if (retcode != 0) {
27270Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
2728*6842Sth160488 				    gettext("file_backup: file_move(%s, %s)"
2729*6842Sth160488 				    " failed with %d\n"),
2730*6842Sth160488 				    yp_dir, yp_dir_back, retcode);
27310Sstevel@tonic-gate 				ret = CLIENT_ERR_RENAME;
27320Sstevel@tonic-gate 			}
27330Sstevel@tonic-gate 		} else {
27340Sstevel@tonic-gate 			if (mode_verbose)
27350Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
2736*6842Sth160488 				    gettext("file_backup: No %s "
2737*6842Sth160488 				    "directory.\n"), yp_dir);
27380Sstevel@tonic-gate 		}
27390Sstevel@tonic-gate 	}
27400Sstevel@tonic-gate 
27410Sstevel@tonic-gate 
27420Sstevel@tonic-gate 	/* point to file name, not path delim (/) */
27430Sstevel@tonic-gate 	ldap_conf_file = strrchr(NSCONFIGFILE, '/') + 1;
27440Sstevel@tonic-gate 	ldap_cred_file = strrchr(NSCREDFILE, '/') + 1;
27450Sstevel@tonic-gate 
27460Sstevel@tonic-gate 	ldap_stat = stat(NSCONFIGFILE, &buf);
27470Sstevel@tonic-gate 	if (mode_verbose)
27480Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2749*6842Sth160488 		    gettext("file_backup: stat(%s)=%d\n"),
2750*6842Sth160488 		    NSCONFIGFILE, ldap_stat);
27510Sstevel@tonic-gate 	if (ldap_stat == 0) {
27520Sstevel@tonic-gate 		(void) strlcpy(ldap_file_back, LDAP_RESTORE_DIR "/", BUFSIZE);
27530Sstevel@tonic-gate 		(void) strlcat(ldap_file_back, ldap_conf_file, BUFSIZE);
27540Sstevel@tonic-gate 		if (mode_verbose)
27550Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2756*6842Sth160488 			    gettext("file_backup: (%s -> %s)\n"),
2757*6842Sth160488 			    NSCONFIGFILE, ldap_file_back);
27580Sstevel@tonic-gate 		retcode = file_move(NSCONFIGFILE, ldap_file_back);
27590Sstevel@tonic-gate 		if (retcode != 0) {
27600Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2761*6842Sth160488 			    gettext("file_backup: file_move(%s, %s) failed "
2762*6842Sth160488 			    "with %d\n"),
2763*6842Sth160488 			    NSCONFIGFILE, ldap_file_back, retcode);
27640Sstevel@tonic-gate 			ret = CLIENT_ERR_RENAME;
27650Sstevel@tonic-gate 		}
27660Sstevel@tonic-gate 
27670Sstevel@tonic-gate 		(void) strlcpy(ldap_cred_back, LDAP_RESTORE_DIR "/", BUFSIZE);
27680Sstevel@tonic-gate 		(void) strlcat(ldap_cred_back, ldap_cred_file, BUFSIZE);
27690Sstevel@tonic-gate 		if (mode_verbose)
27700Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2771*6842Sth160488 			    gettext("file_backup: (%s -> %s)\n"),
2772*6842Sth160488 			    NSCREDFILE, ldap_cred_back);
27730Sstevel@tonic-gate 		retcode = file_move(NSCREDFILE, ldap_cred_back);
27740Sstevel@tonic-gate 		if (retcode != 0) {
27750Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2776*6842Sth160488 			    gettext("file_backup: file_move(%s, %s) failed "
2777*6842Sth160488 			    "with %d\n"),
2778*6842Sth160488 			    NSCREDFILE, ldap_cred_back, retcode);
27790Sstevel@tonic-gate 			ret = CLIENT_ERR_RENAME;
27800Sstevel@tonic-gate 		}
27810Sstevel@tonic-gate 	} else {
27820Sstevel@tonic-gate 		if (mode_verbose)
27830Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2784*6842Sth160488 			    gettext("file_backup: No %s file.\n"),
2785*6842Sth160488 			    NSCONFIGFILE);
27860Sstevel@tonic-gate 	}
27870Sstevel@tonic-gate 
27880Sstevel@tonic-gate 	return (ret);
27890Sstevel@tonic-gate }
27900Sstevel@tonic-gate 
27910Sstevel@tonic-gate /*
27920Sstevel@tonic-gate  * mod_backup()
27930Sstevel@tonic-gate  *
27940Sstevel@tonic-gate  * This function is used to temporily backup the LDAP client files in /var/ldap
27950Sstevel@tonic-gate  * that the "mod" operation needs to update.  If an error occurs then the
27960Sstevel@tonic-gate  * function mod_recover() can be invoke to recover the unmodified files.
27970Sstevel@tonic-gate  */
27980Sstevel@tonic-gate static int
27990Sstevel@tonic-gate mod_backup(void)
28000Sstevel@tonic-gate {
28010Sstevel@tonic-gate 	int rc;
28020Sstevel@tonic-gate 	int retcode = CLIENT_SUCCESS;
28030Sstevel@tonic-gate 
28040Sstevel@tonic-gate 	rc = system(CMD_CP " " NSCONFIGFILE " " NSCONFIGFILE ".mod");
28050Sstevel@tonic-gate 	retcode += rc;
28060Sstevel@tonic-gate 	if (mode_verbose)
28070Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
28080Sstevel@tonic-gate 		    gettext("mod_backup: backup %s for %s\n"),
28090Sstevel@tonic-gate 		    rc ? "failed" : "successful", NSCONFIGFILE);
28100Sstevel@tonic-gate 
28110Sstevel@tonic-gate 	rc = system(CMD_CP " " NSCREDFILE " " NSCREDFILE ".mod");
28120Sstevel@tonic-gate 	retcode += rc;
28130Sstevel@tonic-gate 	if (mode_verbose)
28140Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
28150Sstevel@tonic-gate 		    gettext("mod_backup: backup %s for %s\n"),
28160Sstevel@tonic-gate 		    rc ? "failed" : "successful", NSCREDFILE);
28170Sstevel@tonic-gate 
28180Sstevel@tonic-gate 	rc = system(CMD_CP " " DOMAINNAME " " DOMAINNAME ".mod");
28190Sstevel@tonic-gate 	retcode += rc;
28200Sstevel@tonic-gate 	if (mode_verbose)
28210Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
28220Sstevel@tonic-gate 		    gettext("mod_backup: backup %s for %s\n"),
28230Sstevel@tonic-gate 		    rc ? "failed" : "successful", DOMAINNAME);
28240Sstevel@tonic-gate 
28250Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS)
28260Sstevel@tonic-gate 		retcode = CLIENT_ERR_RENAME;
28270Sstevel@tonic-gate 	return (retcode);
28280Sstevel@tonic-gate }
28290Sstevel@tonic-gate 
28300Sstevel@tonic-gate /*
28310Sstevel@tonic-gate  * mod_recover()
28320Sstevel@tonic-gate  *
28330Sstevel@tonic-gate  * This function is used to recover the temporily backed up files by
28340Sstevel@tonic-gate  * the mod_backup() function if an error occurs during the "mod"
28350Sstevel@tonic-gate  * operation.
28360Sstevel@tonic-gate  */
28370Sstevel@tonic-gate static int
28380Sstevel@tonic-gate mod_recover(void)
28390Sstevel@tonic-gate {
28400Sstevel@tonic-gate 	int rc;
28410Sstevel@tonic-gate 	int retcode = CLIENT_SUCCESS;
28420Sstevel@tonic-gate 
28430Sstevel@tonic-gate 	rc = system(CMD_MV " " NSCONFIGFILE ".mod " NSCONFIGFILE);
28440Sstevel@tonic-gate 	retcode += rc;
28450Sstevel@tonic-gate 	if (mode_verbose)
28460Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
28470Sstevel@tonic-gate 		    gettext("mod_recover: recovery %s for %s\n"),
28480Sstevel@tonic-gate 		    rc ? "failed" : "successful", NSCONFIGFILE);
28490Sstevel@tonic-gate 
28500Sstevel@tonic-gate 	rc = system(CMD_MV " " NSCREDFILE ".mod " NSCREDFILE);
28510Sstevel@tonic-gate 	retcode += rc;
28520Sstevel@tonic-gate 	if (mode_verbose)
28530Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
28540Sstevel@tonic-gate 		    gettext("mod_recover: recovery %s for %s\n"),
28550Sstevel@tonic-gate 		    rc ? "failed" : "successful", NSCREDFILE);
28560Sstevel@tonic-gate 
28570Sstevel@tonic-gate 	rc = system(CMD_MV " " DOMAINNAME ".mod " DOMAINNAME);
28580Sstevel@tonic-gate 	retcode += rc;
28590Sstevel@tonic-gate 	if (mode_verbose)
28600Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
28610Sstevel@tonic-gate 		    gettext("mod_recover: recovery %s for %s\n"),
28620Sstevel@tonic-gate 		    rc ? "failed" : "successful", DOMAINNAME);
28630Sstevel@tonic-gate 
28640Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS)
28650Sstevel@tonic-gate 		retcode = CLIENT_ERR_RENAME;
28660Sstevel@tonic-gate 	return (retcode);
28670Sstevel@tonic-gate }
28680Sstevel@tonic-gate 
28690Sstevel@tonic-gate /*
28700Sstevel@tonic-gate  * mod_cleanup()
28710Sstevel@tonic-gate  *
28720Sstevel@tonic-gate  * This function removes the .mod files in /var/ldap.
28730Sstevel@tonic-gate  */
28740Sstevel@tonic-gate static void
28750Sstevel@tonic-gate mod_cleanup(void)
28760Sstevel@tonic-gate {
28770Sstevel@tonic-gate 	(void) system(CMD_RM " " NSCONFIGFILE ".mod " TO_DEV_NULL);
28780Sstevel@tonic-gate 	(void) system(CMD_RM " " NSCREDFILE ".mod " TO_DEV_NULL);
28790Sstevel@tonic-gate 	(void) system(CMD_RM " " DOMAINNAME ".mod " TO_DEV_NULL);
28800Sstevel@tonic-gate }
28810Sstevel@tonic-gate 
28820Sstevel@tonic-gate #define	MAX_DN_ARRAY 100
28830Sstevel@tonic-gate #define	LDAP_NAMINGCONTEXTS	"namingcontexts"
28840Sstevel@tonic-gate 
28850Sstevel@tonic-gate static multival_t *
28860Sstevel@tonic-gate multival_new()
28870Sstevel@tonic-gate {
28880Sstevel@tonic-gate 	multival_t *hold;
28890Sstevel@tonic-gate 
28900Sstevel@tonic-gate 	hold = calloc(1, sizeof (multival_t));
28910Sstevel@tonic-gate 	if (hold == NULL) {
28920Sstevel@tonic-gate 		CLIENT_FPUTS(
2893*6842Sth160488 		    gettext("multival_new: Memory allocation error\n"),
2894*6842Sth160488 		    stderr);
28950Sstevel@tonic-gate 	}
28960Sstevel@tonic-gate 	return (hold);	/* NULL -> error */
28970Sstevel@tonic-gate }
28980Sstevel@tonic-gate 
28990Sstevel@tonic-gate static int
29000Sstevel@tonic-gate multival_add(multival_t *list, char *opt)
29010Sstevel@tonic-gate {
29020Sstevel@tonic-gate 	if (opt == NULL) {
29030Sstevel@tonic-gate 		CLIENT_FPUTS(
2904*6842Sth160488 		    gettext("Empty value passed to multival_add\n"),
2905*6842Sth160488 		    stderr);
29060Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
29070Sstevel@tonic-gate 	}
29080Sstevel@tonic-gate 
29090Sstevel@tonic-gate 	if (list->count == 0) {
29100Sstevel@tonic-gate 		list->optlist = (char **)malloc(sizeof (char **));
29110Sstevel@tonic-gate 	} else {
29120Sstevel@tonic-gate 		list->optlist = (char **)realloc(list->optlist,
2913*6842Sth160488 		    (list->count + 1) * sizeof (char **));
29140Sstevel@tonic-gate 	}
29150Sstevel@tonic-gate 
29160Sstevel@tonic-gate 	if (list->optlist == NULL) {
29170Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error allocating memory\n"), stderr);
29180Sstevel@tonic-gate 		return (CLIENT_ERR_MEMORY);	/* 0 is success */
29190Sstevel@tonic-gate 	}
29200Sstevel@tonic-gate 
29210Sstevel@tonic-gate 	list->optlist[list->count] = opt;
29220Sstevel@tonic-gate 	list->count++;
29230Sstevel@tonic-gate 
29240Sstevel@tonic-gate 	return (CLIENT_SUCCESS);
29250Sstevel@tonic-gate }
29260Sstevel@tonic-gate 
29270Sstevel@tonic-gate static void
29280Sstevel@tonic-gate multival_free(multival_t *list)
29290Sstevel@tonic-gate {
29300Sstevel@tonic-gate 	if (list == NULL)
29310Sstevel@tonic-gate 		return;
29320Sstevel@tonic-gate 
29330Sstevel@tonic-gate 	if (list->optlist != NULL)
29340Sstevel@tonic-gate 		free(list->optlist);
29350Sstevel@tonic-gate 	free(list);
29360Sstevel@tonic-gate }
29370Sstevel@tonic-gate 
29380Sstevel@tonic-gate static clientopts_t *
29390Sstevel@tonic-gate clientopts_new()
29400Sstevel@tonic-gate {
29410Sstevel@tonic-gate 	clientopts_t *hold;
29420Sstevel@tonic-gate 
29430Sstevel@tonic-gate 	hold = calloc(1, sizeof (clientopts_t));
29440Sstevel@tonic-gate 	if (NULL == hold) {
29450Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error allocating memory for "
2946*6842Sth160488 		    "clientopts structure\n"), stderr);
29470Sstevel@tonic-gate 		return (hold);	/* NULL -> error */
29480Sstevel@tonic-gate 	}
29490Sstevel@tonic-gate 
29500Sstevel@tonic-gate 	hold->serviceAuthenticationMethod = multival_new();
29510Sstevel@tonic-gate 	if (NULL == hold->serviceAuthenticationMethod) {
29520Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error allocating memory for "
2953*6842Sth160488 		    "serviceAuthenticationMethod\n"), stderr);
29540Sstevel@tonic-gate 		free(hold);
29550Sstevel@tonic-gate 		return (NULL);	/* NULL -> error */
29560Sstevel@tonic-gate 	}
29570Sstevel@tonic-gate 
29580Sstevel@tonic-gate 	hold->serviceCredentialLevel = multival_new();
29590Sstevel@tonic-gate 	if (NULL == hold->serviceCredentialLevel) {
29600Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error allocating memory for "
2961*6842Sth160488 		    "serviceCredentialLevel\n"), stderr);
29620Sstevel@tonic-gate 		multival_free(hold->serviceAuthenticationMethod);
29630Sstevel@tonic-gate 		free(hold);
29640Sstevel@tonic-gate 		return (NULL);	/* NULL -> error */
29650Sstevel@tonic-gate 	}
29660Sstevel@tonic-gate 
29670Sstevel@tonic-gate 	hold->objectclassMap = multival_new();
29680Sstevel@tonic-gate 	if (NULL == hold->objectclassMap) {
29690Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error allocating memory for "
2970*6842Sth160488 		    "objectclassMap\n"), stderr);
29710Sstevel@tonic-gate 		multival_free(hold->serviceAuthenticationMethod);
29720Sstevel@tonic-gate 		multival_free(hold->serviceCredentialLevel);
29730Sstevel@tonic-gate 		free(hold);
29740Sstevel@tonic-gate 		return (NULL);	/* NULL -> error */
29750Sstevel@tonic-gate 	}
29760Sstevel@tonic-gate 
29770Sstevel@tonic-gate 	hold->attributeMap = multival_new();
29780Sstevel@tonic-gate 	if (NULL == hold->attributeMap) {
29790Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error allocating memory for "
2980*6842Sth160488 		    "attributeMap\n"), stderr);
29810Sstevel@tonic-gate 		multival_free(hold->serviceAuthenticationMethod);
29820Sstevel@tonic-gate 		multival_free(hold->serviceCredentialLevel);
29830Sstevel@tonic-gate 		multival_free(hold->objectclassMap);
29840Sstevel@tonic-gate 		free(hold);
29850Sstevel@tonic-gate 		return (NULL);	/* NULL -> error */
29860Sstevel@tonic-gate 	}
29870Sstevel@tonic-gate 
29880Sstevel@tonic-gate 	hold->serviceSearchDescriptor = multival_new();
29890Sstevel@tonic-gate 	if (NULL == hold->serviceSearchDescriptor) {
29900Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error allocating memory for "
2991*6842Sth160488 		    "serviceSearchDescriptor\n"), stderr);
29920Sstevel@tonic-gate 		multival_free(hold->serviceAuthenticationMethod);
29930Sstevel@tonic-gate 		multival_free(hold->serviceCredentialLevel);
29940Sstevel@tonic-gate 		multival_free(hold->objectclassMap);
29950Sstevel@tonic-gate 		multival_free(hold->attributeMap);
29960Sstevel@tonic-gate 		free(hold);
29970Sstevel@tonic-gate 		return (NULL);	/* NULL -> error */
29980Sstevel@tonic-gate 	}
29990Sstevel@tonic-gate 
30000Sstevel@tonic-gate 	return (hold);
30010Sstevel@tonic-gate }
30020Sstevel@tonic-gate 
30030Sstevel@tonic-gate static void
30040Sstevel@tonic-gate clientopts_free(clientopts_t *list)
30050Sstevel@tonic-gate {
30060Sstevel@tonic-gate 	if (NULL == list)
30070Sstevel@tonic-gate 		return;
30080Sstevel@tonic-gate 
30090Sstevel@tonic-gate 	multival_free(list->serviceAuthenticationMethod);
30100Sstevel@tonic-gate 	multival_free(list->serviceCredentialLevel);
30110Sstevel@tonic-gate 	multival_free(list->objectclassMap);
30120Sstevel@tonic-gate 	multival_free(list->attributeMap);
30130Sstevel@tonic-gate 	multival_free(list->serviceSearchDescriptor);
30140Sstevel@tonic-gate 
30150Sstevel@tonic-gate 	free(list);
30160Sstevel@tonic-gate 
30170Sstevel@tonic-gate }
30180Sstevel@tonic-gate 
30190Sstevel@tonic-gate static void
30200Sstevel@tonic-gate multival_list(char *opt, multival_t *list)
30210Sstevel@tonic-gate {
30220Sstevel@tonic-gate 	int i;
30230Sstevel@tonic-gate 
30240Sstevel@tonic-gate 	if (list->count == 0)
30250Sstevel@tonic-gate 		return;
30260Sstevel@tonic-gate 
30270Sstevel@tonic-gate 	(void) puts(opt);
30280Sstevel@tonic-gate 	for (i = 0; i < list->count; i++) {
30290Sstevel@tonic-gate 		(void) printf("\t\targ[%d]: %s\n", i, list->optlist[i]);
30300Sstevel@tonic-gate 	}
30310Sstevel@tonic-gate }
30320Sstevel@tonic-gate 
30330Sstevel@tonic-gate /* return the number of arguments specified in the command line */
30340Sstevel@tonic-gate static int
30350Sstevel@tonic-gate num_args(clientopts_t *list)
30360Sstevel@tonic-gate {
30370Sstevel@tonic-gate 	int arg_count = 0;
30380Sstevel@tonic-gate 
30390Sstevel@tonic-gate 	arg_count += list->authenticationMethod ? 1 : 0;
30400Sstevel@tonic-gate 	arg_count += list->serviceAuthenticationMethod->count;
30410Sstevel@tonic-gate 	arg_count += list->defaultSearchBase ? 1 : 0;
30420Sstevel@tonic-gate 	arg_count += list->credentialLevel ? 1 : 0;
30430Sstevel@tonic-gate 	arg_count += list->serviceCredentialLevel->count;
30440Sstevel@tonic-gate 	arg_count += list->domainName ? 1 : 0;
30450Sstevel@tonic-gate 	arg_count += list->proxyDN ? 1 : 0;
30460Sstevel@tonic-gate 	arg_count += list->profileTTL ? 1 : 0;
30470Sstevel@tonic-gate 	arg_count += list->objectclassMap->count;
30480Sstevel@tonic-gate 	arg_count += list->searchTimeLimit ? 1 : 0;
30490Sstevel@tonic-gate 	arg_count += list->preferredServerList ? 1 : 0;
30500Sstevel@tonic-gate 	arg_count += list->profileName ? 1 : 0;
30510Sstevel@tonic-gate 	arg_count += list->followReferrals ? 1 : 0;
30520Sstevel@tonic-gate 	arg_count += list->attributeMap->count;
30530Sstevel@tonic-gate 	arg_count += list->defaultSearchScope ? 1 : 0;
30540Sstevel@tonic-gate 	arg_count += list->serviceSearchDescriptor->count;
30550Sstevel@tonic-gate 	arg_count += list->bindTimeLimit ? 1 : 0;
30560Sstevel@tonic-gate 	arg_count += list->proxyPassword ? 1 : 0;
30570Sstevel@tonic-gate 	arg_count += list->defaultServerList ? 1 : 0;
30580Sstevel@tonic-gate 	arg_count += list->certificatePath ? 1 : 0;
30590Sstevel@tonic-gate 
30600Sstevel@tonic-gate 	return (arg_count);
30610Sstevel@tonic-gate }
30620Sstevel@tonic-gate 
30630Sstevel@tonic-gate #define	CLIENT_PRINT(opt, str) if (str) \
30640Sstevel@tonic-gate 		(void) printf("%s%s\n", (opt), (str))
30650Sstevel@tonic-gate 
30660Sstevel@tonic-gate static void
30670Sstevel@tonic-gate dumpargs(clientopts_t *list)
30680Sstevel@tonic-gate {
30690Sstevel@tonic-gate 	CLIENT_PRINT("\tauthenticationMethod: ", list->authenticationMethod);
30700Sstevel@tonic-gate 	multival_list("\tserviceAuthenticationMethod: ",
3071*6842Sth160488 	    list->serviceAuthenticationMethod);
30720Sstevel@tonic-gate 	CLIENT_PRINT("\tdefaultSearchBase: ", list->defaultSearchBase);
30730Sstevel@tonic-gate 	CLIENT_PRINT("\tcredentialLevel: ", list->credentialLevel);
30740Sstevel@tonic-gate 	multival_list("\tserviceCredentialLevel: ",
3075*6842Sth160488 	    list->serviceCredentialLevel);
30760Sstevel@tonic-gate 	CLIENT_PRINT("\tdomainName: ", list->domainName);
30770Sstevel@tonic-gate 	CLIENT_PRINT("\tproxyDN: ", list->proxyDN);
30780Sstevel@tonic-gate 	CLIENT_PRINT("\tprofileTTL: ", list->profileTTL);
30790Sstevel@tonic-gate 	multival_list("\tobjectclassMap: ", list->objectclassMap);
30800Sstevel@tonic-gate 	CLIENT_PRINT("\tsearchTimeLimit: ", list->searchTimeLimit);
30810Sstevel@tonic-gate 	CLIENT_PRINT("\tpreferredServerList: ", list->preferredServerList);
30820Sstevel@tonic-gate 	CLIENT_PRINT("\tprofileName: ", list->profileName);
30830Sstevel@tonic-gate 	CLIENT_PRINT("\tfollowReferrals: ", list->followReferrals);
30840Sstevel@tonic-gate 	multival_list("\tattributeMap: ", list->attributeMap);
30850Sstevel@tonic-gate 	CLIENT_PRINT("\tdefaultSearchScope: ", list->defaultSearchScope);
30860Sstevel@tonic-gate 	multival_list("\tserviceSearchDescriptor: ",
3087*6842Sth160488 	    list->serviceSearchDescriptor);
30880Sstevel@tonic-gate 	CLIENT_PRINT("\tbindTimeLimit: ", list->bindTimeLimit);
30890Sstevel@tonic-gate 	CLIENT_PRINT("\tproxyPassword: ", list->proxyPassword);
30900Sstevel@tonic-gate 	CLIENT_PRINT("\tdefaultServerList: ", list->defaultServerList);
30910Sstevel@tonic-gate 	CLIENT_PRINT("\tcertificatePath: ", list->certificatePath);
30920Sstevel@tonic-gate }
30930Sstevel@tonic-gate 
30940Sstevel@tonic-gate 
30950Sstevel@tonic-gate /* These definitions are only used in parseParam() below. */
30960Sstevel@tonic-gate struct param {
30970Sstevel@tonic-gate 	char	*name;
30980Sstevel@tonic-gate 	int	index;
30990Sstevel@tonic-gate };
31000Sstevel@tonic-gate 
31010Sstevel@tonic-gate static struct param paramArray[] = {
31020Sstevel@tonic-gate 	{"proxyDN", NS_LDAP_BINDDN_P},
31030Sstevel@tonic-gate 	{"proxyPassword", NS_LDAP_BINDPASSWD_P},
31040Sstevel@tonic-gate 	{"defaultServerList", NS_LDAP_SERVERS_P},
31050Sstevel@tonic-gate 	{"defaultSearchBase", NS_LDAP_SEARCH_BASEDN_P},
31060Sstevel@tonic-gate 	{"authenticationMethod", NS_LDAP_AUTH_P},
31070Sstevel@tonic-gate 	{"followReferrals", NS_LDAP_SEARCH_REF_P},
31080Sstevel@tonic-gate 	{"profileTTL", NS_LDAP_CACHETTL_P},
31090Sstevel@tonic-gate 	{"certificatePath", NS_LDAP_HOST_CERTPATH_P},
31100Sstevel@tonic-gate 	{"defaultSearchScope", NS_LDAP_SEARCH_SCOPE_P},
31110Sstevel@tonic-gate 	{"bindTimeLimit", NS_LDAP_BIND_TIME_P},
31120Sstevel@tonic-gate 	{"searchTimeLimit", NS_LDAP_SEARCH_TIME_P},
31130Sstevel@tonic-gate 	{"preferredServerList", NS_LDAP_SERVER_PREF_P},
31140Sstevel@tonic-gate 	{"profileName", NS_LDAP_PROFILE_P},
31150Sstevel@tonic-gate 	{"credentialLevel", NS_LDAP_CREDENTIAL_LEVEL_P},
31160Sstevel@tonic-gate 	{"serviceSearchDescriptor", NS_LDAP_SERVICE_SEARCH_DESC_P},
31170Sstevel@tonic-gate 	{"attributeMap", NS_LDAP_ATTRIBUTEMAP_P},
31180Sstevel@tonic-gate 	{"objectclassMap", NS_LDAP_OBJECTCLASSMAP_P},
31190Sstevel@tonic-gate 	{"serviceAuthenticationMethod", NS_LDAP_SERVICE_AUTH_METHOD_P},
31200Sstevel@tonic-gate 	{"serviceCredentialLevel", NS_LDAP_SERVICE_CRED_LEVEL_P},
31210Sstevel@tonic-gate 	{"domainName", LOCAL_DOMAIN_P},
31220Sstevel@tonic-gate 	{NULL, 0}
31230Sstevel@tonic-gate };
31240Sstevel@tonic-gate 
31250Sstevel@tonic-gate static int
31260Sstevel@tonic-gate parseParam(char *param, char **paramVal)
31270Sstevel@tonic-gate {
31280Sstevel@tonic-gate 	char *val = NULL;
31290Sstevel@tonic-gate 	int counter;
31300Sstevel@tonic-gate 
31310Sstevel@tonic-gate 	if (mode_verbose) {
31320Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr, gettext("Parsing %s\n"), param);
31330Sstevel@tonic-gate 	}
31340Sstevel@tonic-gate 
31350Sstevel@tonic-gate 	val = strchr(param, '=');
31360Sstevel@tonic-gate 	if (val == NULL) {
31370Sstevel@tonic-gate 		CLIENT_FPUTS(
3138*6842Sth160488 		    gettext("Didn\'t find \'=\' character in string\n"),
3139*6842Sth160488 		    stderr);
31400Sstevel@tonic-gate 		paramVal = NULL;
31410Sstevel@tonic-gate 		return (CLIENT_ERR_PARSE);
31420Sstevel@tonic-gate 	}
31430Sstevel@tonic-gate 
31440Sstevel@tonic-gate 	*val = '\0';
31450Sstevel@tonic-gate 
31460Sstevel@tonic-gate 	for (counter = 0; paramArray[counter].name != NULL; counter++) {
31470Sstevel@tonic-gate 		if (strcasecmp(paramArray[counter].name, param) == 0) {
31480Sstevel@tonic-gate 			*paramVal = val+1;
31490Sstevel@tonic-gate 			*val = '=';	/* restore original param */
31500Sstevel@tonic-gate 			return (paramArray[counter].index);
31510Sstevel@tonic-gate 		}
31520Sstevel@tonic-gate 	}
31530Sstevel@tonic-gate 
31540Sstevel@tonic-gate 	/* Not found */
31550Sstevel@tonic-gate 	*val = '=';	/* restore original param */
31560Sstevel@tonic-gate 	*paramVal = NULL;
31570Sstevel@tonic-gate 	return (CLIENT_ERR_PARSE);
31580Sstevel@tonic-gate }
31590Sstevel@tonic-gate 
31600Sstevel@tonic-gate /*
31610Sstevel@tonic-gate  * The following macro checks if an option has already been specified
31620Sstevel@tonic-gate  * and errs out with usage if so
31630Sstevel@tonic-gate  */
31640Sstevel@tonic-gate #define	CLIENT_OPT_CHECK(opt, optarg)	\
31650Sstevel@tonic-gate if (optarg) {			\
31660Sstevel@tonic-gate 	CLIENT_FPUTS(gettext("Invalid use of option\n"), stderr);	\
31670Sstevel@tonic-gate 	usage();		\
31680Sstevel@tonic-gate 	clientopts_free(optlist); \
31690Sstevel@tonic-gate 	return (CLIENT_ERR_FAIL);		\
31700Sstevel@tonic-gate }
31710Sstevel@tonic-gate 
31720Sstevel@tonic-gate static int
31730Sstevel@tonic-gate clientSetParam(clientopts_t *optlist, int paramFlag, char *attrVal)
31740Sstevel@tonic-gate {
31750Sstevel@tonic-gate 	int retcode = 0;
31760Sstevel@tonic-gate 	int counter;
31770Sstevel@tonic-gate 
31780Sstevel@tonic-gate 
31790Sstevel@tonic-gate 	switch (paramFlag) {
31800Sstevel@tonic-gate 	case NS_LDAP_AUTH_P:
31810Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->authenticationMethod);
31820Sstevel@tonic-gate 		optlist->authenticationMethod = attrVal;
31830Sstevel@tonic-gate 		break;
31840Sstevel@tonic-gate 
31850Sstevel@tonic-gate 	case NS_LDAP_SERVICE_AUTH_METHOD_P:	/* multiple allowed */
31860Sstevel@tonic-gate 		retcode = multival_add(optlist->serviceAuthenticationMethod,
3187*6842Sth160488 		    attrVal);
31880Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
31890Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
3190*6842Sth160488 			    gettext("Error processing attrVal %s\n"),
3191*6842Sth160488 			    attrVal?attrVal:"NULL");
31920Sstevel@tonic-gate 			usage();
31930Sstevel@tonic-gate 			clientopts_free(optlist);
31940Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
31950Sstevel@tonic-gate 		}
31960Sstevel@tonic-gate 		break;
31970Sstevel@tonic-gate 
31980Sstevel@tonic-gate 	case NS_LDAP_SEARCH_BASEDN_P:
31990Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->defaultSearchBase);
32000Sstevel@tonic-gate 		optlist->defaultSearchBase = attrVal;
32010Sstevel@tonic-gate 		break;
32020Sstevel@tonic-gate 
32030Sstevel@tonic-gate 	case NS_LDAP_CREDENTIAL_LEVEL_P:
32040Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->credentialLevel);
32050Sstevel@tonic-gate 		optlist->credentialLevel = attrVal;
32060Sstevel@tonic-gate 		break;
32070Sstevel@tonic-gate 
32080Sstevel@tonic-gate 	case NS_LDAP_SERVICE_CRED_LEVEL_P:	/* multiple allowed */
32090Sstevel@tonic-gate 		retcode = multival_add(optlist->serviceCredentialLevel,
3210*6842Sth160488 		    attrVal);
32110Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
32120Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
3213*6842Sth160488 			    gettext("Error processing attrVal %s\n"),
3214*6842Sth160488 			    attrVal?attrVal:"NULL");
32150Sstevel@tonic-gate 			usage();
32160Sstevel@tonic-gate 			clientopts_free(optlist);
32170Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
32180Sstevel@tonic-gate 		}
32190Sstevel@tonic-gate 		break;
32200Sstevel@tonic-gate 
32210Sstevel@tonic-gate 	case LOCAL_DOMAIN_P:
32220Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->domainName);
32230Sstevel@tonic-gate 		optlist->domainName = attrVal;
32240Sstevel@tonic-gate 		dname = optlist->domainName;
32250Sstevel@tonic-gate 		break;
32260Sstevel@tonic-gate 
32270Sstevel@tonic-gate 	case NS_LDAP_BINDDN_P:
32280Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->proxyDN);
32290Sstevel@tonic-gate 		optlist->proxyDN = attrVal;
32300Sstevel@tonic-gate 		break;
32310Sstevel@tonic-gate 
32320Sstevel@tonic-gate 	case NS_LDAP_CACHETTL_P:
32330Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->profileTTL);
32340Sstevel@tonic-gate 		optlist->profileTTL = attrVal;
32350Sstevel@tonic-gate 		break;
32360Sstevel@tonic-gate 
32370Sstevel@tonic-gate 	case NS_LDAP_OBJECTCLASSMAP_P:	/* multiple allowed */
32380Sstevel@tonic-gate 		retcode = multival_add(optlist->objectclassMap, attrVal);
32390Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
32400Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
3241*6842Sth160488 			    gettext("Error processing attrVal %s\n"),
3242*6842Sth160488 			    attrVal?attrVal:"NULL");
32430Sstevel@tonic-gate 			usage();
32440Sstevel@tonic-gate 			clientopts_free(optlist);
32450Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
32460Sstevel@tonic-gate 		}
32470Sstevel@tonic-gate 		break;
32480Sstevel@tonic-gate 
32490Sstevel@tonic-gate 	case NS_LDAP_SEARCH_TIME_P:
32500Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->searchTimeLimit);
32510Sstevel@tonic-gate 		optlist->searchTimeLimit = attrVal;
32520Sstevel@tonic-gate 		break;
32530Sstevel@tonic-gate 
32540Sstevel@tonic-gate 	case NS_LDAP_SERVER_PREF_P:
32550Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->preferredServerList);
32560Sstevel@tonic-gate 		optlist->preferredServerList = attrVal;
32570Sstevel@tonic-gate 		/* replace ',' chars with ' ' for proper syntax */
32580Sstevel@tonic-gate 		for (counter = 0;
3259*6842Sth160488 		    counter < strlen(optlist->preferredServerList);
3260*6842Sth160488 		    counter++) {
32610Sstevel@tonic-gate 
32620Sstevel@tonic-gate 			if (optlist->preferredServerList[counter] == ',')
32630Sstevel@tonic-gate 				optlist->preferredServerList[counter] = ' ';
32640Sstevel@tonic-gate 		}
32650Sstevel@tonic-gate 		break;
32660Sstevel@tonic-gate 
32670Sstevel@tonic-gate 	case NS_LDAP_PROFILE_P:
32680Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->profileName);
32690Sstevel@tonic-gate 		optlist->profileName = attrVal;
32700Sstevel@tonic-gate 		break;
32710Sstevel@tonic-gate 
32720Sstevel@tonic-gate 	case NS_LDAP_SEARCH_REF_P:
32730Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->followReferrals);
32740Sstevel@tonic-gate 		if (0 == strcasecmp(attrVal, "followref"))
32750Sstevel@tonic-gate 			optlist->followReferrals = "TRUE";
32760Sstevel@tonic-gate 		else if (0 == strcasecmp(attrVal, "noref"))
32770Sstevel@tonic-gate 			optlist->followReferrals = "FALSE";
32780Sstevel@tonic-gate 		else
32790Sstevel@tonic-gate 			optlist->followReferrals = attrVal;
32800Sstevel@tonic-gate 		break;
32810Sstevel@tonic-gate 
32820Sstevel@tonic-gate 	case NS_LDAP_ATTRIBUTEMAP_P:	/* multiple allowed */
32830Sstevel@tonic-gate 		retcode = multival_add(optlist->attributeMap, attrVal);
32840Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
32850Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
3286*6842Sth160488 			    gettext("Error processing attrVal %s\n"),
3287*6842Sth160488 			    attrVal?attrVal:"NULL");
32880Sstevel@tonic-gate 			usage();
32890Sstevel@tonic-gate 			clientopts_free(optlist);
32900Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
32910Sstevel@tonic-gate 		}
32920Sstevel@tonic-gate 		break;
32930Sstevel@tonic-gate 
32940Sstevel@tonic-gate 	case NS_LDAP_SEARCH_SCOPE_P:
32950Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->defaultSearchScope);
32960Sstevel@tonic-gate 		optlist->defaultSearchScope = attrVal;
32970Sstevel@tonic-gate 		break;
32980Sstevel@tonic-gate 
32990Sstevel@tonic-gate 	case NS_LDAP_SERVICE_SEARCH_DESC_P:	/* multiple allowed */
33000Sstevel@tonic-gate 		retcode = multival_add(optlist->serviceSearchDescriptor,
3301*6842Sth160488 		    attrVal);
33020Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
33030Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
3304*6842Sth160488 			    gettext("Error processing attrVal %s\n"),
3305*6842Sth160488 			    attrVal?attrVal:"NULL");
33060Sstevel@tonic-gate 			usage();
33070Sstevel@tonic-gate 			clientopts_free(optlist);
33080Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
33090Sstevel@tonic-gate 		}
33100Sstevel@tonic-gate 		break;
33110Sstevel@tonic-gate 
33120Sstevel@tonic-gate 	case NS_LDAP_BIND_TIME_P:
33130Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->bindTimeLimit);
33140Sstevel@tonic-gate 		optlist->bindTimeLimit = attrVal;
33150Sstevel@tonic-gate 		break;
33160Sstevel@tonic-gate 
33170Sstevel@tonic-gate 	case NS_LDAP_BINDPASSWD_P:
33180Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->proxyPassword);
33190Sstevel@tonic-gate 		optlist->proxyPassword = attrVal;
33200Sstevel@tonic-gate 		break;
33210Sstevel@tonic-gate 
33220Sstevel@tonic-gate 	case NS_LDAP_HOST_CERTPATH_P:
33230Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->certificatePath);
33240Sstevel@tonic-gate 		optlist->certificatePath = attrVal;
33250Sstevel@tonic-gate 		break;
33260Sstevel@tonic-gate 
33270Sstevel@tonic-gate 	case NS_LDAP_SERVERS_P:
33280Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->defaultServerList);
33290Sstevel@tonic-gate 		optlist->defaultServerList = attrVal;
33300Sstevel@tonic-gate 		break;
33310Sstevel@tonic-gate 
33320Sstevel@tonic-gate 	default:
33330Sstevel@tonic-gate 		usage();
33340Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
33350Sstevel@tonic-gate 		/* break;  lint doesn't like break before end of switch */
33360Sstevel@tonic-gate 	}
33370Sstevel@tonic-gate 
33380Sstevel@tonic-gate 	return (retcode);
33390Sstevel@tonic-gate }
33400Sstevel@tonic-gate 
33410Sstevel@tonic-gate /*
33420Sstevel@tonic-gate  * file_move() - Used to move a config file (backup/restore).
33430Sstevel@tonic-gate  *
33440Sstevel@tonic-gate  * This function uses a system() call with /bin/mv to handle the
33450Sstevel@tonic-gate  * case where the backup directory (/var) is on a different file
33460Sstevel@tonic-gate  * system than the config file (typically /etc).
33470Sstevel@tonic-gate  */
33480Sstevel@tonic-gate static int
33490Sstevel@tonic-gate file_move(const char *from, const char *to)
33500Sstevel@tonic-gate {
33510Sstevel@tonic-gate 	int retcode;
33520Sstevel@tonic-gate 	char mvCommand[] = CMD_MV;
33530Sstevel@tonic-gate 	char cmd_buffer[(2 * MAXPATHLEN) + sizeof (mvCommand) + 3];
33540Sstevel@tonic-gate 
33550Sstevel@tonic-gate 	(void) snprintf(cmd_buffer, sizeof (cmd_buffer), "%s %s %s",
3356*6842Sth160488 	    mvCommand, from, to);
33570Sstevel@tonic-gate 
33580Sstevel@tonic-gate 	/*
33590Sstevel@tonic-gate 	 * This function should only be used internally to move
33600Sstevel@tonic-gate 	 * system files to/from the backup directory.  For security
33610Sstevel@tonic-gate 	 * reasons (this is run as root), don't use this function
33620Sstevel@tonic-gate 	 * with arguments passed into the program.
33630Sstevel@tonic-gate 	 */
33640Sstevel@tonic-gate 	retcode = system(cmd_buffer);
33650Sstevel@tonic-gate 
33660Sstevel@tonic-gate 	return (retcode);
33670Sstevel@tonic-gate }
33680Sstevel@tonic-gate 
33690Sstevel@tonic-gate 
33700Sstevel@tonic-gate /*
33710Sstevel@tonic-gate  * Manipulate the service as instructed by "dowhat"
33720Sstevel@tonic-gate  */
33730Sstevel@tonic-gate static int
33740Sstevel@tonic-gate do_service(const char *fmri, boolean_t waitflag, int dowhat,
33750Sstevel@tonic-gate 		const char *state) {
33760Sstevel@tonic-gate 
33770Sstevel@tonic-gate 	int		status;
33780Sstevel@tonic-gate 	boolean_t	is_maint;
33790Sstevel@tonic-gate 	const char	*what = gettext("not set");
33800Sstevel@tonic-gate 	useconds_t	max;
33810Sstevel@tonic-gate 
33820Sstevel@tonic-gate 	/* Check if we are in maintenance */
33830Sstevel@tonic-gate 	is_maint = is_service(fmri, SCF_STATE_STRING_MAINT);
33840Sstevel@tonic-gate 
33850Sstevel@tonic-gate 	switch (dowhat) {
33860Sstevel@tonic-gate 	case START_SERVICE:
33870Sstevel@tonic-gate 		what = gettext("start");
33880Sstevel@tonic-gate 		status = smf_enable_instance(fmri,
33890Sstevel@tonic-gate 			(sysid_install == B_TRUE)?SMF_TEMPORARY:0);
33900Sstevel@tonic-gate 		break;
33910Sstevel@tonic-gate 	case STOP_SERVICE:
33920Sstevel@tonic-gate 		what = gettext("stop");
33930Sstevel@tonic-gate 		status = smf_disable_instance(fmri,
33940Sstevel@tonic-gate 			(sysid_install == B_TRUE)?SMF_TEMPORARY:0);
33950Sstevel@tonic-gate 		break;
33960Sstevel@tonic-gate 	case RESTART_SERVICE:
33970Sstevel@tonic-gate 		what = gettext("restart");
33980Sstevel@tonic-gate 		status = smf_restart_instance(fmri);
33990Sstevel@tonic-gate 		break;
34000Sstevel@tonic-gate 	default:
34010Sstevel@tonic-gate 		/* coding error; will not happen */
34020Sstevel@tonic-gate 		assert(0);
34030Sstevel@tonic-gate 	}
34040Sstevel@tonic-gate 
34050Sstevel@tonic-gate 	/*
34060Sstevel@tonic-gate 	 * If the service was previously in maintenance then we need to
34070Sstevel@tonic-gate 	 * clear it immediately.  The "dowhat" action will set the
34080Sstevel@tonic-gate 	 * enabled property of the service as intended by the caller while
34090Sstevel@tonic-gate 	 * clear will actually cause it to be enabled/disabled.
34100Sstevel@tonic-gate 	 * We assume that the caller has called us after taking some
34110Sstevel@tonic-gate 	 * recovery action. Even if it's not the case, we don't lose
34120Sstevel@tonic-gate 	 * anything.
34130Sstevel@tonic-gate 	 */
34140Sstevel@tonic-gate 	if (status == 0 && is_maint == B_TRUE) {
34150Sstevel@tonic-gate 		if (mode_verbose)
34160Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
34170Sstevel@tonic-gate 				"%s: %s... %s\n",
34180Sstevel@tonic-gate 				what,
34190Sstevel@tonic-gate 				fmri,
34200Sstevel@tonic-gate 				gettext("restoring from maintenance state"));
34210Sstevel@tonic-gate 		status = smf_restore_instance(fmri);
34220Sstevel@tonic-gate 	}
34230Sstevel@tonic-gate 
34240Sstevel@tonic-gate 	if (status == 0) {
34250Sstevel@tonic-gate 		/* Check if we need to wait ? */
34260Sstevel@tonic-gate 		if (waitflag == B_FALSE) {
34270Sstevel@tonic-gate 			if (mode_verbose)
34280Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
34290Sstevel@tonic-gate 					"%s: %s... %s\n",
34300Sstevel@tonic-gate 					what,
34310Sstevel@tonic-gate 					fmri,
34320Sstevel@tonic-gate 					gettext("success"));
34330Sstevel@tonic-gate 			return (CLIENT_SUCCESS);
34340Sstevel@tonic-gate 		}
34350Sstevel@tonic-gate 
34360Sstevel@tonic-gate 		/* Otherwise wait for max seconds (from the manifest) */
34370Sstevel@tonic-gate 		max = get_timeout_value(dowhat, fmri, DEFAULT_TIMEOUT);
34380Sstevel@tonic-gate 		status = wait_till(fmri, state, max, what, !is_maint);
34390Sstevel@tonic-gate 		if (status == CLIENT_SUCCESS)
34400Sstevel@tonic-gate 			return (CLIENT_SUCCESS);
34410Sstevel@tonic-gate 		/* For error fall through for corrective action */
34420Sstevel@tonic-gate 	} else {
34430Sstevel@tonic-gate 		/* Well, service failed ... */
34440Sstevel@tonic-gate 		if (mode_verbose)
34450Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, "%s: %s... %s: %s\n",
34460Sstevel@tonic-gate 				what,
34470Sstevel@tonic-gate 				fmri,
34480Sstevel@tonic-gate 				gettext("failed"),
34490Sstevel@tonic-gate 				scf_strerror(scf_error()));
34500Sstevel@tonic-gate 		status = CLIENT_ERR_FAIL;
34510Sstevel@tonic-gate 		/* For error fall through for corrective action */
34520Sstevel@tonic-gate 	}
34530Sstevel@tonic-gate 
34540Sstevel@tonic-gate 	/*
34550Sstevel@tonic-gate 	 * If service is still offline after start/restart, then transitioning
34560Sstevel@tonic-gate 	 * failed and guess is restarter failed to apply the timeout as well.
34570Sstevel@tonic-gate 	 * So instead of leaving it offline, let's just disable it until we have
34580Sstevel@tonic-gate 	 * some other mechanism available from smf to handle such situation.
34590Sstevel@tonic-gate 	 */
34600Sstevel@tonic-gate 	if (dowhat != STOP_SERVICE)
34610Sstevel@tonic-gate 		if (is_service(fmri, SCF_STATE_STRING_OFFLINE)) {
34620Sstevel@tonic-gate 			if (mode_verbose)
34630Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
34640Sstevel@tonic-gate 					"%s: %s... %s\n",
34650Sstevel@tonic-gate 					what,
34660Sstevel@tonic-gate 					fmri,
34670Sstevel@tonic-gate 					gettext("offline to disable"));
34680Sstevel@tonic-gate 			(void) disable_service(fmri, waitflag);
34690Sstevel@tonic-gate 		}
34700Sstevel@tonic-gate 
34710Sstevel@tonic-gate 	return (status);
34720Sstevel@tonic-gate }
34730Sstevel@tonic-gate 
34740Sstevel@tonic-gate 
34750Sstevel@tonic-gate /*
34760Sstevel@tonic-gate  * Wait for "max" usecs for the service described by "fmri" to change
34770Sstevel@tonic-gate  * to "state". If check_maint is true then return immediately if
34780Sstevel@tonic-gate  * service goes into maintenance
34790Sstevel@tonic-gate  */
34800Sstevel@tonic-gate static int
34810Sstevel@tonic-gate wait_till(const char *fmri, const char *state, useconds_t max,
34820Sstevel@tonic-gate 		const char *what, boolean_t check_maint) {
34830Sstevel@tonic-gate 	char *st;
34840Sstevel@tonic-gate 	useconds_t usecs = INIT_WAIT_USECS;
34850Sstevel@tonic-gate 
34860Sstevel@tonic-gate 	for (; max > 0; max -= usecs) {
34870Sstevel@tonic-gate 		/* incremental wait */
34880Sstevel@tonic-gate 		usecs *= 2;
34890Sstevel@tonic-gate 		usecs = (usecs > max)?max:usecs;
34900Sstevel@tonic-gate 		if (mode_verbose)
34910Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
34920Sstevel@tonic-gate 				"%s: %s %u %s\n",
34930Sstevel@tonic-gate 				what, gettext("sleep"), usecs,
34940Sstevel@tonic-gate 				gettext("microseconds"));
34950Sstevel@tonic-gate 		(void) usleep(usecs);
34960Sstevel@tonic-gate 
34970Sstevel@tonic-gate 		/* Check state after the wait */
34980Sstevel@tonic-gate 		if ((st = smf_get_state(fmri)) != NULL) {
34990Sstevel@tonic-gate 			if (strcmp(st, state) == 0) {
35000Sstevel@tonic-gate 				if (mode_verbose)
35010Sstevel@tonic-gate 					CLIENT_FPRINTF(stderr,
35020Sstevel@tonic-gate 						"%s: %s... %s\n",
35030Sstevel@tonic-gate 						what,
35040Sstevel@tonic-gate 						fmri,
35050Sstevel@tonic-gate 						gettext("success"));
35060Sstevel@tonic-gate 				free(st);
35070Sstevel@tonic-gate 				return (CLIENT_SUCCESS);
35080Sstevel@tonic-gate 			}
35090Sstevel@tonic-gate 
35100Sstevel@tonic-gate 			/*
35110Sstevel@tonic-gate 			 * If service has gone into maintenance then
35120Sstevel@tonic-gate 			 * we will time out anyway, so we are better
35130Sstevel@tonic-gate 			 * off returning now
35140Sstevel@tonic-gate 			 */
35150Sstevel@tonic-gate 			if (check_maint &&
35160Sstevel@tonic-gate 				strcmp(st, SCF_STATE_STRING_MAINT) == 0) {
35170Sstevel@tonic-gate 				if (mode_verbose)
35180Sstevel@tonic-gate 					CLIENT_FPRINTF(stderr,
35190Sstevel@tonic-gate 						"%s: %s... %s\n",
35200Sstevel@tonic-gate 						what,
35210Sstevel@tonic-gate 						fmri,
35220Sstevel@tonic-gate 						gettext("maintenance"));
35230Sstevel@tonic-gate 				free(st);
35240Sstevel@tonic-gate 				return (CLIENT_ERR_MAINTENANCE);
35250Sstevel@tonic-gate 			}
35260Sstevel@tonic-gate 			free(st);
35270Sstevel@tonic-gate 		} else {
35280Sstevel@tonic-gate 			if (mode_verbose)
35290Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
35300Sstevel@tonic-gate 						"%s: %s... %s: %s\n",
35310Sstevel@tonic-gate 						what,
35320Sstevel@tonic-gate 						fmri,
35330Sstevel@tonic-gate 						gettext("failed"),
35340Sstevel@tonic-gate 						scf_strerror(scf_error()));
35350Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
35360Sstevel@tonic-gate 		}
35370Sstevel@tonic-gate 	}
35380Sstevel@tonic-gate 
35390Sstevel@tonic-gate 	/* Timed out waiting */
35400Sstevel@tonic-gate 	if (mode_verbose)
35410Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
35420Sstevel@tonic-gate 			"%s: %s... %s\n",
35430Sstevel@tonic-gate 			what,
35440Sstevel@tonic-gate 			fmri,
35450Sstevel@tonic-gate 			gettext("timed out"));
35460Sstevel@tonic-gate 	return (CLIENT_ERR_TIMEDOUT);
35470Sstevel@tonic-gate }
35480Sstevel@tonic-gate 
35490Sstevel@tonic-gate 
35500Sstevel@tonic-gate static boolean_t
35510Sstevel@tonic-gate is_service(const char *fmri, const char *state) {
35520Sstevel@tonic-gate 	char		*st;
35530Sstevel@tonic-gate 	boolean_t	result = B_FALSE;
35540Sstevel@tonic-gate 
35550Sstevel@tonic-gate 	if ((st = smf_get_state(fmri)) != NULL) {
35560Sstevel@tonic-gate 		if (strcmp(st, state) == 0)
35570Sstevel@tonic-gate 			result = B_TRUE;
35580Sstevel@tonic-gate 		free(st);
35590Sstevel@tonic-gate 	}
35600Sstevel@tonic-gate 	return (result);
35610Sstevel@tonic-gate }
35620Sstevel@tonic-gate 
35630Sstevel@tonic-gate 
35640Sstevel@tonic-gate /*
35650Sstevel@tonic-gate  *
35660Sstevel@tonic-gate  * get_timeout_val : returns the timeout value set in fmri manifest
35670Sstevel@tonic-gate  * 	inputs	: action(start/stop)
35680Sstevel@tonic-gate  *	fmri(defined fmri string)
35690Sstevel@tonic-gate  *	Returns default if error, the timeout val otherwise
35700Sstevel@tonic-gate  *
35710Sstevel@tonic-gate  */
35720Sstevel@tonic-gate 
35730Sstevel@tonic-gate static useconds_t
35740Sstevel@tonic-gate get_timeout_value(int dowhat, const char *fmri, useconds_t default_val)
35750Sstevel@tonic-gate {
35760Sstevel@tonic-gate 	scf_simple_prop_t	*sp = NULL;
35770Sstevel@tonic-gate 	uint64_t		*cp = NULL;
35780Sstevel@tonic-gate 	int			timeout = default_val/1000000;
35790Sstevel@tonic-gate 	char			*action = NULL;
35800Sstevel@tonic-gate 	const char		*actionstr = NULL;
35810Sstevel@tonic-gate 
35820Sstevel@tonic-gate 	switch (dowhat)  {
35830Sstevel@tonic-gate 		case START_SERVICE:
35840Sstevel@tonic-gate 		case RESTART_SERVICE:
35850Sstevel@tonic-gate 				action = "start";
35860Sstevel@tonic-gate 				actionstr = gettext("start");
35870Sstevel@tonic-gate 				break;
35880Sstevel@tonic-gate 		case STOP_SERVICE:
35890Sstevel@tonic-gate 				action = "stop";
35900Sstevel@tonic-gate 				actionstr = gettext("stop");
35910Sstevel@tonic-gate 				break;
35920Sstevel@tonic-gate 		default:
35930Sstevel@tonic-gate 			assert(0);
35940Sstevel@tonic-gate 	}
35950Sstevel@tonic-gate 
35960Sstevel@tonic-gate 
35970Sstevel@tonic-gate 	sp = scf_simple_prop_get(NULL, fmri, action, SCF_PROPERTY_TIMEOUT);
35980Sstevel@tonic-gate 	if (sp == NULL) {
35990Sstevel@tonic-gate 		if (mode_verbose)
36000Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, "%s: %s... %s: %s\n",
3601*6842Sth160488 			    actionstr,
3602*6842Sth160488 			    fmri,
3603*6842Sth160488 			    gettext("failed to retrieve timeout property"),
3604*6842Sth160488 			    scf_strerror(scf_error()));
36050Sstevel@tonic-gate 		return (default_val);
36060Sstevel@tonic-gate 	}
36070Sstevel@tonic-gate 
36080Sstevel@tonic-gate 	cp = scf_simple_prop_next_count(sp);
36090Sstevel@tonic-gate 	if (cp == NULL) {
36100Sstevel@tonic-gate 		if (mode_verbose)
36110Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, "%s: %s... %s: %s\n",
3612*6842Sth160488 			    actionstr,
3613*6842Sth160488 			    fmri,
3614*6842Sth160488 			    gettext("failed to retrieve timeout value"),
3615*6842Sth160488 			    scf_strerror(scf_error()));
36160Sstevel@tonic-gate 		scf_simple_prop_free(sp);
36170Sstevel@tonic-gate 		return (default_val);
36180Sstevel@tonic-gate 	}
36190Sstevel@tonic-gate 
36200Sstevel@tonic-gate 	if (*cp != 0)
36210Sstevel@tonic-gate 		timeout = *cp;
36220Sstevel@tonic-gate 	scf_simple_prop_free(sp);
36230Sstevel@tonic-gate 	return (timeout * 1000000);
36240Sstevel@tonic-gate }
3625