Print this page
6414175 kcf.conf's supportedlist not providing much usefulness


 231         (void) fprintf(stderr,
 232             "  cryptoadm install provider=<%s> [mechanism=<%s>]\n",
 233             gettext("provider-name"), gettext("mechanism-list"));
 234         (void) fprintf(stderr,
 235             "  cryptoadm uninstall provider=<%s>\n",
 236             gettext("provider-name"));
 237         (void) fprintf(stderr,
 238             "  cryptoadm unload provider=<%s>\n",
 239             gettext("provider-name"));
 240         (void) fprintf(stderr,
 241             "  cryptoadm refresh\n"
 242             "  cryptoadm start\n"
 243             "  cryptoadm stop\n"
 244             "  cryptoadm --help\n");
 245 }
 246 
 247 
 248 /*
 249  * Get the provider type.  This function returns
 250  * - PROV_UEF_LIB if provname contains an absolute path name
 251  * - PROV_KEF_SOFT if provname is a base name only
 252  * - PROV_KEF_HARD if provname contains one slash only and the slash is not
 253  *      the 1st character.
 254  * - PROV_BADNAME otherwise.
 255  */
 256 static int
 257 get_provider_type(char *provname)
 258 {
 259         char *pslash1;
 260         char *pslash2;
 261 
 262         if (provname == NULL) {
 263                 return (FAILURE);
 264         }
 265 
 266         if (provname[0] == '/') {
 267                 return (PROV_UEF_LIB);
 268         } else if ((pslash1 = strchr(provname, SEP_SLASH)) == NULL) {
 269                 /* no slash */
 270                 return (PROV_KEF_SOFT);
 271         } else {
 272                 pslash2 = strrchr(provname, SEP_SLASH);
 273                 if (pslash1 == pslash2) {


 513                         } else {
 514                                 pcur->next = pmech;
 515                                 pcur = pmech;
 516                         }
 517                 }
 518         } while ((curmech = strtok(NULL, ",")) != NULL);
 519 
 520         if (rc == FAILURE) {
 521                 cryptoerror(LOG_STDERR, gettext("out of memory."));
 522                 free_mechlist(phead);
 523         } else {
 524                 mecharglist = phead;
 525                 rc = SUCCESS;
 526         }
 527         return (rc);
 528 }
 529 
 530 
 531 
 532 /*
 533  * The top level function for the list subcommand and options.
 534  */
 535 static int
 536 do_list(int argc, char **argv)
 537 {
 538         boolean_t       mflag = B_FALSE;
 539         boolean_t       pflag = B_FALSE;
 540         boolean_t       vflag = B_FALSE;
 541         char    ch;
 542         cryptoadm_provider_t    *prov = NULL;
 543         int     rc = SUCCESS;
 544 
 545         argc -= 1;
 546         argv += 1;
 547 
 548         if (argc == 1) {
 549                 rc = list_simple_for_all(B_FALSE);
 550                 goto out;
 551         }
 552 
 553         /*
 554          * [-v] [-m] [-p] [provider=<>] [mechanism=<>]
 555          */
 556         if (argc > 5) {
 557                 usage();
 558                 return (rc);
 559         }
 560 
 561         while ((ch = getopt(argc, argv, "mpv")) != EOF) {
 562                 switch (ch) {
 563                 case 'm':
 564                         mflag = B_TRUE;
 565                         if (pflag) {
 566                                 rc = ERROR_USAGE;
 567                         }
 568                         break;
 569                 case 'p':
 570                         pflag = B_TRUE;
 571                         if (mflag || vflag) {
 572                                 rc = ERROR_USAGE;
 573                         }
 574                         break;


 614                         rc = list_simple_for_all(vflag);
 615                 }
 616         } else if (prov->cp_type == METASLOT) {
 617                 if ((!mflag) && (!vflag) && (!pflag)) {
 618                         /* no flag is specified, just list metaslot status */
 619                         rc = list_metaslot_info(mflag, vflag, mecharglist);
 620                 } else if (mflag || vflag) {
 621                         rc = list_metaslot_info(mflag, vflag, mecharglist);
 622                 } else if (pflag) {
 623                         rc = list_metaslot_policy();
 624                 } else {
 625                         /* error message */
 626                         usage();
 627                         rc = ERROR_USAGE;
 628                 }
 629         } else if (prov->cp_type == PROV_BADNAME) {
 630                 usage();
 631                 rc = ERROR_USAGE;
 632                 goto out;
 633         } else { /* do the listing for a provider only */


 634                 if (mflag || vflag) {
 635                         if (vflag)
 636                                 (void) printf(gettext("Provider: %s\n"),
 637                                         prov->cp_name);
 638                         switch (prov->cp_type) {
 639                         case PROV_UEF_LIB:
 640                                 rc = list_mechlist_for_lib(prov->cp_name,
 641                                         mecharglist, NULL, B_FALSE,
 642                                         vflag, mflag);
 643                                 break;
 644                         case PROV_KEF_SOFT:
 645                                 rc = list_mechlist_for_soft(prov->cp_name);

 646                                 break;
 647                         case PROV_KEF_HARD:
 648                                 rc = list_mechlist_for_hard(prov->cp_name);
 649                                 break;
 650                         default: /* should not come here */
 651                                 rc = FAILURE;
 652                                 break;
 653                         }
 654                 } else if (pflag) {
 655                         switch (prov->cp_type) {
 656                         case PROV_UEF_LIB:
 657                                 rc = list_policy_for_lib(prov->cp_name);
 658                                 break;
 659                         case PROV_KEF_SOFT:
 660                                 if (getzoneid() == GLOBAL_ZONEID) {
 661                                         rc = list_policy_for_soft(
 662                                             prov->cp_name);
 663                                 } else {
 664                                         /*
 665                                          * TRANSLATION_NOTE
 666                                          * "global" is keyword and not to
 667                                          * be translated.
 668                                          */
 669                                         cryptoerror(LOG_STDERR, gettext(
 670                                             "policy information for kernel "
 671                                             "providers is available "
 672                                             "in the %s zone only"), "global");
 673                                         rc = FAILURE;
 674                                 }
 675                                 break;
 676                         case PROV_KEF_HARD:
 677                                 if (getzoneid() == GLOBAL_ZONEID) {
 678                                         rc = list_policy_for_hard(
 679                                             prov->cp_name);
 680                                 } else {
 681                                         /*
 682                                          * TRANSLATION_NOTE
 683                                          * "global" is keyword and not to
 684                                          * be translated.
 685                                          */
 686                                         cryptoerror(LOG_STDERR, gettext(
 687                                             "policy information for kernel "
 688                                             "providers is available "
 689                                             "in the %s zone only"), "global");
 690                                         rc = FAILURE;
 691                                 }
 692 
 693                                 break;
 694                         default: /* should not come here */
 695                                 rc = FAILURE;
 696                                 break;
 697                         }
 698                 } else {
 699                         /* error message */
 700                         usage();
 701                         rc = ERROR_USAGE;
 702                 }
 703         }
 704 
 705 out:
 706         if (prov != NULL)
 707                 free(prov);
 708 
 709         if (mecharglist != NULL)
 710                 free_mechlist(mecharglist);
 711         return (rc);
 712 }
 713 
 714 
 715 /*
 716  * The top level function for the disable subcommand.
 717  */
 718 static int
 719 do_disable(int argc, char **argv)
 720 {
 721         cryptoadm_provider_t    *prov = NULL;
 722         int     rc = SUCCESS;
 723         boolean_t auto_key_migrate_flag = B_FALSE;
 724 
 725         if ((argc < 3) || (argc > 5)) {
 726                 usage();
 727                 return (ERROR_USAGE);
 728         }
 729 
 730         prov = get_provider(argc, argv);
 731         if (prov == NULL) {
 732                 usage();
 733                 return (ERROR_USAGE);
 734         }
 735         if (prov->cp_type == PROV_BADNAME) {
 736                 return (FAILURE);


 813                             "providers is supported in the %2$s zone only"),
 814                             "disable", "global");
 815                         rc = FAILURE;
 816                 }
 817                 break;
 818         default: /* should not come here */
 819                 rc = FAILURE;
 820                 break;
 821         }
 822 
 823 out:
 824         free(prov);
 825         if (mecharglist != NULL) {
 826                 free_mechlist(mecharglist);
 827         }
 828         return (rc);
 829 }
 830 
 831 
 832 /*
 833  * The top level function fo the enable subcommand.
 834  */
 835 static int
 836 do_enable(int argc, char **argv)
 837 {
 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, auto_key_migrate_flag = B_FALSE;

 842 
 843         if ((argc < 3) || (argc > 6)) {
 844                 usage();
 845                 return (ERROR_USAGE);
 846         }
 847 
 848         prov = get_provider(argc, argv);
 849         if (prov == NULL) {
 850                 usage();
 851                 return (ERROR_USAGE);
 852         }
 853         if ((prov->cp_type != METASLOT) && (argc != 4)) {
 854                 usage();
 855                 return (ERROR_USAGE);
 856         }
 857         if (prov->cp_type == PROV_BADNAME) {
 858                 rc = FAILURE;
 859                 goto out;
 860         }
 861 


 927                 rc = FAILURE;
 928                 break;
 929         }
 930 out:
 931         free(prov);
 932         if (mecharglist != NULL) {
 933                 free_mechlist(mecharglist);
 934         }
 935         if (alt_token != NULL) {
 936                 free(alt_token);
 937         }
 938         if (alt_slot != NULL) {
 939                 free(alt_slot);
 940         }
 941         return (rc);
 942 }
 943 
 944 
 945 
 946 /*
 947  * The top level function fo the install subcommand.
 948  */
 949 static int
 950 do_install(int argc, char **argv)
 951 {
 952         cryptoadm_provider_t    *prov = NULL;
 953         int     rc;
 954 
 955         if (argc < 3) {
 956                 usage();
 957                 return (ERROR_USAGE);
 958         }
 959 
 960         prov = get_provider(argc, argv);
 961         if (prov == NULL ||
 962             prov->cp_type == PROV_BADNAME || prov->cp_type == PROV_KEF_HARD) {
 963                 /*
 964                  * TRANSLATION_NOTE
 965                  * "install" could be either a literal keyword and hence
 966                  * not to be translated, or a verb and translatable.  A
 967                  * choice was made to view it as a literal keyword.


1017         } else {
1018                 /*
1019                  * TRANSLATION_NOTE
1020                  * "install" could be either a literal keyword and hence
1021                  * not to be translated, or a verb and translatable.  A
1022                  * choice was made to view it as a literal keyword.
1023                  * "global" is keyword and not to be translated.
1024                  */
1025                 cryptoerror(LOG_STDERR, gettext("%1$s for kernel providers "
1026                     "is supported in the %2$s zone only"), "install", "global");
1027                 rc = FAILURE;
1028         }
1029 out:
1030         free(prov);
1031         return (rc);
1032 }
1033 
1034 
1035 
1036 /*
1037  * The top level function for the uninstall subcommand.
1038  */
1039 static int
1040 do_uninstall(int argc, char **argv)
1041 {
1042         cryptoadm_provider_t    *prov = NULL;
1043         int     rc = SUCCESS;
1044 
1045         if (argc != 3) {
1046                 usage();
1047                 return (ERROR_USAGE);
1048         }
1049 
1050         prov = get_provider(argc, argv);
1051         if (prov == NULL ||
1052             prov->cp_type == PROV_BADNAME || prov->cp_type == PROV_KEF_HARD) {
1053                 /*
1054                  * TRANSLATION_NOTE
1055                  * "uninstall" could be either a literal keyword and hence
1056                  * not to be translated, or a verb and translatable.  A
1057                  * choice was made to view it as a literal keyword.
1058                  */
1059                 cryptoerror(LOG_STDERR,
1060                     gettext("bad provider name for %s."), "uninstall");
1061                 free(prov);
1062                 return (FAILURE);
1063         }
1064 
1065         if (prov->cp_type == PROV_UEF_LIB) {
1066                 rc = uninstall_uef_lib(prov->cp_name);

1067         } else if (prov->cp_type == PROV_KEF_SOFT) {
1068                 if (getzoneid() == GLOBAL_ZONEID) {

1069                         rc = uninstall_kef(prov->cp_name);
1070                 } else {
1071                         /*
1072                          * TRANSLATION_NOTE
1073                          * "uninstall" could be either a literal keyword and
1074                          * hence not to be translated, or a verb and
1075                          * translatable.  A choice was made to view it as a
1076                          * literal keyword.  "global" is keyword and not to
1077                          * be translated.
1078                          */
1079                         cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
1080                             "providers is supported in the %2$s zone only"),
1081                             "uninstall", "global");
1082                         rc = FAILURE;
1083                 }
1084         }
1085 
1086         free(prov);
1087         return (rc);
1088 }
1089 
1090 
1091 /*
1092  * The top level function for the unload subcommand.
1093  */
1094 static int
1095 do_unload(int argc, char **argv)
1096 {
1097         cryptoadm_provider_t    *prov = NULL;
1098         entry_t *pent;
1099         boolean_t       is_active;
1100         int rc = SUCCESS;

1101 
1102         if (argc != 3) {
1103                 usage();
1104                 return (ERROR_USAGE);
1105         }
1106 
1107         /* check if it is a kernel software provider */
1108         prov = get_provider(argc, argv);
1109         if (prov == NULL) {
1110                 cryptoerror(LOG_STDERR,
1111                     gettext("unable to determine provider name."));
1112                 goto out;
1113         }

1114         if (prov->cp_type != PROV_KEF_SOFT) {
1115                 cryptoerror(LOG_STDERR,
1116                     gettext("%s is not a valid kernel software provider."),
1117                     prov->cp_name);
1118                 rc = FAILURE;
1119                 goto out;
1120         }
1121 
1122         if (getzoneid() != GLOBAL_ZONEID) {
1123                 /*
1124                  * TRANSLATION_NOTE
1125                  * "unload" could be either a literal keyword and hence
1126                  * not to be translated, or a verb and translatable.
1127                  * A choice was made to view it as a literal keyword.
1128                  * "global" is keyword and not to be translated.
1129                  */
1130                 cryptoerror(LOG_STDERR, gettext("%1$s for kernel providers "
1131                     "is supported in the %2$s zone only"), "unload", "global");
1132                 rc = FAILURE;
1133                 goto out;
1134         }
1135 
1136         /* Check if it is in the kcf.conf file first */
1137         if ((pent = getent_kef(prov->cp_name)) == NULL) {



1138                 cryptoerror(LOG_STDERR,
1139                     gettext("provider %s does not exist."), prov->cp_name);

1140                 rc = FAILURE;
1141                 goto out;
1142         }
1143         free_entry(pent);
1144 
1145         /* If it is unloaded already, return  */
1146         if (check_active_for_soft(prov->cp_name, &is_active) == FAILURE) {
1147                 cryptodebug("internal error");
1148                 cryptoerror(LOG_STDERR,
1149                     gettext("failed to unload %s."), prov->cp_name);
1150                 rc = FAILURE;
1151                 goto out;
1152         }

1153 
1154         if (is_active == B_FALSE) { /* unloaded already */
1155                 rc = SUCCESS;
1156                 goto out;
1157         } else if (unload_kef_soft(prov->cp_name, B_TRUE) == FAILURE) {
1158                 cryptoerror(LOG_STDERR,
1159                     gettext("failed to unload %s."), prov->cp_name);
1160                 rc = FAILURE;





1161         } else {
1162                 rc = SUCCESS;


1163         }
1164 out:
1165         free(prov);

1166         return (rc);
1167 }
1168 
1169 
1170 
1171 /*
1172  * The top level function for the refresh subcommand.
1173  */
1174 static int
1175 do_refresh(int argc)
1176 {
1177         if (argc != 2) {
1178                 usage();
1179                 return (ERROR_USAGE);
1180         }
1181 



1182         /*
1183          * Note:  in non-global zone, this must silently return SUCCESS
1184          * due to integration with SMF, for "svcadm refresh cryptosvc"
1185          */
1186         if (getzoneid() != GLOBAL_ZONEID)
1187                 return (SUCCESS);
1188 
1189         return (refresh());
1190 }
1191 
1192 
1193 /*
1194  * The top level function for the start subcommand.
1195  */
1196 static int
1197 do_start(int argc)
1198 {
1199         int ret;
1200 
1201         if (argc != 2) {
1202                 usage();
1203                 return (ERROR_USAGE);
1204         }
1205 
1206         ret = do_refresh(argc);
1207         if (ret != SUCCESS)
1208                 return (ret);
1209 
1210         return (start_daemon());
1211 }
1212 
1213 /*
1214  * The top level function for the stop subcommand.
1215  */
1216 static int
1217 do_stop(int argc)
1218 {
1219         if (argc != 2) {
1220                 usage();
1221                 return (ERROR_USAGE);
1222         }
1223 
1224         return (stop_daemon());
1225 }
1226 
1227 
1228 
1229 /*
1230  * List all the providers.

1231  */
1232 static int
1233 list_simple_for_all(boolean_t verbose)
1234 {
1235         uentrylist_t    *pliblist;
1236         uentrylist_t    *plibptr;
1237         entrylist_t     *pdevlist_conf;
1238         entrylist_t     *psoftlist_conf;
1239         entrylist_t     *pdevlist_zone;
1240         entrylist_t     *psoftlist_zone;
1241         entrylist_t     *ptr;
1242         crypto_get_dev_list_t   *pdevlist_kernel = NULL;
1243         boolean_t       is_active;
1244         int     ru = SUCCESS;
1245         int     rs = SUCCESS;
1246         int     rd = SUCCESS;
1247         int     i;
1248 
1249         /* get user-level providers */
1250         (void) printf(gettext("\nUser-level providers:\n"));
1251         if (get_pkcs11conf_info(&pliblist) != SUCCESS) {
1252                 cryptoerror(LOG_STDERR, gettext(
1253                     "failed to retrieve the list of user-level providers."));
1254                 ru = FAILURE;
1255         }
1256         plibptr = pliblist;
1257         while (plibptr != NULL) {
1258                 if (strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) {
1259                         (void) printf(gettext("Provider: %s\n"),
1260                             plibptr->puent->name);
1261                         if (verbose) {
1262                                 (void) list_mechlist_for_lib(
1263                                     plibptr->puent->name, mecharglist, NULL,
1264                                     B_FALSE, verbose, B_FALSE);
1265                                 (void) printf("\n");
1266                         }
1267                 }
1268                 plibptr = plibptr->next;
1269         }
1270         free_uentrylist(pliblist);
1271 
1272         /* get kernel software providers */
1273         (void) printf(gettext("\nKernel software providers:\n"));
1274 
1275         if (getzoneid() == GLOBAL_ZONEID) {
1276                 /* use kcf.conf for kernel software providers in global zone */
1277                 pdevlist_conf = NULL;
1278                 psoftlist_conf = NULL;



1279 
1280                 if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) !=
1281                     SUCCESS) {
1282                         cryptoerror(LOG_STDERR,
1283                             gettext("failed to retrieve the "
1284                             "list of kernel software providers.\n"));
1285                         rs = FAILURE;
1286                 }
1287 
1288                 ptr = psoftlist_conf;
1289                 while (ptr != NULL) {
1290                         if (check_active_for_soft(ptr->pent->name, &is_active)
1291                             == FAILURE) {
1292                                 rs = FAILURE;
1293                                 cryptoerror(LOG_STDERR, gettext("failed to "
1294                                     "get the state of a kernel software "
1295                                     "providers.\n"));
1296                                 break;
1297                         }
1298 
1299                         (void) printf("\t%s", ptr->pent->name);
1300                         if (is_active == B_FALSE) {
1301                                 (void) printf(gettext(" (inactive)\n"));
1302                         } else {
1303                                 (void) printf("\n");
1304                         }
1305                         ptr = ptr->next;
1306                 }
1307 










