17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5cb5caa98Sdjl  * Common Development and Distribution License (the "License").
6cb5caa98Sdjl  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*dd1104fbSMichen Chang  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /*
277c478bd9Sstevel@tonic-gate  * ldapclient command. To make (initiailize) or uninitialize a machines as
287c478bd9Sstevel@tonic-gate  * and LDAP client.  This command MUST be run as root (or it will simply exit).
297c478bd9Sstevel@tonic-gate  *
307c478bd9Sstevel@tonic-gate  *	-I	Install. No file_backup/recover for installing only (no doc).
317c478bd9Sstevel@tonic-gate  *
327c478bd9Sstevel@tonic-gate  *	init	Initialze (create) an LDAP client from a profile stored
337c478bd9Sstevel@tonic-gate  *		in a directory-server.
347c478bd9Sstevel@tonic-gate  *	manual	Initialze (create) an LDAP client by hand (-file option
357c478bd9Sstevel@tonic-gate  *		reads from file).
367c478bd9Sstevel@tonic-gate  *	mod	Modify the LDAP client configuration on this machine by hand.
377c478bd9Sstevel@tonic-gate  *	list	List the contents of the LDAP client cache files.
387c478bd9Sstevel@tonic-gate  *	uninit	Uninitialize this machine.
397c478bd9Sstevel@tonic-gate  *
407c478bd9Sstevel@tonic-gate  *	-v	Verbose flag.
417c478bd9Sstevel@tonic-gate  *	-q	Quiet flag (mutually exclusive with -v).
427c478bd9Sstevel@tonic-gate  *
437c478bd9Sstevel@tonic-gate  *	-a attrName=attrVal
447c478bd9Sstevel@tonic-gate  *	<attrName> can be one of the following:
457c478bd9Sstevel@tonic-gate  *
467c478bd9Sstevel@tonic-gate  *	attributeMap
477c478bd9Sstevel@tonic-gate  *		Attribute map.  Can be multiple instances of this option.
487c478bd9Sstevel@tonic-gate  *		(no former option)
497c478bd9Sstevel@tonic-gate  *	authenticationMethod
507c478bd9Sstevel@tonic-gate  *		Authentication method (formerly -a)
517c478bd9Sstevel@tonic-gate  *	bindTimeLimit
527c478bd9Sstevel@tonic-gate  *		Bind time limit. (no former option)
537c478bd9Sstevel@tonic-gate  *	certificatePath
547c478bd9Sstevel@tonic-gate  *		Path to certificates used for secure bind (no former option)
557c478bd9Sstevel@tonic-gate  *	credentialLevel
567c478bd9Sstevel@tonic-gate  *		Client credential level (no former option)
577c478bd9Sstevel@tonic-gate  *	defaultServerList
587c478bd9Sstevel@tonic-gate  *		Default server (no former option) Refer to DUA Config
597c478bd9Sstevel@tonic-gate  *		Schema draft.
607c478bd9Sstevel@tonic-gate  *	defaultSearchBase
617c478bd9Sstevel@tonic-gate  *		Search Base DN. e.g. dc=eng,dc=sun,dc=com (formerly -b)
627c478bd9Sstevel@tonic-gate  *	defaultSearchScope
637c478bd9Sstevel@tonic-gate  *		Search scope. (formerly -s)
647c478bd9Sstevel@tonic-gate  *	domainName
657c478bd9Sstevel@tonic-gate  *		Hosts lookup domain (DNS)  Ex. eng.sun.com (formerly -d)
667c478bd9Sstevel@tonic-gate  *	followReferrals
677c478bd9Sstevel@tonic-gate  *		Search dereference. followref or noref (default followref)
687c478bd9Sstevel@tonic-gate  *		(formerly -r)
697c478bd9Sstevel@tonic-gate  *	objectclassMap
707c478bd9Sstevel@tonic-gate  *		Objectclass map.  Can be multiple instances of this option.
717c478bd9Sstevel@tonic-gate  *		(no former option)
727c478bd9Sstevel@tonic-gate  *	preferredServerList
737c478bd9Sstevel@tonic-gate  *		Server preference list. Comma ',' seperated list of IPaddr.
747c478bd9Sstevel@tonic-gate  *		(formerly -p)
757c478bd9Sstevel@tonic-gate  *	profileName
767c478bd9Sstevel@tonic-gate  *		Profile name to use for init (ldapclient) or
777c478bd9Sstevel@tonic-gate  *		generate (gen_profile). (formerly -P)
787c478bd9Sstevel@tonic-gate  *	profileTTL
797c478bd9Sstevel@tonic-gate  *		Client info TTL.  If set to 0 this information will not be
807c478bd9Sstevel@tonic-gate  *		automatically updated by the ldap_cachemgr(1M).
817c478bd9Sstevel@tonic-gate  *		(formerly -e)
827c478bd9Sstevel@tonic-gate  *	proxyDN
837c478bd9Sstevel@tonic-gate  *		Binding DN.  Ex. cn=client,ou=people,cd=eng,dc=sun,dc=com
847c478bd9Sstevel@tonic-gate  *		(formerly -D)
857c478bd9Sstevel@tonic-gate  *	proxyPassword
867c478bd9Sstevel@tonic-gate  *		Client password not needed for authentication "none".
877c478bd9Sstevel@tonic-gate  *		(formerly -w)
88*dd1104fbSMichen Chang  *	adminDN
89*dd1104fbSMichen Chang  *		Administrator DN for updating naming data.
90*dd1104fbSMichen Chang  *	adminPassword
91*dd1104fbSMichen Chang  *		Administrator password
92*dd1104fbSMichen Chang  *	enableShadowUpdate
93*dd1104fbSMichen Chang  *		Allow Administrator to change shadow data in LDAP
947c478bd9Sstevel@tonic-gate  *	searchTimeLimit
957c478bd9Sstevel@tonic-gate  *		Timeout value. (formerly -o)
967c478bd9Sstevel@tonic-gate  *	serviceSearchDescriptor
977c478bd9Sstevel@tonic-gate  *		Service search scope. (no former option)
987c478bd9Sstevel@tonic-gate  *	serviceAuthenticationMethod
997c478bd9Sstevel@tonic-gate  *		Service authenticaion method (no former option)
1007c478bd9Sstevel@tonic-gate  *	serviceCredentialLevel
1017c478bd9Sstevel@tonic-gate  *		Service credential level (no former option)
1027c478bd9Sstevel@tonic-gate  *
1037c478bd9Sstevel@tonic-gate  */
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate #include <stdlib.h>
1067c478bd9Sstevel@tonic-gate #include <stdio.h>
1077c478bd9Sstevel@tonic-gate #include <unistd.h>
1087c478bd9Sstevel@tonic-gate #include <errno.h>
1097c478bd9Sstevel@tonic-gate #include <sys/types.h>
1107c478bd9Sstevel@tonic-gate #include <time.h>
1117c478bd9Sstevel@tonic-gate #include <sys/param.h>
1127c478bd9Sstevel@tonic-gate #include <sys/stat.h>
1137c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h>
1147c478bd9Sstevel@tonic-gate #include <fcntl.h>
1157c478bd9Sstevel@tonic-gate #include <xti.h>
1167c478bd9Sstevel@tonic-gate #include <strings.h>
1177c478bd9Sstevel@tonic-gate #include <limits.h>
1187c478bd9Sstevel@tonic-gate #include <locale.h>
1197c478bd9Sstevel@tonic-gate #include <syslog.h>
1207c478bd9Sstevel@tonic-gate #include <libscf.h>
1217c478bd9Sstevel@tonic-gate #include <assert.h>
122e1dd0a2fSth 
123e1dd0a2fSth #include "standalone.h"
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
1267c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN "SUNW_OST_OSCMD"
1277c478bd9Sstevel@tonic-gate #endif
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate /* error codes */
1307c478bd9Sstevel@tonic-gate /* The manpage doc only allows for SUCCESS(0), FAIL(1) and CRED(2) on exit */
1317c478bd9Sstevel@tonic-gate #define	CLIENT_SUCCESS		0
1327c478bd9Sstevel@tonic-gate #define	CLIENT_ERR_PARSE	-1
1337c478bd9Sstevel@tonic-gate #define	CLIENT_ERR_FAIL		1
1347c478bd9Sstevel@tonic-gate #define	CLIENT_ERR_CREDENTIAL	2
1357c478bd9Sstevel@tonic-gate #define	CLIENT_ERR_MEMORY	3
1367c478bd9Sstevel@tonic-gate #define	CLIENT_ERR_RESTORE	4
1377c478bd9Sstevel@tonic-gate #define	CLIENT_ERR_RENAME	5
1387c478bd9Sstevel@tonic-gate #define	CLIENT_ERR_RECOVER	6
1397c478bd9Sstevel@tonic-gate #define	CLIENT_ERR_TIMEDOUT	7
1407c478bd9Sstevel@tonic-gate #define	CLIENT_ERR_MAINTENANCE	8
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate /* Reset flag for start_services() */
1437c478bd9Sstevel@tonic-gate #define	START_INIT	1
1447c478bd9Sstevel@tonic-gate #define	START_RESET	2
1457c478bd9Sstevel@tonic-gate #define	START_UNINIT	3
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate /* Reset flag for stop_services() */
1487c478bd9Sstevel@tonic-gate #define	STATE_NOSAVE	0
1497c478bd9Sstevel@tonic-gate #define	STATE_SAVE	1
1507c478bd9Sstevel@tonic-gate 
1517c478bd9Sstevel@tonic-gate /* files to (possibiliy) restore */
1527c478bd9Sstevel@tonic-gate #define	LDAP_RESTORE_DIR	"/var/ldap/restore"
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate #define	DOMAINNAME_DIR		"/etc"
1557c478bd9Sstevel@tonic-gate #define	DOMAINNAME_FILE		"defaultdomain"
1567c478bd9Sstevel@tonic-gate #define	DOMAINNAME		DOMAINNAME_DIR "/" DOMAINNAME_FILE
1577c478bd9Sstevel@tonic-gate #define	DOMAINNAME_BACK		LDAP_RESTORE_DIR "/" DOMAINNAME_FILE
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate #define	NSSWITCH_DIR		"/etc"
1607c478bd9Sstevel@tonic-gate #define	NSSWITCH_FILE		"nsswitch.conf"
1617c478bd9Sstevel@tonic-gate #define	NSSWITCH_CONF		NSSWITCH_DIR "/" NSSWITCH_FILE
1627c478bd9Sstevel@tonic-gate #define	NSSWITCH_BACK		LDAP_RESTORE_DIR "/" NSSWITCH_FILE
1637c478bd9Sstevel@tonic-gate #define	NSSWITCH_LDAP		"/etc/nsswitch.ldap"
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate #define	NIS_COLDSTART_DIR	"/var/nis"
1667c478bd9Sstevel@tonic-gate #define	NIS_COLDSTART_FILE	"NIS_COLD_START"
1677c478bd9Sstevel@tonic-gate #define	NIS_COLDSTART		NIS_COLDSTART_DIR "/" NIS_COLDSTART_FILE
1687c478bd9Sstevel@tonic-gate #define	NIS_COLDSTART_BACK	LDAP_RESTORE_DIR "/" NIS_COLDSTART_FILE
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate #define	YP_BIND_DIR		"/var/yp/binding"
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate /* Define the service FMRIs */
1737c478bd9Sstevel@tonic-gate #define	SENDMAIL_FMRI		"network/smtp:sendmail"
1747c478bd9Sstevel@tonic-gate #define	NSCD_FMRI		"system/name-service-cache:default"
1757c478bd9Sstevel@tonic-gate #define	AUTOFS_FMRI		"system/filesystem/autofs:default"
1767c478bd9Sstevel@tonic-gate #define	LDAP_FMRI		"network/ldap/client:default"
1777c478bd9Sstevel@tonic-gate #define	NISD_FMRI		"network/rpc/nisplus:default"
1787c478bd9Sstevel@tonic-gate #define	YP_FMRI			"network/nis/client:default"
1797c478bd9Sstevel@tonic-gate #define	NS_MILESTONE_FMRI	"milestone/name-services:default"
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate /* Define flags for checking if services were enabled */
1827c478bd9Sstevel@tonic-gate #define	SENDMAIL_ON	0x1
1837c478bd9Sstevel@tonic-gate #define	NSCD_ON		0x10
1847c478bd9Sstevel@tonic-gate #define	AUTOFS_ON	0x100
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate #define	CMD_DOMAIN_START	"/usr/bin/domainname"
1877c478bd9Sstevel@tonic-gate 
1887c478bd9Sstevel@tonic-gate /* Command to copy files */
1897c478bd9Sstevel@tonic-gate #define	CMD_CP			"/bin/cp -f"
1907c478bd9Sstevel@tonic-gate #define	CMD_MV			"/bin/mv -f"
1917c478bd9Sstevel@tonic-gate #define	CMD_RM			"/bin/rm -f"
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate #define	TO_DEV_NULL		" >/dev/null 2>&1"
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate /* Files that need to be just removed */
1967c478bd9Sstevel@tonic-gate #define	NIS_PRIVATE_CACHE	"/var/nis/.NIS_PRIVATE_DIRCACHE"
1977c478bd9Sstevel@tonic-gate #define	NIS_SHARED_CACHE	"/var/nis/NIS_SHARED_DIRCACHE"
1987c478bd9Sstevel@tonic-gate #define	NIS_CLIENT_INFO		"/var/nis/client_info"
1997c478bd9Sstevel@tonic-gate #define	LDAP_CACHE_LOG		"/var/ldap/cachemgr.log"
2007c478bd9Sstevel@tonic-gate 
2017c478bd9Sstevel@tonic-gate /* Output defines to supress if quiet mode set */
2027c478bd9Sstevel@tonic-gate #define	CLIENT_FPUTS if (!mode_quiet) (void) fputs
2037c478bd9Sstevel@tonic-gate #define	CLIENT_FPRINTF if (!mode_quiet) (void) fprintf
2047c478bd9Sstevel@tonic-gate #define	CLIENT_FPUTC if (!mode_quiet) (void) fputc
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate #define	restart_service(fmri, waitflag)\
2077c478bd9Sstevel@tonic-gate 		do_service(fmri, waitflag, RESTART_SERVICE,\
2087c478bd9Sstevel@tonic-gate 		SCF_STATE_STRING_ONLINE)
2097c478bd9Sstevel@tonic-gate #define	start_service(fmri, waitflag)	\
2107c478bd9Sstevel@tonic-gate 		do_service(fmri, waitflag, START_SERVICE,\
2117c478bd9Sstevel@tonic-gate 		SCF_STATE_STRING_ONLINE)
2127c478bd9Sstevel@tonic-gate #define	disable_service(fmri, waitflag)	\
2137c478bd9Sstevel@tonic-gate 		do_service(fmri, waitflag, STOP_SERVICE,\
2147c478bd9Sstevel@tonic-gate 		SCF_STATE_STRING_DISABLED)
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate /*
2177c478bd9Sstevel@tonic-gate  * There isn't a domainName defined as a param, so we set a value here
2187c478bd9Sstevel@tonic-gate  * (1001) should be big enough
2197c478bd9Sstevel@tonic-gate  */
2207c478bd9Sstevel@tonic-gate #define	LOCAL_DOMAIN_P 1001
2217c478bd9Sstevel@tonic-gate 
2227c478bd9Sstevel@tonic-gate #define	START_SERVICE	1
2237c478bd9Sstevel@tonic-gate #define	STOP_SERVICE	2
2247c478bd9Sstevel@tonic-gate #define	RESTART_SERVICE	3
2257c478bd9Sstevel@tonic-gate 
2267c478bd9Sstevel@tonic-gate #define	DEFAULT_TIMEOUT	60000000
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate #define	INIT_WAIT_USECS	50000
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate /* Used to turn off profile checking */
2317c478bd9Sstevel@tonic-gate #define	CACHETTL_OFF "0"
2327c478bd9Sstevel@tonic-gate 
2337c478bd9Sstevel@tonic-gate /* Globals */
2347c478bd9Sstevel@tonic-gate static char *cmd;
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate static char *dname = NULL;
2377c478bd9Sstevel@tonic-gate static char dname_buf[BUFSIZ];
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate static boolean_t sysid_install = B_FALSE;
2407c478bd9Sstevel@tonic-gate 
2417c478bd9Sstevel@tonic-gate static int mode_verbose = 0;
2427c478bd9Sstevel@tonic-gate static int mode_quiet = 0;
2437c478bd9Sstevel@tonic-gate static int gen = 0;
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate static int gStartLdap = 0;
2467c478bd9Sstevel@tonic-gate static int gStartYp = 0;
2477c478bd9Sstevel@tonic-gate static int gStartNisd = 0;
2487c478bd9Sstevel@tonic-gate 
2497c478bd9Sstevel@tonic-gate static int enableFlag = 0;
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate /* multival_t is used to hold params that can have more than one value */
2527c478bd9Sstevel@tonic-gate typedef struct {
2537c478bd9Sstevel@tonic-gate 	int count;
2547c478bd9Sstevel@tonic-gate 	char **optlist;
2557c478bd9Sstevel@tonic-gate } multival_t;
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate static multival_t *multival_new();
2587c478bd9Sstevel@tonic-gate static int multival_add(multival_t *list, char *opt);
2597c478bd9Sstevel@tonic-gate static void multival_free(multival_t *list);
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate /*
2627c478bd9Sstevel@tonic-gate  * clientopts_t is used to hold and pass around the param values from
2637c478bd9Sstevel@tonic-gate  * the cmd line
2647c478bd9Sstevel@tonic-gate  */
2657c478bd9Sstevel@tonic-gate typedef struct {
2667c478bd9Sstevel@tonic-gate 	multival_t	*attributeMap;
2677c478bd9Sstevel@tonic-gate 	char		*authenticationMethod;
2687c478bd9Sstevel@tonic-gate 	char		*bindTimeLimit;
2697c478bd9Sstevel@tonic-gate 	char		*certificatePath;
2707c478bd9Sstevel@tonic-gate 	char		*credentialLevel;
2717c478bd9Sstevel@tonic-gate 	char		*defaultSearchBase;
2727c478bd9Sstevel@tonic-gate 	char		*defaultServerList;
2737c478bd9Sstevel@tonic-gate 	char		*domainName;
2747c478bd9Sstevel@tonic-gate 	char		*followReferrals;
2757c478bd9Sstevel@tonic-gate 	multival_t	*objectclassMap;
2767c478bd9Sstevel@tonic-gate 	char		*preferredServerList;
2777c478bd9Sstevel@tonic-gate 	char		*profileName;
2787c478bd9Sstevel@tonic-gate 	char		*profileTTL;
2797c478bd9Sstevel@tonic-gate 	char		*proxyDN;
2807c478bd9Sstevel@tonic-gate 	char		*proxyPassword;
281*dd1104fbSMichen Chang 	char		*enableShadowUpdate;
282*dd1104fbSMichen Chang 	char		*adminDN;
283*dd1104fbSMichen Chang 	char		*adminPassword;
284e1dd0a2fSth 	char		*bindDN;
285e1dd0a2fSth 	char		*bindPasswd;
2867c478bd9Sstevel@tonic-gate 	char		*defaultSearchScope;
2877c478bd9Sstevel@tonic-gate 	char		*searchTimeLimit;
2887c478bd9Sstevel@tonic-gate 	multival_t	*serviceAuthenticationMethod;
2897c478bd9Sstevel@tonic-gate 	multival_t	*serviceCredentialLevel;
2907c478bd9Sstevel@tonic-gate 	multival_t	*serviceSearchDescriptor;
2917c478bd9Sstevel@tonic-gate } clientopts_t;
2927c478bd9Sstevel@tonic-gate 
2937c478bd9Sstevel@tonic-gate static clientopts_t *clientopts_new();
2947c478bd9Sstevel@tonic-gate static void clientopts_free(clientopts_t *list);
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate extern ns_ldap_error_t *__ns_ldap_print_config(int);
2977c478bd9Sstevel@tonic-gate extern void __ns_ldap_default_config();
298cb5caa98Sdjl extern int __ns_ldap_download(const char *, char *, char *, ns_ldap_error_t **);
2997c478bd9Sstevel@tonic-gate 
3007c478bd9Sstevel@tonic-gate /* Function prototypes (these could be static) */
3017c478bd9Sstevel@tonic-gate static void usage(void);
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate static int credCheck(clientopts_t *arglist);
304*dd1104fbSMichen Chang static int adminCredCheck(clientopts_t *arglist);
3057c478bd9Sstevel@tonic-gate static int clientSetParam(clientopts_t *optlist, int paramFlag, char *attrVal);
3067c478bd9Sstevel@tonic-gate static int parseParam(char *param, char **paramVal);
3077c478bd9Sstevel@tonic-gate static void dumpargs(clientopts_t *arglist);
3087c478bd9Sstevel@tonic-gate static int num_args(clientopts_t *arglist);
3097c478bd9Sstevel@tonic-gate 
3107c478bd9Sstevel@tonic-gate static int file_backup(void);
3117c478bd9Sstevel@tonic-gate static int recover(int saveState);
3127c478bd9Sstevel@tonic-gate static int mod_backup(void);
3137c478bd9Sstevel@tonic-gate static int mod_recover(void);
3147c478bd9Sstevel@tonic-gate static void mod_cleanup(void);
3157c478bd9Sstevel@tonic-gate 
3167c478bd9Sstevel@tonic-gate static int client_list(clientopts_t *arglist);
3177c478bd9Sstevel@tonic-gate static int client_manual(clientopts_t *arglist);
3187c478bd9Sstevel@tonic-gate static int client_mod(clientopts_t *arglist);
3197c478bd9Sstevel@tonic-gate static int client_uninit(clientopts_t *arglist);
3207c478bd9Sstevel@tonic-gate static int client_genProfile(clientopts_t *arglist);
3217c478bd9Sstevel@tonic-gate static int client_init(clientopts_t *arglist);
3227c478bd9Sstevel@tonic-gate static int file_move(const char *from, const char *to);
3237c478bd9Sstevel@tonic-gate 
3247c478bd9Sstevel@tonic-gate static int start_services(int flag);
3257c478bd9Sstevel@tonic-gate static int stop_services(int saveState);
3267c478bd9Sstevel@tonic-gate static boolean_t is_service(const char *fmri, const char *state);
3277c478bd9Sstevel@tonic-gate static int wait_till(const char *fmri, const char *state, useconds_t max,
3287c478bd9Sstevel@tonic-gate 		const char *what, boolean_t check_maint);
3297c478bd9Sstevel@tonic-gate static int do_service(const char *fmri, boolean_t waitflag, int dowhat,
3307c478bd9Sstevel@tonic-gate 		const char *state);
3317c478bd9Sstevel@tonic-gate static useconds_t get_timeout_value(int dowhat, const char *fmri,
3327c478bd9Sstevel@tonic-gate 		useconds_t default_val);
3337c478bd9Sstevel@tonic-gate 
334a506a34cSth int
335a506a34cSth main(int argc, char **argv)
3367c478bd9Sstevel@tonic-gate {
337e1dd0a2fSth 	char		*ret_locale, *ret_textdomain;
338e1dd0a2fSth 	int		retcode;
339e1dd0a2fSth 	int		paramFlag;
340e1dd0a2fSth 	char		*attrVal;
341e1dd0a2fSth 	int		sysinfostatus;
342e1dd0a2fSth 	clientopts_t	*optlist = NULL;
343e1dd0a2fSth 	int		op_manual = 0, op_mod = 0, op_uninit = 0;
344e1dd0a2fSth 	int		op_list = 0, op_init = 0, op_genprofile = 0;
345e1dd0a2fSth 	extern char	*optarg;
346e1dd0a2fSth 	extern int	optind;
347e1dd0a2fSth 	int		option;
3487c478bd9Sstevel@tonic-gate 
3497c478bd9Sstevel@tonic-gate 	ret_locale = setlocale(LC_ALL, "");
3507c478bd9Sstevel@tonic-gate 	if (ret_locale == NULL) {
3517c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Unable to set locale.\n"), stderr);
3527c478bd9Sstevel@tonic-gate 	}
3537c478bd9Sstevel@tonic-gate 	ret_textdomain = textdomain(TEXT_DOMAIN);
3547c478bd9Sstevel@tonic-gate 	if (ret_textdomain == NULL) {
3557c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Unable to set textdomain.\n"), stderr);
3567c478bd9Sstevel@tonic-gate 	}
3577c478bd9Sstevel@tonic-gate 
3587c478bd9Sstevel@tonic-gate 	openlog("ldapclient", LOG_PID, LOG_USER);
3597c478bd9Sstevel@tonic-gate 
3607c478bd9Sstevel@tonic-gate 	/* get name that invoked us */
3617c478bd9Sstevel@tonic-gate 	if (cmd = strrchr(argv[0], '/'))
3627c478bd9Sstevel@tonic-gate 		++cmd;
3637c478bd9Sstevel@tonic-gate 	else
3647c478bd9Sstevel@tonic-gate 		cmd = argv[0];
3657c478bd9Sstevel@tonic-gate 
3667c478bd9Sstevel@tonic-gate 	sysinfostatus = sysinfo(SI_SRPC_DOMAIN, dname_buf, BUFSIZ);
3677c478bd9Sstevel@tonic-gate 	if (0 < sysinfostatus)
3687c478bd9Sstevel@tonic-gate 		dname = &dname_buf[0];
3697c478bd9Sstevel@tonic-gate 
3707c478bd9Sstevel@tonic-gate 	optlist = clientopts_new();
3717c478bd9Sstevel@tonic-gate 	if (optlist == NULL) {
3727c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
373e1dd0a2fSth 		    gettext("Error getting optlist (malloc fail)\n"),
374e1dd0a2fSth 		    stderr);
3757c478bd9Sstevel@tonic-gate 		exit(CLIENT_ERR_FAIL);
3767c478bd9Sstevel@tonic-gate 	}
3777c478bd9Sstevel@tonic-gate 
3787c478bd9Sstevel@tonic-gate 	optind = 1;
3797c478bd9Sstevel@tonic-gate 	while (optind < argc) {
380*dd1104fbSMichen Chang 		option = getopt(argc, argv, "vqa:ID:w:j:y:z:");
3817c478bd9Sstevel@tonic-gate 
3827c478bd9Sstevel@tonic-gate 		switch (option) {
3837c478bd9Sstevel@tonic-gate 		case 'v':
3847c478bd9Sstevel@tonic-gate 			mode_verbose = 1;
3857c478bd9Sstevel@tonic-gate 			break;
3867c478bd9Sstevel@tonic-gate 		case 'q':
3877c478bd9Sstevel@tonic-gate 			mode_quiet = 1;
3887c478bd9Sstevel@tonic-gate 			break;
3897c478bd9Sstevel@tonic-gate 		case 'a':
3907c478bd9Sstevel@tonic-gate 			attrVal = NULL;
3917c478bd9Sstevel@tonic-gate 			paramFlag = parseParam(optarg, &attrVal);
3927c478bd9Sstevel@tonic-gate 			if (paramFlag == CLIENT_ERR_PARSE) {
3937c478bd9Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
394e1dd0a2fSth 				    gettext("Unrecognized "
395e1dd0a2fSth 				    "parameter \"%s\"\n"),
396e1dd0a2fSth 				    optarg);
3977c478bd9Sstevel@tonic-gate 				usage();
3987c478bd9Sstevel@tonic-gate 				exit(CLIENT_ERR_FAIL);
3997c478bd9Sstevel@tonic-gate 			}
400e1dd0a2fSth 			if (paramFlag == NS_LDAP_BINDPASSWD_P &&
401e1dd0a2fSth 			    optlist->proxyPassword != NULL) {
402e1dd0a2fSth 				(void) fprintf(stderr,
403e1dd0a2fSth 				    gettext("The -a proxyPassword option is "
404e1dd0a2fSth 				    "mutually exclusive of -y. "
405e1dd0a2fSth 				    "-a proxyPassword is ignored.\n"));
406e1dd0a2fSth 				break;
407e1dd0a2fSth 			}
408*dd1104fbSMichen Chang 			if (paramFlag == NS_LDAP_ADMIN_BINDPASSWD_P &&
409*dd1104fbSMichen Chang 			    optlist->adminPassword != NULL) {
410*dd1104fbSMichen Chang 				(void) fprintf(stderr,
411*dd1104fbSMichen Chang 				    gettext("The -a adminPassword option is "
412*dd1104fbSMichen Chang 				    "mutually exclusive of -z. "
413*dd1104fbSMichen Chang 				    "-a adminPassword is ignored.\n"));
414*dd1104fbSMichen Chang 				break;
415*dd1104fbSMichen Chang 			}
4167c478bd9Sstevel@tonic-gate 			retcode = clientSetParam(optlist, paramFlag, attrVal);
4177c478bd9Sstevel@tonic-gate 			if (retcode != CLIENT_SUCCESS) {
4187c478bd9Sstevel@tonic-gate 				CLIENT_FPRINTF(
419e1dd0a2fSth 				    stderr,
420e1dd0a2fSth 				    gettext("Error (%d) setting "
421e1dd0a2fSth 				    "param \"%s\"\n"),
422e1dd0a2fSth 				    retcode, optarg);
4237c478bd9Sstevel@tonic-gate 				usage();
4247c478bd9Sstevel@tonic-gate 				exit(CLIENT_ERR_FAIL);
4257c478bd9Sstevel@tonic-gate 			}
4267c478bd9Sstevel@tonic-gate 			break;
427e1dd0a2fSth 		case 'D':
428e1dd0a2fSth 			optlist->bindDN = strdup(optarg);
429e1dd0a2fSth 			break;
430e1dd0a2fSth 		case 'w':
431e1dd0a2fSth 			if (optlist->bindPasswd != NULL) {
432e1dd0a2fSth 				CLIENT_FPRINTF(stderr,
433e1dd0a2fSth 				    gettext("The -w option is mutually "
434e1dd0a2fSth 				    "exclusive of -j. -w is ignored."));
435e1dd0a2fSth 				break;
436e1dd0a2fSth 			}
437e1dd0a2fSth 
438e1dd0a2fSth 			if (optarg[0] == '-' && optarg[1] == '\0') {
439e1dd0a2fSth 				/* Ask for a password later */
440e1dd0a2fSth 				break;
441e1dd0a2fSth 			}
442e1dd0a2fSth 
443e1dd0a2fSth 			optlist->bindPasswd = strdup(optarg);
444e1dd0a2fSth 			break;
445e1dd0a2fSth 		case 'j':
446e1dd0a2fSth 			if (optlist->bindPasswd != NULL) {
447e1dd0a2fSth 				(void) fprintf(stderr,
448e1dd0a2fSth 				    gettext("The -w option is mutually "
449e1dd0a2fSth 				    "exclusive of -j. -w is ignored.\n"));
450e1dd0a2fSth 				free(optlist->bindPasswd);
451e1dd0a2fSth 			}
452e1dd0a2fSth 			optlist->bindPasswd = readPwd(optarg);
453e1dd0a2fSth 			if (optlist->bindPasswd == NULL) {
454e1dd0a2fSth 				exit(CLIENT_ERR_FAIL);
455e1dd0a2fSth 			}
456e1dd0a2fSth 			break;
457e1dd0a2fSth 		case 'y':
458e1dd0a2fSth 			if (optlist->proxyPassword != NULL) {
459e1dd0a2fSth 				(void) fprintf(stderr,
460e1dd0a2fSth 				    gettext("The -a proxyPassword option is "
461e1dd0a2fSth 				    "mutually exclusive of -y. "
462e1dd0a2fSth 				    "-a proxyPassword is ignored.\n"));
463e1dd0a2fSth 			}
464e1dd0a2fSth 			optlist->proxyPassword = readPwd(optarg);
465e1dd0a2fSth 			if (optlist->proxyPassword == NULL) {
466e1dd0a2fSth 				exit(CLIENT_ERR_FAIL);
467e1dd0a2fSth 			}
468e1dd0a2fSth 			break;
469*dd1104fbSMichen Chang 		case 'z':
470*dd1104fbSMichen Chang 			if (optlist->adminPassword != NULL) {
471*dd1104fbSMichen Chang 				(void) fprintf(stderr,
472*dd1104fbSMichen Chang 				    gettext("The -a adminPassword option is "
473*dd1104fbSMichen Chang 				    "mutually exclusive of -z. "
474*dd1104fbSMichen Chang 				    "-a adminPassword is ignored.\n"));
475*dd1104fbSMichen Chang 			}
476*dd1104fbSMichen Chang 			optlist->adminPassword = readPwd(optarg);
477*dd1104fbSMichen Chang 			if (optlist->adminPassword == NULL) {
478*dd1104fbSMichen Chang 				exit(CLIENT_ERR_FAIL);
479*dd1104fbSMichen Chang 			}
480*dd1104fbSMichen Chang 			break;
4817c478bd9Sstevel@tonic-gate 		case EOF:
4827c478bd9Sstevel@tonic-gate 			if (strcmp(argv[optind], "init") == 0) {
4837c478bd9Sstevel@tonic-gate 				op_init = 1;
4847c478bd9Sstevel@tonic-gate 			} else if (strcmp(argv[optind], "manual") == 0) {
4857c478bd9Sstevel@tonic-gate 				op_manual = 1;
4867c478bd9Sstevel@tonic-gate 			} else if (strcmp(argv[optind], "mod") == 0) {
4877c478bd9Sstevel@tonic-gate 				op_mod = 1;
4887c478bd9Sstevel@tonic-gate 			} else if (strcmp(argv[optind], "list") == 0) {
4897c478bd9Sstevel@tonic-gate 				op_list = 1;
4907c478bd9Sstevel@tonic-gate 			} else if (strcmp(argv[optind], "uninit") == 0) {
4917c478bd9Sstevel@tonic-gate 				op_uninit = 1;
4927c478bd9Sstevel@tonic-gate 			} else if (strcmp(argv[optind], "genprofile") == 0) {
4937c478bd9Sstevel@tonic-gate 				gen = 1;
4947c478bd9Sstevel@tonic-gate 				op_genprofile = 1;
4957c478bd9Sstevel@tonic-gate 			} else if (optind == argc-1) {
4967c478bd9Sstevel@tonic-gate 				retcode = clientSetParam(
497e1dd0a2fSth 				    optlist,
498e1dd0a2fSth 				    NS_LDAP_SERVERS_P,
499e1dd0a2fSth 				    argv[optind]);	/* ipAddr */
5007c478bd9Sstevel@tonic-gate 				if (retcode != CLIENT_SUCCESS) {
5017c478bd9Sstevel@tonic-gate 					CLIENT_FPRINTF(
502e1dd0a2fSth 					    stderr,
503e1dd0a2fSth 					    gettext("Error (%d) setting "
504e1dd0a2fSth 					    "serverList param.\n"),
505e1dd0a2fSth 					    retcode);
5067c478bd9Sstevel@tonic-gate 					usage();
5077c478bd9Sstevel@tonic-gate 					exit(CLIENT_ERR_FAIL);
5087c478bd9Sstevel@tonic-gate 				}
5097c478bd9Sstevel@tonic-gate 			} else {
5107c478bd9Sstevel@tonic-gate 				CLIENT_FPUTS(
511e1dd0a2fSth 				    gettext("Error parsing "
512e1dd0a2fSth 				    "command line\n"),
513e1dd0a2fSth 				    stderr);
5147c478bd9Sstevel@tonic-gate 				usage();
5157c478bd9Sstevel@tonic-gate 				exit(CLIENT_ERR_FAIL);
5167c478bd9Sstevel@tonic-gate 			}
5177c478bd9Sstevel@tonic-gate 			optind++;	/* get past the verb and keep trying */
5187c478bd9Sstevel@tonic-gate 			break;
5197c478bd9Sstevel@tonic-gate 		/* Backwards compatibility to support system install */
5207c478bd9Sstevel@tonic-gate 		case 'I':
5217c478bd9Sstevel@tonic-gate 			sysid_install = B_TRUE;
5227c478bd9Sstevel@tonic-gate 			op_init = 1;
5237c478bd9Sstevel@tonic-gate 			mode_quiet = 1;
5247c478bd9Sstevel@tonic-gate 			break;
5257c478bd9Sstevel@tonic-gate 		case '?':
5267c478bd9Sstevel@tonic-gate 			usage();
5277c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("\nOr\n\n"), stderr);
5287c478bd9Sstevel@tonic-gate 			gen = 1;
5297c478bd9Sstevel@tonic-gate 			usage();
5307c478bd9Sstevel@tonic-gate 			exit(CLIENT_ERR_FAIL);
5317c478bd9Sstevel@tonic-gate 			break;
5327c478bd9Sstevel@tonic-gate 		}
5337c478bd9Sstevel@tonic-gate 
5347c478bd9Sstevel@tonic-gate 	}
5357c478bd9Sstevel@tonic-gate 
5367c478bd9Sstevel@tonic-gate 	if ((getuid() != 0) && (!op_genprofile)) {
5377c478bd9Sstevel@tonic-gate 		(void) puts(
538e1dd0a2fSth 		    "You must be root (SuperUser) to run this command.");
5397c478bd9Sstevel@tonic-gate 		usage();
5407c478bd9Sstevel@tonic-gate 		exit(CLIENT_ERR_FAIL);
5417c478bd9Sstevel@tonic-gate 	}
5427c478bd9Sstevel@tonic-gate 
5437c478bd9Sstevel@tonic-gate /*
5447c478bd9Sstevel@tonic-gate  *	All command line arguments are finished being parsed now
5457c478bd9Sstevel@tonic-gate  */
5467c478bd9Sstevel@tonic-gate 
5477c478bd9Sstevel@tonic-gate /* *** Do semantic checking here *** */
5487c478bd9Sstevel@tonic-gate 
5497c478bd9Sstevel@tonic-gate /* if gen and no no searchBase then err */
5507c478bd9Sstevel@tonic-gate 	if (gen && !optlist->defaultSearchBase) {
5517c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
552e1dd0a2fSth 		    gettext("ldapclient: Missing required attrName "
553e1dd0a2fSth 		    "defaultSearchBase\n"),
554e1dd0a2fSth 		    stderr);
5557c478bd9Sstevel@tonic-gate 		usage();
5567c478bd9Sstevel@tonic-gate 		clientopts_free(optlist);
5577c478bd9Sstevel@tonic-gate 		exit(CLIENT_ERR_FAIL);
5587c478bd9Sstevel@tonic-gate 	}
5597c478bd9Sstevel@tonic-gate 
560*dd1104fbSMichen Chang /*
561*dd1104fbSMichen Chang  * if init or manual, and if adminDN is specified then enableShadowUpdate
562*dd1104fbSMichen Chang  * must be set to TRUE.
563*dd1104fbSMichen Chang  */
564*dd1104fbSMichen Chang 	if ((op_init || op_manual) &&
565*dd1104fbSMichen Chang 	    (!optlist->enableShadowUpdate ||
566*dd1104fbSMichen Chang 	    strcasecmp(optlist->enableShadowUpdate, "TRUE") != 0) &&
567*dd1104fbSMichen Chang 	    (optlist->adminDN || optlist->adminPassword)) {
568*dd1104fbSMichen Chang 		CLIENT_FPUTS(
569*dd1104fbSMichen Chang 		    gettext("ldapclient: adminDN and adminPassword must not "
570*dd1104fbSMichen Chang 		    "be specified if enableShadowUpdate is not set to TRUE \n"),
571*dd1104fbSMichen Chang 		    stderr);
572*dd1104fbSMichen Chang 		usage();
573*dd1104fbSMichen Chang 		clientopts_free(optlist);
574*dd1104fbSMichen Chang 		exit(CLIENT_ERR_FAIL);
575*dd1104fbSMichen Chang 	}
576*dd1104fbSMichen Chang 
5777c478bd9Sstevel@tonic-gate /* Only one verb can be specified */
5787c478bd9Sstevel@tonic-gate 	if ((op_init + op_manual + op_mod + op_uninit +
579e1dd0a2fSth 	    op_list + op_genprofile) != 1) {
5807c478bd9Sstevel@tonic-gate 		usage();
5817c478bd9Sstevel@tonic-gate 		clientopts_free(optlist);
5827c478bd9Sstevel@tonic-gate 		exit(CLIENT_ERR_FAIL);
5837c478bd9Sstevel@tonic-gate 	}
5847c478bd9Sstevel@tonic-gate 
5857c478bd9Sstevel@tonic-gate /* *** We passed semantic checking, so now do the operation *** */
5867c478bd9Sstevel@tonic-gate 
5877c478bd9Sstevel@tonic-gate 	if (mode_verbose) {
5887c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Arguments parsed:\n"), stderr);
5897c478bd9Sstevel@tonic-gate 		dumpargs(optlist);
5907c478bd9Sstevel@tonic-gate 	}
5917c478bd9Sstevel@tonic-gate 
5927c478bd9Sstevel@tonic-gate 
5937c478bd9Sstevel@tonic-gate /* handle "ldapclient list" here.  err checking done in func */
5947c478bd9Sstevel@tonic-gate 	if (op_list) {
5957c478bd9Sstevel@tonic-gate 		if (mode_verbose)
5967c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
597e1dd0a2fSth 			    gettext("Handling list option\n"),
598e1dd0a2fSth 			    stderr);
5997c478bd9Sstevel@tonic-gate 		retcode = client_list(optlist);
6007c478bd9Sstevel@tonic-gate 	}
6017c478bd9Sstevel@tonic-gate 
6027c478bd9Sstevel@tonic-gate /* handle "ldapclient uninit" here */
6037c478bd9Sstevel@tonic-gate 	if (op_uninit) {
6047c478bd9Sstevel@tonic-gate 		if (mode_verbose)
6057c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
606e1dd0a2fSth 			    gettext("Handling uninit option\n"),
607e1dd0a2fSth 			    stderr);
6087c478bd9Sstevel@tonic-gate 		retcode = client_uninit(optlist);
6097c478bd9Sstevel@tonic-gate 	}
6107c478bd9Sstevel@tonic-gate 
6117c478bd9Sstevel@tonic-gate /* handle "ldapclient init" (profile) */
6127c478bd9Sstevel@tonic-gate 	if (op_init) {
6137c478bd9Sstevel@tonic-gate 		if (mode_verbose)
6147c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
615e1dd0a2fSth 			    gettext("Handling init option\n"),
616e1dd0a2fSth 			    stderr);
6177c478bd9Sstevel@tonic-gate 		retcode = client_init(optlist);
6187c478bd9Sstevel@tonic-gate 	}
6197c478bd9Sstevel@tonic-gate 
6207c478bd9Sstevel@tonic-gate /* handle "genprofile" here */
6217c478bd9Sstevel@tonic-gate 	if (op_genprofile) {
6227c478bd9Sstevel@tonic-gate 		if (mode_verbose)
6237c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
624e1dd0a2fSth 			    gettext("Handling genProfile\n"),
625e1dd0a2fSth 			    stderr);
6267c478bd9Sstevel@tonic-gate 		retcode = client_genProfile(optlist);
6277c478bd9Sstevel@tonic-gate 	}
6287c478bd9Sstevel@tonic-gate 
6297c478bd9Sstevel@tonic-gate /* handle "ldapclient manual" here */
6307c478bd9Sstevel@tonic-gate 	if (op_manual) {
6317c478bd9Sstevel@tonic-gate 		if (mode_verbose)
6327c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
633e1dd0a2fSth 			    gettext("Handling manual option\n"),
634e1dd0a2fSth 			    stderr);
6357c478bd9Sstevel@tonic-gate 		retcode = client_manual(optlist);
6367c478bd9Sstevel@tonic-gate 	}
6377c478bd9Sstevel@tonic-gate 
6387c478bd9Sstevel@tonic-gate /* handle "ldapclient mod" here */
6397c478bd9Sstevel@tonic-gate 	if (op_mod) {
6407c478bd9Sstevel@tonic-gate 		if (mode_verbose)
6417c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
642e1dd0a2fSth 			    gettext("Handling mod option\n"),
643e1dd0a2fSth 			    stderr);
6447c478bd9Sstevel@tonic-gate 		retcode = client_mod(optlist);
6457c478bd9Sstevel@tonic-gate 	}
6467c478bd9Sstevel@tonic-gate 
6477c478bd9Sstevel@tonic-gate 	clientopts_free(optlist);
6487c478bd9Sstevel@tonic-gate 	if ((retcode == CLIENT_SUCCESS) ||
649e1dd0a2fSth 	    (retcode == CLIENT_ERR_FAIL) ||
650e1dd0a2fSth 	    (retcode == CLIENT_ERR_CREDENTIAL))
651cb5caa98Sdjl 		return (retcode);
6527c478bd9Sstevel@tonic-gate 	else
653cb5caa98Sdjl 		return (CLIENT_ERR_FAIL);
6547c478bd9Sstevel@tonic-gate }
6557c478bd9Sstevel@tonic-gate 
6567c478bd9Sstevel@tonic-gate static int
6577c478bd9Sstevel@tonic-gate client_list(clientopts_t *arglist)
6587c478bd9Sstevel@tonic-gate {
6597c478bd9Sstevel@tonic-gate 	ns_ldap_error_t *errorp;
6607c478bd9Sstevel@tonic-gate 	int retcode = CLIENT_SUCCESS;
6617c478bd9Sstevel@tonic-gate 
6627c478bd9Sstevel@tonic-gate 	if (num_args(arglist) > 0) {
6637c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
664e1dd0a2fSth 		    gettext("No args supported with \"list\" option\n"),
665e1dd0a2fSth 		    stderr);
6667c478bd9Sstevel@tonic-gate 		usage();
6677c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);	/* exit code here ? */
6687c478bd9Sstevel@tonic-gate 	}
6697c478bd9Sstevel@tonic-gate 	if ((errorp = __ns_ldap_print_config(mode_verbose)) != NULL) {
6707c478bd9Sstevel@tonic-gate 		retcode = CLIENT_ERR_FAIL;
6717c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
672e1dd0a2fSth 		    gettext("Cannot get print configuration\n"),
673e1dd0a2fSth 		    stderr);
6747c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(errorp->message, stderr);
6757c478bd9Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
6767c478bd9Sstevel@tonic-gate 		CLIENT_FPUTC('\n', stderr);
6777c478bd9Sstevel@tonic-gate 	}
6787c478bd9Sstevel@tonic-gate 
6797c478bd9Sstevel@tonic-gate 	return (retcode);
6807c478bd9Sstevel@tonic-gate }
6817c478bd9Sstevel@tonic-gate 
6827c478bd9Sstevel@tonic-gate static int
6837c478bd9Sstevel@tonic-gate client_uninit(clientopts_t *arglist)
6847c478bd9Sstevel@tonic-gate {
6857c478bd9Sstevel@tonic-gate 	int retcode = CLIENT_SUCCESS;
686cb5caa98Sdjl 	ns_ldap_self_gssapi_config_t config = NS_LDAP_SELF_GSSAPI_CONFIG_NONE;
6877c478bd9Sstevel@tonic-gate 
6887c478bd9Sstevel@tonic-gate 	if (mode_verbose) {
6897c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
690e1dd0a2fSth 		    gettext("Restoring machine to previous "
691e1dd0a2fSth 		    "configuration state\n"),
692e1dd0a2fSth 		    stderr);
6937c478bd9Sstevel@tonic-gate 	}
6947c478bd9Sstevel@tonic-gate 
6957c478bd9Sstevel@tonic-gate 	if (num_args(arglist) > 0) {
6967c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
697e1dd0a2fSth 		    gettext("No args supported with \"uninit\" option\n"),
698e1dd0a2fSth 		    stderr);
6997c478bd9Sstevel@tonic-gate 		usage();
7007c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
7017c478bd9Sstevel@tonic-gate 	}
7027c478bd9Sstevel@tonic-gate 
703cb5caa98Sdjl 	(void) __ns_ldap_self_gssapi_config(&config);
704cb5caa98Sdjl 
7057c478bd9Sstevel@tonic-gate 	retcode = stop_services(STATE_SAVE);
706cb5caa98Sdjl 
707cb5caa98Sdjl 	if (config != NS_LDAP_SELF_GSSAPI_CONFIG_NONE)
708cb5caa98Sdjl 		(void) system("/usr/sbin/cryptoadm enable metaslot");
709cb5caa98Sdjl 
7107c478bd9Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
7117c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
712e1dd0a2fSth 		    gettext("Errors stopping network services.\n"), stderr);
7137c478bd9Sstevel@tonic-gate 		/* restart whatever services we can */
7147c478bd9Sstevel@tonic-gate 		(void) start_services(START_RESET);
7157c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
7167c478bd9Sstevel@tonic-gate 	}
7177c478bd9Sstevel@tonic-gate 
7187c478bd9Sstevel@tonic-gate 	retcode = recover(STATE_SAVE);
7197c478bd9Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
7207c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
721e1dd0a2fSth 		    gettext("Cannot recover the configuration on "
722e1dd0a2fSth 		    "this machine.\n"),
723e1dd0a2fSth 		    stderr);
7247c478bd9Sstevel@tonic-gate 		(void) start_services(START_RESET);
7257c478bd9Sstevel@tonic-gate 	} else {
7267c478bd9Sstevel@tonic-gate 		retcode = start_services(START_UNINIT);
7277c478bd9Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
7287c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
729e1dd0a2fSth 			    gettext("Config restored but problems "
730e1dd0a2fSth 			    "encountered resetting network "
731e1dd0a2fSth 			    "services.\n"),
732e1dd0a2fSth 			    stderr);
7337c478bd9Sstevel@tonic-gate 		}
7347c478bd9Sstevel@tonic-gate 	}
7357c478bd9Sstevel@tonic-gate 
7367c478bd9Sstevel@tonic-gate 	if (retcode == CLIENT_SUCCESS) {
7377c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
738e1dd0a2fSth 		    gettext("System successfully recovered\n"),
739e1dd0a2fSth 		    stderr);
7407c478bd9Sstevel@tonic-gate 	}
7417c478bd9Sstevel@tonic-gate 
7427c478bd9Sstevel@tonic-gate 	return (retcode);
7437c478bd9Sstevel@tonic-gate }
7447c478bd9Sstevel@tonic-gate 
7457c478bd9Sstevel@tonic-gate /*
7467c478bd9Sstevel@tonic-gate  * The following macro is used to do a __ns_ldap_setParam().
7477c478bd9Sstevel@tonic-gate  * On every call, the return code is checked, and if there was
7487c478bd9Sstevel@tonic-gate  * a problem then the error message is printed, the ldaperr
7497c478bd9Sstevel@tonic-gate  * is freed and we return from the function with the offending
7507c478bd9Sstevel@tonic-gate  * error return code.  This macro keeps us from having to
7517c478bd9Sstevel@tonic-gate  * repeat this code for every call to setParam as was done
7527c478bd9Sstevel@tonic-gate  * in the previous incarnation of ldapclient.
7537c478bd9Sstevel@tonic-gate  *
7547c478bd9Sstevel@tonic-gate  * assumes a "retcode" variable is available for status
7557c478bd9Sstevel@tonic-gate  */
7567c478bd9Sstevel@tonic-gate #define	LDAP_SET_PARAM(argval, argdef)	\
7577c478bd9Sstevel@tonic-gate retcode = 0;	\
7587c478bd9Sstevel@tonic-gate if (NULL != argval) {	\
7597c478bd9Sstevel@tonic-gate 	ns_ldap_error_t *ldaperr;	\
7607c478bd9Sstevel@tonic-gate 	retcode = __ns_ldap_setParam(argdef, (void *)argval, &ldaperr);	\
7617c478bd9Sstevel@tonic-gate 	if (retcode != NS_LDAP_SUCCESS) {	\
7627c478bd9Sstevel@tonic-gate 		if (NULL != ldaperr) {	\
7637c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(ldaperr->message, stderr);	\
7647c478bd9Sstevel@tonic-gate 			CLIENT_FPUTC('\n', stderr);	\
7657c478bd9Sstevel@tonic-gate 			(void) __ns_ldap_freeError(&ldaperr);	\
7667c478bd9Sstevel@tonic-gate 		}	\
7677c478bd9Sstevel@tonic-gate 		return (retcode ? CLIENT_ERR_FAIL : CLIENT_SUCCESS);	\
7687c478bd9Sstevel@tonic-gate 	}	\
7697c478bd9Sstevel@tonic-gate }
7707c478bd9Sstevel@tonic-gate 
771e1dd0a2fSth /*
772e1dd0a2fSth  * The following macro is used to check if an arg has already been set
773e1dd0a2fSth  * and issues an error message, a usage message and then returns an error.
774e1dd0a2fSth  * This was made into a macro to avoid the duplication of this code many
775e1dd0a2fSth  * times in the function below.
776e1dd0a2fSth  */
777e1dd0a2fSth #define	LDAP_CHECK_INVALID(arg, param)	\
778e1dd0a2fSth if (arg) {	\
779e1dd0a2fSth 	CLIENT_FPRINTF(stderr, gettext("Invalid parameter (%s) " \
780e1dd0a2fSth 	    "specified\n"), param);	\
781e1dd0a2fSth 	usage();	\
782e1dd0a2fSth 	return (CLIENT_ERR_FAIL);	\
783e1dd0a2fSth }
784e1dd0a2fSth 
7857c478bd9Sstevel@tonic-gate static int
7867c478bd9Sstevel@tonic-gate client_manual(clientopts_t *arglist)
7877c478bd9Sstevel@tonic-gate {
7887c478bd9Sstevel@tonic-gate 	int counter;
7897c478bd9Sstevel@tonic-gate 	int domain_fp;
7907c478bd9Sstevel@tonic-gate 	ns_ldap_error_t *errorp;
7917c478bd9Sstevel@tonic-gate 	int ret_copy;
7927c478bd9Sstevel@tonic-gate 	int reset_ret;
7937c478bd9Sstevel@tonic-gate 	int retcode = CLIENT_SUCCESS;
7947c478bd9Sstevel@tonic-gate 
7957c478bd9Sstevel@tonic-gate 	if (dname == NULL) {
7967c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
797e1dd0a2fSth 		    gettext("Manual failed: System domain not set and "
798e1dd0a2fSth 		    "no domainName specified.\n"),
799e1dd0a2fSth 		    stderr);
8007c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
8017c478bd9Sstevel@tonic-gate 	}
8027c478bd9Sstevel@tonic-gate 
8037c478bd9Sstevel@tonic-gate 	if (arglist->defaultSearchBase == NULL) {
8047c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
805e1dd0a2fSth 		    gettext("Manual failed: Missing required "
806e1dd0a2fSth 		    "defaultSearchBase attribute.\n"),
807e1dd0a2fSth 		    stderr);
8087c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
8097c478bd9Sstevel@tonic-gate 	}
8107c478bd9Sstevel@tonic-gate 
8117c478bd9Sstevel@tonic-gate 	if ((arglist->defaultServerList == NULL) &&
812e1dd0a2fSth 	    (arglist->preferredServerList == NULL)) {
8137c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
814e1dd0a2fSth 		    gettext("Manual failed: Missing required "
815e1dd0a2fSth 		    "defaultServerList or preferredServerList "
816e1dd0a2fSth 		    "attribute.\n"),
817e1dd0a2fSth 		    stderr);
8187c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
8197c478bd9Sstevel@tonic-gate 	}
8207c478bd9Sstevel@tonic-gate 
8217c478bd9Sstevel@tonic-gate 	if (arglist->profileTTL != NULL) {
8227c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
823e1dd0a2fSth 		    gettext("Manual aborted: profileTTL is not supported "
824e1dd0a2fSth 		    "in manual mode.\n"),
825e1dd0a2fSth 		    stderr);
8267c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
8277c478bd9Sstevel@tonic-gate 	}
8287c478bd9Sstevel@tonic-gate 
8297c478bd9Sstevel@tonic-gate 	if (arglist->profileName != NULL) {
8307c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
831e1dd0a2fSth 		    gettext("Manual aborted: profileName is not supported "
832e1dd0a2fSth 		    "in manual mode.\n"),
833e1dd0a2fSth 		    stderr);
8347c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
8357c478bd9Sstevel@tonic-gate 	}
8367c478bd9Sstevel@tonic-gate 
837e1dd0a2fSth 	LDAP_CHECK_INVALID(arglist->bindDN, "bind DN");
838e1dd0a2fSth 	LDAP_CHECK_INVALID(arglist->bindPasswd, "bind password");
8397c478bd9Sstevel@tonic-gate 
8407c478bd9Sstevel@tonic-gate 	__ns_ldap_setServer(TRUE);	/* Need this for _ns_setParam() */
8417c478bd9Sstevel@tonic-gate 	__ns_ldap_default_config();
8427c478bd9Sstevel@tonic-gate 
8437c478bd9Sstevel@tonic-gate 	/* Set version to latest (not version 1) */
8447c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(NS_LDAP_VERSION, NS_LDAP_FILE_VERSION_P);
8457c478bd9Sstevel@tonic-gate 
8467c478bd9Sstevel@tonic-gate 	/* Set profileTTL to 0 since NO profile on manual */
8477c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(CACHETTL_OFF, NS_LDAP_CACHETTL_P);
8487c478bd9Sstevel@tonic-gate 
8497c478bd9Sstevel@tonic-gate 	/* Set additional valid params from command line */
8507c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->authenticationMethod, NS_LDAP_AUTH_P);
8517c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultSearchBase, NS_LDAP_SEARCH_BASEDN_P);
8527c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->credentialLevel, NS_LDAP_CREDENTIAL_LEVEL_P);
8537c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->proxyDN, NS_LDAP_BINDDN_P);
854*dd1104fbSMichen Chang 	LDAP_SET_PARAM(arglist->enableShadowUpdate,
855*dd1104fbSMichen Chang 	    NS_LDAP_ENABLE_SHADOW_UPDATE_P);
856*dd1104fbSMichen Chang 	LDAP_SET_PARAM(arglist->adminDN, NS_LDAP_ADMIN_BINDDN_P);
8577c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->searchTimeLimit, NS_LDAP_SEARCH_TIME_P);
8587c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->preferredServerList, NS_LDAP_SERVER_PREF_P);
8597c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->profileName, NS_LDAP_PROFILE_P);
8607c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->followReferrals, NS_LDAP_SEARCH_REF_P);
8617c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultSearchScope, NS_LDAP_SEARCH_SCOPE_P);
8627c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->bindTimeLimit, NS_LDAP_BIND_TIME_P);
8637c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->proxyPassword, NS_LDAP_BINDPASSWD_P);
864*dd1104fbSMichen Chang 	LDAP_SET_PARAM(arglist->adminPassword, NS_LDAP_ADMIN_BINDPASSWD_P);
8657c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultServerList, NS_LDAP_SERVERS_P);
8667c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->certificatePath, NS_LDAP_HOST_CERTPATH_P);
8677c478bd9Sstevel@tonic-gate 
8687c478bd9Sstevel@tonic-gate 	for (counter = 0;
869e1dd0a2fSth 	    counter < arglist->serviceAuthenticationMethod->count;
870e1dd0a2fSth 	    counter++) {
8717c478bd9Sstevel@tonic-gate 
8727c478bd9Sstevel@tonic-gate 		LDAP_SET_PARAM(
873e1dd0a2fSth 		    arglist->serviceAuthenticationMethod->optlist[counter],
874e1dd0a2fSth 		    NS_LDAP_SERVICE_AUTH_METHOD_P);
8757c478bd9Sstevel@tonic-gate 	}
8767c478bd9Sstevel@tonic-gate 	for (counter = 0;
877e1dd0a2fSth 	    counter < arglist->serviceCredentialLevel->count;
878e1dd0a2fSth 	    counter++) {
8797c478bd9Sstevel@tonic-gate 
8807c478bd9Sstevel@tonic-gate 		LDAP_SET_PARAM(
881e1dd0a2fSth 		    arglist->serviceCredentialLevel->optlist[counter],
882e1dd0a2fSth 		    NS_LDAP_SERVICE_CRED_LEVEL_P);
8837c478bd9Sstevel@tonic-gate 	}
8847c478bd9Sstevel@tonic-gate 	for (counter = 0;
885e1dd0a2fSth 	    counter < arglist->objectclassMap->count;
886e1dd0a2fSth 	    counter++) {
8877c478bd9Sstevel@tonic-gate 
8887c478bd9Sstevel@tonic-gate 		LDAP_SET_PARAM(arglist->objectclassMap->optlist[counter],
889e1dd0a2fSth 		    NS_LDAP_OBJECTCLASSMAP_P);
8907c478bd9Sstevel@tonic-gate 	}
8917c478bd9Sstevel@tonic-gate 	for (counter = 0; counter < arglist->attributeMap->count; counter++) {
8927c478bd9Sstevel@tonic-gate 		LDAP_SET_PARAM(arglist->attributeMap->optlist[counter],
893e1dd0a2fSth 		    NS_LDAP_ATTRIBUTEMAP_P);
8947c478bd9Sstevel@tonic-gate 	}
8957c478bd9Sstevel@tonic-gate 	for (counter = 0;
896e1dd0a2fSth 	    counter < arglist->serviceSearchDescriptor->count;
897e1dd0a2fSth 	    counter++) {
8987c478bd9Sstevel@tonic-gate 
8997c478bd9Sstevel@tonic-gate 		LDAP_SET_PARAM(
900e1dd0a2fSth 		    arglist->serviceSearchDescriptor->optlist[counter],
901e1dd0a2fSth 		    NS_LDAP_SERVICE_SEARCH_DESC_P);
9027c478bd9Sstevel@tonic-gate 	}
9037c478bd9Sstevel@tonic-gate 
9047c478bd9Sstevel@tonic-gate 	retcode = credCheck(arglist);
905*dd1104fbSMichen Chang 	if (retcode == CLIENT_SUCCESS)
906*dd1104fbSMichen Chang 		retcode = adminCredCheck(arglist);
9077c478bd9Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
9087c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
909e1dd0a2fSth 		    gettext("Error in setting up credentials\n"),
910e1dd0a2fSth 		    stderr);
9117c478bd9Sstevel@tonic-gate 		return (retcode);
9127c478bd9Sstevel@tonic-gate 	}
9137c478bd9Sstevel@tonic-gate 
9147c478bd9Sstevel@tonic-gate 	if (mode_verbose)
9157c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
916e1dd0a2fSth 		    gettext("About to modify this machines "
917e1dd0a2fSth 		    "configuration by writing the files\n"),
918e1dd0a2fSth 		    stderr);
9197c478bd9Sstevel@tonic-gate 
9207c478bd9Sstevel@tonic-gate 	/* get ready to start playing with files */
9217c478bd9Sstevel@tonic-gate 	retcode = stop_services(STATE_SAVE);
9227c478bd9Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
9237c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
924e1dd0a2fSth 		    gettext("Errors stopping network services.\n"), stderr);
9257c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
9267c478bd9Sstevel@tonic-gate 	}
9277c478bd9Sstevel@tonic-gate 
9287c478bd9Sstevel@tonic-gate 	/* Save orig versions of files */
9297c478bd9Sstevel@tonic-gate 	retcode = file_backup();
9307c478bd9Sstevel@tonic-gate 	if (retcode == CLIENT_ERR_RESTORE) {
9317c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
932e1dd0a2fSth 		    gettext("System not in state to enable ldap client.\n"),
933e1dd0a2fSth 		    stderr);
9347c478bd9Sstevel@tonic-gate 
9357c478bd9Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
9367c478bd9Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
9377c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
938e1dd0a2fSth 			    "starting services during reset\n"),
939e1dd0a2fSth 			    reset_ret);
9407c478bd9Sstevel@tonic-gate 		}
9417c478bd9Sstevel@tonic-gate 		return (retcode);
9427c478bd9Sstevel@tonic-gate 	} else if (retcode != CLIENT_SUCCESS) {
9437c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
944e1dd0a2fSth 		    gettext("Save of system configuration failed!  "
945e1dd0a2fSth 		    "Attempting recovery.\n"),
946e1dd0a2fSth 		    stderr);
9477c478bd9Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
9487c478bd9Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
9497c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
950e1dd0a2fSth 			    gettext("Recovery of systems configuration "
951e1dd0a2fSth 			    "failed.  Manual intervention of "
952e1dd0a2fSth 			    "config files is required.\n"),
953e1dd0a2fSth 			    stderr);
9547c478bd9Sstevel@tonic-gate 			return (retcode);
9557c478bd9Sstevel@tonic-gate 		}
9567c478bd9Sstevel@tonic-gate 
9577c478bd9Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
9587c478bd9Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
9597c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
960e1dd0a2fSth 			    "starting services during reset\n"),
961e1dd0a2fSth 			    reset_ret);
9627c478bd9Sstevel@tonic-gate 		}
9637c478bd9Sstevel@tonic-gate 
9647c478bd9Sstevel@tonic-gate 		return (retcode);
9657c478bd9Sstevel@tonic-gate 	}
9667c478bd9Sstevel@tonic-gate 
9677c478bd9Sstevel@tonic-gate 	/* Dump new files */
9687c478bd9Sstevel@tonic-gate 	errorp = __ns_ldap_DumpConfiguration(NSCONFIGFILE);
9697c478bd9Sstevel@tonic-gate 	if (errorp != NULL) {
9707c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
971e1dd0a2fSth 		    gettext("%s manual: errorp is not NULL; %s\n"),
972e1dd0a2fSth 		    cmd, errorp->message);
9737c478bd9Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
9747c478bd9Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
9757c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
976e1dd0a2fSth 			    gettext("Recovery of systems configuration "
977e1dd0a2fSth 			    "failed.  Manual intervention of "
978e1dd0a2fSth 			    "config files is required.\n"),
979e1dd0a2fSth 			    stderr);
9807c478bd9Sstevel@tonic-gate 			return (retcode);
9817c478bd9Sstevel@tonic-gate 		}
9827c478bd9Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
9837c478bd9Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
9847c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
985e1dd0a2fSth 			    "starting services during reset\n"),
986e1dd0a2fSth 			    reset_ret);
9877c478bd9Sstevel@tonic-gate 		}
9887c478bd9Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
9897c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
9907c478bd9Sstevel@tonic-gate 	}
9917c478bd9Sstevel@tonic-gate 
9927c478bd9Sstevel@tonic-gate 	/* if (credargs(arglist)) */
9937c478bd9Sstevel@tonic-gate 	errorp = __ns_ldap_DumpConfiguration(NSCREDFILE);
9947c478bd9Sstevel@tonic-gate 	if (errorp != NULL) {
9957c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
996e1dd0a2fSth 		    gettext("%s init: errorp is not NULL; %s\n"),
997e1dd0a2fSth 		    cmd, errorp->message);
9987c478bd9Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
9997c478bd9Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
10007c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
1001e1dd0a2fSth 			    gettext("Recovery of systems configuration "
1002e1dd0a2fSth 			    "failed.  Manual intervention of "
1003e1dd0a2fSth 			    "config files is required.\n"),
1004e1dd0a2fSth 			    stderr);
10057c478bd9Sstevel@tonic-gate 			return (retcode);
10067c478bd9Sstevel@tonic-gate 		}
10077c478bd9Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
10087c478bd9Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
10097c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1010e1dd0a2fSth 			    "starting services during reset\n"),
1011e1dd0a2fSth 			    reset_ret);
10127c478bd9Sstevel@tonic-gate 		}
10137c478bd9Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
10147c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
10157c478bd9Sstevel@tonic-gate 	}
10167c478bd9Sstevel@tonic-gate 
10177c478bd9Sstevel@tonic-gate 	ret_copy = system(CMD_CP " " NSSWITCH_LDAP " " NSSWITCH_CONF);
10187c478bd9Sstevel@tonic-gate 	if (ret_copy != 0) {
10197c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
1020e1dd0a2fSth 		    gettext("Error %d copying (%s) -> (%s)\n"),
1021e1dd0a2fSth 		    ret_copy, NSSWITCH_LDAP, NSSWITCH_CONF);
10227c478bd9Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
10237c478bd9Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
10247c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
1025e1dd0a2fSth 			    gettext("Recovery of systems configuration "
1026e1dd0a2fSth 			    "failed.  Manual intervention of "
1027e1dd0a2fSth 			    "config files is required.\n"),
1028e1dd0a2fSth 			    stderr);
10297c478bd9Sstevel@tonic-gate 		}
10307c478bd9Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
10317c478bd9Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
10327c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1033e1dd0a2fSth 			    "starting services during reset\n"),
1034e1dd0a2fSth 			    reset_ret);
10357c478bd9Sstevel@tonic-gate 		}
10367c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
10377c478bd9Sstevel@tonic-gate 	}
10387c478bd9Sstevel@tonic-gate 
10397c478bd9Sstevel@tonic-gate 	if ((domain_fp = open(DOMAINNAME, O_WRONLY|O_CREAT|O_TRUNC,
1040e1dd0a2fSth 	    S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) { /* 0644 */
10417c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr, gettext("Cannot open %s\n"), DOMAINNAME);
10427c478bd9Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
10437c478bd9Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
10447c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
1045e1dd0a2fSth 			    gettext("Recovery of systems configuration "
1046e1dd0a2fSth 			    "failed.  Manual intervention of "
1047e1dd0a2fSth 			    "config files is required.\n"),
1048e1dd0a2fSth 			    stderr);
10497c478bd9Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
10507c478bd9Sstevel@tonic-gate 		}
10517c478bd9Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
10527c478bd9Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
10537c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1054e1dd0a2fSth 			    "starting services during reset\n"),
1055e1dd0a2fSth 			    reset_ret);
10567c478bd9Sstevel@tonic-gate 		}
10577c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
10587c478bd9Sstevel@tonic-gate 	}
10597c478bd9Sstevel@tonic-gate 	(void) write(domain_fp, dname, strlen(dname));
10607c478bd9Sstevel@tonic-gate 	(void) write(domain_fp, "\n", 1);
10617c478bd9Sstevel@tonic-gate 	(void) close(domain_fp);
10627c478bd9Sstevel@tonic-gate 
10637c478bd9Sstevel@tonic-gate 	retcode = start_services(START_INIT);
10647c478bd9Sstevel@tonic-gate 
10657c478bd9Sstevel@tonic-gate 	if (retcode == CLIENT_SUCCESS) {
10667c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("System successfully configured\n"),
1067e1dd0a2fSth 		    stderr);
10687c478bd9Sstevel@tonic-gate 	} else {
10697c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error resetting system.\n"
1070e1dd0a2fSth 		    "Recovering old system settings.\n"), stderr),
10717c478bd9Sstevel@tonic-gate 
1072e1dd0a2fSth 		    /* stop any started services for recover */
1073e1dd0a2fSth 		    /* don't stomp on history of saved services state */
1074e1dd0a2fSth 		    reset_ret = stop_services(STATE_NOSAVE);
10757c478bd9Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
10767c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1077e1dd0a2fSth 			    "stopping services during reset\n"),
1078e1dd0a2fSth 			    reset_ret);
10797c478bd9Sstevel@tonic-gate 			/* Coninue and try to recover what we can */
10807c478bd9Sstevel@tonic-gate 		}
10817c478bd9Sstevel@tonic-gate 		reset_ret = recover(STATE_NOSAVE);
10827c478bd9Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
10837c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1084e1dd0a2fSth 			    "recovering service files during "
1085e1dd0a2fSth 			    "reset\n"), reset_ret);
10867c478bd9Sstevel@tonic-gate 			/* Continue and start what we can */
10877c478bd9Sstevel@tonic-gate 		}
10887c478bd9Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
10897c478bd9Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
10907c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1091e1dd0a2fSth 			    "starting services during reset\n"),
1092e1dd0a2fSth 			    reset_ret);
10937c478bd9Sstevel@tonic-gate 		}
10947c478bd9Sstevel@tonic-gate 	}
10957c478bd9Sstevel@tonic-gate 
10967c478bd9Sstevel@tonic-gate 	return (retcode);
10977c478bd9Sstevel@tonic-gate }
10987c478bd9Sstevel@tonic-gate 
10997c478bd9Sstevel@tonic-gate static int
11007c478bd9Sstevel@tonic-gate client_mod(clientopts_t *arglist)
11017c478bd9Sstevel@tonic-gate {
11027c478bd9Sstevel@tonic-gate 	int counter;
11037c478bd9Sstevel@tonic-gate 	int domain_fp;
11047c478bd9Sstevel@tonic-gate 	ns_ldap_error_t *errorp;
11057c478bd9Sstevel@tonic-gate 	int reset_ret;
11067c478bd9Sstevel@tonic-gate 	int retcode = CLIENT_SUCCESS;
11077c478bd9Sstevel@tonic-gate 
11087c478bd9Sstevel@tonic-gate 	__ns_ldap_setServer(TRUE);	/* Need this for _ns_setParam() */
11097c478bd9Sstevel@tonic-gate 	if ((errorp = __ns_ldap_LoadConfiguration()) != NULL) {
11107c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Cannot get load configuration\n"),
1111e1dd0a2fSth 		    stderr);
11127c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(errorp->message, stderr);
11137c478bd9Sstevel@tonic-gate 		CLIENT_FPUTC('\n', stderr);
11147c478bd9Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
11157c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
11167c478bd9Sstevel@tonic-gate 	}
11177c478bd9Sstevel@tonic-gate 
11187c478bd9Sstevel@tonic-gate 	if (arglist->profileTTL != NULL) {
11197c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
1120e1dd0a2fSth 		    gettext("Mod aborted: profileTTL modification is "
1121e1dd0a2fSth 		    "not allowed in mod mode.\n"),
1122e1dd0a2fSth 		    stderr);
11237c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
11247c478bd9Sstevel@tonic-gate 	}
11257c478bd9Sstevel@tonic-gate 
11267c478bd9Sstevel@tonic-gate 	if (arglist->profileName != NULL) {
11277c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
1128e1dd0a2fSth 		    gettext("Mod aborted: profileName modification is "
1129e1dd0a2fSth 		    "not allowed.  If you want to use profiles "
1130e1dd0a2fSth 		    "generate one with genProfile and load it "
1131e1dd0a2fSth 		    "on the server with ldapadd.\n"),
1132e1dd0a2fSth 		    stderr);
11337c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
11347c478bd9Sstevel@tonic-gate 	}
11357c478bd9Sstevel@tonic-gate 
1136e1dd0a2fSth 	LDAP_CHECK_INVALID(arglist->bindDN, "bind DN");
1137e1dd0a2fSth 	LDAP_CHECK_INVALID(arglist->bindPasswd, "bind password");
11387c478bd9Sstevel@tonic-gate 
11397c478bd9Sstevel@tonic-gate 	/* Set additional valid params from command line */
11407c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->authenticationMethod, NS_LDAP_AUTH_P);
11417c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultSearchBase, NS_LDAP_SEARCH_BASEDN_P);
11427c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->credentialLevel, NS_LDAP_CREDENTIAL_LEVEL_P);
11437c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->proxyDN, NS_LDAP_BINDDN_P);
1144*dd1104fbSMichen Chang 	LDAP_SET_PARAM(arglist->adminDN, NS_LDAP_ADMIN_BINDDN_P);
11457c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->profileTTL, NS_LDAP_CACHETTL_P);
11467c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->searchTimeLimit, NS_LDAP_SEARCH_TIME_P);
11477c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->preferredServerList, NS_LDAP_SERVER_PREF_P);
11487c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->profileName, NS_LDAP_PROFILE_P);
11497c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->followReferrals, NS_LDAP_SEARCH_REF_P);
11507c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultSearchScope, NS_LDAP_SEARCH_SCOPE_P);
11517c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->bindTimeLimit, NS_LDAP_BIND_TIME_P);
11527c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->proxyPassword, NS_LDAP_BINDPASSWD_P);
1153*dd1104fbSMichen Chang 	LDAP_SET_PARAM(arglist->adminPassword, NS_LDAP_ADMIN_BINDPASSWD_P);
11547c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultServerList, NS_LDAP_SERVERS_P);
1155*dd1104fbSMichen Chang 	LDAP_SET_PARAM(arglist->enableShadowUpdate,
1156*dd1104fbSMichen Chang 	    NS_LDAP_ENABLE_SHADOW_UPDATE_P);
11577c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->certificatePath, NS_LDAP_HOST_CERTPATH_P);
11587c478bd9Sstevel@tonic-gate 
11597c478bd9Sstevel@tonic-gate 	for (counter = 0;
1160e1dd0a2fSth 	    counter < arglist->serviceAuthenticationMethod->count;
1161e1dd0a2fSth 	    counter++) {
11627c478bd9Sstevel@tonic-gate 
11637c478bd9Sstevel@tonic-gate 		LDAP_SET_PARAM(
1164e1dd0a2fSth 		    arglist->serviceAuthenticationMethod->optlist[counter],
1165e1dd0a2fSth 		    NS_LDAP_SERVICE_AUTH_METHOD_P);
11667c478bd9Sstevel@tonic-gate 	}
11677c478bd9Sstevel@tonic-gate 	for (counter = 0;
1168e1dd0a2fSth 	    counter < arglist->serviceCredentialLevel->count;
1169e1dd0a2fSth 	    counter++) {
11707c478bd9Sstevel@tonic-gate 
11717c478bd9Sstevel@tonic-gate 		LDAP_SET_PARAM(
1172e1dd0a2fSth 		    arglist->serviceCredentialLevel->optlist[counter],
1173e1dd0a2fSth 		    NS_LDAP_SERVICE_CRED_LEVEL_P);
11747c478bd9Sstevel@tonic-gate 	}
11757c478bd9Sstevel@tonic-gate 	for (counter = 0;
1176e1dd0a2fSth 	    counter < arglist->objectclassMap->count;
1177e1dd0a2fSth 	    counter++) {
11787c478bd9Sstevel@tonic-gate 
11797c478bd9Sstevel@tonic-gate 		LDAP_SET_PARAM(
1180e1dd0a2fSth 		    arglist->objectclassMap->optlist[counter],
1181e1dd0a2fSth 		    NS_LDAP_OBJECTCLASSMAP_P);
11827c478bd9Sstevel@tonic-gate 	}
11837c478bd9Sstevel@tonic-gate 	for (counter = 0;
1184e1dd0a2fSth 	    counter < arglist->attributeMap->count;
1185e1dd0a2fSth 	    counter++) {
11867c478bd9Sstevel@tonic-gate 
11877c478bd9Sstevel@tonic-gate 		LDAP_SET_PARAM(
1188e1dd0a2fSth 		    arglist->attributeMap->optlist[counter],
1189e1dd0a2fSth 		    NS_LDAP_ATTRIBUTEMAP_P);
11907c478bd9Sstevel@tonic-gate 	}
11917c478bd9Sstevel@tonic-gate 	for (counter = 0;
1192e1dd0a2fSth 	    counter < arglist->serviceSearchDescriptor->count;
1193e1dd0a2fSth 	    counter++) {
11947c478bd9Sstevel@tonic-gate 
11957c478bd9Sstevel@tonic-gate 		LDAP_SET_PARAM(
1196e1dd0a2fSth 		    arglist->serviceSearchDescriptor->optlist[counter],
1197e1dd0a2fSth 		    NS_LDAP_SERVICE_SEARCH_DESC_P);
11987c478bd9Sstevel@tonic-gate 	}
11997c478bd9Sstevel@tonic-gate 
12007c478bd9Sstevel@tonic-gate 	retcode = credCheck(arglist);
1201*dd1104fbSMichen Chang 	if (retcode == CLIENT_SUCCESS)
1202*dd1104fbSMichen Chang 		retcode = adminCredCheck(arglist);
12037c478bd9Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
12047c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
1205e1dd0a2fSth 		    gettext("Error in setting up credentials\n"),
1206e1dd0a2fSth 		    stderr);
12077c478bd9Sstevel@tonic-gate 		return (retcode);
12087c478bd9Sstevel@tonic-gate 	}
12097c478bd9Sstevel@tonic-gate 
12107c478bd9Sstevel@tonic-gate 	if (mode_verbose)
12117c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
1212e1dd0a2fSth 		    gettext("About to modify this machines configuration "
1213e1dd0a2fSth 		    "by writing the files\n"),
1214e1dd0a2fSth 		    stderr);
12157c478bd9Sstevel@tonic-gate 
12167c478bd9Sstevel@tonic-gate 	/* get ready to start playing with files */
12177c478bd9Sstevel@tonic-gate 	retcode = stop_services(STATE_SAVE);
12187c478bd9Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
12197c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
1220e1dd0a2fSth 		    gettext("Errors stopping network services.\n"), stderr);
12217c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
12227c478bd9Sstevel@tonic-gate 	}
12237c478bd9Sstevel@tonic-gate 
12247c478bd9Sstevel@tonic-gate 	/* Temporarily save orig versions of files */
12257c478bd9Sstevel@tonic-gate 	retcode = mod_backup();
12267c478bd9Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
12277c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
1228e1dd0a2fSth 		    gettext("Unable to backup the ldap client files!\n"),
1229e1dd0a2fSth 		    stderr);
12307c478bd9Sstevel@tonic-gate 
12317c478bd9Sstevel@tonic-gate 		return (retcode);
12327c478bd9Sstevel@tonic-gate 
12337c478bd9Sstevel@tonic-gate 	}
12347c478bd9Sstevel@tonic-gate 
12357c478bd9Sstevel@tonic-gate 	/* Dump new files */
12367c478bd9Sstevel@tonic-gate 	errorp = __ns_ldap_DumpConfiguration(NSCONFIGFILE);
12377c478bd9Sstevel@tonic-gate 	if (errorp != NULL) {
12387c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
1239e1dd0a2fSth 		    gettext("%s mod: errorp is not NULL; %s\n"),
1240e1dd0a2fSth 		    cmd, errorp->message);
12417c478bd9Sstevel@tonic-gate 		retcode = mod_recover();
12427c478bd9Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
12437c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
1244e1dd0a2fSth 			    gettext("Recovery of systems configuration "
1245e1dd0a2fSth 			    "failed.  Manual intervention of "
1246e1dd0a2fSth 			    "config files is required.\n"),
1247e1dd0a2fSth 			    stderr);
12487c478bd9Sstevel@tonic-gate 		}
12497c478bd9Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
12507c478bd9Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
12517c478bd9Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
12527c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1253e1dd0a2fSth 			    "starting services during reset\n"),
1254e1dd0a2fSth 			    reset_ret);
12557c478bd9Sstevel@tonic-gate 		}
12567c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
12577c478bd9Sstevel@tonic-gate 	}
12587c478bd9Sstevel@tonic-gate 
12597c478bd9Sstevel@tonic-gate 	/* if (credargs(arglist)) */
12607c478bd9Sstevel@tonic-gate 	errorp = __ns_ldap_DumpConfiguration(NSCREDFILE);
12617c478bd9Sstevel@tonic-gate 	if (errorp != NULL) {
12627c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
1263e1dd0a2fSth 		    gettext("%s mod: errorp is not NULL; %s\n"),
1264e1dd0a2fSth 		    cmd, errorp->message);
12657c478bd9Sstevel@tonic-gate 		retcode = mod_recover();
12667c478bd9Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
12677c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
1268e1dd0a2fSth 			    gettext("Recovery of systems configuration "
1269e1dd0a2fSth 			    "failed.  Manual intervention of "
1270e1dd0a2fSth 			    "config files is required.\n"),
1271e1dd0a2fSth 			    stderr);
12727c478bd9Sstevel@tonic-gate 		}
12737c478bd9Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
12747c478bd9Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
12757c478bd9Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
12767c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1277e1dd0a2fSth 			    "starting services during reset\n"),
1278e1dd0a2fSth 			    reset_ret);
12797c478bd9Sstevel@tonic-gate 		}
12807c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
12817c478bd9Sstevel@tonic-gate 	}
12827c478bd9Sstevel@tonic-gate 
12837c478bd9Sstevel@tonic-gate 	if ((domain_fp = open(DOMAINNAME, O_WRONLY|O_CREAT|O_TRUNC,
1284e1dd0a2fSth 	    S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) { /* 0644 */
12857c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr, gettext("Cannot open %s\n"), DOMAINNAME);
12867c478bd9Sstevel@tonic-gate 		retcode = mod_recover();
12877c478bd9Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
12887c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
1289e1dd0a2fSth 			    gettext("Recovery of systems configuration "
1290e1dd0a2fSth 			    "failed!  Machine needs to be "
1291e1dd0a2fSth 			    "fixed!\n"),
1292e1dd0a2fSth 			    stderr);
12937c478bd9Sstevel@tonic-gate 		}
12947c478bd9Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
12957c478bd9Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
12967c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1297e1dd0a2fSth 			    "starting services during reset\n"),
1298e1dd0a2fSth 			    reset_ret);
12997c478bd9Sstevel@tonic-gate 		}
13007c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
13017c478bd9Sstevel@tonic-gate 	}
13027c478bd9Sstevel@tonic-gate 	(void) write(domain_fp, dname, strlen(dname));
13037c478bd9Sstevel@tonic-gate 	(void) write(domain_fp, "\n", 1);
13047c478bd9Sstevel@tonic-gate 	(void) close(domain_fp);
13057c478bd9Sstevel@tonic-gate 
13067c478bd9Sstevel@tonic-gate 	retcode = start_services(START_INIT);
13077c478bd9Sstevel@tonic-gate 
13087c478bd9Sstevel@tonic-gate 	if (retcode == CLIENT_SUCCESS) {
13097c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("System successfully configured\n"),
1310e1dd0a2fSth 		    stderr);
13117c478bd9Sstevel@tonic-gate 	} else {
13127c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error resetting system.\n"
1313e1dd0a2fSth 		    "Recovering old system settings.\n"), stderr),
13147c478bd9Sstevel@tonic-gate 
1315e1dd0a2fSth 		    /* stop any started services for recover */
1316e1dd0a2fSth 		    /* don't stomp on history of saved services state */
1317e1dd0a2fSth 		    reset_ret = stop_services(STATE_NOSAVE);
13187c478bd9Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
13197c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1320e1dd0a2fSth 			    "stopping services during reset\n"),
1321e1dd0a2fSth 			    reset_ret);
13227c478bd9Sstevel@tonic-gate 			/* Coninue and try to recover what we can */
13237c478bd9Sstevel@tonic-gate 		}
13247c478bd9Sstevel@tonic-gate 		reset_ret = mod_recover();
13257c478bd9Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
13267c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1327e1dd0a2fSth 			    "recovering service files during "
1328e1dd0a2fSth 			    "reset\n"), reset_ret);
13297c478bd9Sstevel@tonic-gate 			/* Continue and start what we can */
13307c478bd9Sstevel@tonic-gate 		}
13317c478bd9Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
13327c478bd9Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
13337c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1334e1dd0a2fSth 			    "starting services during reset\n"),
1335e1dd0a2fSth 			    reset_ret);
13367c478bd9Sstevel@tonic-gate 		}
13377c478bd9Sstevel@tonic-gate 	}
13387c478bd9Sstevel@tonic-gate 
13397c478bd9Sstevel@tonic-gate 	/* Cleanup temporary files created by mod_backup() */
13407c478bd9Sstevel@tonic-gate 	mod_cleanup();
13417c478bd9Sstevel@tonic-gate 
13427c478bd9Sstevel@tonic-gate 	return (retcode);
13437c478bd9Sstevel@tonic-gate }
13447c478bd9Sstevel@tonic-gate 
13457c478bd9Sstevel@tonic-gate 
13467c478bd9Sstevel@tonic-gate static int
13477c478bd9Sstevel@tonic-gate client_genProfile(clientopts_t *arglist)
13487c478bd9Sstevel@tonic-gate {
13497c478bd9Sstevel@tonic-gate 	int counter;
13507c478bd9Sstevel@tonic-gate 	int retcode;	/* required for LDAP_SET_PARAM macro */
13517c478bd9Sstevel@tonic-gate 	ns_ldap_error_t *errorp;
13527c478bd9Sstevel@tonic-gate 
13537c478bd9Sstevel@tonic-gate 	if (mode_verbose)
13547c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("About to generate a profile\n"), stderr);
13557c478bd9Sstevel@tonic-gate 
13567c478bd9Sstevel@tonic-gate 	/* *** Check for invalid args *** */
13577c478bd9Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->proxyDN, "proxyDN");
13587c478bd9Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->proxyPassword, "proxyPassword");
1359*dd1104fbSMichen Chang 	LDAP_CHECK_INVALID(arglist->enableShadowUpdate,
1360*dd1104fbSMichen Chang 	    "enableShadowUpdate");
1361*dd1104fbSMichen Chang 	LDAP_CHECK_INVALID(arglist->adminDN, "adminDN");
1362*dd1104fbSMichen Chang 	LDAP_CHECK_INVALID(arglist->adminPassword, "adminPassword");
13637c478bd9Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->certificatePath, "certificatePath");
13647c478bd9Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->domainName, "domainName");
1365e1dd0a2fSth 	LDAP_CHECK_INVALID(arglist->bindDN, "bind DN");
1366e1dd0a2fSth 	LDAP_CHECK_INVALID(arglist->bindPasswd, "bind password");
13677c478bd9Sstevel@tonic-gate 	/* *** End check for invalid args *** */
13687c478bd9Sstevel@tonic-gate 
13697c478bd9Sstevel@tonic-gate 	if (arglist->profileName == NULL) {
13707c478bd9Sstevel@tonic-gate 		if (mode_verbose)
13717c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
1372e1dd0a2fSth 			    gettext("No profile specified. "
1373e1dd0a2fSth 			    "Using \"default\"\n"),
1374e1dd0a2fSth 			    stderr);
13757c478bd9Sstevel@tonic-gate 		arglist->profileName = "default";
13767c478bd9Sstevel@tonic-gate 	}
13777c478bd9Sstevel@tonic-gate 
13787c478bd9Sstevel@tonic-gate 	__ns_ldap_setServer(TRUE);
13797c478bd9Sstevel@tonic-gate 	__ns_ldap_default_config();
13807c478bd9Sstevel@tonic-gate 
13817c478bd9Sstevel@tonic-gate 	/* Set version to latest (not version 1) */
13827c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(NS_LDAP_VERSION, NS_LDAP_FILE_VERSION_P);
13837c478bd9Sstevel@tonic-gate 
13847c478bd9Sstevel@tonic-gate 	/* Set additional valid params from command line */
13857c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->authenticationMethod, NS_LDAP_AUTH_P);
13867c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultSearchBase, NS_LDAP_SEARCH_BASEDN_P);
13877c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->credentialLevel, NS_LDAP_CREDENTIAL_LEVEL_P);
13887c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->profileTTL, NS_LDAP_CACHETTL_P);
13897c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->searchTimeLimit, NS_LDAP_SEARCH_TIME_P);
13907c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->preferredServerList, NS_LDAP_SERVER_PREF_P);
13917c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->profileName, NS_LDAP_PROFILE_P);
13927c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->followReferrals, NS_LDAP_SEARCH_REF_P);
13937c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultSearchScope, NS_LDAP_SEARCH_SCOPE_P);
13947c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->bindTimeLimit, NS_LDAP_BIND_TIME_P);
13957c478bd9Sstevel@tonic-gate 	LDAP_SET_PARAM(arglist->defaultServerList, NS_LDAP_SERVERS_P);
13967c478bd9Sstevel@tonic-gate 
13977c478bd9Sstevel@tonic-gate 	for (counter = 0;
1398e1dd0a2fSth 	    counter < arglist->serviceAuthenticationMethod->count;
1399e1dd0a2fSth 	    counter++) {
14007c478bd9Sstevel@tonic-gate 
14017c478bd9Sstevel@tonic-gate 		LDAP_SET_PARAM(
1402e1dd0a2fSth 		    arglist->serviceAuthenticationMethod->optlist[counter],
1403e1dd0a2fSth 		    NS_LDAP_SERVICE_AUTH_METHOD_P);
14047c478bd9Sstevel@tonic-gate 	}
14057c478bd9Sstevel@tonic-gate 	for (counter = 0;
1406e1dd0a2fSth 	    counter < arglist->serviceCredentialLevel->count;
1407e1dd0a2fSth 	    counter++) {
14087c478bd9Sstevel@tonic-gate 
14097c478bd9Sstevel@tonic-gate 		LDAP_SET_PARAM(
1410e1dd0a2fSth 		    arglist->serviceCredentialLevel->optlist[counter],
1411e1dd0a2fSth 		    NS_LDAP_SERVICE_CRED_LEVEL_P);
14127c478bd9Sstevel@tonic-gate 	}
14137c478bd9Sstevel@tonic-gate 	for (counter = 0;
1414e1dd0a2fSth 	    counter < arglist->objectclassMap->count;
1415e1dd0a2fSth 	    counter++) {
14167c478bd9Sstevel@tonic-gate 
14177c478bd9Sstevel@tonic-gate 		LDAP_SET_PARAM(
1418e1dd0a2fSth 		    arglist->objectclassMap->optlist[counter],
1419e1dd0a2fSth 		    NS_LDAP_OBJECTCLASSMAP_P);
14207c478bd9Sstevel@tonic-gate 	}
14217c478bd9Sstevel@tonic-gate 	for (counter = 0;
1422e1dd0a2fSth 	    counter < arglist->attributeMap->count;
1423e1dd0a2fSth 	    counter++) {
14247c478bd9Sstevel@tonic-gate 
14257c478bd9Sstevel@tonic-gate 		LDAP_SET_PARAM(
1426e1dd0a2fSth 		    arglist->attributeMap->optlist[counter],
1427e1dd0a2fSth 		    NS_LDAP_ATTRIBUTEMAP_P);
14287c478bd9Sstevel@tonic-gate 	}
14297c478bd9Sstevel@tonic-gate 	for (counter = 0;
1430e1dd0a2fSth 	    counter < arglist->serviceSearchDescriptor->count;
1431e1dd0a2fSth 	    counter++) {
14327c478bd9Sstevel@tonic-gate 
14337c478bd9Sstevel@tonic-gate 		LDAP_SET_PARAM(
1434e1dd0a2fSth 		    arglist->serviceSearchDescriptor->optlist[counter],
1435e1dd0a2fSth 		    NS_LDAP_SERVICE_SEARCH_DESC_P);
14367c478bd9Sstevel@tonic-gate 	}
14377c478bd9Sstevel@tonic-gate 
14387c478bd9Sstevel@tonic-gate 	errorp = __ns_ldap_DumpLdif(NULL);
14397c478bd9Sstevel@tonic-gate 	if (errorp != NULL) {
14407c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(errorp->message, stderr);
14417c478bd9Sstevel@tonic-gate 		CLIENT_FPUTC('\n', stderr);
14427c478bd9Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
14437c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
14447c478bd9Sstevel@tonic-gate 	}
14457c478bd9Sstevel@tonic-gate 
14467c478bd9Sstevel@tonic-gate 	return (CLIENT_SUCCESS);
14477c478bd9Sstevel@tonic-gate }
14487c478bd9Sstevel@tonic-gate 
1449e1dd0a2fSth /* INET6_ADDRSTRLEN + ":" + <5-digit port> + some round-up */
1450e1dd0a2fSth #define	MAX_HOSTADDR_LEN (INET6_ADDRSTRLEN + 6 + 12)
1451e1dd0a2fSth 
14527c478bd9Sstevel@tonic-gate static int
14537c478bd9Sstevel@tonic-gate client_init(clientopts_t *arglist)
14547c478bd9Sstevel@tonic-gate {
1455e1dd0a2fSth 	int			profile_fp;
1456e1dd0a2fSth 	int			retcode = CLIENT_SUCCESS;
1457e1dd0a2fSth 	ns_ldap_error_t		*errorp;
1458e1dd0a2fSth 	int			reset_ret;
1459e1dd0a2fSth 	int			ret_copy;
1460e1dd0a2fSth 	ns_standalone_conf_t	cfg = standaloneDefaults;
1461e1dd0a2fSth 	ns_auth_t		auth = {NS_LDAP_AUTH_NONE,
1462e1dd0a2fSth 					NS_LDAP_TLS_NONE,
1463e1dd0a2fSth 					NS_LDAP_SASL_NONE,
1464e1dd0a2fSth 					NS_LDAP_SASLOPT_NONE};
1465e1dd0a2fSth 	char			peer[MAX_HOSTADDR_LEN];
1466e1dd0a2fSth 	ns_auth_t		**authMethod;
1467e1dd0a2fSth 	int			**credLevel, i;
1468e1dd0a2fSth 	char			*cred;
14697c478bd9Sstevel@tonic-gate 
14707c478bd9Sstevel@tonic-gate 	if (mode_verbose)
14717c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
1472e1dd0a2fSth 		    gettext("About to configure machine by downloading "
1473e1dd0a2fSth 		    "a profile\n"),
1474e1dd0a2fSth 		    stderr);
14757c478bd9Sstevel@tonic-gate 
14767c478bd9Sstevel@tonic-gate 	if (dname == NULL) {
14777c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
1478e1dd0a2fSth 		    gettext("Init failed: System domain not set and "
1479e1dd0a2fSth 		    "no domainName specified.\n"),
1480e1dd0a2fSth 		    stderr);
14817c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
14827c478bd9Sstevel@tonic-gate 	}
14837c478bd9Sstevel@tonic-gate 
14847c478bd9Sstevel@tonic-gate 	if (!arglist->defaultServerList) {
14857c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Missing LDAP server address\n"), stderr);
14867c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
14877c478bd9Sstevel@tonic-gate 	}
14887c478bd9Sstevel@tonic-gate 
14897c478bd9Sstevel@tonic-gate 	/* *** Check for invalid args *** */
14907c478bd9Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->defaultSearchBase,
1491e1dd0a2fSth 	    "defaultSearchBase");
14927c478bd9Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->profileTTL,
1493e1dd0a2fSth 	    "profileTTL");
14947c478bd9Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->searchTimeLimit,
1495e1dd0a2fSth 	    "searchTimeLimit");
14967c478bd9Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->preferredServerList,
1497e1dd0a2fSth 	    "preferredServerList");
14987c478bd9Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->followReferrals,
1499e1dd0a2fSth 	    "followReferrals");
15007c478bd9Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->defaultSearchScope,
1501e1dd0a2fSth 	    "defaultSearchScope");
15027c478bd9Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->bindTimeLimit,
1503e1dd0a2fSth 	    "bindTimeLimit");
15047c478bd9Sstevel@tonic-gate 
15057c478bd9Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->objectclassMap->count,
1506e1dd0a2fSth 	    "objectclassMap");
15077c478bd9Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->attributeMap->count,
1508e1dd0a2fSth 	    "attributeMap");
15097c478bd9Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->serviceAuthenticationMethod->count,
1510e1dd0a2fSth 	    "serviceAuthenticationMethod");
15117c478bd9Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->serviceCredentialLevel->count,
1512e1dd0a2fSth 	    "serviceCredentialLevel");
15137c478bd9Sstevel@tonic-gate 	LDAP_CHECK_INVALID(arglist->serviceSearchDescriptor->count,
1514e1dd0a2fSth 	    "serviceSearchDescriptor");
15157c478bd9Sstevel@tonic-gate 	/* *** End check for invalid args *** */
15167c478bd9Sstevel@tonic-gate 
15177c478bd9Sstevel@tonic-gate 	if (arglist->profileName == NULL) {
15187c478bd9Sstevel@tonic-gate 		if (mode_verbose)
15197c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
1520e1dd0a2fSth 			    gettext("No profile specified. "
1521e1dd0a2fSth 			    "Using \"default\"\n"),
1522e1dd0a2fSth 			    stderr);
15237c478bd9Sstevel@tonic-gate 		arglist->profileName = "default";
15247c478bd9Sstevel@tonic-gate 	}
15257c478bd9Sstevel@tonic-gate 
1526e1dd0a2fSth 	(void) strncpy(peer, arglist->defaultServerList, MAX_HOSTADDR_LEN - 1);
1527e1dd0a2fSth 	if (separatePort(peer, &cfg.SA_SERVER, &cfg.SA_PORT) > 0) {
15287c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
15297c478bd9Sstevel@tonic-gate 	}
1530e1dd0a2fSth 
1531e1dd0a2fSth 	if (arglist->bindDN != NULL) {
1532e1dd0a2fSth 		cfg.SA_CRED = "proxy";
1533e1dd0a2fSth 		/*
1534e1dd0a2fSth 		 * We don't want to force users to always specify authentication
1535*dd1104fbSMichen Chang 		 * method when we can infer it. If users want SSL, he/she would
1536e1dd0a2fSth 		 * have to specify appropriate -a though.
1537e1dd0a2fSth 		 */
1538e1dd0a2fSth 		auth.type = NS_LDAP_AUTH_SIMPLE;
1539e1dd0a2fSth 		if (arglist->bindPasswd == NULL) {
1540e1dd0a2fSth 			arglist->bindPasswd =
1541e1dd0a2fSth 			    getpassphrase("Bind Password:");
1542e1dd0a2fSth 			if (arglist->bindPasswd == NULL) {
1543e1dd0a2fSth 				CLIENT_FPUTS(gettext("Get password failed\n"),
1544e1dd0a2fSth 				    stderr);
1545e1dd0a2fSth 
1546e1dd0a2fSth 				if (gStartLdap == START_RESET)
1547e1dd0a2fSth 					(void) start_service(LDAP_FMRI, B_TRUE);
1548e1dd0a2fSth 
1549e1dd0a2fSth 				return (CLIENT_ERR_CREDENTIAL);
1550e1dd0a2fSth 			}
1551e1dd0a2fSth 		}
15527c478bd9Sstevel@tonic-gate 	}
1553e1dd0a2fSth 	cfg.SA_BIND_DN = arglist->bindDN;
1554e1dd0a2fSth 	cfg.SA_BIND_PWD = arglist->bindPasswd;
15557c478bd9Sstevel@tonic-gate 
1556e1dd0a2fSth 	if (arglist->authenticationMethod != NULL) {
1557e1dd0a2fSth 		if (__ns_ldap_initAuth(arglist->authenticationMethod,
1558e1dd0a2fSth 		    &auth, &errorp) != NS_LDAP_SUCCESS) {
1559e1dd0a2fSth 			if (errorp != NULL) {
1560e1dd0a2fSth 				CLIENT_FPRINTF(stderr, "%s", errorp->message);
1561e1dd0a2fSth 				(void) __ns_ldap_freeError(&errorp);
1562e1dd0a2fSth 			}
1563e1dd0a2fSth 
1564e1dd0a2fSth 			if (gStartLdap == START_RESET)
1565e1dd0a2fSth 				(void) start_service(LDAP_FMRI, B_TRUE);
1566e1dd0a2fSth 
1567e1dd0a2fSth 			return (CLIENT_ERR_FAIL);
1568e1dd0a2fSth 		}
1569e1dd0a2fSth 		cfg.SA_AUTH = &auth;
15707c478bd9Sstevel@tonic-gate 	}
1571e1dd0a2fSth 	cfg.SA_CRED = arglist->credentialLevel;
15727c478bd9Sstevel@tonic-gate 
1573e1dd0a2fSth 	cfg.SA_DOMAIN = arglist->domainName;
1574e1dd0a2fSth 	cfg.SA_PROFILE_NAME = arglist->profileName;
1575e1dd0a2fSth 	cfg.SA_CERT_PATH = arglist->certificatePath;
1576e1dd0a2fSth 
1577e1dd0a2fSth 	cfg.type = NS_LDAP_SERVER;
1578e1dd0a2fSth 
1579e1dd0a2fSth 	if (__ns_ldap_initStandalone(&cfg, &errorp) != NS_LDAP_SUCCESS) {
15807c478bd9Sstevel@tonic-gate 		if (errorp != NULL) {
1581e1dd0a2fSth 			CLIENT_FPRINTF(stderr, "%s", errorp->message);
15827c478bd9Sstevel@tonic-gate 			(void) __ns_ldap_freeError(&errorp);
15837c478bd9Sstevel@tonic-gate 		}
15847c478bd9Sstevel@tonic-gate 
15857c478bd9Sstevel@tonic-gate 		if (gStartLdap == START_RESET)
15867c478bd9Sstevel@tonic-gate 			(void) start_service(LDAP_FMRI, B_TRUE);
15877c478bd9Sstevel@tonic-gate 
15887c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
15897c478bd9Sstevel@tonic-gate 	}
15907c478bd9Sstevel@tonic-gate 
1591e1dd0a2fSth 	if (arglist->proxyDN != NULL && arglist->proxyPassword == NULL) {
1592e1dd0a2fSth 		arglist->proxyPassword = getpassphrase("Proxy Bind Password:");
1593e1dd0a2fSth 		if (arglist->proxyPassword == NULL) {
1594e1dd0a2fSth 			CLIENT_FPUTS(gettext("Get password failed\n"), stderr);
1595e1dd0a2fSth 
1596e1dd0a2fSth 			if (gStartLdap == START_RESET)
1597e1dd0a2fSth 				(void) start_service(LDAP_FMRI, B_TRUE);
1598e1dd0a2fSth 
1599e1dd0a2fSth 			return (CLIENT_ERR_CREDENTIAL);
1600e1dd0a2fSth 		}
16017c478bd9Sstevel@tonic-gate 	}
1602e1dd0a2fSth 	if (arglist->proxyDN != NULL && arglist->proxyPassword != NULL) {
1603e1dd0a2fSth 		if (__ns_ldap_setParam(NS_LDAP_BINDDN_P,
1604e1dd0a2fSth 		    arglist->proxyDN, &errorp) != NS_LDAP_SUCCESS) {
1605e1dd0a2fSth 			if (errorp != NULL) {
1606e1dd0a2fSth 				CLIENT_FPRINTF(stderr, "%s", errorp->message);
1607e1dd0a2fSth 				(void) __ns_ldap_freeError(&errorp);
1608e1dd0a2fSth 			}
1609e1dd0a2fSth 			return (CLIENT_ERR_CREDENTIAL);
1610e1dd0a2fSth 		}
1611e1dd0a2fSth 		if (__ns_ldap_setParam(NS_LDAP_BINDPASSWD_P,
1612e1dd0a2fSth 		    arglist->proxyPassword, &errorp) != NS_LDAP_SUCCESS) {
1613e1dd0a2fSth 			if (errorp != NULL) {
1614e1dd0a2fSth 				CLIENT_FPRINTF(stderr, "%s", errorp->message);
1615e1dd0a2fSth 				(void) __ns_ldap_freeError(&errorp);
1616e1dd0a2fSth 			}
1617e1dd0a2fSth 			return (CLIENT_ERR_CREDENTIAL);
1618e1dd0a2fSth 		}
1619e1dd0a2fSth 	}
1620e1dd0a2fSth 
1621*dd1104fbSMichen Chang 	if (arglist->enableShadowUpdate != NULL) {
1622*dd1104fbSMichen Chang 		LDAP_SET_PARAM(arglist->enableShadowUpdate,
1623*dd1104fbSMichen Chang 		    NS_LDAP_ENABLE_SHADOW_UPDATE_P);
1624*dd1104fbSMichen Chang 	}
1625*dd1104fbSMichen Chang 
1626*dd1104fbSMichen Chang 	if (arglist->enableShadowUpdate &&
1627*dd1104fbSMichen Chang 	    strcasecmp(arglist->enableShadowUpdate, "TRUE") == 0 &&
1628*dd1104fbSMichen Chang 	    arglist->adminDN != NULL && arglist->adminPassword == NULL) {
1629*dd1104fbSMichen Chang 		arglist->adminPassword = getpassphrase("admin Bind Password:");
1630*dd1104fbSMichen Chang 		if (arglist->adminPassword == NULL) {
1631*dd1104fbSMichen Chang 			CLIENT_FPUTS(gettext("Get password failed\n"), stderr);
1632*dd1104fbSMichen Chang 
1633*dd1104fbSMichen Chang 			if (gStartLdap == START_RESET)
1634*dd1104fbSMichen Chang 				(void) start_service(LDAP_FMRI, B_TRUE);
1635*dd1104fbSMichen Chang 
1636*dd1104fbSMichen Chang 			return (CLIENT_ERR_CREDENTIAL);
1637*dd1104fbSMichen Chang 		}
1638*dd1104fbSMichen Chang 	}
1639*dd1104fbSMichen Chang 	if (arglist->adminDN != NULL && arglist->adminPassword != NULL) {
1640*dd1104fbSMichen Chang 		if (__ns_ldap_setParam(NS_LDAP_ADMIN_BINDDN_P,
1641*dd1104fbSMichen Chang 		    arglist->adminDN, &errorp) != NS_LDAP_SUCCESS) {
1642*dd1104fbSMichen Chang 			if (errorp != NULL) {
1643*dd1104fbSMichen Chang 				CLIENT_FPRINTF(stderr, "%s\n", errorp->message);
1644*dd1104fbSMichen Chang 				(void) __ns_ldap_freeError(&errorp);
1645*dd1104fbSMichen Chang 			}
1646*dd1104fbSMichen Chang 			return (CLIENT_ERR_CREDENTIAL);
1647*dd1104fbSMichen Chang 		}
1648*dd1104fbSMichen Chang 		if (__ns_ldap_setParam(NS_LDAP_ADMIN_BINDPASSWD_P,
1649*dd1104fbSMichen Chang 		    arglist->adminPassword, &errorp) != NS_LDAP_SUCCESS) {
1650*dd1104fbSMichen Chang 			if (errorp != NULL) {
1651*dd1104fbSMichen Chang 				CLIENT_FPRINTF(stderr, "%s\n", errorp->message);
1652*dd1104fbSMichen Chang 				(void) __ns_ldap_freeError(&errorp);
1653*dd1104fbSMichen Chang 			}
1654*dd1104fbSMichen Chang 			return (CLIENT_ERR_CREDENTIAL);
1655*dd1104fbSMichen Chang 		}
1656*dd1104fbSMichen Chang 	}
1657*dd1104fbSMichen Chang 
1658e1dd0a2fSth 	if (arglist->authenticationMethod != NULL) {
1659e1dd0a2fSth 		if (__ns_ldap_getParam(NS_LDAP_AUTH_P,
1660e1dd0a2fSth 		    (void ***)&authMethod, &errorp) != NS_LDAP_SUCCESS) {
1661e1dd0a2fSth 			if (errorp != NULL) {
1662e1dd0a2fSth 				CLIENT_FPRINTF(stderr, "%s", errorp->message);
1663e1dd0a2fSth 				(void) __ns_ldap_freeError(&errorp);
1664e1dd0a2fSth 			}
1665e1dd0a2fSth 			return (CLIENT_ERR_CREDENTIAL);
1666e1dd0a2fSth 		}
1667e1dd0a2fSth 
1668e1dd0a2fSth 		if (authMethod != NULL) {
1669e1dd0a2fSth 			for (i = 0; authMethod[i] != NULL; ++i) {
1670e1dd0a2fSth 				if (authMethod[i]->type == auth.type) {
1671e1dd0a2fSth 					break;
1672e1dd0a2fSth 				}
1673e1dd0a2fSth 			}
1674e1dd0a2fSth 
1675e1dd0a2fSth 			if (authMethod[i] == NULL) {
1676e1dd0a2fSth 				CLIENT_FPRINTF(stderr, gettext(
1677e1dd0a2fSth 				    "Warning: init authentication method "
1678e1dd0a2fSth 				    "not found in DUAConfigProfile.\n"));
1679e1dd0a2fSth 			} else {
1680e1dd0a2fSth 				if (i != 0) {
1681e1dd0a2fSth 					CLIENT_FPRINTF(stderr,
1682e1dd0a2fSth 					    gettext(
1683e1dd0a2fSth 					    "Warning: init authentication"
1684e1dd0a2fSth 					    "method using secondary "
1685e1dd0a2fSth 					    "authentication method from "
1686e1dd0a2fSth 					    "DUAConfigProfile.\n"));
1687e1dd0a2fSth 				}
1688e1dd0a2fSth 			}
1689e1dd0a2fSth 			(void) __ns_ldap_freeParam((void ***) &authMethod);
1690e1dd0a2fSth 		}
1691e1dd0a2fSth 	}
1692e1dd0a2fSth 
1693e1dd0a2fSth 	if (arglist->credentialLevel != NULL) {
1694e1dd0a2fSth 		if (__ns_ldap_getParam(NS_LDAP_CREDENTIAL_LEVEL_P,
1695e1dd0a2fSth 		    (void ***)&credLevel, &errorp) != NS_LDAP_SUCCESS) {
1696e1dd0a2fSth 			if (errorp != NULL) {
1697e1dd0a2fSth 				CLIENT_FPRINTF(stderr, "%s", errorp->message);
1698e1dd0a2fSth 				(void) __ns_ldap_freeError(&errorp);
1699e1dd0a2fSth 			}
1700e1dd0a2fSth 			return (CLIENT_ERR_CREDENTIAL);
1701e1dd0a2fSth 		}
1702e1dd0a2fSth 		if (credLevel != NULL) {
1703e1dd0a2fSth 			for (i = 0; credLevel[i] != NULL; ++i) {
1704e1dd0a2fSth 				switch (*credLevel[i]) {
1705e1dd0a2fSth 				case NS_LDAP_CRED_ANON :
1706e1dd0a2fSth 					cred = "none";
1707e1dd0a2fSth 					break;
1708e1dd0a2fSth 				case NS_LDAP_CRED_PROXY :
1709e1dd0a2fSth 					cred = "proxy";
1710e1dd0a2fSth 					break;
1711e1dd0a2fSth 				case NS_LDAP_CRED_SELF :
1712e1dd0a2fSth 					cred = "self";
1713e1dd0a2fSth 					break;
1714e1dd0a2fSth 				default:
1715e1dd0a2fSth 					continue;
1716e1dd0a2fSth 					break;
1717e1dd0a2fSth 				}
1718e1dd0a2fSth 				if (strcmp(cred,
1719e1dd0a2fSth 				    arglist->credentialLevel) == 0) {
1720e1dd0a2fSth 					break;
1721e1dd0a2fSth 				}
1722e1dd0a2fSth 			}
1723e1dd0a2fSth 			if (credLevel[i] == NULL) {
1724e1dd0a2fSth 				CLIENT_FPRINTF(stderr, gettext(
1725e1dd0a2fSth 				    "Warning: init credential level not found "
1726e1dd0a2fSth 				    "in DUAConfigProfile.\n"));
1727e1dd0a2fSth 			} else {
1728e1dd0a2fSth 				if (i != 0) {
1729e1dd0a2fSth 					CLIENT_FPRINTF(stderr,
1730e1dd0a2fSth 					    gettext("Warning: "
1731e1dd0a2fSth 					    "init credential level using "
1732e1dd0a2fSth 					    "secondary credential level from "
1733e1dd0a2fSth 					    "DUAConfigProfile.\n"));
1734e1dd0a2fSth 				}
1735e1dd0a2fSth 			}
1736e1dd0a2fSth 			(void) __ns_ldap_freeParam((void ***) &credLevel);
1737e1dd0a2fSth 		}
17387c478bd9Sstevel@tonic-gate 	}
17397c478bd9Sstevel@tonic-gate 
17407c478bd9Sstevel@tonic-gate 	retcode = credCheck(arglist);
1741*dd1104fbSMichen Chang 	if (retcode == CLIENT_SUCCESS)
1742*dd1104fbSMichen Chang 		retcode = adminCredCheck(arglist);
17437c478bd9Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
17447c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
1745e1dd0a2fSth 		    gettext("Error in setting up credentials\n"), stderr);
17467c478bd9Sstevel@tonic-gate 
17477c478bd9Sstevel@tonic-gate 		if (gStartLdap == START_RESET)
17487c478bd9Sstevel@tonic-gate 			(void) start_service(LDAP_FMRI, B_TRUE);
17497c478bd9Sstevel@tonic-gate 
17507c478bd9Sstevel@tonic-gate 		return (retcode);
17517c478bd9Sstevel@tonic-gate 	}
17527c478bd9Sstevel@tonic-gate 
17537c478bd9Sstevel@tonic-gate 	if (mode_verbose)
17547c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
1755e1dd0a2fSth 		    gettext("About to modify this machines configuration "
1756e1dd0a2fSth 		    "by writing the files\n"),
1757e1dd0a2fSth 		    stderr);
17587c478bd9Sstevel@tonic-gate 
17597c478bd9Sstevel@tonic-gate 	/* get ready to start playing with files */
17607c478bd9Sstevel@tonic-gate 	retcode = stop_services(STATE_SAVE);
17617c478bd9Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS) {
17627c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
1763e1dd0a2fSth 		    gettext("Errors stopping network services.\n"), stderr);
17647c478bd9Sstevel@tonic-gate 
17657c478bd9Sstevel@tonic-gate 		if (gStartLdap == START_RESET)
17667c478bd9Sstevel@tonic-gate 			(void) start_service(LDAP_FMRI, B_TRUE);
17677c478bd9Sstevel@tonic-gate 
17687c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
17697c478bd9Sstevel@tonic-gate 	}
17707c478bd9Sstevel@tonic-gate 
17717c478bd9Sstevel@tonic-gate 	/* Save orig versions of files */
17727c478bd9Sstevel@tonic-gate 	retcode = file_backup();
17737c478bd9Sstevel@tonic-gate 	if (retcode == CLIENT_ERR_RESTORE) {
17747c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
1775e1dd0a2fSth 		    gettext("System not in state to enable ldap client.\n"),
1776e1dd0a2fSth 		    stderr);
17777c478bd9Sstevel@tonic-gate 
17787c478bd9Sstevel@tonic-gate 		return (retcode);
17797c478bd9Sstevel@tonic-gate 
17807c478bd9Sstevel@tonic-gate 	} else if (retcode != CLIENT_SUCCESS) {
17817c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
1782e1dd0a2fSth 		    gettext("Save of system configuration failed.  "
1783e1dd0a2fSth 		    "Attempting recovery.\n"),
1784e1dd0a2fSth 		    stderr);
17857c478bd9Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
17867c478bd9Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
17877c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
1788e1dd0a2fSth 			    gettext("Recovery of systems configuration "
1789e1dd0a2fSth 			    "failed.  Manual intervention of "
1790e1dd0a2fSth 			    "config files is required.\n"),
1791e1dd0a2fSth 			    stderr);
17927c478bd9Sstevel@tonic-gate 		}
17937c478bd9Sstevel@tonic-gate 
17947c478bd9Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
17957c478bd9Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
17967c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1797e1dd0a2fSth 			    "starting services during reset\n"),
1798e1dd0a2fSth 			    reset_ret);
17997c478bd9Sstevel@tonic-gate 		}
18007c478bd9Sstevel@tonic-gate 
18017c478bd9Sstevel@tonic-gate 		return (retcode);
18027c478bd9Sstevel@tonic-gate 	}
18037c478bd9Sstevel@tonic-gate 
18047c478bd9Sstevel@tonic-gate 	/* Dump new files */
18057c478bd9Sstevel@tonic-gate 	errorp = __ns_ldap_DumpConfiguration(NSCONFIGFILE);
18067c478bd9Sstevel@tonic-gate 	if (NULL != errorp) {
18077c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
1808e1dd0a2fSth 		    gettext("%s init: errorp is not NULL; %s\n"),
1809e1dd0a2fSth 		    cmd, errorp->message);
18107c478bd9Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
18117c478bd9Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
18127c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
1813e1dd0a2fSth 			    gettext("Recovery of systems configuration "
1814e1dd0a2fSth 			    "failed.  Manual intervention of "
1815e1dd0a2fSth 			    "config files is required.\n"),
1816e1dd0a2fSth 			    stderr);
18177c478bd9Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
18187c478bd9Sstevel@tonic-gate 		}
18197c478bd9Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
18207c478bd9Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
18217c478bd9Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
18227c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1823e1dd0a2fSth 			    "starting services during reset\n"),
1824e1dd0a2fSth 			    reset_ret);
18257c478bd9Sstevel@tonic-gate 		}
18267c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
18277c478bd9Sstevel@tonic-gate 	}
18287c478bd9Sstevel@tonic-gate 
18297c478bd9Sstevel@tonic-gate 	/* if (credargs(arglist)) */
18307c478bd9Sstevel@tonic-gate 	errorp = __ns_ldap_DumpConfiguration(NSCREDFILE);
18317c478bd9Sstevel@tonic-gate 	if (NULL != errorp) {
18327c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
1833e1dd0a2fSth 		    gettext("%s init: errorp is not NULL; %s\n"),
1834e1dd0a2fSth 		    cmd, errorp->message);
18357c478bd9Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
18367c478bd9Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
18377c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
1838e1dd0a2fSth 			    gettext("Recovery of systems configuration "
1839e1dd0a2fSth 			    "failed.  Manual intervention of "
1840e1dd0a2fSth 			    "config files is required.\n"),
1841e1dd0a2fSth 			    stderr);
18427c478bd9Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
18437c478bd9Sstevel@tonic-gate 		}
18447c478bd9Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
18457c478bd9Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
18467c478bd9Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
18477c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1848e1dd0a2fSth 			    "starting services during reset\n"),
1849e1dd0a2fSth 			    reset_ret);
18507c478bd9Sstevel@tonic-gate 		}
18517c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
18527c478bd9Sstevel@tonic-gate 	}
18537c478bd9Sstevel@tonic-gate 
18547c478bd9Sstevel@tonic-gate 	ret_copy = system(CMD_CP " " NSSWITCH_LDAP " " NSSWITCH_CONF);
18557c478bd9Sstevel@tonic-gate 	if (ret_copy != 0) {
18567c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
1857e1dd0a2fSth 		    gettext("Error %d copying (%s) -> (%s)\n"),
1858e1dd0a2fSth 		    ret_copy, NSSWITCH_LDAP, NSSWITCH_CONF);
18597c478bd9Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
18607c478bd9Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
18617c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
1862e1dd0a2fSth 			    gettext("Recovery of systems configuration "
1863e1dd0a2fSth 			    "failed.  Manual intervention of "
1864e1dd0a2fSth 			    "config files is required.\n"),
1865e1dd0a2fSth 			    stderr);
18667c478bd9Sstevel@tonic-gate 		}
18677c478bd9Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
18687c478bd9Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
18697c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1870e1dd0a2fSth 			    "starting services during reset\n"),
1871e1dd0a2fSth 			    reset_ret);
18727c478bd9Sstevel@tonic-gate 		}
18737c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
18747c478bd9Sstevel@tonic-gate 	}
18757c478bd9Sstevel@tonic-gate 
18767c478bd9Sstevel@tonic-gate 	if ((profile_fp = open(DOMAINNAME, O_WRONLY|O_CREAT|O_TRUNC,
1877e1dd0a2fSth 	    S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) { /* 0644 */
18787c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr, gettext("Cannot open %s\n"), DOMAINNAME);
18797c478bd9Sstevel@tonic-gate 		retcode = recover(STATE_NOSAVE);
18807c478bd9Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
18817c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
1882e1dd0a2fSth 			    gettext("Recovery of systems configuration "
1883e1dd0a2fSth 			    "failed.  Manual intervention of "
1884e1dd0a2fSth 			    "config files is required.\n"),
1885e1dd0a2fSth 			    stderr);
18867c478bd9Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
18877c478bd9Sstevel@tonic-gate 		}
18887c478bd9Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
18897c478bd9Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
18907c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1891e1dd0a2fSth 			    "starting services during reset\n"),
1892e1dd0a2fSth 			    reset_ret);
18937c478bd9Sstevel@tonic-gate 		}
18947c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
18957c478bd9Sstevel@tonic-gate 	}
18967c478bd9Sstevel@tonic-gate 	(void) write(profile_fp, dname, strlen(dname));
18977c478bd9Sstevel@tonic-gate 	(void) write(profile_fp, "\n", 1);
18987c478bd9Sstevel@tonic-gate 	(void) close(profile_fp);
18997c478bd9Sstevel@tonic-gate 
19007c478bd9Sstevel@tonic-gate 	retcode = start_services(START_INIT);
19017c478bd9Sstevel@tonic-gate 
19027c478bd9Sstevel@tonic-gate 	if (retcode == CLIENT_SUCCESS) {
19037c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("System successfully configured\n"),
1904e1dd0a2fSth 		    stderr);
19057c478bd9Sstevel@tonic-gate 	} else {
19067c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error resetting system.\n"
1907e1dd0a2fSth 		    "Recovering old system settings.\n"), stderr),
19087c478bd9Sstevel@tonic-gate 
1909e1dd0a2fSth 		    /* stop any started services for recover */
1910e1dd0a2fSth 		    /* don't stomp on history of saved services state */
1911e1dd0a2fSth 		    reset_ret = stop_services(STATE_NOSAVE);
19127c478bd9Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
19137c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1914e1dd0a2fSth 			    "stopping services during reset\n"),
1915e1dd0a2fSth 			    reset_ret);
19167c478bd9Sstevel@tonic-gate 			/* Coninue and try to recover what we can */
19177c478bd9Sstevel@tonic-gate 		}
19187c478bd9Sstevel@tonic-gate 		reset_ret = recover(STATE_NOSAVE);
19197c478bd9Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
19207c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1921e1dd0a2fSth 			    "recovering service files during "
1922e1dd0a2fSth 			    "reset\n"), reset_ret);
19237c478bd9Sstevel@tonic-gate 			/* Continue and start what we can */
19247c478bd9Sstevel@tonic-gate 		}
19257c478bd9Sstevel@tonic-gate 		reset_ret = start_services(START_RESET);
19267c478bd9Sstevel@tonic-gate 		if (reset_ret != CLIENT_SUCCESS) {
19277c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
1928e1dd0a2fSth 			    "starting services during reset\n"),
1929e1dd0a2fSth 			    reset_ret);
19307c478bd9Sstevel@tonic-gate 		}
19317c478bd9Sstevel@tonic-gate 	}
19327c478bd9Sstevel@tonic-gate 
19337c478bd9Sstevel@tonic-gate 	return (retcode);
19347c478bd9Sstevel@tonic-gate }
19357c478bd9Sstevel@tonic-gate 
19367c478bd9Sstevel@tonic-gate 
19377c478bd9Sstevel@tonic-gate static void
19387c478bd9Sstevel@tonic-gate usage(void)
19397c478bd9Sstevel@tonic-gate {
19407c478bd9Sstevel@tonic-gate 	if (mode_quiet)
19417c478bd9Sstevel@tonic-gate 		return;
19427c478bd9Sstevel@tonic-gate 
19437c478bd9Sstevel@tonic-gate 	if (gen == 0) {
19447c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
1945e1dd0a2fSth 		    gettext("Usage: %s [-v | -q] init | manual | mod | "
1946e1dd0a2fSth 		    "list | uninit [<args>]\n"),
1947e1dd0a2fSth 		    cmd);
1948e1dd0a2fSth 
1949e1dd0a2fSth 		CLIENT_FPRINTF(stderr,
1950e1dd0a2fSth 		    gettext("\n       %s [-v | -q] [-a authenticationMethod]"
1951e1dd0a2fSth 		    " [-D bindDN]\n\t[-w bindPassword] [-j passswdFile]"
1952*dd1104fbSMichen Chang 		    " [-y proxyPasswordFile]\n\t"
1953*dd1104fbSMichen Chang 		    "[-z adminPasswordFile] init [<args>]\n"),
1954e1dd0a2fSth 		    cmd);
19557c478bd9Sstevel@tonic-gate 
19567c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
1957e1dd0a2fSth 		    gettext("\nSet up a server or workstation as a "
1958e1dd0a2fSth 		    "client of an LDAP namespace.\n"),
1959e1dd0a2fSth 		    stderr);
19607c478bd9Sstevel@tonic-gate 	} else {	/* genprofile */
19617c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
1962e1dd0a2fSth 		    gettext("Usage: %s [-v | -q] genprofile "
1963e1dd0a2fSth 		    "-a profileName=<name> "
1964e1dd0a2fSth 		    "-a defaultSearchBase=<base> <args>\n"),
1965e1dd0a2fSth 		    cmd);
19667c478bd9Sstevel@tonic-gate 
19677c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
1968e1dd0a2fSth 		    gettext("\nGenerate a profile used to set up clients "
1969e1dd0a2fSth 		    "of an LDAP namespace.\n"),
1970e1dd0a2fSth 		    stderr);
19717c478bd9Sstevel@tonic-gate 	}
19727c478bd9Sstevel@tonic-gate 	CLIENT_FPUTS(
1973e1dd0a2fSth 	    gettext("<args> take the form of \'-a attrName=attrVal\' as "
1974e1dd0a2fSth 	    "described in the\n"),
1975e1dd0a2fSth 	    stderr);
19767c478bd9Sstevel@tonic-gate 	CLIENT_FPUTS(gettext("man page: ldapclient(1M)\n"), stderr);
19777c478bd9Sstevel@tonic-gate }
19787c478bd9Sstevel@tonic-gate 
19797c478bd9Sstevel@tonic-gate 
19807c478bd9Sstevel@tonic-gate /*
19817c478bd9Sstevel@tonic-gate  * stop_services is called to stop network services prior to their
19827c478bd9Sstevel@tonic-gate  * config files being moved/changed.  In case a later recovery is needed
19837c478bd9Sstevel@tonic-gate  * (an error occurs during config), we detect whether the service is
19847c478bd9Sstevel@tonic-gate  * running and store that info so that a reset will only start services
19857c478bd9Sstevel@tonic-gate  * that were stopped here.
19867c478bd9Sstevel@tonic-gate  *
19877c478bd9Sstevel@tonic-gate  * In terms of SMF, this translates to disabling the services. So we
19887c478bd9Sstevel@tonic-gate  * try to disable them if they are in any other state
19897c478bd9Sstevel@tonic-gate  *
19907c478bd9Sstevel@tonic-gate  * Stop order :
19917c478bd9Sstevel@tonic-gate  * sendmail, nscd, autofs, ldap.client, nisd (rpc), inetinit(domainname)
19927c478bd9Sstevel@tonic-gate  */
19937c478bd9Sstevel@tonic-gate static int
19947c478bd9Sstevel@tonic-gate stop_services(int saveState)
19957c478bd9Sstevel@tonic-gate {
19967c478bd9Sstevel@tonic-gate 	int ret;
19977c478bd9Sstevel@tonic-gate 
19987c478bd9Sstevel@tonic-gate 	if (mode_verbose) {
19997c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Stopping network services\n"), stderr);
20007c478bd9Sstevel@tonic-gate 	}
20017c478bd9Sstevel@tonic-gate 
20027c478bd9Sstevel@tonic-gate 	if (!is_service(SENDMAIL_FMRI, SCF_STATE_STRING_DISABLED)) {
20037c478bd9Sstevel@tonic-gate 		if (mode_verbose)
20047c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Stopping sendmail\n"), stderr);
20057c478bd9Sstevel@tonic-gate 		ret = disable_service(SENDMAIL_FMRI, B_TRUE);
20067c478bd9Sstevel@tonic-gate 		if (ret != CLIENT_SUCCESS) {
20077c478bd9Sstevel@tonic-gate 			/* Not serious, but tell user what to do */
20087c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Stopping sendmail "
2009e1dd0a2fSth 			    "failed with (%d). You may need to restart "
2010e1dd0a2fSth 			    "it manually for changes to take effect.\n"),
2011e1dd0a2fSth 			    ret);
20127c478bd9Sstevel@tonic-gate 		} else enableFlag |= SENDMAIL_ON;
20137c478bd9Sstevel@tonic-gate 	} else {
20147c478bd9Sstevel@tonic-gate 		if (mode_verbose)
20157c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("sendmail not running\n"), stderr);
20167c478bd9Sstevel@tonic-gate 	}
20177c478bd9Sstevel@tonic-gate 
20187c478bd9Sstevel@tonic-gate 	if (!is_service(NSCD_FMRI, SCF_STATE_STRING_DISABLED)) {
20197c478bd9Sstevel@tonic-gate 		if (mode_verbose)
20207c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Stopping nscd\n"), stderr);
20217c478bd9Sstevel@tonic-gate 		ret = disable_service(NSCD_FMRI, B_TRUE);
20227c478bd9Sstevel@tonic-gate 		if (ret != CLIENT_SUCCESS) {
20237c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Stopping nscd "
20247c478bd9Sstevel@tonic-gate 			    "failed with (%d)\n"), ret);
20257c478bd9Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
20267c478bd9Sstevel@tonic-gate 		} else enableFlag |= NSCD_ON;
20277c478bd9Sstevel@tonic-gate 	} else {
20287c478bd9Sstevel@tonic-gate 		if (mode_verbose)
20297c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("nscd not running\n"), stderr);
20307c478bd9Sstevel@tonic-gate 	}
20317c478bd9Sstevel@tonic-gate 
20327c478bd9Sstevel@tonic-gate 	if (!is_service(AUTOFS_FMRI, SCF_STATE_STRING_DISABLED)) {
20337c478bd9Sstevel@tonic-gate 		if (mode_verbose)
20347c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Stopping autofs\n"), stderr);
20357c478bd9Sstevel@tonic-gate 		ret = disable_service(AUTOFS_FMRI, B_TRUE);
20367c478bd9Sstevel@tonic-gate 		if (ret != CLIENT_SUCCESS) {
20377c478bd9Sstevel@tonic-gate 			/* Not serious, but tell user what to do */
20387c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Stopping autofs "
2039e1dd0a2fSth 			    "failed with (%d). You may need to restart "
2040e1dd0a2fSth 			    "it manually for changes to take effect.\n"),
2041e1dd0a2fSth 			    ret);
20427c478bd9Sstevel@tonic-gate 		} else enableFlag |= AUTOFS_ON;
20437c478bd9Sstevel@tonic-gate 	} else {
20447c478bd9Sstevel@tonic-gate 		if (mode_verbose)
20457c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("autofs not running\n"), stderr);
20467c478bd9Sstevel@tonic-gate 	}
20477c478bd9Sstevel@tonic-gate 
20487c478bd9Sstevel@tonic-gate 	if (!is_service(LDAP_FMRI, SCF_STATE_STRING_DISABLED)) {
20497c478bd9Sstevel@tonic-gate 		if (saveState)
20507c478bd9Sstevel@tonic-gate 			gStartLdap = START_RESET;
20517c478bd9Sstevel@tonic-gate 		if (mode_verbose)
20527c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Stopping ldap\n"), stderr);
20537c478bd9Sstevel@tonic-gate 		ret = disable_service(LDAP_FMRI, B_TRUE);
20547c478bd9Sstevel@tonic-gate 		if (ret != CLIENT_SUCCESS) {
20557c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Stopping ldap "
20567c478bd9Sstevel@tonic-gate 			    "failed with (%d)\n"), ret);
20577c478bd9Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
20587c478bd9Sstevel@tonic-gate 		}
20597c478bd9Sstevel@tonic-gate 	} else {
20607c478bd9Sstevel@tonic-gate 		if (mode_verbose)
20617c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("ldap not running\n"),
2062e1dd0a2fSth 			    stderr);
20637c478bd9Sstevel@tonic-gate 	}
20647c478bd9Sstevel@tonic-gate 
20657c478bd9Sstevel@tonic-gate 	if (!is_service(NISD_FMRI, SCF_STATE_STRING_DISABLED)) {
20667c478bd9Sstevel@tonic-gate 		if (mode_verbose)
20677c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Stopping nisd\n"), stderr);
20687c478bd9Sstevel@tonic-gate 		ret = disable_service(NISD_FMRI, B_TRUE);
20697c478bd9Sstevel@tonic-gate 		if (ret != CLIENT_SUCCESS) {
20707c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Stopping nisd "
20717c478bd9Sstevel@tonic-gate 			    "failed with (%d)\n"), ret);
20727c478bd9Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
20737c478bd9Sstevel@tonic-gate 		}
20747c478bd9Sstevel@tonic-gate 	} else {
20757c478bd9Sstevel@tonic-gate 		if (mode_verbose)
20767c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("nisd not running\n"),
2077e1dd0a2fSth 			    stderr);
20787c478bd9Sstevel@tonic-gate 	}
20797c478bd9Sstevel@tonic-gate 
20807c478bd9Sstevel@tonic-gate 	if (!is_service(YP_FMRI, SCF_STATE_STRING_DISABLED)) {
20817c478bd9Sstevel@tonic-gate 		if (saveState)
20827c478bd9Sstevel@tonic-gate 			gStartYp = START_RESET;
20837c478bd9Sstevel@tonic-gate 		if (mode_verbose)
20847c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Stopping nis(yp)\n"), stderr);
20857c478bd9Sstevel@tonic-gate 		ret = disable_service(YP_FMRI, B_TRUE);
20867c478bd9Sstevel@tonic-gate 		if (ret != 0) {
20877c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("Stopping nis(yp) "
20887c478bd9Sstevel@tonic-gate 			    "failed with (%d)\n"), ret);
20897c478bd9Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
20907c478bd9Sstevel@tonic-gate 		}
20917c478bd9Sstevel@tonic-gate 	} else {
20927c478bd9Sstevel@tonic-gate 		if (mode_verbose)
20937c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("nis(yp) not running\n"),
2094e1dd0a2fSth 			    stderr);
20957c478bd9Sstevel@tonic-gate 	}
20967c478bd9Sstevel@tonic-gate 
20977c478bd9Sstevel@tonic-gate 	return (CLIENT_SUCCESS);
20987c478bd9Sstevel@tonic-gate }
20997c478bd9Sstevel@tonic-gate 
21007c478bd9Sstevel@tonic-gate /*
21017c478bd9Sstevel@tonic-gate  * start_services is called to start up network services after config
21027c478bd9Sstevel@tonic-gate  * files have all been setup or recovered.  In the case of an error, the
21037c478bd9Sstevel@tonic-gate  * files will be recovered and start_services will be called with the
21047c478bd9Sstevel@tonic-gate  * "reset" flag set so that only those services that were earlier stopped
21057c478bd9Sstevel@tonic-gate  * will be started.  If it is not a reset, then the services associated
21067c478bd9Sstevel@tonic-gate  * with files "recovered" will attempt to be started.
21077c478bd9Sstevel@tonic-gate  */
21087c478bd9Sstevel@tonic-gate static int
21097c478bd9Sstevel@tonic-gate start_services(int flag)
21107c478bd9Sstevel@tonic-gate {
2111cb5caa98Sdjl 	int sysret, retcode = CLIENT_SUCCESS, rc = NS_LDAP_SUCCESS;
21127c478bd9Sstevel@tonic-gate 	FILE *domain_fp;
21137c478bd9Sstevel@tonic-gate 	char domainname[BUFSIZ];
21147c478bd9Sstevel@tonic-gate 	char cmd_domain_start[BUFSIZ];
21157c478bd9Sstevel@tonic-gate 	int domainlen;
2116cb5caa98Sdjl 	ns_ldap_self_gssapi_config_t config = NS_LDAP_SELF_GSSAPI_CONFIG_NONE;
2117cb5caa98Sdjl 	ns_ldap_error_t		*errorp = NULL;
21187c478bd9Sstevel@tonic-gate 
21197c478bd9Sstevel@tonic-gate 	if (mode_verbose) {
21207c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Starting network services\n"), stderr);
21217c478bd9Sstevel@tonic-gate 	}
21227c478bd9Sstevel@tonic-gate 
21237c478bd9Sstevel@tonic-gate 	/* Read in current defaultdomain so we can set it */
21247c478bd9Sstevel@tonic-gate 	domain_fp = fopen(DOMAINNAME, "r");
21257c478bd9Sstevel@tonic-gate 	if (domain_fp == NULL) {
21267c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr, gettext("Error opening defaultdomain "
2127e1dd0a2fSth 		    "(%d)\n"), errno);
21287c478bd9Sstevel@tonic-gate 		/* if we did an ldap init, we must have domain */
21297c478bd9Sstevel@tonic-gate 		if (flag == START_INIT)
21307c478bd9Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
21317c478bd9Sstevel@tonic-gate 	} else {
21327c478bd9Sstevel@tonic-gate 		if (fgets(domainname, BUFSIZ, domain_fp) == NULL) {
21337c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Error reading defaultdomain\n"),
2134e1dd0a2fSth 			    stderr);
21357c478bd9Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
21367c478bd9Sstevel@tonic-gate 		}
21377c478bd9Sstevel@tonic-gate 
21387c478bd9Sstevel@tonic-gate 		if (fclose(domain_fp) != 0) {
21397c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2140e1dd0a2fSth 			    gettext("Error closing defaultdomain (%d)\n"),
2141e1dd0a2fSth 			    errno);
21427c478bd9Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
21437c478bd9Sstevel@tonic-gate 		}
21447c478bd9Sstevel@tonic-gate 		domainlen = strlen(domainname);
21457c478bd9Sstevel@tonic-gate 		/* sanity check to make sure sprintf will fit */
21467c478bd9Sstevel@tonic-gate 		if (domainlen > (BUFSIZE - sizeof (CMD_DOMAIN_START) -
2147e1dd0a2fSth 		    sizeof (TO_DEV_NULL) - 3)) {
21487c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Specified domainname is "
2149e1dd0a2fSth 			    "too large\n"), stderr);
21507c478bd9Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
21517c478bd9Sstevel@tonic-gate 		}
21527c478bd9Sstevel@tonic-gate 		if (domainname[domainlen-1] == '\n')
21537c478bd9Sstevel@tonic-gate 			domainname[domainlen-1] = 0;
21547c478bd9Sstevel@tonic-gate 		/* buffer size is checked above */
2155cb5caa98Sdjl 		(void) snprintf(cmd_domain_start, BUFSIZ, "%s %s %s",
2156e1dd0a2fSth 		    CMD_DOMAIN_START, domainname, TO_DEV_NULL);
21577c478bd9Sstevel@tonic-gate 	}
21587c478bd9Sstevel@tonic-gate 
21597c478bd9Sstevel@tonic-gate 	/*
21607c478bd9Sstevel@tonic-gate 	 * We can be starting services after an init in which case
21617c478bd9Sstevel@tonic-gate 	 * we want to start ldap and not start yp or nis+.
21627c478bd9Sstevel@tonic-gate 	 */
21637c478bd9Sstevel@tonic-gate 	if (flag == START_INIT) {
21647c478bd9Sstevel@tonic-gate 		sysret = system(cmd_domain_start);
21657c478bd9Sstevel@tonic-gate 		if (mode_verbose)
21667c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, "start: %s %s... %s\n",
2167e1dd0a2fSth 			    CMD_DOMAIN_START, domainname,
2168e1dd0a2fSth 			    (sysret == 0) ? gettext("success") :
2169e1dd0a2fSth 			    gettext("failed"));
21707c478bd9Sstevel@tonic-gate 		if (sysret != 0) {
21717c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, gettext("\"%s\" returned: %d\n"),
2172e1dd0a2fSth 			    CMD_DOMAIN_START, sysret);
21737c478bd9Sstevel@tonic-gate 
21747c478bd9Sstevel@tonic-gate 			retcode = CLIENT_ERR_FAIL;
21757c478bd9Sstevel@tonic-gate 		}
21767c478bd9Sstevel@tonic-gate 
2177cb5caa98Sdjl 		if ((rc = __ns_ldap_self_gssapi_config(&config)) !=
2178e1dd0a2fSth 		    NS_LDAP_SUCCESS) {
2179cb5caa98Sdjl 			CLIENT_FPRINTF(stderr, gettext("Error (%d) while "
2180e1dd0a2fSth 			    "checking sasl/GSSAPI configuration\n"),
2181e1dd0a2fSth 			    rc);
21827c478bd9Sstevel@tonic-gate 			retcode = CLIENT_ERR_FAIL;
2183cb5caa98Sdjl 		}
21847c478bd9Sstevel@tonic-gate 
2185cb5caa98Sdjl 		if (config != NS_LDAP_SELF_GSSAPI_CONFIG_NONE) {
2186cb5caa98Sdjl 
2187cb5caa98Sdjl 			rc = __ns_ldap_check_dns_preq(
2188e1dd0a2fSth 			    1, mode_verbose, mode_quiet,
2189e1dd0a2fSth 			    NSSWITCH_LDAP, config, &errorp);
2190cb5caa98Sdjl 			if (errorp)
2191cb5caa98Sdjl 				(void) __ns_ldap_freeError(&errorp);
2192cb5caa98Sdjl 
2193cb5caa98Sdjl 			if (rc != NS_LDAP_SUCCESS)
2194cb5caa98Sdjl 				retcode = CLIENT_ERR_FAIL;
2195cb5caa98Sdjl 		}
2196cb5caa98Sdjl 
2197cb5caa98Sdjl 		if (rc == NS_LDAP_SUCCESS &&
2198e1dd0a2fSth 		    start_service(LDAP_FMRI, B_TRUE) != CLIENT_SUCCESS)
2199cb5caa98Sdjl 			retcode = CLIENT_ERR_FAIL;
2200cb5caa98Sdjl 
2201cb5caa98Sdjl 		if (config != NS_LDAP_SELF_GSSAPI_CONFIG_NONE &&
2202e1dd0a2fSth 		    rc == NS_LDAP_SUCCESS && retcode == CLIENT_SUCCESS) {
2203cb5caa98Sdjl 			rc = __ns_ldap_check_gssapi_preq(
2204e1dd0a2fSth 			    1, mode_verbose, mode_quiet, config,
2205e1dd0a2fSth 			    &errorp);
2206cb5caa98Sdjl 			if (errorp)
2207cb5caa98Sdjl 				(void) __ns_ldap_freeError(&errorp);
2208cb5caa98Sdjl 
2209cb5caa98Sdjl 			if (rc != NS_LDAP_SUCCESS)
2210cb5caa98Sdjl 				retcode = CLIENT_ERR_FAIL;
2211cb5caa98Sdjl 
2212cb5caa98Sdjl 		}
22137c478bd9Sstevel@tonic-gate 		/* No YP or NIS+ after init */
22147c478bd9Sstevel@tonic-gate 	/*
22157c478bd9Sstevel@tonic-gate 	 * Or we can be starting services after an uninit or error
22167c478bd9Sstevel@tonic-gate 	 * recovery.  We want to start whatever services were running
22177c478bd9Sstevel@tonic-gate 	 * before.  In the case of error recovery, it is the services
22187c478bd9Sstevel@tonic-gate 	 * that were running before we stopped them (flags set in
22197c478bd9Sstevel@tonic-gate 	 * stop_services).  If it is an uninit then we determine
22207c478bd9Sstevel@tonic-gate 	 * which services to start based on the files we recovered
22217c478bd9Sstevel@tonic-gate 	 * (flags set in recover).
22227c478bd9Sstevel@tonic-gate 	 */
22237c478bd9Sstevel@tonic-gate 	} else {
22247c478bd9Sstevel@tonic-gate 		/* uninit and recover should set flags of what to start */
22257c478bd9Sstevel@tonic-gate 		if (domain_fp) {
22267c478bd9Sstevel@tonic-gate 			sysret = system(cmd_domain_start);
22277c478bd9Sstevel@tonic-gate 			if (mode_verbose)
22287c478bd9Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr, "start: %s %s... %s\n",
2229e1dd0a2fSth 				    CMD_DOMAIN_START, domainname,
2230e1dd0a2fSth 				    (sysret == 0) ? gettext("success") :
2231e1dd0a2fSth 				    gettext("failed"));
22327c478bd9Sstevel@tonic-gate 			if (sysret != 0) {
22337c478bd9Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr, gettext("\"%s\" "
2234e1dd0a2fSth 				    "returned: %d\n"),
2235e1dd0a2fSth 				    CMD_DOMAIN_START, sysret);
22367c478bd9Sstevel@tonic-gate 
22377c478bd9Sstevel@tonic-gate 				retcode = CLIENT_ERR_FAIL;
22387c478bd9Sstevel@tonic-gate 			}
22397c478bd9Sstevel@tonic-gate 		}
22407c478bd9Sstevel@tonic-gate 
22417c478bd9Sstevel@tonic-gate 		if (gStartLdap == flag) {
22427c478bd9Sstevel@tonic-gate 			if (!(is_service(LDAP_FMRI, SCF_STATE_STRING_ONLINE)))
22437c478bd9Sstevel@tonic-gate 				if (start_service(LDAP_FMRI, B_TRUE)
2244e1dd0a2fSth 				    != CLIENT_SUCCESS)
22457c478bd9Sstevel@tonic-gate 					retcode = CLIENT_ERR_FAIL;
22467c478bd9Sstevel@tonic-gate 		}
22477c478bd9Sstevel@tonic-gate 
22487c478bd9Sstevel@tonic-gate 		if (gStartYp == flag) {
22497c478bd9Sstevel@tonic-gate 			if (!(is_service(YP_FMRI, SCF_STATE_STRING_ONLINE)))
22507c478bd9Sstevel@tonic-gate 				(void) start_service(YP_FMRI, B_TRUE);
22517c478bd9Sstevel@tonic-gate 		}
22527c478bd9Sstevel@tonic-gate 
22537c478bd9Sstevel@tonic-gate 		if (gStartNisd == flag) {
22547c478bd9Sstevel@tonic-gate 			if (!(is_service(NISD_FMRI, SCF_STATE_STRING_ONLINE)))
22557c478bd9Sstevel@tonic-gate 				(void) start_service(NISD_FMRI, B_TRUE);
22567c478bd9Sstevel@tonic-gate 		}
22577c478bd9Sstevel@tonic-gate 
22587c478bd9Sstevel@tonic-gate 	}
22597c478bd9Sstevel@tonic-gate 	if ((enableFlag & AUTOFS_ON) &&
22607c478bd9Sstevel@tonic-gate 	    !(is_service(AUTOFS_FMRI, SCF_STATE_STRING_ONLINE)))
22617c478bd9Sstevel@tonic-gate 		(void) start_service(AUTOFS_FMRI, B_TRUE);
22627c478bd9Sstevel@tonic-gate 
22637c478bd9Sstevel@tonic-gate 	if ((enableFlag & NSCD_ON) &&
22647c478bd9Sstevel@tonic-gate 	    !(is_service(NSCD_FMRI, SCF_STATE_STRING_ONLINE)))
22657c478bd9Sstevel@tonic-gate 		(void) start_service(NSCD_FMRI, B_TRUE);
22667c478bd9Sstevel@tonic-gate 
2267cb5caa98Sdjl #if 0
2268cb5caa98Sdjl 	if (flag == START_INIT && config != NS_LDAP_SELF_GSSAPI_CONFIG_NONE &&
2269cb5caa98Sdjl 	    retcode == CLIENT_SUCCESS &&
2270cb5caa98Sdjl 	    !(is_service(NSCD_FMRI, SCF_STATE_STRING_ONLINE))) {
2271cb5caa98Sdjl 		CLIENT_FPRINTF(stderr, "start: %s\n",
2272e1dd0a2fSth 		    gettext("self/sasl/GSSAPI is configured"
2273e1dd0a2fSth 		    " but nscd is not online"));
2274cb5caa98Sdjl 		retcode = CLIENT_ERR_FAIL;
2275cb5caa98Sdjl 	}
2276cb5caa98Sdjl #endif
2277cb5caa98Sdjl 
22787c478bd9Sstevel@tonic-gate 	if ((enableFlag & SENDMAIL_ON) &&
22797c478bd9Sstevel@tonic-gate 	    !(is_service(SENDMAIL_FMRI, SCF_STATE_STRING_ONLINE)))
22807c478bd9Sstevel@tonic-gate 		(void) start_service(SENDMAIL_FMRI, B_TRUE);
22817c478bd9Sstevel@tonic-gate 
22827c478bd9Sstevel@tonic-gate 	/*
22837c478bd9Sstevel@tonic-gate 	 * Restart name-service milestone so that any consumer
22847c478bd9Sstevel@tonic-gate 	 * which depends on it will be restarted.
22857c478bd9Sstevel@tonic-gate 	 */
22867c478bd9Sstevel@tonic-gate 	(void) restart_service(NS_MILESTONE_FMRI, B_TRUE);
22877c478bd9Sstevel@tonic-gate 	return (retcode);
22887c478bd9Sstevel@tonic-gate }
22897c478bd9Sstevel@tonic-gate 
22907c478bd9Sstevel@tonic-gate /*
22917c478bd9Sstevel@tonic-gate  * credCheck is called to check if credentials are required for this
22927c478bd9Sstevel@tonic-gate  * configuration.  Currently, this means that if any credentialLevel is
22937c478bd9Sstevel@tonic-gate  * proxy and any authenticationMethod is something other than none, then
22947c478bd9Sstevel@tonic-gate  * credential info is required (proxyDN and proxyPassword).
22957c478bd9Sstevel@tonic-gate  */
22967c478bd9Sstevel@tonic-gate static int
22977c478bd9Sstevel@tonic-gate credCheck(clientopts_t *arglist)
22987c478bd9Sstevel@tonic-gate {
22997c478bd9Sstevel@tonic-gate 	int counter;
23007c478bd9Sstevel@tonic-gate 	int **credLevel;
23017c478bd9Sstevel@tonic-gate 	ns_auth_t **authMethod;
23027c478bd9Sstevel@tonic-gate 	char **proxyDN, **proxyPassword;
23037c478bd9Sstevel@tonic-gate 	ns_ldap_error_t *errorp;
23047c478bd9Sstevel@tonic-gate 	int credProxy, authNotNone;
23057c478bd9Sstevel@tonic-gate 	int retcode;
23067c478bd9Sstevel@tonic-gate 
23077c478bd9Sstevel@tonic-gate /* If credentialLevel is proxy, make sure we have proxyDN and proxyPassword */
23087c478bd9Sstevel@tonic-gate 	retcode = __ns_ldap_getParam(NS_LDAP_CREDENTIAL_LEVEL_P,
2309e1dd0a2fSth 	    (void ***)&credLevel, &errorp);
23107c478bd9Sstevel@tonic-gate 	if (retcode != 0) {
23117c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2312e1dd0a2fSth 		    gettext("Error %d while trying to retrieve "
2313e1dd0a2fSth 		    "credLevel\n"),
2314e1dd0a2fSth 		    retcode);
23157c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
23167c478bd9Sstevel@tonic-gate 	}
23177c478bd9Sstevel@tonic-gate 	retcode = __ns_ldap_getParam(NS_LDAP_AUTH_P,
2318e1dd0a2fSth 	    (void ***)&authMethod, &errorp);
23197c478bd9Sstevel@tonic-gate 	if (retcode != 0) {
23207c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2321e1dd0a2fSth 		    gettext("Error %d while trying to retrieve "
2322e1dd0a2fSth 		    "authMethod\n"), retcode);
23237c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
23247c478bd9Sstevel@tonic-gate 	}
23257c478bd9Sstevel@tonic-gate 	retcode = __ns_ldap_getParam(NS_LDAP_BINDDN_P,
2326e1dd0a2fSth 	    (void ***)&proxyDN, &errorp);
23277c478bd9Sstevel@tonic-gate 	if (retcode != 0) {
23287c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2329e1dd0a2fSth 		    gettext("Error %d while trying to retrieve proxyDN\n"),
2330e1dd0a2fSth 		    retcode);
23317c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
23327c478bd9Sstevel@tonic-gate 	}
23337c478bd9Sstevel@tonic-gate 	retcode = __ns_ldap_getParam(NS_LDAP_BINDPASSWD_P,
2334e1dd0a2fSth 	    (void ***)&proxyPassword, &errorp);
23357c478bd9Sstevel@tonic-gate 	if (retcode != 0) {
23367c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2337e1dd0a2fSth 		    gettext("Error %d while trying to retrieve "
2338e1dd0a2fSth 		    "proxyPassword\n"), retcode);
23397c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
23407c478bd9Sstevel@tonic-gate 	}
23417c478bd9Sstevel@tonic-gate 
23427c478bd9Sstevel@tonic-gate 	if (mode_verbose) {
23437c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2344e1dd0a2fSth 		    gettext("Proxy DN: %s\n"),
2345e1dd0a2fSth 		    (proxyDN && proxyDN[0]) ? proxyDN[0] : "NULL");
23467c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2347e1dd0a2fSth 		    gettext("Proxy password: %s\n"),
2348e1dd0a2fSth 		    (proxyPassword && proxyPassword[0]) ?
2349e1dd0a2fSth 		    proxyPassword[0] : "NULL");
23507c478bd9Sstevel@tonic-gate 	}
23517c478bd9Sstevel@tonic-gate 
23527c478bd9Sstevel@tonic-gate 	credProxy = 0;	/* flag to indicate if we have a credLevel of proxy */
23537c478bd9Sstevel@tonic-gate 	for (counter = 0; credLevel && credLevel[counter] != NULL; counter++) {
23547c478bd9Sstevel@tonic-gate 		if (mode_verbose)
23557c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2356e1dd0a2fSth 			    gettext("Credential level: %d\n"),
2357e1dd0a2fSth 			    *credLevel[counter]);
23587c478bd9Sstevel@tonic-gate 		if (*credLevel[counter] == NS_LDAP_CRED_PROXY) {
23597c478bd9Sstevel@tonic-gate 			credProxy = 1;
23607c478bd9Sstevel@tonic-gate 			break;
23617c478bd9Sstevel@tonic-gate 		}
23627c478bd9Sstevel@tonic-gate 	}
23637c478bd9Sstevel@tonic-gate 
23647c478bd9Sstevel@tonic-gate 	authNotNone = 0;	/* flag for authMethod other than none */
23657c478bd9Sstevel@tonic-gate 	for (counter = 0;
2366e1dd0a2fSth 	    authMethod && authMethod[counter] != NULL;
2367e1dd0a2fSth 	    counter++) {
23687c478bd9Sstevel@tonic-gate 
23697c478bd9Sstevel@tonic-gate 		if (mode_verbose)
23707c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2371e1dd0a2fSth 			    gettext("Authentication method: %d\n"),
2372e1dd0a2fSth 			    authMethod[counter]->type);
23737c478bd9Sstevel@tonic-gate 		if (authMethod[counter]->type != NS_LDAP_AUTH_NONE &&
23747c478bd9Sstevel@tonic-gate 		    !(authMethod[counter]->type == NS_LDAP_AUTH_TLS &&
23757c478bd9Sstevel@tonic-gate 		    authMethod[counter]->tlstype == NS_LDAP_TLS_NONE)) {
23767c478bd9Sstevel@tonic-gate 			authNotNone = 1;
23777c478bd9Sstevel@tonic-gate 			break;
23787c478bd9Sstevel@tonic-gate 		}
23797c478bd9Sstevel@tonic-gate 	}
23807c478bd9Sstevel@tonic-gate 
23817c478bd9Sstevel@tonic-gate 	/* First, if we don't need proxyDN/Password then just return ok */
23827c478bd9Sstevel@tonic-gate 	if (!(credProxy && authNotNone)) {
23837c478bd9Sstevel@tonic-gate 		if (mode_verbose)
23847c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
2385e1dd0a2fSth 			    gettext("No proxyDN/proxyPassword required\n"),
2386e1dd0a2fSth 			    stderr);
23877c478bd9Sstevel@tonic-gate 		return (CLIENT_SUCCESS);
23887c478bd9Sstevel@tonic-gate 	}
23897c478bd9Sstevel@tonic-gate 
23907c478bd9Sstevel@tonic-gate 	/* Now let's check if we have the cred stuff we need */
23917c478bd9Sstevel@tonic-gate 	if (!proxyDN || !proxyDN[0]) {
23927c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
2393e1dd0a2fSth 		    gettext("credentialLevel is proxy and no proxyDN "
2394e1dd0a2fSth 		    "specified\n"),
2395e1dd0a2fSth 		    stderr);
23967c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_CREDENTIAL);
23977c478bd9Sstevel@tonic-gate 	}
23987c478bd9Sstevel@tonic-gate 
23997c478bd9Sstevel@tonic-gate 	/* If we need proxyPassword (prompt) */
24007c478bd9Sstevel@tonic-gate 	if (!proxyPassword || !proxyPassword[0]) {
24017c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
2402e1dd0a2fSth 		    gettext("credentialLevel requires proxyPassword\n"),
2403e1dd0a2fSth 		    stderr);
24047c478bd9Sstevel@tonic-gate 		arglist->proxyPassword = getpassphrase("Proxy Bind Password:");
24057c478bd9Sstevel@tonic-gate 		if (arglist->proxyPassword == NULL) {
24067c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(gettext("Get password failed\n"), stderr);
24077c478bd9Sstevel@tonic-gate 			return (CLIENT_ERR_CREDENTIAL);
24087c478bd9Sstevel@tonic-gate 		}
24097c478bd9Sstevel@tonic-gate 		LDAP_SET_PARAM(arglist->proxyPassword, NS_LDAP_BINDPASSWD_P);
24107c478bd9Sstevel@tonic-gate 		if (retcode != 0) {
24117c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
2412e1dd0a2fSth 			    gettext("setParam proxyPassword failed.\n"),
2413e1dd0a2fSth 			    stderr);
24147c478bd9Sstevel@tonic-gate 			return (CLIENT_ERR_CREDENTIAL);
24157c478bd9Sstevel@tonic-gate 		}
24167c478bd9Sstevel@tonic-gate 	}
24177c478bd9Sstevel@tonic-gate 
24187c478bd9Sstevel@tonic-gate 	return (CLIENT_SUCCESS);
24197c478bd9Sstevel@tonic-gate }
24207c478bd9Sstevel@tonic-gate 
2421*dd1104fbSMichen Chang /*
2422*dd1104fbSMichen Chang  * adminCredCheck is called to check if the admin credential is required
2423*dd1104fbSMichen Chang  * for this configuration. This means that if enableShadowUpdate is set
2424*dd1104fbSMichen Chang  * to TRUE then credential info is required (adminDN and adminPassword).
2425*dd1104fbSMichen Chang  * One exception is that if there is a 'self' credentialLevel and
2426*dd1104fbSMichen Chang  * 'sasl/GSSAPI' authenticationMethod (i.e., possibly using Kerberos
2427*dd1104fbSMichen Chang  * host credential) then adminDN and adminPassword are not required.
2428*dd1104fbSMichen Chang  */
2429*dd1104fbSMichen Chang static int
2430*dd1104fbSMichen Chang adminCredCheck(clientopts_t *arglist)
2431*dd1104fbSMichen Chang {
2432*dd1104fbSMichen Chang 	int counter;
2433*dd1104fbSMichen Chang 	int **enabled = NULL;
2434*dd1104fbSMichen Chang 	int **credLevel = NULL;
2435*dd1104fbSMichen Chang 	char **adminDN = NULL;
2436*dd1104fbSMichen Chang 	char **adminPassword = NULL;
2437*dd1104fbSMichen Chang 	ns_auth_t **authMethod = NULL;
2438*dd1104fbSMichen Chang 	ns_ldap_error_t *errorp = NULL;
2439*dd1104fbSMichen Chang 	int credSelf, authSASLgss;
2440*dd1104fbSMichen Chang 	int retcode, rc;
2441*dd1104fbSMichen Chang 
2442*dd1104fbSMichen Chang 	/* If shadow update not enabled, then no need to check */
2443*dd1104fbSMichen Chang 	retcode = __ns_ldap_getParam(NS_LDAP_ENABLE_SHADOW_UPDATE_P,
2444*dd1104fbSMichen Chang 	    (void ***)&enabled, &errorp);
2445*dd1104fbSMichen Chang 	if (retcode != 0) {
2446*dd1104fbSMichen Chang 		CLIENT_FPRINTF(stderr,
2447*dd1104fbSMichen Chang 		    gettext("Error %d while trying to retrieve "
2448*dd1104fbSMichen Chang 		    "enableShadowUpdate\n"), retcode);
2449*dd1104fbSMichen Chang 		rc = CLIENT_ERR_FAIL;
2450*dd1104fbSMichen Chang 		goto out;
2451*dd1104fbSMichen Chang 	}
2452*dd1104fbSMichen Chang 	if (enabled == NULL ||
2453*dd1104fbSMichen Chang 	    *enabled[0] != NS_LDAP_ENABLE_SHADOW_UPDATE_TRUE) {
2454*dd1104fbSMichen Chang 		if (mode_verbose)
2455*dd1104fbSMichen Chang 			CLIENT_FPUTS(
2456*dd1104fbSMichen Chang 			    gettext("Shadow Update is not enabled, "
2457*dd1104fbSMichen Chang 			    "no adminDN/adminPassword is required.\n"), stderr);
2458*dd1104fbSMichen Chang 		rc = CLIENT_SUCCESS;
2459*dd1104fbSMichen Chang 		goto out;
2460*dd1104fbSMichen Chang 	}
2461*dd1104fbSMichen Chang 
2462*dd1104fbSMichen Chang 	/* get credentialLevel */
2463*dd1104fbSMichen Chang 	retcode = __ns_ldap_getParam(NS_LDAP_CREDENTIAL_LEVEL_P,
2464*dd1104fbSMichen Chang 	    (void ***)&credLevel, &errorp);
2465*dd1104fbSMichen Chang 	if (retcode != 0) {
2466*dd1104fbSMichen Chang 		CLIENT_FPRINTF(stderr,
2467*dd1104fbSMichen Chang 		    gettext("Error %d while trying to retrieve credLevel\n"),
2468*dd1104fbSMichen Chang 		    retcode);
2469*dd1104fbSMichen Chang 		rc = CLIENT_ERR_FAIL;
2470*dd1104fbSMichen Chang 		goto out;
2471*dd1104fbSMichen Chang 	}
2472*dd1104fbSMichen Chang 
2473*dd1104fbSMichen Chang 	/* get AuthenticationMethod */
2474*dd1104fbSMichen Chang 	retcode = __ns_ldap_getParam(NS_LDAP_AUTH_P,
2475*dd1104fbSMichen Chang 	    (void ***)&authMethod, &errorp);
2476*dd1104fbSMichen Chang 	if (retcode != 0) {
2477*dd1104fbSMichen Chang 		CLIENT_FPRINTF(stderr,
2478*dd1104fbSMichen Chang 		    gettext("Error %d while trying to retrieve authMethod\n"),
2479*dd1104fbSMichen Chang 		    retcode);
2480*dd1104fbSMichen Chang 		rc = CLIENT_ERR_FAIL;
2481*dd1104fbSMichen Chang 		goto out;
2482*dd1104fbSMichen Chang 	}
2483*dd1104fbSMichen Chang 
2484*dd1104fbSMichen Chang 	/* get adminDN */
2485*dd1104fbSMichen Chang 	retcode = __ns_ldap_getParam(NS_LDAP_ADMIN_BINDDN_P,
2486*dd1104fbSMichen Chang 	    (void ***)&adminDN, &errorp);
2487*dd1104fbSMichen Chang 	if (retcode != 0) {
2488*dd1104fbSMichen Chang 		CLIENT_FPRINTF(stderr,
2489*dd1104fbSMichen Chang 		    gettext("Error %d while trying to retrieve adminDN\n"),
2490*dd1104fbSMichen Chang 		    retcode);
2491*dd1104fbSMichen Chang 		rc = CLIENT_ERR_FAIL;
2492*dd1104fbSMichen Chang 		goto out;
2493*dd1104fbSMichen Chang 	}
2494*dd1104fbSMichen Chang 
2495*dd1104fbSMichen Chang 	/* get adminPassword */
2496*dd1104fbSMichen Chang 	retcode = __ns_ldap_getParam(NS_LDAP_ADMIN_BINDPASSWD_P,
2497*dd1104fbSMichen Chang 	    (void ***)&adminPassword, &errorp);
2498*dd1104fbSMichen Chang 	if (retcode != 0) {
2499*dd1104fbSMichen Chang 		CLIENT_FPRINTF(stderr,
2500*dd1104fbSMichen Chang 		    gettext("Error %d while trying to retrieve "
2501*dd1104fbSMichen Chang 		    "adminPassword\n"), retcode);
2502*dd1104fbSMichen Chang 		rc = CLIENT_ERR_FAIL;
2503*dd1104fbSMichen Chang 		goto out;
2504*dd1104fbSMichen Chang 	}
2505*dd1104fbSMichen Chang 
2506*dd1104fbSMichen Chang 	if (mode_verbose) {
2507*dd1104fbSMichen Chang 		CLIENT_FPRINTF(stderr,
2508*dd1104fbSMichen Chang 		    gettext("admin DN: %s\n"),
2509*dd1104fbSMichen Chang 		    (adminDN && adminDN[0]) ? adminDN[0] : "NULL");
2510*dd1104fbSMichen Chang 		CLIENT_FPRINTF(stderr,
2511*dd1104fbSMichen Chang 		    gettext("admin password: %s\n"),
2512*dd1104fbSMichen Chang 		    (adminPassword && adminPassword[0]) ?
2513*dd1104fbSMichen Chang 		    adminPassword[0] : "NULL");
2514*dd1104fbSMichen Chang 	}
2515*dd1104fbSMichen Chang 
2516*dd1104fbSMichen Chang 	credSelf = 0;	/* flag to indicate if we have a credLevel of self */
2517*dd1104fbSMichen Chang 	for (counter = 0; credLevel && credLevel[counter] != NULL; counter++) {
2518*dd1104fbSMichen Chang 		if (mode_verbose)
2519*dd1104fbSMichen Chang 			CLIENT_FPRINTF(stderr,
2520*dd1104fbSMichen Chang 			    gettext("Credential level: %d\n"),
2521*dd1104fbSMichen Chang 			    *credLevel[counter]);
2522*dd1104fbSMichen Chang 		if (*credLevel[counter] == NS_LDAP_CRED_SELF) {
2523*dd1104fbSMichen Chang 			credSelf = 1;
2524*dd1104fbSMichen Chang 			break;
2525*dd1104fbSMichen Chang 		}
2526*dd1104fbSMichen Chang 	}
2527*dd1104fbSMichen Chang 
2528*dd1104fbSMichen Chang 	authSASLgss = 0;	/* flag for authMethod of SASL/gssapi */
2529*dd1104fbSMichen Chang 	for (counter = 0;
2530*dd1104fbSMichen Chang 	    authMethod && authMethod[counter] != NULL;
2531*dd1104fbSMichen Chang 	    counter++) {
2532*dd1104fbSMichen Chang 
2533*dd1104fbSMichen Chang 		if (mode_verbose)
2534*dd1104fbSMichen Chang 			CLIENT_FPRINTF(stderr,
2535*dd1104fbSMichen Chang 			    gettext("Authentication sasl mechanism: %d\n"),
2536*dd1104fbSMichen Chang 			    authMethod[counter]->saslmech);
2537*dd1104fbSMichen Chang 		if (authMethod[counter]->saslmech == NS_LDAP_SASL_GSSAPI) {
2538*dd1104fbSMichen Chang 			authSASLgss = 1;
2539*dd1104fbSMichen Chang 			break;
2540*dd1104fbSMichen Chang 		}
2541*dd1104fbSMichen Chang 	}
2542*dd1104fbSMichen Chang 
2543*dd1104fbSMichen Chang 	/* First, if we don't need adminDN/adminPassword then just return ok */
2544*dd1104fbSMichen Chang 	if (credSelf && authSASLgss) {
2545*dd1104fbSMichen Chang 		if (mode_verbose)
2546*dd1104fbSMichen Chang 			CLIENT_FPUTS(
2547*dd1104fbSMichen Chang 			    gettext("A credential Level of self and an "
2548*dd1104fbSMichen Chang 			    "authentication method of sasl/GSSAPI is "
2549*dd1104fbSMichen Chang 			    "configured, no adminDN/adminPassword "
2550*dd1104fbSMichen Chang 			    "is required.\n"), stderr);
2551*dd1104fbSMichen Chang 		rc = CLIENT_SUCCESS;
2552*dd1104fbSMichen Chang 		goto out;
2553*dd1104fbSMichen Chang 	}
2554*dd1104fbSMichen Chang 
2555*dd1104fbSMichen Chang 	/* Now let's check if we have the cred stuff we need */
2556*dd1104fbSMichen Chang 	if (adminDN == NULL || adminDN[0] == '\0') {
2557*dd1104fbSMichen Chang 		CLIENT_FPUTS(
2558*dd1104fbSMichen Chang 		    gettext("Shadow Update is enabled, but "
2559*dd1104fbSMichen Chang 		    "no adminDN is configured.\n"), stderr);
2560*dd1104fbSMichen Chang 		rc = CLIENT_ERR_CREDENTIAL;
2561*dd1104fbSMichen Chang 		goto out;
2562*dd1104fbSMichen Chang 	}
2563*dd1104fbSMichen Chang 
2564*dd1104fbSMichen Chang 	/* If we need adminPassword (prompt) */
2565*dd1104fbSMichen Chang 	if (adminPassword == NULL || adminPassword[0] == '\0') {
2566*dd1104fbSMichen Chang 		CLIENT_FPUTS(
2567*dd1104fbSMichen Chang 		    gettext("Shadow Update requires adminPassword\n"),
2568*dd1104fbSMichen Chang 		    stderr);
2569*dd1104fbSMichen Chang 		arglist->adminPassword = getpassphrase("admin Password:");
2570*dd1104fbSMichen Chang 		if (arglist->adminPassword == NULL) {
2571*dd1104fbSMichen Chang 			CLIENT_FPUTS(gettext("Unable to get admin password\n"),
2572*dd1104fbSMichen Chang 			    stderr);
2573*dd1104fbSMichen Chang 			rc = CLIENT_ERR_CREDENTIAL;
2574*dd1104fbSMichen Chang 			goto out;
2575*dd1104fbSMichen Chang 		}
2576*dd1104fbSMichen Chang 		LDAP_SET_PARAM(arglist->adminPassword,
2577*dd1104fbSMichen Chang 		    NS_LDAP_ADMIN_BINDPASSWD_P);
2578*dd1104fbSMichen Chang 		if (retcode != 0) {
2579*dd1104fbSMichen Chang 			CLIENT_FPUTS(
2580*dd1104fbSMichen Chang 			    gettext("setParam adminPassword failed.\n"),
2581*dd1104fbSMichen Chang 			    stderr);
2582*dd1104fbSMichen Chang 			rc = CLIENT_ERR_CREDENTIAL;
2583*dd1104fbSMichen Chang 			goto out;
2584*dd1104fbSMichen Chang 		}
2585*dd1104fbSMichen Chang 	}
2586*dd1104fbSMichen Chang 
2587*dd1104fbSMichen Chang 	rc = CLIENT_SUCCESS;
2588*dd1104fbSMichen Chang 
2589*dd1104fbSMichen Chang 	out:
2590*dd1104fbSMichen Chang 	if (enabled != NULL)
2591*dd1104fbSMichen Chang 		(void) __ns_ldap_freeParam((void ***)&enabled);
2592*dd1104fbSMichen Chang 	if (credLevel != NULL)
2593*dd1104fbSMichen Chang 		(void) __ns_ldap_freeParam((void ***)&credLevel);
2594*dd1104fbSMichen Chang 	if (authMethod != NULL)
2595*dd1104fbSMichen Chang 		(void) __ns_ldap_freeParam((void ***)&authMethod);
2596*dd1104fbSMichen Chang 	if (adminDN != NULL)
2597*dd1104fbSMichen Chang 		(void) __ns_ldap_freeParam((void ***)&adminDN);
2598*dd1104fbSMichen Chang 	if (adminPassword != NULL)
2599*dd1104fbSMichen Chang 		(void) __ns_ldap_freeParam((void ***)&adminPassword);
2600*dd1104fbSMichen Chang 
2601*dd1104fbSMichen Chang 	return (rc);
2602*dd1104fbSMichen Chang }
2603*dd1104fbSMichen Chang 
26047c478bd9Sstevel@tonic-gate /*
26057c478bd9Sstevel@tonic-gate  * try to restore the previous name space on this machine
26067c478bd9Sstevel@tonic-gate  */
26077c478bd9Sstevel@tonic-gate static int
26087c478bd9Sstevel@tonic-gate recover(int saveState)
26097c478bd9Sstevel@tonic-gate {
26107c478bd9Sstevel@tonic-gate 	struct stat buf;
26117c478bd9Sstevel@tonic-gate 	int stat_ret, retcode, fd;
26127c478bd9Sstevel@tonic-gate 	int domain = 0, domainlen;
26137c478bd9Sstevel@tonic-gate 	char yp_dir[BUFSIZE], yp_dir_back[BUFSIZE];
26147c478bd9Sstevel@tonic-gate 	char name[BUFSIZ];
26157c478bd9Sstevel@tonic-gate 	char *ldap_conf_file, *ldap_cred_file;
26167c478bd9Sstevel@tonic-gate 	char ldap_file_back[BUFSIZE], ldap_cred_back[BUFSIZE];
26177c478bd9Sstevel@tonic-gate 
26187c478bd9Sstevel@tonic-gate 	/* If running as Sysid Install become a no-op */
26197c478bd9Sstevel@tonic-gate 	if (sysid_install == B_TRUE)
26207c478bd9Sstevel@tonic-gate 		return (CLIENT_SUCCESS);
26217c478bd9Sstevel@tonic-gate 
26227c478bd9Sstevel@tonic-gate 	stat_ret = stat(LDAP_RESTORE_DIR, &buf);
26237c478bd9Sstevel@tonic-gate 	if (stat_ret != 0) {
26247c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
2625e1dd0a2fSth 		    gettext("Cannot recover.  No backup files "
2626e1dd0a2fSth 		    "found.\n"),
2627e1dd0a2fSth 		    stderr);
26287c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
2629e1dd0a2fSth 		    gettext("\t Either this machine was not initialized\n"),
2630e1dd0a2fSth 		    stderr);
26317c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
2632e1dd0a2fSth 		    gettext("\t by ldapclient or the backup files "
2633e1dd0a2fSth 		    "have been\n"),
2634e1dd0a2fSth 		    stderr);
26357c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
2636e1dd0a2fSth 		    gettext("\t removed manually or with an \"uninit\"\n"),
2637e1dd0a2fSth 		    stderr);
26387c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_RESTORE);	/* invalid backup */
26397c478bd9Sstevel@tonic-gate 	}
26407c478bd9Sstevel@tonic-gate 
26417c478bd9Sstevel@tonic-gate 	/*
26427c478bd9Sstevel@tonic-gate 	 * Get domainname.  Allow no domainname for the case where "files"
26437c478bd9Sstevel@tonic-gate 	 * config was backed up.
26447c478bd9Sstevel@tonic-gate 	 */
26457c478bd9Sstevel@tonic-gate 	stat_ret = stat(DOMAINNAME_BACK, &buf);
26467c478bd9Sstevel@tonic-gate 	if (mode_verbose)
26477c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2648e1dd0a2fSth 		    gettext("recover: stat(%s)=%d\n"),
2649e1dd0a2fSth 		    DOMAINNAME_BACK, stat_ret);
26507c478bd9Sstevel@tonic-gate 	if (stat_ret == 0) {
26517c478bd9Sstevel@tonic-gate 		if (mode_verbose)
26527c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2653e1dd0a2fSth 			    gettext("recover: open(%s)\n"),
2654e1dd0a2fSth 			    DOMAINNAME_BACK);
26557c478bd9Sstevel@tonic-gate 		fd = open(DOMAINNAME_BACK, O_RDONLY);
26567c478bd9Sstevel@tonic-gate 		if (mode_verbose)
26577c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2658e1dd0a2fSth 			    gettext("recover: read(%s)\n"),
2659e1dd0a2fSth 			    DOMAINNAME_BACK);
26607c478bd9Sstevel@tonic-gate 		domainlen = read(fd, &(name[0]), BUFSIZ-1);
26617c478bd9Sstevel@tonic-gate 		(void) close(fd);
26627c478bd9Sstevel@tonic-gate 		if (domainlen < 0) {
26637c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
2664e1dd0a2fSth 			    gettext("Cannot recover.  Cannot determine "
2665e1dd0a2fSth 			    "previous domain name.\n"),
2666e1dd0a2fSth 			    stderr);
26677c478bd9Sstevel@tonic-gate 			return (CLIENT_ERR_RESTORE);	/* invalid backup */
26687c478bd9Sstevel@tonic-gate 		} else 	{
26697c478bd9Sstevel@tonic-gate 			char *ptr;
26707c478bd9Sstevel@tonic-gate 
26717c478bd9Sstevel@tonic-gate 			ptr = strchr(&(name[0]), '\n');
26727c478bd9Sstevel@tonic-gate 			if (ptr != NULL)
26737c478bd9Sstevel@tonic-gate 				*ptr = '\0';
26747c478bd9Sstevel@tonic-gate 			else
26757c478bd9Sstevel@tonic-gate 				name[domainlen] = '\0';
26767c478bd9Sstevel@tonic-gate 
26777c478bd9Sstevel@tonic-gate 			if (mode_verbose)
26787c478bd9Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
2679e1dd0a2fSth 				    gettext("recover: old domainname "
2680e1dd0a2fSth 				    "\"%s\"\n"), name);
26817c478bd9Sstevel@tonic-gate 
26827c478bd9Sstevel@tonic-gate 			if (strlen(name) == 0)
26837c478bd9Sstevel@tonic-gate 				domain = 0;
26847c478bd9Sstevel@tonic-gate 			else
26857c478bd9Sstevel@tonic-gate 				domain = 1;	/* flag that we have domain */
26867c478bd9Sstevel@tonic-gate 
26877c478bd9Sstevel@tonic-gate 		}
26887c478bd9Sstevel@tonic-gate 	}
26897c478bd9Sstevel@tonic-gate 
26907c478bd9Sstevel@tonic-gate 
26917c478bd9Sstevel@tonic-gate 	/*
26927c478bd9Sstevel@tonic-gate 	 * we can recover at this point
26937c478bd9Sstevel@tonic-gate 	 * remove LDAP config files before restore
26947c478bd9Sstevel@tonic-gate 	 */
26957c478bd9Sstevel@tonic-gate 	(void) unlink(NSCONFIGFILE);
26967c478bd9Sstevel@tonic-gate 	(void) unlink(NSCREDFILE);
26977c478bd9Sstevel@tonic-gate 
26987c478bd9Sstevel@tonic-gate 	ldap_conf_file = strrchr(NSCONFIGFILE, '/') + 1;
26997c478bd9Sstevel@tonic-gate 	ldap_cred_file = strrchr(NSCREDFILE, '/') + 1;
27007c478bd9Sstevel@tonic-gate 
27017c478bd9Sstevel@tonic-gate 	(void) strlcpy(ldap_file_back, LDAP_RESTORE_DIR "/", BUFSIZE);
27027c478bd9Sstevel@tonic-gate 	(void) strlcat(ldap_file_back, ldap_conf_file, BUFSIZE);
27037c478bd9Sstevel@tonic-gate 
27047c478bd9Sstevel@tonic-gate 	stat_ret = stat(ldap_file_back, &buf);
27057c478bd9Sstevel@tonic-gate 	if (mode_verbose)
27067c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2707e1dd0a2fSth 		    gettext("recover: stat(%s)=%d\n"),
2708e1dd0a2fSth 		    ldap_file_back, stat_ret);
27097c478bd9Sstevel@tonic-gate 	if (stat_ret == 0) {
27107c478bd9Sstevel@tonic-gate 		if (saveState)
27117c478bd9Sstevel@tonic-gate 			gStartLdap = START_UNINIT;
27127c478bd9Sstevel@tonic-gate 		retcode = file_move(ldap_file_back, NSCONFIGFILE);
27137c478bd9Sstevel@tonic-gate 		if (mode_verbose)
27147c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2715e1dd0a2fSth 			    gettext("recover: file_move(%s, %s)=%d\n"),
2716e1dd0a2fSth 			    ldap_file_back, NSCONFIGFILE, retcode);
27177c478bd9Sstevel@tonic-gate 		if (retcode != 0)
27187c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2719e1dd0a2fSth 			    gettext("recover: file_move(%s, %s) failed\n"),
2720e1dd0a2fSth 			    ldap_file_back, NSCONFIGFILE);
27217c478bd9Sstevel@tonic-gate 	}
27227c478bd9Sstevel@tonic-gate 
27237c478bd9Sstevel@tonic-gate 	(void) strlcpy(ldap_cred_back, LDAP_RESTORE_DIR "/", BUFSIZE);
27247c478bd9Sstevel@tonic-gate 	(void) strlcat(ldap_cred_back, ldap_cred_file, BUFSIZE);
27257c478bd9Sstevel@tonic-gate 
27267c478bd9Sstevel@tonic-gate 	stat_ret = stat(ldap_cred_back, &buf);
27277c478bd9Sstevel@tonic-gate 	if (mode_verbose)
27287c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2729e1dd0a2fSth 		    gettext("recover: stat(%s)=%d\n"),
2730e1dd0a2fSth 		    ldap_cred_back, stat_ret);
27317c478bd9Sstevel@tonic-gate 	if (stat_ret == 0) {
27327c478bd9Sstevel@tonic-gate 		retcode = file_move(ldap_cred_back, NSCREDFILE);
27337c478bd9Sstevel@tonic-gate 		if (mode_verbose)
27347c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2735e1dd0a2fSth 			    gettext("recover: file_move(%s, %s)=%d\n"),
2736e1dd0a2fSth 			    ldap_cred_back, NSCREDFILE, retcode);
27377c478bd9Sstevel@tonic-gate 		if (retcode != 0)
27387c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2739e1dd0a2fSth 			    gettext("recover: file_move(%s, %s) failed\n"),
2740e1dd0a2fSth 			    ldap_cred_back, NSCREDFILE);
27417c478bd9Sstevel@tonic-gate 	}
27427c478bd9Sstevel@tonic-gate 
27437c478bd9Sstevel@tonic-gate 	/* Check for recovery of NIS+ */
27447c478bd9Sstevel@tonic-gate 	stat_ret = stat(NIS_COLDSTART_BACK, &buf);
27457c478bd9Sstevel@tonic-gate 	if (mode_verbose)
27467c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2747e1dd0a2fSth 		    gettext("recover: stat(%s)=%d\n"),
2748e1dd0a2fSth 		    NIS_COLDSTART_BACK, stat_ret);
27497c478bd9Sstevel@tonic-gate 	if (stat_ret == 0) {
27507c478bd9Sstevel@tonic-gate 		if (saveState) {
27517c478bd9Sstevel@tonic-gate 			gStartNisd = START_UNINIT;
27527c478bd9Sstevel@tonic-gate 		}
27537c478bd9Sstevel@tonic-gate 		if (mode_verbose)
27547c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2755e1dd0a2fSth 			    gettext("recover: file_move(%s, %s)\n"),
2756e1dd0a2fSth 			    NIS_COLDSTART_BACK, NIS_COLDSTART);
27577c478bd9Sstevel@tonic-gate 		retcode = file_move(NIS_COLDSTART_BACK, NIS_COLDSTART);
27587c478bd9Sstevel@tonic-gate 		if (retcode != 0)
27597c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2760e1dd0a2fSth 			    gettext("recover: file_move(%s, %s) failed!\n"),
2761e1dd0a2fSth 			    NIS_COLDSTART_BACK, NIS_COLDSTART);
27627c478bd9Sstevel@tonic-gate 	}
27637c478bd9Sstevel@tonic-gate 
27647c478bd9Sstevel@tonic-gate 	/* Check for recovery of NIS(YP) if we have a domainname */
27657c478bd9Sstevel@tonic-gate 	if (domain) {
27667c478bd9Sstevel@tonic-gate 		/* "name" would have to be huge for this, but just in case */
27677c478bd9Sstevel@tonic-gate 		if (strlen(name) >= (BUFSIZE - strlen(LDAP_RESTORE_DIR)))
27687c478bd9Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
27697c478bd9Sstevel@tonic-gate 		if (strlen(name) >= (BUFSIZE - strlen(YP_BIND_DIR)))
27707c478bd9Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
27717c478bd9Sstevel@tonic-gate 
27727c478bd9Sstevel@tonic-gate 		(void) strlcpy(yp_dir_back, LDAP_RESTORE_DIR "/", BUFSIZE);
27737c478bd9Sstevel@tonic-gate 		(void) strlcat(yp_dir_back, name, BUFSIZE);
27747c478bd9Sstevel@tonic-gate 		stat_ret = stat(yp_dir_back, &buf);
27757c478bd9Sstevel@tonic-gate 		if (mode_verbose)
27767c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2777e1dd0a2fSth 			    gettext("recover: stat(%s)=%d\n"),
2778e1dd0a2fSth 			    yp_dir_back, stat_ret);
27797c478bd9Sstevel@tonic-gate 		if (stat_ret == 0) {
27807c478bd9Sstevel@tonic-gate 			(void) strlcpy(yp_dir, YP_BIND_DIR "/", BUFSIZE);
27817c478bd9Sstevel@tonic-gate 			(void) strlcat(yp_dir, name, BUFSIZE);
27827c478bd9Sstevel@tonic-gate 			retcode = file_move(yp_dir_back, yp_dir);
27837c478bd9Sstevel@tonic-gate 			if (mode_verbose)
27847c478bd9Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
2785e1dd0a2fSth 				    gettext("recover: file_move(%s, "
2786e1dd0a2fSth 				    "%s)=%d\n"),
2787e1dd0a2fSth 				    yp_dir_back, yp_dir, retcode);
27887c478bd9Sstevel@tonic-gate 			if (retcode != 0) {
27897c478bd9Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
2790e1dd0a2fSth 				    gettext("recover: file_move(%s, "
2791e1dd0a2fSth 				    "%s) failed!\n"),
2792e1dd0a2fSth 				    yp_dir_back, yp_dir);
27937c478bd9Sstevel@tonic-gate 			} else {
27947c478bd9Sstevel@tonic-gate 				if (saveState)
27957c478bd9Sstevel@tonic-gate 					gStartYp = START_UNINIT;
27967c478bd9Sstevel@tonic-gate 			}
27977c478bd9Sstevel@tonic-gate 		}
27987c478bd9Sstevel@tonic-gate 	}
27997c478bd9Sstevel@tonic-gate 
28007c478bd9Sstevel@tonic-gate 	/* restore machine configuration */
28017c478bd9Sstevel@tonic-gate 	stat_ret = stat(NSSWITCH_BACK, &buf);
28027c478bd9Sstevel@tonic-gate 	if (mode_verbose)
28037c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2804e1dd0a2fSth 		    gettext("recover: stat(%s)=%d\n"),
2805e1dd0a2fSth 		    NSSWITCH_BACK, stat_ret);
28067c478bd9Sstevel@tonic-gate 	if (stat_ret == 0) {
28077c478bd9Sstevel@tonic-gate 		retcode = file_move(NSSWITCH_BACK, NSSWITCH_CONF);
28087c478bd9Sstevel@tonic-gate 		if (mode_verbose)
28097c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2810e1dd0a2fSth 			    gettext("recover: file_move(%s, %s)=%d\n"),
2811e1dd0a2fSth 			    NSSWITCH_BACK, NSSWITCH_CONF, retcode);
28127c478bd9Sstevel@tonic-gate 		if (retcode != 0)
28137c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2814e1dd0a2fSth 			    gettext("recover: file_move(%s, %s) failed\n"),
2815e1dd0a2fSth 			    NSSWITCH_BACK, NSSWITCH_CONF);
28167c478bd9Sstevel@tonic-gate 	}
28177c478bd9Sstevel@tonic-gate 
28187c478bd9Sstevel@tonic-gate 	stat_ret = stat(DOMAINNAME_BACK, &buf);
28197c478bd9Sstevel@tonic-gate 	if (mode_verbose)
28207c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2821e1dd0a2fSth 		    gettext("recover: stat(%s)=%d\n"),
2822e1dd0a2fSth 		    DOMAINNAME_BACK, stat_ret);
28237c478bd9Sstevel@tonic-gate 	if (stat_ret == 0) {
28247c478bd9Sstevel@tonic-gate 		retcode = file_move(DOMAINNAME_BACK, DOMAINNAME);
28257c478bd9Sstevel@tonic-gate 		if (mode_verbose)
28267c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2827e1dd0a2fSth 			    gettext("recover: file_move(%s, %s)=%d\n"),
2828e1dd0a2fSth 			    DOMAINNAME_BACK, DOMAINNAME, retcode);
28297c478bd9Sstevel@tonic-gate 		if (retcode != 0)
28307c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2831e1dd0a2fSth 			    gettext("recover: file_move(%s, %s) failed\n"),
2832e1dd0a2fSth 			    DOMAINNAME_BACK, DOMAINNAME);
28337c478bd9Sstevel@tonic-gate 	}
28347c478bd9Sstevel@tonic-gate 
28357c478bd9Sstevel@tonic-gate 	retcode = rmdir(LDAP_RESTORE_DIR);
28367c478bd9Sstevel@tonic-gate 	if (retcode != 0) {
28377c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2838e1dd0a2fSth 		    gettext("Error removing \"%s\" directory.\n"),
2839e1dd0a2fSth 		    LDAP_RESTORE_DIR);
28407c478bd9Sstevel@tonic-gate 	}
28417c478bd9Sstevel@tonic-gate 
28427c478bd9Sstevel@tonic-gate 	return (CLIENT_SUCCESS);
28437c478bd9Sstevel@tonic-gate }
28447c478bd9Sstevel@tonic-gate 
28457c478bd9Sstevel@tonic-gate /*
28467c478bd9Sstevel@tonic-gate  * try to save the current state of this machine.
28477c478bd9Sstevel@tonic-gate  * this just overwrites any old saved configration files.
28487c478bd9Sstevel@tonic-gate  *
28497c478bd9Sstevel@tonic-gate  * This function should only be called after network services have been stopped.
28507c478bd9Sstevel@tonic-gate  *
28517c478bd9Sstevel@tonic-gate  * Returns 0 on successful save
28527c478bd9Sstevel@tonic-gate  * Otherwise returns -1
28537c478bd9Sstevel@tonic-gate  */
28547c478bd9Sstevel@tonic-gate static int
28557c478bd9Sstevel@tonic-gate file_backup(void)
28567c478bd9Sstevel@tonic-gate {
28577c478bd9Sstevel@tonic-gate 	struct stat buf;
28587c478bd9Sstevel@tonic-gate 	int domain_stat, conf_stat, ldap_stat;
28597c478bd9Sstevel@tonic-gate 	int nis_stat, yp_stat, restore_stat;
28607c478bd9Sstevel@tonic-gate 	int retcode, namelen, ret;
28617c478bd9Sstevel@tonic-gate 	char yp_dir[BUFSIZ], yp_dir_back[BUFSIZ];
28627c478bd9Sstevel@tonic-gate 	char name[BUFSIZ];
28637c478bd9Sstevel@tonic-gate 	char *ldap_conf_file, *ldap_cred_file;
28647c478bd9Sstevel@tonic-gate 	char ldap_file_back[BUFSIZE], ldap_cred_back[BUFSIZE];
28657c478bd9Sstevel@tonic-gate 
28667c478bd9Sstevel@tonic-gate 	ret = CLIENT_SUCCESS;
28677c478bd9Sstevel@tonic-gate 	/* If running as Sysid Install become a no-op */
28687c478bd9Sstevel@tonic-gate 	if (sysid_install == B_TRUE)
28697c478bd9Sstevel@tonic-gate 		return (CLIENT_SUCCESS);
28707c478bd9Sstevel@tonic-gate 
28717c478bd9Sstevel@tonic-gate 	/* If existing backup files, clear for this run */
28727c478bd9Sstevel@tonic-gate 	restore_stat = stat(LDAP_RESTORE_DIR, &buf);
28737c478bd9Sstevel@tonic-gate 	if (restore_stat == 0) {
28747c478bd9Sstevel@tonic-gate 		if (mode_verbose) {
28757c478bd9Sstevel@tonic-gate 			CLIENT_FPUTS(
2876e1dd0a2fSth 			    gettext("Removing existing restore "
2877e1dd0a2fSth 			    "directory\n"),
2878e1dd0a2fSth 			    stderr);
28797c478bd9Sstevel@tonic-gate 		}
28807c478bd9Sstevel@tonic-gate 		(void) system("/bin/rm -fr " LDAP_RESTORE_DIR);
28817c478bd9Sstevel@tonic-gate 		restore_stat = stat(LDAP_RESTORE_DIR, &buf);
28827c478bd9Sstevel@tonic-gate 		if (restore_stat == 0) {
28837c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2884e1dd0a2fSth 			    gettext("Unable to remove backup "
2885e1dd0a2fSth 			    "directory (%s)\n"),
2886e1dd0a2fSth 			    LDAP_RESTORE_DIR);
28877c478bd9Sstevel@tonic-gate 			return (CLIENT_ERR_RESTORE);
28887c478bd9Sstevel@tonic-gate 		}
28897c478bd9Sstevel@tonic-gate 	}
28907c478bd9Sstevel@tonic-gate 
28917c478bd9Sstevel@tonic-gate 	retcode = mkdir(LDAP_RESTORE_DIR, 0755);
28927c478bd9Sstevel@tonic-gate 	if (retcode != 0) {
28937c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2894e1dd0a2fSth 		    gettext("file_backup: Failed to make %s backup "
2895e1dd0a2fSth 		    "directory. mkdir=%d\n"),
2896e1dd0a2fSth 		    LDAP_RESTORE_DIR, retcode);
28977c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
28987c478bd9Sstevel@tonic-gate 	}
28997c478bd9Sstevel@tonic-gate 
29007c478bd9Sstevel@tonic-gate 	conf_stat = stat(NSSWITCH_CONF, &buf);
29017c478bd9Sstevel@tonic-gate 	if (mode_verbose)
29027c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2903e1dd0a2fSth 		    gettext("file_backup: stat(%s)=%d\n"),
2904e1dd0a2fSth 		    NSSWITCH_CONF, conf_stat);
29057c478bd9Sstevel@tonic-gate 	if (conf_stat == 0) {
29067c478bd9Sstevel@tonic-gate 		if (mode_verbose)
29077c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2908e1dd0a2fSth 			    gettext("file_backup: (%s -> %s)\n"),
2909e1dd0a2fSth 			    NSSWITCH_CONF, NSSWITCH_BACK);
29107c478bd9Sstevel@tonic-gate 		retcode = file_move(NSSWITCH_CONF, NSSWITCH_BACK);
29117c478bd9Sstevel@tonic-gate 		if (retcode != 0) {
29127c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2913e1dd0a2fSth 			    gettext("file_backup: file_move(%s, %s) failed "
2914e1dd0a2fSth 			    "with %d\n"),
2915e1dd0a2fSth 			    NSSWITCH_CONF, NSSWITCH_BACK, retcode);
29167c478bd9Sstevel@tonic-gate 			ret = CLIENT_ERR_RENAME;
29177c478bd9Sstevel@tonic-gate 		}
29187c478bd9Sstevel@tonic-gate 	} else {
29197c478bd9Sstevel@tonic-gate 		if (mode_verbose)
29207c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2921e1dd0a2fSth 			    gettext("file_backup: No %s file.\n"),
2922e1dd0a2fSth 			    NSSWITCH_CONF);
29237c478bd9Sstevel@tonic-gate 	}
29247c478bd9Sstevel@tonic-gate 
29257c478bd9Sstevel@tonic-gate 	domain_stat = stat(DOMAINNAME, &buf);
29267c478bd9Sstevel@tonic-gate 	if (mode_verbose)
29277c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2928e1dd0a2fSth 		    gettext("file_backup: stat(%s)=%d\n"),
2929e1dd0a2fSth 		    DOMAINNAME, domain_stat);
29307c478bd9Sstevel@tonic-gate 	if ((domain_stat == 0) && (buf.st_size > 0)) {
29317c478bd9Sstevel@tonic-gate 		if (mode_verbose)
29327c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2933e1dd0a2fSth 			    gettext("file_backup: (%s -> %s)\n"),
2934e1dd0a2fSth 			    DOMAINNAME, DOMAINNAME_BACK);
29357c478bd9Sstevel@tonic-gate 		retcode = file_move(DOMAINNAME, DOMAINNAME_BACK);
29367c478bd9Sstevel@tonic-gate 		if (retcode != 0) {
29377c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2938e1dd0a2fSth 			    gettext("file_backup: file_move(%s, %s) failed "
2939e1dd0a2fSth 			    "with %d\n"),
2940e1dd0a2fSth 			    DOMAINNAME, DOMAINNAME_BACK, retcode);
29417c478bd9Sstevel@tonic-gate 			ret = CLIENT_ERR_RENAME;
29427c478bd9Sstevel@tonic-gate 		}
29437c478bd9Sstevel@tonic-gate 	} else {
29447c478bd9Sstevel@tonic-gate 		if (mode_verbose)
29457c478bd9Sstevel@tonic-gate 			if (domain_stat != 0) {
29467c478bd9Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
2947e1dd0a2fSth 				    gettext("file_backup: No %s file.\n"),
2948e1dd0a2fSth 				    DOMAINNAME);
29497c478bd9Sstevel@tonic-gate 			} else {
29507c478bd9Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
2951e1dd0a2fSth 				    gettext("file_backup: Empty %s "
2952e1dd0a2fSth 				    "file.\n"),
2953e1dd0a2fSth 				    DOMAINNAME);
29547c478bd9Sstevel@tonic-gate 			}
29557c478bd9Sstevel@tonic-gate 	}
29567c478bd9Sstevel@tonic-gate 
29577c478bd9Sstevel@tonic-gate 	nis_stat = stat(NIS_COLDSTART, &buf);
29587c478bd9Sstevel@tonic-gate 	if (mode_verbose)
29597c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2960e1dd0a2fSth 		    gettext("file_backup: stat(%s)=%d\n"),
2961e1dd0a2fSth 		    NIS_COLDSTART, nis_stat);
29627c478bd9Sstevel@tonic-gate 	if (nis_stat == 0) {
29637c478bd9Sstevel@tonic-gate 		if (mode_verbose)
29647c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2965e1dd0a2fSth 			    gettext("file_backup: (%s -> %s)\n"),
2966e1dd0a2fSth 			    NIS_COLDSTART, NIS_COLDSTART_BACK);
29677c478bd9Sstevel@tonic-gate 		retcode = file_move(NIS_COLDSTART, NIS_COLDSTART_BACK);
29687c478bd9Sstevel@tonic-gate 		if (retcode != 0) {
29697c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2970e1dd0a2fSth 			    gettext("file_backup: file_move(%s, %s) failed "
2971e1dd0a2fSth 			    "with %d\n"),
2972e1dd0a2fSth 			    NIS_COLDSTART, NIS_COLDSTART_BACK, retcode);
29737c478bd9Sstevel@tonic-gate 			ret = CLIENT_ERR_RENAME;
29747c478bd9Sstevel@tonic-gate 		}
29757c478bd9Sstevel@tonic-gate 	} else {
29767c478bd9Sstevel@tonic-gate 		if (mode_verbose)
29777c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2978e1dd0a2fSth 			    gettext("file_backup: No %s file.\n"),
2979e1dd0a2fSth 			    NIS_COLDSTART);
29807c478bd9Sstevel@tonic-gate 	}
29817c478bd9Sstevel@tonic-gate 
29827c478bd9Sstevel@tonic-gate 	namelen = BUFSIZ;
29837c478bd9Sstevel@tonic-gate 	(void) sysinfo(SI_SRPC_DOMAIN, &(name[0]), namelen);
29847c478bd9Sstevel@tonic-gate 	namelen = strlen(name);
29857c478bd9Sstevel@tonic-gate 
29867c478bd9Sstevel@tonic-gate 	if (mode_verbose)
29877c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
2988e1dd0a2fSth 		    gettext("file_backup: nis domain is \"%s\"\n"),
2989e1dd0a2fSth 		    (namelen > 0) ? name : "EMPTY");
29907c478bd9Sstevel@tonic-gate 	/* check for domain name if not set cannot save NIS(YP) state */
29917c478bd9Sstevel@tonic-gate 	if (namelen > 0) {
29927c478bd9Sstevel@tonic-gate 		/* moving /var/yp/binding will cause ypbind to core dump */
29937c478bd9Sstevel@tonic-gate 		(void) strlcpy(yp_dir, YP_BIND_DIR "/", BUFSIZE);
29947c478bd9Sstevel@tonic-gate 		(void) strlcat(yp_dir, name, BUFSIZE);
29957c478bd9Sstevel@tonic-gate 		yp_stat = stat(yp_dir, &buf);
29967c478bd9Sstevel@tonic-gate 		if (mode_verbose)
29977c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
2998e1dd0a2fSth 			    gettext("file_backup: stat(%s)=%d\n"),
2999e1dd0a2fSth 			    yp_dir, yp_stat);
30007c478bd9Sstevel@tonic-gate 		if (yp_stat == 0) {
30017c478bd9Sstevel@tonic-gate 			(void) strlcpy(yp_dir_back, LDAP_RESTORE_DIR "/",
3002e1dd0a2fSth 			    BUFSIZE);
30037c478bd9Sstevel@tonic-gate 			(void) strlcat(yp_dir_back, name, BUFSIZE);
30047c478bd9Sstevel@tonic-gate 			if (mode_verbose)
30057c478bd9Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
3006e1dd0a2fSth 				    gettext("file_backup: (%s -> %s)\n"),
3007e1dd0a2fSth 				    yp_dir, yp_dir_back);
30087c478bd9Sstevel@tonic-gate 			retcode = file_move(yp_dir, yp_dir_back);
30097c478bd9Sstevel@tonic-gate 			if (retcode != 0) {
30107c478bd9Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
3011e1dd0a2fSth 				    gettext("file_backup: file_move(%s, %s)"
3012e1dd0a2fSth 				    " failed with %d\n"),
3013e1dd0a2fSth 				    yp_dir, yp_dir_back, retcode);
30147c478bd9Sstevel@tonic-gate 				ret = CLIENT_ERR_RENAME;
30157c478bd9Sstevel@tonic-gate 			}
30167c478bd9Sstevel@tonic-gate 		} else {
30177c478bd9Sstevel@tonic-gate 			if (mode_verbose)
30187c478bd9Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
3019e1dd0a2fSth 				    gettext("file_backup: No %s "
3020e1dd0a2fSth 				    "directory.\n"), yp_dir);
30217c478bd9Sstevel@tonic-gate 		}
30227c478bd9Sstevel@tonic-gate 	}
30237c478bd9Sstevel@tonic-gate 
30247c478bd9Sstevel@tonic-gate 
30257c478bd9Sstevel@tonic-gate 	/* point to file name, not path delim (/) */
30267c478bd9Sstevel@tonic-gate 	ldap_conf_file = strrchr(NSCONFIGFILE, '/') + 1;
30277c478bd9Sstevel@tonic-gate 	ldap_cred_file = strrchr(NSCREDFILE, '/') + 1;
30287c478bd9Sstevel@tonic-gate 
30297c478bd9Sstevel@tonic-gate 	ldap_stat = stat(NSCONFIGFILE, &buf);
30307c478bd9Sstevel@tonic-gate 	if (mode_verbose)
30317c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
3032e1dd0a2fSth 		    gettext("file_backup: stat(%s)=%d\n"),
3033e1dd0a2fSth 		    NSCONFIGFILE, ldap_stat);
30347c478bd9Sstevel@tonic-gate 	if (ldap_stat == 0) {
30357c478bd9Sstevel@tonic-gate 		(void) strlcpy(ldap_file_back, LDAP_RESTORE_DIR "/", BUFSIZE);
30367c478bd9Sstevel@tonic-gate 		(void) strlcat(ldap_file_back, ldap_conf_file, BUFSIZE);
30377c478bd9Sstevel@tonic-gate 		if (mode_verbose)
30387c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
3039e1dd0a2fSth 			    gettext("file_backup: (%s -> %s)\n"),
3040e1dd0a2fSth 			    NSCONFIGFILE, ldap_file_back);
30417c478bd9Sstevel@tonic-gate 		retcode = file_move(NSCONFIGFILE, ldap_file_back);
30427c478bd9Sstevel@tonic-gate 		if (retcode != 0) {
30437c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
3044e1dd0a2fSth 			    gettext("file_backup: file_move(%s, %s) failed "
3045e1dd0a2fSth 			    "with %d\n"),
3046e1dd0a2fSth 			    NSCONFIGFILE, ldap_file_back, retcode);
30477c478bd9Sstevel@tonic-gate 			ret = CLIENT_ERR_RENAME;
30487c478bd9Sstevel@tonic-gate 		}
30497c478bd9Sstevel@tonic-gate 
30507c478bd9Sstevel@tonic-gate 		(void) strlcpy(ldap_cred_back, LDAP_RESTORE_DIR "/", BUFSIZE);
30517c478bd9Sstevel@tonic-gate 		(void) strlcat(ldap_cred_back, ldap_cred_file, BUFSIZE);
30527c478bd9Sstevel@tonic-gate 		if (mode_verbose)
30537c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
3054e1dd0a2fSth 			    gettext("file_backup: (%s -> %s)\n"),
3055e1dd0a2fSth 			    NSCREDFILE, ldap_cred_back);
30567c478bd9Sstevel@tonic-gate 		retcode = file_move(NSCREDFILE, ldap_cred_back);
30577c478bd9Sstevel@tonic-gate 		if (retcode != 0) {
30587c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
3059e1dd0a2fSth 			    gettext("file_backup: file_move(%s, %s) failed "
3060e1dd0a2fSth 			    "with %d\n"),
3061e1dd0a2fSth 			    NSCREDFILE, ldap_cred_back, retcode);
30627c478bd9Sstevel@tonic-gate 			ret = CLIENT_ERR_RENAME;
30637c478bd9Sstevel@tonic-gate 		}
30647c478bd9Sstevel@tonic-gate 	} else {
30657c478bd9Sstevel@tonic-gate 		if (mode_verbose)
30667c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
3067e1dd0a2fSth 			    gettext("file_backup: No %s file.\n"),
3068e1dd0a2fSth 			    NSCONFIGFILE);
30697c478bd9Sstevel@tonic-gate 	}
30707c478bd9Sstevel@tonic-gate 
30717c478bd9Sstevel@tonic-gate 	return (ret);
30727c478bd9Sstevel@tonic-gate }
30737c478bd9Sstevel@tonic-gate 
30747c478bd9Sstevel@tonic-gate /*
30757c478bd9Sstevel@tonic-gate  * mod_backup()
30767c478bd9Sstevel@tonic-gate  *
30777c478bd9Sstevel@tonic-gate  * This function is used to temporily backup the LDAP client files in /var/ldap
30787c478bd9Sstevel@tonic-gate  * that the "mod" operation needs to update.  If an error occurs then the
30797c478bd9Sstevel@tonic-gate  * function mod_recover() can be invoke to recover the unmodified files.
30807c478bd9Sstevel@tonic-gate  */
30817c478bd9Sstevel@tonic-gate static int
30827c478bd9Sstevel@tonic-gate mod_backup(void)
30837c478bd9Sstevel@tonic-gate {
30847c478bd9Sstevel@tonic-gate 	int rc;
30857c478bd9Sstevel@tonic-gate 	int retcode = CLIENT_SUCCESS;
30867c478bd9Sstevel@tonic-gate 
30877c478bd9Sstevel@tonic-gate 	rc = system(CMD_CP " " NSCONFIGFILE " " NSCONFIGFILE ".mod");
30887c478bd9Sstevel@tonic-gate 	retcode += rc;
30897c478bd9Sstevel@tonic-gate 	if (mode_verbose)
30907c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
30917c478bd9Sstevel@tonic-gate 		    gettext("mod_backup: backup %s for %s\n"),
30927c478bd9Sstevel@tonic-gate 		    rc ? "failed" : "successful", NSCONFIGFILE);
30937c478bd9Sstevel@tonic-gate 
30947c478bd9Sstevel@tonic-gate 	rc = system(CMD_CP " " NSCREDFILE " " NSCREDFILE ".mod");
30957c478bd9Sstevel@tonic-gate 	retcode += rc;
30967c478bd9Sstevel@tonic-gate 	if (mode_verbose)
30977c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
30987c478bd9Sstevel@tonic-gate 		    gettext("mod_backup: backup %s for %s\n"),
30997c478bd9Sstevel@tonic-gate 		    rc ? "failed" : "successful", NSCREDFILE);
31007c478bd9Sstevel@tonic-gate 
31017c478bd9Sstevel@tonic-gate 	rc = system(CMD_CP " " DOMAINNAME " " DOMAINNAME ".mod");
31027c478bd9Sstevel@tonic-gate 	retcode += rc;
31037c478bd9Sstevel@tonic-gate 	if (mode_verbose)
31047c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
31057c478bd9Sstevel@tonic-gate 		    gettext("mod_backup: backup %s for %s\n"),
31067c478bd9Sstevel@tonic-gate 		    rc ? "failed" : "successful", DOMAINNAME);
31077c478bd9Sstevel@tonic-gate 
31087c478bd9Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS)
31097c478bd9Sstevel@tonic-gate 		retcode = CLIENT_ERR_RENAME;
31107c478bd9Sstevel@tonic-gate 	return (retcode);
31117c478bd9Sstevel@tonic-gate }
31127c478bd9Sstevel@tonic-gate 
31137c478bd9Sstevel@tonic-gate /*
31147c478bd9Sstevel@tonic-gate  * mod_recover()
31157c478bd9Sstevel@tonic-gate  *
31167c478bd9Sstevel@tonic-gate  * This function is used to recover the temporily backed up files by
31177c478bd9Sstevel@tonic-gate  * the mod_backup() function if an error occurs during the "mod"
31187c478bd9Sstevel@tonic-gate  * operation.
31197c478bd9Sstevel@tonic-gate  */
31207c478bd9Sstevel@tonic-gate static int
31217c478bd9Sstevel@tonic-gate mod_recover(void)
31227c478bd9Sstevel@tonic-gate {
31237c478bd9Sstevel@tonic-gate 	int rc;
31247c478bd9Sstevel@tonic-gate 	int retcode = CLIENT_SUCCESS;
31257c478bd9Sstevel@tonic-gate 
31267c478bd9Sstevel@tonic-gate 	rc = system(CMD_MV " " NSCONFIGFILE ".mod " NSCONFIGFILE);
31277c478bd9Sstevel@tonic-gate 	retcode += rc;
31287c478bd9Sstevel@tonic-gate 	if (mode_verbose)
31297c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
31307c478bd9Sstevel@tonic-gate 		    gettext("mod_recover: recovery %s for %s\n"),
31317c478bd9Sstevel@tonic-gate 		    rc ? "failed" : "successful", NSCONFIGFILE);
31327c478bd9Sstevel@tonic-gate 
31337c478bd9Sstevel@tonic-gate 	rc = system(CMD_MV " " NSCREDFILE ".mod " NSCREDFILE);
31347c478bd9Sstevel@tonic-gate 	retcode += rc;
31357c478bd9Sstevel@tonic-gate 	if (mode_verbose)
31367c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
31377c478bd9Sstevel@tonic-gate 		    gettext("mod_recover: recovery %s for %s\n"),
31387c478bd9Sstevel@tonic-gate 		    rc ? "failed" : "successful", NSCREDFILE);
31397c478bd9Sstevel@tonic-gate 
31407c478bd9Sstevel@tonic-gate 	rc = system(CMD_MV " " DOMAINNAME ".mod " DOMAINNAME);
31417c478bd9Sstevel@tonic-gate 	retcode += rc;
31427c478bd9Sstevel@tonic-gate 	if (mode_verbose)
31437c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
31447c478bd9Sstevel@tonic-gate 		    gettext("mod_recover: recovery %s for %s\n"),
31457c478bd9Sstevel@tonic-gate 		    rc ? "failed" : "successful", DOMAINNAME);
31467c478bd9Sstevel@tonic-gate 
31477c478bd9Sstevel@tonic-gate 	if (retcode != CLIENT_SUCCESS)
31487c478bd9Sstevel@tonic-gate 		retcode = CLIENT_ERR_RENAME;
31497c478bd9Sstevel@tonic-gate 	return (retcode);
31507c478bd9Sstevel@tonic-gate }
31517c478bd9Sstevel@tonic-gate 
31527c478bd9Sstevel@tonic-gate /*
31537c478bd9Sstevel@tonic-gate  * mod_cleanup()
31547c478bd9Sstevel@tonic-gate  *
31557c478bd9Sstevel@tonic-gate  * This function removes the .mod files in /var/ldap.
31567c478bd9Sstevel@tonic-gate  */
31577c478bd9Sstevel@tonic-gate static void
31587c478bd9Sstevel@tonic-gate mod_cleanup(void)
31597c478bd9Sstevel@tonic-gate {
31607c478bd9Sstevel@tonic-gate 	(void) system(CMD_RM " " NSCONFIGFILE ".mod " TO_DEV_NULL);
31617c478bd9Sstevel@tonic-gate 	(void) system(CMD_RM " " NSCREDFILE ".mod " TO_DEV_NULL);
31627c478bd9Sstevel@tonic-gate 	(void) system(CMD_RM " " DOMAINNAME ".mod " TO_DEV_NULL);
31637c478bd9Sstevel@tonic-gate }
31647c478bd9Sstevel@tonic-gate 
31657c478bd9Sstevel@tonic-gate #define	MAX_DN_ARRAY 100
31667c478bd9Sstevel@tonic-gate #define	LDAP_NAMINGCONTEXTS	"namingcontexts"
31677c478bd9Sstevel@tonic-gate 
31687c478bd9Sstevel@tonic-gate static multival_t *
31697c478bd9Sstevel@tonic-gate multival_new()
31707c478bd9Sstevel@tonic-gate {
31717c478bd9Sstevel@tonic-gate 	multival_t *hold;
31727c478bd9Sstevel@tonic-gate 
31737c478bd9Sstevel@tonic-gate 	hold = calloc(1, sizeof (multival_t));
31747c478bd9Sstevel@tonic-gate 	if (hold == NULL) {
31757c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
3176e1dd0a2fSth 		    gettext("multival_new: Memory allocation error\n"),
3177e1dd0a2fSth 		    stderr);
31787c478bd9Sstevel@tonic-gate 	}
31797c478bd9Sstevel@tonic-gate 	return (hold);	/* NULL -> error */
31807c478bd9Sstevel@tonic-gate }
31817c478bd9Sstevel@tonic-gate 
31827c478bd9Sstevel@tonic-gate static int
31837c478bd9Sstevel@tonic-gate multival_add(multival_t *list, char *opt)
31847c478bd9Sstevel@tonic-gate {
31857c478bd9Sstevel@tonic-gate 	if (opt == NULL) {
31867c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
3187e1dd0a2fSth 		    gettext("Empty value passed to multival_add\n"),
3188e1dd0a2fSth 		    stderr);
31897c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
31907c478bd9Sstevel@tonic-gate 	}
31917c478bd9Sstevel@tonic-gate 
31927c478bd9Sstevel@tonic-gate 	if (list->count == 0) {
31937c478bd9Sstevel@tonic-gate 		list->optlist = (char **)malloc(sizeof (char **));
31947c478bd9Sstevel@tonic-gate 	} else {
31957c478bd9Sstevel@tonic-gate 		list->optlist = (char **)realloc(list->optlist,
3196e1dd0a2fSth 		    (list->count + 1) * sizeof (char **));
31977c478bd9Sstevel@tonic-gate 	}
31987c478bd9Sstevel@tonic-gate 
31997c478bd9Sstevel@tonic-gate 	if (list->optlist == NULL) {
32007c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error allocating memory\n"), stderr);
32017c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_MEMORY);	/* 0 is success */
32027c478bd9Sstevel@tonic-gate 	}
32037c478bd9Sstevel@tonic-gate 
32047c478bd9Sstevel@tonic-gate 	list->optlist[list->count] = opt;
32057c478bd9Sstevel@tonic-gate 	list->count++;
32067c478bd9Sstevel@tonic-gate 
32077c478bd9Sstevel@tonic-gate 	return (CLIENT_SUCCESS);
32087c478bd9Sstevel@tonic-gate }
32097c478bd9Sstevel@tonic-gate 
32107c478bd9Sstevel@tonic-gate static void
32117c478bd9Sstevel@tonic-gate multival_free(multival_t *list)
32127c478bd9Sstevel@tonic-gate {
32137c478bd9Sstevel@tonic-gate 	if (list == NULL)
32147c478bd9Sstevel@tonic-gate 		return;
32157c478bd9Sstevel@tonic-gate 
32167c478bd9Sstevel@tonic-gate 	if (list->optlist != NULL)
32177c478bd9Sstevel@tonic-gate 		free(list->optlist);
32187c478bd9Sstevel@tonic-gate 	free(list);
32197c478bd9Sstevel@tonic-gate }
32207c478bd9Sstevel@tonic-gate 
32217c478bd9Sstevel@tonic-gate static clientopts_t *
32227c478bd9Sstevel@tonic-gate clientopts_new()
32237c478bd9Sstevel@tonic-gate {
32247c478bd9Sstevel@tonic-gate 	clientopts_t *hold;
32257c478bd9Sstevel@tonic-gate 
32267c478bd9Sstevel@tonic-gate 	hold = calloc(1, sizeof (clientopts_t));
32277c478bd9Sstevel@tonic-gate 	if (NULL == hold) {
32287c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error allocating memory for "
3229e1dd0a2fSth 		    "clientopts structure\n"), stderr);
32307c478bd9Sstevel@tonic-gate 		return (hold);	/* NULL -> error */
32317c478bd9Sstevel@tonic-gate 	}
32327c478bd9Sstevel@tonic-gate 
32337c478bd9Sstevel@tonic-gate 	hold->serviceAuthenticationMethod = multival_new();
32347c478bd9Sstevel@tonic-gate 	if (NULL == hold->serviceAuthenticationMethod) {
32357c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error allocating memory for "
3236e1dd0a2fSth 		    "serviceAuthenticationMethod\n"), stderr);
32377c478bd9Sstevel@tonic-gate 		free(hold);
32387c478bd9Sstevel@tonic-gate 		return (NULL);	/* NULL -> error */
32397c478bd9Sstevel@tonic-gate 	}
32407c478bd9Sstevel@tonic-gate 
32417c478bd9Sstevel@tonic-gate 	hold->serviceCredentialLevel = multival_new();
32427c478bd9Sstevel@tonic-gate 	if (NULL == hold->serviceCredentialLevel) {
32437c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error allocating memory for "
3244e1dd0a2fSth 		    "serviceCredentialLevel\n"), stderr);
32457c478bd9Sstevel@tonic-gate 		multival_free(hold->serviceAuthenticationMethod);
32467c478bd9Sstevel@tonic-gate 		free(hold);
32477c478bd9Sstevel@tonic-gate 		return (NULL);	/* NULL -> error */
32487c478bd9Sstevel@tonic-gate 	}
32497c478bd9Sstevel@tonic-gate 
32507c478bd9Sstevel@tonic-gate 	hold->objectclassMap = multival_new();
32517c478bd9Sstevel@tonic-gate 	if (NULL == hold->objectclassMap) {
32527c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error allocating memory for "
3253e1dd0a2fSth 		    "objectclassMap\n"), stderr);
32547c478bd9Sstevel@tonic-gate 		multival_free(hold->serviceAuthenticationMethod);
32557c478bd9Sstevel@tonic-gate 		multival_free(hold->serviceCredentialLevel);
32567c478bd9Sstevel@tonic-gate 		free(hold);
32577c478bd9Sstevel@tonic-gate 		return (NULL);	/* NULL -> error */
32587c478bd9Sstevel@tonic-gate 	}
32597c478bd9Sstevel@tonic-gate 
32607c478bd9Sstevel@tonic-gate 	hold->attributeMap = multival_new();
32617c478bd9Sstevel@tonic-gate 	if (NULL == hold->attributeMap) {
32627c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error allocating memory for "
3263e1dd0a2fSth 		    "attributeMap\n"), stderr);
32647c478bd9Sstevel@tonic-gate 		multival_free(hold->serviceAuthenticationMethod);
32657c478bd9Sstevel@tonic-gate 		multival_free(hold->serviceCredentialLevel);
32667c478bd9Sstevel@tonic-gate 		multival_free(hold->objectclassMap);
32677c478bd9Sstevel@tonic-gate 		free(hold);
32687c478bd9Sstevel@tonic-gate 		return (NULL);	/* NULL -> error */
32697c478bd9Sstevel@tonic-gate 	}
32707c478bd9Sstevel@tonic-gate 
32717c478bd9Sstevel@tonic-gate 	hold->serviceSearchDescriptor = multival_new();
32727c478bd9Sstevel@tonic-gate 	if (NULL == hold->serviceSearchDescriptor) {
32737c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(gettext("Error allocating memory for "
3274e1dd0a2fSth 		    "serviceSearchDescriptor\n"), stderr);
32757c478bd9Sstevel@tonic-gate 		multival_free(hold->serviceAuthenticationMethod);
32767c478bd9Sstevel@tonic-gate 		multival_free(hold->serviceCredentialLevel);
32777c478bd9Sstevel@tonic-gate 		multival_free(hold->objectclassMap);
32787c478bd9Sstevel@tonic-gate 		multival_free(hold->attributeMap);
32797c478bd9Sstevel@tonic-gate 		free(hold);
32807c478bd9Sstevel@tonic-gate 		return (NULL);	/* NULL -> error */
32817c478bd9Sstevel@tonic-gate 	}
32827c478bd9Sstevel@tonic-gate 
32837c478bd9Sstevel@tonic-gate 	return (hold);
32847c478bd9Sstevel@tonic-gate }
32857c478bd9Sstevel@tonic-gate 
32867c478bd9Sstevel@tonic-gate static void
32877c478bd9Sstevel@tonic-gate clientopts_free(clientopts_t *list)
32887c478bd9Sstevel@tonic-gate {
32897c478bd9Sstevel@tonic-gate 	if (NULL == list)
32907c478bd9Sstevel@tonic-gate 		return;
32917c478bd9Sstevel@tonic-gate 
32927c478bd9Sstevel@tonic-gate 	multival_free(list->serviceAuthenticationMethod);
32937c478bd9Sstevel@tonic-gate 	multival_free(list->serviceCredentialLevel);
32947c478bd9Sstevel@tonic-gate 	multival_free(list->objectclassMap);
32957c478bd9Sstevel@tonic-gate 	multival_free(list->attributeMap);
32967c478bd9Sstevel@tonic-gate 	multival_free(list->serviceSearchDescriptor);
32977c478bd9Sstevel@tonic-gate 
32987c478bd9Sstevel@tonic-gate 	free(list);
32997c478bd9Sstevel@tonic-gate 
33007c478bd9Sstevel@tonic-gate }
33017c478bd9Sstevel@tonic-gate 
33027c478bd9Sstevel@tonic-gate static void
33037c478bd9Sstevel@tonic-gate multival_list(char *opt, multival_t *list)
33047c478bd9Sstevel@tonic-gate {
33057c478bd9Sstevel@tonic-gate 	int i;
33067c478bd9Sstevel@tonic-gate 
33077c478bd9Sstevel@tonic-gate 	if (list->count == 0)
33087c478bd9Sstevel@tonic-gate 		return;
33097c478bd9Sstevel@tonic-gate 
33107c478bd9Sstevel@tonic-gate 	(void) puts(opt);
33117c478bd9Sstevel@tonic-gate 	for (i = 0; i < list->count; i++) {
33127c478bd9Sstevel@tonic-gate 		(void) printf("\t\targ[%d]: %s\n", i, list->optlist[i]);
33137c478bd9Sstevel@tonic-gate 	}
33147c478bd9Sstevel@tonic-gate }
33157c478bd9Sstevel@tonic-gate 
33167c478bd9Sstevel@tonic-gate /* return the number of arguments specified in the command line */
33177c478bd9Sstevel@tonic-gate static int
33187c478bd9Sstevel@tonic-gate num_args(clientopts_t *list)
33197c478bd9Sstevel@tonic-gate {
33207c478bd9Sstevel@tonic-gate 	int arg_count = 0;
33217c478bd9Sstevel@tonic-gate 
33227c478bd9Sstevel@tonic-gate 	arg_count += list->authenticationMethod ? 1 : 0;
33237c478bd9Sstevel@tonic-gate 	arg_count += list->serviceAuthenticationMethod->count;
33247c478bd9Sstevel@tonic-gate 	arg_count += list->defaultSearchBase ? 1 : 0;
33257c478bd9Sstevel@tonic-gate 	arg_count += list->credentialLevel ? 1 : 0;
33267c478bd9Sstevel@tonic-gate 	arg_count += list->serviceCredentialLevel->count;
33277c478bd9Sstevel@tonic-gate 	arg_count += list->domainName ? 1 : 0;
33287c478bd9Sstevel@tonic-gate 	arg_count += list->proxyDN ? 1 : 0;
3329*dd1104fbSMichen Chang 	arg_count += list->enableShadowUpdate ? 1 : 0;
3330*dd1104fbSMichen Chang 	arg_count += list->adminDN ? 1 : 0;
33317c478bd9Sstevel@tonic-gate 	arg_count += list->profileTTL ? 1 : 0;
33327c478bd9Sstevel@tonic-gate 	arg_count += list->objectclassMap->count;
33337c478bd9Sstevel@tonic-gate 	arg_count += list->searchTimeLimit ? 1 : 0;
33347c478bd9Sstevel@tonic-gate 	arg_count += list->preferredServerList ? 1 : 0;
33357c478bd9Sstevel@tonic-gate 	arg_count += list->profileName ? 1 : 0;
33367c478bd9Sstevel@tonic-gate 	arg_count += list->followReferrals ? 1 : 0;
33377c478bd9Sstevel@tonic-gate 	arg_count += list->attributeMap->count;
33387c478bd9Sstevel@tonic-gate 	arg_count += list->defaultSearchScope ? 1 : 0;
33397c478bd9Sstevel@tonic-gate 	arg_count += list->serviceSearchDescriptor->count;
33407c478bd9Sstevel@tonic-gate 	arg_count += list->bindTimeLimit ? 1 : 0;
33417c478bd9Sstevel@tonic-gate 	arg_count += list->proxyPassword ? 1 : 0;
3342*dd1104fbSMichen Chang 	arg_count += list->adminPassword ? 1 : 0;
33437c478bd9Sstevel@tonic-gate 	arg_count += list->defaultServerList ? 1 : 0;
33447c478bd9Sstevel@tonic-gate 	arg_count += list->certificatePath ? 1 : 0;
33457c478bd9Sstevel@tonic-gate 
33467c478bd9Sstevel@tonic-gate 	return (arg_count);
33477c478bd9Sstevel@tonic-gate }
33487c478bd9Sstevel@tonic-gate 
33497c478bd9Sstevel@tonic-gate #define	CLIENT_PRINT(opt, str) if (str) \
33507c478bd9Sstevel@tonic-gate 		(void) printf("%s%s\n", (opt), (str))
33517c478bd9Sstevel@tonic-gate 
33527c478bd9Sstevel@tonic-gate static void
33537c478bd9Sstevel@tonic-gate dumpargs(clientopts_t *list)
33547c478bd9Sstevel@tonic-gate {
33557c478bd9Sstevel@tonic-gate 	CLIENT_PRINT("\tauthenticationMethod: ", list->authenticationMethod);
33567c478bd9Sstevel@tonic-gate 	multival_list("\tserviceAuthenticationMethod: ",
3357e1dd0a2fSth 	    list->serviceAuthenticationMethod);
33587c478bd9Sstevel@tonic-gate 	CLIENT_PRINT("\tdefaultSearchBase: ", list->defaultSearchBase);
33597c478bd9Sstevel@tonic-gate 	CLIENT_PRINT("\tcredentialLevel: ", list->credentialLevel);
33607c478bd9Sstevel@tonic-gate 	multival_list("\tserviceCredentialLevel: ",
3361e1dd0a2fSth 	    list->serviceCredentialLevel);
33627c478bd9Sstevel@tonic-gate 	CLIENT_PRINT("\tdomainName: ", list->domainName);
33637c478bd9Sstevel@tonic-gate 	CLIENT_PRINT("\tproxyDN: ", list->proxyDN);
3364*dd1104fbSMichen Chang 	CLIENT_PRINT("\tadminDN: ", list->adminDN);
3365*dd1104fbSMichen Chang 	CLIENT_PRINT("\tenableShadowUpdate: ", list->enableShadowUpdate);
33667c478bd9Sstevel@tonic-gate 	CLIENT_PRINT("\tprofileTTL: ", list->profileTTL);
33677c478bd9Sstevel@tonic-gate 	multival_list("\tobjectclassMap: ", list->objectclassMap);
33687c478bd9Sstevel@tonic-gate 	CLIENT_PRINT("\tsearchTimeLimit: ", list->searchTimeLimit);
33697c478bd9Sstevel@tonic-gate 	CLIENT_PRINT("\tpreferredServerList: ", list->preferredServerList);
33707c478bd9Sstevel@tonic-gate 	CLIENT_PRINT("\tprofileName: ", list->profileName);
33717c478bd9Sstevel@tonic-gate 	CLIENT_PRINT("\tfollowReferrals: ", list->followReferrals);
33727c478bd9Sstevel@tonic-gate 	multival_list("\tattributeMap: ", list->attributeMap);
33737c478bd9Sstevel@tonic-gate 	CLIENT_PRINT("\tdefaultSearchScope: ", list->defaultSearchScope);
33747c478bd9Sstevel@tonic-gate 	multival_list("\tserviceSearchDescriptor: ",
3375e1dd0a2fSth 	    list->serviceSearchDescriptor);
33767c478bd9Sstevel@tonic-gate 	CLIENT_PRINT("\tbindTimeLimit: ", list->bindTimeLimit);
33777c478bd9Sstevel@tonic-gate 	CLIENT_PRINT("\tproxyPassword: ", list->proxyPassword);
3378*dd1104fbSMichen Chang 	CLIENT_PRINT("\tadminPassword: ", list->adminPassword);
33797c478bd9Sstevel@tonic-gate 	CLIENT_PRINT("\tdefaultServerList: ", list->defaultServerList);
33807c478bd9Sstevel@tonic-gate 	CLIENT_PRINT("\tcertificatePath: ", list->certificatePath);
33817c478bd9Sstevel@tonic-gate }
33827c478bd9Sstevel@tonic-gate 
33837c478bd9Sstevel@tonic-gate 
33847c478bd9Sstevel@tonic-gate /* These definitions are only used in parseParam() below. */
33857c478bd9Sstevel@tonic-gate struct param {
33867c478bd9Sstevel@tonic-gate 	char	*name;
33877c478bd9Sstevel@tonic-gate 	int	index;
33887c478bd9Sstevel@tonic-gate };
33897c478bd9Sstevel@tonic-gate 
33907c478bd9Sstevel@tonic-gate static struct param paramArray[] = {
33917c478bd9Sstevel@tonic-gate 	{"proxyDN", NS_LDAP_BINDDN_P},
33927c478bd9Sstevel@tonic-gate 	{"proxyPassword", NS_LDAP_BINDPASSWD_P},
33937c478bd9Sstevel@tonic-gate 	{"defaultServerList", NS_LDAP_SERVERS_P},
33947c478bd9Sstevel@tonic-gate 	{"defaultSearchBase", NS_LDAP_SEARCH_BASEDN_P},
33957c478bd9Sstevel@tonic-gate 	{"authenticationMethod", NS_LDAP_AUTH_P},
33967c478bd9Sstevel@tonic-gate 	{"followReferrals", NS_LDAP_SEARCH_REF_P},
33977c478bd9Sstevel@tonic-gate 	{"profileTTL", NS_LDAP_CACHETTL_P},
33987c478bd9Sstevel@tonic-gate 	{"certificatePath", NS_LDAP_HOST_CERTPATH_P},
33997c478bd9Sstevel@tonic-gate 	{"defaultSearchScope", NS_LDAP_SEARCH_SCOPE_P},
34007c478bd9Sstevel@tonic-gate 	{"bindTimeLimit", NS_LDAP_BIND_TIME_P},
34017c478bd9Sstevel@tonic-gate 	{"searchTimeLimit", NS_LDAP_SEARCH_TIME_P},
34027c478bd9Sstevel@tonic-gate 	{"preferredServerList", NS_LDAP_SERVER_PREF_P},
34037c478bd9Sstevel@tonic-gate 	{"profileName", NS_LDAP_PROFILE_P},
34047c478bd9Sstevel@tonic-gate 	{"credentialLevel", NS_LDAP_CREDENTIAL_LEVEL_P},
34057c478bd9Sstevel@tonic-gate 	{"serviceSearchDescriptor", NS_LDAP_SERVICE_SEARCH_DESC_P},
34067c478bd9Sstevel@tonic-gate 	{"attributeMap", NS_LDAP_ATTRIBUTEMAP_P},
34077c478bd9Sstevel@tonic-gate 	{"objectclassMap", NS_LDAP_OBJECTCLASSMAP_P},
34087c478bd9Sstevel@tonic-gate 	{"serviceAuthenticationMethod", NS_LDAP_SERVICE_AUTH_METHOD_P},
34097c478bd9Sstevel@tonic-gate 	{"serviceCredentialLevel", NS_LDAP_SERVICE_CRED_LEVEL_P},
34107c478bd9Sstevel@tonic-gate 	{"domainName", LOCAL_DOMAIN_P},
3411*dd1104fbSMichen Chang 	{"enableShadowUpdate", NS_LDAP_ENABLE_SHADOW_UPDATE_P},
3412*dd1104fbSMichen Chang 	{"adminDN", NS_LDAP_ADMIN_BINDDN_P},
3413*dd1104fbSMichen Chang 	{"adminPassword", NS_LDAP_ADMIN_BINDPASSWD_P},
34147c478bd9Sstevel@tonic-gate 	{NULL, 0}
34157c478bd9Sstevel@tonic-gate };
34167c478bd9Sstevel@tonic-gate 
34177c478bd9Sstevel@tonic-gate static int
34187c478bd9Sstevel@tonic-gate parseParam(char *param, char **paramVal)
34197c478bd9Sstevel@tonic-gate {
34207c478bd9Sstevel@tonic-gate 	char *val = NULL;
34217c478bd9Sstevel@tonic-gate 	int counter;
34227c478bd9Sstevel@tonic-gate 
34237c478bd9Sstevel@tonic-gate 	if (mode_verbose) {
34247c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr, gettext("Parsing %s\n"), param);
34257c478bd9Sstevel@tonic-gate 	}
34267c478bd9Sstevel@tonic-gate 
34277c478bd9Sstevel@tonic-gate 	val = strchr(param, '=');
34287c478bd9Sstevel@tonic-gate 	if (val == NULL) {
34297c478bd9Sstevel@tonic-gate 		CLIENT_FPUTS(
3430e1dd0a2fSth 		    gettext("Didn\'t find \'=\' character in string\n"),
3431e1dd0a2fSth 		    stderr);
34327c478bd9Sstevel@tonic-gate 		paramVal = NULL;
34337c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_PARSE);
34347c478bd9Sstevel@tonic-gate 	}
34357c478bd9Sstevel@tonic-gate 
34367c478bd9Sstevel@tonic-gate 	*val = '\0';
34377c478bd9Sstevel@tonic-gate 
34387c478bd9Sstevel@tonic-gate 	for (counter = 0; paramArray[counter].name != NULL; counter++) {
34397c478bd9Sstevel@tonic-gate 		if (strcasecmp(paramArray[counter].name, param) == 0) {
34407c478bd9Sstevel@tonic-gate 			*paramVal = val+1;
34417c478bd9Sstevel@tonic-gate 			*val = '=';	/* restore original param */
34427c478bd9Sstevel@tonic-gate 			return (paramArray[counter].index);
34437c478bd9Sstevel@tonic-gate 		}
34447c478bd9Sstevel@tonic-gate 	}
34457c478bd9Sstevel@tonic-gate 
34467c478bd9Sstevel@tonic-gate 	/* Not found */
34477c478bd9Sstevel@tonic-gate 	*val = '=';	/* restore original param */
34487c478bd9Sstevel@tonic-gate 	*paramVal = NULL;
34497c478bd9Sstevel@tonic-gate 	return (CLIENT_ERR_PARSE);
34507c478bd9Sstevel@tonic-gate }
34517c478bd9Sstevel@tonic-gate 
34527c478bd9Sstevel@tonic-gate /*
34537c478bd9Sstevel@tonic-gate  * The following macro checks if an option has already been specified
34547c478bd9Sstevel@tonic-gate  * and errs out with usage if so
34557c478bd9Sstevel@tonic-gate  */
34567c478bd9Sstevel@tonic-gate #define	CLIENT_OPT_CHECK(opt, optarg)	\
34577c478bd9Sstevel@tonic-gate if (optarg) {			\
34587c478bd9Sstevel@tonic-gate 	CLIENT_FPUTS(gettext("Invalid use of option\n"), stderr);	\
34597c478bd9Sstevel@tonic-gate 	usage();		\
34607c478bd9Sstevel@tonic-gate 	clientopts_free(optlist); \
34617c478bd9Sstevel@tonic-gate 	return (CLIENT_ERR_FAIL);		\
34627c478bd9Sstevel@tonic-gate }
34637c478bd9Sstevel@tonic-gate 
34647c478bd9Sstevel@tonic-gate static int
34657c478bd9Sstevel@tonic-gate clientSetParam(clientopts_t *optlist, int paramFlag, char *attrVal)
34667c478bd9Sstevel@tonic-gate {
34677c478bd9Sstevel@tonic-gate 	int retcode = 0;
34687c478bd9Sstevel@tonic-gate 	int counter;
34697c478bd9Sstevel@tonic-gate 
34707c478bd9Sstevel@tonic-gate 
34717c478bd9Sstevel@tonic-gate 	switch (paramFlag) {
34727c478bd9Sstevel@tonic-gate 	case NS_LDAP_AUTH_P:
34737c478bd9Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->authenticationMethod);
34747c478bd9Sstevel@tonic-gate 		optlist->authenticationMethod = attrVal;
34757c478bd9Sstevel@tonic-gate 		break;
34767c478bd9Sstevel@tonic-gate 
34777c478bd9Sstevel@tonic-gate 	case NS_LDAP_SERVICE_AUTH_METHOD_P:	/* multiple allowed */
34787c478bd9Sstevel@tonic-gate 		retcode = multival_add(optlist->serviceAuthenticationMethod,
3479e1dd0a2fSth 		    attrVal);
34807c478bd9Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
34817c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
3482e1dd0a2fSth 			    gettext("Error processing attrVal %s\n"),
3483e1dd0a2fSth 			    attrVal?attrVal:"NULL");
34847c478bd9Sstevel@tonic-gate 			usage();
34857c478bd9Sstevel@tonic-gate 			clientopts_free(optlist);
34867c478bd9Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
34877c478bd9Sstevel@tonic-gate 		}
34887c478bd9Sstevel@tonic-gate 		break;
34897c478bd9Sstevel@tonic-gate 
34907c478bd9Sstevel@tonic-gate 	case NS_LDAP_SEARCH_BASEDN_P:
34917c478bd9Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->defaultSearchBase);
34927c478bd9Sstevel@tonic-gate 		optlist->defaultSearchBase = attrVal;
34937c478bd9Sstevel@tonic-gate 		break;
34947c478bd9Sstevel@tonic-gate 
34957c478bd9Sstevel@tonic-gate 	case NS_LDAP_CREDENTIAL_LEVEL_P:
34967c478bd9Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->credentialLevel);
34977c478bd9Sstevel@tonic-gate 		optlist->credentialLevel = attrVal;
34987c478bd9Sstevel@tonic-gate 		break;
34997c478bd9Sstevel@tonic-gate 
35007c478bd9Sstevel@tonic-gate 	case NS_LDAP_SERVICE_CRED_LEVEL_P:	/* multiple allowed */
35017c478bd9Sstevel@tonic-gate 		retcode = multival_add(optlist->serviceCredentialLevel,
3502e1dd0a2fSth 		    attrVal);
35037c478bd9Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
35047c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
3505e1dd0a2fSth 			    gettext("Error processing attrVal %s\n"),
3506e1dd0a2fSth 			    attrVal?attrVal:"NULL");
35077c478bd9Sstevel@tonic-gate 			usage();
35087c478bd9Sstevel@tonic-gate 			clientopts_free(optlist);
35097c478bd9Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
35107c478bd9Sstevel@tonic-gate 		}
35117c478bd9Sstevel@tonic-gate 		break;
35127c478bd9Sstevel@tonic-gate 
35137c478bd9Sstevel@tonic-gate 	case LOCAL_DOMAIN_P:
35147c478bd9Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->domainName);
35157c478bd9Sstevel@tonic-gate 		optlist->domainName = attrVal;
35167c478bd9Sstevel@tonic-gate 		dname = optlist->domainName;
35177c478bd9Sstevel@tonic-gate 		break;
35187c478bd9Sstevel@tonic-gate 
35197c478bd9Sstevel@tonic-gate 	case NS_LDAP_BINDDN_P:
35207c478bd9Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->proxyDN);
35217c478bd9Sstevel@tonic-gate 		optlist->proxyDN = attrVal;
35227c478bd9Sstevel@tonic-gate 		break;
35237c478bd9Sstevel@tonic-gate 
3524*dd1104fbSMichen Chang 	case NS_LDAP_ENABLE_SHADOW_UPDATE_P:
3525*dd1104fbSMichen Chang 		CLIENT_OPT_CHECK(paramFlag, optlist->enableShadowUpdate);
3526*dd1104fbSMichen Chang 		optlist->enableShadowUpdate = attrVal;
3527*dd1104fbSMichen Chang 		break;
3528*dd1104fbSMichen Chang 
3529*dd1104fbSMichen Chang 	case NS_LDAP_ADMIN_BINDDN_P:
3530*dd1104fbSMichen Chang 		CLIENT_OPT_CHECK(paramFlag, optlist->adminDN);
3531*dd1104fbSMichen Chang 		optlist->adminDN = attrVal;
3532*dd1104fbSMichen Chang 		break;
3533*dd1104fbSMichen Chang 
35347c478bd9Sstevel@tonic-gate 	case NS_LDAP_CACHETTL_P:
35357c478bd9Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->profileTTL);
35367c478bd9Sstevel@tonic-gate 		optlist->profileTTL = attrVal;
35377c478bd9Sstevel@tonic-gate 		break;
35387c478bd9Sstevel@tonic-gate 
35397c478bd9Sstevel@tonic-gate 	case NS_LDAP_OBJECTCLASSMAP_P:	/* multiple allowed */
35407c478bd9Sstevel@tonic-gate 		retcode = multival_add(optlist->objectclassMap, attrVal);
35417c478bd9Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
35427c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
3543e1dd0a2fSth 			    gettext("Error processing attrVal %s\n"),
3544e1dd0a2fSth 			    attrVal?attrVal:"NULL");
35457c478bd9Sstevel@tonic-gate 			usage();
35467c478bd9Sstevel@tonic-gate 			clientopts_free(optlist);
35477c478bd9Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
35487c478bd9Sstevel@tonic-gate 		}
35497c478bd9Sstevel@tonic-gate 		break;
35507c478bd9Sstevel@tonic-gate 
35517c478bd9Sstevel@tonic-gate 	case NS_LDAP_SEARCH_TIME_P:
35527c478bd9Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->searchTimeLimit);
35537c478bd9Sstevel@tonic-gate 		optlist->searchTimeLimit = attrVal;
35547c478bd9Sstevel@tonic-gate 		break;
35557c478bd9Sstevel@tonic-gate 
35567c478bd9Sstevel@tonic-gate 	case NS_LDAP_SERVER_PREF_P:
35577c478bd9Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->preferredServerList);
35587c478bd9Sstevel@tonic-gate 		optlist->preferredServerList = attrVal;
35597c478bd9Sstevel@tonic-gate 		/* replace ',' chars with ' ' for proper syntax */
35607c478bd9Sstevel@tonic-gate 		for (counter = 0;
3561e1dd0a2fSth 		    counter < strlen(optlist->preferredServerList);
3562e1dd0a2fSth 		    counter++) {
35637c478bd9Sstevel@tonic-gate 
35647c478bd9Sstevel@tonic-gate 			if (optlist->preferredServerList[counter] == ',')
35657c478bd9Sstevel@tonic-gate 				optlist->preferredServerList[counter] = ' ';
35667c478bd9Sstevel@tonic-gate 		}
35677c478bd9Sstevel@tonic-gate 		break;
35687c478bd9Sstevel@tonic-gate 
35697c478bd9Sstevel@tonic-gate 	case NS_LDAP_PROFILE_P:
35707c478bd9Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->profileName);
35717c478bd9Sstevel@tonic-gate 		optlist->profileName = attrVal;
35727c478bd9Sstevel@tonic-gate 		break;
35737c478bd9Sstevel@tonic-gate 
35747c478bd9Sstevel@tonic-gate 	case NS_LDAP_SEARCH_REF_P:
35757c478bd9Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->followReferrals);
35767c478bd9Sstevel@tonic-gate 		if (0 == strcasecmp(attrVal, "followref"))
35777c478bd9Sstevel@tonic-gate 			optlist->followReferrals = "TRUE";
35787c478bd9Sstevel@tonic-gate 		else if (0 == strcasecmp(attrVal, "noref"))
35797c478bd9Sstevel@tonic-gate 			optlist->followReferrals = "FALSE";
35807c478bd9Sstevel@tonic-gate 		else
35817c478bd9Sstevel@tonic-gate 			optlist->followReferrals = attrVal;
35827c478bd9Sstevel@tonic-gate 		break;
35837c478bd9Sstevel@tonic-gate 
35847c478bd9Sstevel@tonic-gate 	case NS_LDAP_ATTRIBUTEMAP_P:	/* multiple allowed */
35857c478bd9Sstevel@tonic-gate 		retcode = multival_add(optlist->attributeMap, attrVal);
35867c478bd9Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
35877c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
3588e1dd0a2fSth 			    gettext("Error processing attrVal %s\n"),
3589e1dd0a2fSth 			    attrVal?attrVal:"NULL");
35907c478bd9Sstevel@tonic-gate 			usage();
35917c478bd9Sstevel@tonic-gate 			clientopts_free(optlist);
35927c478bd9Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
35937c478bd9Sstevel@tonic-gate 		}
35947c478bd9Sstevel@tonic-gate 		break;
35957c478bd9Sstevel@tonic-gate 
35967c478bd9Sstevel@tonic-gate 	case NS_LDAP_SEARCH_SCOPE_P:
35977c478bd9Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->defaultSearchScope);
35987c478bd9Sstevel@tonic-gate 		optlist->defaultSearchScope = attrVal;
35997c478bd9Sstevel@tonic-gate 		break;
36007c478bd9Sstevel@tonic-gate 
36017c478bd9Sstevel@tonic-gate 	case NS_LDAP_SERVICE_SEARCH_DESC_P:	/* multiple allowed */
36027c478bd9Sstevel@tonic-gate 		retcode = multival_add(optlist->serviceSearchDescriptor,
3603e1dd0a2fSth 		    attrVal);
36047c478bd9Sstevel@tonic-gate 		if (retcode != CLIENT_SUCCESS) {
36057c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
3606e1dd0a2fSth 			    gettext("Error processing attrVal %s\n"),
3607e1dd0a2fSth 			    attrVal?attrVal:"NULL");
36087c478bd9Sstevel@tonic-gate 			usage();
36097c478bd9Sstevel@tonic-gate 			clientopts_free(optlist);
36107c478bd9Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
36117c478bd9Sstevel@tonic-gate 		}
36127c478bd9Sstevel@tonic-gate 		break;
36137c478bd9Sstevel@tonic-gate 
36147c478bd9Sstevel@tonic-gate 	case NS_LDAP_BIND_TIME_P:
36157c478bd9Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->bindTimeLimit);
36167c478bd9Sstevel@tonic-gate 		optlist->bindTimeLimit = attrVal;
36177c478bd9Sstevel@tonic-gate 		break;
36187c478bd9Sstevel@tonic-gate 
36197c478bd9Sstevel@tonic-gate 	case NS_LDAP_BINDPASSWD_P:
36207c478bd9Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->proxyPassword);
36217c478bd9Sstevel@tonic-gate 		optlist->proxyPassword = attrVal;
36227c478bd9Sstevel@tonic-gate 		break;
36237c478bd9Sstevel@tonic-gate 
3624*dd1104fbSMichen Chang 	case NS_LDAP_ADMIN_BINDPASSWD_P:
3625*dd1104fbSMichen Chang 		CLIENT_OPT_CHECK(paramFlag, optlist->adminPassword);
3626*dd1104fbSMichen Chang 		optlist->adminPassword = attrVal;
3627*dd1104fbSMichen Chang 		break;
3628*dd1104fbSMichen Chang 
36297c478bd9Sstevel@tonic-gate 	case NS_LDAP_HOST_CERTPATH_P:
36307c478bd9Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->certificatePath);
36317c478bd9Sstevel@tonic-gate 		optlist->certificatePath = attrVal;
36327c478bd9Sstevel@tonic-gate 		break;
36337c478bd9Sstevel@tonic-gate 
36347c478bd9Sstevel@tonic-gate 	case NS_LDAP_SERVERS_P:
36357c478bd9Sstevel@tonic-gate 		CLIENT_OPT_CHECK(paramFlag, optlist->defaultServerList);
36367c478bd9Sstevel@tonic-gate 		optlist->defaultServerList = attrVal;
36377c478bd9Sstevel@tonic-gate 		break;
36387c478bd9Sstevel@tonic-gate 
36397c478bd9Sstevel@tonic-gate 	default:
36407c478bd9Sstevel@tonic-gate 		usage();
36417c478bd9Sstevel@tonic-gate 		return (CLIENT_ERR_FAIL);
36427c478bd9Sstevel@tonic-gate 		/* break;  lint doesn't like break before end of switch */
36437c478bd9Sstevel@tonic-gate 	}
36447c478bd9Sstevel@tonic-gate 
36457c478bd9Sstevel@tonic-gate 	return (retcode);
36467c478bd9Sstevel@tonic-gate }
36477c478bd9Sstevel@tonic-gate 
36487c478bd9Sstevel@tonic-gate /*
36497c478bd9Sstevel@tonic-gate  * file_move() - Used to move a config file (backup/restore).
36507c478bd9Sstevel@tonic-gate  *
36517c478bd9Sstevel@tonic-gate  * This function uses a system() call with /bin/mv to handle the
36527c478bd9Sstevel@tonic-gate  * case where the backup directory (/var) is on a different file
36537c478bd9Sstevel@tonic-gate  * system than the config file (typically /etc).
36547c478bd9Sstevel@tonic-gate  */
36557c478bd9Sstevel@tonic-gate static int
36567c478bd9Sstevel@tonic-gate file_move(const char *from, const char *to)
36577c478bd9Sstevel@tonic-gate {
36587c478bd9Sstevel@tonic-gate 	int retcode;
36597c478bd9Sstevel@tonic-gate 	char mvCommand[] = CMD_MV;
36607c478bd9Sstevel@tonic-gate 	char cmd_buffer[(2 * MAXPATHLEN) + sizeof (mvCommand) + 3];
36617c478bd9Sstevel@tonic-gate 
36627c478bd9Sstevel@tonic-gate 	(void) snprintf(cmd_buffer, sizeof (cmd_buffer), "%s %s %s",
3663e1dd0a2fSth 	    mvCommand, from, to);
36647c478bd9Sstevel@tonic-gate 
36657c478bd9Sstevel@tonic-gate 	/*
36667c478bd9Sstevel@tonic-gate 	 * This function should only be used internally to move
36677c478bd9Sstevel@tonic-gate 	 * system files to/from the backup directory.  For security
36687c478bd9Sstevel@tonic-gate 	 * reasons (this is run as root), don't use this function
36697c478bd9Sstevel@tonic-gate 	 * with arguments passed into the program.
36707c478bd9Sstevel@tonic-gate 	 */
36717c478bd9Sstevel@tonic-gate 	retcode = system(cmd_buffer);
36727c478bd9Sstevel@tonic-gate 
36737c478bd9Sstevel@tonic-gate 	return (retcode);
36747c478bd9Sstevel@tonic-gate }
36757c478bd9Sstevel@tonic-gate 
36767c478bd9Sstevel@tonic-gate 
36777c478bd9Sstevel@tonic-gate /*
36787c478bd9Sstevel@tonic-gate  * Manipulate the service as instructed by "dowhat"
36797c478bd9Sstevel@tonic-gate  */
36807c478bd9Sstevel@tonic-gate static int
36817c478bd9Sstevel@tonic-gate do_service(const char *fmri, boolean_t waitflag, int dowhat,
36827c478bd9Sstevel@tonic-gate 		const char *state) {
36837c478bd9Sstevel@tonic-gate 
36847c478bd9Sstevel@tonic-gate 	int		status;
36857c478bd9Sstevel@tonic-gate 	boolean_t	is_maint;
36867c478bd9Sstevel@tonic-gate 	const char	*what = gettext("not set");
36877c478bd9Sstevel@tonic-gate 	useconds_t	max;
36887c478bd9Sstevel@tonic-gate 
36897c478bd9Sstevel@tonic-gate 	/* Check if we are in maintenance */
36907c478bd9Sstevel@tonic-gate 	is_maint = is_service(fmri, SCF_STATE_STRING_MAINT);
36917c478bd9Sstevel@tonic-gate 
36927c478bd9Sstevel@tonic-gate 	switch (dowhat) {
36937c478bd9Sstevel@tonic-gate 	case START_SERVICE:
36947c478bd9Sstevel@tonic-gate 		what = gettext("start");
36957c478bd9Sstevel@tonic-gate 		status = smf_enable_instance(fmri,
36967c478bd9Sstevel@tonic-gate 			(sysid_install == B_TRUE)?SMF_TEMPORARY:0);
36977c478bd9Sstevel@tonic-gate 		break;
36987c478bd9Sstevel@tonic-gate 	case STOP_SERVICE:
36997c478bd9Sstevel@tonic-gate 		what = gettext("stop");
37007c478bd9Sstevel@tonic-gate 		status = smf_disable_instance(fmri,
37017c478bd9Sstevel@tonic-gate 			(sysid_install == B_TRUE)?SMF_TEMPORARY:0);
37027c478bd9Sstevel@tonic-gate 		break;
37037c478bd9Sstevel@tonic-gate 	case RESTART_SERVICE:
37047c478bd9Sstevel@tonic-gate 		what = gettext("restart");
37057c478bd9Sstevel@tonic-gate 		status = smf_restart_instance(fmri);
37067c478bd9Sstevel@tonic-gate 		break;
37077c478bd9Sstevel@tonic-gate 	default:
37087c478bd9Sstevel@tonic-gate 		/* coding error; will not happen */
37097c478bd9Sstevel@tonic-gate 		assert(0);
37107c478bd9Sstevel@tonic-gate 	}
37117c478bd9Sstevel@tonic-gate 
37127c478bd9Sstevel@tonic-gate 	/*
37137c478bd9Sstevel@tonic-gate 	 * If the service was previously in maintenance then we need to
37147c478bd9Sstevel@tonic-gate 	 * clear it immediately.  The "dowhat" action will set the
37157c478bd9Sstevel@tonic-gate 	 * enabled property of the service as intended by the caller while
37167c478bd9Sstevel@tonic-gate 	 * clear will actually cause it to be enabled/disabled.
37177c478bd9Sstevel@tonic-gate 	 * We assume that the caller has called us after taking some
37187c478bd9Sstevel@tonic-gate 	 * recovery action. Even if it's not the case, we don't lose
37197c478bd9Sstevel@tonic-gate 	 * anything.
37207c478bd9Sstevel@tonic-gate 	 */
37217c478bd9Sstevel@tonic-gate 	if (status == 0 && is_maint == B_TRUE) {
37227c478bd9Sstevel@tonic-gate 		if (mode_verbose)
37237c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
37247c478bd9Sstevel@tonic-gate 				"%s: %s... %s\n",
37257c478bd9Sstevel@tonic-gate 				what,
37267c478bd9Sstevel@tonic-gate 				fmri,
37277c478bd9Sstevel@tonic-gate 				gettext("restoring from maintenance state"));
37287c478bd9Sstevel@tonic-gate 		status = smf_restore_instance(fmri);
37297c478bd9Sstevel@tonic-gate 	}
37307c478bd9Sstevel@tonic-gate 
37317c478bd9Sstevel@tonic-gate 	if (status == 0) {
37327c478bd9Sstevel@tonic-gate 		/* Check if we need to wait ? */
37337c478bd9Sstevel@tonic-gate 		if (waitflag == B_FALSE) {
37347c478bd9Sstevel@tonic-gate 			if (mode_verbose)
37357c478bd9Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
37367c478bd9Sstevel@tonic-gate 					"%s: %s... %s\n",
37377c478bd9Sstevel@tonic-gate 					what,
37387c478bd9Sstevel@tonic-gate 					fmri,
37397c478bd9Sstevel@tonic-gate 					gettext("success"));
37407c478bd9Sstevel@tonic-gate 			return (CLIENT_SUCCESS);
37417c478bd9Sstevel@tonic-gate 		}
37427c478bd9Sstevel@tonic-gate 
37437c478bd9Sstevel@tonic-gate 		/* Otherwise wait for max seconds (from the manifest) */
37447c478bd9Sstevel@tonic-gate 		max = get_timeout_value(dowhat, fmri, DEFAULT_TIMEOUT);
37457c478bd9Sstevel@tonic-gate 		status = wait_till(fmri, state, max, what, !is_maint);
37467c478bd9Sstevel@tonic-gate 		if (status == CLIENT_SUCCESS)
37477c478bd9Sstevel@tonic-gate 			return (CLIENT_SUCCESS);
37487c478bd9Sstevel@tonic-gate 		/* For error fall through for corrective action */
37497c478bd9Sstevel@tonic-gate 	} else {
37507c478bd9Sstevel@tonic-gate 		/* Well, service failed ... */
37517c478bd9Sstevel@tonic-gate 		if (mode_verbose)
37527c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, "%s: %s... %s: %s\n",
37537c478bd9Sstevel@tonic-gate 				what,
37547c478bd9Sstevel@tonic-gate 				fmri,
37557c478bd9Sstevel@tonic-gate 				gettext("failed"),
37567c478bd9Sstevel@tonic-gate 				scf_strerror(scf_error()));
37577c478bd9Sstevel@tonic-gate 		status = CLIENT_ERR_FAIL;
37587c478bd9Sstevel@tonic-gate 		/* For error fall through for corrective action */
37597c478bd9Sstevel@tonic-gate 	}
37607c478bd9Sstevel@tonic-gate 
37617c478bd9Sstevel@tonic-gate 	/*
37627c478bd9Sstevel@tonic-gate 	 * If service is still offline after start/restart, then transitioning
37637c478bd9Sstevel@tonic-gate 	 * failed and guess is restarter failed to apply the timeout as well.
37647c478bd9Sstevel@tonic-gate 	 * So instead of leaving it offline, let's just disable it until we have
37657c478bd9Sstevel@tonic-gate 	 * some other mechanism available from smf to handle such situation.
37667c478bd9Sstevel@tonic-gate 	 */
37677c478bd9Sstevel@tonic-gate 	if (dowhat != STOP_SERVICE)
37687c478bd9Sstevel@tonic-gate 		if (is_service(fmri, SCF_STATE_STRING_OFFLINE)) {
37697c478bd9Sstevel@tonic-gate 			if (mode_verbose)
37707c478bd9Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
37717c478bd9Sstevel@tonic-gate 					"%s: %s... %s\n",
37727c478bd9Sstevel@tonic-gate 					what,
37737c478bd9Sstevel@tonic-gate 					fmri,
37747c478bd9Sstevel@tonic-gate 					gettext("offline to disable"));
37757c478bd9Sstevel@tonic-gate 			(void) disable_service(fmri, waitflag);
37767c478bd9Sstevel@tonic-gate 		}
37777c478bd9Sstevel@tonic-gate 
37787c478bd9Sstevel@tonic-gate 	return (status);
37797c478bd9Sstevel@tonic-gate }
37807c478bd9Sstevel@tonic-gate 
37817c478bd9Sstevel@tonic-gate 
37827c478bd9Sstevel@tonic-gate /*
37837c478bd9Sstevel@tonic-gate  * Wait for "max" usecs for the service described by "fmri" to change
37847c478bd9Sstevel@tonic-gate  * to "state". If check_maint is true then return immediately if
37857c478bd9Sstevel@tonic-gate  * service goes into maintenance
37867c478bd9Sstevel@tonic-gate  */
37877c478bd9Sstevel@tonic-gate static int
37887c478bd9Sstevel@tonic-gate wait_till(const char *fmri, const char *state, useconds_t max,
37897c478bd9Sstevel@tonic-gate 		const char *what, boolean_t check_maint) {
37907c478bd9Sstevel@tonic-gate 	char *st;
37917c478bd9Sstevel@tonic-gate 	useconds_t usecs = INIT_WAIT_USECS;
37927c478bd9Sstevel@tonic-gate 
37937c478bd9Sstevel@tonic-gate 	for (; max > 0; max -= usecs) {
37947c478bd9Sstevel@tonic-gate 		/* incremental wait */
37957c478bd9Sstevel@tonic-gate 		usecs *= 2;
37967c478bd9Sstevel@tonic-gate 		usecs = (usecs > max)?max:usecs;
37977c478bd9Sstevel@tonic-gate 		if (mode_verbose)
37987c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr,
37997c478bd9Sstevel@tonic-gate 				"%s: %s %u %s\n",
38007c478bd9Sstevel@tonic-gate 				what, gettext("sleep"), usecs,
38017c478bd9Sstevel@tonic-gate 				gettext("microseconds"));
38027c478bd9Sstevel@tonic-gate 		(void) usleep(usecs);
38037c478bd9Sstevel@tonic-gate 
38047c478bd9Sstevel@tonic-gate 		/* Check state after the wait */
38057c478bd9Sstevel@tonic-gate 		if ((st = smf_get_state(fmri)) != NULL) {
38067c478bd9Sstevel@tonic-gate 			if (strcmp(st, state) == 0) {
38077c478bd9Sstevel@tonic-gate 				if (mode_verbose)
38087c478bd9Sstevel@tonic-gate 					CLIENT_FPRINTF(stderr,
38097c478bd9Sstevel@tonic-gate 						"%s: %s... %s\n",
38107c478bd9Sstevel@tonic-gate 						what,
38117c478bd9Sstevel@tonic-gate 						fmri,
38127c478bd9Sstevel@tonic-gate 						gettext("success"));
38137c478bd9Sstevel@tonic-gate 				free(st);
38147c478bd9Sstevel@tonic-gate 				return (CLIENT_SUCCESS);
38157c478bd9Sstevel@tonic-gate 			}
38167c478bd9Sstevel@tonic-gate 
38177c478bd9Sstevel@tonic-gate 			/*
38187c478bd9Sstevel@tonic-gate 			 * If service has gone into maintenance then
38197c478bd9Sstevel@tonic-gate 			 * we will time out anyway, so we are better
38207c478bd9Sstevel@tonic-gate 			 * off returning now
38217c478bd9Sstevel@tonic-gate 			 */
38227c478bd9Sstevel@tonic-gate 			if (check_maint &&
38237c478bd9Sstevel@tonic-gate 				strcmp(st, SCF_STATE_STRING_MAINT) == 0) {
38247c478bd9Sstevel@tonic-gate 				if (mode_verbose)
38257c478bd9Sstevel@tonic-gate 					CLIENT_FPRINTF(stderr,
38267c478bd9Sstevel@tonic-gate 						"%s: %s... %s\n",
38277c478bd9Sstevel@tonic-gate 						what,
38287c478bd9Sstevel@tonic-gate 						fmri,
38297c478bd9Sstevel@tonic-gate 						gettext("maintenance"));
38307c478bd9Sstevel@tonic-gate 				free(st);
38317c478bd9Sstevel@tonic-gate 				return (CLIENT_ERR_MAINTENANCE);
38327c478bd9Sstevel@tonic-gate 			}
38337c478bd9Sstevel@tonic-gate 			free(st);
38347c478bd9Sstevel@tonic-gate 		} else {
38357c478bd9Sstevel@tonic-gate 			if (mode_verbose)
38367c478bd9Sstevel@tonic-gate 				CLIENT_FPRINTF(stderr,
38377c478bd9Sstevel@tonic-gate 						"%s: %s... %s: %s\n",
38387c478bd9Sstevel@tonic-gate 						what,
38397c478bd9Sstevel@tonic-gate 						fmri,
38407c478bd9Sstevel@tonic-gate 						gettext("failed"),
38417c478bd9Sstevel@tonic-gate 						scf_strerror(scf_error()));
38427c478bd9Sstevel@tonic-gate 			return (CLIENT_ERR_FAIL);
38437c478bd9Sstevel@tonic-gate 		}
38447c478bd9Sstevel@tonic-gate 	}
38457c478bd9Sstevel@tonic-gate 
38467c478bd9Sstevel@tonic-gate 	/* Timed out waiting */
38477c478bd9Sstevel@tonic-gate 	if (mode_verbose)
38487c478bd9Sstevel@tonic-gate 		CLIENT_FPRINTF(stderr,
38497c478bd9Sstevel@tonic-gate 			"%s: %s... %s\n",
38507c478bd9Sstevel@tonic-gate 			what,
38517c478bd9Sstevel@tonic-gate 			fmri,
38527c478bd9Sstevel@tonic-gate 			gettext("timed out"));
38537c478bd9Sstevel@tonic-gate 	return (CLIENT_ERR_TIMEDOUT);
38547c478bd9Sstevel@tonic-gate }
38557c478bd9Sstevel@tonic-gate 
38567c478bd9Sstevel@tonic-gate 
38577c478bd9Sstevel@tonic-gate static boolean_t
38587c478bd9Sstevel@tonic-gate is_service(const char *fmri, const char *state) {
38597c478bd9Sstevel@tonic-gate 	char		*st;
38607c478bd9Sstevel@tonic-gate 	boolean_t	result = B_FALSE;
38617c478bd9Sstevel@tonic-gate 
38627c478bd9Sstevel@tonic-gate 	if ((st = smf_get_state(fmri)) != NULL) {
38637c478bd9Sstevel@tonic-gate 		if (strcmp(st, state) == 0)
38647c478bd9Sstevel@tonic-gate 			result = B_TRUE;
38657c478bd9Sstevel@tonic-gate 		free(st);
38667c478bd9Sstevel@tonic-gate 	}
38677c478bd9Sstevel@tonic-gate 	return (result);
38687c478bd9Sstevel@tonic-gate }
38697c478bd9Sstevel@tonic-gate 
38707c478bd9Sstevel@tonic-gate 
38717c478bd9Sstevel@tonic-gate /*
38727c478bd9Sstevel@tonic-gate  *
38737c478bd9Sstevel@tonic-gate  * get_timeout_val : returns the timeout value set in fmri manifest
38747c478bd9Sstevel@tonic-gate  * 	inputs	: action(start/stop)
38757c478bd9Sstevel@tonic-gate  *	fmri(defined fmri string)
38767c478bd9Sstevel@tonic-gate  *	Returns default if error, the timeout val otherwise
38777c478bd9Sstevel@tonic-gate  *
38787c478bd9Sstevel@tonic-gate  */
38797c478bd9Sstevel@tonic-gate 
38807c478bd9Sstevel@tonic-gate static useconds_t
38817c478bd9Sstevel@tonic-gate get_timeout_value(int dowhat, const char *fmri, useconds_t default_val)
38827c478bd9Sstevel@tonic-gate {
38837c478bd9Sstevel@tonic-gate 	scf_simple_prop_t	*sp = NULL;
38847c478bd9Sstevel@tonic-gate 	uint64_t		*cp = NULL;
38857c478bd9Sstevel@tonic-gate 	int			timeout = default_val/1000000;
38867c478bd9Sstevel@tonic-gate 	char			*action = NULL;
38877c478bd9Sstevel@tonic-gate 	const char		*actionstr = NULL;
38887c478bd9Sstevel@tonic-gate 
38897c478bd9Sstevel@tonic-gate 	switch (dowhat)  {
38907c478bd9Sstevel@tonic-gate 		case START_SERVICE:
38917c478bd9Sstevel@tonic-gate 		case RESTART_SERVICE:
38927c478bd9Sstevel@tonic-gate 				action = "start";
38937c478bd9Sstevel@tonic-gate 				actionstr = gettext("start");
38947c478bd9Sstevel@tonic-gate 				break;
38957c478bd9Sstevel@tonic-gate 		case STOP_SERVICE:
38967c478bd9Sstevel@tonic-gate 				action = "stop";
38977c478bd9Sstevel@tonic-gate 				actionstr = gettext("stop");
38987c478bd9Sstevel@tonic-gate 				break;
38997c478bd9Sstevel@tonic-gate 		default:
39007c478bd9Sstevel@tonic-gate 			assert(0);
39017c478bd9Sstevel@tonic-gate 	}
39027c478bd9Sstevel@tonic-gate 
39037c478bd9Sstevel@tonic-gate 
39047c478bd9Sstevel@tonic-gate 	sp = scf_simple_prop_get(NULL, fmri, action, SCF_PROPERTY_TIMEOUT);
39057c478bd9Sstevel@tonic-gate 	if (sp == NULL) {
39067c478bd9Sstevel@tonic-gate 		if (mode_verbose)
39077c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, "%s: %s... %s: %s\n",
3908e1dd0a2fSth 			    actionstr,
3909e1dd0a2fSth 			    fmri,
3910e1dd0a2fSth 			    gettext("failed to retrieve timeout property"),
3911e1dd0a2fSth 			    scf_strerror(scf_error()));
39127c478bd9Sstevel@tonic-gate 		return (default_val);
39137c478bd9Sstevel@tonic-gate 	}
39147c478bd9Sstevel@tonic-gate 
39157c478bd9Sstevel@tonic-gate 	cp = scf_simple_prop_next_count(sp);
39167c478bd9Sstevel@tonic-gate 	if (cp == NULL) {
39177c478bd9Sstevel@tonic-gate 		if (mode_verbose)
39187c478bd9Sstevel@tonic-gate 			CLIENT_FPRINTF(stderr, "%s: %s... %s: %s\n",
3919e1dd0a2fSth 			    actionstr,
3920e1dd0a2fSth 			    fmri,
3921e1dd0a2fSth 			    gettext("failed to retrieve timeout value"),
3922e1dd0a2fSth 			    scf_strerror(scf_error()));
39237c478bd9Sstevel@tonic-gate 		scf_simple_prop_free(sp);
39247c478bd9Sstevel@tonic-gate 		return (default_val);
39257c478bd9Sstevel@tonic-gate 	}
39267c478bd9Sstevel@tonic-gate 
39277c478bd9Sstevel@tonic-gate 	if (*cp != 0)
39287c478bd9Sstevel@tonic-gate 		timeout = *cp;
39297c478bd9Sstevel@tonic-gate 	scf_simple_prop_free(sp);
39307c478bd9Sstevel@tonic-gate 	return (timeout * 1000000);
39317c478bd9Sstevel@tonic-gate }
3932