17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
50a85b835SDaniel Anderson * Common Development and Distribution License (the "License").
60a85b835SDaniel Anderson * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
22ddcb6370SDan OpenSolaris Anderson * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate #include <errno.h>
277c478bd9Sstevel@tonic-gate #include <fcntl.h>
287c478bd9Sstevel@tonic-gate #include <stdio.h>
297c478bd9Sstevel@tonic-gate #include <stdlib.h>
307c478bd9Sstevel@tonic-gate #include <strings.h>
317c478bd9Sstevel@tonic-gate #include <time.h>
327c478bd9Sstevel@tonic-gate #include <unistd.h>
337c478bd9Sstevel@tonic-gate #include <locale.h>
347c478bd9Sstevel@tonic-gate #include <sys/types.h>
351b22764fSDaniel OpenSolaris Anderson #include <zone.h>
367c478bd9Sstevel@tonic-gate #include <sys/stat.h>
377c478bd9Sstevel@tonic-gate #include "cryptoadm.h"
387c478bd9Sstevel@tonic-gate
397c478bd9Sstevel@tonic-gate static int err; /* To store errno which may be overwritten by gettext() */
40*0f5cc0e1SDan OpenSolaris Anderson static int build_entrylist(entry_t *pent, entrylist_t **pplist);
41*0f5cc0e1SDan OpenSolaris Anderson static entry_t *dup_entry(entry_t *pent1);
42*0f5cc0e1SDan OpenSolaris Anderson static mechlist_t *dup_mechlist(mechlist_t *plist);
43*0f5cc0e1SDan OpenSolaris Anderson static entry_t *getent(char *provname, entrylist_t *entrylist);
44*0f5cc0e1SDan OpenSolaris Anderson static int interpret(char *buf, entry_t **ppent);
45ddcb6370SDan OpenSolaris Anderson static int parse_sup_dis_list(const char *buf, entry_t *pent);
467c478bd9Sstevel@tonic-gate
477c478bd9Sstevel@tonic-gate
487c478bd9Sstevel@tonic-gate /*
497c478bd9Sstevel@tonic-gate * Duplicate the mechanism list. A null pointer is returned if the storage
507c478bd9Sstevel@tonic-gate * space available is insufficient or the input argument is NULL.
517c478bd9Sstevel@tonic-gate */
527c478bd9Sstevel@tonic-gate static mechlist_t *
dup_mechlist(mechlist_t * plist)537c478bd9Sstevel@tonic-gate dup_mechlist(mechlist_t *plist)
547c478bd9Sstevel@tonic-gate {
557c478bd9Sstevel@tonic-gate mechlist_t *pres = NULL;
567c478bd9Sstevel@tonic-gate mechlist_t *pcur;
577c478bd9Sstevel@tonic-gate mechlist_t *ptmp;
587c478bd9Sstevel@tonic-gate int rc = SUCCESS;
597c478bd9Sstevel@tonic-gate
607c478bd9Sstevel@tonic-gate while (plist != NULL) {
617c478bd9Sstevel@tonic-gate if (!(ptmp = create_mech(plist->name))) {
627c478bd9Sstevel@tonic-gate rc = FAILURE;
637c478bd9Sstevel@tonic-gate break;
647c478bd9Sstevel@tonic-gate }
657c478bd9Sstevel@tonic-gate
667c478bd9Sstevel@tonic-gate if (pres == NULL) {
677c478bd9Sstevel@tonic-gate pres = pcur = ptmp;
687c478bd9Sstevel@tonic-gate } else {
697c478bd9Sstevel@tonic-gate pcur->next = ptmp;
707c478bd9Sstevel@tonic-gate pcur = pcur->next;
717c478bd9Sstevel@tonic-gate }
727c478bd9Sstevel@tonic-gate plist = plist->next;
737c478bd9Sstevel@tonic-gate }
747c478bd9Sstevel@tonic-gate
757c478bd9Sstevel@tonic-gate if (rc != SUCCESS) {
767c478bd9Sstevel@tonic-gate free_mechlist(pres);
777c478bd9Sstevel@tonic-gate return (NULL);
787c478bd9Sstevel@tonic-gate }
797c478bd9Sstevel@tonic-gate
807c478bd9Sstevel@tonic-gate return (pres);
817c478bd9Sstevel@tonic-gate }
827c478bd9Sstevel@tonic-gate
837c478bd9Sstevel@tonic-gate
847c478bd9Sstevel@tonic-gate /*
857c478bd9Sstevel@tonic-gate * Get the number of mechanisms in the mechanism list.
867c478bd9Sstevel@tonic-gate */
877c478bd9Sstevel@tonic-gate int
get_mech_count(mechlist_t * plist)887c478bd9Sstevel@tonic-gate get_mech_count(mechlist_t *plist)
897c478bd9Sstevel@tonic-gate {
907c478bd9Sstevel@tonic-gate int count = 0;
917c478bd9Sstevel@tonic-gate
927c478bd9Sstevel@tonic-gate while (plist != NULL) {
937c478bd9Sstevel@tonic-gate count++;
947c478bd9Sstevel@tonic-gate plist = plist->next;
957c478bd9Sstevel@tonic-gate }
967c478bd9Sstevel@tonic-gate return (count);
977c478bd9Sstevel@tonic-gate }
987c478bd9Sstevel@tonic-gate
991b22764fSDaniel OpenSolaris Anderson /*
1001b22764fSDaniel OpenSolaris Anderson * Create one item of type entry_t with the provider name.
1011b22764fSDaniel OpenSolaris Anderson * Return NULL if there's not enough memory or provname is NULL.
1021b22764fSDaniel OpenSolaris Anderson */
1031b22764fSDaniel OpenSolaris Anderson entry_t *
create_entry(char * provname)1041b22764fSDaniel OpenSolaris Anderson create_entry(char *provname)
1051b22764fSDaniel OpenSolaris Anderson {
1061b22764fSDaniel OpenSolaris Anderson entry_t *pent = NULL;
1071b22764fSDaniel OpenSolaris Anderson
1081b22764fSDaniel OpenSolaris Anderson if (provname == NULL) {
1091b22764fSDaniel OpenSolaris Anderson return (NULL);
1101b22764fSDaniel OpenSolaris Anderson }
1111b22764fSDaniel OpenSolaris Anderson
1121b22764fSDaniel OpenSolaris Anderson pent = calloc(1, sizeof (entry_t));
1131b22764fSDaniel OpenSolaris Anderson if (pent == NULL) {
1141b22764fSDaniel OpenSolaris Anderson cryptodebug("out of memory.");
1151b22764fSDaniel OpenSolaris Anderson return (NULL);
1161b22764fSDaniel OpenSolaris Anderson }
1171b22764fSDaniel OpenSolaris Anderson
1181b22764fSDaniel OpenSolaris Anderson (void) strlcpy(pent->name, provname, MAXNAMELEN);
1191b22764fSDaniel OpenSolaris Anderson pent->suplist = NULL;
1201b22764fSDaniel OpenSolaris Anderson pent->sup_count = 0;
1211b22764fSDaniel OpenSolaris Anderson pent->dislist = NULL;
1221b22764fSDaniel OpenSolaris Anderson pent->dis_count = 0;
1231b22764fSDaniel OpenSolaris Anderson pent->load = B_TRUE;
1241b22764fSDaniel OpenSolaris Anderson
1251b22764fSDaniel OpenSolaris Anderson return (pent);
1261b22764fSDaniel OpenSolaris Anderson }
1277c478bd9Sstevel@tonic-gate
1287c478bd9Sstevel@tonic-gate /*
1291b22764fSDaniel OpenSolaris Anderson * Duplicate an entry for a provider from kcf.conf.
1301b22764fSDaniel OpenSolaris Anderson * Return NULL if memory is insufficient or the input argument is NULL.
1311b22764fSDaniel OpenSolaris Anderson * Called by getent().
1327c478bd9Sstevel@tonic-gate */
1337c478bd9Sstevel@tonic-gate static entry_t *
dup_entry(entry_t * pent1)1347c478bd9Sstevel@tonic-gate dup_entry(entry_t *pent1)
1357c478bd9Sstevel@tonic-gate {
1367c478bd9Sstevel@tonic-gate entry_t *pent2 = NULL;
1377c478bd9Sstevel@tonic-gate
1387c478bd9Sstevel@tonic-gate if (pent1 == NULL) {
1397c478bd9Sstevel@tonic-gate return (NULL);
1407c478bd9Sstevel@tonic-gate }
1417c478bd9Sstevel@tonic-gate
1421b22764fSDaniel OpenSolaris Anderson if ((pent2 = create_entry(pent1->name)) == NULL) {
1437c478bd9Sstevel@tonic-gate cryptodebug("out of memory.");
1447c478bd9Sstevel@tonic-gate return (NULL);
1457c478bd9Sstevel@tonic-gate }
1467c478bd9Sstevel@tonic-gate
1477c478bd9Sstevel@tonic-gate pent2->sup_count = pent1->sup_count;
1487c478bd9Sstevel@tonic-gate pent2->dis_count = pent1->dis_count;
1491b22764fSDaniel OpenSolaris Anderson pent2->load = pent1->load;
1507c478bd9Sstevel@tonic-gate if (pent1->suplist != NULL) {
1517c478bd9Sstevel@tonic-gate pent2->suplist = dup_mechlist(pent1->suplist);
1527c478bd9Sstevel@tonic-gate if (pent2->suplist == NULL) {
1537c478bd9Sstevel@tonic-gate free_entry(pent2);
1547c478bd9Sstevel@tonic-gate return (NULL);
1557c478bd9Sstevel@tonic-gate }
1567c478bd9Sstevel@tonic-gate }
1577c478bd9Sstevel@tonic-gate if (pent1->dislist != NULL) {
1587c478bd9Sstevel@tonic-gate pent2->dislist = dup_mechlist(pent1->dislist);
1597c478bd9Sstevel@tonic-gate if (pent2->dislist == NULL) {
1607c478bd9Sstevel@tonic-gate free_entry(pent2);
1617c478bd9Sstevel@tonic-gate return (NULL);
1627c478bd9Sstevel@tonic-gate }
1637c478bd9Sstevel@tonic-gate }
1647c478bd9Sstevel@tonic-gate
1657c478bd9Sstevel@tonic-gate return (pent2);
1667c478bd9Sstevel@tonic-gate }
1677c478bd9Sstevel@tonic-gate
1687c478bd9Sstevel@tonic-gate
1697c478bd9Sstevel@tonic-gate /*
1707c478bd9Sstevel@tonic-gate * This routine parses the disabledlist or the supportedlist of an entry
1717c478bd9Sstevel@tonic-gate * in the kcf.conf configuration file.
1727c478bd9Sstevel@tonic-gate *
1737c478bd9Sstevel@tonic-gate * Arguments:
1747c478bd9Sstevel@tonic-gate * buf: an input argument which is a char string with the format of
1757c478bd9Sstevel@tonic-gate * "disabledlist=m1,m2,..." or "supportedlist=m1,m2,..."
1767c478bd9Sstevel@tonic-gate * pent: the entry for the disabledlist. This is an IN/OUT argument.
1777c478bd9Sstevel@tonic-gate *
1787c478bd9Sstevel@tonic-gate * Return value: SUCCESS or FAILURE.
1797c478bd9Sstevel@tonic-gate */
1807c478bd9Sstevel@tonic-gate static int
parse_sup_dis_list(const char * buf,entry_t * pent)181ddcb6370SDan OpenSolaris Anderson parse_sup_dis_list(const char *buf, entry_t *pent)
1827c478bd9Sstevel@tonic-gate {
1831b22764fSDaniel OpenSolaris Anderson mechlist_t *pmech = NULL;
1841b22764fSDaniel OpenSolaris Anderson mechlist_t *phead = NULL;
1857c478bd9Sstevel@tonic-gate char *next_token;
1867c478bd9Sstevel@tonic-gate char *value;
1877c478bd9Sstevel@tonic-gate int count;
1887c478bd9Sstevel@tonic-gate int supflag = B_FALSE;
1897c478bd9Sstevel@tonic-gate int disflag = B_FALSE;
1907c478bd9Sstevel@tonic-gate int rc = SUCCESS;
1917c478bd9Sstevel@tonic-gate
1927c478bd9Sstevel@tonic-gate if (strncmp(buf, EF_SUPPORTED, strlen(EF_SUPPORTED)) == 0) {
1937c478bd9Sstevel@tonic-gate supflag = B_TRUE;
1947c478bd9Sstevel@tonic-gate } else if (strncmp(buf, EF_DISABLED, strlen(EF_DISABLED)) == 0) {
1957c478bd9Sstevel@tonic-gate disflag = B_TRUE;
1967c478bd9Sstevel@tonic-gate } else {
1977c478bd9Sstevel@tonic-gate /* should not come here */
1987c478bd9Sstevel@tonic-gate return (FAILURE);
1997c478bd9Sstevel@tonic-gate }
2007c478bd9Sstevel@tonic-gate
2017c478bd9Sstevel@tonic-gate if (value = strpbrk(buf, SEP_EQUAL)) {
2027c478bd9Sstevel@tonic-gate value++; /* get rid of = */
2037c478bd9Sstevel@tonic-gate } else {
2047c478bd9Sstevel@tonic-gate cryptodebug("failed to parse the kcf.conf file.");
2057c478bd9Sstevel@tonic-gate return (FAILURE);
2067c478bd9Sstevel@tonic-gate }
2077c478bd9Sstevel@tonic-gate
2087c478bd9Sstevel@tonic-gate if ((next_token = strtok(value, SEP_COMMA)) == NULL) {
2097c478bd9Sstevel@tonic-gate cryptodebug("failed to parse the kcf.conf file.");
2107c478bd9Sstevel@tonic-gate return (FAILURE);
2117c478bd9Sstevel@tonic-gate }
2127c478bd9Sstevel@tonic-gate
2137c478bd9Sstevel@tonic-gate if ((pmech = create_mech(next_token)) == NULL) {
2147c478bd9Sstevel@tonic-gate return (FAILURE);
2157c478bd9Sstevel@tonic-gate }
2167c478bd9Sstevel@tonic-gate
2177c478bd9Sstevel@tonic-gate if (supflag) {
218ddcb6370SDan OpenSolaris Anderson if (pent->suplist != NULL) {
219ddcb6370SDan OpenSolaris Anderson cryptodebug("multiple supportedlist entries "
220ddcb6370SDan OpenSolaris Anderson "for a mechanism in file kcf.conf.");
221ddcb6370SDan OpenSolaris Anderson return (FAILURE);
222ddcb6370SDan OpenSolaris Anderson } else {
2237c478bd9Sstevel@tonic-gate pent->suplist = phead = pmech;
224ddcb6370SDan OpenSolaris Anderson }
2257c478bd9Sstevel@tonic-gate } else if (disflag) {
226ddcb6370SDan OpenSolaris Anderson if (pent->dislist != NULL) {
227ddcb6370SDan OpenSolaris Anderson cryptodebug("multiple disabledlist entries "
228ddcb6370SDan OpenSolaris Anderson "for a mechanism in file kcf.conf.");
229ddcb6370SDan OpenSolaris Anderson return (FAILURE);
230ddcb6370SDan OpenSolaris Anderson } else {
2317c478bd9Sstevel@tonic-gate pent->dislist = phead = pmech;
2327c478bd9Sstevel@tonic-gate }
233ddcb6370SDan OpenSolaris Anderson }
2347c478bd9Sstevel@tonic-gate
2357c478bd9Sstevel@tonic-gate count = 1;
2367c478bd9Sstevel@tonic-gate while (next_token) {
2377c478bd9Sstevel@tonic-gate if (next_token = strtok(NULL, SEP_COMMA)) {
2387c478bd9Sstevel@tonic-gate if ((pmech = create_mech(next_token)) == NULL) {
2397c478bd9Sstevel@tonic-gate rc = FAILURE;
2407c478bd9Sstevel@tonic-gate break;
2417c478bd9Sstevel@tonic-gate }
2427c478bd9Sstevel@tonic-gate count++;
2437c478bd9Sstevel@tonic-gate phead->next = pmech;
2447c478bd9Sstevel@tonic-gate phead = phead->next;
2457c478bd9Sstevel@tonic-gate }
2467c478bd9Sstevel@tonic-gate }
2477c478bd9Sstevel@tonic-gate
2487c478bd9Sstevel@tonic-gate if (rc == SUCCESS) {
2497c478bd9Sstevel@tonic-gate if (supflag) {
2507c478bd9Sstevel@tonic-gate pent->sup_count = count;
2517c478bd9Sstevel@tonic-gate } else if (disflag) {
2527c478bd9Sstevel@tonic-gate pent->dis_count = count;
2537c478bd9Sstevel@tonic-gate }
2547c478bd9Sstevel@tonic-gate } else {
2557c478bd9Sstevel@tonic-gate free_mechlist(phead);
2567c478bd9Sstevel@tonic-gate }
2577c478bd9Sstevel@tonic-gate
2587c478bd9Sstevel@tonic-gate return (rc);
2597c478bd9Sstevel@tonic-gate }
2607c478bd9Sstevel@tonic-gate
2617c478bd9Sstevel@tonic-gate
2627c478bd9Sstevel@tonic-gate /*
2631b22764fSDaniel OpenSolaris Anderson * Convert a char string containing a line about a provider
2641b22764fSDaniel OpenSolaris Anderson * from kcf.conf into an entry_t structure.
2651b22764fSDaniel OpenSolaris Anderson *
266ddcb6370SDan OpenSolaris Anderson * Note: the input string, buf, may be modified by this function.
267ddcb6370SDan OpenSolaris Anderson *
2681b22764fSDaniel OpenSolaris Anderson * See ent2str(), the reverse of this function, for the format of
2691b22764fSDaniel OpenSolaris Anderson * kcf.conf lines.
2707c478bd9Sstevel@tonic-gate */
2717c478bd9Sstevel@tonic-gate static int
interpret(char * buf,entry_t ** ppent)2727c478bd9Sstevel@tonic-gate interpret(char *buf, entry_t **ppent)
2737c478bd9Sstevel@tonic-gate {
2741b22764fSDaniel OpenSolaris Anderson entry_t *pent = NULL;
2757c478bd9Sstevel@tonic-gate char *token1;
2767c478bd9Sstevel@tonic-gate char *token2;
2777c478bd9Sstevel@tonic-gate char *token3;
2787c478bd9Sstevel@tonic-gate int rc;
2797c478bd9Sstevel@tonic-gate
2801b22764fSDaniel OpenSolaris Anderson /* Get provider name */
2817c478bd9Sstevel@tonic-gate if ((token1 = strtok(buf, SEP_COLON)) == NULL) { /* buf is NULL */
2827c478bd9Sstevel@tonic-gate return (FAILURE);
2837c478bd9Sstevel@tonic-gate };
2847c478bd9Sstevel@tonic-gate
2851b22764fSDaniel OpenSolaris Anderson pent = create_entry(token1);
2867c478bd9Sstevel@tonic-gate if (pent == NULL) {
2877c478bd9Sstevel@tonic-gate cryptodebug("out of memory.");
2887c478bd9Sstevel@tonic-gate return (FAILURE);
2897c478bd9Sstevel@tonic-gate }
2907c478bd9Sstevel@tonic-gate
2917c478bd9Sstevel@tonic-gate if ((token2 = strtok(NULL, SEP_SEMICOLON)) == NULL) {
2927c478bd9Sstevel@tonic-gate /* The entry contains a provider name only */
2937c478bd9Sstevel@tonic-gate free_entry(pent);
2947c478bd9Sstevel@tonic-gate return (FAILURE);
2957c478bd9Sstevel@tonic-gate }
2967c478bd9Sstevel@tonic-gate
2971b22764fSDaniel OpenSolaris Anderson if (strncmp(token2, EF_UNLOAD, strlen(EF_UNLOAD)) == 0) {
2981b22764fSDaniel OpenSolaris Anderson pent->load = B_FALSE; /* cryptoadm unload */
299ddcb6370SDan OpenSolaris Anderson token2 = strtok(NULL, SEP_SEMICOLON);
300ddcb6370SDan OpenSolaris Anderson /*
301ddcb6370SDan OpenSolaris Anderson * If token2 is NULL, the entry contains a
302ddcb6370SDan OpenSolaris Anderson * provider name:unload only
303ddcb6370SDan OpenSolaris Anderson */
3041b22764fSDaniel OpenSolaris Anderson }
3057c478bd9Sstevel@tonic-gate
306ddcb6370SDan OpenSolaris Anderson if (token2 != NULL) {
307ddcb6370SDan OpenSolaris Anderson /*
308ddcb6370SDan OpenSolaris Anderson * Either supportedlist or disabledlist or both are present.
309ddcb6370SDan OpenSolaris Anderson * Need to call strtok() to get token3 first, as function
310ddcb6370SDan OpenSolaris Anderson * parse_sup_dis_list() makes strtok() calls on the
311ddcb6370SDan OpenSolaris Anderson * token2 substring.
312ddcb6370SDan OpenSolaris Anderson */
3131b22764fSDaniel OpenSolaris Anderson token3 = strtok(NULL, SEP_SEMICOLON); /* optional */
3141b22764fSDaniel OpenSolaris Anderson
3151b22764fSDaniel OpenSolaris Anderson /* parse supportedlist (or disabledlist if no supportedlist) */
316ddcb6370SDan OpenSolaris Anderson if ((rc = parse_sup_dis_list(token2, pent)) != SUCCESS) {
3177c478bd9Sstevel@tonic-gate free_entry(pent);
3187c478bd9Sstevel@tonic-gate return (rc);
3197c478bd9Sstevel@tonic-gate }
3207c478bd9Sstevel@tonic-gate
3211b22764fSDaniel OpenSolaris Anderson /* parse disabledlist (if there's a supportedlist) */
322ddcb6370SDan OpenSolaris Anderson if ((token3 != NULL) && ((rc = parse_sup_dis_list(token3,
323ddcb6370SDan OpenSolaris Anderson pent)) != SUCCESS)) {
3247c478bd9Sstevel@tonic-gate free_entry(pent);
3257c478bd9Sstevel@tonic-gate return (rc);
3267c478bd9Sstevel@tonic-gate }
327ddcb6370SDan OpenSolaris Anderson }
3287c478bd9Sstevel@tonic-gate
3297c478bd9Sstevel@tonic-gate *ppent = pent;
3307c478bd9Sstevel@tonic-gate return (SUCCESS);
3317c478bd9Sstevel@tonic-gate }
3327c478bd9Sstevel@tonic-gate
3337c478bd9Sstevel@tonic-gate
3347c478bd9Sstevel@tonic-gate /*
3351b22764fSDaniel OpenSolaris Anderson * Add an entry about a provider from kcf.conf to the end of an entry list.
3361b22764fSDaniel OpenSolaris Anderson * If the entry list pplist is NULL, create the linked list with pent as the
3371b22764fSDaniel OpenSolaris Anderson * first element.
3387c478bd9Sstevel@tonic-gate */
3397c478bd9Sstevel@tonic-gate static int
build_entrylist(entry_t * pent,entrylist_t ** pplist)3407c478bd9Sstevel@tonic-gate build_entrylist(entry_t *pent, entrylist_t **pplist)
3417c478bd9Sstevel@tonic-gate {
3427c478bd9Sstevel@tonic-gate entrylist_t *pentlist;
3431b22764fSDaniel OpenSolaris Anderson entrylist_t *pcur = NULL;
3447c478bd9Sstevel@tonic-gate
3457c478bd9Sstevel@tonic-gate pentlist = malloc(sizeof (entrylist_t));
3467c478bd9Sstevel@tonic-gate if (pentlist == NULL) {
3477c478bd9Sstevel@tonic-gate cryptodebug("out of memory.");
3487c478bd9Sstevel@tonic-gate return (FAILURE);
3497c478bd9Sstevel@tonic-gate }
3507c478bd9Sstevel@tonic-gate pentlist->pent = pent;
3517c478bd9Sstevel@tonic-gate pentlist->next = NULL;
3527c478bd9Sstevel@tonic-gate
3537c478bd9Sstevel@tonic-gate if (*pplist) {
3547c478bd9Sstevel@tonic-gate pcur = *pplist;
3557c478bd9Sstevel@tonic-gate while (pcur->next != NULL)
3567c478bd9Sstevel@tonic-gate pcur = pcur->next;
3577c478bd9Sstevel@tonic-gate pcur->next = pentlist;
3587c478bd9Sstevel@tonic-gate } else { /* empty list */
3597c478bd9Sstevel@tonic-gate *pplist = pentlist;
3607c478bd9Sstevel@tonic-gate }
3617c478bd9Sstevel@tonic-gate
3627c478bd9Sstevel@tonic-gate return (SUCCESS);
3637c478bd9Sstevel@tonic-gate }
3647c478bd9Sstevel@tonic-gate
3657c478bd9Sstevel@tonic-gate
3667c478bd9Sstevel@tonic-gate
3677c478bd9Sstevel@tonic-gate /*
3687c478bd9Sstevel@tonic-gate * Find the entry with the "provname" name from the entry list and duplicate
3691b22764fSDaniel OpenSolaris Anderson * it. Called by getent_kef().
3707c478bd9Sstevel@tonic-gate */
3717c478bd9Sstevel@tonic-gate static entry_t *
getent(char * provname,entrylist_t * entrylist)3727c478bd9Sstevel@tonic-gate getent(char *provname, entrylist_t *entrylist)
3737c478bd9Sstevel@tonic-gate {
3747c478bd9Sstevel@tonic-gate boolean_t found = B_FALSE;
3757c478bd9Sstevel@tonic-gate entry_t *pent1 = NULL;
3767c478bd9Sstevel@tonic-gate
3777c478bd9Sstevel@tonic-gate if ((provname == NULL) || (entrylist == NULL)) {
3787c478bd9Sstevel@tonic-gate return (NULL);
3797c478bd9Sstevel@tonic-gate }
3807c478bd9Sstevel@tonic-gate
3817c478bd9Sstevel@tonic-gate while (!found && entrylist) {
3827c478bd9Sstevel@tonic-gate if (strcmp(entrylist->pent->name, provname) == 0) {
3837c478bd9Sstevel@tonic-gate found = B_TRUE;
3847c478bd9Sstevel@tonic-gate pent1 = entrylist->pent;
3857c478bd9Sstevel@tonic-gate } else {
3867c478bd9Sstevel@tonic-gate entrylist = entrylist->next;
3877c478bd9Sstevel@tonic-gate }
3887c478bd9Sstevel@tonic-gate }
3897c478bd9Sstevel@tonic-gate
3907c478bd9Sstevel@tonic-gate if (!found) {
3917c478bd9Sstevel@tonic-gate return (NULL);
3927c478bd9Sstevel@tonic-gate }
3937c478bd9Sstevel@tonic-gate
3947c478bd9Sstevel@tonic-gate /* duplicate the entry to be returned */
3957c478bd9Sstevel@tonic-gate return (dup_entry(pent1));
3967c478bd9Sstevel@tonic-gate }
3977c478bd9Sstevel@tonic-gate
3987c478bd9Sstevel@tonic-gate
3991b22764fSDaniel OpenSolaris Anderson /*
4001b22764fSDaniel OpenSolaris Anderson * Free memory in entry_t.
4011b22764fSDaniel OpenSolaris Anderson * That is, the supported and disabled lists for a provider
4021b22764fSDaniel OpenSolaris Anderson * from kcf.conf.
4031b22764fSDaniel OpenSolaris Anderson */
4047c478bd9Sstevel@tonic-gate void
free_entry(entry_t * pent)4057c478bd9Sstevel@tonic-gate free_entry(entry_t *pent)
4067c478bd9Sstevel@tonic-gate {
4077c478bd9Sstevel@tonic-gate if (pent == NULL) {
4087c478bd9Sstevel@tonic-gate return;
4097c478bd9Sstevel@tonic-gate } else {
4107c478bd9Sstevel@tonic-gate free_mechlist(pent->suplist);
4117c478bd9Sstevel@tonic-gate free_mechlist(pent->dislist);
4127c478bd9Sstevel@tonic-gate free(pent);
4137c478bd9Sstevel@tonic-gate }
4147c478bd9Sstevel@tonic-gate }
4157c478bd9Sstevel@tonic-gate
4167c478bd9Sstevel@tonic-gate
4171b22764fSDaniel OpenSolaris Anderson /*
4181b22764fSDaniel OpenSolaris Anderson * Free elements in a entrylist_t linked list,
4191b22764fSDaniel OpenSolaris Anderson * which lists providers in kcf.conf.
4201b22764fSDaniel OpenSolaris Anderson */
4217c478bd9Sstevel@tonic-gate void
free_entrylist(entrylist_t * entrylist)4227c478bd9Sstevel@tonic-gate free_entrylist(entrylist_t *entrylist)
4237c478bd9Sstevel@tonic-gate {
4247c478bd9Sstevel@tonic-gate entrylist_t *pnext;
4257c478bd9Sstevel@tonic-gate
4267c478bd9Sstevel@tonic-gate while (entrylist != NULL) {
4277c478bd9Sstevel@tonic-gate pnext = entrylist->next;
4287c478bd9Sstevel@tonic-gate free_entry(entrylist->pent);
4297c478bd9Sstevel@tonic-gate entrylist = pnext;
4307c478bd9Sstevel@tonic-gate }
4317c478bd9Sstevel@tonic-gate }
4327c478bd9Sstevel@tonic-gate
4337c478bd9Sstevel@tonic-gate
4347c478bd9Sstevel@tonic-gate /*
435*0f5cc0e1SDan OpenSolaris Anderson * Convert an entry_t to a kcf.conf line string. Build a string to insert
436*0f5cc0e1SDan OpenSolaris Anderson * as a line in file kcf.conf. Based on the content of an entry_t,
437*0f5cc0e1SDan OpenSolaris Anderson * the result string is one of these 8 forms:
4387c478bd9Sstevel@tonic-gate * - name:supportedlist=m1,m2,...,mj
4397c478bd9Sstevel@tonic-gate * - name:disabledlist=m1,m2,...,mj
4407c478bd9Sstevel@tonic-gate * - name:supportedlist=m1,...,mj;disabledlist=m1,m2,...,mk
4417c478bd9Sstevel@tonic-gate *
442ddcb6370SDan OpenSolaris Anderson * - name:unload
4431b22764fSDaniel OpenSolaris Anderson * - name:unload;supportedlist=m1,m2,...,mj
4441b22764fSDaniel OpenSolaris Anderson * - name:unload;disabledlist=m1,m2,...,mj
4451b22764fSDaniel OpenSolaris Anderson * - name:unload;supportedlist=m1,...,mj;disabledlist=m1,m2,...,mk
4461b22764fSDaniel OpenSolaris Anderson *
447*0f5cc0e1SDan OpenSolaris Anderson * - (NUL character or 0-length string)
448*0f5cc0e1SDan OpenSolaris Anderson *
449*0f5cc0e1SDan OpenSolaris Anderson * Return a 0-length empty string if no keyword is present (that is,
450*0f5cc0e1SDan OpenSolaris Anderson * supportedlist, disabledlist, or unload). A kcf.conf line with just the
451*0f5cc0e1SDan OpenSolaris Anderson * provider name with no keyword is invalid.
452*0f5cc0e1SDan OpenSolaris Anderson *
4531b22764fSDaniel OpenSolaris Anderson * Note that the caller is responsible for freeing the returned string
4541b22764fSDaniel OpenSolaris Anderson * (with free_entry()).
4551b22764fSDaniel OpenSolaris Anderson * See interpret() for the reverse of this function: converting a string
4561b22764fSDaniel OpenSolaris Anderson * to an entry_t.
4577c478bd9Sstevel@tonic-gate */
4587c478bd9Sstevel@tonic-gate char *
ent2str(entry_t * pent)4597c478bd9Sstevel@tonic-gate ent2str(entry_t *pent)
4607c478bd9Sstevel@tonic-gate {
4617c478bd9Sstevel@tonic-gate char *buf;
4621b22764fSDaniel OpenSolaris Anderson mechlist_t *pcur = NULL;
463*0f5cc0e1SDan OpenSolaris Anderson boolean_t keyword_already_present = B_FALSE;
4647c478bd9Sstevel@tonic-gate
4657c478bd9Sstevel@tonic-gate if (pent == NULL) {
4667c478bd9Sstevel@tonic-gate return (NULL);
4677c478bd9Sstevel@tonic-gate }
4687c478bd9Sstevel@tonic-gate
4697c478bd9Sstevel@tonic-gate if ((buf = malloc(BUFSIZ)) == NULL) {
4707c478bd9Sstevel@tonic-gate return (NULL);
4717c478bd9Sstevel@tonic-gate }
4727c478bd9Sstevel@tonic-gate
4737c478bd9Sstevel@tonic-gate /* convert the provider name */
4747c478bd9Sstevel@tonic-gate if (strlcpy(buf, pent->name, BUFSIZ) >= BUFSIZ) {
4757c478bd9Sstevel@tonic-gate free(buf);
4767c478bd9Sstevel@tonic-gate return (NULL);
4777c478bd9Sstevel@tonic-gate }
4787c478bd9Sstevel@tonic-gate
4791b22764fSDaniel OpenSolaris Anderson if (!pent->load) { /* add "unload" keyword */
4807c478bd9Sstevel@tonic-gate if (strlcat(buf, SEP_COLON, BUFSIZ) >= BUFSIZ) {
4817c478bd9Sstevel@tonic-gate free(buf);
4827c478bd9Sstevel@tonic-gate return (NULL);
4837c478bd9Sstevel@tonic-gate }
4847c478bd9Sstevel@tonic-gate
4851b22764fSDaniel OpenSolaris Anderson if (strlcat(buf, EF_UNLOAD, BUFSIZ) >= BUFSIZ) {
4861b22764fSDaniel OpenSolaris Anderson free(buf);
4871b22764fSDaniel OpenSolaris Anderson return (NULL);
4881b22764fSDaniel OpenSolaris Anderson }
4891b22764fSDaniel OpenSolaris Anderson
490*0f5cc0e1SDan OpenSolaris Anderson keyword_already_present = B_TRUE;
4911b22764fSDaniel OpenSolaris Anderson }
4921b22764fSDaniel OpenSolaris Anderson
4931b22764fSDaniel OpenSolaris Anderson /* convert the supported list if any */
4941b22764fSDaniel OpenSolaris Anderson pcur = pent->suplist;
4951b22764fSDaniel OpenSolaris Anderson if (pcur != NULL) {
4961b22764fSDaniel OpenSolaris Anderson if (strlcat(buf,
497*0f5cc0e1SDan OpenSolaris Anderson keyword_already_present ? SEP_SEMICOLON : SEP_COLON,
4981b22764fSDaniel OpenSolaris Anderson BUFSIZ) >= BUFSIZ) {
4991b22764fSDaniel OpenSolaris Anderson free(buf);
5001b22764fSDaniel OpenSolaris Anderson return (NULL);
5011b22764fSDaniel OpenSolaris Anderson }
5021b22764fSDaniel OpenSolaris Anderson
5037c478bd9Sstevel@tonic-gate if (strlcat(buf, EF_SUPPORTED, BUFSIZ) >= BUFSIZ) {
5047c478bd9Sstevel@tonic-gate free(buf);
5057c478bd9Sstevel@tonic-gate return (NULL);
5067c478bd9Sstevel@tonic-gate }
5077c478bd9Sstevel@tonic-gate
5081b22764fSDaniel OpenSolaris Anderson while (pcur != NULL) {
5091b22764fSDaniel OpenSolaris Anderson if (strlcat(buf, pcur->name, BUFSIZ) >= BUFSIZ) {
5107c478bd9Sstevel@tonic-gate free(buf);
5117c478bd9Sstevel@tonic-gate return (NULL);
5127c478bd9Sstevel@tonic-gate }
5137c478bd9Sstevel@tonic-gate
5141b22764fSDaniel OpenSolaris Anderson pcur = pcur->next;
5151b22764fSDaniel OpenSolaris Anderson if (pcur != NULL) {
5167c478bd9Sstevel@tonic-gate if (strlcat(buf, SEP_COMMA, BUFSIZ)
5177c478bd9Sstevel@tonic-gate >= BUFSIZ) {
5187c478bd9Sstevel@tonic-gate free(buf);
5197c478bd9Sstevel@tonic-gate return (NULL);
5207c478bd9Sstevel@tonic-gate }
5217c478bd9Sstevel@tonic-gate }
5227c478bd9Sstevel@tonic-gate }
523*0f5cc0e1SDan OpenSolaris Anderson keyword_already_present = B_TRUE;
5247c478bd9Sstevel@tonic-gate }
5257c478bd9Sstevel@tonic-gate
5267c478bd9Sstevel@tonic-gate /* convert the disabled list if any */
5271b22764fSDaniel OpenSolaris Anderson pcur = pent->dislist;
5281b22764fSDaniel OpenSolaris Anderson if (pcur != NULL) {
5291b22764fSDaniel OpenSolaris Anderson if (strlcat(buf,
530*0f5cc0e1SDan OpenSolaris Anderson keyword_already_present ? SEP_SEMICOLON : SEP_COLON,
5311b22764fSDaniel OpenSolaris Anderson BUFSIZ) >= BUFSIZ) {
5327c478bd9Sstevel@tonic-gate free(buf);
5337c478bd9Sstevel@tonic-gate return (NULL);
5347c478bd9Sstevel@tonic-gate }
5357c478bd9Sstevel@tonic-gate
5361b22764fSDaniel OpenSolaris Anderson if (strlcat(buf, EF_DISABLED, BUFSIZ) >= BUFSIZ) {
5371b22764fSDaniel OpenSolaris Anderson free(buf);
5381b22764fSDaniel OpenSolaris Anderson return (NULL);
5391b22764fSDaniel OpenSolaris Anderson }
5401b22764fSDaniel OpenSolaris Anderson
5411b22764fSDaniel OpenSolaris Anderson while (pcur != NULL) {
5421b22764fSDaniel OpenSolaris Anderson if (strlcat(buf, pcur->name, BUFSIZ) >= BUFSIZ) {
5431b22764fSDaniel OpenSolaris Anderson free(buf);
5441b22764fSDaniel OpenSolaris Anderson return (NULL);
5451b22764fSDaniel OpenSolaris Anderson }
5461b22764fSDaniel OpenSolaris Anderson
5471b22764fSDaniel OpenSolaris Anderson pcur = pcur->next;
5481b22764fSDaniel OpenSolaris Anderson if (pcur != NULL) {
5497c478bd9Sstevel@tonic-gate if (strlcat(buf, SEP_COMMA, BUFSIZ)
5507c478bd9Sstevel@tonic-gate >= BUFSIZ) {
5517c478bd9Sstevel@tonic-gate free(buf);
5527c478bd9Sstevel@tonic-gate return (NULL);
5537c478bd9Sstevel@tonic-gate }
5547c478bd9Sstevel@tonic-gate }
5557c478bd9Sstevel@tonic-gate }
556*0f5cc0e1SDan OpenSolaris Anderson keyword_already_present = B_TRUE;
5577c478bd9Sstevel@tonic-gate }
5587c478bd9Sstevel@tonic-gate
5597c478bd9Sstevel@tonic-gate if (strlcat(buf, "\n", BUFSIZ) >= BUFSIZ) {
5607c478bd9Sstevel@tonic-gate free(buf);
5617c478bd9Sstevel@tonic-gate return (NULL);
5627c478bd9Sstevel@tonic-gate }
5637c478bd9Sstevel@tonic-gate
564*0f5cc0e1SDan OpenSolaris Anderson if (!keyword_already_present) {
565*0f5cc0e1SDan OpenSolaris Anderson /* Only the provider name, without a keyword, is on the line */
566*0f5cc0e1SDan OpenSolaris Anderson buf[0] = '\0';
567*0f5cc0e1SDan OpenSolaris Anderson }
5687c478bd9Sstevel@tonic-gate return (buf);
5697c478bd9Sstevel@tonic-gate }
5707c478bd9Sstevel@tonic-gate
5717c478bd9Sstevel@tonic-gate
5727c478bd9Sstevel@tonic-gate /*
5737c478bd9Sstevel@tonic-gate * Enable the mechanisms for the provider pointed by *ppent. If allflag is
5747c478bd9Sstevel@tonic-gate * TRUE, enable all. Otherwise, enable the mechanisms specified in the 3rd
5757c478bd9Sstevel@tonic-gate * argument "mlist". The result will be stored in ppent also.
5767c478bd9Sstevel@tonic-gate */
5777c478bd9Sstevel@tonic-gate int
enable_mechs(entry_t ** ppent,boolean_t allflag,mechlist_t * mlist)5787c478bd9Sstevel@tonic-gate enable_mechs(entry_t **ppent, boolean_t allflag, mechlist_t *mlist)
5797c478bd9Sstevel@tonic-gate {
5807c478bd9Sstevel@tonic-gate entry_t *pent;
5817c478bd9Sstevel@tonic-gate mechlist_t *phead; /* the current and resulting disabled list */
5821b22764fSDaniel OpenSolaris Anderson mechlist_t *ptr = NULL;
5831b22764fSDaniel OpenSolaris Anderson mechlist_t *pcur = NULL;
5847c478bd9Sstevel@tonic-gate boolean_t found;
5857c478bd9Sstevel@tonic-gate
5867c478bd9Sstevel@tonic-gate pent = *ppent;
5877c478bd9Sstevel@tonic-gate if (pent == NULL) {
5887c478bd9Sstevel@tonic-gate return (FAILURE);
5897c478bd9Sstevel@tonic-gate }
5907c478bd9Sstevel@tonic-gate
5917c478bd9Sstevel@tonic-gate if (allflag) {
5927c478bd9Sstevel@tonic-gate free_mechlist(pent->dislist);
5937c478bd9Sstevel@tonic-gate pent->dis_count = 0;
5947c478bd9Sstevel@tonic-gate pent->dislist = NULL;
5957c478bd9Sstevel@tonic-gate return (SUCCESS);
5967c478bd9Sstevel@tonic-gate }
5977c478bd9Sstevel@tonic-gate
5987c478bd9Sstevel@tonic-gate /*
5997c478bd9Sstevel@tonic-gate * for each mechanism in the to-be-enabled mechanism list,
6007c478bd9Sstevel@tonic-gate * - check if it is in the current disabled list
6017c478bd9Sstevel@tonic-gate * - if found, delete it from the disabled list
6027c478bd9Sstevel@tonic-gate * otherwise, give a warning.
6037c478bd9Sstevel@tonic-gate */
6047c478bd9Sstevel@tonic-gate ptr = mlist;
6057c478bd9Sstevel@tonic-gate while (ptr != NULL) {
6067c478bd9Sstevel@tonic-gate found = B_FALSE;
6077c478bd9Sstevel@tonic-gate phead = pcur = pent->dislist;
6087c478bd9Sstevel@tonic-gate while (!found && pcur) {
6097c478bd9Sstevel@tonic-gate if (strcmp(pcur->name, ptr->name) == 0) {
6107c478bd9Sstevel@tonic-gate found = B_TRUE;
6117c478bd9Sstevel@tonic-gate } else {
6127c478bd9Sstevel@tonic-gate phead = pcur;
6137c478bd9Sstevel@tonic-gate pcur = pcur->next;
6147c478bd9Sstevel@tonic-gate }
6157c478bd9Sstevel@tonic-gate }
6167c478bd9Sstevel@tonic-gate
6177c478bd9Sstevel@tonic-gate if (found) {
6187c478bd9Sstevel@tonic-gate if (phead == pcur) {
6197c478bd9Sstevel@tonic-gate pent->dislist = pent->dislist->next;
6207c478bd9Sstevel@tonic-gate free(pcur);
6217c478bd9Sstevel@tonic-gate } else {
6227c478bd9Sstevel@tonic-gate phead->next = pcur->next;
6237c478bd9Sstevel@tonic-gate free(pcur);
6247c478bd9Sstevel@tonic-gate }
6257c478bd9Sstevel@tonic-gate pent->dis_count--;
6267c478bd9Sstevel@tonic-gate } else {
6277c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext(
6287c478bd9Sstevel@tonic-gate "(Warning) %1$s is either enabled already or not "
6297c478bd9Sstevel@tonic-gate "a valid mechanism for %2$s"), ptr->name,
6307c478bd9Sstevel@tonic-gate pent->name);
6317c478bd9Sstevel@tonic-gate }
6327c478bd9Sstevel@tonic-gate ptr = ptr->next;
6337c478bd9Sstevel@tonic-gate }
6347c478bd9Sstevel@tonic-gate
6357c478bd9Sstevel@tonic-gate if (pent->dis_count == 0) {
6367c478bd9Sstevel@tonic-gate pent->dislist = NULL;
6377c478bd9Sstevel@tonic-gate }
6387c478bd9Sstevel@tonic-gate
6397c478bd9Sstevel@tonic-gate return (SUCCESS);
6407c478bd9Sstevel@tonic-gate
6417c478bd9Sstevel@tonic-gate }
6427c478bd9Sstevel@tonic-gate
6437c478bd9Sstevel@tonic-gate
6441b22764fSDaniel OpenSolaris Anderson /*
6451b22764fSDaniel OpenSolaris Anderson * Determine if the kernel provider name, path, is a device
6461b22764fSDaniel OpenSolaris Anderson * (that is, it contains a slash character (e.g., "mca/0").
6471b22764fSDaniel OpenSolaris Anderson * If so, it is a hardware provider; otherwise it is a software provider.
6481b22764fSDaniel OpenSolaris Anderson */
6497c478bd9Sstevel@tonic-gate boolean_t
is_device(char * path)6507c478bd9Sstevel@tonic-gate is_device(char *path)
6517c478bd9Sstevel@tonic-gate {
6527c478bd9Sstevel@tonic-gate if (strchr(path, SEP_SLASH) != NULL) {
6537c478bd9Sstevel@tonic-gate return (B_TRUE);
6547c478bd9Sstevel@tonic-gate } else {
6557c478bd9Sstevel@tonic-gate return (B_FALSE);
6567c478bd9Sstevel@tonic-gate }
6577c478bd9Sstevel@tonic-gate }
6587c478bd9Sstevel@tonic-gate
6597c478bd9Sstevel@tonic-gate /*
6607c478bd9Sstevel@tonic-gate * Split a hardware provider name with the "name/inst_num" format into
6611b22764fSDaniel OpenSolaris Anderson * a name and a number (e.g., split "mca/0" into "mca" instance 0).
6627c478bd9Sstevel@tonic-gate */
6637c478bd9Sstevel@tonic-gate int
split_hw_provname(char * provname,char * pname,int * inst_num)6647c478bd9Sstevel@tonic-gate split_hw_provname(char *provname, char *pname, int *inst_num)
6657c478bd9Sstevel@tonic-gate {
6667c478bd9Sstevel@tonic-gate char name[MAXNAMELEN];
6677c478bd9Sstevel@tonic-gate char *inst_str;
6687c478bd9Sstevel@tonic-gate
6697c478bd9Sstevel@tonic-gate if (provname == NULL) {
6707c478bd9Sstevel@tonic-gate return (FAILURE);
6717c478bd9Sstevel@tonic-gate }
6727c478bd9Sstevel@tonic-gate
6737c478bd9Sstevel@tonic-gate (void) strlcpy(name, provname, MAXNAMELEN);
6747c478bd9Sstevel@tonic-gate if (strtok(name, "/") == NULL) {
6757c478bd9Sstevel@tonic-gate return (FAILURE);
6767c478bd9Sstevel@tonic-gate }
6777c478bd9Sstevel@tonic-gate
6787c478bd9Sstevel@tonic-gate if ((inst_str = strtok(NULL, "/")) == NULL) {
6797c478bd9Sstevel@tonic-gate return (FAILURE);
6807c478bd9Sstevel@tonic-gate }
6817c478bd9Sstevel@tonic-gate
6827c478bd9Sstevel@tonic-gate (void) strlcpy(pname, name, MAXNAMELEN);
6837c478bd9Sstevel@tonic-gate *inst_num = atoi(inst_str);
6847c478bd9Sstevel@tonic-gate
6857c478bd9Sstevel@tonic-gate return (SUCCESS);
6867c478bd9Sstevel@tonic-gate }
6877c478bd9Sstevel@tonic-gate
6887c478bd9Sstevel@tonic-gate
6897c478bd9Sstevel@tonic-gate /*
6901b22764fSDaniel OpenSolaris Anderson * Retrieve information from kcf.conf and build a hardware device entry list
6911b22764fSDaniel OpenSolaris Anderson * and a software entry list of kernel crypto providers.
6921b22764fSDaniel OpenSolaris Anderson *
6931b22764fSDaniel OpenSolaris Anderson * This list is usually incomplete, as kernel crypto providers only have to
6941b22764fSDaniel OpenSolaris Anderson * be listed in kcf.conf if a mechanism is disabled (by cryptoadm) or
6951b22764fSDaniel OpenSolaris Anderson * if the kernel provider module is not one of the default kernel providers.
6961b22764fSDaniel OpenSolaris Anderson *
6971b22764fSDaniel OpenSolaris Anderson * The kcf.conf file is available only in the global zone.
6987c478bd9Sstevel@tonic-gate */
6997c478bd9Sstevel@tonic-gate int
get_kcfconf_info(entrylist_t ** ppdevlist,entrylist_t ** ppsoftlist)700d616ad8eSHai-May Chao get_kcfconf_info(entrylist_t **ppdevlist, entrylist_t **ppsoftlist)
7017c478bd9Sstevel@tonic-gate {
7021b22764fSDaniel OpenSolaris Anderson FILE *pfile = NULL;
7037c478bd9Sstevel@tonic-gate char buffer[BUFSIZ];
7047c478bd9Sstevel@tonic-gate int len;
7057c478bd9Sstevel@tonic-gate entry_t *pent = NULL;
7067c478bd9Sstevel@tonic-gate int rc = SUCCESS;
7077c478bd9Sstevel@tonic-gate
7087c478bd9Sstevel@tonic-gate if ((pfile = fopen(_PATH_KCF_CONF, "r")) == NULL) {
7097c478bd9Sstevel@tonic-gate cryptodebug("failed to open the kcf.conf file for read only");
7107c478bd9Sstevel@tonic-gate return (FAILURE);
7117c478bd9Sstevel@tonic-gate }
7127c478bd9Sstevel@tonic-gate
7137c478bd9Sstevel@tonic-gate *ppdevlist = NULL;
7147c478bd9Sstevel@tonic-gate *ppsoftlist = NULL;
7157c478bd9Sstevel@tonic-gate while (fgets(buffer, BUFSIZ, pfile) != NULL) {
7167c478bd9Sstevel@tonic-gate if (buffer[0] == '#' || buffer[0] == ' ' ||
7177c478bd9Sstevel@tonic-gate buffer[0] == '\n'|| buffer[0] == '\t') {
7187c478bd9Sstevel@tonic-gate continue; /* ignore comment lines */
7197c478bd9Sstevel@tonic-gate }
7207c478bd9Sstevel@tonic-gate
7217c478bd9Sstevel@tonic-gate len = strlen(buffer);
7227c478bd9Sstevel@tonic-gate if (buffer[len - 1] == '\n') { /* get rid of trailing '\n' */
7237c478bd9Sstevel@tonic-gate len--;
7247c478bd9Sstevel@tonic-gate }
7257c478bd9Sstevel@tonic-gate buffer[len] = '\0';
7267c478bd9Sstevel@tonic-gate
7277c478bd9Sstevel@tonic-gate if ((rc = interpret(buffer, &pent)) == SUCCESS) {
728d616ad8eSHai-May Chao if (is_device(pent->name)) {
7297c478bd9Sstevel@tonic-gate rc = build_entrylist(pent, ppdevlist);
7307c478bd9Sstevel@tonic-gate } else {
7317c478bd9Sstevel@tonic-gate rc = build_entrylist(pent, ppsoftlist);
7327c478bd9Sstevel@tonic-gate }
7337c478bd9Sstevel@tonic-gate } else {
7347c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext(
7357c478bd9Sstevel@tonic-gate "failed to parse configuration."));
7367c478bd9Sstevel@tonic-gate }
7377c478bd9Sstevel@tonic-gate
7387c478bd9Sstevel@tonic-gate if (rc != SUCCESS) {
7397c478bd9Sstevel@tonic-gate free_entrylist(*ppdevlist);
7407c478bd9Sstevel@tonic-gate free_entrylist(*ppsoftlist);
7417c478bd9Sstevel@tonic-gate free_entry(pent);
7427c478bd9Sstevel@tonic-gate break;
7437c478bd9Sstevel@tonic-gate }
7447c478bd9Sstevel@tonic-gate }
7457c478bd9Sstevel@tonic-gate
7467c478bd9Sstevel@tonic-gate (void) fclose(pfile);
7477c478bd9Sstevel@tonic-gate return (rc);
7487c478bd9Sstevel@tonic-gate }
7497c478bd9Sstevel@tonic-gate
7507c478bd9Sstevel@tonic-gate /*
7517c478bd9Sstevel@tonic-gate * Retrieve information from admin device and build a device entry list and
7521b22764fSDaniel OpenSolaris Anderson * a software entry list. This is used where there is no kcf.conf, e.g., the
7537c478bd9Sstevel@tonic-gate * non-global zone.
7547c478bd9Sstevel@tonic-gate */
7557c478bd9Sstevel@tonic-gate int
get_admindev_info(entrylist_t ** ppdevlist,entrylist_t ** ppsoftlist)7567c478bd9Sstevel@tonic-gate get_admindev_info(entrylist_t **ppdevlist, entrylist_t **ppsoftlist)
7577c478bd9Sstevel@tonic-gate {
7587c478bd9Sstevel@tonic-gate crypto_get_dev_list_t *pdevlist_kernel = NULL;
7597c478bd9Sstevel@tonic-gate crypto_get_soft_list_t *psoftlist_kernel = NULL;
7607c478bd9Sstevel@tonic-gate char *devname;
7617c478bd9Sstevel@tonic-gate int inst_num;
7627c478bd9Sstevel@tonic-gate int mcount;
7631b22764fSDaniel OpenSolaris Anderson mechlist_t *pmech = NULL;
7641b22764fSDaniel OpenSolaris Anderson entry_t *pent_dev = NULL, *pent_soft = NULL;
7657c478bd9Sstevel@tonic-gate int i;
7667c478bd9Sstevel@tonic-gate char *psoftname;
7677c478bd9Sstevel@tonic-gate entrylist_t *tmp_pdev = NULL;
7687c478bd9Sstevel@tonic-gate entrylist_t *tmp_psoft = NULL;
7691b22764fSDaniel OpenSolaris Anderson entrylist_t *phardlist = NULL, *psoftlist = NULL;
7707c478bd9Sstevel@tonic-gate
7711b22764fSDaniel OpenSolaris Anderson /*
7721b22764fSDaniel OpenSolaris Anderson * Get hardware providers
7731b22764fSDaniel OpenSolaris Anderson */
7747c478bd9Sstevel@tonic-gate if (get_dev_list(&pdevlist_kernel) != SUCCESS) {
7757c478bd9Sstevel@tonic-gate cryptodebug("failed to get hardware provider list from kernel");
7767c478bd9Sstevel@tonic-gate return (FAILURE);
7777c478bd9Sstevel@tonic-gate }
7787c478bd9Sstevel@tonic-gate
7797c478bd9Sstevel@tonic-gate for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) {
7807c478bd9Sstevel@tonic-gate devname = pdevlist_kernel->dl_devs[i].le_dev_name;
7817c478bd9Sstevel@tonic-gate inst_num = pdevlist_kernel->dl_devs[i].le_dev_instance;
7827c478bd9Sstevel@tonic-gate mcount = pdevlist_kernel->dl_devs[i].le_mechanism_count;
7837c478bd9Sstevel@tonic-gate
7847c478bd9Sstevel@tonic-gate pmech = NULL;
7857c478bd9Sstevel@tonic-gate if (get_dev_info(devname, inst_num, mcount, &pmech) !=
7867c478bd9Sstevel@tonic-gate SUCCESS) {
7877c478bd9Sstevel@tonic-gate cryptodebug(
7887c478bd9Sstevel@tonic-gate "failed to retrieve the mechanism list for %s/%d.",
7897c478bd9Sstevel@tonic-gate devname, inst_num);
7907c478bd9Sstevel@tonic-gate goto fail_out;
7917c478bd9Sstevel@tonic-gate }
7927c478bd9Sstevel@tonic-gate
7931b22764fSDaniel OpenSolaris Anderson if ((pent_dev = create_entry(devname)) == NULL) {
7947c478bd9Sstevel@tonic-gate cryptodebug("out of memory.");
7957c478bd9Sstevel@tonic-gate free_mechlist(pmech);
7967c478bd9Sstevel@tonic-gate goto fail_out;
7977c478bd9Sstevel@tonic-gate }
7981b22764fSDaniel OpenSolaris Anderson pent_dev->suplist = pmech;
7991b22764fSDaniel OpenSolaris Anderson pent_dev->sup_count = mcount;
8007c478bd9Sstevel@tonic-gate
8011b22764fSDaniel OpenSolaris Anderson if (build_entrylist(pent_dev, &tmp_pdev) != SUCCESS) {
8027c478bd9Sstevel@tonic-gate goto fail_out;
8037c478bd9Sstevel@tonic-gate }
8047c478bd9Sstevel@tonic-gate }
8057c478bd9Sstevel@tonic-gate
8067c478bd9Sstevel@tonic-gate free(pdevlist_kernel);
8077c478bd9Sstevel@tonic-gate pdevlist_kernel = NULL;
8087c478bd9Sstevel@tonic-gate
8091b22764fSDaniel OpenSolaris Anderson /*
8101b22764fSDaniel OpenSolaris Anderson * Get software providers
8111b22764fSDaniel OpenSolaris Anderson */
8121b22764fSDaniel OpenSolaris Anderson if (getzoneid() == GLOBAL_ZONEID) {
813d616ad8eSHai-May Chao if (get_kcfconf_info(&phardlist, &psoftlist) != SUCCESS) {
8141b22764fSDaniel OpenSolaris Anderson goto fail_out;
8151b22764fSDaniel OpenSolaris Anderson }
8161b22764fSDaniel OpenSolaris Anderson }
8171b22764fSDaniel OpenSolaris Anderson
8187c478bd9Sstevel@tonic-gate if (get_soft_list(&psoftlist_kernel) != SUCCESS) {
8197c478bd9Sstevel@tonic-gate cryptodebug("failed to get software provider list from kernel");
8207c478bd9Sstevel@tonic-gate goto fail_out;
8217c478bd9Sstevel@tonic-gate }
8227c478bd9Sstevel@tonic-gate
8237c478bd9Sstevel@tonic-gate for (i = 0, psoftname = psoftlist_kernel->sl_soft_names;
8247c478bd9Sstevel@tonic-gate i < psoftlist_kernel->sl_soft_count;
8257c478bd9Sstevel@tonic-gate i++, psoftname = psoftname + strlen(psoftname) + 1) {
8267c478bd9Sstevel@tonic-gate pmech = NULL;
827d616ad8eSHai-May Chao if (get_soft_info(psoftname, &pmech, phardlist, psoftlist) !=
828d616ad8eSHai-May Chao SUCCESS) {
8297c478bd9Sstevel@tonic-gate cryptodebug(
8307c478bd9Sstevel@tonic-gate "failed to retrieve the mechanism list for %s.",
8317c478bd9Sstevel@tonic-gate psoftname);
8327c478bd9Sstevel@tonic-gate goto fail_out;
8337c478bd9Sstevel@tonic-gate }
8347c478bd9Sstevel@tonic-gate
8351b22764fSDaniel OpenSolaris Anderson if ((pent_soft = create_entry(psoftname)) == NULL) {
8367c478bd9Sstevel@tonic-gate cryptodebug("out of memory.");
8377c478bd9Sstevel@tonic-gate free_mechlist(pmech);
8387c478bd9Sstevel@tonic-gate goto fail_out;
8397c478bd9Sstevel@tonic-gate }
8401b22764fSDaniel OpenSolaris Anderson pent_soft->suplist = pmech;
8411b22764fSDaniel OpenSolaris Anderson pent_soft->sup_count = get_mech_count(pmech);
8427c478bd9Sstevel@tonic-gate
8431b22764fSDaniel OpenSolaris Anderson if (build_entrylist(pent_soft, &tmp_psoft) != SUCCESS) {
8447c478bd9Sstevel@tonic-gate goto fail_out;
8457c478bd9Sstevel@tonic-gate }
8467c478bd9Sstevel@tonic-gate }
8477c478bd9Sstevel@tonic-gate
8487c478bd9Sstevel@tonic-gate free(psoftlist_kernel);
8497c478bd9Sstevel@tonic-gate psoftlist_kernel = NULL;
8507c478bd9Sstevel@tonic-gate
8517c478bd9Sstevel@tonic-gate *ppdevlist = tmp_pdev;
8527c478bd9Sstevel@tonic-gate *ppsoftlist = tmp_psoft;
8537c478bd9Sstevel@tonic-gate
8547c478bd9Sstevel@tonic-gate return (SUCCESS);
8557c478bd9Sstevel@tonic-gate
8567c478bd9Sstevel@tonic-gate fail_out:
8571b22764fSDaniel OpenSolaris Anderson if (pent_dev != NULL)
8581b22764fSDaniel OpenSolaris Anderson free_entry(pent_dev);
8591b22764fSDaniel OpenSolaris Anderson if (pent_soft != NULL)
8601b22764fSDaniel OpenSolaris Anderson free_entry(pent_soft);
8617c478bd9Sstevel@tonic-gate
8627c478bd9Sstevel@tonic-gate free_entrylist(tmp_pdev);
8637c478bd9Sstevel@tonic-gate free_entrylist(tmp_psoft);
8647c478bd9Sstevel@tonic-gate
8657c478bd9Sstevel@tonic-gate if (pdevlist_kernel != NULL)
8667c478bd9Sstevel@tonic-gate free(pdevlist_kernel);
8677c478bd9Sstevel@tonic-gate if (psoftlist_kernel != NULL)
8687c478bd9Sstevel@tonic-gate free(psoftlist_kernel);
8697c478bd9Sstevel@tonic-gate
8707c478bd9Sstevel@tonic-gate return (FAILURE);
8717c478bd9Sstevel@tonic-gate }
8727c478bd9Sstevel@tonic-gate
8737c478bd9Sstevel@tonic-gate /*
8741b22764fSDaniel OpenSolaris Anderson * Return configuration information for a kernel provider from kcf.conf.
8751b22764fSDaniel OpenSolaris Anderson * For kernel software providers return a enabled list and disabled list.
8761b22764fSDaniel OpenSolaris Anderson * For kernel hardware providers return just a disabled list.
8771b22764fSDaniel OpenSolaris Anderson *
8781b22764fSDaniel OpenSolaris Anderson * Parameters phardlist and psoftlist are supplied by get_kcfconf_info().
8791b22764fSDaniel OpenSolaris Anderson * If NULL, this function calls get_kcfconf_info() internally.
8807c478bd9Sstevel@tonic-gate */
8817c478bd9Sstevel@tonic-gate entry_t *
getent_kef(char * provname,entrylist_t * phardlist,entrylist_t * psoftlist)882d616ad8eSHai-May Chao getent_kef(char *provname, entrylist_t *phardlist, entrylist_t *psoftlist)
8837c478bd9Sstevel@tonic-gate {
8847c478bd9Sstevel@tonic-gate entry_t *pent = NULL;
8851b22764fSDaniel OpenSolaris Anderson boolean_t memory_allocated = B_FALSE;
8867c478bd9Sstevel@tonic-gate
887d616ad8eSHai-May Chao if ((phardlist == NULL) || (psoftlist == NULL)) {
888d616ad8eSHai-May Chao if (get_kcfconf_info(&phardlist, &psoftlist) != SUCCESS) {
8897c478bd9Sstevel@tonic-gate return (NULL);
8907c478bd9Sstevel@tonic-gate }
8911b22764fSDaniel OpenSolaris Anderson memory_allocated = B_TRUE;
8921b22764fSDaniel OpenSolaris Anderson }
8937c478bd9Sstevel@tonic-gate
8947c478bd9Sstevel@tonic-gate if (is_device(provname)) {
8951b22764fSDaniel OpenSolaris Anderson pent = getent(provname, phardlist);
8967c478bd9Sstevel@tonic-gate } else {
8977c478bd9Sstevel@tonic-gate pent = getent(provname, psoftlist);
8987c478bd9Sstevel@tonic-gate }
8997c478bd9Sstevel@tonic-gate
9001b22764fSDaniel OpenSolaris Anderson if (memory_allocated) {
9011b22764fSDaniel OpenSolaris Anderson free_entrylist(phardlist);
9027c478bd9Sstevel@tonic-gate free_entrylist(psoftlist);
9031b22764fSDaniel OpenSolaris Anderson }
9047c478bd9Sstevel@tonic-gate
9057c478bd9Sstevel@tonic-gate return (pent);
9067c478bd9Sstevel@tonic-gate }
9077c478bd9Sstevel@tonic-gate
9087c478bd9Sstevel@tonic-gate /*
9097c478bd9Sstevel@tonic-gate * Print out the provider name and the mechanism list.
9107c478bd9Sstevel@tonic-gate */
9117c478bd9Sstevel@tonic-gate void
print_mechlist(char * provname,mechlist_t * pmechlist)9127c478bd9Sstevel@tonic-gate print_mechlist(char *provname, mechlist_t *pmechlist)
9137c478bd9Sstevel@tonic-gate {
9141b22764fSDaniel OpenSolaris Anderson mechlist_t *ptr = NULL;
9157c478bd9Sstevel@tonic-gate
9167c478bd9Sstevel@tonic-gate if (provname == NULL) {
9177c478bd9Sstevel@tonic-gate return;
9187c478bd9Sstevel@tonic-gate }
9197c478bd9Sstevel@tonic-gate
9207c478bd9Sstevel@tonic-gate (void) printf("%s: ", provname);
9217c478bd9Sstevel@tonic-gate if (pmechlist == NULL) {
9227c478bd9Sstevel@tonic-gate (void) printf(gettext("No mechanisms presented.\n"));
9237c478bd9Sstevel@tonic-gate return;
9247c478bd9Sstevel@tonic-gate }
9257c478bd9Sstevel@tonic-gate
9267c478bd9Sstevel@tonic-gate ptr = pmechlist;
9277c478bd9Sstevel@tonic-gate while (ptr != NULL) {
9287c478bd9Sstevel@tonic-gate (void) printf("%s", ptr->name);
9297c478bd9Sstevel@tonic-gate ptr = ptr->next;
9307c478bd9Sstevel@tonic-gate if (ptr == NULL) {
9317c478bd9Sstevel@tonic-gate (void) printf("\n");
9327c478bd9Sstevel@tonic-gate } else {
9337c478bd9Sstevel@tonic-gate (void) printf(",");
9347c478bd9Sstevel@tonic-gate }
9357c478bd9Sstevel@tonic-gate }
9367c478bd9Sstevel@tonic-gate }
9377c478bd9Sstevel@tonic-gate
9387c478bd9Sstevel@tonic-gate
9397c478bd9Sstevel@tonic-gate /*
9401b22764fSDaniel OpenSolaris Anderson * Update the kcf.conf file based on the update mode:
9411b22764fSDaniel OpenSolaris Anderson * - If update_mode is MODIFY_MODE, modify the entry with the same name.
9421b22764fSDaniel OpenSolaris Anderson * If not found, append a new entry to the kcf.conf file.
9431b22764fSDaniel OpenSolaris Anderson * - If update_mode is DELETE_MODE, delete the entry with the same name.
9441b22764fSDaniel OpenSolaris Anderson * - If update_mode is ADD_MODE, append a new entry to the kcf.conf file.
9457c478bd9Sstevel@tonic-gate */
9467c478bd9Sstevel@tonic-gate int
update_kcfconf(entry_t * pent,int update_mode)9477c478bd9Sstevel@tonic-gate update_kcfconf(entry_t *pent, int update_mode)
9487c478bd9Sstevel@tonic-gate {
9497c478bd9Sstevel@tonic-gate boolean_t add_it = B_FALSE;
9507c478bd9Sstevel@tonic-gate boolean_t delete_it = B_FALSE;
951b50892d1SDan OpenSolaris Anderson boolean_t this_entry_matches = B_FALSE;
9527c478bd9Sstevel@tonic-gate boolean_t found_entry = B_FALSE;
9531b22764fSDaniel OpenSolaris Anderson FILE *pfile = NULL;
9541b22764fSDaniel OpenSolaris Anderson FILE *pfile_tmp = NULL;
9557c478bd9Sstevel@tonic-gate char buffer[BUFSIZ];
9567c478bd9Sstevel@tonic-gate char buffer2[BUFSIZ];
9577c478bd9Sstevel@tonic-gate char tmpfile_name[MAXPATHLEN];
9587c478bd9Sstevel@tonic-gate char *name;
9597c478bd9Sstevel@tonic-gate char *new_str = NULL;
9607c478bd9Sstevel@tonic-gate int rc = SUCCESS;
9617c478bd9Sstevel@tonic-gate
9627c478bd9Sstevel@tonic-gate if (pent == NULL) {
9637c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("internal error."));
9647c478bd9Sstevel@tonic-gate return (FAILURE);
9657c478bd9Sstevel@tonic-gate }
9667c478bd9Sstevel@tonic-gate
9677c478bd9Sstevel@tonic-gate /* Check the update_mode */
9681b22764fSDaniel OpenSolaris Anderson switch (update_mode) {
9691b22764fSDaniel OpenSolaris Anderson case ADD_MODE:
9707c478bd9Sstevel@tonic-gate add_it = B_TRUE;
9711b22764fSDaniel OpenSolaris Anderson /* FALLTHROUGH */
9721b22764fSDaniel OpenSolaris Anderson case MODIFY_MODE:
9731b22764fSDaniel OpenSolaris Anderson /* Convert the entry a string to add to kcf.conf */
9747c478bd9Sstevel@tonic-gate if ((new_str = ent2str(pent)) == NULL) {
9757c478bd9Sstevel@tonic-gate return (FAILURE);
9767c478bd9Sstevel@tonic-gate }
977*0f5cc0e1SDan OpenSolaris Anderson if (strlen(new_str) == 0) {
978*0f5cc0e1SDan OpenSolaris Anderson free(new_str);
979*0f5cc0e1SDan OpenSolaris Anderson delete_it = B_TRUE;
980*0f5cc0e1SDan OpenSolaris Anderson }
9811b22764fSDaniel OpenSolaris Anderson break;
9821b22764fSDaniel OpenSolaris Anderson case DELETE_MODE:
9837c478bd9Sstevel@tonic-gate delete_it = B_TRUE;
9841b22764fSDaniel OpenSolaris Anderson break;
9851b22764fSDaniel OpenSolaris Anderson default:
9867c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("internal error."));
9877c478bd9Sstevel@tonic-gate return (FAILURE);
9887c478bd9Sstevel@tonic-gate }
9897c478bd9Sstevel@tonic-gate
9907c478bd9Sstevel@tonic-gate /* Open the kcf.conf file */
9917c478bd9Sstevel@tonic-gate if ((pfile = fopen(_PATH_KCF_CONF, "r+")) == NULL) {
9927c478bd9Sstevel@tonic-gate err = errno;
9937c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR,
9947c478bd9Sstevel@tonic-gate gettext("failed to update the configuration - %s"),
9957c478bd9Sstevel@tonic-gate strerror(err));
9967c478bd9Sstevel@tonic-gate cryptodebug("failed to open %s for write.", _PATH_KCF_CONF);
9977c478bd9Sstevel@tonic-gate return (FAILURE);
9987c478bd9Sstevel@tonic-gate }
9997c478bd9Sstevel@tonic-gate
10007c478bd9Sstevel@tonic-gate /* Lock the kcf.conf file */
10017c478bd9Sstevel@tonic-gate if (lockf(fileno(pfile), F_TLOCK, 0) == -1) {
10027c478bd9Sstevel@tonic-gate err = errno;
10037c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR,
10047c478bd9Sstevel@tonic-gate gettext("failed to update the configuration - %s"),
10057c478bd9Sstevel@tonic-gate strerror(err));
10067c478bd9Sstevel@tonic-gate (void) fclose(pfile);
10077c478bd9Sstevel@tonic-gate return (FAILURE);
10087c478bd9Sstevel@tonic-gate }
10097c478bd9Sstevel@tonic-gate
10107c478bd9Sstevel@tonic-gate /*
10117c478bd9Sstevel@tonic-gate * Create a temporary file in the /etc/crypto directory to save
10127c478bd9Sstevel@tonic-gate * updated configuration file first.
10137c478bd9Sstevel@tonic-gate */
10147c478bd9Sstevel@tonic-gate (void) strlcpy(tmpfile_name, TMPFILE_TEMPLATE, sizeof (tmpfile_name));
10157c478bd9Sstevel@tonic-gate if (mkstemp(tmpfile_name) == -1) {
10167c478bd9Sstevel@tonic-gate err = errno;
10177c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR,
10187c478bd9Sstevel@tonic-gate gettext("failed to create a temporary file - %s"),
10197c478bd9Sstevel@tonic-gate strerror(err));
10207c478bd9Sstevel@tonic-gate (void) fclose(pfile);
10217c478bd9Sstevel@tonic-gate return (FAILURE);
10227c478bd9Sstevel@tonic-gate }
10237c478bd9Sstevel@tonic-gate
10247c478bd9Sstevel@tonic-gate if ((pfile_tmp = fopen(tmpfile_name, "w")) == NULL) {
10257c478bd9Sstevel@tonic-gate err = errno;
10267c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("failed to open %s - %s"),
10277c478bd9Sstevel@tonic-gate tmpfile_name, strerror(err));
10287c478bd9Sstevel@tonic-gate (void) fclose(pfile);
10297c478bd9Sstevel@tonic-gate return (FAILURE);
10307c478bd9Sstevel@tonic-gate }
10317c478bd9Sstevel@tonic-gate
10327c478bd9Sstevel@tonic-gate /*
10337c478bd9Sstevel@tonic-gate * Loop thru the entire kcf.conf file, insert, modify or delete
10347c478bd9Sstevel@tonic-gate * an entry.
10357c478bd9Sstevel@tonic-gate */
10367c478bd9Sstevel@tonic-gate while (fgets(buffer, BUFSIZ, pfile) != NULL) {
10377c478bd9Sstevel@tonic-gate if (add_it) {
10387c478bd9Sstevel@tonic-gate if (fputs(buffer, pfile_tmp) == EOF) {
10397c478bd9Sstevel@tonic-gate err = errno;
10407c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext(
10417c478bd9Sstevel@tonic-gate "failed to write to a temp file: %s."),
10427c478bd9Sstevel@tonic-gate strerror(err));
10437c478bd9Sstevel@tonic-gate rc = FAILURE;
10447c478bd9Sstevel@tonic-gate break;
10457c478bd9Sstevel@tonic-gate }
10467c478bd9Sstevel@tonic-gate
10477c478bd9Sstevel@tonic-gate } else { /* modify or delete */
1048b50892d1SDan OpenSolaris Anderson this_entry_matches = B_FALSE;
10491b22764fSDaniel OpenSolaris Anderson
10507c478bd9Sstevel@tonic-gate if (!(buffer[0] == '#' || buffer[0] == ' ' ||
10517c478bd9Sstevel@tonic-gate buffer[0] == '\n'|| buffer[0] == '\t')) {
10527c478bd9Sstevel@tonic-gate /*
10537c478bd9Sstevel@tonic-gate * Get the provider name from this line and
10547c478bd9Sstevel@tonic-gate * check if this is the entry to be updated
10557c478bd9Sstevel@tonic-gate * or deleted. Note: can not use "buffer"
10567c478bd9Sstevel@tonic-gate * directly because strtok will change its
10577c478bd9Sstevel@tonic-gate * value.
10587c478bd9Sstevel@tonic-gate */
10597c478bd9Sstevel@tonic-gate (void) strlcpy(buffer2, buffer, BUFSIZ);
10607c478bd9Sstevel@tonic-gate if ((name = strtok(buffer2, SEP_COLON)) ==
10617c478bd9Sstevel@tonic-gate NULL) {
10627c478bd9Sstevel@tonic-gate rc = FAILURE;
10637c478bd9Sstevel@tonic-gate break;
10647c478bd9Sstevel@tonic-gate }
10657c478bd9Sstevel@tonic-gate
10667c478bd9Sstevel@tonic-gate if (strcmp(pent->name, name) == 0) {
1067b50892d1SDan OpenSolaris Anderson this_entry_matches = B_TRUE;
10687c478bd9Sstevel@tonic-gate found_entry = B_TRUE;
10697c478bd9Sstevel@tonic-gate }
10707c478bd9Sstevel@tonic-gate }
10717c478bd9Sstevel@tonic-gate
1072b50892d1SDan OpenSolaris Anderson
1073b50892d1SDan OpenSolaris Anderson if (!this_entry_matches || !delete_it) {
1074b50892d1SDan OpenSolaris Anderson /* write this entry */
1075b50892d1SDan OpenSolaris Anderson if (this_entry_matches) {
10767c478bd9Sstevel@tonic-gate /*
1077b50892d1SDan OpenSolaris Anderson * Modify this entry: get the
10787c478bd9Sstevel@tonic-gate * updated string and place into buffer.
10797c478bd9Sstevel@tonic-gate */
10801b22764fSDaniel OpenSolaris Anderson (void) strlcpy(buffer, new_str, BUFSIZ);
10811b22764fSDaniel OpenSolaris Anderson free(new_str);
10827c478bd9Sstevel@tonic-gate }
1083b50892d1SDan OpenSolaris Anderson /* write the (unchanged or modified) entry */
10847c478bd9Sstevel@tonic-gate if (fputs(buffer, pfile_tmp) == EOF) {
10857c478bd9Sstevel@tonic-gate err = errno;
10867c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext(
10877c478bd9Sstevel@tonic-gate "failed to write to a temp file: "
10887c478bd9Sstevel@tonic-gate "%s."), strerror(err));
10897c478bd9Sstevel@tonic-gate rc = FAILURE;
10907c478bd9Sstevel@tonic-gate break;
10917c478bd9Sstevel@tonic-gate }
10927c478bd9Sstevel@tonic-gate }
10937c478bd9Sstevel@tonic-gate }
10947c478bd9Sstevel@tonic-gate }
10957c478bd9Sstevel@tonic-gate
10961b22764fSDaniel OpenSolaris Anderson if ((!delete_it) && (rc != FAILURE)) {
10971b22764fSDaniel OpenSolaris Anderson if (add_it || !found_entry) {
10981b22764fSDaniel OpenSolaris Anderson /* append new entry to end of file */
10991b22764fSDaniel OpenSolaris Anderson if (fputs(new_str, pfile_tmp) == EOF) {
11007c478bd9Sstevel@tonic-gate err = errno;
11017c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext(
11021b22764fSDaniel OpenSolaris Anderson "failed to write to a temp file: %s."),
11031b22764fSDaniel OpenSolaris Anderson strerror(err));
11041b22764fSDaniel OpenSolaris Anderson rc = FAILURE;
11057c478bd9Sstevel@tonic-gate }
11061b22764fSDaniel OpenSolaris Anderson free(new_str);
11071b22764fSDaniel OpenSolaris Anderson }
11087c478bd9Sstevel@tonic-gate }
11097c478bd9Sstevel@tonic-gate
11107c478bd9Sstevel@tonic-gate (void) fclose(pfile);
11117c478bd9Sstevel@tonic-gate if (fclose(pfile_tmp) != 0) {
11127c478bd9Sstevel@tonic-gate err = errno;
11137c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR,
11147c478bd9Sstevel@tonic-gate gettext("failed to close %s: %s"), tmpfile_name,
11157c478bd9Sstevel@tonic-gate strerror(err));
11167c478bd9Sstevel@tonic-gate return (FAILURE);
11177c478bd9Sstevel@tonic-gate }
11187c478bd9Sstevel@tonic-gate
11197c478bd9Sstevel@tonic-gate /* Copy the temporary file to the kcf.conf file */
11207c478bd9Sstevel@tonic-gate if (rename(tmpfile_name, _PATH_KCF_CONF) == -1) {
11217c478bd9Sstevel@tonic-gate err = errno;
11227c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR,
11237c478bd9Sstevel@tonic-gate gettext("failed to update the configuration - %s"),
11247c478bd9Sstevel@tonic-gate strerror(err));
11257c478bd9Sstevel@tonic-gate cryptodebug("failed to rename %s to %s: %s", tmpfile,
11267c478bd9Sstevel@tonic-gate _PATH_KCF_CONF, strerror(err));
11277c478bd9Sstevel@tonic-gate rc = FAILURE;
11287c478bd9Sstevel@tonic-gate } else if (chmod(_PATH_KCF_CONF,
11297c478bd9Sstevel@tonic-gate S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) {
11307c478bd9Sstevel@tonic-gate err = errno;
11317c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR,
11327c478bd9Sstevel@tonic-gate gettext("failed to update the configuration - %s"),
11337c478bd9Sstevel@tonic-gate strerror(err));
11347c478bd9Sstevel@tonic-gate cryptodebug("failed to chmod to %s: %s", _PATH_KCF_CONF,
11357c478bd9Sstevel@tonic-gate strerror(err));
11367c478bd9Sstevel@tonic-gate rc = FAILURE;
11377c478bd9Sstevel@tonic-gate } else {
11387c478bd9Sstevel@tonic-gate rc = SUCCESS;
11397c478bd9Sstevel@tonic-gate }
11407c478bd9Sstevel@tonic-gate
11417c478bd9Sstevel@tonic-gate if ((rc == FAILURE) && (unlink(tmpfile_name) != 0)) {
11427c478bd9Sstevel@tonic-gate err = errno;
11437c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext(
11447c478bd9Sstevel@tonic-gate "(Warning) failed to remove %s: %s"),
11457c478bd9Sstevel@tonic-gate tmpfile_name, strerror(err));
11467c478bd9Sstevel@tonic-gate }
11477c478bd9Sstevel@tonic-gate
11487c478bd9Sstevel@tonic-gate return (rc);
11497c478bd9Sstevel@tonic-gate }
11507c478bd9Sstevel@tonic-gate
11517c478bd9Sstevel@tonic-gate
11527c478bd9Sstevel@tonic-gate /*
11537c478bd9Sstevel@tonic-gate * Disable the mechanisms for the provider pointed by *ppent. If allflag is
11547c478bd9Sstevel@tonic-gate * TRUE, disable all. Otherwise, disable the mechanisms specified in the
11557c478bd9Sstevel@tonic-gate * dislist argument. The "infolist" argument contains the mechanism list
11567c478bd9Sstevel@tonic-gate * supported by this provider.
11577c478bd9Sstevel@tonic-gate */
11587c478bd9Sstevel@tonic-gate int
disable_mechs(entry_t ** ppent,mechlist_t * infolist,boolean_t allflag,mechlist_t * dislist)11597c478bd9Sstevel@tonic-gate disable_mechs(entry_t **ppent, mechlist_t *infolist, boolean_t allflag,
11607c478bd9Sstevel@tonic-gate mechlist_t *dislist)
11617c478bd9Sstevel@tonic-gate {
11627c478bd9Sstevel@tonic-gate entry_t *pent;
11631b22764fSDaniel OpenSolaris Anderson mechlist_t *plist = NULL;
11641b22764fSDaniel OpenSolaris Anderson mechlist_t *phead = NULL;
11651b22764fSDaniel OpenSolaris Anderson mechlist_t *pmech = NULL;
11667c478bd9Sstevel@tonic-gate int rc = SUCCESS;
11677c478bd9Sstevel@tonic-gate
11687c478bd9Sstevel@tonic-gate pent = *ppent;
11697c478bd9Sstevel@tonic-gate if (pent == NULL) {
11707c478bd9Sstevel@tonic-gate return (FAILURE);
11717c478bd9Sstevel@tonic-gate }
11727c478bd9Sstevel@tonic-gate
11737c478bd9Sstevel@tonic-gate if (allflag) {
11747c478bd9Sstevel@tonic-gate free_mechlist(pent->dislist);
11757c478bd9Sstevel@tonic-gate pent->dis_count = get_mech_count(infolist);
11767c478bd9Sstevel@tonic-gate if (!(pent->dislist = dup_mechlist(infolist))) {
11777c478bd9Sstevel@tonic-gate return (FAILURE);
11787c478bd9Sstevel@tonic-gate } else {
11797c478bd9Sstevel@tonic-gate return (SUCCESS);
11807c478bd9Sstevel@tonic-gate }
11817c478bd9Sstevel@tonic-gate }
11827c478bd9Sstevel@tonic-gate
11837c478bd9Sstevel@tonic-gate /*
11847c478bd9Sstevel@tonic-gate * Not disable all. Now loop thru the mechanisms specified in the
11857c478bd9Sstevel@tonic-gate * dislist. If the mechanism is not supported by the provider,
11867c478bd9Sstevel@tonic-gate * ignore it with a warning. If the mechanism is disabled already,
11877c478bd9Sstevel@tonic-gate * do nothing. Otherwise, prepend it to the beginning of the disabled
11887c478bd9Sstevel@tonic-gate * list of the provider.
11897c478bd9Sstevel@tonic-gate */
11907c478bd9Sstevel@tonic-gate plist = dislist;
11917c478bd9Sstevel@tonic-gate while (plist != NULL) {
11927c478bd9Sstevel@tonic-gate if (!is_in_list(plist->name, infolist)) {
11937c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("(Warning) "
11947c478bd9Sstevel@tonic-gate "%1$s is not a valid mechanism for %2$s."),
11957c478bd9Sstevel@tonic-gate plist->name, pent->name);
11967c478bd9Sstevel@tonic-gate } else if (!is_in_list(plist->name, pent->dislist)) {
11977c478bd9Sstevel@tonic-gate /* Add this mechanism into the disabled list */
11987c478bd9Sstevel@tonic-gate if ((pmech = create_mech(plist->name)) == NULL) {
11997c478bd9Sstevel@tonic-gate rc = FAILURE;
12007c478bd9Sstevel@tonic-gate break;
12017c478bd9Sstevel@tonic-gate }
12027c478bd9Sstevel@tonic-gate
12037c478bd9Sstevel@tonic-gate if (pent->dislist == NULL) {
12047c478bd9Sstevel@tonic-gate pent->dislist = pmech;
12057c478bd9Sstevel@tonic-gate } else {
12067c478bd9Sstevel@tonic-gate phead = pent->dislist;
12077c478bd9Sstevel@tonic-gate pent->dislist = pmech;
12087c478bd9Sstevel@tonic-gate pmech->next = phead;
12097c478bd9Sstevel@tonic-gate }
12107c478bd9Sstevel@tonic-gate pent->dis_count++;
12117c478bd9Sstevel@tonic-gate }
12127c478bd9Sstevel@tonic-gate plist = plist->next;
12137c478bd9Sstevel@tonic-gate }
12147c478bd9Sstevel@tonic-gate
12157c478bd9Sstevel@tonic-gate return (rc);
12167c478bd9Sstevel@tonic-gate }
12177c478bd9Sstevel@tonic-gate
12187c478bd9Sstevel@tonic-gate /*
12197c478bd9Sstevel@tonic-gate * Remove the mechanism passed, specified by mech, from the list of
12207c478bd9Sstevel@tonic-gate * mechanisms, if present in the list. Else, do nothing.
12217c478bd9Sstevel@tonic-gate *
12227c478bd9Sstevel@tonic-gate * Returns B_TRUE if mechanism is present in the list.
12237c478bd9Sstevel@tonic-gate */
12247c478bd9Sstevel@tonic-gate boolean_t
filter_mechlist(mechlist_t ** pmechlist,const char * mech)12257c478bd9Sstevel@tonic-gate filter_mechlist(mechlist_t **pmechlist, const char *mech)
12267c478bd9Sstevel@tonic-gate {
12277c478bd9Sstevel@tonic-gate int cnt = 0;
12287c478bd9Sstevel@tonic-gate mechlist_t *ptr, *pptr;
12297c478bd9Sstevel@tonic-gate boolean_t mech_present = B_FALSE;
12307c478bd9Sstevel@tonic-gate
12317c478bd9Sstevel@tonic-gate ptr = pptr = *pmechlist;
12327c478bd9Sstevel@tonic-gate
12337c478bd9Sstevel@tonic-gate while (ptr != NULL) {
12347c478bd9Sstevel@tonic-gate if (strncmp(ptr->name, mech, sizeof (mech_name_t)) == 0) {
12357c478bd9Sstevel@tonic-gate mech_present = B_TRUE;
12367c478bd9Sstevel@tonic-gate if (ptr == *pmechlist) {
12377c478bd9Sstevel@tonic-gate pptr = *pmechlist = ptr->next;
12387c478bd9Sstevel@tonic-gate free(ptr);
12397c478bd9Sstevel@tonic-gate ptr = pptr;
12407c478bd9Sstevel@tonic-gate } else {
12417c478bd9Sstevel@tonic-gate pptr->next = ptr->next;
12427c478bd9Sstevel@tonic-gate free(ptr);
12437c478bd9Sstevel@tonic-gate ptr = pptr->next;
12447c478bd9Sstevel@tonic-gate }
12457c478bd9Sstevel@tonic-gate } else {
12467c478bd9Sstevel@tonic-gate pptr = ptr;
12477c478bd9Sstevel@tonic-gate ptr = ptr->next;
12487c478bd9Sstevel@tonic-gate cnt++;
12497c478bd9Sstevel@tonic-gate }
12507c478bd9Sstevel@tonic-gate }
12517c478bd9Sstevel@tonic-gate
12527c478bd9Sstevel@tonic-gate /* Only one entry is present */
12537c478bd9Sstevel@tonic-gate if (cnt == 0)
12547c478bd9Sstevel@tonic-gate *pmechlist = NULL;
12557c478bd9Sstevel@tonic-gate
12567c478bd9Sstevel@tonic-gate return (mech_present);
12577c478bd9Sstevel@tonic-gate }
12587c478bd9Sstevel@tonic-gate
12597c478bd9Sstevel@tonic-gate
12607c478bd9Sstevel@tonic-gate
12617c478bd9Sstevel@tonic-gate /*
12627c478bd9Sstevel@tonic-gate * Print out the mechanism policy for a kernel provider that has an entry
12637c478bd9Sstevel@tonic-gate * in the kcf.conf file.
12647c478bd9Sstevel@tonic-gate *
12657c478bd9Sstevel@tonic-gate * The flag has_random is set to B_TRUE if the provider does random
12667c478bd9Sstevel@tonic-gate * numbers. The flag has_mechs is set by the caller to B_TRUE if the provider
12677c478bd9Sstevel@tonic-gate * has some mechanisms.
12681b22764fSDaniel OpenSolaris Anderson *
12691b22764fSDaniel OpenSolaris Anderson * If pent is NULL, the provider doesn't have a kcf.conf entry.
12707c478bd9Sstevel@tonic-gate */
12717c478bd9Sstevel@tonic-gate void
print_kef_policy(char * provname,entry_t * pent,boolean_t has_random,boolean_t has_mechs)12721b22764fSDaniel OpenSolaris Anderson print_kef_policy(char *provname, entry_t *pent, boolean_t has_random,
12731b22764fSDaniel OpenSolaris Anderson boolean_t has_mechs)
12747c478bd9Sstevel@tonic-gate {
12751b22764fSDaniel OpenSolaris Anderson mechlist_t *ptr = NULL;
12767c478bd9Sstevel@tonic-gate boolean_t rnd_disabled = B_FALSE;
12777c478bd9Sstevel@tonic-gate
12781b22764fSDaniel OpenSolaris Anderson if (pent != NULL) {
12797c478bd9Sstevel@tonic-gate rnd_disabled = filter_mechlist(&pent->dislist, RANDOM);
12807c478bd9Sstevel@tonic-gate ptr = pent->dislist;
12811b22764fSDaniel OpenSolaris Anderson }
12827c478bd9Sstevel@tonic-gate
12831b22764fSDaniel OpenSolaris Anderson (void) printf("%s:", provname);
12847c478bd9Sstevel@tonic-gate
12857c478bd9Sstevel@tonic-gate if (has_mechs == B_TRUE) {
12867c478bd9Sstevel@tonic-gate /*
12870a85b835SDaniel Anderson * TRANSLATION_NOTE
12887c478bd9Sstevel@tonic-gate * This code block may need to be modified a bit to avoid
12897c478bd9Sstevel@tonic-gate * constructing the text message on the fly.
12907c478bd9Sstevel@tonic-gate */
12917c478bd9Sstevel@tonic-gate (void) printf(gettext(" all mechanisms are enabled"));
12927c478bd9Sstevel@tonic-gate if (ptr != NULL)
12937c478bd9Sstevel@tonic-gate (void) printf(gettext(", except "));
12947c478bd9Sstevel@tonic-gate while (ptr != NULL) {
12957c478bd9Sstevel@tonic-gate (void) printf("%s", ptr->name);
12967c478bd9Sstevel@tonic-gate ptr = ptr->next;
12977c478bd9Sstevel@tonic-gate if (ptr != NULL)
12987c478bd9Sstevel@tonic-gate (void) printf(",");
12997c478bd9Sstevel@tonic-gate }
13007c478bd9Sstevel@tonic-gate if (ptr == NULL)
13017c478bd9Sstevel@tonic-gate (void) printf(".");
13027c478bd9Sstevel@tonic-gate }
13037c478bd9Sstevel@tonic-gate
13047c478bd9Sstevel@tonic-gate /*
13050a85b835SDaniel Anderson * TRANSLATION_NOTE
13067c478bd9Sstevel@tonic-gate * "random" is a keyword and not to be translated.
13077c478bd9Sstevel@tonic-gate */
13087c478bd9Sstevel@tonic-gate if (rnd_disabled)
13097c478bd9Sstevel@tonic-gate (void) printf(gettext(" %s is disabled."), "random");
13107c478bd9Sstevel@tonic-gate else if (has_random)
13117c478bd9Sstevel@tonic-gate (void) printf(gettext(" %s is enabled."), "random");
13127c478bd9Sstevel@tonic-gate (void) printf("\n");
13137c478bd9Sstevel@tonic-gate }
13147c478bd9Sstevel@tonic-gate
13151b22764fSDaniel OpenSolaris Anderson
13167c478bd9Sstevel@tonic-gate /*
13177c478bd9Sstevel@tonic-gate * Check if a kernel software provider is in the kernel.
13181b22764fSDaniel OpenSolaris Anderson *
13191b22764fSDaniel OpenSolaris Anderson * Parameters:
13201b22764fSDaniel OpenSolaris Anderson * provname Provider name
13211b22764fSDaniel OpenSolaris Anderson * psoftlist_kernel Optional software provider list. If NULL, it will be
13221b22764fSDaniel OpenSolaris Anderson * obtained from get_soft_list().
13231b22764fSDaniel OpenSolaris Anderson * in_kernel Set to B_TRUE if device is in the kernel, else B_FALSE
13247c478bd9Sstevel@tonic-gate */
13257c478bd9Sstevel@tonic-gate int
check_kernel_for_soft(char * provname,crypto_get_soft_list_t * psoftlist_kernel,boolean_t * in_kernel)13261b22764fSDaniel OpenSolaris Anderson check_kernel_for_soft(char *provname, crypto_get_soft_list_t *psoftlist_kernel,
13271b22764fSDaniel OpenSolaris Anderson boolean_t *in_kernel)
13287c478bd9Sstevel@tonic-gate {
13297c478bd9Sstevel@tonic-gate char *ptr;
13307c478bd9Sstevel@tonic-gate int i;
13311b22764fSDaniel OpenSolaris Anderson boolean_t psoftlist_allocated = B_FALSE;
13327c478bd9Sstevel@tonic-gate
13337c478bd9Sstevel@tonic-gate if (provname == NULL) {
13347c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("internal error."));
13357c478bd9Sstevel@tonic-gate return (FAILURE);
13367c478bd9Sstevel@tonic-gate }
13377c478bd9Sstevel@tonic-gate
13381b22764fSDaniel OpenSolaris Anderson if (psoftlist_kernel == NULL) {
13397c478bd9Sstevel@tonic-gate if (get_soft_list(&psoftlist_kernel) == FAILURE) {
13401b22764fSDaniel OpenSolaris Anderson cryptodebug("failed to get the software provider list"
13411b22764fSDaniel OpenSolaris Anderson " from kernel.");
13427c478bd9Sstevel@tonic-gate return (FAILURE);
13437c478bd9Sstevel@tonic-gate }
13441b22764fSDaniel OpenSolaris Anderson psoftlist_allocated = B_TRUE;
13451b22764fSDaniel OpenSolaris Anderson }
13467c478bd9Sstevel@tonic-gate
13471b22764fSDaniel OpenSolaris Anderson *in_kernel = B_FALSE;
13487c478bd9Sstevel@tonic-gate ptr = psoftlist_kernel->sl_soft_names;
13497c478bd9Sstevel@tonic-gate for (i = 0; i < psoftlist_kernel->sl_soft_count; i++) {
13507c478bd9Sstevel@tonic-gate if (strcmp(provname, ptr) == 0) {
13511b22764fSDaniel OpenSolaris Anderson *in_kernel = B_TRUE;
13527c478bd9Sstevel@tonic-gate break;
13537c478bd9Sstevel@tonic-gate }
13547c478bd9Sstevel@tonic-gate ptr = ptr + strlen(ptr) + 1;
13557c478bd9Sstevel@tonic-gate }
13561b22764fSDaniel OpenSolaris Anderson
13571b22764fSDaniel OpenSolaris Anderson if (psoftlist_allocated)
13587c478bd9Sstevel@tonic-gate free(psoftlist_kernel);
13597c478bd9Sstevel@tonic-gate
13607c478bd9Sstevel@tonic-gate return (SUCCESS);
13617c478bd9Sstevel@tonic-gate }
13627c478bd9Sstevel@tonic-gate
13637c478bd9Sstevel@tonic-gate
13647c478bd9Sstevel@tonic-gate /*
13657c478bd9Sstevel@tonic-gate * Check if a kernel hardware provider is in the kernel.
13661b22764fSDaniel OpenSolaris Anderson *
13671b22764fSDaniel OpenSolaris Anderson * Parameters:
13681b22764fSDaniel OpenSolaris Anderson * provname Provider name
13691b22764fSDaniel OpenSolaris Anderson * pdevlist Optional Hardware Crypto Device List. If NULL, it will be
13701b22764fSDaniel OpenSolaris Anderson * obtained from get_dev_list().
13711b22764fSDaniel OpenSolaris Anderson * in_kernel Set to B_TRUE if device is in the kernel, otherwise B_FALSE
13727c478bd9Sstevel@tonic-gate */
13737c478bd9Sstevel@tonic-gate int
check_kernel_for_hard(char * provname,crypto_get_dev_list_t * pdevlist,boolean_t * in_kernel)13741b22764fSDaniel OpenSolaris Anderson check_kernel_for_hard(char *provname,
13751b22764fSDaniel OpenSolaris Anderson crypto_get_dev_list_t *pdevlist, boolean_t *in_kernel)
13767c478bd9Sstevel@tonic-gate {
13777c478bd9Sstevel@tonic-gate char devname[MAXNAMELEN];
13787c478bd9Sstevel@tonic-gate int inst_num;
13797c478bd9Sstevel@tonic-gate int i;
13801b22764fSDaniel OpenSolaris Anderson boolean_t dev_list_allocated = B_FALSE;
13817c478bd9Sstevel@tonic-gate
13827c478bd9Sstevel@tonic-gate if (provname == NULL) {
13837c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("internal error."));
13847c478bd9Sstevel@tonic-gate return (FAILURE);
13857c478bd9Sstevel@tonic-gate }
13867c478bd9Sstevel@tonic-gate
13877c478bd9Sstevel@tonic-gate if (split_hw_provname(provname, devname, &inst_num) == FAILURE) {
13887c478bd9Sstevel@tonic-gate return (FAILURE);
13897c478bd9Sstevel@tonic-gate }
13907c478bd9Sstevel@tonic-gate
13911b22764fSDaniel OpenSolaris Anderson if (pdevlist == NULL) {
13927c478bd9Sstevel@tonic-gate if (get_dev_list(&pdevlist) == FAILURE) {
13937c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("internal error."));
13947c478bd9Sstevel@tonic-gate return (FAILURE);
13957c478bd9Sstevel@tonic-gate }
13961b22764fSDaniel OpenSolaris Anderson dev_list_allocated = B_TRUE;
13971b22764fSDaniel OpenSolaris Anderson }
13987c478bd9Sstevel@tonic-gate
13991b22764fSDaniel OpenSolaris Anderson *in_kernel = B_FALSE;
14007c478bd9Sstevel@tonic-gate for (i = 0; i < pdevlist->dl_dev_count; i++) {
14017c478bd9Sstevel@tonic-gate if ((strcmp(pdevlist->dl_devs[i].le_dev_name, devname) == 0) &&
14027c478bd9Sstevel@tonic-gate (pdevlist->dl_devs[i].le_dev_instance == inst_num)) {
14031b22764fSDaniel OpenSolaris Anderson *in_kernel = B_TRUE;
14047c478bd9Sstevel@tonic-gate break;
14057c478bd9Sstevel@tonic-gate }
14067c478bd9Sstevel@tonic-gate }
14071b22764fSDaniel OpenSolaris Anderson
14081b22764fSDaniel OpenSolaris Anderson if (dev_list_allocated)
14097c478bd9Sstevel@tonic-gate free(pdevlist);
14107c478bd9Sstevel@tonic-gate
14117c478bd9Sstevel@tonic-gate return (SUCCESS);
14127c478bd9Sstevel@tonic-gate }
1413