xref: /titanic_51/usr/src/cmd/cmd-crypto/cryptoadm/cryptoadm.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate #include <fcntl.h>
30*7c478bd9Sstevel@tonic-gate #include <stdio.h>
31*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
32*7c478bd9Sstevel@tonic-gate #include <strings.h>
33*7c478bd9Sstevel@tonic-gate #include <unistd.h>
34*7c478bd9Sstevel@tonic-gate #include <locale.h>
35*7c478bd9Sstevel@tonic-gate #include <libgen.h>
36*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
37*7c478bd9Sstevel@tonic-gate #include <zone.h>
38*7c478bd9Sstevel@tonic-gate #include <sys/crypto/ioctladmin.h>
39*7c478bd9Sstevel@tonic-gate #include <cryptoutil.h>
40*7c478bd9Sstevel@tonic-gate #include "cryptoadm.h"
41*7c478bd9Sstevel@tonic-gate 
42*7c478bd9Sstevel@tonic-gate #define	REQ_ARG_CNT	2
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate /* subcommand index */
45*7c478bd9Sstevel@tonic-gate enum subcommand_index {
46*7c478bd9Sstevel@tonic-gate 	CRYPTO_LIST,
47*7c478bd9Sstevel@tonic-gate 	CRYPTO_DISABLE,
48*7c478bd9Sstevel@tonic-gate 	CRYPTO_ENABLE,
49*7c478bd9Sstevel@tonic-gate 	CRYPTO_INSTALL,
50*7c478bd9Sstevel@tonic-gate 	CRYPTO_UNINSTALL,
51*7c478bd9Sstevel@tonic-gate 	CRYPTO_UNLOAD,
52*7c478bd9Sstevel@tonic-gate 	CRYPTO_REFRESH,
53*7c478bd9Sstevel@tonic-gate 	CRYPTO_START,
54*7c478bd9Sstevel@tonic-gate 	CRYPTO_STOP,
55*7c478bd9Sstevel@tonic-gate 	CRYPTO_HELP };
56*7c478bd9Sstevel@tonic-gate 
57*7c478bd9Sstevel@tonic-gate /*
58*7c478bd9Sstevel@tonic-gate  * TRANSLATION_NOTE:
59*7c478bd9Sstevel@tonic-gate  * Command keywords are not to be translated.
60*7c478bd9Sstevel@tonic-gate  */
61*7c478bd9Sstevel@tonic-gate static char *cmd_table[] = {
62*7c478bd9Sstevel@tonic-gate 	"list",
63*7c478bd9Sstevel@tonic-gate 	"disable",
64*7c478bd9Sstevel@tonic-gate 	"enable",
65*7c478bd9Sstevel@tonic-gate 	"install",
66*7c478bd9Sstevel@tonic-gate 	"uninstall",
67*7c478bd9Sstevel@tonic-gate 	"unload",
68*7c478bd9Sstevel@tonic-gate 	"refresh",
69*7c478bd9Sstevel@tonic-gate 	"start",
70*7c478bd9Sstevel@tonic-gate 	"stop",
71*7c478bd9Sstevel@tonic-gate 	"--help" };
72*7c478bd9Sstevel@tonic-gate 
73*7c478bd9Sstevel@tonic-gate /* provider type */
74*7c478bd9Sstevel@tonic-gate enum provider_type_index {
75*7c478bd9Sstevel@tonic-gate 	PROV_UEF_LIB,
76*7c478bd9Sstevel@tonic-gate 	PROV_KEF_SOFT,
77*7c478bd9Sstevel@tonic-gate 	PROV_KEF_HARD,
78*7c478bd9Sstevel@tonic-gate 	METASLOT,
79*7c478bd9Sstevel@tonic-gate 	PROV_BADNAME };
80*7c478bd9Sstevel@tonic-gate 
81*7c478bd9Sstevel@tonic-gate typedef struct {
82*7c478bd9Sstevel@tonic-gate 	char cp_name[MAXPATHLEN];
83*7c478bd9Sstevel@tonic-gate 	enum provider_type_index cp_type;
84*7c478bd9Sstevel@tonic-gate } cryptoadm_provider_t;
85*7c478bd9Sstevel@tonic-gate 
86*7c478bd9Sstevel@tonic-gate /*
87*7c478bd9Sstevel@tonic-gate  * TRANSLATION_NOTE:
88*7c478bd9Sstevel@tonic-gate  * Operand keywords are not to be translated.
89*7c478bd9Sstevel@tonic-gate  */
90*7c478bd9Sstevel@tonic-gate static const char *KN_PROVIDER = "provider=";
91*7c478bd9Sstevel@tonic-gate static const char *KN_MECH = "mechanism=";
92*7c478bd9Sstevel@tonic-gate static const char *KN_ALL = "all";
93*7c478bd9Sstevel@tonic-gate static const char *KN_TOKEN = "token=";
94*7c478bd9Sstevel@tonic-gate static const char *KN_SLOT = "slot=";
95*7c478bd9Sstevel@tonic-gate static const char *KN_DEFAULT_KS = "default-keystore";
96*7c478bd9Sstevel@tonic-gate static const char *KN_AUTO_KEY_MIGRATE = "auto-key-migrate";
97*7c478bd9Sstevel@tonic-gate 
98*7c478bd9Sstevel@tonic-gate /* static variables */
99*7c478bd9Sstevel@tonic-gate static boolean_t	allflag = B_FALSE;
100*7c478bd9Sstevel@tonic-gate static boolean_t	rndflag = B_FALSE;
101*7c478bd9Sstevel@tonic-gate static mechlist_t	*mecharglist = NULL;
102*7c478bd9Sstevel@tonic-gate 
103*7c478bd9Sstevel@tonic-gate /* static functions */
104*7c478bd9Sstevel@tonic-gate static void usage(void);
105*7c478bd9Sstevel@tonic-gate static int get_provider_type(char *);
106*7c478bd9Sstevel@tonic-gate static int process_mech_operands(int, char **, boolean_t);
107*7c478bd9Sstevel@tonic-gate static int do_list(int, char **);
108*7c478bd9Sstevel@tonic-gate static int do_disable(int, char **);
109*7c478bd9Sstevel@tonic-gate static int do_enable(int, char **);
110*7c478bd9Sstevel@tonic-gate static int do_install(int, char **);
111*7c478bd9Sstevel@tonic-gate static int do_uninstall(int, char **);
112*7c478bd9Sstevel@tonic-gate static int do_unload(int, char **);
113*7c478bd9Sstevel@tonic-gate static int do_refresh(int);
114*7c478bd9Sstevel@tonic-gate static int do_start(int);
115*7c478bd9Sstevel@tonic-gate static int do_stop(int);
116*7c478bd9Sstevel@tonic-gate static int list_simple_for_all(boolean_t);
117*7c478bd9Sstevel@tonic-gate static int list_mechlist_for_all(boolean_t);
118*7c478bd9Sstevel@tonic-gate static int list_policy_for_all(void);
119*7c478bd9Sstevel@tonic-gate 
120*7c478bd9Sstevel@tonic-gate int
121*7c478bd9Sstevel@tonic-gate main(int argc, char *argv[])
122*7c478bd9Sstevel@tonic-gate {
123*7c478bd9Sstevel@tonic-gate 	char	*subcmd;
124*7c478bd9Sstevel@tonic-gate 	int	cmdnum;
125*7c478bd9Sstevel@tonic-gate 	int	cmd_index = 0;
126*7c478bd9Sstevel@tonic-gate 	int	rc = SUCCESS;
127*7c478bd9Sstevel@tonic-gate 
128*7c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
129*7c478bd9Sstevel@tonic-gate 
130*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
131*7c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"	/* Use this only if it weren't */
132*7c478bd9Sstevel@tonic-gate #endif
133*7c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
134*7c478bd9Sstevel@tonic-gate 
135*7c478bd9Sstevel@tonic-gate 	cryptodebug_init(basename(argv[0]));
136*7c478bd9Sstevel@tonic-gate 
137*7c478bd9Sstevel@tonic-gate 	if (argc < REQ_ARG_CNT) {
138*7c478bd9Sstevel@tonic-gate 		usage();
139*7c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
140*7c478bd9Sstevel@tonic-gate 	}
141*7c478bd9Sstevel@tonic-gate 
142*7c478bd9Sstevel@tonic-gate 	/* get the subcommand index */
143*7c478bd9Sstevel@tonic-gate 	cmd_index = 0;
144*7c478bd9Sstevel@tonic-gate 	subcmd = argv[1];
145*7c478bd9Sstevel@tonic-gate 	cmdnum = sizeof (cmd_table)/sizeof (cmd_table[0]);
146*7c478bd9Sstevel@tonic-gate 
147*7c478bd9Sstevel@tonic-gate 	while ((cmd_index < cmdnum) &&
148*7c478bd9Sstevel@tonic-gate 	    (strcmp(subcmd, cmd_table[cmd_index]) != 0)) {
149*7c478bd9Sstevel@tonic-gate 		cmd_index++;
150*7c478bd9Sstevel@tonic-gate 	}
151*7c478bd9Sstevel@tonic-gate 	if (cmd_index >= cmdnum) {
152*7c478bd9Sstevel@tonic-gate 		usage();
153*7c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
154*7c478bd9Sstevel@tonic-gate 	}
155*7c478bd9Sstevel@tonic-gate 
156*7c478bd9Sstevel@tonic-gate 	/* do the subcommand */
157*7c478bd9Sstevel@tonic-gate 	switch (cmd_index) {
158*7c478bd9Sstevel@tonic-gate 	case CRYPTO_LIST:
159*7c478bd9Sstevel@tonic-gate 		rc = do_list(argc, argv);
160*7c478bd9Sstevel@tonic-gate 		break;
161*7c478bd9Sstevel@tonic-gate 	case CRYPTO_DISABLE:
162*7c478bd9Sstevel@tonic-gate 		rc = do_disable(argc, argv);
163*7c478bd9Sstevel@tonic-gate 		break;
164*7c478bd9Sstevel@tonic-gate 	case CRYPTO_ENABLE:
165*7c478bd9Sstevel@tonic-gate 		rc = do_enable(argc, argv);
166*7c478bd9Sstevel@tonic-gate 		break;
167*7c478bd9Sstevel@tonic-gate 	case CRYPTO_INSTALL:
168*7c478bd9Sstevel@tonic-gate 		rc = do_install(argc, argv);
169*7c478bd9Sstevel@tonic-gate 		break;
170*7c478bd9Sstevel@tonic-gate 	case CRYPTO_UNINSTALL:
171*7c478bd9Sstevel@tonic-gate 		rc = do_uninstall(argc, argv);
172*7c478bd9Sstevel@tonic-gate 		break;
173*7c478bd9Sstevel@tonic-gate 	case CRYPTO_UNLOAD:
174*7c478bd9Sstevel@tonic-gate 		rc = do_unload(argc, argv);
175*7c478bd9Sstevel@tonic-gate 		break;
176*7c478bd9Sstevel@tonic-gate 	case CRYPTO_REFRESH:
177*7c478bd9Sstevel@tonic-gate 		rc = do_refresh(argc);
178*7c478bd9Sstevel@tonic-gate 		break;
179*7c478bd9Sstevel@tonic-gate 	case CRYPTO_START:
180*7c478bd9Sstevel@tonic-gate 		rc = do_start(argc);
181*7c478bd9Sstevel@tonic-gate 		break;
182*7c478bd9Sstevel@tonic-gate 	case CRYPTO_STOP:
183*7c478bd9Sstevel@tonic-gate 		rc = do_stop(argc);
184*7c478bd9Sstevel@tonic-gate 		break;
185*7c478bd9Sstevel@tonic-gate 	case CRYPTO_HELP:
186*7c478bd9Sstevel@tonic-gate 		usage();
187*7c478bd9Sstevel@tonic-gate 		rc = SUCCESS;
188*7c478bd9Sstevel@tonic-gate 		break;
189*7c478bd9Sstevel@tonic-gate 	default: /* should not come here */
190*7c478bd9Sstevel@tonic-gate 		usage();
191*7c478bd9Sstevel@tonic-gate 		rc = ERROR_USAGE;
192*7c478bd9Sstevel@tonic-gate 		break;
193*7c478bd9Sstevel@tonic-gate 	}
194*7c478bd9Sstevel@tonic-gate 	return (rc);
195*7c478bd9Sstevel@tonic-gate }
196*7c478bd9Sstevel@tonic-gate 
197*7c478bd9Sstevel@tonic-gate 
198*7c478bd9Sstevel@tonic-gate static void
199*7c478bd9Sstevel@tonic-gate usage(void)
200*7c478bd9Sstevel@tonic-gate {
201*7c478bd9Sstevel@tonic-gate 	/*
202*7c478bd9Sstevel@tonic-gate 	 * TRANSLATION_NOTE:
203*7c478bd9Sstevel@tonic-gate 	 * Command usage is not to be translated.  Only the word "Usage:"
204*7c478bd9Sstevel@tonic-gate 	 * along with localized expressions indicating what kind of value
205*7c478bd9Sstevel@tonic-gate 	 * is expected for arguments.
206*7c478bd9Sstevel@tonic-gate 	 */
207*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, gettext("Usage:\n"));
208*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
209*7c478bd9Sstevel@tonic-gate 	    "  cryptoadm list [-mpv] [provider=<%s> | metaslot]"
210*7c478bd9Sstevel@tonic-gate 	    " [mechanism=<%s>]\n",
211*7c478bd9Sstevel@tonic-gate 	    gettext("provider-name"), gettext("mechanism-list"));
212*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
213*7c478bd9Sstevel@tonic-gate 	    "  cryptoadm disable provider=<%s>"
214*7c478bd9Sstevel@tonic-gate 	    " mechanism=<%s> | random | all\n",
215*7c478bd9Sstevel@tonic-gate 	    gettext("provider-name"), gettext("mechanism-list"));
216*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
217*7c478bd9Sstevel@tonic-gate 	    "  cryptoadm disable metaslot"
218*7c478bd9Sstevel@tonic-gate 	    " [auto-key-migrate] [mechanism=<%s>]\n",
219*7c478bd9Sstevel@tonic-gate 	    gettext("mechanism-list"));
220*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
221*7c478bd9Sstevel@tonic-gate 	    "  cryptoadm enable provider=<%s>"
222*7c478bd9Sstevel@tonic-gate 	    " mechanism=<%s> | random | all\n",
223*7c478bd9Sstevel@tonic-gate 	    gettext("provider-name"), gettext("mechanism-list"));
224*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
225*7c478bd9Sstevel@tonic-gate 	    "  cryptoadm enable metaslot [mechanism=<%s>]"
226*7c478bd9Sstevel@tonic-gate 	    " [[token=<%s>] [slot=<%s>]"
227*7c478bd9Sstevel@tonic-gate 	    " | [default-keystore]] | [auto-key-migrate]\n",
228*7c478bd9Sstevel@tonic-gate 	    gettext("mechanism-list"), gettext("token-label"),
229*7c478bd9Sstevel@tonic-gate 	    gettext("slot-description"));
230*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
231*7c478bd9Sstevel@tonic-gate 	    "  cryptoadm install provider=<%s>\n",
232*7c478bd9Sstevel@tonic-gate 	    gettext("provider-name"));
233*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
234*7c478bd9Sstevel@tonic-gate 	    "  cryptoadm install provider=<%s> [mechanism=<%s>]\n",
235*7c478bd9Sstevel@tonic-gate 	    gettext("provider-name"), gettext("mechanism-list"));
236*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
237*7c478bd9Sstevel@tonic-gate 	    "  cryptoadm uninstall provider=<%s>\n",
238*7c478bd9Sstevel@tonic-gate 	    gettext("provider-name"));
239*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
240*7c478bd9Sstevel@tonic-gate 	    "  cryptoadm unload provider=<%s>\n",
241*7c478bd9Sstevel@tonic-gate 	    gettext("provider-name"));
242*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
243*7c478bd9Sstevel@tonic-gate 	    "  cryptoadm refresh\n"
244*7c478bd9Sstevel@tonic-gate 	    "  cryptoadm start\n"
245*7c478bd9Sstevel@tonic-gate 	    "  cryptoadm stop\n"
246*7c478bd9Sstevel@tonic-gate 	    "  cryptoadm --help\n");
247*7c478bd9Sstevel@tonic-gate }
248*7c478bd9Sstevel@tonic-gate 
249*7c478bd9Sstevel@tonic-gate 
250*7c478bd9Sstevel@tonic-gate /*
251*7c478bd9Sstevel@tonic-gate  * Get the provider type.  This function returns
252*7c478bd9Sstevel@tonic-gate  * - PROV_UEF_LIB if provname contains an absolute path name
253*7c478bd9Sstevel@tonic-gate  * - PROV_KEF_SOFT if provname is a base name only
254*7c478bd9Sstevel@tonic-gate  * - PROV_KEF_HARD if provname contains one slash only and the slash is not
255*7c478bd9Sstevel@tonic-gate  *	the 1st character.
256*7c478bd9Sstevel@tonic-gate  * - PROV_BADNAME othewise.
257*7c478bd9Sstevel@tonic-gate  */
258*7c478bd9Sstevel@tonic-gate static int
259*7c478bd9Sstevel@tonic-gate get_provider_type(char *provname)
260*7c478bd9Sstevel@tonic-gate {
261*7c478bd9Sstevel@tonic-gate 	char *pslash1;
262*7c478bd9Sstevel@tonic-gate 	char *pslash2;
263*7c478bd9Sstevel@tonic-gate 
264*7c478bd9Sstevel@tonic-gate 	if (provname == NULL) {
265*7c478bd9Sstevel@tonic-gate 		return (FAILURE);
266*7c478bd9Sstevel@tonic-gate 	}
267*7c478bd9Sstevel@tonic-gate 
268*7c478bd9Sstevel@tonic-gate 	if (provname[0] == '/') {
269*7c478bd9Sstevel@tonic-gate 		return (PROV_UEF_LIB);
270*7c478bd9Sstevel@tonic-gate 	} else if ((pslash1 = strchr(provname, SEP_SLASH)) == NULL) {
271*7c478bd9Sstevel@tonic-gate 		/* no slash */
272*7c478bd9Sstevel@tonic-gate 		return (PROV_KEF_SOFT);
273*7c478bd9Sstevel@tonic-gate 	} else {
274*7c478bd9Sstevel@tonic-gate 		pslash2 = strrchr(provname, SEP_SLASH);
275*7c478bd9Sstevel@tonic-gate 		if (pslash1 == pslash2) {
276*7c478bd9Sstevel@tonic-gate 			return (PROV_KEF_HARD);
277*7c478bd9Sstevel@tonic-gate 		} else {
278*7c478bd9Sstevel@tonic-gate 			return (PROV_BADNAME);
279*7c478bd9Sstevel@tonic-gate 		}
280*7c478bd9Sstevel@tonic-gate 	}
281*7c478bd9Sstevel@tonic-gate }
282*7c478bd9Sstevel@tonic-gate 
283*7c478bd9Sstevel@tonic-gate /*
284*7c478bd9Sstevel@tonic-gate  * Get the provider structure.  This function returns NULL if no valid
285*7c478bd9Sstevel@tonic-gate  * provider= is found in argv[], otherwise a cryptoadm_provider_t is returned.
286*7c478bd9Sstevel@tonic-gate  * If provider= is found but has no argument, then a cryptoadm_provider_t
287*7c478bd9Sstevel@tonic-gate  * with cp_type = PROV_BADNAME is returned.
288*7c478bd9Sstevel@tonic-gate  */
289*7c478bd9Sstevel@tonic-gate static cryptoadm_provider_t *
290*7c478bd9Sstevel@tonic-gate get_provider(int argc, char **argv)
291*7c478bd9Sstevel@tonic-gate {
292*7c478bd9Sstevel@tonic-gate 	int c = 0;
293*7c478bd9Sstevel@tonic-gate 	boolean_t found = B_FALSE;
294*7c478bd9Sstevel@tonic-gate 	cryptoadm_provider_t *provider = NULL;
295*7c478bd9Sstevel@tonic-gate 	char *provstr = NULL, *savstr;
296*7c478bd9Sstevel@tonic-gate 	boolean_t is_metaslot = B_FALSE;
297*7c478bd9Sstevel@tonic-gate 
298*7c478bd9Sstevel@tonic-gate 	while (!found && ++c < argc) {
299*7c478bd9Sstevel@tonic-gate 		if (strncmp(argv[c], METASLOT_KEYWORD,
300*7c478bd9Sstevel@tonic-gate 		    strlen(METASLOT_KEYWORD)) == 0) {
301*7c478bd9Sstevel@tonic-gate 			is_metaslot = B_TRUE;
302*7c478bd9Sstevel@tonic-gate 			found = B_TRUE;
303*7c478bd9Sstevel@tonic-gate 		} else if (strncmp(argv[c], KN_PROVIDER,
304*7c478bd9Sstevel@tonic-gate 		    strlen(KN_PROVIDER)) == 0 &&
305*7c478bd9Sstevel@tonic-gate 		    strlen(argv[c]) > strlen(KN_PROVIDER)) {
306*7c478bd9Sstevel@tonic-gate 			if ((provstr = strdup(argv[c])) == NULL) {
307*7c478bd9Sstevel@tonic-gate 				int err = errno;
308*7c478bd9Sstevel@tonic-gate 				/*
309*7c478bd9Sstevel@tonic-gate 				 * TRANSLATION_NOTE:
310*7c478bd9Sstevel@tonic-gate 				 * "get_provider" is a function name and should
311*7c478bd9Sstevel@tonic-gate 				 * not be translated.
312*7c478bd9Sstevel@tonic-gate 				 */
313*7c478bd9Sstevel@tonic-gate 				cryptoerror(LOG_STDERR, "get_provider: %s.",
314*7c478bd9Sstevel@tonic-gate 				    strerror(err));
315*7c478bd9Sstevel@tonic-gate 				return (NULL);
316*7c478bd9Sstevel@tonic-gate 			}
317*7c478bd9Sstevel@tonic-gate 			found = B_TRUE;
318*7c478bd9Sstevel@tonic-gate 		}
319*7c478bd9Sstevel@tonic-gate 	}
320*7c478bd9Sstevel@tonic-gate 	if (!found)
321*7c478bd9Sstevel@tonic-gate 		return (NULL);
322*7c478bd9Sstevel@tonic-gate 
323*7c478bd9Sstevel@tonic-gate 	provider = malloc(sizeof (cryptoadm_provider_t));
324*7c478bd9Sstevel@tonic-gate 	if (provider == NULL) {
325*7c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("out of memory."));
326*7c478bd9Sstevel@tonic-gate 		if (provstr) {
327*7c478bd9Sstevel@tonic-gate 			free(provstr);
328*7c478bd9Sstevel@tonic-gate 		}
329*7c478bd9Sstevel@tonic-gate 		return (NULL);
330*7c478bd9Sstevel@tonic-gate 	}
331*7c478bd9Sstevel@tonic-gate 
332*7c478bd9Sstevel@tonic-gate 	if (is_metaslot) {
333*7c478bd9Sstevel@tonic-gate 		(void) strlcpy(provider->cp_name, METASLOT_KEYWORD,
334*7c478bd9Sstevel@tonic-gate 		    strlen(METASLOT_KEYWORD));
335*7c478bd9Sstevel@tonic-gate 		provider->cp_type = METASLOT;
336*7c478bd9Sstevel@tonic-gate 	} else {
337*7c478bd9Sstevel@tonic-gate 
338*7c478bd9Sstevel@tonic-gate 		savstr = provstr;
339*7c478bd9Sstevel@tonic-gate 		(void) strtok(provstr, "=");
340*7c478bd9Sstevel@tonic-gate 		provstr = strtok(NULL, "=");
341*7c478bd9Sstevel@tonic-gate 		if (provstr == NULL) {
342*7c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR, gettext("bad provider name."));
343*7c478bd9Sstevel@tonic-gate 			provider->cp_type = PROV_BADNAME;
344*7c478bd9Sstevel@tonic-gate 			free(savstr);
345*7c478bd9Sstevel@tonic-gate 			return (provider);
346*7c478bd9Sstevel@tonic-gate 		}
347*7c478bd9Sstevel@tonic-gate 
348*7c478bd9Sstevel@tonic-gate 		(void) strlcpy(provider->cp_name, provstr,
349*7c478bd9Sstevel@tonic-gate 		    sizeof (provider->cp_name));
350*7c478bd9Sstevel@tonic-gate 		provider->cp_type = get_provider_type(provider->cp_name);
351*7c478bd9Sstevel@tonic-gate 
352*7c478bd9Sstevel@tonic-gate 		free(savstr);
353*7c478bd9Sstevel@tonic-gate 	}
354*7c478bd9Sstevel@tonic-gate 	return (provider);
355*7c478bd9Sstevel@tonic-gate }
356*7c478bd9Sstevel@tonic-gate 
357*7c478bd9Sstevel@tonic-gate /*
358*7c478bd9Sstevel@tonic-gate  * Process the "feature" operands.
359*7c478bd9Sstevel@tonic-gate  *
360*7c478bd9Sstevel@tonic-gate  * "argc" and "argv" contain values specified on the command line.
361*7c478bd9Sstevel@tonic-gate  * All other arguments are used for returning parsing results.
362*7c478bd9Sstevel@tonic-gate  * If any of these arguments are NULL, that keyword is not expected,
363*7c478bd9Sstevel@tonic-gate  * and FAILURE will be returned.
364*7c478bd9Sstevel@tonic-gate  */
365*7c478bd9Sstevel@tonic-gate static int
366*7c478bd9Sstevel@tonic-gate process_metaslot_operands(int argc, char **argv, char **meta_ks_token,
367*7c478bd9Sstevel@tonic-gate     char **meta_ks_slot, boolean_t *use_default,
368*7c478bd9Sstevel@tonic-gate     boolean_t *auto_key_migrate_flag)
369*7c478bd9Sstevel@tonic-gate {
370*7c478bd9Sstevel@tonic-gate 	int c = 2;
371*7c478bd9Sstevel@tonic-gate 	int rc = SUCCESS;
372*7c478bd9Sstevel@tonic-gate 
373*7c478bd9Sstevel@tonic-gate 	while (++c < argc) {
374*7c478bd9Sstevel@tonic-gate 		if ((strncmp(argv[c], KN_MECH, strlen(KN_MECH)) == 0) &&
375*7c478bd9Sstevel@tonic-gate 		    strlen(argv[c]) > strlen(KN_MECH)) {
376*7c478bd9Sstevel@tonic-gate 
377*7c478bd9Sstevel@tonic-gate 			/* process mechanism operands */
378*7c478bd9Sstevel@tonic-gate 			if ((rc = process_mech_operands(argc, argv, B_TRUE))
379*7c478bd9Sstevel@tonic-gate 			    != SUCCESS) {
380*7c478bd9Sstevel@tonic-gate 				goto finish;
381*7c478bd9Sstevel@tonic-gate 			}
382*7c478bd9Sstevel@tonic-gate 
383*7c478bd9Sstevel@tonic-gate 		} else if ((strncmp(argv[c], KN_TOKEN,
384*7c478bd9Sstevel@tonic-gate 		    strlen(KN_TOKEN)) == 0) &&
385*7c478bd9Sstevel@tonic-gate 		    strlen(argv[c]) > strlen(KN_TOKEN)) {
386*7c478bd9Sstevel@tonic-gate 			if ((meta_ks_token) && (strtok(argv[c], "=") != NULL)) {
387*7c478bd9Sstevel@tonic-gate 				char *tmp;
388*7c478bd9Sstevel@tonic-gate 				if ((tmp = strtok(NULL, "=")) != NULL) {
389*7c478bd9Sstevel@tonic-gate 					*meta_ks_token = strdup(tmp);
390*7c478bd9Sstevel@tonic-gate 				} else {
391*7c478bd9Sstevel@tonic-gate 					return (FAILURE);
392*7c478bd9Sstevel@tonic-gate 				}
393*7c478bd9Sstevel@tonic-gate 			} else {
394*7c478bd9Sstevel@tonic-gate 				return (FAILURE);
395*7c478bd9Sstevel@tonic-gate 			}
396*7c478bd9Sstevel@tonic-gate 
397*7c478bd9Sstevel@tonic-gate 		} else if ((strncmp(argv[c], KN_SLOT,
398*7c478bd9Sstevel@tonic-gate 		    strlen(KN_SLOT)) == 0) &&
399*7c478bd9Sstevel@tonic-gate 		    strlen(argv[c]) > strlen(KN_SLOT)) {
400*7c478bd9Sstevel@tonic-gate 
401*7c478bd9Sstevel@tonic-gate 			if ((meta_ks_slot) && (strtok(argv[c], "=") != NULL)) {
402*7c478bd9Sstevel@tonic-gate 				char *tmp;
403*7c478bd9Sstevel@tonic-gate 				if ((tmp = strtok(NULL, "=")) != NULL) {
404*7c478bd9Sstevel@tonic-gate 					*meta_ks_slot = strdup(tmp);
405*7c478bd9Sstevel@tonic-gate 				} else {
406*7c478bd9Sstevel@tonic-gate 					return (FAILURE);
407*7c478bd9Sstevel@tonic-gate 				}
408*7c478bd9Sstevel@tonic-gate 			} else {
409*7c478bd9Sstevel@tonic-gate 				return (FAILURE);
410*7c478bd9Sstevel@tonic-gate 			}
411*7c478bd9Sstevel@tonic-gate 
412*7c478bd9Sstevel@tonic-gate 		} else if (strncmp(argv[c], KN_DEFAULT_KS,
413*7c478bd9Sstevel@tonic-gate 		    strlen(KN_DEFAULT_KS)) == 0) {
414*7c478bd9Sstevel@tonic-gate 
415*7c478bd9Sstevel@tonic-gate 			if (use_default) {
416*7c478bd9Sstevel@tonic-gate 				*use_default = B_TRUE;
417*7c478bd9Sstevel@tonic-gate 			} else {
418*7c478bd9Sstevel@tonic-gate 				return (FAILURE);
419*7c478bd9Sstevel@tonic-gate 			}
420*7c478bd9Sstevel@tonic-gate 		} else if (strncmp(argv[c], KN_AUTO_KEY_MIGRATE,
421*7c478bd9Sstevel@tonic-gate 		    strlen(KN_AUTO_KEY_MIGRATE)) == 0) {
422*7c478bd9Sstevel@tonic-gate 
423*7c478bd9Sstevel@tonic-gate 			if (auto_key_migrate_flag) {
424*7c478bd9Sstevel@tonic-gate 				*auto_key_migrate_flag = B_TRUE;
425*7c478bd9Sstevel@tonic-gate 			} else {
426*7c478bd9Sstevel@tonic-gate 				return (FAILURE);
427*7c478bd9Sstevel@tonic-gate 			}
428*7c478bd9Sstevel@tonic-gate 		} else {
429*7c478bd9Sstevel@tonic-gate 			return (FAILURE);
430*7c478bd9Sstevel@tonic-gate 		}
431*7c478bd9Sstevel@tonic-gate 	}
432*7c478bd9Sstevel@tonic-gate finish:
433*7c478bd9Sstevel@tonic-gate 	return (rc);
434*7c478bd9Sstevel@tonic-gate }
435*7c478bd9Sstevel@tonic-gate 
436*7c478bd9Sstevel@tonic-gate /*
437*7c478bd9Sstevel@tonic-gate  * Process the "feature" operands.
438*7c478bd9Sstevel@tonic-gate  */
439*7c478bd9Sstevel@tonic-gate static int
440*7c478bd9Sstevel@tonic-gate process_feature_operands(int argc, char **argv)
441*7c478bd9Sstevel@tonic-gate {
442*7c478bd9Sstevel@tonic-gate 	int c = 2;
443*7c478bd9Sstevel@tonic-gate 
444*7c478bd9Sstevel@tonic-gate 	while (++c < argc) {
445*7c478bd9Sstevel@tonic-gate 		if (strcmp(argv[c], KN_ALL) == 0) {
446*7c478bd9Sstevel@tonic-gate 			allflag = B_TRUE;
447*7c478bd9Sstevel@tonic-gate 			rndflag = B_TRUE; /* all includes random also. */
448*7c478bd9Sstevel@tonic-gate 		} else if (strcmp(argv[c], RANDOM) == 0) {
449*7c478bd9Sstevel@tonic-gate 			rndflag = B_TRUE;
450*7c478bd9Sstevel@tonic-gate 		}
451*7c478bd9Sstevel@tonic-gate 	}
452*7c478bd9Sstevel@tonic-gate 	return (SUCCESS);
453*7c478bd9Sstevel@tonic-gate }
454*7c478bd9Sstevel@tonic-gate 
455*7c478bd9Sstevel@tonic-gate /*
456*7c478bd9Sstevel@tonic-gate  * Process the mechanism operands for the disable, enable and install
457*7c478bd9Sstevel@tonic-gate  * subcommands.  This function sets the static variable allflag to be B_TRUE
458*7c478bd9Sstevel@tonic-gate  * if the keyword "all" is specified, otherwise builds a link list of the
459*7c478bd9Sstevel@tonic-gate  * mechanism operands and save it in the static variable mecharglist.
460*7c478bd9Sstevel@tonic-gate  *
461*7c478bd9Sstevel@tonic-gate  * This function returns
462*7c478bd9Sstevel@tonic-gate  * 	ERROR_USAGE: mechanism operand is missing.
463*7c478bd9Sstevel@tonic-gate  * 	FAILURE: out of memory.
464*7c478bd9Sstevel@tonic-gate  * 	SUCCESS: otherwise.
465*7c478bd9Sstevel@tonic-gate  */
466*7c478bd9Sstevel@tonic-gate static int
467*7c478bd9Sstevel@tonic-gate process_mech_operands(int argc, char **argv, boolean_t quiet)
468*7c478bd9Sstevel@tonic-gate {
469*7c478bd9Sstevel@tonic-gate 	mechlist_t *pmech;
470*7c478bd9Sstevel@tonic-gate 	mechlist_t *pcur = NULL;
471*7c478bd9Sstevel@tonic-gate 	mechlist_t *phead = NULL;
472*7c478bd9Sstevel@tonic-gate 	boolean_t found = B_FALSE;
473*7c478bd9Sstevel@tonic-gate 	char *mechliststr = NULL;
474*7c478bd9Sstevel@tonic-gate 	char *curmech = NULL;
475*7c478bd9Sstevel@tonic-gate 	int c = -1;
476*7c478bd9Sstevel@tonic-gate 	int rc = SUCCESS;
477*7c478bd9Sstevel@tonic-gate 
478*7c478bd9Sstevel@tonic-gate 	while (!found && ++c < argc) {
479*7c478bd9Sstevel@tonic-gate 		if ((strncmp(argv[c], KN_MECH, strlen(KN_MECH)) == 0) &&
480*7c478bd9Sstevel@tonic-gate 		    strlen(argv[c]) > strlen(KN_MECH)) {
481*7c478bd9Sstevel@tonic-gate 			found = B_TRUE;
482*7c478bd9Sstevel@tonic-gate 		}
483*7c478bd9Sstevel@tonic-gate 	}
484*7c478bd9Sstevel@tonic-gate 	if (!found) {
485*7c478bd9Sstevel@tonic-gate 		if (!quiet)
486*7c478bd9Sstevel@tonic-gate 			/*
487*7c478bd9Sstevel@tonic-gate 			 * TRANSLATION_NOTE:
488*7c478bd9Sstevel@tonic-gate 			 * "mechanism" could be either a literal keyword
489*7c478bd9Sstevel@tonic-gate 			 * and hence not to be translated, or a descriptive
490*7c478bd9Sstevel@tonic-gate 			 * word and translatable.  A choice was made to
491*7c478bd9Sstevel@tonic-gate 			 * view it as a literal keyword.
492*7c478bd9Sstevel@tonic-gate 			 */
493*7c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR,
494*7c478bd9Sstevel@tonic-gate 				gettext("the %s operand is missing.\n"),
495*7c478bd9Sstevel@tonic-gate 				"mechanism");
496*7c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
497*7c478bd9Sstevel@tonic-gate 	}
498*7c478bd9Sstevel@tonic-gate 	(void) strtok(argv[c], "=");
499*7c478bd9Sstevel@tonic-gate 	mechliststr = strtok(NULL, "=");
500*7c478bd9Sstevel@tonic-gate 
501*7c478bd9Sstevel@tonic-gate 	if (strcmp(mechliststr, "all") == 0) {
502*7c478bd9Sstevel@tonic-gate 		allflag = B_TRUE;
503*7c478bd9Sstevel@tonic-gate 		mecharglist = NULL;
504*7c478bd9Sstevel@tonic-gate 		return (SUCCESS);
505*7c478bd9Sstevel@tonic-gate 	}
506*7c478bd9Sstevel@tonic-gate 
507*7c478bd9Sstevel@tonic-gate 	curmech = strtok(mechliststr, ",");
508*7c478bd9Sstevel@tonic-gate 	do {
509*7c478bd9Sstevel@tonic-gate 		if ((pmech = create_mech(curmech)) == NULL) {
510*7c478bd9Sstevel@tonic-gate 			rc = FAILURE;
511*7c478bd9Sstevel@tonic-gate 			break;
512*7c478bd9Sstevel@tonic-gate 		} else {
513*7c478bd9Sstevel@tonic-gate 			if (phead == NULL) {
514*7c478bd9Sstevel@tonic-gate 				phead = pcur = pmech;
515*7c478bd9Sstevel@tonic-gate 			} else {
516*7c478bd9Sstevel@tonic-gate 				pcur->next = pmech;
517*7c478bd9Sstevel@tonic-gate 				pcur = pmech;
518*7c478bd9Sstevel@tonic-gate 			}
519*7c478bd9Sstevel@tonic-gate 		}
520*7c478bd9Sstevel@tonic-gate 	} while ((curmech = strtok(NULL, ",")) != NULL);
521*7c478bd9Sstevel@tonic-gate 
522*7c478bd9Sstevel@tonic-gate 	if (rc == FAILURE) {
523*7c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("out of memory."));
524*7c478bd9Sstevel@tonic-gate 		free_mechlist(phead);
525*7c478bd9Sstevel@tonic-gate 	} else {
526*7c478bd9Sstevel@tonic-gate 		mecharglist = phead;
527*7c478bd9Sstevel@tonic-gate 		rc = SUCCESS;
528*7c478bd9Sstevel@tonic-gate 	}
529*7c478bd9Sstevel@tonic-gate 	return (rc);
530*7c478bd9Sstevel@tonic-gate }
531*7c478bd9Sstevel@tonic-gate 
532*7c478bd9Sstevel@tonic-gate 
533*7c478bd9Sstevel@tonic-gate 
534*7c478bd9Sstevel@tonic-gate /*
535*7c478bd9Sstevel@tonic-gate  * The top level function for the list subcommand and options.
536*7c478bd9Sstevel@tonic-gate  */
537*7c478bd9Sstevel@tonic-gate static int
538*7c478bd9Sstevel@tonic-gate do_list(int argc, char **argv)
539*7c478bd9Sstevel@tonic-gate {
540*7c478bd9Sstevel@tonic-gate 	boolean_t	mflag = B_FALSE;
541*7c478bd9Sstevel@tonic-gate 	boolean_t	pflag = B_FALSE;
542*7c478bd9Sstevel@tonic-gate 	boolean_t	vflag = B_FALSE;
543*7c478bd9Sstevel@tonic-gate 	char	ch;
544*7c478bd9Sstevel@tonic-gate 	cryptoadm_provider_t 	*prov = NULL;
545*7c478bd9Sstevel@tonic-gate 	int	rc = SUCCESS;
546*7c478bd9Sstevel@tonic-gate 
547*7c478bd9Sstevel@tonic-gate 	argc -= 1;
548*7c478bd9Sstevel@tonic-gate 	argv += 1;
549*7c478bd9Sstevel@tonic-gate 
550*7c478bd9Sstevel@tonic-gate 	if (argc == 1) {
551*7c478bd9Sstevel@tonic-gate 		rc = list_simple_for_all(B_FALSE);
552*7c478bd9Sstevel@tonic-gate 		goto out;
553*7c478bd9Sstevel@tonic-gate 	}
554*7c478bd9Sstevel@tonic-gate 
555*7c478bd9Sstevel@tonic-gate 	/*
556*7c478bd9Sstevel@tonic-gate 	 * [-v] [-m] [-p] [provider=<>] [mechanism=<>]
557*7c478bd9Sstevel@tonic-gate 	 */
558*7c478bd9Sstevel@tonic-gate 	if (argc > 5) {
559*7c478bd9Sstevel@tonic-gate 		usage();
560*7c478bd9Sstevel@tonic-gate 		return (rc);
561*7c478bd9Sstevel@tonic-gate 	}
562*7c478bd9Sstevel@tonic-gate 
563*7c478bd9Sstevel@tonic-gate 	while ((ch = getopt(argc, argv, "mpv")) != EOF) {
564*7c478bd9Sstevel@tonic-gate 		switch (ch) {
565*7c478bd9Sstevel@tonic-gate 		case 'm':
566*7c478bd9Sstevel@tonic-gate 			mflag = B_TRUE;
567*7c478bd9Sstevel@tonic-gate 			if (pflag) {
568*7c478bd9Sstevel@tonic-gate 				rc = ERROR_USAGE;
569*7c478bd9Sstevel@tonic-gate 			}
570*7c478bd9Sstevel@tonic-gate 			break;
571*7c478bd9Sstevel@tonic-gate 		case 'p':
572*7c478bd9Sstevel@tonic-gate 			pflag = B_TRUE;
573*7c478bd9Sstevel@tonic-gate 			if (mflag || vflag) {
574*7c478bd9Sstevel@tonic-gate 				rc = ERROR_USAGE;
575*7c478bd9Sstevel@tonic-gate 			}
576*7c478bd9Sstevel@tonic-gate 			break;
577*7c478bd9Sstevel@tonic-gate 		case 'v':
578*7c478bd9Sstevel@tonic-gate 			vflag = B_TRUE;
579*7c478bd9Sstevel@tonic-gate 			if (pflag)
580*7c478bd9Sstevel@tonic-gate 				rc = ERROR_USAGE;
581*7c478bd9Sstevel@tonic-gate 			break;
582*7c478bd9Sstevel@tonic-gate 		default:
583*7c478bd9Sstevel@tonic-gate 			rc = ERROR_USAGE;
584*7c478bd9Sstevel@tonic-gate 			break;
585*7c478bd9Sstevel@tonic-gate 		}
586*7c478bd9Sstevel@tonic-gate 	}
587*7c478bd9Sstevel@tonic-gate 
588*7c478bd9Sstevel@tonic-gate 	if (rc == ERROR_USAGE) {
589*7c478bd9Sstevel@tonic-gate 		usage();
590*7c478bd9Sstevel@tonic-gate 		return (rc);
591*7c478bd9Sstevel@tonic-gate 	}
592*7c478bd9Sstevel@tonic-gate 
593*7c478bd9Sstevel@tonic-gate 	if ((rc = process_feature_operands(argc, argv)) != SUCCESS) {
594*7c478bd9Sstevel@tonic-gate 		goto out;
595*7c478bd9Sstevel@tonic-gate 	}
596*7c478bd9Sstevel@tonic-gate 
597*7c478bd9Sstevel@tonic-gate 	prov = get_provider(argc, argv);
598*7c478bd9Sstevel@tonic-gate 
599*7c478bd9Sstevel@tonic-gate 	if (mflag || vflag) {
600*7c478bd9Sstevel@tonic-gate 		if (argc > 0) {
601*7c478bd9Sstevel@tonic-gate 			rc = process_mech_operands(argc, argv, B_TRUE);
602*7c478bd9Sstevel@tonic-gate 			if (rc == FAILURE)
603*7c478bd9Sstevel@tonic-gate 				goto out;
604*7c478bd9Sstevel@tonic-gate 			/* "-m" is implied when a mechanism list is given */
605*7c478bd9Sstevel@tonic-gate 			if (mecharglist != NULL || allflag)
606*7c478bd9Sstevel@tonic-gate 				mflag = B_TRUE;
607*7c478bd9Sstevel@tonic-gate 		}
608*7c478bd9Sstevel@tonic-gate 	}
609*7c478bd9Sstevel@tonic-gate 
610*7c478bd9Sstevel@tonic-gate 	if (prov == NULL) {
611*7c478bd9Sstevel@tonic-gate 		if (mflag) {
612*7c478bd9Sstevel@tonic-gate 			rc = list_mechlist_for_all(vflag);
613*7c478bd9Sstevel@tonic-gate 		} else if (pflag) {
614*7c478bd9Sstevel@tonic-gate 			rc = list_policy_for_all();
615*7c478bd9Sstevel@tonic-gate 		} else if (vflag) {
616*7c478bd9Sstevel@tonic-gate 			rc = list_simple_for_all(vflag);
617*7c478bd9Sstevel@tonic-gate 		}
618*7c478bd9Sstevel@tonic-gate 	} else if (prov->cp_type == METASLOT) {
619*7c478bd9Sstevel@tonic-gate 		if ((!mflag) && (!vflag) && (!pflag)) {
620*7c478bd9Sstevel@tonic-gate 			/* no flag is specified, just list metaslot status */
621*7c478bd9Sstevel@tonic-gate 			rc = list_metaslot_info(mflag, vflag, mecharglist);
622*7c478bd9Sstevel@tonic-gate 		} else if (mflag || vflag) {
623*7c478bd9Sstevel@tonic-gate 			rc = list_metaslot_info(mflag, vflag, mecharglist);
624*7c478bd9Sstevel@tonic-gate 		} else if (pflag) {
625*7c478bd9Sstevel@tonic-gate 			rc = list_metaslot_policy();
626*7c478bd9Sstevel@tonic-gate 		} else {
627*7c478bd9Sstevel@tonic-gate 			/* error message */
628*7c478bd9Sstevel@tonic-gate 			usage();
629*7c478bd9Sstevel@tonic-gate 			rc = ERROR_USAGE;
630*7c478bd9Sstevel@tonic-gate 		}
631*7c478bd9Sstevel@tonic-gate 	} else if (prov->cp_type == PROV_BADNAME) {
632*7c478bd9Sstevel@tonic-gate 		usage();
633*7c478bd9Sstevel@tonic-gate 		rc = ERROR_USAGE;
634*7c478bd9Sstevel@tonic-gate 		goto out;
635*7c478bd9Sstevel@tonic-gate 	} else { /* do the listing for a provider only */
636*7c478bd9Sstevel@tonic-gate 		if (mflag || vflag) {
637*7c478bd9Sstevel@tonic-gate 			if (vflag)
638*7c478bd9Sstevel@tonic-gate 				(void) printf(gettext("Provider: %s\n"),
639*7c478bd9Sstevel@tonic-gate 					prov->cp_name);
640*7c478bd9Sstevel@tonic-gate 			switch (prov->cp_type) {
641*7c478bd9Sstevel@tonic-gate 			case PROV_UEF_LIB:
642*7c478bd9Sstevel@tonic-gate 				rc = list_mechlist_for_lib(prov->cp_name,
643*7c478bd9Sstevel@tonic-gate 					mecharglist, NULL, B_FALSE,
644*7c478bd9Sstevel@tonic-gate 					vflag, mflag);
645*7c478bd9Sstevel@tonic-gate 				break;
646*7c478bd9Sstevel@tonic-gate 			case PROV_KEF_SOFT:
647*7c478bd9Sstevel@tonic-gate 				rc = list_mechlist_for_soft(prov->cp_name);
648*7c478bd9Sstevel@tonic-gate 				break;
649*7c478bd9Sstevel@tonic-gate 			case PROV_KEF_HARD:
650*7c478bd9Sstevel@tonic-gate 				rc = list_mechlist_for_hard(prov->cp_name);
651*7c478bd9Sstevel@tonic-gate 				break;
652*7c478bd9Sstevel@tonic-gate 			default: /* should not come here */
653*7c478bd9Sstevel@tonic-gate 				rc = FAILURE;
654*7c478bd9Sstevel@tonic-gate 				break;
655*7c478bd9Sstevel@tonic-gate 			}
656*7c478bd9Sstevel@tonic-gate 		} else if (pflag) {
657*7c478bd9Sstevel@tonic-gate 			switch (prov->cp_type) {
658*7c478bd9Sstevel@tonic-gate 			case PROV_UEF_LIB:
659*7c478bd9Sstevel@tonic-gate 				rc = list_policy_for_lib(prov->cp_name);
660*7c478bd9Sstevel@tonic-gate 				break;
661*7c478bd9Sstevel@tonic-gate 			case PROV_KEF_SOFT:
662*7c478bd9Sstevel@tonic-gate 				if (getzoneid() == GLOBAL_ZONEID) {
663*7c478bd9Sstevel@tonic-gate 					rc = list_policy_for_soft(
664*7c478bd9Sstevel@tonic-gate 					    prov->cp_name);
665*7c478bd9Sstevel@tonic-gate 				} else {
666*7c478bd9Sstevel@tonic-gate 					/*
667*7c478bd9Sstevel@tonic-gate 					 * TRANSLATION_NOTE:
668*7c478bd9Sstevel@tonic-gate 					 * "global" is keyword and not to
669*7c478bd9Sstevel@tonic-gate 					 * be translated.
670*7c478bd9Sstevel@tonic-gate 					 */
671*7c478bd9Sstevel@tonic-gate 					cryptoerror(LOG_STDERR, gettext(
672*7c478bd9Sstevel@tonic-gate 					    "policy information for kernel "
673*7c478bd9Sstevel@tonic-gate 					    "providers is available "
674*7c478bd9Sstevel@tonic-gate 					    "in the %s zone only"), "global");
675*7c478bd9Sstevel@tonic-gate 					rc = FAILURE;
676*7c478bd9Sstevel@tonic-gate 				}
677*7c478bd9Sstevel@tonic-gate 				break;
678*7c478bd9Sstevel@tonic-gate 			case PROV_KEF_HARD:
679*7c478bd9Sstevel@tonic-gate 				if (getzoneid() == GLOBAL_ZONEID) {
680*7c478bd9Sstevel@tonic-gate 					rc = list_policy_for_hard(
681*7c478bd9Sstevel@tonic-gate 					    prov->cp_name);
682*7c478bd9Sstevel@tonic-gate 				} else {
683*7c478bd9Sstevel@tonic-gate 					/*
684*7c478bd9Sstevel@tonic-gate 					 * TRANSLATION_NOTE:
685*7c478bd9Sstevel@tonic-gate 					 * "global" is keyword and not to
686*7c478bd9Sstevel@tonic-gate 					 * be translated.
687*7c478bd9Sstevel@tonic-gate 					 */
688*7c478bd9Sstevel@tonic-gate 					cryptoerror(LOG_STDERR, gettext(
689*7c478bd9Sstevel@tonic-gate 					    "policy information for kernel "
690*7c478bd9Sstevel@tonic-gate 					    "providers is available "
691*7c478bd9Sstevel@tonic-gate 					    "in the %s zone only"), "global");
692*7c478bd9Sstevel@tonic-gate 					rc = FAILURE;
693*7c478bd9Sstevel@tonic-gate 				}
694*7c478bd9Sstevel@tonic-gate 
695*7c478bd9Sstevel@tonic-gate 				break;
696*7c478bd9Sstevel@tonic-gate 			default: /* should not come here */
697*7c478bd9Sstevel@tonic-gate 				rc = FAILURE;
698*7c478bd9Sstevel@tonic-gate 				break;
699*7c478bd9Sstevel@tonic-gate 			}
700*7c478bd9Sstevel@tonic-gate 		} else {
701*7c478bd9Sstevel@tonic-gate 			/* error message */
702*7c478bd9Sstevel@tonic-gate 			usage();
703*7c478bd9Sstevel@tonic-gate 			rc = ERROR_USAGE;
704*7c478bd9Sstevel@tonic-gate 		}
705*7c478bd9Sstevel@tonic-gate 	}
706*7c478bd9Sstevel@tonic-gate 
707*7c478bd9Sstevel@tonic-gate out:
708*7c478bd9Sstevel@tonic-gate 	if (prov != NULL)
709*7c478bd9Sstevel@tonic-gate 		free(prov);
710*7c478bd9Sstevel@tonic-gate 
711*7c478bd9Sstevel@tonic-gate 	if (mecharglist != NULL)
712*7c478bd9Sstevel@tonic-gate 		free_mechlist(mecharglist);
713*7c478bd9Sstevel@tonic-gate 	return (rc);
714*7c478bd9Sstevel@tonic-gate }
715*7c478bd9Sstevel@tonic-gate 
716*7c478bd9Sstevel@tonic-gate 
717*7c478bd9Sstevel@tonic-gate /*
718*7c478bd9Sstevel@tonic-gate  * The top level function for the disable subcommand.
719*7c478bd9Sstevel@tonic-gate  */
720*7c478bd9Sstevel@tonic-gate static int
721*7c478bd9Sstevel@tonic-gate do_disable(int argc, char **argv)
722*7c478bd9Sstevel@tonic-gate {
723*7c478bd9Sstevel@tonic-gate 	cryptoadm_provider_t	*prov = NULL;
724*7c478bd9Sstevel@tonic-gate 	int	rc = SUCCESS;
725*7c478bd9Sstevel@tonic-gate 	boolean_t auto_key_migrate_flag = B_FALSE;
726*7c478bd9Sstevel@tonic-gate 
727*7c478bd9Sstevel@tonic-gate 	if ((argc < 3) || (argc > 5)) {
728*7c478bd9Sstevel@tonic-gate 		usage();
729*7c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
730*7c478bd9Sstevel@tonic-gate 	}
731*7c478bd9Sstevel@tonic-gate 
732*7c478bd9Sstevel@tonic-gate 	prov = get_provider(argc, argv);
733*7c478bd9Sstevel@tonic-gate 	if (prov == NULL) {
734*7c478bd9Sstevel@tonic-gate 		usage();
735*7c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
736*7c478bd9Sstevel@tonic-gate 	}
737*7c478bd9Sstevel@tonic-gate 	if (prov->cp_type == PROV_BADNAME) {
738*7c478bd9Sstevel@tonic-gate 		return (FAILURE);
739*7c478bd9Sstevel@tonic-gate 	}
740*7c478bd9Sstevel@tonic-gate 
741*7c478bd9Sstevel@tonic-gate 	if ((rc = process_feature_operands(argc, argv)) != SUCCESS) {
742*7c478bd9Sstevel@tonic-gate 		goto out;
743*7c478bd9Sstevel@tonic-gate 	}
744*7c478bd9Sstevel@tonic-gate 
745*7c478bd9Sstevel@tonic-gate 	/*
746*7c478bd9Sstevel@tonic-gate 	 * If allflag or rndflag has already been set there is no reason to
747*7c478bd9Sstevel@tonic-gate 	 * process mech=
748*7c478bd9Sstevel@tonic-gate 	 */
749*7c478bd9Sstevel@tonic-gate 	if (prov->cp_type == METASLOT) {
750*7c478bd9Sstevel@tonic-gate 		if ((argc > 3) &&
751*7c478bd9Sstevel@tonic-gate 		    (rc = process_metaslot_operands(argc, argv,
752*7c478bd9Sstevel@tonic-gate 		    NULL, NULL, NULL, &auto_key_migrate_flag)) != SUCCESS) {
753*7c478bd9Sstevel@tonic-gate 			usage();
754*7c478bd9Sstevel@tonic-gate 			return (rc);
755*7c478bd9Sstevel@tonic-gate 		}
756*7c478bd9Sstevel@tonic-gate 	} else if (!allflag && !rndflag &&
757*7c478bd9Sstevel@tonic-gate 		(rc = process_mech_operands(argc, argv, B_FALSE)) != SUCCESS) {
758*7c478bd9Sstevel@tonic-gate 			return (rc);
759*7c478bd9Sstevel@tonic-gate 	}
760*7c478bd9Sstevel@tonic-gate 
761*7c478bd9Sstevel@tonic-gate 	switch (prov->cp_type) {
762*7c478bd9Sstevel@tonic-gate 	case METASLOT:
763*7c478bd9Sstevel@tonic-gate 		rc = disable_metaslot(mecharglist, allflag,
764*7c478bd9Sstevel@tonic-gate 		    auto_key_migrate_flag);
765*7c478bd9Sstevel@tonic-gate 		break;
766*7c478bd9Sstevel@tonic-gate 	case PROV_UEF_LIB:
767*7c478bd9Sstevel@tonic-gate 		rc = disable_uef_lib(prov->cp_name, rndflag, allflag,
768*7c478bd9Sstevel@tonic-gate 		    mecharglist);
769*7c478bd9Sstevel@tonic-gate 		break;
770*7c478bd9Sstevel@tonic-gate 	case PROV_KEF_SOFT:
771*7c478bd9Sstevel@tonic-gate 		if (rndflag && !allflag) {
772*7c478bd9Sstevel@tonic-gate 			if ((mecharglist = create_mech(RANDOM)) == NULL) {
773*7c478bd9Sstevel@tonic-gate 				rc = FAILURE;
774*7c478bd9Sstevel@tonic-gate 				break;
775*7c478bd9Sstevel@tonic-gate 			}
776*7c478bd9Sstevel@tonic-gate 		}
777*7c478bd9Sstevel@tonic-gate 		if (getzoneid() == GLOBAL_ZONEID) {
778*7c478bd9Sstevel@tonic-gate 			rc = disable_kef_software(prov->cp_name, rndflag,
779*7c478bd9Sstevel@tonic-gate 			    allflag, mecharglist);
780*7c478bd9Sstevel@tonic-gate 		} else {
781*7c478bd9Sstevel@tonic-gate 			/*
782*7c478bd9Sstevel@tonic-gate 			 * TRANSLATION_NOTE:
783*7c478bd9Sstevel@tonic-gate 			 * "disable" could be either a literal keyword
784*7c478bd9Sstevel@tonic-gate 			 * and hence not to be translated, or a verb and
785*7c478bd9Sstevel@tonic-gate 			 * translatable.  A choice was made to view it as
786*7c478bd9Sstevel@tonic-gate 			 * a literal keyword.  "global" is keyword and not
787*7c478bd9Sstevel@tonic-gate 			 * to be translated.
788*7c478bd9Sstevel@tonic-gate 			 */
789*7c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
790*7c478bd9Sstevel@tonic-gate 			    "providers is supported in the %2$s zone only"),
791*7c478bd9Sstevel@tonic-gate 			    "disable", "global");
792*7c478bd9Sstevel@tonic-gate 			rc = FAILURE;
793*7c478bd9Sstevel@tonic-gate 		}
794*7c478bd9Sstevel@tonic-gate 		break;
795*7c478bd9Sstevel@tonic-gate 	case PROV_KEF_HARD:
796*7c478bd9Sstevel@tonic-gate 		if (rndflag && !allflag) {
797*7c478bd9Sstevel@tonic-gate 			if ((mecharglist = create_mech(RANDOM)) == NULL) {
798*7c478bd9Sstevel@tonic-gate 				rc = FAILURE;
799*7c478bd9Sstevel@tonic-gate 				break;
800*7c478bd9Sstevel@tonic-gate 			}
801*7c478bd9Sstevel@tonic-gate 		}
802*7c478bd9Sstevel@tonic-gate 		if (getzoneid() == GLOBAL_ZONEID) {
803*7c478bd9Sstevel@tonic-gate 			rc = disable_kef_hardware(prov->cp_name, rndflag,
804*7c478bd9Sstevel@tonic-gate 			    allflag, mecharglist);
805*7c478bd9Sstevel@tonic-gate 		} else {
806*7c478bd9Sstevel@tonic-gate 			/*
807*7c478bd9Sstevel@tonic-gate 			 * TRANSLATION_NOTE:
808*7c478bd9Sstevel@tonic-gate 			 * "disable" could be either a literal keyword
809*7c478bd9Sstevel@tonic-gate 			 * and hence not to be translated, or a verb and
810*7c478bd9Sstevel@tonic-gate 			 * translatable.  A choice was made to view it as
811*7c478bd9Sstevel@tonic-gate 			 * a literal keyword.  "global" is keyword and not
812*7c478bd9Sstevel@tonic-gate 			 * to be translated.
813*7c478bd9Sstevel@tonic-gate 			 */
814*7c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
815*7c478bd9Sstevel@tonic-gate 			    "providers is supported in the %2$s zone only"),
816*7c478bd9Sstevel@tonic-gate 			    "disable", "global");
817*7c478bd9Sstevel@tonic-gate 			rc = FAILURE;
818*7c478bd9Sstevel@tonic-gate 		}
819*7c478bd9Sstevel@tonic-gate 		break;
820*7c478bd9Sstevel@tonic-gate 	default: /* should not come here */
821*7c478bd9Sstevel@tonic-gate 		rc = FAILURE;
822*7c478bd9Sstevel@tonic-gate 		break;
823*7c478bd9Sstevel@tonic-gate 	}
824*7c478bd9Sstevel@tonic-gate 
825*7c478bd9Sstevel@tonic-gate out:
826*7c478bd9Sstevel@tonic-gate 	free(prov);
827*7c478bd9Sstevel@tonic-gate 	if (mecharglist != NULL) {
828*7c478bd9Sstevel@tonic-gate 		free_mechlist(mecharglist);
829*7c478bd9Sstevel@tonic-gate 	}
830*7c478bd9Sstevel@tonic-gate 	return (rc);
831*7c478bd9Sstevel@tonic-gate }
832*7c478bd9Sstevel@tonic-gate 
833*7c478bd9Sstevel@tonic-gate 
834*7c478bd9Sstevel@tonic-gate /*
835*7c478bd9Sstevel@tonic-gate  * The top level function fo the enable subcommand.
836*7c478bd9Sstevel@tonic-gate  */
837*7c478bd9Sstevel@tonic-gate static int
838*7c478bd9Sstevel@tonic-gate do_enable(int argc, char **argv)
839*7c478bd9Sstevel@tonic-gate {
840*7c478bd9Sstevel@tonic-gate 	cryptoadm_provider_t 	*prov = NULL;
841*7c478bd9Sstevel@tonic-gate 	int	rc = SUCCESS;
842*7c478bd9Sstevel@tonic-gate 	char *alt_token = NULL, *alt_slot = NULL;
843*7c478bd9Sstevel@tonic-gate 	boolean_t use_default = B_FALSE, auto_key_migrate_flag = B_FALSE;
844*7c478bd9Sstevel@tonic-gate 
845*7c478bd9Sstevel@tonic-gate 	if ((argc < 3) || (argc > 6)) {
846*7c478bd9Sstevel@tonic-gate 		usage();
847*7c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
848*7c478bd9Sstevel@tonic-gate 	}
849*7c478bd9Sstevel@tonic-gate 
850*7c478bd9Sstevel@tonic-gate 	prov = get_provider(argc, argv);
851*7c478bd9Sstevel@tonic-gate 	if (prov == NULL) {
852*7c478bd9Sstevel@tonic-gate 		usage();
853*7c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
854*7c478bd9Sstevel@tonic-gate 	}
855*7c478bd9Sstevel@tonic-gate 	if ((prov->cp_type != METASLOT) && (argc != 4)) {
856*7c478bd9Sstevel@tonic-gate 		usage();
857*7c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
858*7c478bd9Sstevel@tonic-gate 	}
859*7c478bd9Sstevel@tonic-gate 	if (prov->cp_type == PROV_BADNAME) {
860*7c478bd9Sstevel@tonic-gate 		rc = FAILURE;
861*7c478bd9Sstevel@tonic-gate 		goto out;
862*7c478bd9Sstevel@tonic-gate 	}
863*7c478bd9Sstevel@tonic-gate 
864*7c478bd9Sstevel@tonic-gate 
865*7c478bd9Sstevel@tonic-gate 	if (prov->cp_type == METASLOT) {
866*7c478bd9Sstevel@tonic-gate 		if ((rc = process_metaslot_operands(argc, argv, &alt_token,
867*7c478bd9Sstevel@tonic-gate 		    &alt_slot, &use_default, &auto_key_migrate_flag))
868*7c478bd9Sstevel@tonic-gate 		    != SUCCESS) {
869*7c478bd9Sstevel@tonic-gate 			usage();
870*7c478bd9Sstevel@tonic-gate 			goto out;
871*7c478bd9Sstevel@tonic-gate 		}
872*7c478bd9Sstevel@tonic-gate 		if ((alt_slot || alt_token) && use_default) {
873*7c478bd9Sstevel@tonic-gate 			usage();
874*7c478bd9Sstevel@tonic-gate 			rc = FAILURE;
875*7c478bd9Sstevel@tonic-gate 			goto out;
876*7c478bd9Sstevel@tonic-gate 		}
877*7c478bd9Sstevel@tonic-gate 	} else {
878*7c478bd9Sstevel@tonic-gate 		if ((rc = process_feature_operands(argc, argv)) != SUCCESS) {
879*7c478bd9Sstevel@tonic-gate 			goto out;
880*7c478bd9Sstevel@tonic-gate 		}
881*7c478bd9Sstevel@tonic-gate 
882*7c478bd9Sstevel@tonic-gate 		/*
883*7c478bd9Sstevel@tonic-gate 		 * If allflag or rndflag has already been set there is
884*7c478bd9Sstevel@tonic-gate 		 * no reason to process mech=
885*7c478bd9Sstevel@tonic-gate 		 */
886*7c478bd9Sstevel@tonic-gate 		if (!allflag && !rndflag &&
887*7c478bd9Sstevel@tonic-gate 		    (rc = process_mech_operands(argc, argv, B_FALSE))
888*7c478bd9Sstevel@tonic-gate 		    != SUCCESS) {
889*7c478bd9Sstevel@tonic-gate 			goto out;
890*7c478bd9Sstevel@tonic-gate 		}
891*7c478bd9Sstevel@tonic-gate 	}
892*7c478bd9Sstevel@tonic-gate 
893*7c478bd9Sstevel@tonic-gate 	switch (prov->cp_type) {
894*7c478bd9Sstevel@tonic-gate 	case METASLOT:
895*7c478bd9Sstevel@tonic-gate 		rc = enable_metaslot(alt_token, alt_slot, use_default,
896*7c478bd9Sstevel@tonic-gate 		    mecharglist, allflag, auto_key_migrate_flag);
897*7c478bd9Sstevel@tonic-gate 		break;
898*7c478bd9Sstevel@tonic-gate 	case PROV_UEF_LIB:
899*7c478bd9Sstevel@tonic-gate 		rc = enable_uef_lib(prov->cp_name, rndflag, allflag,
900*7c478bd9Sstevel@tonic-gate 		    mecharglist);
901*7c478bd9Sstevel@tonic-gate 		break;
902*7c478bd9Sstevel@tonic-gate 	case PROV_KEF_SOFT:
903*7c478bd9Sstevel@tonic-gate 	case PROV_KEF_HARD:
904*7c478bd9Sstevel@tonic-gate 		if (rndflag && !allflag) {
905*7c478bd9Sstevel@tonic-gate 			if ((mecharglist = create_mech(RANDOM)) == NULL) {
906*7c478bd9Sstevel@tonic-gate 				rc = FAILURE;
907*7c478bd9Sstevel@tonic-gate 				break;
908*7c478bd9Sstevel@tonic-gate 			}
909*7c478bd9Sstevel@tonic-gate 		}
910*7c478bd9Sstevel@tonic-gate 		if (getzoneid() == GLOBAL_ZONEID) {
911*7c478bd9Sstevel@tonic-gate 			rc = enable_kef(prov->cp_name, rndflag, allflag,
912*7c478bd9Sstevel@tonic-gate 			    mecharglist);
913*7c478bd9Sstevel@tonic-gate 		} else {
914*7c478bd9Sstevel@tonic-gate 			/*
915*7c478bd9Sstevel@tonic-gate 			 * TRANSLATION_NOTE:
916*7c478bd9Sstevel@tonic-gate 			 * "enable" could be either a literal keyword
917*7c478bd9Sstevel@tonic-gate 			 * and hence not to be translated, or a verb and
918*7c478bd9Sstevel@tonic-gate 			 * translatable.  A choice was made to view it as
919*7c478bd9Sstevel@tonic-gate 			 * a literal keyword.  "global" is keyword and not
920*7c478bd9Sstevel@tonic-gate 			 * to be translated.
921*7c478bd9Sstevel@tonic-gate 			 */
922*7c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
923*7c478bd9Sstevel@tonic-gate 			    "providers is supported in the %2$s zone only"),
924*7c478bd9Sstevel@tonic-gate 			    "enable", "global");
925*7c478bd9Sstevel@tonic-gate 			rc = FAILURE;
926*7c478bd9Sstevel@tonic-gate 		}
927*7c478bd9Sstevel@tonic-gate 		break;
928*7c478bd9Sstevel@tonic-gate 	default: /* should not come here */
929*7c478bd9Sstevel@tonic-gate 		rc = FAILURE;
930*7c478bd9Sstevel@tonic-gate 		break;
931*7c478bd9Sstevel@tonic-gate 	}
932*7c478bd9Sstevel@tonic-gate out:
933*7c478bd9Sstevel@tonic-gate 	free(prov);
934*7c478bd9Sstevel@tonic-gate 	if (mecharglist != NULL) {
935*7c478bd9Sstevel@tonic-gate 		free_mechlist(mecharglist);
936*7c478bd9Sstevel@tonic-gate 	}
937*7c478bd9Sstevel@tonic-gate 	if (alt_token != NULL) {
938*7c478bd9Sstevel@tonic-gate 		free(alt_token);
939*7c478bd9Sstevel@tonic-gate 	}
940*7c478bd9Sstevel@tonic-gate 	if (alt_slot != NULL) {
941*7c478bd9Sstevel@tonic-gate 		free(alt_slot);
942*7c478bd9Sstevel@tonic-gate 	}
943*7c478bd9Sstevel@tonic-gate 	return (rc);
944*7c478bd9Sstevel@tonic-gate }
945*7c478bd9Sstevel@tonic-gate 
946*7c478bd9Sstevel@tonic-gate 
947*7c478bd9Sstevel@tonic-gate 
948*7c478bd9Sstevel@tonic-gate /*
949*7c478bd9Sstevel@tonic-gate  * The top level function fo the install subcommand.
950*7c478bd9Sstevel@tonic-gate  */
951*7c478bd9Sstevel@tonic-gate static int
952*7c478bd9Sstevel@tonic-gate do_install(int argc, char **argv)
953*7c478bd9Sstevel@tonic-gate {
954*7c478bd9Sstevel@tonic-gate 	cryptoadm_provider_t 	*prov = NULL;
955*7c478bd9Sstevel@tonic-gate 	int	rc;
956*7c478bd9Sstevel@tonic-gate 
957*7c478bd9Sstevel@tonic-gate 	if (argc < 3) {
958*7c478bd9Sstevel@tonic-gate 		usage();
959*7c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
960*7c478bd9Sstevel@tonic-gate 	}
961*7c478bd9Sstevel@tonic-gate 
962*7c478bd9Sstevel@tonic-gate 	prov = get_provider(argc, argv);
963*7c478bd9Sstevel@tonic-gate 	if (prov == NULL ||
964*7c478bd9Sstevel@tonic-gate 	    prov->cp_type == PROV_BADNAME || prov->cp_type == PROV_KEF_HARD) {
965*7c478bd9Sstevel@tonic-gate 		/*
966*7c478bd9Sstevel@tonic-gate 		 * TRANSLATION_NOTE:
967*7c478bd9Sstevel@tonic-gate 		 * "install" could be either a literal keyword and hence
968*7c478bd9Sstevel@tonic-gate 		 * not to be translated, or a verb and translatable.  A
969*7c478bd9Sstevel@tonic-gate 		 * choice was made to view it as a literal keyword.
970*7c478bd9Sstevel@tonic-gate 		 */
971*7c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
972*7c478bd9Sstevel@tonic-gate 		    gettext("bad provider name for %s."), "install");
973*7c478bd9Sstevel@tonic-gate 		rc = FAILURE;
974*7c478bd9Sstevel@tonic-gate 		goto out;
975*7c478bd9Sstevel@tonic-gate 	}
976*7c478bd9Sstevel@tonic-gate 
977*7c478bd9Sstevel@tonic-gate 	if (prov->cp_type == PROV_UEF_LIB) {
978*7c478bd9Sstevel@tonic-gate 		rc = install_uef_lib(prov->cp_name);
979*7c478bd9Sstevel@tonic-gate 		goto out;
980*7c478bd9Sstevel@tonic-gate 	}
981*7c478bd9Sstevel@tonic-gate 
982*7c478bd9Sstevel@tonic-gate 	/* It is the PROV_KEF_SOFT type now  */
983*7c478bd9Sstevel@tonic-gate 
984*7c478bd9Sstevel@tonic-gate 	/* check if there are mechanism operands */
985*7c478bd9Sstevel@tonic-gate 	if (argc < 4) {
986*7c478bd9Sstevel@tonic-gate 		/*
987*7c478bd9Sstevel@tonic-gate 		 * TRANSLATION_NOTE:
988*7c478bd9Sstevel@tonic-gate 		 * "mechanism" could be either a literal keyword and hence
989*7c478bd9Sstevel@tonic-gate 		 * not to be translated, or a descriptive word and
990*7c478bd9Sstevel@tonic-gate 		 * translatable.  A choice was made to view it as a literal
991*7c478bd9Sstevel@tonic-gate 		 * keyword.
992*7c478bd9Sstevel@tonic-gate 		 */
993*7c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
994*7c478bd9Sstevel@tonic-gate 		    gettext("need %s operands for installing a"
995*7c478bd9Sstevel@tonic-gate 		    " kernel software provider."), "mechanism");
996*7c478bd9Sstevel@tonic-gate 		rc = ERROR_USAGE;
997*7c478bd9Sstevel@tonic-gate 		goto out;
998*7c478bd9Sstevel@tonic-gate 	}
999*7c478bd9Sstevel@tonic-gate 
1000*7c478bd9Sstevel@tonic-gate 	if ((rc = process_mech_operands(argc, argv, B_FALSE)) != SUCCESS) {
1001*7c478bd9Sstevel@tonic-gate 		goto out;
1002*7c478bd9Sstevel@tonic-gate 	}
1003*7c478bd9Sstevel@tonic-gate 
1004*7c478bd9Sstevel@tonic-gate 	if (allflag == B_TRUE) {
1005*7c478bd9Sstevel@tonic-gate 		/*
1006*7c478bd9Sstevel@tonic-gate 		 * TRANSLATION_NOTE:
1007*7c478bd9Sstevel@tonic-gate 		 * "all", "mechanism", and "install" are all keywords and
1008*7c478bd9Sstevel@tonic-gate 		 * not to be translated.
1009*7c478bd9Sstevel@tonic-gate 		 */
1010*7c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
1011*7c478bd9Sstevel@tonic-gate 		    gettext("can not use the %1$s keyword for %2$s "
1012*7c478bd9Sstevel@tonic-gate 		    "in the %3$s subcommand."), "all", "mechanism", "install");
1013*7c478bd9Sstevel@tonic-gate 		rc = ERROR_USAGE;
1014*7c478bd9Sstevel@tonic-gate 		goto out;
1015*7c478bd9Sstevel@tonic-gate 	}
1016*7c478bd9Sstevel@tonic-gate 
1017*7c478bd9Sstevel@tonic-gate 	if (getzoneid() == GLOBAL_ZONEID) {
1018*7c478bd9Sstevel@tonic-gate 		rc = install_kef(prov->cp_name, mecharglist);
1019*7c478bd9Sstevel@tonic-gate 	} else {
1020*7c478bd9Sstevel@tonic-gate 		/*
1021*7c478bd9Sstevel@tonic-gate 		 * TRANSLATION_NOTE:
1022*7c478bd9Sstevel@tonic-gate 		 * "install" could be either a literal keyword and hence
1023*7c478bd9Sstevel@tonic-gate 		 * not to be translated, or a verb and translatable.  A
1024*7c478bd9Sstevel@tonic-gate 		 * choice was made to view it as a literal keyword.
1025*7c478bd9Sstevel@tonic-gate 		 * "global" is keyword and not to be translated.
1026*7c478bd9Sstevel@tonic-gate 		 */
1027*7c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("%1$s for kernel providers "
1028*7c478bd9Sstevel@tonic-gate 		    "is supported in the %2$s zone only"), "install", "global");
1029*7c478bd9Sstevel@tonic-gate 		rc = FAILURE;
1030*7c478bd9Sstevel@tonic-gate 	}
1031*7c478bd9Sstevel@tonic-gate out:
1032*7c478bd9Sstevel@tonic-gate 	free(prov);
1033*7c478bd9Sstevel@tonic-gate 	return (rc);
1034*7c478bd9Sstevel@tonic-gate }
1035*7c478bd9Sstevel@tonic-gate 
1036*7c478bd9Sstevel@tonic-gate 
1037*7c478bd9Sstevel@tonic-gate 
1038*7c478bd9Sstevel@tonic-gate /*
1039*7c478bd9Sstevel@tonic-gate  * The top level function for the uninstall subcommand.
1040*7c478bd9Sstevel@tonic-gate  */
1041*7c478bd9Sstevel@tonic-gate static int
1042*7c478bd9Sstevel@tonic-gate do_uninstall(int argc, char **argv)
1043*7c478bd9Sstevel@tonic-gate {
1044*7c478bd9Sstevel@tonic-gate 	cryptoadm_provider_t 	*prov = NULL;
1045*7c478bd9Sstevel@tonic-gate 	int	rc = SUCCESS;
1046*7c478bd9Sstevel@tonic-gate 
1047*7c478bd9Sstevel@tonic-gate 	if (argc != 3) {
1048*7c478bd9Sstevel@tonic-gate 		usage();
1049*7c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
1050*7c478bd9Sstevel@tonic-gate 	}
1051*7c478bd9Sstevel@tonic-gate 
1052*7c478bd9Sstevel@tonic-gate 	prov = get_provider(argc, argv);
1053*7c478bd9Sstevel@tonic-gate 	if (prov == NULL ||
1054*7c478bd9Sstevel@tonic-gate 	    prov->cp_type == PROV_BADNAME || prov->cp_type == PROV_KEF_HARD) {
1055*7c478bd9Sstevel@tonic-gate 		/*
1056*7c478bd9Sstevel@tonic-gate 		 * TRANSLATION_NOTE:
1057*7c478bd9Sstevel@tonic-gate 		 * "uninstall" could be either a literal keyword and hence
1058*7c478bd9Sstevel@tonic-gate 		 * not to be translated, or a verb and translatable.  A
1059*7c478bd9Sstevel@tonic-gate 		 * choice was made to view it as a literal keyword.
1060*7c478bd9Sstevel@tonic-gate 		 */
1061*7c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
1062*7c478bd9Sstevel@tonic-gate 		    gettext("bad provider name for %s."), "uninstall");
1063*7c478bd9Sstevel@tonic-gate 		free(prov);
1064*7c478bd9Sstevel@tonic-gate 		return (FAILURE);
1065*7c478bd9Sstevel@tonic-gate 	}
1066*7c478bd9Sstevel@tonic-gate 
1067*7c478bd9Sstevel@tonic-gate 	if (prov->cp_type == PROV_UEF_LIB) {
1068*7c478bd9Sstevel@tonic-gate 		rc = uninstall_uef_lib(prov->cp_name);
1069*7c478bd9Sstevel@tonic-gate 	} else if (prov->cp_type == PROV_KEF_SOFT) {
1070*7c478bd9Sstevel@tonic-gate 		if (getzoneid() == GLOBAL_ZONEID) {
1071*7c478bd9Sstevel@tonic-gate 			rc = uninstall_kef(prov->cp_name);
1072*7c478bd9Sstevel@tonic-gate 		} else {
1073*7c478bd9Sstevel@tonic-gate 			/*
1074*7c478bd9Sstevel@tonic-gate 			 * TRANSLATION_NOTE:
1075*7c478bd9Sstevel@tonic-gate 			 * "uninstall" could be either a literal keyword and
1076*7c478bd9Sstevel@tonic-gate 			 * hence not to be translated, or a verb and
1077*7c478bd9Sstevel@tonic-gate 			 * translatable.  A choice was made to view it as a
1078*7c478bd9Sstevel@tonic-gate 			 * literal keyword.  "global" is keyword and not to
1079*7c478bd9Sstevel@tonic-gate 			 * be translated.
1080*7c478bd9Sstevel@tonic-gate 			 */
1081*7c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
1082*7c478bd9Sstevel@tonic-gate 			    "providers is supported in the %2$s zone only"),
1083*7c478bd9Sstevel@tonic-gate 			    "uninstall", "global");
1084*7c478bd9Sstevel@tonic-gate 			rc = FAILURE;
1085*7c478bd9Sstevel@tonic-gate 		}
1086*7c478bd9Sstevel@tonic-gate 	}
1087*7c478bd9Sstevel@tonic-gate 
1088*7c478bd9Sstevel@tonic-gate 	free(prov);
1089*7c478bd9Sstevel@tonic-gate 	return (rc);
1090*7c478bd9Sstevel@tonic-gate }
1091*7c478bd9Sstevel@tonic-gate 
1092*7c478bd9Sstevel@tonic-gate 
1093*7c478bd9Sstevel@tonic-gate /*
1094*7c478bd9Sstevel@tonic-gate  * The top level function for the unload subcommand.
1095*7c478bd9Sstevel@tonic-gate  */
1096*7c478bd9Sstevel@tonic-gate static int
1097*7c478bd9Sstevel@tonic-gate do_unload(int argc, char **argv)
1098*7c478bd9Sstevel@tonic-gate {
1099*7c478bd9Sstevel@tonic-gate 	cryptoadm_provider_t 	*prov = NULL;
1100*7c478bd9Sstevel@tonic-gate 	entry_t	*pent;
1101*7c478bd9Sstevel@tonic-gate 	boolean_t	is_active;
1102*7c478bd9Sstevel@tonic-gate 	int rc = SUCCESS;
1103*7c478bd9Sstevel@tonic-gate 
1104*7c478bd9Sstevel@tonic-gate 	if (argc != 3) {
1105*7c478bd9Sstevel@tonic-gate 		usage();
1106*7c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
1107*7c478bd9Sstevel@tonic-gate 	}
1108*7c478bd9Sstevel@tonic-gate 
1109*7c478bd9Sstevel@tonic-gate 	/* check if it is a kernel software provider */
1110*7c478bd9Sstevel@tonic-gate 	prov = get_provider(argc, argv);
1111*7c478bd9Sstevel@tonic-gate 	if (prov == NULL) {
1112*7c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
1113*7c478bd9Sstevel@tonic-gate 		    gettext("unable to determine provider name."));
1114*7c478bd9Sstevel@tonic-gate 		goto out;
1115*7c478bd9Sstevel@tonic-gate 	}
1116*7c478bd9Sstevel@tonic-gate 	if (prov->cp_type != PROV_KEF_SOFT) {
1117*7c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
1118*7c478bd9Sstevel@tonic-gate 		    gettext("%s is not a valid kernel software provider."),
1119*7c478bd9Sstevel@tonic-gate 		    prov->cp_name);
1120*7c478bd9Sstevel@tonic-gate 		rc = FAILURE;
1121*7c478bd9Sstevel@tonic-gate 		goto out;
1122*7c478bd9Sstevel@tonic-gate 	}
1123*7c478bd9Sstevel@tonic-gate 
1124*7c478bd9Sstevel@tonic-gate 	if (getzoneid() != GLOBAL_ZONEID) {
1125*7c478bd9Sstevel@tonic-gate 		/*
1126*7c478bd9Sstevel@tonic-gate 		 * TRANSLATION_NOTE:
1127*7c478bd9Sstevel@tonic-gate 		 * "unload" could be either a literal keyword and hence
1128*7c478bd9Sstevel@tonic-gate 		 * not to be translated, or a verb and translatable.
1129*7c478bd9Sstevel@tonic-gate 		 * A choice was made to view it as a literal keyword.
1130*7c478bd9Sstevel@tonic-gate 		 * "global" is keyword and not to be translated.
1131*7c478bd9Sstevel@tonic-gate 		 */
1132*7c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("%1$s for kernel providers "
1133*7c478bd9Sstevel@tonic-gate 		    "is supported in the %2$s zone only"), "unload", "global");
1134*7c478bd9Sstevel@tonic-gate 		rc = FAILURE;
1135*7c478bd9Sstevel@tonic-gate 		goto out;
1136*7c478bd9Sstevel@tonic-gate 	}
1137*7c478bd9Sstevel@tonic-gate 
1138*7c478bd9Sstevel@tonic-gate 	/* Check if it is in the kcf.conf file first */
1139*7c478bd9Sstevel@tonic-gate 	if ((pent = getent_kef(prov->cp_name)) == NULL) {
1140*7c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
1141*7c478bd9Sstevel@tonic-gate 		    gettext("provider %s does not exist."), prov->cp_name);
1142*7c478bd9Sstevel@tonic-gate 		rc = FAILURE;
1143*7c478bd9Sstevel@tonic-gate 		goto out;
1144*7c478bd9Sstevel@tonic-gate 	}
1145*7c478bd9Sstevel@tonic-gate 	free_entry(pent);
1146*7c478bd9Sstevel@tonic-gate 
1147*7c478bd9Sstevel@tonic-gate 	/* If it is unloaded already, return  */
1148*7c478bd9Sstevel@tonic-gate 	if (check_active_for_soft(prov->cp_name, &is_active) == FAILURE) {
1149*7c478bd9Sstevel@tonic-gate 		cryptodebug("internal error");
1150*7c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
1151*7c478bd9Sstevel@tonic-gate 		    gettext("failed to unload %s."), prov->cp_name);
1152*7c478bd9Sstevel@tonic-gate 		rc = FAILURE;
1153*7c478bd9Sstevel@tonic-gate 		goto out;
1154*7c478bd9Sstevel@tonic-gate 	}
1155*7c478bd9Sstevel@tonic-gate 
1156*7c478bd9Sstevel@tonic-gate 	if (is_active == B_FALSE) { /* unloaded already */
1157*7c478bd9Sstevel@tonic-gate 		rc = SUCCESS;
1158*7c478bd9Sstevel@tonic-gate 		goto out;
1159*7c478bd9Sstevel@tonic-gate 	} else if (unload_kef_soft(prov->cp_name) == FAILURE) {
1160*7c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
1161*7c478bd9Sstevel@tonic-gate 		    gettext("failed to unload %s."), prov->cp_name);
1162*7c478bd9Sstevel@tonic-gate 		rc = FAILURE;
1163*7c478bd9Sstevel@tonic-gate 	} else {
1164*7c478bd9Sstevel@tonic-gate 		rc = SUCCESS;
1165*7c478bd9Sstevel@tonic-gate 	}
1166*7c478bd9Sstevel@tonic-gate out:
1167*7c478bd9Sstevel@tonic-gate 	free(prov);
1168*7c478bd9Sstevel@tonic-gate 	return (rc);
1169*7c478bd9Sstevel@tonic-gate }
1170*7c478bd9Sstevel@tonic-gate 
1171*7c478bd9Sstevel@tonic-gate 
1172*7c478bd9Sstevel@tonic-gate 
1173*7c478bd9Sstevel@tonic-gate /*
1174*7c478bd9Sstevel@tonic-gate  * The top level function for the refresh subcommand.
1175*7c478bd9Sstevel@tonic-gate  */
1176*7c478bd9Sstevel@tonic-gate static int
1177*7c478bd9Sstevel@tonic-gate do_refresh(int argc)
1178*7c478bd9Sstevel@tonic-gate {
1179*7c478bd9Sstevel@tonic-gate 	if (argc != 2) {
1180*7c478bd9Sstevel@tonic-gate 		usage();
1181*7c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
1182*7c478bd9Sstevel@tonic-gate 	}
1183*7c478bd9Sstevel@tonic-gate 
1184*7c478bd9Sstevel@tonic-gate 	/*
1185*7c478bd9Sstevel@tonic-gate 	 * Note:  in non-global zone, this must silently return SUCCESS
1186*7c478bd9Sstevel@tonic-gate 	 * due to integration with SMF, for "svcadm refresh cryptosvc"
1187*7c478bd9Sstevel@tonic-gate 	 */
1188*7c478bd9Sstevel@tonic-gate 	if (getzoneid() != GLOBAL_ZONEID)
1189*7c478bd9Sstevel@tonic-gate 		return (SUCCESS);
1190*7c478bd9Sstevel@tonic-gate 
1191*7c478bd9Sstevel@tonic-gate 	return (refresh());
1192*7c478bd9Sstevel@tonic-gate }
1193*7c478bd9Sstevel@tonic-gate 
1194*7c478bd9Sstevel@tonic-gate 
1195*7c478bd9Sstevel@tonic-gate /*
1196*7c478bd9Sstevel@tonic-gate  * The top level function for the start subcommand.
1197*7c478bd9Sstevel@tonic-gate  */
1198*7c478bd9Sstevel@tonic-gate static int
1199*7c478bd9Sstevel@tonic-gate do_start(int argc)
1200*7c478bd9Sstevel@tonic-gate {
1201*7c478bd9Sstevel@tonic-gate 	int ret;
1202*7c478bd9Sstevel@tonic-gate 
1203*7c478bd9Sstevel@tonic-gate 	if (argc != 2) {
1204*7c478bd9Sstevel@tonic-gate 		usage();
1205*7c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
1206*7c478bd9Sstevel@tonic-gate 	}
1207*7c478bd9Sstevel@tonic-gate 
1208*7c478bd9Sstevel@tonic-gate 	ret = do_refresh(argc);
1209*7c478bd9Sstevel@tonic-gate 	if (ret != SUCCESS)
1210*7c478bd9Sstevel@tonic-gate 		return (ret);
1211*7c478bd9Sstevel@tonic-gate 
1212*7c478bd9Sstevel@tonic-gate 	return (start_daemon());
1213*7c478bd9Sstevel@tonic-gate }
1214*7c478bd9Sstevel@tonic-gate 
1215*7c478bd9Sstevel@tonic-gate /*
1216*7c478bd9Sstevel@tonic-gate  * The top level function for the stop subcommand.
1217*7c478bd9Sstevel@tonic-gate  */
1218*7c478bd9Sstevel@tonic-gate static int
1219*7c478bd9Sstevel@tonic-gate do_stop(int argc)
1220*7c478bd9Sstevel@tonic-gate {
1221*7c478bd9Sstevel@tonic-gate 	if (argc != 2) {
1222*7c478bd9Sstevel@tonic-gate 		usage();
1223*7c478bd9Sstevel@tonic-gate 		return (ERROR_USAGE);
1224*7c478bd9Sstevel@tonic-gate 	}
1225*7c478bd9Sstevel@tonic-gate 
1226*7c478bd9Sstevel@tonic-gate 	return (stop_daemon());
1227*7c478bd9Sstevel@tonic-gate }
1228*7c478bd9Sstevel@tonic-gate 
1229*7c478bd9Sstevel@tonic-gate 
1230*7c478bd9Sstevel@tonic-gate 
1231*7c478bd9Sstevel@tonic-gate /*
1232*7c478bd9Sstevel@tonic-gate  * List all the providers.
1233*7c478bd9Sstevel@tonic-gate  */
1234*7c478bd9Sstevel@tonic-gate static int
1235*7c478bd9Sstevel@tonic-gate list_simple_for_all(boolean_t verbose)
1236*7c478bd9Sstevel@tonic-gate {
1237*7c478bd9Sstevel@tonic-gate 	uentrylist_t	*pliblist;
1238*7c478bd9Sstevel@tonic-gate 	uentrylist_t	*plibptr;
1239*7c478bd9Sstevel@tonic-gate 	entrylist_t	*pdevlist_conf;
1240*7c478bd9Sstevel@tonic-gate 	entrylist_t	*psoftlist_conf;
1241*7c478bd9Sstevel@tonic-gate 	entrylist_t	*pdevlist_zone;
1242*7c478bd9Sstevel@tonic-gate 	entrylist_t	*psoftlist_zone;
1243*7c478bd9Sstevel@tonic-gate 	entrylist_t	*ptr;
1244*7c478bd9Sstevel@tonic-gate 	crypto_get_dev_list_t	*pdevlist_kernel = NULL;
1245*7c478bd9Sstevel@tonic-gate 	boolean_t	is_active;
1246*7c478bd9Sstevel@tonic-gate 	int	ru = SUCCESS;
1247*7c478bd9Sstevel@tonic-gate 	int	rs = SUCCESS;
1248*7c478bd9Sstevel@tonic-gate 	int	rd = SUCCESS;
1249*7c478bd9Sstevel@tonic-gate 	int	i;
1250*7c478bd9Sstevel@tonic-gate 
1251*7c478bd9Sstevel@tonic-gate 	/* get user-level providers */
1252*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\nUser-level providers:\n"));
1253*7c478bd9Sstevel@tonic-gate 	if (get_pkcs11conf_info(&pliblist) != SUCCESS) {
1254*7c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext(
1255*7c478bd9Sstevel@tonic-gate 		    "failed to retrieve the list of user-level providers."));
1256*7c478bd9Sstevel@tonic-gate 		ru = FAILURE;
1257*7c478bd9Sstevel@tonic-gate 	}
1258*7c478bd9Sstevel@tonic-gate 	plibptr = pliblist;
1259*7c478bd9Sstevel@tonic-gate 	while (plibptr != NULL) {
1260*7c478bd9Sstevel@tonic-gate 		if (strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) {
1261*7c478bd9Sstevel@tonic-gate 			(void) printf(gettext("Provider: %s\n"),
1262*7c478bd9Sstevel@tonic-gate 			    plibptr->puent->name);
1263*7c478bd9Sstevel@tonic-gate 			if (verbose) {
1264*7c478bd9Sstevel@tonic-gate 				(void) list_mechlist_for_lib(
1265*7c478bd9Sstevel@tonic-gate 				    plibptr->puent->name, mecharglist, NULL,
1266*7c478bd9Sstevel@tonic-gate 				    B_FALSE, verbose, B_FALSE);
1267*7c478bd9Sstevel@tonic-gate 				(void) printf("\n");
1268*7c478bd9Sstevel@tonic-gate 			}
1269*7c478bd9Sstevel@tonic-gate 		}
1270*7c478bd9Sstevel@tonic-gate 		plibptr = plibptr->next;
1271*7c478bd9Sstevel@tonic-gate 	}
1272*7c478bd9Sstevel@tonic-gate 	free_uentrylist(pliblist);
1273*7c478bd9Sstevel@tonic-gate 
1274*7c478bd9Sstevel@tonic-gate 	/* get kernel software providers */
1275*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\nKernel software providers:\n"));
1276*7c478bd9Sstevel@tonic-gate 
1277*7c478bd9Sstevel@tonic-gate 	if (getzoneid() == GLOBAL_ZONEID) {
1278*7c478bd9Sstevel@tonic-gate 		/* use kcf.conf for kernel software providers in global zone */
1279*7c478bd9Sstevel@tonic-gate 		pdevlist_conf = NULL;
1280*7c478bd9Sstevel@tonic-gate 		psoftlist_conf = NULL;
1281*7c478bd9Sstevel@tonic-gate 
1282*7c478bd9Sstevel@tonic-gate 		if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) !=
1283*7c478bd9Sstevel@tonic-gate 		    SUCCESS) {
1284*7c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR,
1285*7c478bd9Sstevel@tonic-gate 			    gettext("failed to retrieve the "
1286*7c478bd9Sstevel@tonic-gate 			    "list of kernel software providers.\n"));
1287*7c478bd9Sstevel@tonic-gate 			rs = FAILURE;
1288*7c478bd9Sstevel@tonic-gate 		}
1289*7c478bd9Sstevel@tonic-gate 
1290*7c478bd9Sstevel@tonic-gate 		ptr = psoftlist_conf;
1291*7c478bd9Sstevel@tonic-gate 		while (ptr != NULL) {
1292*7c478bd9Sstevel@tonic-gate 			if (check_active_for_soft(ptr->pent->name, &is_active)
1293*7c478bd9Sstevel@tonic-gate 			    == FAILURE) {
1294*7c478bd9Sstevel@tonic-gate 				rs = FAILURE;
1295*7c478bd9Sstevel@tonic-gate 				cryptoerror(LOG_STDERR, gettext("failed to "
1296*7c478bd9Sstevel@tonic-gate 				    "get the state of a kernel software "
1297*7c478bd9Sstevel@tonic-gate 				    "providers.\n"));
1298*7c478bd9Sstevel@tonic-gate 				break;
1299*7c478bd9Sstevel@tonic-gate 			}
1300*7c478bd9Sstevel@tonic-gate 
1301*7c478bd9Sstevel@tonic-gate 			(void) printf("\t%s", ptr->pent->name);
1302*7c478bd9Sstevel@tonic-gate 			if (is_active == B_FALSE) {
1303*7c478bd9Sstevel@tonic-gate 				(void) printf(gettext(" (inactive)\n"));
1304*7c478bd9Sstevel@tonic-gate 			} else {
1305*7c478bd9Sstevel@tonic-gate 				(void) printf("\n");
1306*7c478bd9Sstevel@tonic-gate 			}
1307*7c478bd9Sstevel@tonic-gate 			ptr = ptr->next;
1308*7c478bd9Sstevel@tonic-gate 		}
1309*7c478bd9Sstevel@tonic-gate 
1310*7c478bd9Sstevel@tonic-gate 		free_entrylist(pdevlist_conf);
1311*7c478bd9Sstevel@tonic-gate 		free_entrylist(psoftlist_conf);
1312*7c478bd9Sstevel@tonic-gate 	} else {
1313*7c478bd9Sstevel@tonic-gate 		/* kcf.conf not there in non-global zone, use /dev/cryptoadm */
1314*7c478bd9Sstevel@tonic-gate 		pdevlist_zone = NULL;
1315*7c478bd9Sstevel@tonic-gate 		psoftlist_zone = NULL;
1316*7c478bd9Sstevel@tonic-gate 
1317*7c478bd9Sstevel@tonic-gate 		if (get_admindev_info(&pdevlist_zone, &psoftlist_zone) !=
1318*7c478bd9Sstevel@tonic-gate 		    SUCCESS) {
1319*7c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR,
1320*7c478bd9Sstevel@tonic-gate 			    gettext("failed to retrieve the "
1321*7c478bd9Sstevel@tonic-gate 			    "list of kernel software providers.\n"));
1322*7c478bd9Sstevel@tonic-gate 			rs = FAILURE;
1323*7c478bd9Sstevel@tonic-gate 		}
1324*7c478bd9Sstevel@tonic-gate 
1325*7c478bd9Sstevel@tonic-gate 		ptr = psoftlist_zone;
1326*7c478bd9Sstevel@tonic-gate 		while (ptr != NULL) {
1327*7c478bd9Sstevel@tonic-gate 			(void) printf("\t%s\n", ptr->pent->name);
1328*7c478bd9Sstevel@tonic-gate 			ptr = ptr->next;
1329*7c478bd9Sstevel@tonic-gate 		}
1330*7c478bd9Sstevel@tonic-gate 
1331*7c478bd9Sstevel@tonic-gate 		free_entrylist(pdevlist_zone);
1332*7c478bd9Sstevel@tonic-gate 		free_entrylist(psoftlist_zone);
1333*7c478bd9Sstevel@tonic-gate 	}
1334*7c478bd9Sstevel@tonic-gate 
1335*7c478bd9Sstevel@tonic-gate 	/* get kernel hardware providers */
1336*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\nKernel hardware providers:\n"));
1337*7c478bd9Sstevel@tonic-gate 	if (get_dev_list(&pdevlist_kernel) == FAILURE) {
1338*7c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1339*7c478bd9Sstevel@tonic-gate 		    "the list of kernel hardware providers.\n"));
1340*7c478bd9Sstevel@tonic-gate 		rd = FAILURE;
1341*7c478bd9Sstevel@tonic-gate 	} else {
1342*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) {
1343*7c478bd9Sstevel@tonic-gate 			(void) printf("\t%s/%d\n",
1344*7c478bd9Sstevel@tonic-gate 			    pdevlist_kernel->dl_devs[i].le_dev_name,
1345*7c478bd9Sstevel@tonic-gate 			    pdevlist_kernel->dl_devs[i].le_dev_instance);
1346*7c478bd9Sstevel@tonic-gate 		}
1347*7c478bd9Sstevel@tonic-gate 	}
1348*7c478bd9Sstevel@tonic-gate 	free(pdevlist_kernel);
1349*7c478bd9Sstevel@tonic-gate 
1350*7c478bd9Sstevel@tonic-gate 	if (ru == FAILURE || rs == FAILURE || rd == FAILURE) {
1351*7c478bd9Sstevel@tonic-gate 		return (FAILURE);
1352*7c478bd9Sstevel@tonic-gate 	} else {
1353*7c478bd9Sstevel@tonic-gate 		return (SUCCESS);
1354*7c478bd9Sstevel@tonic-gate 	}
1355*7c478bd9Sstevel@tonic-gate }
1356*7c478bd9Sstevel@tonic-gate 
1357*7c478bd9Sstevel@tonic-gate 
1358*7c478bd9Sstevel@tonic-gate 
1359*7c478bd9Sstevel@tonic-gate /*
1360*7c478bd9Sstevel@tonic-gate  * List all the providers. And for each provider, list the mechanism list.
1361*7c478bd9Sstevel@tonic-gate  */
1362*7c478bd9Sstevel@tonic-gate static int
1363*7c478bd9Sstevel@tonic-gate list_mechlist_for_all(boolean_t verbose)
1364*7c478bd9Sstevel@tonic-gate {
1365*7c478bd9Sstevel@tonic-gate 	crypto_get_dev_list_t	*pdevlist_kernel;
1366*7c478bd9Sstevel@tonic-gate 	uentrylist_t	*pliblist;
1367*7c478bd9Sstevel@tonic-gate 	uentrylist_t	*plibptr;
1368*7c478bd9Sstevel@tonic-gate 	entrylist_t	*pdevlist_conf;
1369*7c478bd9Sstevel@tonic-gate 	entrylist_t	*psoftlist_conf;
1370*7c478bd9Sstevel@tonic-gate 	entrylist_t	*pdevlist_zone;
1371*7c478bd9Sstevel@tonic-gate 	entrylist_t	*psoftlist_zone;
1372*7c478bd9Sstevel@tonic-gate 	entrylist_t	*ptr;
1373*7c478bd9Sstevel@tonic-gate 	mechlist_t	*pmechlist;
1374*7c478bd9Sstevel@tonic-gate 	boolean_t	is_active;
1375*7c478bd9Sstevel@tonic-gate 	char	provname[MAXNAMELEN];
1376*7c478bd9Sstevel@tonic-gate 	char	devname[MAXNAMELEN];
1377*7c478bd9Sstevel@tonic-gate 	int 	inst_num;
1378*7c478bd9Sstevel@tonic-gate 	int	count;
1379*7c478bd9Sstevel@tonic-gate 	int	i;
1380*7c478bd9Sstevel@tonic-gate 	int	rv;
1381*7c478bd9Sstevel@tonic-gate 	int	rc = SUCCESS;
1382*7c478bd9Sstevel@tonic-gate 
1383*7c478bd9Sstevel@tonic-gate 	/* get user-level providers */
1384*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\nUser-level providers:\n"));
1385*7c478bd9Sstevel@tonic-gate 	/*
1386*7c478bd9Sstevel@tonic-gate 	 * TRANSLATION_NOTE:
1387*7c478bd9Sstevel@tonic-gate 	 * Strictly for appearance's sake, this line should be as long as
1388*7c478bd9Sstevel@tonic-gate 	 * the length of the translated text above.
1389*7c478bd9Sstevel@tonic-gate 	 */
1390*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("=====================\n"));
1391*7c478bd9Sstevel@tonic-gate 	if (get_pkcs11conf_info(&pliblist) != SUCCESS) {
1392*7c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1393*7c478bd9Sstevel@tonic-gate 		    "the list of user-level providers.\n"));
1394*7c478bd9Sstevel@tonic-gate 		rc = FAILURE;
1395*7c478bd9Sstevel@tonic-gate 	}
1396*7c478bd9Sstevel@tonic-gate 
1397*7c478bd9Sstevel@tonic-gate 	plibptr = pliblist;
1398*7c478bd9Sstevel@tonic-gate 	while (plibptr != NULL) {
1399*7c478bd9Sstevel@tonic-gate 		/* skip metaslot entry */
1400*7c478bd9Sstevel@tonic-gate 		if (strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) {
1401*7c478bd9Sstevel@tonic-gate 			(void) printf(gettext("\nProvider: %s\n"),
1402*7c478bd9Sstevel@tonic-gate 			    plibptr->puent->name);
1403*7c478bd9Sstevel@tonic-gate 			rv = list_mechlist_for_lib(plibptr->puent->name,
1404*7c478bd9Sstevel@tonic-gate 			    mecharglist, NULL, B_FALSE, verbose, B_TRUE);
1405*7c478bd9Sstevel@tonic-gate 			if (rv == FAILURE) {
1406*7c478bd9Sstevel@tonic-gate 				rc = FAILURE;
1407*7c478bd9Sstevel@tonic-gate 			}
1408*7c478bd9Sstevel@tonic-gate 		}
1409*7c478bd9Sstevel@tonic-gate 		plibptr = plibptr->next;
1410*7c478bd9Sstevel@tonic-gate 	}
1411*7c478bd9Sstevel@tonic-gate 	free_uentrylist(pliblist);
1412*7c478bd9Sstevel@tonic-gate 
1413*7c478bd9Sstevel@tonic-gate 	/* get kernel software providers */
1414*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\nKernel software providers:\n"));
1415*7c478bd9Sstevel@tonic-gate 	/*
1416*7c478bd9Sstevel@tonic-gate 	 * TRANSLATION_NOTE:
1417*7c478bd9Sstevel@tonic-gate 	 * Strictly for appearance's sake, this line should be as long as
1418*7c478bd9Sstevel@tonic-gate 	 * the length of the translated text above.
1419*7c478bd9Sstevel@tonic-gate 	 */
1420*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("==========================\n"));
1421*7c478bd9Sstevel@tonic-gate 	if (getzoneid() == GLOBAL_ZONEID) {
1422*7c478bd9Sstevel@tonic-gate 		/* use kcf.conf for kernel software providers in global zone */
1423*7c478bd9Sstevel@tonic-gate 		pdevlist_conf = NULL;
1424*7c478bd9Sstevel@tonic-gate 		psoftlist_conf = NULL;
1425*7c478bd9Sstevel@tonic-gate 
1426*7c478bd9Sstevel@tonic-gate 		if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) !=
1427*7c478bd9Sstevel@tonic-gate 		    SUCCESS) {
1428*7c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1429*7c478bd9Sstevel@tonic-gate 			    "the list of kernel software providers.\n"));
1430*7c478bd9Sstevel@tonic-gate 			rc = FAILURE;
1431*7c478bd9Sstevel@tonic-gate 		}
1432*7c478bd9Sstevel@tonic-gate 
1433*7c478bd9Sstevel@tonic-gate 		ptr = psoftlist_conf;
1434*7c478bd9Sstevel@tonic-gate 		while (ptr != NULL) {
1435*7c478bd9Sstevel@tonic-gate 			if (check_active_for_soft(ptr->pent->name, &is_active)
1436*7c478bd9Sstevel@tonic-gate 			    == SUCCESS) {
1437*7c478bd9Sstevel@tonic-gate 				if (is_active) {
1438*7c478bd9Sstevel@tonic-gate 					rv = list_mechlist_for_soft(
1439*7c478bd9Sstevel@tonic-gate 					    ptr->pent->name);
1440*7c478bd9Sstevel@tonic-gate 					if (rv == FAILURE) {
1441*7c478bd9Sstevel@tonic-gate 						rc = FAILURE;
1442*7c478bd9Sstevel@tonic-gate 					}
1443*7c478bd9Sstevel@tonic-gate 				} else {
1444*7c478bd9Sstevel@tonic-gate 					(void) printf(gettext(
1445*7c478bd9Sstevel@tonic-gate 					    "%s: (inactive)\n"),
1446*7c478bd9Sstevel@tonic-gate 					    ptr->pent->name);
1447*7c478bd9Sstevel@tonic-gate 				}
1448*7c478bd9Sstevel@tonic-gate 			} else {
1449*7c478bd9Sstevel@tonic-gate 				/* should not happen */
1450*7c478bd9Sstevel@tonic-gate 				(void) printf(gettext(
1451*7c478bd9Sstevel@tonic-gate 				    "%s: failed to get the mechanism list.\n"),
1452*7c478bd9Sstevel@tonic-gate 				    ptr->pent->name);
1453*7c478bd9Sstevel@tonic-gate 				rc = FAILURE;
1454*7c478bd9Sstevel@tonic-gate 			}
1455*7c478bd9Sstevel@tonic-gate 			ptr = ptr->next;
1456*7c478bd9Sstevel@tonic-gate 		}
1457*7c478bd9Sstevel@tonic-gate 
1458*7c478bd9Sstevel@tonic-gate 		free_entrylist(pdevlist_conf);
1459*7c478bd9Sstevel@tonic-gate 		free_entrylist(psoftlist_conf);
1460*7c478bd9Sstevel@tonic-gate 	} else {
1461*7c478bd9Sstevel@tonic-gate 		/* kcf.conf not there in non-global zone, use /dev/cryptoadm */
1462*7c478bd9Sstevel@tonic-gate 		pdevlist_zone = NULL;
1463*7c478bd9Sstevel@tonic-gate 		psoftlist_zone = NULL;
1464*7c478bd9Sstevel@tonic-gate 
1465*7c478bd9Sstevel@tonic-gate 		if (get_admindev_info(&pdevlist_zone, &psoftlist_zone) !=
1466*7c478bd9Sstevel@tonic-gate 		    SUCCESS) {
1467*7c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1468*7c478bd9Sstevel@tonic-gate 			    "the list of kernel software providers.\n"));
1469*7c478bd9Sstevel@tonic-gate 			rc = FAILURE;
1470*7c478bd9Sstevel@tonic-gate 		}
1471*7c478bd9Sstevel@tonic-gate 
1472*7c478bd9Sstevel@tonic-gate 		ptr = psoftlist_zone;
1473*7c478bd9Sstevel@tonic-gate 		while (ptr != NULL) {
1474*7c478bd9Sstevel@tonic-gate 			rv = list_mechlist_for_soft(ptr->pent->name);
1475*7c478bd9Sstevel@tonic-gate 			if (rv == FAILURE) {
1476*7c478bd9Sstevel@tonic-gate 				(void) printf(gettext(
1477*7c478bd9Sstevel@tonic-gate 				    "%s: failed to get the mechanism list.\n"),
1478*7c478bd9Sstevel@tonic-gate 				    ptr->pent->name);
1479*7c478bd9Sstevel@tonic-gate 				rc = FAILURE;
1480*7c478bd9Sstevel@tonic-gate 			}
1481*7c478bd9Sstevel@tonic-gate 			ptr = ptr->next;
1482*7c478bd9Sstevel@tonic-gate 		}
1483*7c478bd9Sstevel@tonic-gate 
1484*7c478bd9Sstevel@tonic-gate 		free_entrylist(pdevlist_zone);
1485*7c478bd9Sstevel@tonic-gate 		free_entrylist(psoftlist_zone);
1486*7c478bd9Sstevel@tonic-gate 	}
1487*7c478bd9Sstevel@tonic-gate 
1488*7c478bd9Sstevel@tonic-gate 	/* Get kernel hardware providers and their mechanism lists */
1489*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\nKernel hardware providers:\n"));
1490*7c478bd9Sstevel@tonic-gate 	/*
1491*7c478bd9Sstevel@tonic-gate 	 * TRANSLATION_NOTE:
1492*7c478bd9Sstevel@tonic-gate 	 * Strictly for appearance's sake, this line should be as long as
1493*7c478bd9Sstevel@tonic-gate 	 * the length of the translated text above.
1494*7c478bd9Sstevel@tonic-gate 	 */
1495*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("==========================\n"));
1496*7c478bd9Sstevel@tonic-gate 	if (get_dev_list(&pdevlist_kernel) != SUCCESS) {
1497*7c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1498*7c478bd9Sstevel@tonic-gate 		    "the list of hardware providers.\n"));
1499*7c478bd9Sstevel@tonic-gate 		return (FAILURE);
1500*7c478bd9Sstevel@tonic-gate 	}
1501*7c478bd9Sstevel@tonic-gate 
1502*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) {
1503*7c478bd9Sstevel@tonic-gate 		(void) strlcpy(devname,
1504*7c478bd9Sstevel@tonic-gate 		    pdevlist_kernel->dl_devs[i].le_dev_name, MAXNAMELEN);
1505*7c478bd9Sstevel@tonic-gate 		inst_num = pdevlist_kernel->dl_devs[i].le_dev_instance;
1506*7c478bd9Sstevel@tonic-gate 		count = pdevlist_kernel->dl_devs[i].le_mechanism_count;
1507*7c478bd9Sstevel@tonic-gate 		(void) snprintf(provname, sizeof (provname), "%s/%d", devname,
1508*7c478bd9Sstevel@tonic-gate 		    inst_num);
1509*7c478bd9Sstevel@tonic-gate 		if (get_dev_info(devname, inst_num, count, &pmechlist) ==
1510*7c478bd9Sstevel@tonic-gate 		    SUCCESS) {
1511*7c478bd9Sstevel@tonic-gate 			(void) filter_mechlist(&pmechlist, RANDOM);
1512*7c478bd9Sstevel@tonic-gate 			print_mechlist(provname, pmechlist);
1513*7c478bd9Sstevel@tonic-gate 			free_mechlist(pmechlist);
1514*7c478bd9Sstevel@tonic-gate 		} else {
1515*7c478bd9Sstevel@tonic-gate 			(void) printf(gettext("%s: failed to get the mechanism"
1516*7c478bd9Sstevel@tonic-gate 			    " list.\n"), provname);
1517*7c478bd9Sstevel@tonic-gate 			rc = FAILURE;
1518*7c478bd9Sstevel@tonic-gate 		}
1519*7c478bd9Sstevel@tonic-gate 	}
1520*7c478bd9Sstevel@tonic-gate 	free(pdevlist_kernel);
1521*7c478bd9Sstevel@tonic-gate 	return (rc);
1522*7c478bd9Sstevel@tonic-gate }
1523*7c478bd9Sstevel@tonic-gate 
1524*7c478bd9Sstevel@tonic-gate 
1525*7c478bd9Sstevel@tonic-gate /*
1526*7c478bd9Sstevel@tonic-gate  * List all the providers. And for each provider, list the policy information.
1527*7c478bd9Sstevel@tonic-gate  */
1528*7c478bd9Sstevel@tonic-gate static int
1529*7c478bd9Sstevel@tonic-gate list_policy_for_all(void)
1530*7c478bd9Sstevel@tonic-gate {
1531*7c478bd9Sstevel@tonic-gate 	crypto_get_dev_list_t	*pdevlist_kernel;
1532*7c478bd9Sstevel@tonic-gate 	uentrylist_t	*pliblist;
1533*7c478bd9Sstevel@tonic-gate 	uentrylist_t	*plibptr;
1534*7c478bd9Sstevel@tonic-gate 	entrylist_t	*pdevlist_conf;
1535*7c478bd9Sstevel@tonic-gate 	entrylist_t	*psoftlist_conf;
1536*7c478bd9Sstevel@tonic-gate 	entrylist_t	*ptr;
1537*7c478bd9Sstevel@tonic-gate 	entrylist_t	*phead;
1538*7c478bd9Sstevel@tonic-gate 	boolean_t	found;
1539*7c478bd9Sstevel@tonic-gate 	char	provname[MAXNAMELEN];
1540*7c478bd9Sstevel@tonic-gate 	int	i;
1541*7c478bd9Sstevel@tonic-gate 	int	rc = SUCCESS;
1542*7c478bd9Sstevel@tonic-gate 
1543*7c478bd9Sstevel@tonic-gate 	/* Get user-level providers */
1544*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\nUser-level providers:\n"));
1545*7c478bd9Sstevel@tonic-gate 	/*
1546*7c478bd9Sstevel@tonic-gate 	 * TRANSLATION_NOTE:
1547*7c478bd9Sstevel@tonic-gate 	 * Strictly for appearance's sake, this line should be as long as
1548*7c478bd9Sstevel@tonic-gate 	 * the length of the translated text above.
1549*7c478bd9Sstevel@tonic-gate 	 */
1550*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("=====================\n"));
1551*7c478bd9Sstevel@tonic-gate 	if (get_pkcs11conf_info(&pliblist) == FAILURE) {
1552*7c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1553*7c478bd9Sstevel@tonic-gate 		    "the list of user-level providers.\n"));
1554*7c478bd9Sstevel@tonic-gate 	} else {
1555*7c478bd9Sstevel@tonic-gate 		plibptr = pliblist;
1556*7c478bd9Sstevel@tonic-gate 		while (plibptr != NULL) {
1557*7c478bd9Sstevel@tonic-gate 			/* skip metaslot entry */
1558*7c478bd9Sstevel@tonic-gate 			if (strcmp(plibptr->puent->name,
1559*7c478bd9Sstevel@tonic-gate 			    METASLOT_KEYWORD) != 0) {
1560*7c478bd9Sstevel@tonic-gate 				if (print_uef_policy(plibptr->puent)
1561*7c478bd9Sstevel@tonic-gate 				    == FAILURE) {
1562*7c478bd9Sstevel@tonic-gate 					rc = FAILURE;
1563*7c478bd9Sstevel@tonic-gate 				}
1564*7c478bd9Sstevel@tonic-gate 			}
1565*7c478bd9Sstevel@tonic-gate 			plibptr = plibptr->next;
1566*7c478bd9Sstevel@tonic-gate 		}
1567*7c478bd9Sstevel@tonic-gate 		free_uentrylist(pliblist);
1568*7c478bd9Sstevel@tonic-gate 	}
1569*7c478bd9Sstevel@tonic-gate 
1570*7c478bd9Sstevel@tonic-gate 	/* kernel software providers */
1571*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\nKernel software providers:\n"));
1572*7c478bd9Sstevel@tonic-gate 	/*
1573*7c478bd9Sstevel@tonic-gate 	 * TRANSLATION_NOTE:
1574*7c478bd9Sstevel@tonic-gate 	 * Strictly for appearance's sake, this line should be as long as
1575*7c478bd9Sstevel@tonic-gate 	 * the length of the translated text above.
1576*7c478bd9Sstevel@tonic-gate 	 */
1577*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("==========================\n"));
1578*7c478bd9Sstevel@tonic-gate 
1579*7c478bd9Sstevel@tonic-gate 	/* Get all entries from the kcf.conf file */
1580*7c478bd9Sstevel@tonic-gate 	pdevlist_conf = NULL;
1581*7c478bd9Sstevel@tonic-gate 	if (getzoneid() == GLOBAL_ZONEID) {
1582*7c478bd9Sstevel@tonic-gate 		/* use kcf.conf for kernel software providers in global zone */
1583*7c478bd9Sstevel@tonic-gate 		psoftlist_conf = NULL;
1584*7c478bd9Sstevel@tonic-gate 
1585*7c478bd9Sstevel@tonic-gate 		if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) ==
1586*7c478bd9Sstevel@tonic-gate 		    FAILURE) {
1587*7c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR, gettext(
1588*7c478bd9Sstevel@tonic-gate 			    "failed to retrieve the list of kernel "
1589*7c478bd9Sstevel@tonic-gate 			    "providers.\n"));
1590*7c478bd9Sstevel@tonic-gate 			return (FAILURE);
1591*7c478bd9Sstevel@tonic-gate 		}
1592*7c478bd9Sstevel@tonic-gate 
1593*7c478bd9Sstevel@tonic-gate 		ptr = psoftlist_conf;
1594*7c478bd9Sstevel@tonic-gate 		while (ptr != NULL) {
1595*7c478bd9Sstevel@tonic-gate 			(void) list_policy_for_soft(ptr->pent->name);
1596*7c478bd9Sstevel@tonic-gate 			ptr = ptr->next;
1597*7c478bd9Sstevel@tonic-gate 		}
1598*7c478bd9Sstevel@tonic-gate 
1599*7c478bd9Sstevel@tonic-gate 		free_entrylist(psoftlist_conf);
1600*7c478bd9Sstevel@tonic-gate 	} else {
1601*7c478bd9Sstevel@tonic-gate 		/* kcf.conf not there in non-global zone, no policy info */
1602*7c478bd9Sstevel@tonic-gate 
1603*7c478bd9Sstevel@tonic-gate 		/*
1604*7c478bd9Sstevel@tonic-gate 		 * TRANSLATION_NOTE:
1605*7c478bd9Sstevel@tonic-gate 		 * "global" is keyword and not to be translated.
1606*7c478bd9Sstevel@tonic-gate 		 */
1607*7c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext(
1608*7c478bd9Sstevel@tonic-gate 		    "policy information for kernel software providers is "
1609*7c478bd9Sstevel@tonic-gate 		    "available in the %s zone only"), "global");
1610*7c478bd9Sstevel@tonic-gate 	}
1611*7c478bd9Sstevel@tonic-gate 
1612*7c478bd9Sstevel@tonic-gate 	/* Kernel hardware providers */
1613*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\nKernel hardware providers:\n"));
1614*7c478bd9Sstevel@tonic-gate 	/*
1615*7c478bd9Sstevel@tonic-gate 	 * TRANSLATION_NOTE:
1616*7c478bd9Sstevel@tonic-gate 	 * Strictly for appearance's sake, this line should be as long as
1617*7c478bd9Sstevel@tonic-gate 	 * the length of the translated text above.
1618*7c478bd9Sstevel@tonic-gate 	 */
1619*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("==========================\n"));
1620*7c478bd9Sstevel@tonic-gate 
1621*7c478bd9Sstevel@tonic-gate 	if (getzoneid() != GLOBAL_ZONEID) {
1622*7c478bd9Sstevel@tonic-gate 		/*
1623*7c478bd9Sstevel@tonic-gate 		 * TRANSLATION_NOTE:
1624*7c478bd9Sstevel@tonic-gate 		 * "global" is keyword and not to be translated.
1625*7c478bd9Sstevel@tonic-gate 		 */
1626*7c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext(
1627*7c478bd9Sstevel@tonic-gate 		    "policy information for kernel hardware providers is "
1628*7c478bd9Sstevel@tonic-gate 		    "available in the %s zone only"), "global");
1629*7c478bd9Sstevel@tonic-gate 		return (FAILURE);
1630*7c478bd9Sstevel@tonic-gate 	}
1631*7c478bd9Sstevel@tonic-gate 
1632*7c478bd9Sstevel@tonic-gate 	/* Get the hardware provider list from kernel */
1633*7c478bd9Sstevel@tonic-gate 	if (get_dev_list(&pdevlist_kernel) != SUCCESS) {
1634*7c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext(
1635*7c478bd9Sstevel@tonic-gate 		    "failed to retrieve the list of hardware providers.\n"));
1636*7c478bd9Sstevel@tonic-gate 		free_entrylist(pdevlist_conf);
1637*7c478bd9Sstevel@tonic-gate 		return (FAILURE);
1638*7c478bd9Sstevel@tonic-gate 	}
1639*7c478bd9Sstevel@tonic-gate 
1640*7c478bd9Sstevel@tonic-gate 	/*
1641*7c478bd9Sstevel@tonic-gate 	 * For each hardware provider from kernel, check if it has an entry
1642*7c478bd9Sstevel@tonic-gate 	 * in the config file.  If it has an entry, print out the policy from
1643*7c478bd9Sstevel@tonic-gate 	 * config file and remove the entry from the hardware provider list
1644*7c478bd9Sstevel@tonic-gate 	 * of the config file.  If it does not have an entry in the config
1645*7c478bd9Sstevel@tonic-gate 	 * file, no mechanisms of it have been disabled. But, we still call
1646*7c478bd9Sstevel@tonic-gate 	 * list_policy_for_hard() to account for the "random" feature.
1647*7c478bd9Sstevel@tonic-gate 	 */
1648*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) {
1649*7c478bd9Sstevel@tonic-gate 		(void) snprintf(provname, sizeof (provname), "%s/%d",
1650*7c478bd9Sstevel@tonic-gate 		    pdevlist_kernel->dl_devs[i].le_dev_name,
1651*7c478bd9Sstevel@tonic-gate 		    pdevlist_kernel->dl_devs[i].le_dev_instance);
1652*7c478bd9Sstevel@tonic-gate 		found = B_FALSE;
1653*7c478bd9Sstevel@tonic-gate 		phead = ptr = pdevlist_conf;
1654*7c478bd9Sstevel@tonic-gate 		while (!found && ptr) {
1655*7c478bd9Sstevel@tonic-gate 			if (strcmp(ptr->pent->name, provname) == 0) {
1656*7c478bd9Sstevel@tonic-gate 				found = B_TRUE;
1657*7c478bd9Sstevel@tonic-gate 			} else {
1658*7c478bd9Sstevel@tonic-gate 				phead = ptr;
1659*7c478bd9Sstevel@tonic-gate 				ptr = ptr->next;
1660*7c478bd9Sstevel@tonic-gate 			}
1661*7c478bd9Sstevel@tonic-gate 		}
1662*7c478bd9Sstevel@tonic-gate 
1663*7c478bd9Sstevel@tonic-gate 		if (found) {
1664*7c478bd9Sstevel@tonic-gate 			(void) list_policy_for_hard(ptr->pent->name);
1665*7c478bd9Sstevel@tonic-gate 			if (phead == ptr) {
1666*7c478bd9Sstevel@tonic-gate 				pdevlist_conf = pdevlist_conf->next;
1667*7c478bd9Sstevel@tonic-gate 			} else {
1668*7c478bd9Sstevel@tonic-gate 				phead->next = ptr->next;
1669*7c478bd9Sstevel@tonic-gate 			}
1670*7c478bd9Sstevel@tonic-gate 			free_entry(ptr->pent);
1671*7c478bd9Sstevel@tonic-gate 			free(ptr);
1672*7c478bd9Sstevel@tonic-gate 		} else {
1673*7c478bd9Sstevel@tonic-gate 			(void) list_policy_for_hard(provname);
1674*7c478bd9Sstevel@tonic-gate 		}
1675*7c478bd9Sstevel@tonic-gate 	}
1676*7c478bd9Sstevel@tonic-gate 
1677*7c478bd9Sstevel@tonic-gate 	/*
1678*7c478bd9Sstevel@tonic-gate 	 * If there are still entries left in the pdevlist_conf list from
1679*7c478bd9Sstevel@tonic-gate 	 * the config file, these providers must have been detached.
1680*7c478bd9Sstevel@tonic-gate 	 * Should print out their policy information also.
1681*7c478bd9Sstevel@tonic-gate 	 */
1682*7c478bd9Sstevel@tonic-gate 	ptr = pdevlist_conf;
1683*7c478bd9Sstevel@tonic-gate 	while (ptr != NULL) {
1684*7c478bd9Sstevel@tonic-gate 		print_kef_policy(ptr->pent, B_FALSE, B_TRUE);
1685*7c478bd9Sstevel@tonic-gate 		ptr = ptr->next;
1686*7c478bd9Sstevel@tonic-gate 	}
1687*7c478bd9Sstevel@tonic-gate 
1688*7c478bd9Sstevel@tonic-gate 	free_entrylist(pdevlist_conf);
1689*7c478bd9Sstevel@tonic-gate 	free(pdevlist_kernel);
1690*7c478bd9Sstevel@tonic-gate 
1691*7c478bd9Sstevel@tonic-gate 	return (rc);
1692*7c478bd9Sstevel@tonic-gate }
1693