dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / cmd-crypto / cryptoadm / cryptoadm.c
blob3658388d5b9fe3f23be23d753dc91104bf1386e0
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <fcntl.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <strings.h>
30 #include <unistd.h>
31 #include <locale.h>
32 #include <libgen.h>
33 #include <sys/types.h>
34 #include <zone.h>
35 #include <sys/crypto/ioctladmin.h>
36 #include <cryptoutil.h>
37 #include "cryptoadm.h"
39 #define REQ_ARG_CNT 2
41 /* subcommand index */
42 enum subcommand_index {
43 CRYPTO_LIST,
44 CRYPTO_DISABLE,
45 CRYPTO_ENABLE,
46 CRYPTO_INSTALL,
47 CRYPTO_UNINSTALL,
48 CRYPTO_UNLOAD,
49 CRYPTO_REFRESH,
50 CRYPTO_START,
51 CRYPTO_STOP,
52 CRYPTO_HELP };
55 * TRANSLATION_NOTE
56 * Command keywords are not to be translated.
58 static char *cmd_table[] = {
59 "list",
60 "disable",
61 "enable",
62 "install",
63 "uninstall",
64 "unload",
65 "refresh",
66 "start",
67 "stop",
68 "--help" };
70 /* provider type */
71 enum provider_type_index {
72 PROV_UEF_LIB,
73 PROV_KEF_SOFT,
74 PROV_KEF_HARD,
75 METASLOT,
76 PROV_BADNAME };
78 typedef struct {
79 char cp_name[MAXPATHLEN];
80 enum provider_type_index cp_type;
81 } cryptoadm_provider_t;
84 * TRANSLATION_NOTE
85 * Operand keywords are not to be translated.
87 static const char *KN_PROVIDER = "provider=";
88 static const char *KN_MECH = "mechanism=";
89 static const char *KN_ALL = "all";
90 static const char *KN_TOKEN = "token=";
91 static const char *KN_SLOT = "slot=";
92 static const char *KN_DEFAULT_KS = "default-keystore";
93 static const char *KN_AUTO_KEY_MIGRATE = "auto-key-migrate";
95 /* static variables */
96 static boolean_t allflag = B_FALSE;
97 static boolean_t rndflag = B_FALSE;
98 static mechlist_t *mecharglist = NULL;
100 /* static functions */
101 static void usage(void);
102 static int get_provider_type(char *);
103 static int process_mech_operands(int, char **, boolean_t);
104 static int do_list(int, char **);
105 static int do_disable(int, char **);
106 static int do_enable(int, char **);
107 static int do_install(int, char **);
108 static int do_uninstall(int, char **);
109 static int do_unload(int, char **);
110 static int do_refresh(int);
111 static int do_start(int);
112 static int do_stop(int);
113 static int list_simple_for_all(boolean_t);
114 static int list_mechlist_for_all(boolean_t);
115 static int list_policy_for_all(void);
118 main(int argc, char *argv[])
120 char *subcmd;
121 int cmdnum;
122 int cmd_index = 0;
123 int rc = SUCCESS;
125 (void) setlocale(LC_ALL, "");
127 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
128 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
129 #endif
130 (void) textdomain(TEXT_DOMAIN);
132 cryptodebug_init(basename(argv[0]));
134 if (argc < REQ_ARG_CNT) {
135 usage();
136 return (ERROR_USAGE);
139 /* get the subcommand index */
140 cmd_index = 0;
141 subcmd = argv[1];
142 cmdnum = sizeof (cmd_table)/sizeof (cmd_table[0]);
144 while ((cmd_index < cmdnum) &&
145 (strcmp(subcmd, cmd_table[cmd_index]) != 0)) {
146 cmd_index++;
148 if (cmd_index >= cmdnum) {
149 usage();
150 return (ERROR_USAGE);
153 /* do the subcommand */
154 switch (cmd_index) {
155 case CRYPTO_LIST:
156 rc = do_list(argc, argv);
157 break;
158 case CRYPTO_DISABLE:
159 rc = do_disable(argc, argv);
160 break;
161 case CRYPTO_ENABLE:
162 rc = do_enable(argc, argv);
163 break;
164 case CRYPTO_INSTALL:
165 rc = do_install(argc, argv);
166 break;
167 case CRYPTO_UNINSTALL:
168 rc = do_uninstall(argc, argv);
169 break;
170 case CRYPTO_UNLOAD:
171 rc = do_unload(argc, argv);
172 break;
173 case CRYPTO_REFRESH:
174 rc = do_refresh(argc);
175 break;
176 case CRYPTO_START:
177 rc = do_start(argc);
178 break;
179 case CRYPTO_STOP:
180 rc = do_stop(argc);
181 break;
182 case CRYPTO_HELP:
183 usage();
184 rc = SUCCESS;
185 break;
186 default: /* should not come here */
187 usage();
188 rc = ERROR_USAGE;
189 break;
191 return (rc);
195 static void
196 usage(void)
199 * TRANSLATION_NOTE
200 * Command usage is not to be translated. Only the word "Usage:"
201 * along with localized expressions indicating what kind of value
202 * is expected for arguments.
204 (void) fprintf(stderr, gettext("Usage:\n"));
205 (void) fprintf(stderr,
206 " cryptoadm list [-mpv] [provider=<%s> | metaslot]"
207 " [mechanism=<%s>]\n",
208 gettext("provider-name"), gettext("mechanism-list"));
209 (void) fprintf(stderr,
210 " cryptoadm disable provider=<%s>"
211 " mechanism=<%s> | random | all\n",
212 gettext("provider-name"), gettext("mechanism-list"));
213 (void) fprintf(stderr,
214 " cryptoadm disable metaslot"
215 " [auto-key-migrate] [mechanism=<%s>]\n",
216 gettext("mechanism-list"));
217 (void) fprintf(stderr,
218 " cryptoadm enable provider=<%s>"
219 " mechanism=<%s> | random | all\n",
220 gettext("provider-name"), gettext("mechanism-list"));
221 (void) fprintf(stderr,
222 " cryptoadm enable metaslot [mechanism=<%s>]"
223 " [[token=<%s>] [slot=<%s>]"
224 " | [default-keystore]] | [auto-key-migrate]\n",
225 gettext("mechanism-list"), gettext("token-label"),
226 gettext("slot-description"));
227 (void) fprintf(stderr,
228 " cryptoadm install provider=<%s>\n",
229 gettext("provider-name"));
230 (void) fprintf(stderr,
231 " cryptoadm install provider=<%s> [mechanism=<%s>]\n",
232 gettext("provider-name"), gettext("mechanism-list"));
233 (void) fprintf(stderr,
234 " cryptoadm uninstall provider=<%s>\n",
235 gettext("provider-name"));
236 (void) fprintf(stderr,
237 " cryptoadm unload provider=<%s>\n",
238 gettext("provider-name"));
239 (void) fprintf(stderr,
240 " cryptoadm refresh\n"
241 " cryptoadm start\n"
242 " cryptoadm stop\n"
243 " cryptoadm --help\n");
248 * Get the provider type. This function returns
249 * - PROV_UEF_LIB if provname contains an absolute path name
250 * - PROV_KEF_SOFT if provname is a base name only (e.g., "aes").
251 * - PROV_KEF_HARD if provname contains one slash only and the slash is not
252 * the 1st character (e.g., "mca/0").
253 * - PROV_BADNAME otherwise.
255 static int
256 get_provider_type(char *provname)
258 char *pslash1;
259 char *pslash2;
261 if (provname == NULL) {
262 return (FAILURE);
265 if (provname[0] == '/') {
266 return (PROV_UEF_LIB);
267 } else if ((pslash1 = strchr(provname, SEP_SLASH)) == NULL) {
268 /* no slash */
269 return (PROV_KEF_SOFT);
270 } else {
271 pslash2 = strrchr(provname, SEP_SLASH);
272 if (pslash1 == pslash2) {
273 return (PROV_KEF_HARD);
274 } else {
275 return (PROV_BADNAME);
281 * Get the provider structure. This function returns NULL if no valid
282 * provider= is found in argv[], otherwise a cryptoadm_provider_t is returned.
283 * If provider= is found but has no argument, then a cryptoadm_provider_t
284 * with cp_type = PROV_BADNAME is returned.
286 static cryptoadm_provider_t *
287 get_provider(int argc, char **argv)
289 int c = 0;
290 boolean_t found = B_FALSE;
291 cryptoadm_provider_t *provider = NULL;
292 char *provstr = NULL, *savstr;
293 boolean_t is_metaslot = B_FALSE;
295 while (!found && ++c < argc) {
296 if (strncmp(argv[c], METASLOT_KEYWORD,
297 strlen(METASLOT_KEYWORD)) == 0) {
298 is_metaslot = B_TRUE;
299 found = B_TRUE;
300 } else if (strncmp(argv[c], KN_PROVIDER,
301 strlen(KN_PROVIDER)) == 0 &&
302 strlen(argv[c]) > strlen(KN_PROVIDER)) {
303 if ((provstr = strdup(argv[c])) == NULL) {
304 int err = errno;
306 * TRANSLATION_NOTE
307 * "get_provider" is a function name and should
308 * not be translated.
310 cryptoerror(LOG_STDERR, "get_provider: %s.",
311 strerror(err));
312 return (NULL);
314 found = B_TRUE;
317 if (!found)
318 return (NULL);
320 provider = malloc(sizeof (cryptoadm_provider_t));
321 if (provider == NULL) {
322 cryptoerror(LOG_STDERR, gettext("out of memory."));
323 if (provstr) {
324 free(provstr);
326 return (NULL);
329 if (is_metaslot) {
330 (void) strlcpy(provider->cp_name, METASLOT_KEYWORD,
331 strlen(METASLOT_KEYWORD));
332 provider->cp_type = METASLOT;
333 } else {
335 savstr = provstr;
336 (void) strtok(provstr, "=");
337 provstr = strtok(NULL, "=");
338 if (provstr == NULL) {
339 cryptoerror(LOG_STDERR, gettext("bad provider name."));
340 provider->cp_type = PROV_BADNAME;
341 free(savstr);
342 return (provider);
345 (void) strlcpy(provider->cp_name, provstr,
346 sizeof (provider->cp_name));
347 provider->cp_type = get_provider_type(provider->cp_name);
349 free(savstr);
351 return (provider);
355 * Process the "feature" operands.
357 * "argc" and "argv" contain values specified on the command line.
358 * All other arguments are used for returning parsing results.
359 * If any of these arguments are NULL, that keyword is not expected,
360 * and FAILURE will be returned.
362 static int
363 process_metaslot_operands(int argc, char **argv, char **meta_ks_token,
364 char **meta_ks_slot, boolean_t *use_default,
365 boolean_t *auto_key_migrate_flag)
367 int c = 2;
368 int rc = SUCCESS;
370 while (++c < argc) {
371 if ((strncmp(argv[c], KN_MECH, strlen(KN_MECH)) == 0) &&
372 strlen(argv[c]) > strlen(KN_MECH)) {
374 /* process mechanism operands */
375 if ((rc = process_mech_operands(argc, argv, B_TRUE))
376 != SUCCESS) {
377 goto finish;
380 } else if ((strncmp(argv[c], KN_TOKEN,
381 strlen(KN_TOKEN)) == 0) &&
382 strlen(argv[c]) > strlen(KN_TOKEN)) {
383 if ((meta_ks_token) && (strtok(argv[c], "=") != NULL)) {
384 char *tmp;
385 if ((tmp = strtok(NULL, "=")) != NULL) {
386 *meta_ks_token = strdup(tmp);
387 } else {
388 return (FAILURE);
390 } else {
391 return (FAILURE);
394 } else if ((strncmp(argv[c], KN_SLOT,
395 strlen(KN_SLOT)) == 0) &&
396 strlen(argv[c]) > strlen(KN_SLOT)) {
398 if ((meta_ks_slot) && (strtok(argv[c], "=") != NULL)) {
399 char *tmp;
400 if ((tmp = strtok(NULL, "=")) != NULL) {
401 *meta_ks_slot = strdup(tmp);
402 } else {
403 return (FAILURE);
405 } else {
406 return (FAILURE);
409 } else if (strncmp(argv[c], KN_DEFAULT_KS,
410 strlen(KN_DEFAULT_KS)) == 0) {
412 if (use_default) {
413 *use_default = B_TRUE;
414 } else {
415 return (FAILURE);
417 } else if (strncmp(argv[c], KN_AUTO_KEY_MIGRATE,
418 strlen(KN_AUTO_KEY_MIGRATE)) == 0) {
420 if (auto_key_migrate_flag) {
421 *auto_key_migrate_flag = B_TRUE;
422 } else {
423 return (FAILURE);
425 } else {
426 return (FAILURE);
429 finish:
430 return (rc);
434 * Process the "feature" operands.
436 static int
437 process_feature_operands(int argc, char **argv)
439 int c = 2;
441 while (++c < argc) {
442 if (strcmp(argv[c], KN_ALL) == 0) {
443 allflag = B_TRUE;
444 rndflag = B_TRUE; /* all includes random also. */
445 } else if (strcmp(argv[c], RANDOM) == 0) {
446 rndflag = B_TRUE;
449 return (SUCCESS);
453 * Process the mechanism operands for the disable, enable and install
454 * subcommands. This function sets the static variable allflag to be B_TRUE
455 * if the keyword "all" is specified, otherwise builds a link list of the
456 * mechanism operands and save it in the static variable mecharglist.
458 * This function returns
459 * ERROR_USAGE: mechanism operand is missing.
460 * FAILURE: out of memory.
461 * SUCCESS: otherwise.
463 static int
464 process_mech_operands(int argc, char **argv, boolean_t quiet)
466 mechlist_t *pmech;
467 mechlist_t *pcur = NULL;
468 mechlist_t *phead = NULL;
469 boolean_t found = B_FALSE;
470 char *mechliststr = NULL;
471 char *curmech = NULL;
472 int c = -1;
473 int rc = SUCCESS;
475 while (!found && ++c < argc) {
476 if ((strncmp(argv[c], KN_MECH, strlen(KN_MECH)) == 0) &&
477 strlen(argv[c]) > strlen(KN_MECH)) {
478 found = B_TRUE;
481 if (!found) {
482 if (!quiet)
484 * TRANSLATION_NOTE
485 * "mechanism" could be either a literal keyword
486 * and hence not to be translated, or a descriptive
487 * word and translatable. A choice was made to
488 * view it as a literal keyword.
490 cryptoerror(LOG_STDERR,
491 gettext("the %s operand is missing.\n"),
492 "mechanism");
493 return (ERROR_USAGE);
495 (void) strtok(argv[c], "=");
496 mechliststr = strtok(NULL, "=");
498 if (strcmp(mechliststr, "all") == 0) {
499 allflag = B_TRUE;
500 mecharglist = NULL;
501 return (SUCCESS);
504 curmech = strtok(mechliststr, ",");
505 do {
506 if ((pmech = create_mech(curmech)) == NULL) {
507 rc = FAILURE;
508 break;
509 } else {
510 if (phead == NULL) {
511 phead = pcur = pmech;
512 } else {
513 pcur->next = pmech;
514 pcur = pmech;
517 } while ((curmech = strtok(NULL, ",")) != NULL);
519 if (rc == FAILURE) {
520 cryptoerror(LOG_STDERR, gettext("out of memory."));
521 free_mechlist(phead);
522 } else {
523 mecharglist = phead;
524 rc = SUCCESS;
526 return (rc);
532 * The top level function for the "cryptoadm list" subcommand and options.
534 static int
535 do_list(int argc, char **argv)
537 boolean_t mflag = B_FALSE;
538 boolean_t pflag = B_FALSE;
539 boolean_t vflag = B_FALSE;
540 char ch;
541 cryptoadm_provider_t *prov = NULL;
542 int rc = SUCCESS;
544 argc -= 1;
545 argv += 1;
547 if (argc == 1) {
548 rc = list_simple_for_all(B_FALSE);
549 goto out;
553 * cryptoadm list [-v] [-m] [-p] [provider=<>] [mechanism=<>]
555 if (argc > 5) {
556 usage();
557 return (rc);
560 while ((ch = getopt(argc, argv, "mpv")) != EOF) {
561 switch (ch) {
562 case 'm':
563 mflag = B_TRUE;
564 if (pflag) {
565 rc = ERROR_USAGE;
567 break;
568 case 'p':
569 pflag = B_TRUE;
570 if (mflag || vflag) {
571 rc = ERROR_USAGE;
573 break;
574 case 'v':
575 vflag = B_TRUE;
576 if (pflag)
577 rc = ERROR_USAGE;
578 break;
579 default:
580 rc = ERROR_USAGE;
581 break;
585 if (rc == ERROR_USAGE) {
586 usage();
587 return (rc);
590 if ((rc = process_feature_operands(argc, argv)) != SUCCESS) {
591 goto out;
594 prov = get_provider(argc, argv);
596 if (mflag || vflag) {
597 if (argc > 0) {
598 rc = process_mech_operands(argc, argv, B_TRUE);
599 if (rc == FAILURE)
600 goto out;
601 /* "-m" is implied when a mechanism list is given */
602 if (mecharglist != NULL || allflag)
603 mflag = B_TRUE;
607 if (prov == NULL) {
608 if (mflag) {
609 rc = list_mechlist_for_all(vflag);
610 } else if (pflag) {
611 rc = list_policy_for_all();
612 } else if (vflag) {
613 rc = list_simple_for_all(vflag);
615 } else if (prov->cp_type == METASLOT) {
616 if ((!mflag) && (!vflag) && (!pflag)) {
617 /* no flag is specified, just list metaslot status */
618 rc = list_metaslot_info(mflag, vflag, mecharglist);
619 } else if (mflag || vflag) {
620 rc = list_metaslot_info(mflag, vflag, mecharglist);
621 } else if (pflag) {
622 rc = list_metaslot_policy();
623 } else {
624 /* error message */
625 usage();
626 rc = ERROR_USAGE;
628 } else if (prov->cp_type == PROV_BADNAME) {
629 usage();
630 rc = ERROR_USAGE;
631 goto out;
632 } else { /* do the listing for a provider only */
633 char *provname = prov->cp_name;
635 if (mflag || vflag) {
636 if (vflag)
637 (void) printf(gettext("Provider: %s\n"),
638 provname);
639 switch (prov->cp_type) {
640 case PROV_UEF_LIB:
641 rc = list_mechlist_for_lib(provname,
642 mecharglist, NULL, B_FALSE, vflag, mflag);
643 break;
644 case PROV_KEF_SOFT:
645 rc = list_mechlist_for_soft(provname,
646 NULL, NULL);
647 break;
648 case PROV_KEF_HARD:
649 rc = list_mechlist_for_hard(provname);
650 break;
651 default: /* should not come here */
652 rc = FAILURE;
653 break;
655 } else if (pflag) {
656 switch (prov->cp_type) {
657 case PROV_UEF_LIB:
658 rc = list_policy_for_lib(provname);
659 break;
660 case PROV_KEF_SOFT:
661 if (getzoneid() == GLOBAL_ZONEID) {
662 rc = list_policy_for_soft(provname,
663 NULL, NULL);
664 } else {
666 * TRANSLATION_NOTE
667 * "global" is keyword and not to
668 * be translated.
670 cryptoerror(LOG_STDERR, gettext(
671 "policy information for kernel "
672 "providers is available "
673 "in the %s zone only"), "global");
674 rc = FAILURE;
676 break;
677 case PROV_KEF_HARD:
678 if (getzoneid() == GLOBAL_ZONEID) {
679 rc = list_policy_for_hard(
680 provname, NULL, NULL, NULL);
681 } else {
683 * TRANSLATION_NOTE
684 * "global" is keyword and not to
685 * be translated.
687 cryptoerror(LOG_STDERR, gettext(
688 "policy information for kernel "
689 "providers is available "
690 "in the %s zone only"), "global");
691 rc = FAILURE;
694 break;
695 default: /* should not come here */
696 rc = FAILURE;
697 break;
699 } else {
700 /* error message */
701 usage();
702 rc = ERROR_USAGE;
706 out:
707 free(prov);
709 if (mecharglist != NULL)
710 free_mechlist(mecharglist);
711 return (rc);
716 * The top level function for the "cryptoadm disable" subcommand.
718 static int
719 do_disable(int argc, char **argv)
721 cryptoadm_provider_t *prov = NULL;
722 int rc = SUCCESS;
723 boolean_t auto_key_migrate_flag = B_FALSE;
725 if ((argc < 3) || (argc > 5)) {
726 usage();
727 return (ERROR_USAGE);
730 prov = get_provider(argc, argv);
731 if (prov == NULL) {
732 usage();
733 return (ERROR_USAGE);
735 if (prov->cp_type == PROV_BADNAME) {
736 return (FAILURE);
739 if ((rc = process_feature_operands(argc, argv)) != SUCCESS) {
740 goto out;
744 * If allflag or rndflag has already been set there is no reason to
745 * process mech=
747 if (prov->cp_type == METASLOT) {
748 if ((argc > 3) &&
749 (rc = process_metaslot_operands(argc, argv,
750 NULL, NULL, NULL, &auto_key_migrate_flag)) != SUCCESS) {
751 usage();
752 return (rc);
754 } else if (!allflag && !rndflag &&
755 (rc = process_mech_operands(argc, argv, B_FALSE)) != SUCCESS) {
756 return (rc);
759 switch (prov->cp_type) {
760 case METASLOT:
761 rc = disable_metaslot(mecharglist, allflag,
762 auto_key_migrate_flag);
763 break;
764 case PROV_UEF_LIB:
765 rc = disable_uef_lib(prov->cp_name, rndflag, allflag,
766 mecharglist);
767 break;
768 case PROV_KEF_SOFT:
769 if (rndflag && !allflag) {
770 if ((mecharglist = create_mech(RANDOM)) == NULL) {
771 rc = FAILURE;
772 break;
775 if (getzoneid() == GLOBAL_ZONEID) {
776 rc = disable_kef_software(prov->cp_name, rndflag,
777 allflag, mecharglist);
778 } else {
780 * TRANSLATION_NOTE
781 * "disable" could be either a literal keyword
782 * and hence not to be translated, or a verb and
783 * translatable. A choice was made to view it as
784 * a literal keyword. "global" is keyword and not
785 * to be translated.
787 cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
788 "providers is supported in the %2$s zone only"),
789 "disable", "global");
790 rc = FAILURE;
792 break;
793 case PROV_KEF_HARD:
794 if (rndflag && !allflag) {
795 if ((mecharglist = create_mech(RANDOM)) == NULL) {
796 rc = FAILURE;
797 break;
800 if (getzoneid() == GLOBAL_ZONEID) {
801 rc = disable_kef_hardware(prov->cp_name, rndflag,
802 allflag, mecharglist);
803 } else {
805 * TRANSLATION_NOTE
806 * "disable" could be either a literal keyword
807 * and hence not to be translated, or a verb and
808 * translatable. A choice was made to view it as
809 * a literal keyword. "global" is keyword and not
810 * to be translated.
812 cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
813 "providers is supported in the %2$s zone only"),
814 "disable", "global");
815 rc = FAILURE;
817 break;
818 default: /* should not come here */
819 rc = FAILURE;
820 break;
823 out:
824 free(prov);
825 if (mecharglist != NULL) {
826 free_mechlist(mecharglist);
828 return (rc);
833 * The top level function for the "cryptoadm enable" subcommand.
835 static int
836 do_enable(int argc, char **argv)
838 cryptoadm_provider_t *prov = NULL;
839 int rc = SUCCESS;
840 char *alt_token = NULL, *alt_slot = NULL;
841 boolean_t use_default = B_FALSE;
842 boolean_t auto_key_migrate_flag = B_FALSE;
844 if ((argc < 3) || (argc > 6)) {
845 usage();
846 return (ERROR_USAGE);
849 prov = get_provider(argc, argv);
850 if (prov == NULL) {
851 usage();
852 return (ERROR_USAGE);
854 if ((prov->cp_type != METASLOT) && (argc != 4)) {
855 usage();
856 return (ERROR_USAGE);
858 if (prov->cp_type == PROV_BADNAME) {
859 rc = FAILURE;
860 goto out;
864 if (prov->cp_type == METASLOT) {
865 if ((rc = process_metaslot_operands(argc, argv, &alt_token,
866 &alt_slot, &use_default, &auto_key_migrate_flag))
867 != SUCCESS) {
868 usage();
869 goto out;
871 if ((alt_slot || alt_token) && use_default) {
872 usage();
873 rc = FAILURE;
874 goto out;
876 } else {
877 if ((rc = process_feature_operands(argc, argv)) != SUCCESS) {
878 goto out;
882 * If allflag or rndflag has already been set there is
883 * no reason to process mech=
885 if (!allflag && !rndflag &&
886 (rc = process_mech_operands(argc, argv, B_FALSE))
887 != SUCCESS) {
888 goto out;
892 switch (prov->cp_type) {
893 case METASLOT:
894 rc = enable_metaslot(alt_token, alt_slot, use_default,
895 mecharglist, allflag, auto_key_migrate_flag);
896 break;
897 case PROV_UEF_LIB:
898 rc = enable_uef_lib(prov->cp_name, rndflag, allflag,
899 mecharglist);
900 break;
901 case PROV_KEF_SOFT:
902 case PROV_KEF_HARD:
903 if (rndflag && !allflag) {
904 if ((mecharglist = create_mech(RANDOM)) == NULL) {
905 rc = FAILURE;
906 break;
909 if (getzoneid() == GLOBAL_ZONEID) {
910 rc = enable_kef(prov->cp_name, rndflag, allflag,
911 mecharglist);
912 } else {
914 * TRANSLATION_NOTE
915 * "enable" could be either a literal keyword
916 * and hence not to be translated, or a verb and
917 * translatable. A choice was made to view it as
918 * a literal keyword. "global" is keyword and not
919 * to be translated.
921 cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
922 "providers is supported in the %2$s zone only"),
923 "enable", "global");
924 rc = FAILURE;
926 break;
927 default: /* should not come here */
928 rc = FAILURE;
929 break;
931 out:
932 free(prov);
933 if (mecharglist != NULL) {
934 free_mechlist(mecharglist);
936 if (alt_token != NULL) {
937 free(alt_token);
939 if (alt_slot != NULL) {
940 free(alt_slot);
942 return (rc);
948 * The top level function for the "cryptoadm install" subcommand.
950 static int
951 do_install(int argc, char **argv)
953 cryptoadm_provider_t *prov = NULL;
954 int rc;
956 if (argc < 3) {
957 usage();
958 return (ERROR_USAGE);
961 prov = get_provider(argc, argv);
962 if (prov == NULL ||
963 prov->cp_type == PROV_BADNAME || prov->cp_type == PROV_KEF_HARD) {
965 * TRANSLATION_NOTE
966 * "install" could be either a literal keyword and hence
967 * not to be translated, or a verb and translatable. A
968 * choice was made to view it as a literal keyword.
970 cryptoerror(LOG_STDERR,
971 gettext("bad provider name for %s."), "install");
972 rc = FAILURE;
973 goto out;
976 if (prov->cp_type == PROV_UEF_LIB) {
977 rc = install_uef_lib(prov->cp_name);
978 goto out;
981 /* It is the PROV_KEF_SOFT type now */
983 /* check if there are mechanism operands */
984 if (argc < 4) {
986 * TRANSLATION_NOTE
987 * "mechanism" could be either a literal keyword and hence
988 * not to be translated, or a descriptive word and
989 * translatable. A choice was made to view it as a literal
990 * keyword.
992 cryptoerror(LOG_STDERR,
993 gettext("need %s operands for installing a"
994 " kernel software provider."), "mechanism");
995 rc = ERROR_USAGE;
996 goto out;
999 if ((rc = process_mech_operands(argc, argv, B_FALSE)) != SUCCESS) {
1000 goto out;
1003 if (allflag == B_TRUE) {
1005 * TRANSLATION_NOTE
1006 * "all", "mechanism", and "install" are all keywords and
1007 * not to be translated.
1009 cryptoerror(LOG_STDERR,
1010 gettext("can not use the %1$s keyword for %2$s "
1011 "in the %3$s subcommand."), "all", "mechanism", "install");
1012 rc = ERROR_USAGE;
1013 goto out;
1016 if (getzoneid() == GLOBAL_ZONEID) {
1017 rc = install_kef(prov->cp_name, mecharglist);
1018 } else {
1020 * TRANSLATION_NOTE
1021 * "install" could be either a literal keyword and hence
1022 * not to be translated, or a verb and translatable. A
1023 * choice was made to view it as a literal keyword.
1024 * "global" is keyword and not to be translated.
1026 cryptoerror(LOG_STDERR, gettext("%1$s for kernel providers "
1027 "is supported in the %2$s zone only"), "install", "global");
1028 rc = FAILURE;
1030 out:
1031 free(prov);
1032 return (rc);
1038 * The top level function for the "cryptoadm uninstall" subcommand.
1040 static int
1041 do_uninstall(int argc, char **argv)
1043 cryptoadm_provider_t *prov = NULL;
1044 int rc = SUCCESS;
1046 if (argc != 3) {
1047 usage();
1048 return (ERROR_USAGE);
1051 prov = get_provider(argc, argv);
1052 if (prov == NULL ||
1053 prov->cp_type == PROV_BADNAME || prov->cp_type == PROV_KEF_HARD) {
1055 * TRANSLATION_NOTE
1056 * "uninstall" could be either a literal keyword and hence
1057 * not to be translated, or a verb and translatable. A
1058 * choice was made to view it as a literal keyword.
1060 cryptoerror(LOG_STDERR,
1061 gettext("bad provider name for %s."), "uninstall");
1062 free(prov);
1063 return (FAILURE);
1066 if (prov->cp_type == PROV_UEF_LIB) {
1067 rc = uninstall_uef_lib(prov->cp_name);
1069 } else if (prov->cp_type == PROV_KEF_SOFT) {
1070 if (getzoneid() == GLOBAL_ZONEID) {
1071 /* unload and remove from kcf.conf */
1072 rc = uninstall_kef(prov->cp_name);
1073 } else {
1075 * TRANSLATION_NOTE
1076 * "uninstall" could be either a literal keyword and
1077 * hence not to be translated, or a verb and
1078 * translatable. A choice was made to view it as a
1079 * literal keyword. "global" is keyword and not to
1080 * be translated.
1082 cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
1083 "providers is supported in the %2$s zone only"),
1084 "uninstall", "global");
1085 rc = FAILURE;
1089 free(prov);
1090 return (rc);
1095 * The top level function for the "cryptoadm unload" subcommand.
1097 static int
1098 do_unload(int argc, char **argv)
1100 cryptoadm_provider_t *prov = NULL;
1101 entry_t *pent = NULL;
1102 boolean_t in_kernel = B_FALSE;
1103 int rc = SUCCESS;
1104 char *provname = NULL;
1106 if (argc != 3) {
1107 usage();
1108 return (ERROR_USAGE);
1111 /* check if it is a kernel software provider */
1112 prov = get_provider(argc, argv);
1113 if (prov == NULL) {
1114 cryptoerror(LOG_STDERR,
1115 gettext("unable to determine provider name."));
1116 goto out;
1118 provname = prov->cp_name;
1119 if (prov->cp_type != PROV_KEF_SOFT) {
1120 cryptoerror(LOG_STDERR,
1121 gettext("%s is not a valid kernel software provider."),
1122 provname);
1123 rc = FAILURE;
1124 goto out;
1127 if (getzoneid() != GLOBAL_ZONEID) {
1129 * TRANSLATION_NOTE
1130 * "unload" could be either a literal keyword and hence
1131 * not to be translated, or a verb and translatable.
1132 * A choice was made to view it as a literal keyword.
1133 * "global" is keyword and not to be translated.
1135 cryptoerror(LOG_STDERR, gettext("%1$s for kernel providers "
1136 "is supported in the %2$s zone only"), "unload", "global");
1137 rc = FAILURE;
1138 goto out;
1141 if (check_kernel_for_soft(provname, NULL, &in_kernel) == FAILURE) {
1142 cryptodebug("internal error");
1143 rc = FAILURE;
1144 goto out;
1145 } else if (in_kernel == B_FALSE) {
1146 cryptoerror(LOG_STDERR,
1147 gettext("provider %s is not loaded or does not exist."),
1148 provname);
1149 rc = FAILURE;
1150 goto out;
1153 /* Get kcf.conf entry. If none, build a new entry */
1154 if ((pent = getent_kef(provname, NULL, NULL)) == NULL) {
1155 if ((pent = create_entry(provname)) == NULL) {
1156 cryptoerror(LOG_STDERR, gettext("out of memory."));
1157 rc = FAILURE;
1158 goto out;
1162 /* If it is unloaded already, return */
1163 if (!pent->load) { /* unloaded already */
1164 cryptoerror(LOG_STDERR,
1165 gettext("failed to unload %s."), provname);
1166 rc = FAILURE;
1167 goto out;
1168 } else if (unload_kef_soft(provname) != FAILURE) {
1169 /* Mark as unloaded in kcf.conf */
1170 pent->load = B_FALSE;
1171 rc = update_kcfconf(pent, MODIFY_MODE);
1172 } else {
1173 cryptoerror(LOG_STDERR,
1174 gettext("failed to unload %s."), provname);
1175 rc = FAILURE;
1177 out:
1178 free(prov);
1179 free_entry(pent);
1180 return (rc);
1186 * The top level function for the "cryptoadm refresh" subcommand.
1188 static int
1189 do_refresh(int argc)
1191 if (argc != 2) {
1192 usage();
1193 return (ERROR_USAGE);
1196 if (getzoneid() == GLOBAL_ZONEID) {
1197 return (refresh());
1198 } else { /* non-global zone */
1200 * Note: in non-global zone, this must silently return SUCCESS
1201 * due to integration with SMF, for "svcadm refresh cryptosvc"
1203 return (SUCCESS);
1209 * The top level function for the "cryptoadm start" subcommand.
1210 * This used to start up kcfd, but now all it does is load up the
1211 * initial providers.
1213 static int
1214 do_start(int argc)
1216 if (argc != 2) {
1217 usage();
1218 return (ERROR_USAGE);
1221 return (do_refresh(argc));
1225 * The top level function for the "cryptoadm stop" subcommand.
1226 * This no longer does anything useful, but we leave it here
1227 * for compatibility.
1229 static int
1230 do_stop(int argc)
1232 if (argc != 2) {
1233 usage();
1234 return (ERROR_USAGE);
1237 return (SUCCESS);
1243 * Print a list all the the providers.
1244 * Called for "cryptoadm list" or "cryptoadm list -v" (no -m or -p).
1246 static int
1247 list_simple_for_all(boolean_t verbose)
1249 uentrylist_t *pliblist = NULL;
1250 uentrylist_t *plibptr = NULL;
1251 entry_t *pent = NULL;
1252 crypto_get_dev_list_t *pdevlist_kernel = NULL;
1253 int rc = SUCCESS;
1254 int i;
1256 /* get user-level providers */
1257 (void) printf(gettext("\nUser-level providers:\n"));
1258 if (get_pkcs11conf_info(&pliblist) != SUCCESS) {
1259 cryptoerror(LOG_STDERR, gettext(
1260 "failed to retrieve the list of user-level providers."));
1261 rc = FAILURE;
1264 for (plibptr = pliblist; plibptr != NULL; plibptr = plibptr->next) {
1265 /* skip metaslot and fips-140 entry */
1266 if ((strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) &&
1267 (strcmp(plibptr->puent->name, FIPS_KEYWORD) != 0)) {
1268 (void) printf(gettext("Provider: %s\n"),
1269 plibptr->puent->name);
1270 if (verbose) {
1271 (void) list_mechlist_for_lib(
1272 plibptr->puent->name, mecharglist, NULL,
1273 B_FALSE, verbose, B_FALSE);
1274 (void) printf("\n");
1278 free_uentrylist(pliblist);
1280 /* get kernel software providers */
1281 (void) printf(gettext("\nKernel software providers:\n"));
1283 if (getzoneid() == GLOBAL_ZONEID) {
1284 /* get kernel software providers from kernel ioctl */
1285 crypto_get_soft_list_t *psoftlist_kernel = NULL;
1286 uint_t sl_soft_count;
1287 char *psoftname;
1288 entrylist_t *pdevlist_conf = NULL;
1289 entrylist_t *psoftlist_conf = NULL;
1291 if (get_soft_list(&psoftlist_kernel) == FAILURE) {
1292 cryptoerror(LOG_ERR, gettext("Failed to retrieve the "
1293 "software provider list from kernel."));
1294 rc = FAILURE;
1295 } else {
1296 sl_soft_count = psoftlist_kernel->sl_soft_count;
1298 if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf)
1299 == FAILURE) {
1300 cryptoerror(LOG_ERR,
1301 "failed to retrieve the providers' "
1302 "information from file kcf.conf - %s.",
1303 _PATH_KCF_CONF);
1304 free(psoftlist_kernel);
1305 rc = FAILURE;
1306 } else {
1308 for (i = 0,
1309 psoftname = psoftlist_kernel->sl_soft_names;
1310 i < sl_soft_count;
1311 ++i, psoftname += strlen(psoftname) + 1) {
1312 pent = getent_kef(psoftname,
1313 pdevlist_conf, psoftlist_conf);
1314 (void) printf("\t%s%s\n", psoftname,
1315 (pent == NULL) || (pent->load) ?
1316 "" : gettext(" (inactive)"));
1318 free_entrylist(pdevlist_conf);
1319 free_entrylist(psoftlist_conf);
1321 free(psoftlist_kernel);
1324 } else {
1325 /* kcf.conf not there in non-global zone, use /dev/cryptoadm */
1326 entrylist_t *pdevlist_zone = NULL;
1327 entrylist_t *psoftlist_zone = NULL;
1328 entrylist_t *ptr;
1330 if (get_admindev_info(&pdevlist_zone, &psoftlist_zone) !=
1331 SUCCESS) {
1332 cryptoerror(LOG_STDERR,
1333 gettext("failed to retrieve the "
1334 "list of kernel software providers.\n"));
1335 rc = FAILURE;
1338 ptr = psoftlist_zone;
1339 while (ptr != NULL) {
1340 (void) printf("\t%s\n", ptr->pent->name);
1341 ptr = ptr->next;
1344 free_entrylist(pdevlist_zone);
1345 free_entrylist(psoftlist_zone);
1348 /* get kernel hardware providers */
1349 (void) printf(gettext("\nKernel hardware providers:\n"));
1350 if (get_dev_list(&pdevlist_kernel) == FAILURE) {
1351 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1352 "the list of kernel hardware providers.\n"));
1353 rc = FAILURE;
1354 } else {
1355 for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) {
1356 (void) printf("\t%s/%d\n",
1357 pdevlist_kernel->dl_devs[i].le_dev_name,
1358 pdevlist_kernel->dl_devs[i].le_dev_instance);
1361 free(pdevlist_kernel);
1363 return (rc);
1369 * List all the providers. And for each provider, list the mechanism list.
1370 * Called for "cryptoadm list -m" or "cryptoadm list -mv" .
1372 static int
1373 list_mechlist_for_all(boolean_t verbose)
1375 crypto_get_dev_list_t *pdevlist_kernel = NULL;
1376 uentrylist_t *pliblist = NULL;
1377 uentrylist_t *plibptr = NULL;
1378 entry_t *pent = NULL;
1379 mechlist_t *pmechlist = NULL;
1380 char provname[MAXNAMELEN];
1381 char devname[MAXNAMELEN];
1382 int inst_num;
1383 int count;
1384 int i;
1385 int rv;
1386 int rc = SUCCESS;
1388 /* get user-level providers */
1389 (void) printf(gettext("\nUser-level providers:\n"));
1391 * TRANSLATION_NOTE
1392 * Strictly for appearance's sake, this line should be as long as
1393 * the length of the translated text above.
1395 (void) printf(gettext("=====================\n"));
1396 if (get_pkcs11conf_info(&pliblist) != SUCCESS) {
1397 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1398 "the list of user-level providers.\n"));
1399 rc = FAILURE;
1402 plibptr = pliblist;
1403 while (plibptr != NULL) {
1404 /* skip metaslot and fips-140 entry */
1405 if ((strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) &&
1406 (strcmp(plibptr->puent->name, FIPS_KEYWORD) != 0)) {
1407 (void) printf(gettext("\nProvider: %s\n"),
1408 plibptr->puent->name);
1409 rv = list_mechlist_for_lib(plibptr->puent->name,
1410 mecharglist, NULL, B_FALSE, verbose, B_TRUE);
1411 if (rv == FAILURE) {
1412 rc = FAILURE;
1415 plibptr = plibptr->next;
1417 free_uentrylist(pliblist);
1419 /* get kernel software providers */
1420 (void) printf(gettext("\nKernel software providers:\n"));
1423 * TRANSLATION_NOTE
1424 * Strictly for appearance's sake, this line should be as long as
1425 * the length of the translated text above.
1427 (void) printf(gettext("==========================\n"));
1428 if (getzoneid() == GLOBAL_ZONEID) {
1429 /* get kernel software providers from kernel ioctl */
1430 crypto_get_soft_list_t *psoftlist_kernel = NULL;
1431 uint_t sl_soft_count;
1432 char *psoftname;
1433 int i;
1434 entrylist_t *pdevlist_conf = NULL;
1435 entrylist_t *psoftlist_conf = NULL;
1437 if (get_soft_list(&psoftlist_kernel) == FAILURE) {
1438 cryptoerror(LOG_ERR, gettext("Failed to retrieve the "
1439 "software provider list from kernel."));
1440 return (FAILURE);
1442 sl_soft_count = psoftlist_kernel->sl_soft_count;
1444 if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf)
1445 == FAILURE) {
1446 cryptoerror(LOG_ERR,
1447 "failed to retrieve the providers' "
1448 "information from file kcf.conf - %s.",
1449 _PATH_KCF_CONF);
1450 free(psoftlist_kernel);
1451 return (FAILURE);
1454 for (i = 0, psoftname = psoftlist_kernel->sl_soft_names;
1455 i < sl_soft_count;
1456 ++i, psoftname += strlen(psoftname) + 1) {
1457 pent = getent_kef(psoftname, pdevlist_conf,
1458 psoftlist_conf);
1459 if ((pent == NULL) || (pent->load)) {
1460 rv = list_mechlist_for_soft(psoftname,
1461 NULL, NULL);
1462 if (rv == FAILURE) {
1463 rc = FAILURE;
1465 } else {
1466 (void) printf(gettext("%s: (inactive)\n"),
1467 psoftname);
1471 free(psoftlist_kernel);
1472 free_entrylist(pdevlist_conf);
1473 free_entrylist(psoftlist_conf);
1475 } else {
1476 /* kcf.conf not there in non-global zone, use /dev/cryptoadm */
1477 entrylist_t *pdevlist_zone = NULL;
1478 entrylist_t *psoftlist_zone = NULL;
1479 entrylist_t *ptr;
1481 if (get_admindev_info(&pdevlist_zone, &psoftlist_zone) !=
1482 SUCCESS) {
1483 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1484 "the list of kernel software providers.\n"));
1485 rc = FAILURE;
1488 for (ptr = psoftlist_zone; ptr != NULL; ptr = ptr->next) {
1489 rv = list_mechlist_for_soft(ptr->pent->name,
1490 pdevlist_zone, psoftlist_zone);
1491 if (rv == FAILURE) {
1492 (void) printf(gettext(
1493 "%s: failed to get the mechanism list.\n"),
1494 ptr->pent->name);
1495 rc = FAILURE;
1499 free_entrylist(pdevlist_zone);
1500 free_entrylist(psoftlist_zone);
1503 /* Get kernel hardware providers and their mechanism lists */
1504 (void) printf(gettext("\nKernel hardware providers:\n"));
1506 * TRANSLATION_NOTE
1507 * Strictly for appearance's sake, this line should be as long as
1508 * the length of the translated text above.
1510 (void) printf(gettext("==========================\n"));
1511 if (get_dev_list(&pdevlist_kernel) != SUCCESS) {
1512 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1513 "the list of hardware providers.\n"));
1514 return (FAILURE);
1517 for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) {
1518 (void) strlcpy(devname,
1519 pdevlist_kernel->dl_devs[i].le_dev_name, MAXNAMELEN);
1520 inst_num = pdevlist_kernel->dl_devs[i].le_dev_instance;
1521 count = pdevlist_kernel->dl_devs[i].le_mechanism_count;
1522 (void) snprintf(provname, sizeof (provname), "%s/%d", devname,
1523 inst_num);
1524 if (get_dev_info(devname, inst_num, count, &pmechlist) ==
1525 SUCCESS) {
1526 (void) filter_mechlist(&pmechlist, RANDOM);
1527 print_mechlist(provname, pmechlist);
1528 free_mechlist(pmechlist);
1529 } else {
1530 (void) printf(gettext("%s: failed to get the mechanism"
1531 " list.\n"), provname);
1532 rc = FAILURE;
1535 free(pdevlist_kernel);
1536 return (rc);
1541 * List all the providers. And for each provider, list the policy information.
1542 * Called for "cryptoadm list -p".
1544 static int
1545 list_policy_for_all(void)
1547 crypto_get_dev_list_t *pdevlist_kernel = NULL;
1548 uentrylist_t *pliblist = NULL;
1549 entrylist_t *pdevlist_conf = NULL;
1550 entrylist_t *psoftlist_conf = NULL;
1551 entrylist_t *ptr = NULL;
1552 entrylist_t *phead = NULL;
1553 boolean_t found = B_FALSE;
1554 char provname[MAXNAMELEN];
1555 int i;
1556 int rc = SUCCESS;
1558 /* Get user-level providers */
1559 (void) printf(gettext("\nUser-level providers:\n"));
1561 * TRANSLATION_NOTE
1562 * Strictly for appearance's sake, this line should be as long as
1563 * the length of the translated text above.
1565 (void) printf(gettext("=====================\n"));
1566 if (get_pkcs11conf_info(&pliblist) == FAILURE) {
1567 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1568 "the list of user-level providers.\n"));
1569 rc = FAILURE;
1570 } else {
1571 uentrylist_t *plibptr = pliblist;
1573 while (plibptr != NULL) {
1574 /* skip metaslot and fips-140 entry */
1575 if ((strcmp(plibptr->puent->name,
1576 METASLOT_KEYWORD) != 0) &&
1577 (strcmp(plibptr->puent->name,
1578 FIPS_KEYWORD) != 0)) {
1579 if (print_uef_policy(plibptr->puent)
1580 == FAILURE) {
1581 rc = FAILURE;
1584 plibptr = plibptr->next;
1586 free_uentrylist(pliblist);
1589 /* kernel software providers */
1590 (void) printf(gettext("\nKernel software providers:\n"));
1592 * TRANSLATION_NOTE
1593 * Strictly for appearance's sake, this line should be as long as
1594 * the length of the translated text above.
1596 (void) printf(gettext("==========================\n"));
1598 /* Get all entries from the kernel */
1599 if (getzoneid() == GLOBAL_ZONEID) {
1600 /* get kernel software providers from kernel ioctl */
1601 crypto_get_soft_list_t *psoftlist_kernel = NULL;
1602 uint_t sl_soft_count;
1603 char *psoftname;
1604 int i;
1606 if (get_soft_list(&psoftlist_kernel) == FAILURE) {
1607 cryptoerror(LOG_ERR, gettext("Failed to retrieve the "
1608 "software provider list from kernel."));
1609 rc = FAILURE;
1610 } else {
1611 sl_soft_count = psoftlist_kernel->sl_soft_count;
1613 for (i = 0, psoftname = psoftlist_kernel->sl_soft_names;
1614 i < sl_soft_count;
1615 ++i, psoftname += strlen(psoftname) + 1) {
1616 (void) list_policy_for_soft(psoftname,
1617 pdevlist_conf, psoftlist_conf);
1619 free(psoftlist_kernel);
1622 } else {
1623 /* kcf.conf not there in non-global zone, no policy info */
1626 * TRANSLATION_NOTE
1627 * "global" is keyword and not to be translated.
1629 cryptoerror(LOG_STDERR, gettext(
1630 "policy information for kernel software providers is "
1631 "available in the %s zone only"), "global");
1634 /* Kernel hardware providers */
1635 (void) printf(gettext("\nKernel hardware providers:\n"));
1637 * TRANSLATION_NOTE
1638 * Strictly for appearance's sake, this line should be as long as
1639 * the length of the translated text above.
1641 (void) printf(gettext("==========================\n"));
1643 if (getzoneid() != GLOBAL_ZONEID) {
1645 * TRANSLATION_NOTE
1646 * "global" is keyword and not to be translated.
1648 cryptoerror(LOG_STDERR, gettext(
1649 "policy information for kernel hardware providers is "
1650 "available in the %s zone only"), "global");
1651 return (FAILURE);
1654 /* Get the hardware provider list from kernel */
1655 if (get_dev_list(&pdevlist_kernel) != SUCCESS) {
1656 cryptoerror(LOG_STDERR, gettext(
1657 "failed to retrieve the list of hardware providers.\n"));
1658 return (FAILURE);
1661 if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) == FAILURE) {
1662 cryptoerror(LOG_ERR, "failed to retrieve the providers' "
1663 "information from file kcf.conf - %s.",
1664 _PATH_KCF_CONF);
1665 return (FAILURE);
1670 * For each hardware provider from kernel, check if it has an entry
1671 * in the config file. If it has an entry, print out the policy from
1672 * config file and remove the entry from the hardware provider list
1673 * of the config file. If it does not have an entry in the config
1674 * file, no mechanisms of it have been disabled. But, we still call
1675 * list_policy_for_hard() to account for the "random" feature.
1677 for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) {
1678 (void) snprintf(provname, sizeof (provname), "%s/%d",
1679 pdevlist_kernel->dl_devs[i].le_dev_name,
1680 pdevlist_kernel->dl_devs[i].le_dev_instance);
1682 found = B_FALSE;
1683 phead = ptr = pdevlist_conf;
1684 while (!found && ptr) {
1685 if (strcmp(ptr->pent->name, provname) == 0) {
1686 found = B_TRUE;
1687 } else {
1688 phead = ptr;
1689 ptr = ptr->next;
1693 if (found) {
1694 (void) list_policy_for_hard(ptr->pent->name,
1695 pdevlist_conf, psoftlist_conf, pdevlist_kernel);
1696 if (phead == ptr) {
1697 pdevlist_conf = pdevlist_conf->next;
1698 } else {
1699 phead->next = ptr->next;
1701 free_entry(ptr->pent);
1702 free(ptr);
1703 } else {
1704 (void) list_policy_for_hard(provname, pdevlist_conf,
1705 psoftlist_conf, pdevlist_kernel);
1710 * If there are still entries left in the pdevlist_conf list from
1711 * the config file, these providers must have been detached.
1712 * Should print out their policy information also.
1714 for (ptr = pdevlist_conf; ptr != NULL; ptr = ptr->next) {
1715 print_kef_policy(ptr->pent->name, ptr->pent, B_FALSE, B_TRUE);
1718 free_entrylist(pdevlist_conf);
1719 free_entrylist(psoftlist_conf);
1720 free(pdevlist_kernel);
1722 return (rc);