1308                 free_entrylist(pdevlist_conf);
1309                 free_entrylist(psoftlist_conf);




1310         } else {
1311                 /* kcf.conf not there in non-global zone, use /dev/cryptoadm */
1312                 pdevlist_zone = NULL;
1313                 psoftlist_zone = NULL;

1314 
1315                 if (get_admindev_info(&pdevlist_zone, &psoftlist_zone) !=
1316                     SUCCESS) {
1317                         cryptoerror(LOG_STDERR,
1318                             gettext("failed to retrieve the "
1319                             "list of kernel software providers.\n"));
1320                         rs = FAILURE;
1321                 }
1322 
1323                 ptr = psoftlist_zone;
1324                 while (ptr != NULL) {
1325                         (void) printf("\t%s\n", ptr->pent->name);
1326                         ptr = ptr->next;
1327                 }
1328 
1329                 free_entrylist(pdevlist_zone);
1330                 free_entrylist(psoftlist_zone);
1331         }
1332 
1333         /* get kernel hardware providers */
1334         (void) printf(gettext("\nKernel hardware providers:\n"));
1335         if (get_dev_list(&pdevlist_kernel) == FAILURE) {
1336                 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1337                     "the list of kernel hardware providers.\n"));
1338                 rd = FAILURE;
1339         } else {
1340                 for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) {
1341                         (void) printf("\t%s/%d\n",
1342                             pdevlist_kernel->dl_devs[i].le_dev_name,
1343                             pdevlist_kernel->dl_devs[i].le_dev_instance);
1344                 }
1345         }
1346         free(pdevlist_kernel);
1347 
1348         if (ru == FAILURE || rs == FAILURE || rd == FAILURE) {
1349                 return (FAILURE);
1350         } else {
1351                 return (SUCCESS);
1352         }
1353 }
1354 
1355 
1356 
1357 /*
1358  * List all the providers. And for each provider, list the mechanism list.

1359  */
1360 static int
1361 list_mechlist_for_all(boolean_t verbose)
1362 {
1363         crypto_get_dev_list_t   *pdevlist_kernel;
1364         uentrylist_t    *pliblist;
1365         uentrylist_t    *plibptr;
1366         entrylist_t     *pdevlist_conf;
1367         entrylist_t     *psoftlist_conf;
1368         entrylist_t     *pdevlist_zone;
1369         entrylist_t     *psoftlist_zone;
1370         entrylist_t     *ptr;
1371         mechlist_t      *pmechlist;
1372         boolean_t       is_active;
1373         char    provname[MAXNAMELEN];
1374         char    devname[MAXNAMELEN];
1375         int     inst_num;
1376         int     count;
1377         int     i;
1378         int     rv;
1379         int     rc = SUCCESS;
1380 
1381         /* get user-level providers */
1382         (void) printf(gettext("\nUser-level providers:\n"));
1383         /*
1384          * TRANSLATION_NOTE
1385          * Strictly for appearance's sake, this line should be as long as
1386          * the length of the translated text above.
1387          */
1388         (void) printf(gettext("=====================\n"));
1389         if (get_pkcs11conf_info(&pliblist) != SUCCESS) {
1390                 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1391                     "the list of user-level providers.\n"));
1392                 rc = FAILURE;
1393         }
1394 
1395         plibptr = pliblist;
1396         while (plibptr != NULL) {
1397                 /* skip metaslot entry */
1398                 if (strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) {
1399                         (void) printf(gettext("\nProvider: %s\n"),
1400                             plibptr->puent->name);
1401                         rv = list_mechlist_for_lib(plibptr->puent->name,
1402                             mecharglist, NULL, B_FALSE, verbose, B_TRUE);
1403                         if (rv == FAILURE) {
1404                                 rc = FAILURE;
1405                         }
1406                 }
1407                 plibptr = plibptr->next;
1408         }
1409         free_uentrylist(pliblist);
1410 
1411         /* get kernel software providers */
1412         (void) printf(gettext("\nKernel software providers:\n"));

