8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / cmd-crypto / cryptoadm / cryptoadm.c
blob989eae315a97376bf3e13094cbea410024d3a2a6
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 if (prov != NULL)
708 free(prov);
710 if (mecharglist != NULL)
711 free_mechlist(mecharglist);
712 return (rc);
717 * The top level function for the "cryptoadm disable" subcommand.
719 static int
720 do_disable(int argc, char **argv)
722 cryptoadm_provider_t *prov = NULL;
723 int rc = SUCCESS;
724 boolean_t auto_key_migrate_flag = B_FALSE;
726 if ((argc < 3) || (argc > 5)) {
727 usage();
728 return (ERROR_USAGE);
731 prov = get_provider(argc, argv);
732 if (prov == NULL) {
733 usage();
734 return (ERROR_USAGE);
736 if (prov->cp_type == PROV_BADNAME) {
737 return (FAILURE);
740 if ((rc = process_feature_operands(argc, argv)) != SUCCESS) {
741 goto out;
745 * If allflag or rndflag has already been set there is no reason to
746 * process mech=
748 if (prov->cp_type == METASLOT) {
749 if ((argc > 3) &&
750 (rc = process_metaslot_operands(argc, argv,
751 NULL, NULL, NULL, &auto_key_migrate_flag)) != SUCCESS) {
752 usage();
753 return (rc);
755 } else if (!allflag && !rndflag &&
756 (rc = process_mech_operands(argc, argv, B_FALSE)) != SUCCESS) {
757 return (rc);
760 switch (prov->cp_type) {
761 case METASLOT:
762 rc = disable_metaslot(mecharglist, allflag,
763 auto_key_migrate_flag);
764 break;
765 case PROV_UEF_LIB:
766 rc = disable_uef_lib(prov->cp_name, rndflag, allflag,
767 mecharglist);
768 break;
769 case PROV_KEF_SOFT:
770 if (rndflag && !allflag) {
771 if ((mecharglist = create_mech(RANDOM)) == NULL) {
772 rc = FAILURE;
773 break;
776 if (getzoneid() == GLOBAL_ZONEID) {
777 rc = disable_kef_software(prov->cp_name, rndflag,
778 allflag, mecharglist);
779 } else {
781 * TRANSLATION_NOTE
782 * "disable" could be either a literal keyword
783 * and hence not to be translated, or a verb and
784 * translatable. A choice was made to view it as
785 * a literal keyword. "global" is keyword and not
786 * to be translated.
788 cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
789 "providers is supported in the %2$s zone only"),
790 "disable", "global");
791 rc = FAILURE;
793 break;
794 case PROV_KEF_HARD:
795 if (rndflag && !allflag) {
796 if ((mecharglist = create_mech(RANDOM)) == NULL) {
797 rc = FAILURE;
798 break;
801 if (getzoneid() == GLOBAL_ZONEID) {
802 rc = disable_kef_hardware(prov->cp_name, rndflag,
803 allflag, mecharglist);
804 } else {
806 * TRANSLATION_NOTE
807 * "disable" could be either a literal keyword
808 * and hence not to be translated, or a verb and
809 * translatable. A choice was made to view it as
810 * a literal keyword. "global" is keyword and not
811 * to be translated.
813 cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
814 "providers is supported in the %2$s zone only"),
815 "disable", "global");
816 rc = FAILURE;
818 break;
819 default: /* should not come here */
820 rc = FAILURE;
821 break;
824 out:
825 free(prov);
826 if (mecharglist != NULL) {
827 free_mechlist(mecharglist);
829 return (rc);
834 * The top level function for the "cryptoadm enable" subcommand.
836 static int
837 do_enable(int argc, char **argv)
839 cryptoadm_provider_t *prov = NULL;
840 int rc = SUCCESS;
841 char *alt_token = NULL, *alt_slot = NULL;
842 boolean_t use_default = B_FALSE;
843 boolean_t auto_key_migrate_flag = B_FALSE;
845 if ((argc < 3) || (argc > 6)) {
846 usage();
847 return (ERROR_USAGE);
850 prov = get_provider(argc, argv);
851 if (prov == NULL) {
852 usage();
853 return (ERROR_USAGE);
855 if ((prov->cp_type != METASLOT) && (argc != 4)) {
856 usage();
857 return (ERROR_USAGE);
859 if (prov->cp_type == PROV_BADNAME) {
860 rc = FAILURE;
861 goto out;
865 if (prov->cp_type == METASLOT) {
866 if ((rc = process_metaslot_operands(argc, argv, &alt_token,
867 &alt_slot, &use_default, &auto_key_migrate_flag))
868 != SUCCESS) {
869 usage();
870 goto out;
872 if ((alt_slot || alt_token) && use_default) {
873 usage();
874 rc = FAILURE;
875 goto out;
877 } else {
878 if ((rc = process_feature_operands(argc, argv)) != SUCCESS) {
879 goto out;
883 * If allflag or rndflag has already been set there is
884 * no reason to process mech=
886 if (!allflag && !rndflag &&
887 (rc = process_mech_operands(argc, argv, B_FALSE))
888 != SUCCESS) {
889 goto out;
893 switch (prov->cp_type) {
894 case METASLOT:
895 rc = enable_metaslot(alt_token, alt_slot, use_default,
896 mecharglist, allflag, auto_key_migrate_flag);
897 break;
898 case PROV_UEF_LIB:
899 rc = enable_uef_lib(prov->cp_name, rndflag, allflag,
900 mecharglist);
901 break;
902 case PROV_KEF_SOFT:
903 case PROV_KEF_HARD:
904 if (rndflag && !allflag) {
905 if ((mecharglist = create_mech(RANDOM)) == NULL) {
906 rc = FAILURE;
907 break;
910 if (getzoneid() == GLOBAL_ZONEID) {
911 rc = enable_kef(prov->cp_name, rndflag, allflag,
912 mecharglist);
913 } else {
915 * TRANSLATION_NOTE
916 * "enable" could be either a literal keyword
917 * and hence not to be translated, or a verb and
918 * translatable. A choice was made to view it as
919 * a literal keyword. "global" is keyword and not
920 * to be translated.
922 cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
923 "providers is supported in the %2$s zone only"),
924 "enable", "global");
925 rc = FAILURE;
927 break;
928 default: /* should not come here */
929 rc = FAILURE;
930 break;
932 out:
933 free(prov);
934 if (mecharglist != NULL) {
935 free_mechlist(mecharglist);
937 if (alt_token != NULL) {
938 free(alt_token);
940 if (alt_slot != NULL) {
941 free(alt_slot);
943 return (rc);
949 * The top level function for the "cryptoadm install" subcommand.
951 static int
952 do_install(int argc, char **argv)
954 cryptoadm_provider_t *prov = NULL;
955 int rc;
957 if (argc < 3) {
958 usage();
959 return (ERROR_USAGE);
962 prov = get_provider(argc, argv);
963 if (prov == NULL ||
964 prov->cp_type == PROV_BADNAME || prov->cp_type == PROV_KEF_HARD) {
966 * TRANSLATION_NOTE
967 * "install" could be either a literal keyword and hence
968 * not to be translated, or a verb and translatable. A
969 * choice was made to view it as a literal keyword.
971 cryptoerror(LOG_STDERR,
972 gettext("bad provider name for %s."), "install");
973 rc = FAILURE;
974 goto out;
977 if (prov->cp_type == PROV_UEF_LIB) {
978 rc = install_uef_lib(prov->cp_name);
979 goto out;
982 /* It is the PROV_KEF_SOFT type now */
984 /* check if there are mechanism operands */
985 if (argc < 4) {
987 * TRANSLATION_NOTE
988 * "mechanism" could be either a literal keyword and hence
989 * not to be translated, or a descriptive word and
990 * translatable. A choice was made to view it as a literal
991 * keyword.
993 cryptoerror(LOG_STDERR,
994 gettext("need %s operands for installing a"
995 " kernel software provider."), "mechanism");
996 rc = ERROR_USAGE;
997 goto out;
1000 if ((rc = process_mech_operands(argc, argv, B_FALSE)) != SUCCESS) {
1001 goto out;
1004 if (allflag == B_TRUE) {
1006 * TRANSLATION_NOTE
1007 * "all", "mechanism", and "install" are all keywords and
1008 * not to be translated.
1010 cryptoerror(LOG_STDERR,
1011 gettext("can not use the %1$s keyword for %2$s "
1012 "in the %3$s subcommand."), "all", "mechanism", "install");
1013 rc = ERROR_USAGE;
1014 goto out;
1017 if (getzoneid() == GLOBAL_ZONEID) {
1018 rc = install_kef(prov->cp_name, mecharglist);
1019 } else {
1021 * TRANSLATION_NOTE
1022 * "install" could be either a literal keyword and hence
1023 * not to be translated, or a verb and translatable. A
1024 * choice was made to view it as a literal keyword.
1025 * "global" is keyword and not to be translated.
1027 cryptoerror(LOG_STDERR, gettext("%1$s for kernel providers "
1028 "is supported in the %2$s zone only"), "install", "global");
1029 rc = FAILURE;
1031 out:
1032 free(prov);
1033 return (rc);
1039 * The top level function for the "cryptoadm uninstall" subcommand.
1041 static int
1042 do_uninstall(int argc, char **argv)
1044 cryptoadm_provider_t *prov = NULL;
1045 int rc = SUCCESS;
1047 if (argc != 3) {
1048 usage();
1049 return (ERROR_USAGE);
1052 prov = get_provider(argc, argv);
1053 if (prov == NULL ||
1054 prov->cp_type == PROV_BADNAME || prov->cp_type == PROV_KEF_HARD) {
1056 * TRANSLATION_NOTE
1057 * "uninstall" could be either a literal keyword and hence
1058 * not to be translated, or a verb and translatable. A
1059 * choice was made to view it as a literal keyword.
1061 cryptoerror(LOG_STDERR,
1062 gettext("bad provider name for %s."), "uninstall");
1063 free(prov);
1064 return (FAILURE);
1067 if (prov->cp_type == PROV_UEF_LIB) {
1068 rc = uninstall_uef_lib(prov->cp_name);
1070 } else if (prov->cp_type == PROV_KEF_SOFT) {
1071 if (getzoneid() == GLOBAL_ZONEID) {
1072 /* unload and remove from kcf.conf */
1073 rc = uninstall_kef(prov->cp_name);
1074 } else {
1076 * TRANSLATION_NOTE
1077 * "uninstall" could be either a literal keyword and
1078 * hence not to be translated, or a verb and
1079 * translatable. A choice was made to view it as a
1080 * literal keyword. "global" is keyword and not to
1081 * be translated.
1083 cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
1084 "providers is supported in the %2$s zone only"),
1085 "uninstall", "global");
1086 rc = FAILURE;
1090 free(prov);
1091 return (rc);
1096 * The top level function for the "cryptoadm unload" subcommand.
1098 static int
1099 do_unload(int argc, char **argv)
1101 cryptoadm_provider_t *prov = NULL;
1102 entry_t *pent = NULL;
1103 boolean_t in_kernel = B_FALSE;
1104 int rc = SUCCESS;
1105 char *provname = NULL;
1107 if (argc != 3) {
1108 usage();
1109 return (ERROR_USAGE);
1112 /* check if it is a kernel software provider */
1113 prov = get_provider(argc, argv);
1114 if (prov == NULL) {
1115 cryptoerror(LOG_STDERR,
1116 gettext("unable to determine provider name."));
1117 goto out;
1119 provname = prov->cp_name;
1120 if (prov->cp_type != PROV_KEF_SOFT) {
1121 cryptoerror(LOG_STDERR,
1122 gettext("%s is not a valid kernel software provider."),
1123 provname);
1124 rc = FAILURE;
1125 goto out;
1128 if (getzoneid() != GLOBAL_ZONEID) {
1130 * TRANSLATION_NOTE
1131 * "unload" could be either a literal keyword and hence
1132 * not to be translated, or a verb and translatable.
1133 * A choice was made to view it as a literal keyword.
1134 * "global" is keyword and not to be translated.
1136 cryptoerror(LOG_STDERR, gettext("%1$s for kernel providers "
1137 "is supported in the %2$s zone only"), "unload", "global");
1138 rc = FAILURE;
1139 goto out;
1142 if (check_kernel_for_soft(provname, NULL, &in_kernel) == FAILURE) {
1143 cryptodebug("internal error");
1144 rc = FAILURE;
1145 goto out;
1146 } else if (in_kernel == B_FALSE) {
1147 cryptoerror(LOG_STDERR,
1148 gettext("provider %s is not loaded or does not exist."),
1149 provname);
1150 rc = FAILURE;
1151 goto out;
1154 /* Get kcf.conf entry. If none, build a new entry */
1155 if ((pent = getent_kef(provname, NULL, NULL)) == NULL) {
1156 if ((pent = create_entry(provname)) == NULL) {
1157 cryptoerror(LOG_STDERR, gettext("out of memory."));
1158 rc = FAILURE;
1159 goto out;
1163 /* If it is unloaded already, return */
1164 if (!pent->load) { /* unloaded already */
1165 cryptoerror(LOG_STDERR,
1166 gettext("failed to unload %s."), provname);
1167 rc = FAILURE;
1168 goto out;
1169 } else if (unload_kef_soft(provname) != FAILURE) {
1170 /* Mark as unloaded in kcf.conf */
1171 pent->load = B_FALSE;
1172 rc = update_kcfconf(pent, MODIFY_MODE);
1173 } else {
1174 cryptoerror(LOG_STDERR,
1175 gettext("failed to unload %s."), provname);
1176 rc = FAILURE;
1178 out:
1179 free(prov);
1180 free_entry(pent);
1181 return (rc);
1187 * The top level function for the "cryptoadm refresh" subcommand.
1189 static int
1190 do_refresh(int argc)
1192 if (argc != 2) {
1193 usage();
1194 return (ERROR_USAGE);
1197 if (getzoneid() == GLOBAL_ZONEID) {
1198 return (refresh());
1199 } else { /* non-global zone */
1201 * Note: in non-global zone, this must silently return SUCCESS
1202 * due to integration with SMF, for "svcadm refresh cryptosvc"
1204 return (SUCCESS);
1210 * The top level function for the "cryptoadm start" subcommand.
1211 * This used to start up kcfd, but now all it does is load up the
1212 * initial providers.
1214 static int
1215 do_start(int argc)
1217 if (argc != 2) {
1218 usage();
1219 return (ERROR_USAGE);
1222 return (do_refresh(argc));
1226 * The top level function for the "cryptoadm stop" subcommand.
1227 * This no longer does anything useful, but we leave it here
1228 * for compatibility.
1230 static int
1231 do_stop(int argc)
1233 if (argc != 2) {
1234 usage();
1235 return (ERROR_USAGE);
1238 return (SUCCESS);
1244 * Print a list all the the providers.
1245 * Called for "cryptoadm list" or "cryptoadm list -v" (no -m or -p).
1247 static int
1248 list_simple_for_all(boolean_t verbose)
1250 uentrylist_t *pliblist = NULL;
1251 uentrylist_t *plibptr = NULL;
1252 entry_t *pent = NULL;
1253 crypto_get_dev_list_t *pdevlist_kernel = NULL;
1254 int rc = SUCCESS;
1255 int i;
1257 /* get user-level providers */
1258 (void) printf(gettext("\nUser-level providers:\n"));
1259 if (get_pkcs11conf_info(&pliblist) != SUCCESS) {
1260 cryptoerror(LOG_STDERR, gettext(
1261 "failed to retrieve the list of user-level providers."));
1262 rc = FAILURE;
1265 for (plibptr = pliblist; plibptr != NULL; plibptr = plibptr->next) {
1266 /* skip metaslot and fips-140 entry */
1267 if ((strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) &&
1268 (strcmp(plibptr->puent->name, FIPS_KEYWORD) != 0)) {
1269 (void) printf(gettext("Provider: %s\n"),
1270 plibptr->puent->name);
1271 if (verbose) {
1272 (void) list_mechlist_for_lib(
1273 plibptr->puent->name, mecharglist, NULL,
1274 B_FALSE, verbose, B_FALSE);
1275 (void) printf("\n");
1279 free_uentrylist(pliblist);
1281 /* get kernel software providers */
1282 (void) printf(gettext("\nKernel software providers:\n"));
1284 if (getzoneid() == GLOBAL_ZONEID) {
1285 /* get kernel software providers from kernel ioctl */
1286 crypto_get_soft_list_t *psoftlist_kernel = NULL;
1287 uint_t sl_soft_count;
1288 char *psoftname;
1289 entrylist_t *pdevlist_conf = NULL;
1290 entrylist_t *psoftlist_conf = NULL;
1292 if (get_soft_list(&psoftlist_kernel) == FAILURE) {
1293 cryptoerror(LOG_ERR, gettext("Failed to retrieve the "
1294 "software provider list from kernel."));
1295 rc = FAILURE;
1296 } else {
1297 sl_soft_count = psoftlist_kernel->sl_soft_count;
1299 if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf)
1300 == FAILURE) {
1301 cryptoerror(LOG_ERR,
1302 "failed to retrieve the providers' "
1303 "information from file kcf.conf - %s.",
1304 _PATH_KCF_CONF);
1305 free(psoftlist_kernel);
1306 rc = FAILURE;
1307 } else {
1309 for (i = 0,
1310 psoftname = psoftlist_kernel->sl_soft_names;
1311 i < sl_soft_count;
1312 ++i, psoftname += strlen(psoftname) + 1) {
1313 pent = getent_kef(psoftname,
1314 pdevlist_conf, psoftlist_conf);
1315 (void) printf("\t%s%s\n", psoftname,
1316 (pent == NULL) || (pent->load) ?
1317 "" : gettext(" (inactive)"));
1319 free_entrylist(pdevlist_conf);
1320 free_entrylist(psoftlist_conf);
1322 free(psoftlist_kernel);
1325 } else {
1326 /* kcf.conf not there in non-global zone, use /dev/cryptoadm */
1327 entrylist_t *pdevlist_zone = NULL;
1328 entrylist_t *psoftlist_zone = NULL;
1329 entrylist_t *ptr;
1331 if (get_admindev_info(&pdevlist_zone, &psoftlist_zone) !=
1332 SUCCESS) {
1333 cryptoerror(LOG_STDERR,
1334 gettext("failed to retrieve the "
1335 "list of kernel software providers.\n"));
1336 rc = FAILURE;
1339 ptr = psoftlist_zone;
1340 while (ptr != NULL) {
1341 (void) printf("\t%s\n", ptr->pent->name);
1342 ptr = ptr->next;
1345 free_entrylist(pdevlist_zone);
1346 free_entrylist(psoftlist_zone);
1349 /* get kernel hardware providers */
1350 (void) printf(gettext("\nKernel hardware providers:\n"));
1351 if (get_dev_list(&pdevlist_kernel) == FAILURE) {
1352 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1353 "the list of kernel hardware providers.\n"));
1354 rc = FAILURE;
1355 } else {
1356 for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) {
1357 (void) printf("\t%s/%d\n",
1358 pdevlist_kernel->dl_devs[i].le_dev_name,
1359 pdevlist_kernel->dl_devs[i].le_dev_instance);
1362 free(pdevlist_kernel);
1364 return (rc);
1370 * List all the providers. And for each provider, list the mechanism list.
1371 * Called for "cryptoadm list -m" or "cryptoadm list -mv" .
1373 static int
1374 list_mechlist_for_all(boolean_t verbose)
1376 crypto_get_dev_list_t *pdevlist_kernel = NULL;
1377 uentrylist_t *pliblist = NULL;
1378 uentrylist_t *plibptr = NULL;
1379 entry_t *pent = NULL;
1380 mechlist_t *pmechlist = NULL;
1381 char provname[MAXNAMELEN];
1382 char devname[MAXNAMELEN];
1383 int inst_num;
1384 int count;
1385 int i;
1386 int rv;
1387 int rc = SUCCESS;
1389 /* get user-level providers */
1390 (void) printf(gettext("\nUser-level providers:\n"));
1392 * TRANSLATION_NOTE
1393 * Strictly for appearance's sake, this line should be as long as
1394 * the length of the translated text above.
1396 (void) printf(gettext("=====================\n"));
1397 if (get_pkcs11conf_info(&pliblist) != SUCCESS) {
1398 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1399 "the list of user-level providers.\n"));
1400 rc = FAILURE;
1403 plibptr = pliblist;
1404 while (plibptr != NULL) {
1405 /* skip metaslot and fips-140 entry */
1406 if ((strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) &&
1407 (strcmp(plibptr->puent->name, FIPS_KEYWORD) != 0)) {
1408 (void) printf(gettext("\nProvider: %s\n"),
1409 plibptr->puent->name);
1410 rv = list_mechlist_for_lib(plibptr->puent->name,
1411 mecharglist, NULL, B_FALSE, verbose, B_TRUE);
1412 if (rv == FAILURE) {
1413 rc = FAILURE;
1416 plibptr = plibptr->next;
1418 free_uentrylist(pliblist);
1420 /* get kernel software providers */
1421 (void) printf(gettext("\nKernel software providers:\n"));
1424 * TRANSLATION_NOTE
1425 * Strictly for appearance's sake, this line should be as long as
1426 * the length of the translated text above.
1428 (void) printf(gettext("==========================\n"));
1429 if (getzoneid() == GLOBAL_ZONEID) {
1430 /* get kernel software providers from kernel ioctl */
1431 crypto_get_soft_list_t *psoftlist_kernel = NULL;
1432 uint_t sl_soft_count;
1433 char *psoftname;
1434 int i;
1435 entrylist_t *pdevlist_conf = NULL;
1436 entrylist_t *psoftlist_conf = NULL;
1438 if (get_soft_list(&psoftlist_kernel) == FAILURE) {
1439 cryptoerror(LOG_ERR, gettext("Failed to retrieve the "
1440 "software provider list from kernel."));
1441 return (FAILURE);
1443 sl_soft_count = psoftlist_kernel->sl_soft_count;
1445 if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf)
1446 == FAILURE) {
1447 cryptoerror(LOG_ERR,
1448 "failed to retrieve the providers' "
1449 "information from file kcf.conf - %s.",
1450 _PATH_KCF_CONF);
1451 free(psoftlist_kernel);
1452 return (FAILURE);
1455 for (i = 0, psoftname = psoftlist_kernel->sl_soft_names;
1456 i < sl_soft_count;
1457 ++i, psoftname += strlen(psoftname) + 1) {
1458 pent = getent_kef(psoftname, pdevlist_conf,
1459 psoftlist_conf);
1460 if ((pent == NULL) || (pent->load)) {
1461 rv = list_mechlist_for_soft(psoftname,
1462 NULL, NULL);
1463 if (rv == FAILURE) {
1464 rc = FAILURE;
1466 } else {
1467 (void) printf(gettext("%s: (inactive)\n"),
1468 psoftname);
1472 free(psoftlist_kernel);
1473 free_entrylist(pdevlist_conf);
1474 free_entrylist(psoftlist_conf);
1476 } else {
1477 /* kcf.conf not there in non-global zone, use /dev/cryptoadm */
1478 entrylist_t *pdevlist_zone = NULL;
1479 entrylist_t *psoftlist_zone = NULL;
1480 entrylist_t *ptr;
1482 if (get_admindev_info(&pdevlist_zone, &psoftlist_zone) !=
1483 SUCCESS) {
1484 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1485 "the list of kernel software providers.\n"));
1486 rc = FAILURE;
1489 for (ptr = psoftlist_zone; ptr != NULL; ptr = ptr->next) {
1490 rv = list_mechlist_for_soft(ptr->pent->name,
1491 pdevlist_zone, psoftlist_zone);
1492 if (rv == FAILURE) {
1493 (void) printf(gettext(
1494 "%s: failed to get the mechanism list.\n"),
1495 ptr->pent->name);
1496 rc = FAILURE;
1500 free_entrylist(pdevlist_zone);
1501 free_entrylist(psoftlist_zone);
1504 /* Get kernel hardware providers and their mechanism lists */
1505 (void) printf(gettext("\nKernel hardware providers:\n"));
1507 * TRANSLATION_NOTE
1508 * Strictly for appearance's sake, this line should be as long as
1509 * the length of the translated text above.
1511 (void) printf(gettext("==========================\n"));
1512 if (get_dev_list(&pdevlist_kernel) != SUCCESS) {
1513 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1514 "the list of hardware providers.\n"));
1515 return (FAILURE);
1518 for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) {
1519 (void) strlcpy(devname,
1520 pdevlist_kernel->dl_devs[i].le_dev_name, MAXNAMELEN);
1521 inst_num = pdevlist_kernel->dl_devs[i].le_dev_instance;
1522 count = pdevlist_kernel->dl_devs[i].le_mechanism_count;
1523 (void) snprintf(provname, sizeof (provname), "%s/%d", devname,
1524 inst_num);
1525 if (get_dev_info(devname, inst_num, count, &pmechlist) ==
1526 SUCCESS) {
1527 (void) filter_mechlist(&pmechlist, RANDOM);
1528 print_mechlist(provname, pmechlist);
1529 free_mechlist(pmechlist);
1530 } else {
1531 (void) printf(gettext("%s: failed to get the mechanism"
1532 " list.\n"), provname);
1533 rc = FAILURE;
1536 free(pdevlist_kernel);
1537 return (rc);
1542 * List all the providers. And for each provider, list the policy information.
1543 * Called for "cryptoadm list -p".
1545 static int
1546 list_policy_for_all(void)
1548 crypto_get_dev_list_t *pdevlist_kernel = NULL;
1549 uentrylist_t *pliblist = NULL;
1550 entrylist_t *pdevlist_conf = NULL;
1551 entrylist_t *psoftlist_conf = NULL;
1552 entrylist_t *ptr = NULL;
1553 entrylist_t *phead = NULL;
1554 boolean_t found = B_FALSE;
1555 char provname[MAXNAMELEN];
1556 int i;
1557 int rc = SUCCESS;
1559 /* Get user-level providers */
1560 (void) printf(gettext("\nUser-level providers:\n"));
1562 * TRANSLATION_NOTE
1563 * Strictly for appearance's sake, this line should be as long as
1564 * the length of the translated text above.
1566 (void) printf(gettext("=====================\n"));
1567 if (get_pkcs11conf_info(&pliblist) == FAILURE) {
1568 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1569 "the list of user-level providers.\n"));
1570 rc = FAILURE;
1571 } else {
1572 uentrylist_t *plibptr = pliblist;
1574 while (plibptr != NULL) {
1575 /* skip metaslot and fips-140 entry */
1576 if ((strcmp(plibptr->puent->name,
1577 METASLOT_KEYWORD) != 0) &&
1578 (strcmp(plibptr->puent->name,
1579 FIPS_KEYWORD) != 0)) {
1580 if (print_uef_policy(plibptr->puent)
1581 == FAILURE) {
1582 rc = FAILURE;
1585 plibptr = plibptr->next;
1587 free_uentrylist(pliblist);
1590 /* kernel software providers */
1591 (void) printf(gettext("\nKernel software providers:\n"));
1593 * TRANSLATION_NOTE
1594 * Strictly for appearance's sake, this line should be as long as
1595 * the length of the translated text above.
1597 (void) printf(gettext("==========================\n"));
1599 /* Get all entries from the kernel */
1600 if (getzoneid() == GLOBAL_ZONEID) {
1601 /* get kernel software providers from kernel ioctl */
1602 crypto_get_soft_list_t *psoftlist_kernel = NULL;
1603 uint_t sl_soft_count;
1604 char *psoftname;
1605 int i;
1607 if (get_soft_list(&psoftlist_kernel) == FAILURE) {
1608 cryptoerror(LOG_ERR, gettext("Failed to retrieve the "
1609 "software provider list from kernel."));
1610 rc = FAILURE;
1611 } else {
1612 sl_soft_count = psoftlist_kernel->sl_soft_count;
1614 for (i = 0, psoftname = psoftlist_kernel->sl_soft_names;
1615 i < sl_soft_count;
1616 ++i, psoftname += strlen(psoftname) + 1) {
1617 (void) list_policy_for_soft(psoftname,
1618 pdevlist_conf, psoftlist_conf);
1620 free(psoftlist_kernel);
1623 } else {
1624 /* kcf.conf not there in non-global zone, no policy info */
1627 * TRANSLATION_NOTE
1628 * "global" is keyword and not to be translated.
1630 cryptoerror(LOG_STDERR, gettext(
1631 "policy information for kernel software providers is "
1632 "available in the %s zone only"), "global");
1635 /* Kernel hardware providers */
1636 (void) printf(gettext("\nKernel hardware providers:\n"));
1638 * TRANSLATION_NOTE
1639 * Strictly for appearance's sake, this line should be as long as
1640 * the length of the translated text above.
1642 (void) printf(gettext("==========================\n"));
1644 if (getzoneid() != GLOBAL_ZONEID) {
1646 * TRANSLATION_NOTE
1647 * "global" is keyword and not to be translated.
1649 cryptoerror(LOG_STDERR, gettext(
1650 "policy information for kernel hardware providers is "
1651 "available in the %s zone only"), "global");
1652 return (FAILURE);
1655 /* Get the hardware provider list from kernel */
1656 if (get_dev_list(&pdevlist_kernel) != SUCCESS) {
1657 cryptoerror(LOG_STDERR, gettext(
1658 "failed to retrieve the list of hardware providers.\n"));
1659 return (FAILURE);
1662 if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) == FAILURE) {
1663 cryptoerror(LOG_ERR, "failed to retrieve the providers' "
1664 "information from file kcf.conf - %s.",
1665 _PATH_KCF_CONF);
1666 return (FAILURE);
1671 * For each hardware provider from kernel, check if it has an entry
1672 * in the config file. If it has an entry, print out the policy from
1673 * config file and remove the entry from the hardware provider list
1674 * of the config file. If it does not have an entry in the config
1675 * file, no mechanisms of it have been disabled. But, we still call
1676 * list_policy_for_hard() to account for the "random" feature.
1678 for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) {
1679 (void) snprintf(provname, sizeof (provname), "%s/%d",
1680 pdevlist_kernel->dl_devs[i].le_dev_name,
1681 pdevlist_kernel->dl_devs[i].le_dev_instance);
1683 found = B_FALSE;
1684 phead = ptr = pdevlist_conf;
1685 while (!found && ptr) {
1686 if (strcmp(ptr->pent->name, provname) == 0) {
1687 found = B_TRUE;
1688 } else {
1689 phead = ptr;
1690 ptr = ptr->next;
1694 if (found) {
1695 (void) list_policy_for_hard(ptr->pent->name,
1696 pdevlist_conf, psoftlist_conf, pdevlist_kernel);
1697 if (phead == ptr) {
1698 pdevlist_conf = pdevlist_conf->next;
1699 } else {
1700 phead->next = ptr->next;
1702 free_entry(ptr->pent);
1703 free(ptr);
1704 } else {
1705 (void) list_policy_for_hard(provname, pdevlist_conf,
1706 psoftlist_conf, pdevlist_kernel);
1711 * If there are still entries left in the pdevlist_conf list from
1712 * the config file, these providers must have been detached.
1713 * Should print out their policy information also.
1715 for (ptr = pdevlist_conf; ptr != NULL; ptr = ptr->next) {
1716 print_kef_policy(ptr->pent->name, ptr->pent, B_FALSE, B_TRUE);
1719 free_entrylist(pdevlist_conf);
1720 free_entrylist(psoftlist_conf);
1721 free(pdevlist_kernel);
1723 return (rc);