10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7334SDaniel.Anderson@Sun.COM * Common Development and Distribution License (the "License"). 6*7334SDaniel.Anderson@Sun.COM * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*7334SDaniel.Anderson@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #include <errno.h> 270Sstevel@tonic-gate #include <fcntl.h> 280Sstevel@tonic-gate #include <stdio.h> 290Sstevel@tonic-gate #include <stdlib.h> 300Sstevel@tonic-gate #include <strings.h> 310Sstevel@tonic-gate #include <time.h> 320Sstevel@tonic-gate #include <unistd.h> 330Sstevel@tonic-gate #include <locale.h> 340Sstevel@tonic-gate #include <sys/types.h> 350Sstevel@tonic-gate #include <sys/stat.h> 360Sstevel@tonic-gate #include "cryptoadm.h" 370Sstevel@tonic-gate 380Sstevel@tonic-gate static int err; /* To store errno which may be overwritten by gettext() */ 390Sstevel@tonic-gate static int build_entrylist(entry_t *, entrylist_t **); 400Sstevel@tonic-gate static entry_t *dup_entry(entry_t *); 410Sstevel@tonic-gate static mechlist_t *dup_mechlist(mechlist_t *); 420Sstevel@tonic-gate static entry_t *getent(char *, entrylist_t *); 430Sstevel@tonic-gate static int interpret(char *, entry_t **); 440Sstevel@tonic-gate static int parse_dislist(char *, entry_t *); 450Sstevel@tonic-gate 460Sstevel@tonic-gate 470Sstevel@tonic-gate /* 480Sstevel@tonic-gate * Duplicate the mechanism list. A null pointer is returned if the storage 490Sstevel@tonic-gate * space available is insufficient or the input argument is NULL. 500Sstevel@tonic-gate */ 510Sstevel@tonic-gate static mechlist_t * 520Sstevel@tonic-gate dup_mechlist(mechlist_t *plist) 530Sstevel@tonic-gate { 540Sstevel@tonic-gate mechlist_t *pres = NULL; 550Sstevel@tonic-gate mechlist_t *pcur; 560Sstevel@tonic-gate mechlist_t *ptmp; 570Sstevel@tonic-gate int rc = SUCCESS; 580Sstevel@tonic-gate 590Sstevel@tonic-gate while (plist != NULL) { 600Sstevel@tonic-gate if (!(ptmp = create_mech(plist->name))) { 610Sstevel@tonic-gate rc = FAILURE; 620Sstevel@tonic-gate break; 630Sstevel@tonic-gate } 640Sstevel@tonic-gate 650Sstevel@tonic-gate if (pres == NULL) { 660Sstevel@tonic-gate pres = pcur = ptmp; 670Sstevel@tonic-gate } else { 680Sstevel@tonic-gate pcur->next = ptmp; 690Sstevel@tonic-gate pcur = pcur->next; 700Sstevel@tonic-gate } 710Sstevel@tonic-gate plist = plist->next; 720Sstevel@tonic-gate } 730Sstevel@tonic-gate 740Sstevel@tonic-gate if (rc != SUCCESS) { 750Sstevel@tonic-gate free_mechlist(pres); 760Sstevel@tonic-gate return (NULL); 770Sstevel@tonic-gate } 780Sstevel@tonic-gate 790Sstevel@tonic-gate return (pres); 800Sstevel@tonic-gate } 810Sstevel@tonic-gate 820Sstevel@tonic-gate 830Sstevel@tonic-gate /* 840Sstevel@tonic-gate * Get the number of mechanisms in the mechanism list. 850Sstevel@tonic-gate */ 860Sstevel@tonic-gate int 870Sstevel@tonic-gate get_mech_count(mechlist_t *plist) 880Sstevel@tonic-gate { 890Sstevel@tonic-gate int count = 0; 900Sstevel@tonic-gate 910Sstevel@tonic-gate while (plist != NULL) { 920Sstevel@tonic-gate count++; 930Sstevel@tonic-gate plist = plist->next; 940Sstevel@tonic-gate } 950Sstevel@tonic-gate return (count); 960Sstevel@tonic-gate } 970Sstevel@tonic-gate 980Sstevel@tonic-gate 990Sstevel@tonic-gate /* 1000Sstevel@tonic-gate * Duplicate an entry. A null pointer is returned if the storage space 1010Sstevel@tonic-gate * available is insufficient or the input argument is NULL. 1020Sstevel@tonic-gate */ 1030Sstevel@tonic-gate static entry_t * 1040Sstevel@tonic-gate dup_entry(entry_t *pent1) 1050Sstevel@tonic-gate { 1060Sstevel@tonic-gate entry_t *pent2 = NULL; 1070Sstevel@tonic-gate 1080Sstevel@tonic-gate if (pent1 == NULL) { 1090Sstevel@tonic-gate return (NULL); 1100Sstevel@tonic-gate } 1110Sstevel@tonic-gate 1120Sstevel@tonic-gate if ((pent2 = malloc(sizeof (entry_t))) == NULL) { 1130Sstevel@tonic-gate cryptodebug("out of memory."); 1140Sstevel@tonic-gate return (NULL); 1150Sstevel@tonic-gate } 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate (void) strlcpy(pent2->name, pent1->name, sizeof (pent2->name)); 1180Sstevel@tonic-gate pent2->sup_count = pent1->sup_count; 1190Sstevel@tonic-gate pent2->dis_count = pent1->dis_count; 1200Sstevel@tonic-gate pent2->suplist = NULL; 1210Sstevel@tonic-gate pent2->dislist = NULL; 1220Sstevel@tonic-gate if (pent1->suplist != NULL) { 1230Sstevel@tonic-gate pent2->suplist = dup_mechlist(pent1->suplist); 1240Sstevel@tonic-gate if (pent2->suplist == NULL) { 1250Sstevel@tonic-gate free_entry(pent2); 1260Sstevel@tonic-gate return (NULL); 1270Sstevel@tonic-gate } 1280Sstevel@tonic-gate } 1290Sstevel@tonic-gate if (pent1->dislist != NULL) { 1300Sstevel@tonic-gate pent2->dislist = dup_mechlist(pent1->dislist); 1310Sstevel@tonic-gate if (pent2->dislist == NULL) { 1320Sstevel@tonic-gate free_entry(pent2); 1330Sstevel@tonic-gate return (NULL); 1340Sstevel@tonic-gate } 1350Sstevel@tonic-gate } 1360Sstevel@tonic-gate 1370Sstevel@tonic-gate return (pent2); 1380Sstevel@tonic-gate } 1390Sstevel@tonic-gate 1400Sstevel@tonic-gate 1410Sstevel@tonic-gate /* 1420Sstevel@tonic-gate * This routine parses the disabledlist or the supportedlist of an entry 1430Sstevel@tonic-gate * in the kcf.conf configuration file. 1440Sstevel@tonic-gate * 1450Sstevel@tonic-gate * Arguments: 1460Sstevel@tonic-gate * buf: an input argument which is a char string with the format of 1470Sstevel@tonic-gate * "disabledlist=m1,m2,..." or "supportedlist=m1,m2,..." 1480Sstevel@tonic-gate * pent: the entry for the disabledlist. This is an IN/OUT argument. 1490Sstevel@tonic-gate * 1500Sstevel@tonic-gate * Return value: SUCCESS or FAILURE. 1510Sstevel@tonic-gate */ 1520Sstevel@tonic-gate static int 1530Sstevel@tonic-gate parse_dislist(char *buf, entry_t *pent) 1540Sstevel@tonic-gate { 1550Sstevel@tonic-gate mechlist_t *pmech; 1560Sstevel@tonic-gate mechlist_t *phead; 1570Sstevel@tonic-gate char *next_token; 1580Sstevel@tonic-gate char *value; 1590Sstevel@tonic-gate int count; 1600Sstevel@tonic-gate int supflag = B_FALSE; 1610Sstevel@tonic-gate int disflag = B_FALSE; 1620Sstevel@tonic-gate int rc = SUCCESS; 1630Sstevel@tonic-gate 1640Sstevel@tonic-gate if (strncmp(buf, EF_SUPPORTED, strlen(EF_SUPPORTED)) == 0) { 1650Sstevel@tonic-gate supflag = B_TRUE; 1660Sstevel@tonic-gate } else if (strncmp(buf, EF_DISABLED, strlen(EF_DISABLED)) == 0) { 1670Sstevel@tonic-gate disflag = B_TRUE; 1680Sstevel@tonic-gate } else { 1690Sstevel@tonic-gate /* should not come here */ 1700Sstevel@tonic-gate return (FAILURE); 1710Sstevel@tonic-gate } 1720Sstevel@tonic-gate 1730Sstevel@tonic-gate if (value = strpbrk(buf, SEP_EQUAL)) { 1740Sstevel@tonic-gate value++; /* get rid of = */ 1750Sstevel@tonic-gate } else { 1760Sstevel@tonic-gate cryptodebug("failed to parse the kcf.conf file."); 1770Sstevel@tonic-gate return (FAILURE); 1780Sstevel@tonic-gate } 1790Sstevel@tonic-gate 1800Sstevel@tonic-gate if ((next_token = strtok(value, SEP_COMMA)) == NULL) { 1810Sstevel@tonic-gate cryptodebug("failed to parse the kcf.conf file."); 1820Sstevel@tonic-gate return (FAILURE); 1830Sstevel@tonic-gate } 1840Sstevel@tonic-gate 1850Sstevel@tonic-gate if ((pmech = create_mech(next_token)) == NULL) { 1860Sstevel@tonic-gate return (FAILURE); 1870Sstevel@tonic-gate } 1880Sstevel@tonic-gate 1890Sstevel@tonic-gate if (supflag) { 1900Sstevel@tonic-gate pent->suplist = phead = pmech; 1910Sstevel@tonic-gate } else if (disflag) { 1920Sstevel@tonic-gate pent->dislist = phead = pmech; 1930Sstevel@tonic-gate } 1940Sstevel@tonic-gate 1950Sstevel@tonic-gate count = 1; 1960Sstevel@tonic-gate while (next_token) { 1970Sstevel@tonic-gate if (next_token = strtok(NULL, SEP_COMMA)) { 1980Sstevel@tonic-gate if ((pmech = create_mech(next_token)) == NULL) { 1990Sstevel@tonic-gate rc = FAILURE; 2000Sstevel@tonic-gate break; 2010Sstevel@tonic-gate } 2020Sstevel@tonic-gate count++; 2030Sstevel@tonic-gate phead->next = pmech; 2040Sstevel@tonic-gate phead = phead->next; 2050Sstevel@tonic-gate } 2060Sstevel@tonic-gate } 2070Sstevel@tonic-gate 2080Sstevel@tonic-gate if (rc == SUCCESS) { 2090Sstevel@tonic-gate if (supflag) { 2100Sstevel@tonic-gate pent->sup_count = count; 2110Sstevel@tonic-gate } else if (disflag) { 2120Sstevel@tonic-gate pent->dis_count = count; 2130Sstevel@tonic-gate } 2140Sstevel@tonic-gate } else { 2150Sstevel@tonic-gate free_mechlist(phead); 2160Sstevel@tonic-gate } 2170Sstevel@tonic-gate 2180Sstevel@tonic-gate return (rc); 2190Sstevel@tonic-gate } 2200Sstevel@tonic-gate 2210Sstevel@tonic-gate 2220Sstevel@tonic-gate 2230Sstevel@tonic-gate /* 2240Sstevel@tonic-gate * This routine converts a char string into an entry_t structure 2250Sstevel@tonic-gate */ 2260Sstevel@tonic-gate static int 2270Sstevel@tonic-gate interpret(char *buf, entry_t **ppent) 2280Sstevel@tonic-gate { 2290Sstevel@tonic-gate entry_t *pent; 2300Sstevel@tonic-gate char *token1; 2310Sstevel@tonic-gate char *token2; 2320Sstevel@tonic-gate char *token3; 2330Sstevel@tonic-gate int rc; 2340Sstevel@tonic-gate 2350Sstevel@tonic-gate if ((token1 = strtok(buf, SEP_COLON)) == NULL) { /* buf is NULL */ 2360Sstevel@tonic-gate return (FAILURE); 2370Sstevel@tonic-gate }; 2380Sstevel@tonic-gate 2390Sstevel@tonic-gate pent = malloc(sizeof (entry_t)); 2400Sstevel@tonic-gate if (pent == NULL) { 2410Sstevel@tonic-gate cryptodebug("out of memory."); 2420Sstevel@tonic-gate return (FAILURE); 2430Sstevel@tonic-gate } 2440Sstevel@tonic-gate (void) strlcpy(pent->name, token1, sizeof (pent->name)); 2450Sstevel@tonic-gate pent->suplist = NULL; 2460Sstevel@tonic-gate pent->dislist = NULL; 2470Sstevel@tonic-gate pent->sup_count = 0; 2480Sstevel@tonic-gate pent->dis_count = 0; 2490Sstevel@tonic-gate 2500Sstevel@tonic-gate if ((token2 = strtok(NULL, SEP_SEMICOLON)) == NULL) { 2510Sstevel@tonic-gate /* The entry contains a provider name only */ 2520Sstevel@tonic-gate free_entry(pent); 2530Sstevel@tonic-gate return (FAILURE); 2540Sstevel@tonic-gate } 2550Sstevel@tonic-gate 2560Sstevel@tonic-gate /* need to get token3 first to satisfy nested strtok invocations */ 2570Sstevel@tonic-gate token3 = strtok(NULL, SEP_SEMICOLON); 2580Sstevel@tonic-gate 2590Sstevel@tonic-gate if (token2 && ((rc = parse_dislist(token2, pent)) != SUCCESS)) { 2600Sstevel@tonic-gate free_entry(pent); 2610Sstevel@tonic-gate return (rc); 2620Sstevel@tonic-gate } 2630Sstevel@tonic-gate 2640Sstevel@tonic-gate if (token3 && ((rc = parse_dislist(token3, pent)) != SUCCESS)) { 2650Sstevel@tonic-gate free_entry(pent); 2660Sstevel@tonic-gate return (rc); 2670Sstevel@tonic-gate } 2680Sstevel@tonic-gate 2690Sstevel@tonic-gate *ppent = pent; 2700Sstevel@tonic-gate return (SUCCESS); 2710Sstevel@tonic-gate } 2720Sstevel@tonic-gate 2730Sstevel@tonic-gate 2740Sstevel@tonic-gate /* 2750Sstevel@tonic-gate * Add an entry to the end of an entry list. If the entry list is NULL, will 2760Sstevel@tonic-gate * create an entry list with the pent. 2770Sstevel@tonic-gate */ 2780Sstevel@tonic-gate static int 2790Sstevel@tonic-gate build_entrylist(entry_t *pent, entrylist_t **pplist) 2800Sstevel@tonic-gate { 2810Sstevel@tonic-gate entrylist_t *pentlist; 2820Sstevel@tonic-gate entrylist_t *pcur; 2830Sstevel@tonic-gate 2840Sstevel@tonic-gate pentlist = malloc(sizeof (entrylist_t)); 2850Sstevel@tonic-gate if (pentlist == NULL) { 2860Sstevel@tonic-gate cryptodebug("out of memory."); 2870Sstevel@tonic-gate return (FAILURE); 2880Sstevel@tonic-gate } 2890Sstevel@tonic-gate pentlist->pent = pent; 2900Sstevel@tonic-gate pentlist->next = NULL; 2910Sstevel@tonic-gate 2920Sstevel@tonic-gate if (*pplist) { 2930Sstevel@tonic-gate pcur = *pplist; 2940Sstevel@tonic-gate while (pcur->next != NULL) 2950Sstevel@tonic-gate pcur = pcur->next; 2960Sstevel@tonic-gate pcur->next = pentlist; 2970Sstevel@tonic-gate } else { /* empty list */ 2980Sstevel@tonic-gate *pplist = pentlist; 2990Sstevel@tonic-gate } 3000Sstevel@tonic-gate 3010Sstevel@tonic-gate return (SUCCESS); 3020Sstevel@tonic-gate } 3030Sstevel@tonic-gate 3040Sstevel@tonic-gate 3050Sstevel@tonic-gate 3060Sstevel@tonic-gate /* 3070Sstevel@tonic-gate * Find the entry with the "provname" name from the entry list and duplicate 3080Sstevel@tonic-gate * it. 3090Sstevel@tonic-gate */ 3100Sstevel@tonic-gate static entry_t * 3110Sstevel@tonic-gate getent(char *provname, entrylist_t *entrylist) 3120Sstevel@tonic-gate { 3130Sstevel@tonic-gate boolean_t found = B_FALSE; 3140Sstevel@tonic-gate entry_t *pent1 = NULL; 3150Sstevel@tonic-gate 3160Sstevel@tonic-gate if ((provname == NULL) || (entrylist == NULL)) { 3170Sstevel@tonic-gate return (NULL); 3180Sstevel@tonic-gate } 3190Sstevel@tonic-gate 3200Sstevel@tonic-gate while (!found && entrylist) { 3210Sstevel@tonic-gate if (strcmp(entrylist->pent->name, provname) == 0) { 3220Sstevel@tonic-gate found = B_TRUE; 3230Sstevel@tonic-gate pent1 = entrylist->pent; 3240Sstevel@tonic-gate } else { 3250Sstevel@tonic-gate entrylist = entrylist->next; 3260Sstevel@tonic-gate } 3270Sstevel@tonic-gate } 3280Sstevel@tonic-gate 3290Sstevel@tonic-gate if (!found) { 3300Sstevel@tonic-gate return (NULL); 3310Sstevel@tonic-gate } 3320Sstevel@tonic-gate 3330Sstevel@tonic-gate /* duplicate the entry to be returned */ 3340Sstevel@tonic-gate return (dup_entry(pent1)); 3350Sstevel@tonic-gate } 3360Sstevel@tonic-gate 3370Sstevel@tonic-gate 3380Sstevel@tonic-gate 3390Sstevel@tonic-gate void 3400Sstevel@tonic-gate free_entry(entry_t *pent) 3410Sstevel@tonic-gate { 3420Sstevel@tonic-gate if (pent == NULL) { 3430Sstevel@tonic-gate return; 3440Sstevel@tonic-gate } else { 3450Sstevel@tonic-gate free_mechlist(pent->suplist); 3460Sstevel@tonic-gate free_mechlist(pent->dislist); 3470Sstevel@tonic-gate free(pent); 3480Sstevel@tonic-gate } 3490Sstevel@tonic-gate } 3500Sstevel@tonic-gate 3510Sstevel@tonic-gate 3520Sstevel@tonic-gate void 3530Sstevel@tonic-gate free_entrylist(entrylist_t *entrylist) 3540Sstevel@tonic-gate { 3550Sstevel@tonic-gate entrylist_t *pnext; 3560Sstevel@tonic-gate 3570Sstevel@tonic-gate while (entrylist != NULL) { 3580Sstevel@tonic-gate pnext = entrylist->next; 3590Sstevel@tonic-gate free_entry(entrylist->pent); 3600Sstevel@tonic-gate entrylist = pnext; 3610Sstevel@tonic-gate } 3620Sstevel@tonic-gate } 3630Sstevel@tonic-gate 3640Sstevel@tonic-gate 3650Sstevel@tonic-gate /* 3660Sstevel@tonic-gate * Convert an entry to a string. This routine builds a string for the entry 3670Sstevel@tonic-gate * to be inserted in the config file. Based on the content of each entry, 3680Sstevel@tonic-gate * the result string can be one of the 4 forms: 3690Sstevel@tonic-gate * - name 3700Sstevel@tonic-gate * - name:supportedlist=m1,m2,...,mj 3710Sstevel@tonic-gate * - name:disabledlist=m1,m2,...,mj 3720Sstevel@tonic-gate * - name:supportedlist=m1,...,mj;disabledlist=m1,m2,...,mk 3730Sstevel@tonic-gate * 3740Sstevel@tonic-gate * Note that the caller is responsible for freeing the returned string. 3750Sstevel@tonic-gate */ 3760Sstevel@tonic-gate char * 3770Sstevel@tonic-gate ent2str(entry_t *pent) 3780Sstevel@tonic-gate { 3790Sstevel@tonic-gate char *buf; 3800Sstevel@tonic-gate mechlist_t *phead; 3810Sstevel@tonic-gate boolean_t supflag = B_FALSE; 3820Sstevel@tonic-gate 3830Sstevel@tonic-gate 3840Sstevel@tonic-gate if (pent == NULL) { 3850Sstevel@tonic-gate return (NULL); 3860Sstevel@tonic-gate } 3870Sstevel@tonic-gate 3880Sstevel@tonic-gate if ((buf = malloc(BUFSIZ)) == NULL) { 3890Sstevel@tonic-gate return (NULL); 3900Sstevel@tonic-gate } 3910Sstevel@tonic-gate 3920Sstevel@tonic-gate /* convert the provider name */ 3930Sstevel@tonic-gate if (strlcpy(buf, pent->name, BUFSIZ) >= BUFSIZ) { 3940Sstevel@tonic-gate free(buf); 3950Sstevel@tonic-gate return (NULL); 3960Sstevel@tonic-gate } 3970Sstevel@tonic-gate 3980Sstevel@tonic-gate /* convert the supported list if any */ 3990Sstevel@tonic-gate phead = pent->suplist; 4000Sstevel@tonic-gate if (phead != NULL) { 4010Sstevel@tonic-gate supflag = B_TRUE; 4020Sstevel@tonic-gate 4030Sstevel@tonic-gate if (strlcat(buf, SEP_COLON, BUFSIZ) >= BUFSIZ) { 4040Sstevel@tonic-gate free(buf); 4050Sstevel@tonic-gate return (NULL); 4060Sstevel@tonic-gate } 4070Sstevel@tonic-gate 4080Sstevel@tonic-gate if (strlcat(buf, EF_SUPPORTED, BUFSIZ) >= BUFSIZ) { 4090Sstevel@tonic-gate free(buf); 4100Sstevel@tonic-gate return (NULL); 4110Sstevel@tonic-gate } 4120Sstevel@tonic-gate 4130Sstevel@tonic-gate while (phead != NULL) { 4140Sstevel@tonic-gate if (strlcat(buf, phead->name, BUFSIZ) >= BUFSIZ) { 4150Sstevel@tonic-gate free(buf); 4160Sstevel@tonic-gate return (NULL); 4170Sstevel@tonic-gate } 4180Sstevel@tonic-gate 4190Sstevel@tonic-gate phead = phead->next; 4200Sstevel@tonic-gate if (phead != NULL) { 4210Sstevel@tonic-gate if (strlcat(buf, SEP_COMMA, BUFSIZ) 4220Sstevel@tonic-gate >= BUFSIZ) { 4230Sstevel@tonic-gate free(buf); 4240Sstevel@tonic-gate return (NULL); 4250Sstevel@tonic-gate } 4260Sstevel@tonic-gate } 4270Sstevel@tonic-gate } 4280Sstevel@tonic-gate } 4290Sstevel@tonic-gate 4300Sstevel@tonic-gate /* convert the disabled list if any */ 4310Sstevel@tonic-gate phead = pent->dislist; 4320Sstevel@tonic-gate if (phead != NULL) { 4330Sstevel@tonic-gate if (supflag) { 4340Sstevel@tonic-gate if (strlcat(buf, ";disabledlist=", BUFSIZ) >= BUFSIZ) { 4350Sstevel@tonic-gate free(buf); 4360Sstevel@tonic-gate return (NULL); 4370Sstevel@tonic-gate } 4380Sstevel@tonic-gate } else { 4390Sstevel@tonic-gate if (strlcat(buf, ":disabledlist=", BUFSIZ) >= BUFSIZ) { 4400Sstevel@tonic-gate free(buf); 4410Sstevel@tonic-gate return (NULL); 4420Sstevel@tonic-gate } 4430Sstevel@tonic-gate } 4440Sstevel@tonic-gate 4450Sstevel@tonic-gate while (phead != NULL) { 4460Sstevel@tonic-gate if (strlcat(buf, phead->name, BUFSIZ) >= BUFSIZ) { 4470Sstevel@tonic-gate free(buf); 4480Sstevel@tonic-gate return (NULL); 4490Sstevel@tonic-gate } 4500Sstevel@tonic-gate 4510Sstevel@tonic-gate phead = phead->next; 4520Sstevel@tonic-gate if (phead != NULL) { 4530Sstevel@tonic-gate if (strlcat(buf, SEP_COMMA, BUFSIZ) 4540Sstevel@tonic-gate >= BUFSIZ) { 4550Sstevel@tonic-gate free(buf); 4560Sstevel@tonic-gate return (NULL); 4570Sstevel@tonic-gate } 4580Sstevel@tonic-gate } 4590Sstevel@tonic-gate } 4600Sstevel@tonic-gate } 4610Sstevel@tonic-gate 4620Sstevel@tonic-gate if (strlcat(buf, "\n", BUFSIZ) >= BUFSIZ) { 4630Sstevel@tonic-gate free(buf); 4640Sstevel@tonic-gate return (NULL); 4650Sstevel@tonic-gate } 4660Sstevel@tonic-gate 4670Sstevel@tonic-gate return (buf); 4680Sstevel@tonic-gate } 4690Sstevel@tonic-gate 4700Sstevel@tonic-gate 4710Sstevel@tonic-gate /* 4720Sstevel@tonic-gate * Enable the mechanisms for the provider pointed by *ppent. If allflag is 4730Sstevel@tonic-gate * TRUE, enable all. Otherwise, enable the mechanisms specified in the 3rd 4740Sstevel@tonic-gate * argument "mlist". The result will be stored in ppent also. 4750Sstevel@tonic-gate */ 4760Sstevel@tonic-gate int 4770Sstevel@tonic-gate enable_mechs(entry_t **ppent, boolean_t allflag, mechlist_t *mlist) 4780Sstevel@tonic-gate { 4790Sstevel@tonic-gate entry_t *pent; 4800Sstevel@tonic-gate mechlist_t *phead; /* the current and resulting disabled list */ 4810Sstevel@tonic-gate mechlist_t *ptr; 4820Sstevel@tonic-gate mechlist_t *pcur; 4830Sstevel@tonic-gate boolean_t found; 4840Sstevel@tonic-gate 4850Sstevel@tonic-gate pent = *ppent; 4860Sstevel@tonic-gate if (pent == NULL) { 4870Sstevel@tonic-gate return (FAILURE); 4880Sstevel@tonic-gate } 4890Sstevel@tonic-gate 4900Sstevel@tonic-gate if (allflag) { 4910Sstevel@tonic-gate free_mechlist(pent->dislist); 4920Sstevel@tonic-gate pent->dis_count = 0; 4930Sstevel@tonic-gate pent->dislist = NULL; 4940Sstevel@tonic-gate return (SUCCESS); 4950Sstevel@tonic-gate } 4960Sstevel@tonic-gate 4970Sstevel@tonic-gate /* 4980Sstevel@tonic-gate * for each mechanism in the to-be-enabled mechanism list, 4990Sstevel@tonic-gate * - check if it is in the current disabled list 5000Sstevel@tonic-gate * - if found, delete it from the disabled list 5010Sstevel@tonic-gate * otherwise, give a warning. 5020Sstevel@tonic-gate */ 5030Sstevel@tonic-gate ptr = mlist; 5040Sstevel@tonic-gate while (ptr != NULL) { 5050Sstevel@tonic-gate found = B_FALSE; 5060Sstevel@tonic-gate phead = pcur = pent->dislist; 5070Sstevel@tonic-gate while (!found && pcur) { 5080Sstevel@tonic-gate if (strcmp(pcur->name, ptr->name) == 0) { 5090Sstevel@tonic-gate found = B_TRUE; 5100Sstevel@tonic-gate } else { 5110Sstevel@tonic-gate phead = pcur; 5120Sstevel@tonic-gate pcur = pcur->next; 5130Sstevel@tonic-gate } 5140Sstevel@tonic-gate } 5150Sstevel@tonic-gate 5160Sstevel@tonic-gate if (found) { 5170Sstevel@tonic-gate if (phead == pcur) { 5180Sstevel@tonic-gate pent->dislist = pent->dislist->next; 5190Sstevel@tonic-gate free(pcur); 5200Sstevel@tonic-gate } else { 5210Sstevel@tonic-gate phead->next = pcur->next; 5220Sstevel@tonic-gate free(pcur); 5230Sstevel@tonic-gate } 5240Sstevel@tonic-gate pent->dis_count--; 5250Sstevel@tonic-gate } else { 5260Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext( 5270Sstevel@tonic-gate "(Warning) %1$s is either enabled already or not " 5280Sstevel@tonic-gate "a valid mechanism for %2$s"), ptr->name, 5290Sstevel@tonic-gate pent->name); 5300Sstevel@tonic-gate } 5310Sstevel@tonic-gate ptr = ptr->next; 5320Sstevel@tonic-gate } 5330Sstevel@tonic-gate 5340Sstevel@tonic-gate if (pent->dis_count == 0) { 5350Sstevel@tonic-gate pent->dislist = NULL; 5360Sstevel@tonic-gate } 5370Sstevel@tonic-gate 5380Sstevel@tonic-gate return (SUCCESS); 5390Sstevel@tonic-gate 5400Sstevel@tonic-gate } 5410Sstevel@tonic-gate 5420Sstevel@tonic-gate 5430Sstevel@tonic-gate boolean_t 5440Sstevel@tonic-gate is_device(char *path) 5450Sstevel@tonic-gate { 5460Sstevel@tonic-gate if (strchr(path, SEP_SLASH) != NULL) { 5470Sstevel@tonic-gate return (B_TRUE); 5480Sstevel@tonic-gate } else { 5490Sstevel@tonic-gate return (B_FALSE); 5500Sstevel@tonic-gate } 5510Sstevel@tonic-gate } 5520Sstevel@tonic-gate 5530Sstevel@tonic-gate /* 5540Sstevel@tonic-gate * Split a hardware provider name with the "name/inst_num" format into 5550Sstevel@tonic-gate * a name and a number. 5560Sstevel@tonic-gate */ 5570Sstevel@tonic-gate int 5580Sstevel@tonic-gate split_hw_provname(char *provname, char *pname, int *inst_num) 5590Sstevel@tonic-gate { 5600Sstevel@tonic-gate char name[MAXNAMELEN]; 5610Sstevel@tonic-gate char *inst_str; 5620Sstevel@tonic-gate 5630Sstevel@tonic-gate if (provname == NULL) { 5640Sstevel@tonic-gate return (FAILURE); 5650Sstevel@tonic-gate } 5660Sstevel@tonic-gate 5670Sstevel@tonic-gate (void) strlcpy(name, provname, MAXNAMELEN); 5680Sstevel@tonic-gate if (strtok(name, "/") == NULL) { 5690Sstevel@tonic-gate return (FAILURE); 5700Sstevel@tonic-gate } 5710Sstevel@tonic-gate 5720Sstevel@tonic-gate if ((inst_str = strtok(NULL, "/")) == NULL) { 5730Sstevel@tonic-gate return (FAILURE); 5740Sstevel@tonic-gate } 5750Sstevel@tonic-gate 5760Sstevel@tonic-gate (void) strlcpy(pname, name, MAXNAMELEN); 5770Sstevel@tonic-gate *inst_num = atoi(inst_str); 5780Sstevel@tonic-gate 5790Sstevel@tonic-gate return (SUCCESS); 5800Sstevel@tonic-gate } 5810Sstevel@tonic-gate 5820Sstevel@tonic-gate 5830Sstevel@tonic-gate /* 5840Sstevel@tonic-gate * Retrieve information from kcf.conf and build a device entry list and 5850Sstevel@tonic-gate * a software entry list 5860Sstevel@tonic-gate */ 5870Sstevel@tonic-gate int 5880Sstevel@tonic-gate get_kcfconf_info(entrylist_t **ppdevlist, entrylist_t **ppsoftlist) 5890Sstevel@tonic-gate { 5900Sstevel@tonic-gate FILE *pfile; 5910Sstevel@tonic-gate char buffer[BUFSIZ]; 5920Sstevel@tonic-gate int len; 5930Sstevel@tonic-gate entry_t *pent = NULL; 5940Sstevel@tonic-gate int rc = SUCCESS; 5950Sstevel@tonic-gate 5960Sstevel@tonic-gate if ((pfile = fopen(_PATH_KCF_CONF, "r")) == NULL) { 5970Sstevel@tonic-gate cryptodebug("failed to open the kcf.conf file for read only"); 5980Sstevel@tonic-gate return (FAILURE); 5990Sstevel@tonic-gate } 6000Sstevel@tonic-gate 6010Sstevel@tonic-gate *ppdevlist = NULL; 6020Sstevel@tonic-gate *ppsoftlist = NULL; 6030Sstevel@tonic-gate while (fgets(buffer, BUFSIZ, pfile) != NULL) { 6040Sstevel@tonic-gate if (buffer[0] == '#' || buffer[0] == ' ' || 6050Sstevel@tonic-gate buffer[0] == '\n'|| buffer[0] == '\t') { 6060Sstevel@tonic-gate continue; /* ignore comment lines */ 6070Sstevel@tonic-gate } 6080Sstevel@tonic-gate 6090Sstevel@tonic-gate len = strlen(buffer); 6100Sstevel@tonic-gate if (buffer[len-1] == '\n') { /* get rid of trailing '\n' */ 6110Sstevel@tonic-gate len--; 6120Sstevel@tonic-gate } 6130Sstevel@tonic-gate buffer[len] = '\0'; 6140Sstevel@tonic-gate 6150Sstevel@tonic-gate if ((rc = interpret(buffer, &pent)) == SUCCESS) { 6160Sstevel@tonic-gate if (is_device(pent->name)) { 6170Sstevel@tonic-gate rc = build_entrylist(pent, ppdevlist); 6180Sstevel@tonic-gate } else { 6190Sstevel@tonic-gate rc = build_entrylist(pent, ppsoftlist); 6200Sstevel@tonic-gate } 6210Sstevel@tonic-gate } else { 6220Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext( 6230Sstevel@tonic-gate "failed to parse configuration.")); 6240Sstevel@tonic-gate } 6250Sstevel@tonic-gate 6260Sstevel@tonic-gate if (rc != SUCCESS) { 6270Sstevel@tonic-gate free_entrylist(*ppdevlist); 6280Sstevel@tonic-gate free_entrylist(*ppsoftlist); 6290Sstevel@tonic-gate free_entry(pent); 6300Sstevel@tonic-gate break; 6310Sstevel@tonic-gate } 6320Sstevel@tonic-gate } 6330Sstevel@tonic-gate 6340Sstevel@tonic-gate (void) fclose(pfile); 6350Sstevel@tonic-gate return (rc); 6360Sstevel@tonic-gate } 6370Sstevel@tonic-gate 6380Sstevel@tonic-gate /* 6390Sstevel@tonic-gate * Retrieve information from admin device and build a device entry list and 6400Sstevel@tonic-gate * a software entry list. This is used where there is no kcf.conf, e.g. 6410Sstevel@tonic-gate * non-global zone. 6420Sstevel@tonic-gate */ 6430Sstevel@tonic-gate int 6440Sstevel@tonic-gate get_admindev_info(entrylist_t **ppdevlist, entrylist_t **ppsoftlist) 6450Sstevel@tonic-gate { 6460Sstevel@tonic-gate crypto_get_dev_list_t *pdevlist_kernel = NULL; 6470Sstevel@tonic-gate crypto_get_soft_list_t *psoftlist_kernel = NULL; 6480Sstevel@tonic-gate char *devname; 6490Sstevel@tonic-gate int inst_num; 6500Sstevel@tonic-gate int mcount; 6510Sstevel@tonic-gate mechlist_t *pmech; 6520Sstevel@tonic-gate entry_t *pent = NULL; 6530Sstevel@tonic-gate int i; 6540Sstevel@tonic-gate char *psoftname; 6550Sstevel@tonic-gate entrylist_t *tmp_pdev = NULL; 6560Sstevel@tonic-gate entrylist_t *tmp_psoft = NULL; 6570Sstevel@tonic-gate 6580Sstevel@tonic-gate if (get_dev_list(&pdevlist_kernel) != SUCCESS) { 6590Sstevel@tonic-gate cryptodebug("failed to get hardware provider list from kernel"); 6600Sstevel@tonic-gate return (FAILURE); 6610Sstevel@tonic-gate } 6620Sstevel@tonic-gate 6630Sstevel@tonic-gate for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) { 6640Sstevel@tonic-gate devname = pdevlist_kernel->dl_devs[i].le_dev_name; 6650Sstevel@tonic-gate inst_num = pdevlist_kernel->dl_devs[i].le_dev_instance; 6660Sstevel@tonic-gate mcount = pdevlist_kernel->dl_devs[i].le_mechanism_count; 6670Sstevel@tonic-gate 6680Sstevel@tonic-gate pmech = NULL; 6690Sstevel@tonic-gate if (get_dev_info(devname, inst_num, mcount, &pmech) != 6700Sstevel@tonic-gate SUCCESS) { 6710Sstevel@tonic-gate cryptodebug( 6720Sstevel@tonic-gate "failed to retrieve the mechanism list for %s/%d.", 6730Sstevel@tonic-gate devname, inst_num); 6740Sstevel@tonic-gate goto fail_out; 6750Sstevel@tonic-gate } 6760Sstevel@tonic-gate 6770Sstevel@tonic-gate if ((pent = malloc(sizeof (entry_t))) == NULL) { 6780Sstevel@tonic-gate cryptodebug("out of memory."); 6790Sstevel@tonic-gate free_mechlist(pmech); 6800Sstevel@tonic-gate goto fail_out; 6810Sstevel@tonic-gate } 6820Sstevel@tonic-gate 6830Sstevel@tonic-gate (void) strlcpy(pent->name, devname, MAXNAMELEN); 6840Sstevel@tonic-gate pent->suplist = pmech; 6850Sstevel@tonic-gate pent->sup_count = mcount; 6860Sstevel@tonic-gate pent->dislist = NULL; 6870Sstevel@tonic-gate pent->dis_count = 0; 6880Sstevel@tonic-gate 6890Sstevel@tonic-gate if (build_entrylist(pent, &tmp_pdev) != SUCCESS) { 6900Sstevel@tonic-gate goto fail_out; 6910Sstevel@tonic-gate } 6920Sstevel@tonic-gate 6930Sstevel@tonic-gate /* because incorporated in tmp_pdev */ 6940Sstevel@tonic-gate pent = NULL; 6950Sstevel@tonic-gate } 6960Sstevel@tonic-gate 6970Sstevel@tonic-gate free(pdevlist_kernel); 6980Sstevel@tonic-gate pdevlist_kernel = NULL; 6990Sstevel@tonic-gate 7000Sstevel@tonic-gate if (get_soft_list(&psoftlist_kernel) != SUCCESS) { 7010Sstevel@tonic-gate cryptodebug("failed to get software provider list from kernel"); 7020Sstevel@tonic-gate goto fail_out; 7030Sstevel@tonic-gate } 7040Sstevel@tonic-gate 7050Sstevel@tonic-gate for (i = 0, psoftname = psoftlist_kernel->sl_soft_names; 7060Sstevel@tonic-gate i < psoftlist_kernel->sl_soft_count; 7070Sstevel@tonic-gate i++, psoftname = psoftname + strlen(psoftname) + 1) { 7080Sstevel@tonic-gate pmech = NULL; 7090Sstevel@tonic-gate if (get_soft_info(psoftname, &pmech) != SUCCESS) { 7100Sstevel@tonic-gate cryptodebug( 7110Sstevel@tonic-gate "failed to retrieve the mechanism list for %s.", 7120Sstevel@tonic-gate psoftname); 7130Sstevel@tonic-gate goto fail_out; 7140Sstevel@tonic-gate } 7150Sstevel@tonic-gate 7160Sstevel@tonic-gate if ((pent = malloc(sizeof (entry_t))) == NULL) { 7170Sstevel@tonic-gate cryptodebug("out of memory."); 7180Sstevel@tonic-gate free_mechlist(pmech); 7190Sstevel@tonic-gate goto fail_out; 7200Sstevel@tonic-gate } 7210Sstevel@tonic-gate 7220Sstevel@tonic-gate (void) strlcpy(pent->name, psoftname, MAXNAMELEN); 7230Sstevel@tonic-gate pent->suplist = pmech; 7240Sstevel@tonic-gate pent->sup_count = get_mech_count(pmech); 7250Sstevel@tonic-gate pent->dislist = NULL; 7260Sstevel@tonic-gate pent->dis_count = 0; 7270Sstevel@tonic-gate 7280Sstevel@tonic-gate if (build_entrylist(pent, &tmp_psoft) != SUCCESS) { 7290Sstevel@tonic-gate goto fail_out; 7300Sstevel@tonic-gate } 7310Sstevel@tonic-gate } 7320Sstevel@tonic-gate 7330Sstevel@tonic-gate free(psoftlist_kernel); 7340Sstevel@tonic-gate psoftlist_kernel = NULL; 7350Sstevel@tonic-gate 7360Sstevel@tonic-gate *ppdevlist = tmp_pdev; 7370Sstevel@tonic-gate *ppsoftlist = tmp_psoft; 7380Sstevel@tonic-gate 7390Sstevel@tonic-gate return (SUCCESS); 7400Sstevel@tonic-gate 7410Sstevel@tonic-gate fail_out: 7420Sstevel@tonic-gate if (pent != NULL) 7430Sstevel@tonic-gate free_entry(pent); 7440Sstevel@tonic-gate 7450Sstevel@tonic-gate free_entrylist(tmp_pdev); 7460Sstevel@tonic-gate free_entrylist(tmp_psoft); 7470Sstevel@tonic-gate 7480Sstevel@tonic-gate if (pdevlist_kernel != NULL) 7490Sstevel@tonic-gate free(pdevlist_kernel); 7500Sstevel@tonic-gate if (psoftlist_kernel != NULL) 7510Sstevel@tonic-gate free(psoftlist_kernel); 7520Sstevel@tonic-gate 7530Sstevel@tonic-gate return (FAILURE); 7540Sstevel@tonic-gate } 7550Sstevel@tonic-gate 7560Sstevel@tonic-gate /* 7570Sstevel@tonic-gate * Find the entry in the "kcf.conf" file with "provname" as the provider name. 7580Sstevel@tonic-gate * Return the entry if found, otherwise return NULL. 7590Sstevel@tonic-gate */ 7600Sstevel@tonic-gate entry_t * 7610Sstevel@tonic-gate getent_kef(char *provname) 7620Sstevel@tonic-gate { 7630Sstevel@tonic-gate entrylist_t *pdevlist = NULL; 7640Sstevel@tonic-gate entrylist_t *psoftlist = NULL; 7650Sstevel@tonic-gate entry_t *pent = NULL; 7660Sstevel@tonic-gate 7670Sstevel@tonic-gate if (get_kcfconf_info(&pdevlist, &psoftlist) != SUCCESS) { 7680Sstevel@tonic-gate return (NULL); 7690Sstevel@tonic-gate } 7700Sstevel@tonic-gate 7710Sstevel@tonic-gate if (is_device(provname)) { 7720Sstevel@tonic-gate pent = getent(provname, pdevlist); 7730Sstevel@tonic-gate } else { 7740Sstevel@tonic-gate pent = getent(provname, psoftlist); 7750Sstevel@tonic-gate } 7760Sstevel@tonic-gate 7770Sstevel@tonic-gate free_entrylist(pdevlist); 7780Sstevel@tonic-gate free_entrylist(psoftlist); 7790Sstevel@tonic-gate 7800Sstevel@tonic-gate return (pent); 7810Sstevel@tonic-gate } 7820Sstevel@tonic-gate 7830Sstevel@tonic-gate /* 7840Sstevel@tonic-gate * Print out the provider name and the mechanism list. 7850Sstevel@tonic-gate */ 7860Sstevel@tonic-gate void 7870Sstevel@tonic-gate print_mechlist(char *provname, mechlist_t *pmechlist) 7880Sstevel@tonic-gate { 7890Sstevel@tonic-gate mechlist_t *ptr; 7900Sstevel@tonic-gate 7910Sstevel@tonic-gate if (provname == NULL) { 7920Sstevel@tonic-gate return; 7930Sstevel@tonic-gate } 7940Sstevel@tonic-gate 7950Sstevel@tonic-gate (void) printf("%s: ", provname); 7960Sstevel@tonic-gate if (pmechlist == NULL) { 7970Sstevel@tonic-gate (void) printf(gettext("No mechanisms presented.\n")); 7980Sstevel@tonic-gate return; 7990Sstevel@tonic-gate } 8000Sstevel@tonic-gate 8010Sstevel@tonic-gate ptr = pmechlist; 8020Sstevel@tonic-gate while (ptr != NULL) { 8030Sstevel@tonic-gate (void) printf("%s", ptr->name); 8040Sstevel@tonic-gate ptr = ptr->next; 8050Sstevel@tonic-gate if (ptr == NULL) { 8060Sstevel@tonic-gate (void) printf("\n"); 8070Sstevel@tonic-gate } else { 8080Sstevel@tonic-gate (void) printf(","); 8090Sstevel@tonic-gate } 8100Sstevel@tonic-gate } 8110Sstevel@tonic-gate } 8120Sstevel@tonic-gate 8130Sstevel@tonic-gate 8140Sstevel@tonic-gate /* 8150Sstevel@tonic-gate * Update the kcf.conf file based on the specified entry and the update mode. 8160Sstevel@tonic-gate * - If update_mode is MODIFY_MODE or DELETE_MODE, the entry with the same 8170Sstevel@tonic-gate * provider name will be modified or deleted. 8180Sstevel@tonic-gate * - If update_mode is ADD_MODE, this must be a hardware provider without 8190Sstevel@tonic-gate * an entry in the kcf.conf file yet. Need to locate its driver package 8200Sstevel@tonic-gate * bracket and insert an entry into the bracket. 8210Sstevel@tonic-gate */ 8220Sstevel@tonic-gate int 8230Sstevel@tonic-gate update_kcfconf(entry_t *pent, int update_mode) 8240Sstevel@tonic-gate { 8250Sstevel@tonic-gate boolean_t add_it = B_FALSE; 8260Sstevel@tonic-gate boolean_t delete_it = B_FALSE; 8270Sstevel@tonic-gate boolean_t found_package = B_FALSE; 8280Sstevel@tonic-gate boolean_t found_entry = B_FALSE; 8290Sstevel@tonic-gate FILE *pfile; 8300Sstevel@tonic-gate FILE *pfile_tmp; 8310Sstevel@tonic-gate char buffer[BUFSIZ]; 8320Sstevel@tonic-gate char buffer2[BUFSIZ]; 8330Sstevel@tonic-gate char devname[MAXNAMELEN]; 8340Sstevel@tonic-gate char tmpfile_name[MAXPATHLEN]; 8350Sstevel@tonic-gate char *name; 8360Sstevel@tonic-gate char *str; 8370Sstevel@tonic-gate char *new_str = NULL; 8380Sstevel@tonic-gate int inst_num; 8390Sstevel@tonic-gate int rc = SUCCESS; 8400Sstevel@tonic-gate 8410Sstevel@tonic-gate 8420Sstevel@tonic-gate if (pent == NULL) { 8430Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("internal error.")); 8440Sstevel@tonic-gate return (FAILURE); 8450Sstevel@tonic-gate } 8460Sstevel@tonic-gate 8470Sstevel@tonic-gate /* Check the update_mode */ 8480Sstevel@tonic-gate if (update_mode == ADD_MODE) { 8490Sstevel@tonic-gate add_it = B_TRUE; 8500Sstevel@tonic-gate /* Get the hardware provider name first */ 8510Sstevel@tonic-gate if (split_hw_provname(pent->name, devname, &inst_num) == 8520Sstevel@tonic-gate FAILURE) { 8530Sstevel@tonic-gate return (FAILURE); 8540Sstevel@tonic-gate } 8550Sstevel@tonic-gate 8560Sstevel@tonic-gate /* Convert the entry to be a string */ 8570Sstevel@tonic-gate if ((new_str = ent2str(pent)) == NULL) { 8580Sstevel@tonic-gate return (FAILURE); 8590Sstevel@tonic-gate } 8600Sstevel@tonic-gate } else if (update_mode == DELETE_MODE) { 8610Sstevel@tonic-gate delete_it = B_TRUE; 8620Sstevel@tonic-gate } else if (update_mode != MODIFY_MODE) { 8630Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("internal error.")); 8640Sstevel@tonic-gate return (FAILURE); 8650Sstevel@tonic-gate } 8660Sstevel@tonic-gate 8670Sstevel@tonic-gate 8680Sstevel@tonic-gate /* Open the kcf.conf file */ 8690Sstevel@tonic-gate if ((pfile = fopen(_PATH_KCF_CONF, "r+")) == NULL) { 8700Sstevel@tonic-gate err = errno; 8710Sstevel@tonic-gate cryptoerror(LOG_STDERR, 8720Sstevel@tonic-gate gettext("failed to update the configuration - %s"), 8730Sstevel@tonic-gate strerror(err)); 8740Sstevel@tonic-gate cryptodebug("failed to open %s for write.", _PATH_KCF_CONF); 8750Sstevel@tonic-gate return (FAILURE); 8760Sstevel@tonic-gate } 8770Sstevel@tonic-gate 8780Sstevel@tonic-gate /* Lock the kcf.conf file */ 8790Sstevel@tonic-gate if (lockf(fileno(pfile), F_TLOCK, 0) == -1) { 8800Sstevel@tonic-gate err = errno; 8810Sstevel@tonic-gate cryptoerror(LOG_STDERR, 8820Sstevel@tonic-gate gettext("failed to update the configuration - %s"), 8830Sstevel@tonic-gate strerror(err)); 8840Sstevel@tonic-gate (void) fclose(pfile); 8850Sstevel@tonic-gate return (FAILURE); 8860Sstevel@tonic-gate } 8870Sstevel@tonic-gate 8880Sstevel@tonic-gate /* 8890Sstevel@tonic-gate * Create a temporary file in the /etc/crypto directory to save 8900Sstevel@tonic-gate * updated configuration file first. 8910Sstevel@tonic-gate */ 8920Sstevel@tonic-gate (void) strlcpy(tmpfile_name, TMPFILE_TEMPLATE, sizeof (tmpfile_name)); 8930Sstevel@tonic-gate if (mkstemp(tmpfile_name) == -1) { 8940Sstevel@tonic-gate err = errno; 8950Sstevel@tonic-gate cryptoerror(LOG_STDERR, 8960Sstevel@tonic-gate gettext("failed to create a temporary file - %s"), 8970Sstevel@tonic-gate strerror(err)); 8980Sstevel@tonic-gate (void) fclose(pfile); 8990Sstevel@tonic-gate return (FAILURE); 9000Sstevel@tonic-gate } 9010Sstevel@tonic-gate 9020Sstevel@tonic-gate if ((pfile_tmp = fopen(tmpfile_name, "w")) == NULL) { 9030Sstevel@tonic-gate err = errno; 9040Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("failed to open %s - %s"), 9050Sstevel@tonic-gate tmpfile_name, strerror(err)); 9060Sstevel@tonic-gate (void) fclose(pfile); 9070Sstevel@tonic-gate return (FAILURE); 9080Sstevel@tonic-gate } 9090Sstevel@tonic-gate 9100Sstevel@tonic-gate /* 9110Sstevel@tonic-gate * Loop thru the entire kcf.conf file, insert, modify or delete 9120Sstevel@tonic-gate * an entry. 9130Sstevel@tonic-gate */ 9140Sstevel@tonic-gate while (fgets(buffer, BUFSIZ, pfile) != NULL) { 9150Sstevel@tonic-gate if (add_it) { 9160Sstevel@tonic-gate /* always keep the current line */ 9170Sstevel@tonic-gate if (fputs(buffer, pfile_tmp) == EOF) { 9180Sstevel@tonic-gate err = errno; 9190Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext( 9200Sstevel@tonic-gate "failed to write to a temp file: %s."), 9210Sstevel@tonic-gate strerror(err)); 9220Sstevel@tonic-gate rc = FAILURE; 9230Sstevel@tonic-gate break; 9240Sstevel@tonic-gate } 9250Sstevel@tonic-gate 9260Sstevel@tonic-gate /* 9270Sstevel@tonic-gate * If the current position is the beginning of a driver 9280Sstevel@tonic-gate * package and if the driver name matches the hardware 9290Sstevel@tonic-gate * provider name, then we want to insert the entry 9300Sstevel@tonic-gate * here. 9310Sstevel@tonic-gate */ 9320Sstevel@tonic-gate if ((strstr(buffer, HW_DRIVER_STRING) != NULL) && 9330Sstevel@tonic-gate (strstr(buffer, devname) != NULL)) { 9340Sstevel@tonic-gate found_package = B_TRUE; 9350Sstevel@tonic-gate if (fputs(new_str, pfile_tmp) == EOF) { 9360Sstevel@tonic-gate err = errno; 9370Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext( 9380Sstevel@tonic-gate "failed to write to a temp file: " 9390Sstevel@tonic-gate "%s."), strerror(err)); 9400Sstevel@tonic-gate rc = FAILURE; 9410Sstevel@tonic-gate break; 9420Sstevel@tonic-gate } 9430Sstevel@tonic-gate } 9440Sstevel@tonic-gate } else { /* modify or delete */ 9450Sstevel@tonic-gate found_entry = B_FALSE; 9460Sstevel@tonic-gate if (!(buffer[0] == '#' || buffer[0] == ' ' || 9470Sstevel@tonic-gate buffer[0] == '\n'|| buffer[0] == '\t')) { 9480Sstevel@tonic-gate /* 9490Sstevel@tonic-gate * Get the provider name from this line and 9500Sstevel@tonic-gate * check if this is the entry to be updated 9510Sstevel@tonic-gate * or deleted. Note: can not use "buffer" 9520Sstevel@tonic-gate * directly because strtok will change its 9530Sstevel@tonic-gate * value. 9540Sstevel@tonic-gate */ 9550Sstevel@tonic-gate (void) strlcpy(buffer2, buffer, BUFSIZ); 9560Sstevel@tonic-gate if ((name = strtok(buffer2, SEP_COLON)) == 9570Sstevel@tonic-gate NULL) { 9580Sstevel@tonic-gate rc = FAILURE; 9590Sstevel@tonic-gate break; 9600Sstevel@tonic-gate } 9610Sstevel@tonic-gate 9620Sstevel@tonic-gate if (strcmp(pent->name, name) == 0) { 9630Sstevel@tonic-gate found_entry = B_TRUE; 9640Sstevel@tonic-gate } 9650Sstevel@tonic-gate } 9660Sstevel@tonic-gate 9670Sstevel@tonic-gate if (found_entry && !delete_it) { 9680Sstevel@tonic-gate /* 9690Sstevel@tonic-gate * This is the entry to be updated; get the 9700Sstevel@tonic-gate * updated string and place into buffer. 9710Sstevel@tonic-gate */ 9720Sstevel@tonic-gate if ((str = ent2str(pent)) == NULL) { 9730Sstevel@tonic-gate rc = FAILURE; 9740Sstevel@tonic-gate break; 9750Sstevel@tonic-gate } else { 9760Sstevel@tonic-gate (void) strlcpy(buffer, str, BUFSIZ); 9770Sstevel@tonic-gate free(str); 9780Sstevel@tonic-gate } 9790Sstevel@tonic-gate } 9800Sstevel@tonic-gate 9810Sstevel@tonic-gate if (!(found_entry && delete_it)) { 9820Sstevel@tonic-gate /* This is the entry to be updated/reserved */ 9830Sstevel@tonic-gate if (fputs(buffer, pfile_tmp) == EOF) { 9840Sstevel@tonic-gate err = errno; 9850Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext( 9860Sstevel@tonic-gate "failed to write to a temp file: " 9870Sstevel@tonic-gate "%s."), strerror(err)); 9880Sstevel@tonic-gate rc = FAILURE; 9890Sstevel@tonic-gate break; 9900Sstevel@tonic-gate } 9910Sstevel@tonic-gate } 9920Sstevel@tonic-gate } 9930Sstevel@tonic-gate } 9940Sstevel@tonic-gate 9950Sstevel@tonic-gate if (add_it) { 9960Sstevel@tonic-gate free(new_str); 9970Sstevel@tonic-gate } 9980Sstevel@tonic-gate 9990Sstevel@tonic-gate if ((add_it && !found_package) || (rc == FAILURE)) { 10000Sstevel@tonic-gate if (add_it && !found_package) { 10010Sstevel@tonic-gate cryptoerror(LOG_STDERR, 10020Sstevel@tonic-gate gettext("failed to update configuration - no " 10030Sstevel@tonic-gate "driver package information.")); 10040Sstevel@tonic-gate } 10050Sstevel@tonic-gate 10060Sstevel@tonic-gate (void) fclose(pfile); 10070Sstevel@tonic-gate (void) fclose(pfile_tmp); 10080Sstevel@tonic-gate if (unlink(tmpfile_name) != 0) { 10090Sstevel@tonic-gate err = errno; 10100Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext( 10110Sstevel@tonic-gate "(Warning) failed to remove %s: %s"), 10120Sstevel@tonic-gate tmpfile_name, strerror(err)); 10130Sstevel@tonic-gate } 10140Sstevel@tonic-gate return (FAILURE); 10150Sstevel@tonic-gate } 10160Sstevel@tonic-gate 10170Sstevel@tonic-gate (void) fclose(pfile); 10180Sstevel@tonic-gate if (fclose(pfile_tmp) != 0) { 10190Sstevel@tonic-gate err = errno; 10200Sstevel@tonic-gate cryptoerror(LOG_STDERR, 10210Sstevel@tonic-gate gettext("failed to close %s: %s"), tmpfile_name, 10220Sstevel@tonic-gate strerror(err)); 10230Sstevel@tonic-gate return (FAILURE); 10240Sstevel@tonic-gate } 10250Sstevel@tonic-gate 10260Sstevel@tonic-gate /* Copy the temporary file to the kcf.conf file */ 10270Sstevel@tonic-gate if (rename(tmpfile_name, _PATH_KCF_CONF) == -1) { 10280Sstevel@tonic-gate err = errno; 10290Sstevel@tonic-gate cryptoerror(LOG_STDERR, 10300Sstevel@tonic-gate gettext("failed to update the configuration - %s"), 10310Sstevel@tonic-gate strerror(err)); 10320Sstevel@tonic-gate cryptodebug("failed to rename %s to %s: %s", tmpfile, 10330Sstevel@tonic-gate _PATH_KCF_CONF, strerror(err)); 10340Sstevel@tonic-gate rc = FAILURE; 10350Sstevel@tonic-gate } else if (chmod(_PATH_KCF_CONF, 10360Sstevel@tonic-gate S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) { 10370Sstevel@tonic-gate err = errno; 10380Sstevel@tonic-gate cryptoerror(LOG_STDERR, 10390Sstevel@tonic-gate gettext("failed to update the configuration - %s"), 10400Sstevel@tonic-gate strerror(err)); 10410Sstevel@tonic-gate cryptodebug("failed to chmod to %s: %s", _PATH_KCF_CONF, 10420Sstevel@tonic-gate strerror(err)); 10430Sstevel@tonic-gate rc = FAILURE; 10440Sstevel@tonic-gate } else { 10450Sstevel@tonic-gate rc = SUCCESS; 10460Sstevel@tonic-gate } 10470Sstevel@tonic-gate 10480Sstevel@tonic-gate if ((rc == FAILURE) && (unlink(tmpfile_name) != 0)) { 10490Sstevel@tonic-gate err = errno; 10500Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext( 10510Sstevel@tonic-gate "(Warning) failed to remove %s: %s"), 10520Sstevel@tonic-gate tmpfile_name, strerror(err)); 10530Sstevel@tonic-gate } 10540Sstevel@tonic-gate 10550Sstevel@tonic-gate return (rc); 10560Sstevel@tonic-gate } 10570Sstevel@tonic-gate 10580Sstevel@tonic-gate 10590Sstevel@tonic-gate /* 10600Sstevel@tonic-gate * Disable the mechanisms for the provider pointed by *ppent. If allflag is 10610Sstevel@tonic-gate * TRUE, disable all. Otherwise, disable the mechanisms specified in the 10620Sstevel@tonic-gate * dislist argument. The "infolist" argument contains the mechanism list 10630Sstevel@tonic-gate * supported by this provider. 10640Sstevel@tonic-gate */ 10650Sstevel@tonic-gate int 10660Sstevel@tonic-gate disable_mechs(entry_t **ppent, mechlist_t *infolist, boolean_t allflag, 10670Sstevel@tonic-gate mechlist_t *dislist) 10680Sstevel@tonic-gate { 10690Sstevel@tonic-gate entry_t *pent; 10700Sstevel@tonic-gate mechlist_t *plist; 10710Sstevel@tonic-gate mechlist_t *phead; 10720Sstevel@tonic-gate mechlist_t *pmech; 10730Sstevel@tonic-gate int rc = SUCCESS; 10740Sstevel@tonic-gate 10750Sstevel@tonic-gate pent = *ppent; 10760Sstevel@tonic-gate if (pent == NULL) { 10770Sstevel@tonic-gate return (FAILURE); 10780Sstevel@tonic-gate } 10790Sstevel@tonic-gate 10800Sstevel@tonic-gate if (allflag) { 10810Sstevel@tonic-gate free_mechlist(pent->dislist); 10820Sstevel@tonic-gate pent->dis_count = get_mech_count(infolist); 10830Sstevel@tonic-gate if (!(pent->dislist = dup_mechlist(infolist))) { 10840Sstevel@tonic-gate return (FAILURE); 10850Sstevel@tonic-gate } else { 10860Sstevel@tonic-gate return (SUCCESS); 10870Sstevel@tonic-gate } 10880Sstevel@tonic-gate } 10890Sstevel@tonic-gate 10900Sstevel@tonic-gate /* 10910Sstevel@tonic-gate * Not disable all. Now loop thru the mechanisms specified in the 10920Sstevel@tonic-gate * dislist. If the mechanism is not supported by the provider, 10930Sstevel@tonic-gate * ignore it with a warning. If the mechanism is disabled already, 10940Sstevel@tonic-gate * do nothing. Otherwise, prepend it to the beginning of the disabled 10950Sstevel@tonic-gate * list of the provider. 10960Sstevel@tonic-gate */ 10970Sstevel@tonic-gate plist = dislist; 10980Sstevel@tonic-gate while (plist != NULL) { 10990Sstevel@tonic-gate if (!is_in_list(plist->name, infolist)) { 11000Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("(Warning) " 11010Sstevel@tonic-gate "%1$s is not a valid mechanism for %2$s."), 11020Sstevel@tonic-gate plist->name, pent->name); 11030Sstevel@tonic-gate } else if (!is_in_list(plist->name, pent->dislist)) { 11040Sstevel@tonic-gate /* Add this mechanism into the disabled list */ 11050Sstevel@tonic-gate if ((pmech = create_mech(plist->name)) == NULL) { 11060Sstevel@tonic-gate rc = FAILURE; 11070Sstevel@tonic-gate break; 11080Sstevel@tonic-gate } 11090Sstevel@tonic-gate 11100Sstevel@tonic-gate if (pent->dislist == NULL) { 11110Sstevel@tonic-gate pent->dislist = pmech; 11120Sstevel@tonic-gate } else { 11130Sstevel@tonic-gate phead = pent->dislist; 11140Sstevel@tonic-gate pent->dislist = pmech; 11150Sstevel@tonic-gate pmech->next = phead; 11160Sstevel@tonic-gate } 11170Sstevel@tonic-gate pent->dis_count++; 11180Sstevel@tonic-gate } 11190Sstevel@tonic-gate plist = plist->next; 11200Sstevel@tonic-gate } 11210Sstevel@tonic-gate 11220Sstevel@tonic-gate return (rc); 11230Sstevel@tonic-gate } 11240Sstevel@tonic-gate 11250Sstevel@tonic-gate /* 11260Sstevel@tonic-gate * Remove the mechanism passed, specified by mech, from the list of 11270Sstevel@tonic-gate * mechanisms, if present in the list. Else, do nothing. 11280Sstevel@tonic-gate * 11290Sstevel@tonic-gate * Returns B_TRUE if mechanism is present in the list. 11300Sstevel@tonic-gate */ 11310Sstevel@tonic-gate boolean_t 11320Sstevel@tonic-gate filter_mechlist(mechlist_t **pmechlist, const char *mech) 11330Sstevel@tonic-gate { 11340Sstevel@tonic-gate int cnt = 0; 11350Sstevel@tonic-gate mechlist_t *ptr, *pptr; 11360Sstevel@tonic-gate boolean_t mech_present = B_FALSE; 11370Sstevel@tonic-gate 11380Sstevel@tonic-gate ptr = pptr = *pmechlist; 11390Sstevel@tonic-gate 11400Sstevel@tonic-gate while (ptr != NULL) { 11410Sstevel@tonic-gate if (strncmp(ptr->name, mech, sizeof (mech_name_t)) == 0) { 11420Sstevel@tonic-gate mech_present = B_TRUE; 11430Sstevel@tonic-gate if (ptr == *pmechlist) { 11440Sstevel@tonic-gate pptr = *pmechlist = ptr->next; 11450Sstevel@tonic-gate free(ptr); 11460Sstevel@tonic-gate ptr = pptr; 11470Sstevel@tonic-gate } else { 11480Sstevel@tonic-gate pptr->next = ptr->next; 11490Sstevel@tonic-gate free(ptr); 11500Sstevel@tonic-gate ptr = pptr->next; 11510Sstevel@tonic-gate } 11520Sstevel@tonic-gate } else { 11530Sstevel@tonic-gate pptr = ptr; 11540Sstevel@tonic-gate ptr = ptr->next; 11550Sstevel@tonic-gate cnt++; 11560Sstevel@tonic-gate } 11570Sstevel@tonic-gate } 11580Sstevel@tonic-gate 11590Sstevel@tonic-gate /* Only one entry is present */ 11600Sstevel@tonic-gate if (cnt == 0) 11610Sstevel@tonic-gate *pmechlist = NULL; 11620Sstevel@tonic-gate 11630Sstevel@tonic-gate return (mech_present); 11640Sstevel@tonic-gate } 11650Sstevel@tonic-gate 11660Sstevel@tonic-gate 11670Sstevel@tonic-gate 11680Sstevel@tonic-gate /* 11690Sstevel@tonic-gate * Print out the mechanism policy for a kernel provider that has an entry 11700Sstevel@tonic-gate * in the kcf.conf file. 11710Sstevel@tonic-gate * 11720Sstevel@tonic-gate * The flag has_random is set to B_TRUE if the provider does random 11730Sstevel@tonic-gate * numbers. The flag has_mechs is set by the caller to B_TRUE if the provider 11740Sstevel@tonic-gate * has some mechanisms. 11750Sstevel@tonic-gate */ 11760Sstevel@tonic-gate void 11770Sstevel@tonic-gate print_kef_policy(entry_t *pent, boolean_t has_random, boolean_t has_mechs) 11780Sstevel@tonic-gate { 11790Sstevel@tonic-gate mechlist_t *ptr; 11800Sstevel@tonic-gate boolean_t rnd_disabled = B_FALSE; 11810Sstevel@tonic-gate 11820Sstevel@tonic-gate if (pent == NULL) { 11830Sstevel@tonic-gate return; 11840Sstevel@tonic-gate } 11850Sstevel@tonic-gate 11860Sstevel@tonic-gate rnd_disabled = filter_mechlist(&pent->dislist, RANDOM); 11870Sstevel@tonic-gate ptr = pent->dislist; 11880Sstevel@tonic-gate 11890Sstevel@tonic-gate (void) printf("%s:", pent->name); 11900Sstevel@tonic-gate 11910Sstevel@tonic-gate if (has_mechs == B_TRUE) { 11920Sstevel@tonic-gate /* 1193*7334SDaniel.Anderson@Sun.COM * TRANSLATION_NOTE 11940Sstevel@tonic-gate * This code block may need to be modified a bit to avoid 11950Sstevel@tonic-gate * constructing the text message on the fly. 11960Sstevel@tonic-gate */ 11970Sstevel@tonic-gate (void) printf(gettext(" all mechanisms are enabled")); 11980Sstevel@tonic-gate if (ptr != NULL) 11990Sstevel@tonic-gate (void) printf(gettext(", except ")); 12000Sstevel@tonic-gate while (ptr != NULL) { 12010Sstevel@tonic-gate (void) printf("%s", ptr->name); 12020Sstevel@tonic-gate ptr = ptr->next; 12030Sstevel@tonic-gate if (ptr != NULL) 12040Sstevel@tonic-gate (void) printf(","); 12050Sstevel@tonic-gate } 12060Sstevel@tonic-gate if (ptr == NULL) 12070Sstevel@tonic-gate (void) printf("."); 12080Sstevel@tonic-gate } 12090Sstevel@tonic-gate 12100Sstevel@tonic-gate /* 1211*7334SDaniel.Anderson@Sun.COM * TRANSLATION_NOTE 12120Sstevel@tonic-gate * "random" is a keyword and not to be translated. 12130Sstevel@tonic-gate */ 12140Sstevel@tonic-gate if (rnd_disabled) 12150Sstevel@tonic-gate (void) printf(gettext(" %s is disabled."), "random"); 12160Sstevel@tonic-gate else if (has_random) 12170Sstevel@tonic-gate (void) printf(gettext(" %s is enabled."), "random"); 12180Sstevel@tonic-gate (void) printf("\n"); 12190Sstevel@tonic-gate } 12200Sstevel@tonic-gate 12210Sstevel@tonic-gate /* 12220Sstevel@tonic-gate * Check if a kernel software provider is in the kernel. 12230Sstevel@tonic-gate */ 12240Sstevel@tonic-gate int 12250Sstevel@tonic-gate check_active_for_soft(char *provname, boolean_t *is_active) 12260Sstevel@tonic-gate { 12270Sstevel@tonic-gate crypto_get_soft_list_t *psoftlist_kernel = NULL; 12280Sstevel@tonic-gate char *ptr; 12290Sstevel@tonic-gate int i; 12300Sstevel@tonic-gate 12310Sstevel@tonic-gate if (provname == NULL) { 12320Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("internal error.")); 12330Sstevel@tonic-gate return (FAILURE); 12340Sstevel@tonic-gate } 12350Sstevel@tonic-gate 12360Sstevel@tonic-gate if (get_soft_list(&psoftlist_kernel) == FAILURE) { 12370Sstevel@tonic-gate cryptodebug("failed to get the software provider list from" 12380Sstevel@tonic-gate "kernel."); 12390Sstevel@tonic-gate return (FAILURE); 12400Sstevel@tonic-gate } 12410Sstevel@tonic-gate 12420Sstevel@tonic-gate *is_active = B_FALSE; 12430Sstevel@tonic-gate ptr = psoftlist_kernel->sl_soft_names; 12440Sstevel@tonic-gate for (i = 0; i < psoftlist_kernel->sl_soft_count; i++) { 12450Sstevel@tonic-gate if (strcmp(provname, ptr) == 0) { 12460Sstevel@tonic-gate *is_active = B_TRUE; 12470Sstevel@tonic-gate break; 12480Sstevel@tonic-gate } 12490Sstevel@tonic-gate ptr = ptr + strlen(ptr) + 1; 12500Sstevel@tonic-gate } 12510Sstevel@tonic-gate free(psoftlist_kernel); 12520Sstevel@tonic-gate 12530Sstevel@tonic-gate return (SUCCESS); 12540Sstevel@tonic-gate } 12550Sstevel@tonic-gate 12560Sstevel@tonic-gate 12570Sstevel@tonic-gate /* 12580Sstevel@tonic-gate * Check if a kernel hardware provider is in the kernel. 12590Sstevel@tonic-gate */ 12600Sstevel@tonic-gate int 12610Sstevel@tonic-gate check_active_for_hard(char *provname, boolean_t *is_active) 12620Sstevel@tonic-gate { 12630Sstevel@tonic-gate crypto_get_dev_list_t *pdevlist = NULL; 12640Sstevel@tonic-gate char devname[MAXNAMELEN]; 12650Sstevel@tonic-gate int inst_num; 12660Sstevel@tonic-gate int i; 12670Sstevel@tonic-gate 12680Sstevel@tonic-gate if (provname == NULL) { 12690Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("internal error.")); 12700Sstevel@tonic-gate return (FAILURE); 12710Sstevel@tonic-gate } 12720Sstevel@tonic-gate 12730Sstevel@tonic-gate if (split_hw_provname(provname, devname, &inst_num) == FAILURE) { 12740Sstevel@tonic-gate return (FAILURE); 12750Sstevel@tonic-gate } 12760Sstevel@tonic-gate 12770Sstevel@tonic-gate if (get_dev_list(&pdevlist) == FAILURE) { 12780Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("internal error.")); 12790Sstevel@tonic-gate return (FAILURE); 12800Sstevel@tonic-gate } 12810Sstevel@tonic-gate 12820Sstevel@tonic-gate *is_active = B_FALSE; 12830Sstevel@tonic-gate for (i = 0; i < pdevlist->dl_dev_count; i++) { 12840Sstevel@tonic-gate if ((strcmp(pdevlist->dl_devs[i].le_dev_name, devname) == 0) && 12850Sstevel@tonic-gate (pdevlist->dl_devs[i].le_dev_instance == inst_num)) { 12860Sstevel@tonic-gate *is_active = B_TRUE; 12870Sstevel@tonic-gate break; 12880Sstevel@tonic-gate } 12890Sstevel@tonic-gate } 12900Sstevel@tonic-gate free(pdevlist); 12910Sstevel@tonic-gate 12920Sstevel@tonic-gate return (SUCCESS); 12930Sstevel@tonic-gate } 1294