1413         /*
1414          * TRANSLATION_NOTE
1415          * Strictly for appearance's sake, this line should be as long as
1416          * the length of the translated text above.
1417          */
1418         (void) printf(gettext("==========================\n"));
1419         if (getzoneid() == GLOBAL_ZONEID) {
1420                 /* use kcf.conf for kernel software providers in global zone */
1421                 pdevlist_conf = NULL;
1422                 psoftlist_conf = NULL;




1423 
1424                 if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) !=
1425                     SUCCESS) {
1426                         cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1427                             "the list of kernel software providers.\n"));
1428                         rc = FAILURE;
1429                 }

1430 
1431                 ptr = psoftlist_conf;
1432                 while (ptr != NULL) {
1433                         if (check_active_for_soft(ptr->pent->name, &is_active)
1434                             == SUCCESS) {
1435                                 if (is_active) {
1436                                         rv = list_mechlist_for_soft(
1437                                             ptr->pent->name);











1438                                         if (rv == FAILURE) {
1439                                                 rc = FAILURE;
1440                                         }
1441                                 } else {
1442                                         (void) printf(gettext(
1443                                             "%s: (inactive)\n"),
1444                                             ptr->pent->name);
1445                                 }
1446                         } else {
1447                                 /* should not happen */
1448                                 (void) printf(gettext(
1449                                     "%s: failed to get the mechanism list.\n"),
1450                                     ptr->pent->name);
1451                                 rc = FAILURE;
1452                         }
1453                         ptr = ptr->next;
1454                 }
1455 

1456                 free_entrylist(pdevlist_conf);
1457                 free_entrylist(psoftlist_conf);

1458         } else {
1459                 /* kcf.conf not there in non-global zone, use /dev/cryptoadm */
1460                 pdevlist_zone = NULL;
1461                 psoftlist_zone = NULL;

1462 
1463                 if (get_admindev_info(&pdevlist_zone, &psoftlist_zone) !=
1464                     SUCCESS) {
1465                         cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1466                             "the list of kernel software providers.\n"));
1467                         rc = FAILURE;
1468                 }
1469 
1470                 ptr = psoftlist_zone;
1471                 while (ptr != NULL) {
1472                         rv = list_mechlist_for_soft(ptr->pent->name);
1473                         if (rv == FAILURE) {
1474                                 (void) printf(gettext(
1475                                     "%s: failed to get the mechanism list.\n"),
1476                                     ptr->pent->name);
1477                                 rc = FAILURE;
1478                         }
1479                         ptr = ptr->next;
1480                 }
1481 
1482                 free_entrylist(pdevlist_zone);
1483                 free_entrylist(psoftlist_zone);
1484         }
1485 
1486         /* Get kernel hardware providers and their mechanism lists */
1487         (void) printf(gettext("\nKernel hardware providers:\n"));
1488         /*
1489          * TRANSLATION_NOTE
1490          * Strictly for appearance's sake, this line should be as long as
1491          * the length of the translated text above.
1492          */
1493         (void) printf(gettext("==========================\n"));
1494         if (get_dev_list(&pdevlist_kernel) != SUCCESS) {
1495                 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1496                     "the list of hardware providers.\n"));
1497                 return (FAILURE);
1498         }
1499 


1505                 (void) snprintf(provname, sizeof (provname), "%s/%d", devname,
1506                     inst_num);
1507                 if (get_dev_info(devname, inst_num, count, &pmechlist) ==
1508                     SUCCESS) {
1509                         (void) filter_mechlist(&pmechlist, RANDOM);
1510                         print_mechlist(provname, pmechlist);
1511                         free_mechlist(pmechlist);
1512                 } else {
1513                         (void) printf(gettext("%s: failed to get the mechanism"
1514                             " list.\n"), provname);
1515                         rc = FAILURE;
1516                 }
1517         }
1518         free(pdevlist_kernel);
1519         return (rc);
1520 }
1521 
1522 
1523 /*
1524  * List all the providers. And for each provider, list the policy information.

1525  */
1526 static int
1527 list_policy_for_all(void)
1528 {
1529         crypto_get_dev_list_t   *pdevlist_kernel;
1530         uentrylist_t    *pliblist;
1531         uentrylist_t    *plibptr;
1532         entrylist_t     *pdevlist_conf;
1533         entrylist_t     *psoftlist_conf;
1534         entrylist_t     *ptr;
1535         entrylist_t     *phead;
1536         boolean_t       found;
1537         char    provname[MAXNAMELEN];
1538         int     i;
1539         int     rc = SUCCESS;
1540 
1541         /* Get user-level providers */
1542         (void) printf(gettext("\nUser-level providers:\n"));
1543         /*
1544          * TRANSLATION_NOTE
1545          * Strictly for appearance's sake, this line should be as long as
1546          * the length of the translated text above.
1547          */
1548         (void) printf(gettext("=====================\n"));
1549         if (get_pkcs11conf_info(&pliblist) == FAILURE) {
1550                 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1551                     "the list of user-level providers.\n"));

1552         } else {
1553                 plibptr = pliblist;

1554                 while (plibptr != NULL) {
1555                         /* skip metaslot entry */
1556                         if (strcmp(plibptr->puent->name,
1557                             METASLOT_KEYWORD) != 0) {
1558                                 if (print_uef_policy(plibptr->puent)
1559                                     == FAILURE) {
1560                                         rc = FAILURE;
1561                                 }
1562                         }
1563                         plibptr = plibptr->next;
1564                 }
1565                 free_uentrylist(pliblist);
1566         }
1567 
1568         /* kernel software providers */
1569         (void) printf(gettext("\nKernel software providers:\n"));
1570         /*
1571          * TRANSLATION_NOTE
1572          * Strictly for appearance's sake, this line should be as long as
1573          * the length of the translated text above.
1574          */
1575         (void) printf(gettext("==========================\n"));
1576 
1577         /* Get all entries from the kcf.conf file */
1578         pdevlist_conf = NULL;
1579         if (getzoneid() == GLOBAL_ZONEID) {
1580                 /* use kcf.conf for kernel software providers in global zone */
1581                 psoftlist_conf = NULL;



1582 
1583                 if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) ==
1584                     FAILURE) {
1585                         cryptoerror(LOG_STDERR, gettext(
1586                             "failed to retrieve the list of kernel "
1587                             "providers.\n"));
1588                         return (FAILURE);
1589                 }
1590 
1591                 ptr = psoftlist_conf;
1592                 while (ptr != NULL) {
1593                         (void) list_policy_for_soft(ptr->pent->name);
1594                         ptr = ptr->next;

1595                 }


1596 
1597                 free_entrylist(psoftlist_conf);
1598         } else {
1599                 /* kcf.conf not there in non-global zone, no policy info */
1600 
1601                 /*
1602                  * TRANSLATION_NOTE
1603                  * "global" is keyword and not to be translated.
1604                  */
1605                 cryptoerror(LOG_STDERR, gettext(
1606                     "policy information for kernel software providers is "
1607                     "available in the %s zone only"), "global");
1608         }
1609 
1610         /* Kernel hardware providers */
1611         (void) printf(gettext("\nKernel hardware providers:\n"));
1612         /*
1613          * TRANSLATION_NOTE
1614          * Strictly for appearance's sake, this line should be as long as
1615          * the length of the translated text above.
1616          */
1617         (void) printf(gettext("==========================\n"));
1618 
1619         if (getzoneid() != GLOBAL_ZONEID) {
1620                 /*
1621                  * TRANSLATION_NOTE
1622                  * "global" is keyword and not to be translated.
1623                  */
1624                 cryptoerror(LOG_STDERR, gettext(
1625                     "policy information for kernel hardware providers is "
1626                     "available in the %s zone only"), "global");
1627                 return (FAILURE);
1628         }
1629 
1630         /* Get the hardware provider list from kernel */
1631         if (get_dev_list(&pdevlist_kernel) != SUCCESS) {
1632                 cryptoerror(LOG_STDERR, gettext(
1633                     "failed to retrieve the list of hardware providers.\n"));
1634                 free_entrylist(pdevlist_conf);
1635                 return (FAILURE);
1636         }
1637 








1638         /*
1639          * For each hardware provider from kernel, check if it has an entry
1640          * in the config file.  If it has an entry, print out the policy from
1641          * config file and remove the entry from the hardware provider list
1642          * of the config file.  If it does not have an entry in the config
1643          * file, no mechanisms of it have been disabled. But, we still call
1644          * list_policy_for_hard() to account for the "random" feature.
1645          */
1646         for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) {
1647                 (void) snprintf(provname, sizeof (provname), "%s/%d",
1648                     pdevlist_kernel->dl_devs[i].le_dev_name,
1649                     pdevlist_kernel->dl_devs[i].le_dev_instance);

1650                 found = B_FALSE;
1651                 phead = ptr = pdevlist_conf;
1652                 while (!found && ptr) {
1653                         if (strcmp(ptr->pent->name, provname) == 0) {
1654                                 found = B_TRUE;
1655                         } else {
1656                                 phead = ptr;
1657                                 ptr = ptr->next;
1658                         }
1659                 }
1660 
1661                 if (found) {
1662                         (void) list_policy_for_hard(ptr->pent->name);

1663                         if (phead == ptr) {
1664                                 pdevlist_conf = pdevlist_conf->next;
1665                         } else {
1666                                 phead->next = ptr->next;
1667                         }
1668                         free_entry(ptr->pent);
1669                         free(ptr);
1670                 } else {
1671                         (void) list_policy_for_hard(provname);

1672                 }
1673         }
1674 
1675         /*
1676          * If there are still entries left in the pdevlist_conf list from
1677          * the config file, these providers must have been detached.
1678          * Should print out their policy information also.
1679          */
1680         ptr = pdevlist_conf;
1681         while (ptr != NULL) {
1682                 print_kef_policy(ptr->pent, B_FALSE, B_TRUE);
1683                 ptr = ptr->next;
1684         }
1685 
1686         free_entrylist(pdevlist_conf);

1687         free(pdevlist_kernel);
1688 
1689         return (rc);
1690 }


 231         (void) fprintf(stderr,
 232             "  cryptoadm install provider=<%s> [mechanism=<%s>]\n",
 233             gettext("provider-name"), gettext("mechanism-list"));
 234         (void) fprintf(stderr,
 235             "  cryptoadm uninstall provider=<%s>\n",
 236             gettext("provider-name"));
 237         (void) fprintf(stderr,
 238             "  cryptoadm unload provider=<%s>\n",
 239             gettext("provider-name"));
 240         (void) fprintf(stderr,
 241             "  cryptoadm refresh\n"
 242             "  cryptoadm start\n"
 243             "  cryptoadm stop\n"
 244             "  cryptoadm --help\n");
 245 }
 246 
 247 
 248 /*
 249  * Get the provider type.  This function returns
 250  * - PROV_UEF_LIB if provname contains an absolute path name
 251  * - PROV_KEF_SOFT if provname is a base name only (e.g., "aes").
 252  * - PROV_KEF_HARD if provname contains one slash only and the slash is not
 253  *      the 1st character (e.g., "mca/0").
 254  * - PROV_BADNAME otherwise.
 255  */
 256 static int
 257 get_provider_type(char *provname)
 258 {
 259         char *pslash1;
 260         char *pslash2;
 261 
 262         if (provname == NULL) {
 263                 return (FAILURE);
 264         }
 265 
 266         if (provname[0] == '/') {
 267                 return (PROV_UEF_LIB);
 268         } else if ((pslash1 = strchr(provname, SEP_SLASH)) == NULL) {
 269                 /* no slash */
 270                 return (PROV_KEF_SOFT);
 271         } else {
 272                 pslash2 = strrchr(provname, SEP_SLASH);
 273                 if (pslash1 == pslash2) {


 513                         } else {
 514                                 pcur->next = pmech;
 515                                 pcur = pmech;
 516                         }
 517                 }
 518         } while ((curmech = strtok(NULL, ",")) != NULL);
 519 
 520         if (rc == FAILURE) {
 521                 cryptoerror(LOG_STDERR, gettext("out of memory."));
 522                 free_mechlist(phead);
 523         } else {
 524                 mecharglist = phead;
 525                 rc = SUCCESS;
 526         }
 527         return (rc);
 528 }
 529 
 530 
 531 
 532 /*
 533  * The top level function for the "cryptoadm list" subcommand and options.
 534  */
 535 static int
 536 do_list(int argc, char **argv)
 537 {
 538         boolean_t               mflag = B_FALSE;
 539         boolean_t               pflag = B_FALSE;
 540         boolean_t               vflag = B_FALSE;
 541         char                    ch;
 542         cryptoadm_provider_t    *prov = NULL;
 543         int                     rc = SUCCESS;
 544 
 545         argc -= 1;
 546         argv += 1;
 547 
 548         if (argc == 1) {
 549                 rc = list_simple_for_all(B_FALSE);
 550                 goto out;
 551         }
 552 
 553         /*
 554          * cryptoadm list [-v] [-m] [-p] [provider=<>] [mechanism=<>]
 555          */
 556         if (argc > 5) {
 557                 usage();
 558                 return (rc);
 559         }
 560 
 561         while ((ch = getopt(argc, argv, "mpv")) != EOF) {
 562                 switch (ch) {
 563                 case 'm':
 564                         mflag = B_TRUE;
 565                         if (pflag) {
 566                                 rc = ERROR_USAGE;
 567                         }
 568                         break;
 569                 case 'p':
 570                         pflag = B_TRUE;
 571                         if (mflag || vflag) {
 572                                 rc = ERROR_USAGE;
 573                         }
 574                         break;


 614                         rc = list_simple_for_all(vflag);
 615                 }
 616         } else if (prov->cp_type == METASLOT) {
 617                 if ((!mflag) && (!vflag) && (!pflag)) {
 618                         /* no flag is specified, just list metaslot status */
 619                         rc = list_metaslot_info(mflag, vflag, mecharglist);
 620                 } else if (mflag || vflag) {
 621                         rc = list_metaslot_info(mflag, vflag, mecharglist);
 622                 } else if (pflag) {
 623                         rc = list_metaslot_policy();
 624                 } else {
 625                         /* error message */
 626                         usage();
 627                         rc = ERROR_USAGE;
 628                 }
 629         } else if (prov->cp_type == PROV_BADNAME) {
 630                 usage();
 631                 rc = ERROR_USAGE;
 632                 goto out;
 633         } else { /* do the listing for a provider only */
 634                 char    *provname = prov->cp_name;
 635 
 636                 if (mflag || vflag) {
 637                         if (vflag)
 638                                 (void) printf(gettext("Provider: %s\n"),
 639                                     provname);
 640                         switch (prov->cp_type) {
 641                         case PROV_UEF_LIB:
 642                                 rc = list_mechlist_for_lib(provname,
 643                                     mecharglist, NULL, B_FALSE, vflag, mflag);

 644                                 break;
 645                         case PROV_KEF_SOFT:
 646                                 rc = list_mechlist_for_soft(provname,
 647                                     NULL, NULL);
 648                                 break;
 649                         case PROV_KEF_HARD:
 650                                 rc = list_mechlist_for_hard(provname);
 651                                 break;
 652                         default: /* should not come here */
 653                                 rc = FAILURE;
 654                                 break;
 655                         }
 656                 } else if (pflag) {
 657                         switch (prov->cp_type) {
 658                         case PROV_UEF_LIB:
 659                                 rc = list_policy_for_lib(provname);
 660                                 break;
 661                         case PROV_KEF_SOFT:
 662                                 if (getzoneid() == GLOBAL_ZONEID) {
 663                                         rc = list_policy_for_soft(provname,
 664                                             NULL, NULL);
 665                                 } else {
 666                                         /*
 667                                          * TRANSLATION_NOTE
 668                                          * "global" is keyword and not to
 669                                          * be translated.
 670                                          */
 671                                         cryptoerror(LOG_STDERR, gettext(
 672                                             "policy information for kernel "
 673                                             "providers is available "
 674                                             "in the %s zone only"), "global");
 675                                         rc = FAILURE;
 676                                 }
 677                                 break;
 678                         case PROV_KEF_HARD:
 679                                 if (getzoneid() == GLOBAL_ZONEID) {
 680                                         rc = list_policy_for_hard(
 681                                             provname, NULL, NULL, NULL);
 682                                 } else {
 683                                         /*
 684                                          * TRANSLATION_NOTE
 685                                          * "global" is keyword and not to
 686                                          * be translated.
 687                                          */
 688                                         cryptoerror(LOG_STDERR, gettext(
 689                                             "policy information for kernel "
 690                                             "providers is available "
 691                                             "in the %s zone only"), "global");
 692                                         rc = FAILURE;
 693                                 }
 694 
 695                                 break;
 696                         default: /* should not come here */
 697                                 rc = FAILURE;
 698                                 break;
 699                         }
 700                 } else {
 701                         /* error message */
 702                         usage();
 703                         rc = ERROR_USAGE;
 704                 }
 705         }
 706 
 707 out:
 708         if (prov != NULL)
 709                 free(prov);
 710 
 711         if (mecharglist != NULL)
 712                 free_mechlist(mecharglist);
 713         return (rc);
 714 }
 715 
 716 
 717 /*
 718  * The top level function for the "cryptoadm disable" subcommand.
 719  */
 720 static int
 721 do_disable(int argc, char **argv)
 722 {
 723         cryptoadm_provider_t    *prov = NULL;
 724         int                     rc = SUCCESS;
 725         boolean_t               auto_key_migrate_flag = B_FALSE;
 726 
 727         if ((argc < 3) || (argc > 5)) {
 728                 usage();
 729                 return (ERROR_USAGE);
 730         }
 731 
 732         prov = get_provider(argc, argv);
 733         if (prov == NULL) {
 734                 usage();
 735                 return (ERROR_USAGE);
 736         }
 737         if (prov->cp_type == PROV_BADNAME) {
 738                 return (FAILURE);


 815                             "providers is supported in the %2$s zone only"),
 816                             "disable", "global");
 817                         rc = FAILURE;
 818                 }
 819                 break;
 820         default: /* should not come here */
 821                 rc = FAILURE;
 822                 break;
 823         }
 824 
 825 out:
 826         free(prov);
 827         if (mecharglist != NULL) {
 828                 free_mechlist(mecharglist);
 829         }
 830         return (rc);
 831 }
 832 
 833 
 834 /*
 835  * The top level function for the "cryptoadm enable" subcommand.
 836  */
 837 static int
 838 do_enable(int argc, char **argv)
 839 {
 840         cryptoadm_provider_t    *prov = NULL;
 841         int                     rc = SUCCESS;
 842         char                    *alt_token = NULL, *alt_slot = NULL;
 843         boolean_t               use_default = B_FALSE;
 844         boolean_t               auto_key_migrate_flag = B_FALSE;
 845 
 846         if ((argc < 3) || (argc > 6)) {
 847                 usage();
 848                 return (ERROR_USAGE);
 849         }
 850 
 851         prov = get_provider(argc, argv);
 852         if (prov == NULL) {
 853                 usage();
 854                 return (ERROR_USAGE);
 855         }
 856         if ((prov->cp_type != METASLOT) && (argc != 4)) {
 857                 usage();
 858                 return (ERROR_USAGE);
 859         }
 860         if (prov->cp_type == PROV_BADNAME) {
 861                 rc = FAILURE;
 862                 goto out;
 863         }
 864 


 930                 rc = FAILURE;
 931                 break;
 932         }
 933 out:
 934         free(prov);
 935         if (mecharglist != NULL) {
 936                 free_mechlist(mecharglist);
 937         }
 938         if (alt_token != NULL) {
 939                 free(alt_token);
 940         }
 941         if (alt_slot != NULL) {
 942                 free(alt_slot);
 943         }
 944         return (rc);
 945 }
 946 
 947 
 948 
 949 /*
 950  * The top level function for the "cryptoadm install" subcommand.
 951  */
 952 static int
 953 do_install(int argc, char **argv)
 954 {
 955         cryptoadm_provider_t    *prov = NULL;
 956         int     rc;
 957 
 958         if (argc < 3) {
 959                 usage();
 960                 return (ERROR_USAGE);
 961         }
 962 
 963         prov = get_provider(argc, argv);
 964         if (prov == NULL ||
 965             prov->cp_type == PROV_BADNAME || prov->cp_type == PROV_KEF_HARD) {
 966                 /*
 967                  * TRANSLATION_NOTE
 968                  * "install" could be either a literal keyword and hence
 969                  * not to be translated, or a verb and translatable.  A
 970                  * choice was made to view it as a literal keyword.


1020         } else {
1021                 /*
1022                  * TRANSLATION_NOTE
1023                  * "install" could be either a literal keyword and hence
1024                  * not to be translated, or a verb and translatable.  A
1025                  * choice was made to view it as a literal keyword.
1026                  * "global" is keyword and not to be translated.
1027                  */
1028                 cryptoerror(LOG_STDERR, gettext("%1$s for kernel providers "
1029                     "is supported in the %2$s zone only"), "install", "global");
1030                 rc = FAILURE;
1031         }
1032 out:
1033         free(prov);
1034         return (rc);
1035 }
1036 
1037 
1038 
1039 /*
1040  * The top level function for the "cryptoadm uninstall" subcommand.
1041  */
1042 static int
1043 do_uninstall(int argc, char **argv)
1044 {
1045         cryptoadm_provider_t    *prov = NULL;
1046         int     rc = SUCCESS;
1047 
1048         if (argc != 3) {
1049                 usage();
1050                 return (ERROR_USAGE);
1051         }
1052 
1053         prov = get_provider(argc, argv);
1054         if (prov == NULL ||
1055             prov->cp_type == PROV_BADNAME || prov->cp_type == PROV_KEF_HARD) {
1056                 /*
1057                  * TRANSLATION_NOTE
1058                  * "uninstall" could be either a literal keyword and hence
1059                  * not to be translated, or a verb and translatable.  A
1060                  * choice was made to view it as a literal keyword.
1061                  */
1062                 cryptoerror(LOG_STDERR,
1063                     gettext("bad provider name for %s."), "uninstall");
1064                 free(prov);
1065                 return (FAILURE);
1066         }
1067 
1068         if (prov->cp_type == PROV_UEF_LIB) {
1069                 rc = uninstall_uef_lib(prov->cp_name);
1070 
1071         } else if (prov->cp_type == PROV_KEF_SOFT) {
1072                 if (getzoneid() == GLOBAL_ZONEID) {
1073                         /* unload and remove from kcf.conf */
1074                         rc = uninstall_kef(prov->cp_name);
1075                 } else {
1076                         /*
1077                          * TRANSLATION_NOTE
1078                          * "uninstall" could be either a literal keyword and
1079                          * hence not to be translated, or a verb and
1080                          * translatable.  A choice was made to view it as a
1081                          * literal keyword.  "global" is keyword and not to
1082                          * be translated.
1083                          */
1084                         cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
1085                             "providers is supported in the %2$s zone only"),
1086                             "uninstall", "global");
1087                         rc = FAILURE;
1088                 }
1089         }
1090 
1091         free(prov);
1092         return (rc);
1093 }
1094 
1095 
1096 /*
1097  * The top level function for the "cryptoadm unload" subcommand.
1098  */
1099 static int
1100 do_unload(int argc, char **argv)
1101 {
1102         cryptoadm_provider_t    *prov = NULL;
1103         entry_t                 *pent = NULL;
1104         boolean_t               in_kernel = B_FALSE;
1105         int                     rc = SUCCESS;
1106         char                    *provname = NULL;
1107 
1108         if (argc != 3) {
1109                 usage();
1110                 return (ERROR_USAGE);
1111         }
1112 
1113         /* check if it is a kernel software provider */
1114         prov = get_provider(argc, argv);
1115         if (prov == NULL) {
1116                 cryptoerror(LOG_STDERR,
1117                     gettext("unable to determine provider name."));
1118                 goto out;
1119         }
1120         provname = prov->cp_name;
1121         if (prov->cp_type != PROV_KEF_SOFT) {
1122                 cryptoerror(LOG_STDERR,
1123                     gettext("%s is not a valid kernel software provider."),
1124                     provname);
1125                 rc = FAILURE;
1126                 goto out;
1127         }
1128 
1129         if (getzoneid() != GLOBAL_ZONEID) {
1130                 /*
1131                  * TRANSLATION_NOTE
1132                  * "unload" could be either a literal keyword and hence
1133                  * not to be translated, or a verb and translatable.
1134                  * A choice was made to view it as a literal keyword.
1135                  * "global" is keyword and not to be translated.
1136                  */
1137                 cryptoerror(LOG_STDERR, gettext("%1$s for kernel providers "
1138                     "is supported in the %2$s zone only"), "unload", "global");
1139                 rc = FAILURE;
1140                 goto out;
1141         }
1142 
1143         if (check_kernel_for_soft(provname, NULL, &in_kernel) == FAILURE) {
1144                 cryptodebug("internal error");
1145                 rc = FAILURE;
1146                 goto out;
1147         } else if (in_kernel == B_FALSE) {
1148                 cryptoerror(LOG_STDERR,
1149                     gettext("provider %s is not loaded or does not exist."),
1150                     provname);
1151                 rc = FAILURE;
1152                 goto out;
1153         }

1154 
1155         /* Get kcf.conf entry.  If none, build a new entry */
1156         if ((pent = getent_kef(provname, NULL, NULL)) == NULL) {
1157                 if ((pent = create_entry(provname)) == NULL) {
1158                         cryptoerror(LOG_STDERR, gettext("out of memory."));

1159                         rc = FAILURE;
1160                         goto out;
1161                 }
1162         }
1163 
1164         /* If it is unloaded already, return  */
1165         if (!pent->load) { /* unloaded already */


1166                 cryptoerror(LOG_STDERR,
1167                     gettext("failed to unload %s."), provname);
1168                 rc = FAILURE;
1169                 goto out;
1170         } else if (unload_kef_soft(provname) != FAILURE) {
1171                 /* Mark as unloaded in kcf.conf */
1172                 pent->load = B_FALSE;
1173                 rc = update_kcfconf(pent, MODIFY_MODE);
1174         } else {
1175                 cryptoerror(LOG_STDERR,
1176                     gettext("failed to unload %s."), provname);
1177                 rc = FAILURE;
1178         }
1179 out:
1180         free(prov);
1181         free_entry(pent);
1182         return (rc);
1183 }
1184 
1185 
1186 
1187 /*
1188  * The top level function for the "cryptoadm refresh" subcommand.
1189  */
1190 static int
1191 do_refresh(int argc)
1192 {
1193         if (argc != 2) {
1194                 usage();
1195                 return (ERROR_USAGE);
1196         }
1197 
1198         if (getzoneid() == GLOBAL_ZONEID) {
1199                 return (refresh());
1200         } else { /* non-global zone */
1201                 /*
1202                  * Note:  in non-global zone, this must silently return SUCCESS
1203                  * due to integration with SMF, for "svcadm refresh cryptosvc"
1204                  */

1205                 return (SUCCESS);
1206         }

1207 }
1208 
1209 
1210 /*
1211  * The top level function for the "cryptoadm start" subcommand.
1212  */
1213 static int
1214 do_start(int argc)
1215 {
1216         int ret;
1217 
1218         if (argc != 2) {
1219                 usage();
1220                 return (ERROR_USAGE);
1221         }
1222 
1223         ret = do_refresh(argc);
1224         if (ret != SUCCESS)
1225                 return (ret);
1226 
1227         return (start_daemon());
1228 }
1229 
1230 /*
1231  * The top level function for the "cryptoadm stop" subcommand.
1232  */
1233 static int
1234 do_stop(int argc)
1235 {
1236         if (argc != 2) {
1237                 usage();
1238                 return (ERROR_USAGE);
1239         }
1240 
1241         return (stop_daemon());
1242 }
1243 
1244 
1245 
1246 /*
1247  * Print a list all the the providers.
1248  * Called for "cryptoadm list" or "cryptoadm list -v" (no -m or -p).
1249  */
1250 static int
1251 list_simple_for_all(boolean_t verbose)
1252 {
1253         uentrylist_t            *pliblist = NULL;
1254         uentrylist_t            *plibptr = NULL;
1255         entry_t                 *pent = NULL;




1256         crypto_get_dev_list_t   *pdevlist_kernel = NULL;
1257         int                     rc = SUCCESS;



1258         int                     i;
1259 
1260         /* get user-level providers */
1261         (void) printf(gettext("\nUser-level providers:\n"));
1262         if (get_pkcs11conf_info(&pliblist) != SUCCESS) {
1263                 cryptoerror(LOG_STDERR, gettext(
1264                     "failed to retrieve the list of user-level providers."));
1265                 rc = FAILURE;
1266         }
1267 
1268         for (plibptr = pliblist; plibptr != NULL; plibptr = plibptr->next) {
1269                 if (strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) {
1270                         (void) printf(gettext("Provider: %s\n"),
1271                             plibptr->puent->name);
1272                         if (verbose) {
1273                                 (void) list_mechlist_for_lib(
1274                                     plibptr->puent->name, mecharglist, NULL,
1275                                     B_FALSE, verbose, B_FALSE);
1276                                 (void) printf("\n");
1277                         }
1278                 }

1279         }
1280         free_uentrylist(pliblist);
1281 
1282         /* get kernel software providers */
1283         (void) printf(gettext("\nKernel software providers:\n"));
1284 
1285         if (getzoneid() == GLOBAL_ZONEID) {
1286                 /* get kernel software providers from kernel ioctl */
1287                 crypto_get_soft_list_t          *psoftlist_kernel = NULL;
1288                 uint_t                          sl_soft_count;
1289                 char                            *psoftname;
1290                 entrylist_t                     *pdevlist_conf = NULL;
1291                 entrylist_t                     *psoftlist_conf = NULL;
1292 
1293                 if (get_soft_list(&psoftlist_kernel) == FAILURE) {
1294                         cryptoerror(LOG_ERR, gettext("Failed to retrieve the "
1295                             "software provider list from kernel."));
1296                         rc = FAILURE;
1297                 } else {
1298                         sl_soft_count = psoftlist_kernel->sl_soft_count;

1299 
1300                         if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf)


1301                             == FAILURE) {
1302                                 cryptoerror(LOG_ERR,
1303                                     "failed to retrieve the providers' "
1304                                     "information from file kcf.conf - %s.",
1305                                     _PATH_KCF_CONF);
1306                                 free(psoftlist_kernel);
1307                                 rc = FAILURE;




1308                         } else {




1309 
1310                                 for (i = 0,
1311                                     psoftname = psoftlist_kernel->sl_soft_names;
1312                                     i < sl_soft_count;
1313                                     ++i, psoftname += strlen(psoftname) + 1) {
1314                                         pent = getent_kef(psoftname,
1315                                             pdevlist_conf, psoftlist_conf);
1316                                         (void) printf("\t%s%s\n", psoftname,
1317                                             (pent == NULL) || (pent->load) ?
1318                                             "" : gettext(" (inactive)"));
1319                                 }
1320                                 free_entrylist(pdevlist_conf);
1321                                 free_entrylist(psoftlist_conf);
1322                         }
1323                         free(psoftlist_kernel);
1324                 }
1325 
1326         } else {
1327                 /* kcf.conf not there in non-global zone, use /dev/cryptoadm */
1328                 entrylist_t     *pdevlist_zone = NULL;
1329                 entrylist_t     *psoftlist_zone = NULL;
1330                 entrylist_t     *ptr;
1331 
1332                 if (get_admindev_info(&pdevlist_zone, &psoftlist_zone) !=
1333                     SUCCESS) {
1334                         cryptoerror(LOG_STDERR,
1335                             gettext("failed to retrieve the "
1336                             "list of kernel software providers.\n"));
1337                         rc = FAILURE;
1338                 }
1339 
1340                 ptr = psoftlist_zone;
1341                 while (ptr != NULL) {
1342                         (void) printf("\t%s\n", ptr->pent->name);
1343                         ptr = ptr->next;
1344                 }
1345 
1346                 free_entrylist(pdevlist_zone);
1347                 free_entrylist(psoftlist_zone);
1348         }
1349 
1350         /* get kernel hardware providers */
1351         (void) printf(gettext("\nKernel hardware providers:\n"));
1352         if (get_dev_list(&pdevlist_kernel) == FAILURE) {
1353                 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1354                     "the list of kernel hardware providers.\n"));
1355                 rc = FAILURE;
1356         } else {
1357                 for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) {
1358                         (void) printf("\t%s/%d\n",
1359                             pdevlist_kernel->dl_devs[i].le_dev_name,
1360                             pdevlist_kernel->dl_devs[i].le_dev_instance);
1361                 }
1362         }
1363         free(pdevlist_kernel);
1364 
1365         return (rc);




1366 }
1367 
1368 
1369 
1370 /*
1371  * List all the providers. And for each provider, list the mechanism list.
1372  * Called for "cryptoadm list -m" or "cryptoadm list -mv" .
1373  */
1374 static int
1375 list_mechlist_for_all(boolean_t verbose)
1376 {
1377         crypto_get_dev_list_t   *pdevlist_kernel = NULL;
1378         uentrylist_t            *pliblist = NULL;
1379         uentrylist_t            *plibptr = NULL;
1380         entry_t                 *pent = NULL;
1381         mechlist_t              *pmechlist = NULL;





1382         char                    provname[MAXNAMELEN];
1383         char                    devname[MAXNAMELEN];
1384         int                     inst_num;
1385         int                     count;
1386         int                     i;
1387         int                     rv;
1388         int                     rc = SUCCESS;
1389 
1390         /* get user-level providers */
1391         (void) printf(gettext("\nUser-level providers:\n"));
1392         /*
1393          * TRANSLATION_NOTE
1394          * Strictly for appearance's sake, this line should be as long as
1395          * the length of the translated text above.
1396          */
1397         (void) printf(gettext("=====================\n"));
1398         if (get_pkcs11conf_info(&pliblist) != SUCCESS) {
1399                 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1400                     "the list of user-level providers.\n"));
1401                 rc = FAILURE;
1402         }
1403 
1404         plibptr = pliblist;
1405         while (plibptr != NULL) {
1406                 /* skip metaslot entry */
1407                 if (strcmp(plibptr->puent->name, METASLOT_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;
1414                         }
1415                 }
1416                 plibptr = plibptr->next;
1417         }
1418         free_uentrylist(pliblist);
1419 
1420         /* get kernel software providers */
1421         (void) printf(gettext("\nKernel software providers:\n"));
1422 
1423         /*
1424          * TRANSLATION_NOTE
1425          * Strictly for appearance's sake, this line should be as long as
1426          * the length of the translated text above.
1427          */
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;
1437 
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);

1442                 }
1443                 sl_soft_count = psoftlist_kernel->sl_soft_count;
1444 
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);
1453                 }
1454 
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;
1465                                 }
1466                         } else {
1467                                 (void) printf(gettext("%s: (inactive)\n"),
1468                                     psoftname);

1469                         }






1470                 }


1471 
1472                 free(psoftlist_kernel);
1473                 free_entrylist(pdevlist_conf);
1474                 free_entrylist(psoftlist_conf);
1475 
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;
1481 
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;
1487                 }
1488 
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;
1497                         }

1498                 }
1499 
1500                 free_entrylist(pdevlist_zone);
1501                 free_entrylist(psoftlist_zone);
1502         }
1503 
1504         /* Get kernel hardware providers and their mechanism lists */
1505         (void) printf(gettext("\nKernel hardware providers:\n"));
1506         /*
1507          * TRANSLATION_NOTE
1508          * Strictly for appearance's sake, this line should be as long as
1509          * the length of the translated text above.
1510          */
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);
1516         }
1517 


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;
1534                 }
1535         }
1536         free(pdevlist_kernel);
1537         return (rc);
1538 }
1539 
1540 
1541 /*
1542  * List all the providers. And for each provider, list the policy information.
1543  * Called for "cryptoadm list -p".
1544  */
1545 static int
1546 list_policy_for_all(void)
1547 {
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;
1558 
1559         /* Get user-level providers */
1560         (void) printf(gettext("\nUser-level providers:\n"));
1561         /*
1562          * TRANSLATION_NOTE
1563          * Strictly for appearance's sake, this line should be as long as
1564          * the length of the translated text above.
1565          */
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;
1573 
1574                 while (plibptr != NULL) {
1575                         /* skip metaslot entry */
1576                         if (strcmp(plibptr->puent->name,
1577                             METASLOT_KEYWORD) != 0) {
1578                                 if (print_uef_policy(plibptr->puent)
1579                                     == FAILURE) {
1580                                         rc = FAILURE;
1581                                 }
1582                         }
1583                         plibptr = plibptr->next;
1584                 }
1585                 free_uentrylist(pliblist);
1586         }
1587 
1588         /* kernel software providers */
1589         (void) printf(gettext("\nKernel software providers:\n"));
1590         /*
1591          * TRANSLATION_NOTE
1592          * Strictly for appearance's sake, this line should be as long as
1593          * the length of the translated text above.
1594          */
1595         (void) printf(gettext("==========================\n"));
1596 
1597         /* Get all entries from the kernel */

1598         if (getzoneid() == GLOBAL_ZONEID) {
1599                 /* get kernel software providers from kernel ioctl */
1600                 crypto_get_soft_list_t          *psoftlist_kernel = NULL;
1601                 uint_t                          sl_soft_count;
1602                 char                            *psoftname;
1603                 int                             i;
1604 
1605                 if (get_soft_list(&psoftlist_kernel) == FAILURE) {
1606                         cryptoerror(LOG_ERR, gettext("Failed to retrieve the "
1607                             "software provider list from kernel."));
1608                         rc = FAILURE;
1609                 } else {
1610                         sl_soft_count = psoftlist_kernel->sl_soft_count;

1611 
1612                         for (i = 0, psoftname = psoftlist_kernel->sl_soft_names;
1613                             i < sl_soft_count;
1614                             ++i, psoftname += strlen(psoftname) + 1) {
1615                                 (void) list_policy_for_soft(psoftname,
1616                                     pdevlist_conf, psoftlist_conf);
1617                         }
1618                         free(psoftlist_kernel);
1619                 }
1620 

1621         } else {
1622                 /* kcf.conf not there in non-global zone, no policy info */
1623 
1624                 /*
1625                  * TRANSLATION_NOTE
1626                  * "global" is keyword and not to be translated.
1627                  */
1628                 cryptoerror(LOG_STDERR, gettext(
1629                     "policy information for kernel software providers is "
1630                     "available in the %s zone only"), "global");
1631         }
1632 
1633         /* Kernel hardware providers */
1634         (void) printf(gettext("\nKernel hardware providers:\n"));
1635         /*
1636          * TRANSLATION_NOTE
1637          * Strictly for appearance's sake, this line should be as long as
1638          * the length of the translated text above.
1639          */
1640         (void) printf(gettext("==========================\n"));
1641 
1642         if (getzoneid() != GLOBAL_ZONEID) {
1643                 /*
1644                  * TRANSLATION_NOTE
1645                  * "global" is keyword and not to be translated.
1646                  */
1647                 cryptoerror(LOG_STDERR, gettext(
1648                     "policy information for kernel hardware providers is "
1649                     "available in the %s zone only"), "global");
1650                 return (FAILURE);
1651         }
1652 
1653         /* Get the hardware provider list from kernel */
1654         if (get_dev_list(&pdevlist_kernel) != SUCCESS) {
1655                 cryptoerror(LOG_STDERR, gettext(
1656                     "failed to retrieve the list of hardware providers.\n"));

1657                 return (FAILURE);
1658         }
1659 
1660         if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) == FAILURE) {
1661                 cryptoerror(LOG_ERR, "failed to retrieve the providers' "
1662                     "information from file kcf.conf - %s.",
1663                     _PATH_KCF_CONF);
1664                 return (FAILURE);
1665         }
1666 
1667 
1668         /*
1669          * For each hardware provider from kernel, check if it has an entry
1670          * in the config file.  If it has an entry, print out the policy from
1671          * config file and remove the entry from the hardware provider list
1672          * of the config file.  If it does not have an entry in the config
1673          * file, no mechanisms of it have been disabled. But, we still call
1674          * list_policy_for_hard() to account for the "random" feature.
1675          */
1676         for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) {
1677                 (void) snprintf(provname, sizeof (provname), "%s/%d",
1678                     pdevlist_kernel->dl_devs[i].le_dev_name,
1679                     pdevlist_kernel->dl_devs[i].le_dev_instance);
1680 
1681                 found = B_FALSE;
1682                 phead = ptr = pdevlist_conf;
1683                 while (!found && ptr) {
1684                         if (strcmp(ptr->pent->name, provname) == 0) {
1685                                 found = B_TRUE;
1686                         } else {
1687                                 phead = ptr;
1688                                 ptr = ptr->next;
1689                         }
1690                 }
1691 
1692                 if (found) {
1693                         (void) list_policy_for_hard(ptr->pent->name,
1694                             pdevlist_conf, psoftlist_conf, pdevlist_kernel);
1695                         if (phead == ptr) {
1696                                 pdevlist_conf = pdevlist_conf->next;
1697                         } else {
1698                                 phead->next = ptr->next;
1699                         }
1700                         free_entry(ptr->pent);
1701                         free(ptr);
1702                 } else {
1703                         (void) list_policy_for_hard(provname, pdevlist_conf,
1704                             psoftlist_conf, pdevlist_kernel);
1705                 }
1706         }
1707 
1708         /*
1709          * If there are still entries left in the pdevlist_conf list from
1710          * the config file, these providers must have been detached.
1711          * Should print out their policy information also.
1712          */
1713         for (ptr = pdevlist_conf; ptr != NULL; ptr = ptr->next) {
1714                 print_kef_policy(ptr->pent->name, ptr->pent, B_FALSE, B_TRUE);


1715         }
1716 
1717         free_entrylist(pdevlist_conf);
1718         free_entrylist(psoftlist_conf);
1719         free(pdevlist_kernel);
1720 
1721         return (rc);
1722 }