1*269e59f9SJan Pechanec /*
2*269e59f9SJan Pechanec  * CDDL HEADER START
3*269e59f9SJan Pechanec  *
4*269e59f9SJan Pechanec  * The contents of this file are subject to the terms of the
5*269e59f9SJan Pechanec  * Common Development and Distribution License (the "License").
6*269e59f9SJan Pechanec  * You may not use this file except in compliance with the License.
7*269e59f9SJan Pechanec  *
8*269e59f9SJan Pechanec  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*269e59f9SJan Pechanec  * or http://www.opensolaris.org/os/licensing.
10*269e59f9SJan Pechanec  * See the License for the specific language governing permissions
11*269e59f9SJan Pechanec  * and limitations under the License.
12*269e59f9SJan Pechanec  *
13*269e59f9SJan Pechanec  * When distributing Covered Code, include this CDDL HEADER in each
14*269e59f9SJan Pechanec  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*269e59f9SJan Pechanec  * If applicable, add the following below this CDDL HEADER, with the
16*269e59f9SJan Pechanec  * fields enclosed by brackets "[]" replaced with your own identifying
17*269e59f9SJan Pechanec  * information: Portions Copyright [yyyy] [name of copyright owner]
18*269e59f9SJan Pechanec  *
19*269e59f9SJan Pechanec  * CDDL HEADER END
20*269e59f9SJan Pechanec  *
21*269e59f9SJan Pechanec  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
22*269e59f9SJan Pechanec  *
23*269e59f9SJan Pechanec  * This file implements the KMF certificate to name mapping framework.
24*269e59f9SJan Pechanec  */
25*269e59f9SJan Pechanec #include <stdlib.h>
26*269e59f9SJan Pechanec #include <string.h>
27*269e59f9SJan Pechanec #include <dlfcn.h>
28*269e59f9SJan Pechanec #include <libgen.h>
29*269e59f9SJan Pechanec #include <kmftypes.h>
30*269e59f9SJan Pechanec #include <kmfapiP.h>
31*269e59f9SJan Pechanec 
32*269e59f9SJan Pechanec /* Mappers go in the same dir as plugins. */
33*269e59f9SJan Pechanec #define	DEFAULT_MAPPER_DIR KMF_PLUGIN_PATH
34*269e59f9SJan Pechanec 
35*269e59f9SJan Pechanec static void
cleanup_mapper(KMF_HANDLE_T handle)36*269e59f9SJan Pechanec cleanup_mapper(KMF_HANDLE_T handle)
37*269e59f9SJan Pechanec {
38*269e59f9SJan Pechanec 	KMF_MAPPER_RECORD *mapper = &handle->policy->mapper;
39*269e59f9SJan Pechanec 	void (*finalize)(KMF_HANDLE_T);
40*269e59f9SJan Pechanec 
41*269e59f9SJan Pechanec 	if (mapper->curpathname != NULL) {
42*269e59f9SJan Pechanec 		free(mapper->curpathname);
43*269e59f9SJan Pechanec 		mapper->curpathname = NULL;
44*269e59f9SJan Pechanec 	}
45*269e59f9SJan Pechanec 	if (mapper->curoptions != NULL) {
46*269e59f9SJan Pechanec 		free(mapper->curoptions);
47*269e59f9SJan Pechanec 		mapper->curoptions = NULL;
48*269e59f9SJan Pechanec 	}
49*269e59f9SJan Pechanec 	if (mapper->dldesc != NULL) {
50*269e59f9SJan Pechanec 		finalize = (void(*)())dlsym(mapper->dldesc,
51*269e59f9SJan Pechanec 		    MAPPER_FINISH_FUNCTION);
52*269e59f9SJan Pechanec 		/* Optional, not an error if it does not exist. */
53*269e59f9SJan Pechanec 		if (finalize != NULL)
54*269e59f9SJan Pechanec 			finalize(handle);
55*269e59f9SJan Pechanec 
56*269e59f9SJan Pechanec 		(void) dlclose(mapper->dldesc);
57*269e59f9SJan Pechanec 		mapper->dldesc = NULL;
58*269e59f9SJan Pechanec 	}
59*269e59f9SJan Pechanec }
60*269e59f9SJan Pechanec 
61*269e59f9SJan Pechanec /* The caller is expected to free the returned string. */
62*269e59f9SJan Pechanec char *
get_mapper_pathname(char * name,char * dir)63*269e59f9SJan Pechanec get_mapper_pathname(char *name, char *dir)
64*269e59f9SJan Pechanec {
65*269e59f9SJan Pechanec 	char *pathname = NULL;
66*269e59f9SJan Pechanec 	int len;
67*269e59f9SJan Pechanec 
68*269e59f9SJan Pechanec 	if (name == NULL)
69*269e59f9SJan Pechanec 		return (NULL);
70*269e59f9SJan Pechanec 
71*269e59f9SJan Pechanec 	if (dir == NULL)
72*269e59f9SJan Pechanec 		dir = DEFAULT_MAPPER_DIR;
73*269e59f9SJan Pechanec 
74*269e59f9SJan Pechanec 	/*
75*269e59f9SJan Pechanec 	 * MAPPER_NAME_TEMPLATE has 2 extra characters (%s) which make up for
76*269e59f9SJan Pechanec 	 * the "/" and the terminating NULL when computing the total length.
77*269e59f9SJan Pechanec 	 */
78*269e59f9SJan Pechanec 	len = strlen(name) + strlen(MAPPER_NAME_TEMPLATE) + strlen(dir);
79*269e59f9SJan Pechanec 
80*269e59f9SJan Pechanec 	pathname = malloc(len);
81*269e59f9SJan Pechanec 	if (pathname == NULL)
82*269e59f9SJan Pechanec 		return (NULL);
83*269e59f9SJan Pechanec 	(void) memset(pathname, 0, len);
84*269e59f9SJan Pechanec 	/* Avoid double forward slash if the dir's last character is "/". */
85*269e59f9SJan Pechanec 	(void) snprintf(pathname, len, "%s%s" MAPPER_NAME_TEMPLATE,
86*269e59f9SJan Pechanec 	    dir, dir[strlen(dir) - 1] == '/' ? "" : "/", name);
87*269e59f9SJan Pechanec 
88*269e59f9SJan Pechanec 	return (pathname);
89*269e59f9SJan Pechanec }
90*269e59f9SJan Pechanec 
91*269e59f9SJan Pechanec static KMF_RETURN
open_mapper_library(KMF_MAPPER_RECORD * map)92*269e59f9SJan Pechanec open_mapper_library(KMF_MAPPER_RECORD *map)
93*269e59f9SJan Pechanec {
94*269e59f9SJan Pechanec 	KMF_RETURN ret = KMF_OK;
95*269e59f9SJan Pechanec 
96*269e59f9SJan Pechanec 	map->dldesc = dlopen(map->curpathname, RTLD_LAZY | RTLD_PARENT);
97*269e59f9SJan Pechanec 	if (map->dldesc == NULL)
98*269e59f9SJan Pechanec 		return (KMF_ERR_MAPPER_OPEN);
99*269e59f9SJan Pechanec 
100*269e59f9SJan Pechanec 	return (ret);
101*269e59f9SJan Pechanec }
102*269e59f9SJan Pechanec 
103*269e59f9SJan Pechanec /*
104*269e59f9SJan Pechanec  * The mapping framework uses either attributes or the policy file. Those two
105*269e59f9SJan Pechanec  * sources are never mixed. We always need a mapper name or a mapper pathname
106*269e59f9SJan Pechanec  * but these two are mutually exclusive. Directory can be set only if name is
107*269e59f9SJan Pechanec  * set.
108*269e59f9SJan Pechanec  */
109*269e59f9SJan Pechanec KMF_RETURN
kmf_cert_to_name_mapping_initialize(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)110*269e59f9SJan Pechanec kmf_cert_to_name_mapping_initialize(KMF_HANDLE_T handle, int numattr,
111*269e59f9SJan Pechanec 	KMF_ATTRIBUTE *attrlist)
112*269e59f9SJan Pechanec {
113*269e59f9SJan Pechanec 	KMF_RETURN ret = KMF_OK;
114*269e59f9SJan Pechanec 	KMF_RETURN (*initialize)(KMF_HANDLE_T, char *);
115*269e59f9SJan Pechanec 	KMF_MAPPER_RECORD *map = NULL;
116*269e59f9SJan Pechanec 	char *dir = NULL;
117*269e59f9SJan Pechanec 	char *name = NULL;
118*269e59f9SJan Pechanec 	char *opts = NULL;
119*269e59f9SJan Pechanec 	char *path = NULL;
120*269e59f9SJan Pechanec 	char *tmppath = NULL;
121*269e59f9SJan Pechanec 	char *old_curpathname = NULL;
122*269e59f9SJan Pechanec 	char *old_curoptions = NULL;
123*269e59f9SJan Pechanec 
124*269e59f9SJan Pechanec 	if (handle == NULL)
125*269e59f9SJan Pechanec 		return (KMF_ERR_BAD_PARAMETER);
126*269e59f9SJan Pechanec 
127*269e59f9SJan Pechanec 	map = &handle->policy->mapper;
128*269e59f9SJan Pechanec 	old_curpathname = map->curpathname;
129*269e59f9SJan Pechanec 	old_curoptions = map->curoptions;
130*269e59f9SJan Pechanec 
131*269e59f9SJan Pechanec 	name = kmf_get_attr_ptr(KMF_MAPPER_NAME_ATTR, attrlist, numattr);
132*269e59f9SJan Pechanec 	dir = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
133*269e59f9SJan Pechanec 	path = kmf_get_attr_ptr(KMF_MAPPER_PATH_ATTR, attrlist, numattr);
134*269e59f9SJan Pechanec 	opts = kmf_get_attr_ptr(KMF_MAPPER_OPTIONS_ATTR, attrlist, numattr);
135*269e59f9SJan Pechanec 
136*269e59f9SJan Pechanec 	if (path != NULL) {
137*269e59f9SJan Pechanec 		/* Mutually exclusive. */
138*269e59f9SJan Pechanec 		if (name != NULL || dir != NULL)
139*269e59f9SJan Pechanec 			return (KMF_ERR_BAD_PARAMETER);
140*269e59f9SJan Pechanec 		tmppath = strdup(path);
141*269e59f9SJan Pechanec 		if (tmppath == NULL)
142*269e59f9SJan Pechanec 			return (KMF_ERR_MEMORY);
143*269e59f9SJan Pechanec 	/* If we only have a name and possibly a dir, we can find the path. */
144*269e59f9SJan Pechanec 	} else if (name != NULL) {
145*269e59f9SJan Pechanec 		tmppath = get_mapper_pathname(name, dir);
146*269e59f9SJan Pechanec 		/*
147*269e59f9SJan Pechanec 		 * If we were given name but the returned path is still NULL,
148*269e59f9SJan Pechanec 		 * return an error.
149*269e59f9SJan Pechanec 		 */
150*269e59f9SJan Pechanec 		if (tmppath == NULL)
151*269e59f9SJan Pechanec 			return (KMF_ERR_MEMORY);
152*269e59f9SJan Pechanec 	/* Can not exist standalone. */
153*269e59f9SJan Pechanec 	} else if (dir != NULL || opts != NULL) {
154*269e59f9SJan Pechanec 			return (KMF_ERR_BAD_PARAMETER);
155*269e59f9SJan Pechanec 	/* No attributes define the mapper so let's use the policy database. */
156*269e59f9SJan Pechanec 	} else if (map->pathname != NULL) {
157*269e59f9SJan Pechanec 		tmppath = strdup(map->pathname);
158*269e59f9SJan Pechanec 		if (tmppath == NULL)
159*269e59f9SJan Pechanec 			return (KMF_ERR_MEMORY);
160*269e59f9SJan Pechanec 		opts = map->options;
161*269e59f9SJan Pechanec 	} else if (map->mapname != NULL) {
162*269e59f9SJan Pechanec 		tmppath = get_mapper_pathname(map->mapname, map->dir);
163*269e59f9SJan Pechanec 		/*
164*269e59f9SJan Pechanec 		 * If we were given name but the returned path is still NULL,
165*269e59f9SJan Pechanec 		 * return an error.
166*269e59f9SJan Pechanec 		 */
167*269e59f9SJan Pechanec 		if (tmppath == NULL)
168*269e59f9SJan Pechanec 			return (KMF_ERR_MEMORY);
169*269e59f9SJan Pechanec 		opts = map->options;
170*269e59f9SJan Pechanec 	} else {
171*269e59f9SJan Pechanec 		/*
172*269e59f9SJan Pechanec 		 * Either a name or a full pathname must be provided whether
173*269e59f9SJan Pechanec 		 * from attributes or the policy database.
174*269e59f9SJan Pechanec 		 */
175*269e59f9SJan Pechanec 		return (KMF_ERR_BAD_PARAMETER);
176*269e59f9SJan Pechanec 	}
177*269e59f9SJan Pechanec 
178*269e59f9SJan Pechanec 	/*
179*269e59f9SJan Pechanec 	 * Dlopen the mapper specified by the policy. If anything goes wrong
180*269e59f9SJan Pechanec 	 * just return an error. We do not have to worry about resetting
181*269e59f9SJan Pechanec 	 * curpathname and curoptions to the previous values since there was no
182*269e59f9SJan Pechanec 	 * mapper initialized beforehand.
183*269e59f9SJan Pechanec 	 *
184*269e59f9SJan Pechanec 	 * No mapper was open so stored curoptions and curpathname are
185*269e59f9SJan Pechanec 	 * already NULL and need not to be freed.
186*269e59f9SJan Pechanec 	 */
187*269e59f9SJan Pechanec 	if (map->dldesc == NULL) {
188*269e59f9SJan Pechanec 		map->curpathname = tmppath;
189*269e59f9SJan Pechanec 		if (opts != NULL) {
190*269e59f9SJan Pechanec 			map->curoptions = strdup(opts);
191*269e59f9SJan Pechanec 			if (map->curoptions == NULL) {
192*269e59f9SJan Pechanec 				free(map->curpathname);
193*269e59f9SJan Pechanec 				map->curpathname = NULL;
194*269e59f9SJan Pechanec 				return (KMF_ERR_MEMORY);
195*269e59f9SJan Pechanec 			}
196*269e59f9SJan Pechanec 		} else
197*269e59f9SJan Pechanec 			map->curoptions = NULL;
198*269e59f9SJan Pechanec 
199*269e59f9SJan Pechanec 		if ((ret = open_mapper_library(map)) != KMF_OK) {
200*269e59f9SJan Pechanec 			free(map->curpathname);
201*269e59f9SJan Pechanec 			map->curpathname = NULL;
202*269e59f9SJan Pechanec 			if (map->curoptions != NULL) {
203*269e59f9SJan Pechanec 				free(map->curoptions);
204*269e59f9SJan Pechanec 				map->curoptions = NULL;
205*269e59f9SJan Pechanec 			}
206*269e59f9SJan Pechanec 			return (ret);
207*269e59f9SJan Pechanec 		}
208*269e59f9SJan Pechanec 
209*269e59f9SJan Pechanec 		goto end;
210*269e59f9SJan Pechanec 	}
211*269e59f9SJan Pechanec 
212*269e59f9SJan Pechanec 	/*
213*269e59f9SJan Pechanec 	 * We already have an open mapper, let's see if this is a new mapper
214*269e59f9SJan Pechanec 	 * library.
215*269e59f9SJan Pechanec 	 */
216*269e59f9SJan Pechanec 	if (map->curpathname != NULL &&
217*269e59f9SJan Pechanec 	    /* No change in mapper pathname. */
218*269e59f9SJan Pechanec 	    strcmp(map->curpathname, tmppath) == 0) {
219*269e59f9SJan Pechanec 		/* New options are empty while we had some before. */
220*269e59f9SJan Pechanec 		if (map->curoptions != NULL && opts == NULL) {
221*269e59f9SJan Pechanec 			map->curoptions = NULL;
222*269e59f9SJan Pechanec 		/* We have some options now while we had none before. */
223*269e59f9SJan Pechanec 		} else if (map->curoptions == NULL && opts != NULL) {
224*269e59f9SJan Pechanec 			if ((map->curoptions = strdup(opts)) == NULL)
225*269e59f9SJan Pechanec 				goto err_mem;
226*269e59f9SJan Pechanec 		/* We got different options. */
227*269e59f9SJan Pechanec 		} else if (strcmp(map->curoptions, opts) != 0) {
228*269e59f9SJan Pechanec 			if ((map->curoptions = strdup(opts)) == NULL)
229*269e59f9SJan Pechanec 				goto err_mem;
230*269e59f9SJan Pechanec 		} else {
231*269e59f9SJan Pechanec 			/*
232*269e59f9SJan Pechanec 			 * Same options, no free() of current options is
233*269e59f9SJan Pechanec 			 * required.
234*269e59f9SJan Pechanec 			 */
235*269e59f9SJan Pechanec 			old_curoptions = NULL;
236*269e59f9SJan Pechanec 		}
237*269e59f9SJan Pechanec 
238*269e59f9SJan Pechanec 		/* Free old options if applicable. */
239*269e59f9SJan Pechanec 		if (old_curoptions != NULL)
240*269e59f9SJan Pechanec 			free(old_curoptions);
241*269e59f9SJan Pechanec 	} else {
242*269e59f9SJan Pechanec 		/*
243*269e59f9SJan Pechanec 		 * This is a new mapper path, clean up the old data and open the
244*269e59f9SJan Pechanec 		 * new mapper.
245*269e59f9SJan Pechanec 		 */
246*269e59f9SJan Pechanec 		cleanup_mapper(handle);
247*269e59f9SJan Pechanec 		/* These two are no longer valid. */
248*269e59f9SJan Pechanec 		old_curoptions = NULL;
249*269e59f9SJan Pechanec 		old_curpathname = NULL;
250*269e59f9SJan Pechanec 		map->curpathname = tmppath;
251*269e59f9SJan Pechanec 		if (opts != NULL) {
252*269e59f9SJan Pechanec 			map->curoptions = strdup(opts);
253*269e59f9SJan Pechanec 			if (map->curoptions == NULL)
254*269e59f9SJan Pechanec 				goto err_mem;
255*269e59f9SJan Pechanec 		}
256*269e59f9SJan Pechanec 		if ((ret = open_mapper_library(map)) != KMF_OK) {
257*269e59f9SJan Pechanec 			/*
258*269e59f9SJan Pechanec 			 * This will cleanup curoptions and curpathname, and
259*269e59f9SJan Pechanec 			 * ignores the dldesc since it is NULL. Do not free
260*269e59f9SJan Pechanec 			 * tmppath, it will be freed through map->curpathname.
261*269e59f9SJan Pechanec 			 */
262*269e59f9SJan Pechanec 			cleanup_mapper(handle);
263*269e59f9SJan Pechanec 			return (ret);
264*269e59f9SJan Pechanec 		}
265*269e59f9SJan Pechanec 	}
266*269e59f9SJan Pechanec 
267*269e59f9SJan Pechanec end:
268*269e59f9SJan Pechanec 	initialize = (KMF_RETURN(*)())dlsym(map->dldesc,
269*269e59f9SJan Pechanec 	    MAPPER_INIT_FUNCTION);
270*269e59f9SJan Pechanec 	/* Optional, not an error if it does not exist. */
271*269e59f9SJan Pechanec 	ret = KMF_OK;
272*269e59f9SJan Pechanec 	if (initialize != NULL)
273*269e59f9SJan Pechanec 		ret = initialize(handle, map->curoptions);
274*269e59f9SJan Pechanec 
275*269e59f9SJan Pechanec 	if (ret != KMF_OK)
276*269e59f9SJan Pechanec 		cleanup_mapper(handle);
277*269e59f9SJan Pechanec 
278*269e59f9SJan Pechanec 	return (ret);
279*269e59f9SJan Pechanec 
280*269e59f9SJan Pechanec err_mem:
281*269e59f9SJan Pechanec 	/*
282*269e59f9SJan Pechanec 	 * Try to put the old curpathname and curoptions back there. In theory,
283*269e59f9SJan Pechanec 	 * the application might be able to continue to use the old mapping
284*269e59f9SJan Pechanec 	 * unless we already called cleanup_mapper(). However, it's neither
285*269e59f9SJan Pechanec 	 * recommended nor officially supported. The app should initialize the
286*269e59f9SJan Pechanec 	 * old mapping again.
287*269e59f9SJan Pechanec 	 */
288*269e59f9SJan Pechanec 	if (tmppath != NULL)
289*269e59f9SJan Pechanec 		free(tmppath);
290*269e59f9SJan Pechanec 	map->curoptions = old_curoptions;
291*269e59f9SJan Pechanec 	map->curpathname = old_curpathname;
292*269e59f9SJan Pechanec 	return (KMF_ERR_MEMORY);
293*269e59f9SJan Pechanec }
294*269e59f9SJan Pechanec 
295*269e59f9SJan Pechanec KMF_RETURN
kmf_cert_to_name_mapping_finalize(KMF_HANDLE_T handle)296*269e59f9SJan Pechanec kmf_cert_to_name_mapping_finalize(KMF_HANDLE_T handle)
297*269e59f9SJan Pechanec {
298*269e59f9SJan Pechanec 	if (handle == NULL)
299*269e59f9SJan Pechanec 		return (KMF_ERR_BAD_PARAMETER);
300*269e59f9SJan Pechanec 
301*269e59f9SJan Pechanec 	cleanup_mapper(handle);
302*269e59f9SJan Pechanec 
303*269e59f9SJan Pechanec 	return (KMF_OK);
304*269e59f9SJan Pechanec }
305*269e59f9SJan Pechanec 
306*269e59f9SJan Pechanec KMF_RETURN
kmf_map_cert_to_name(KMF_HANDLE_T handle,KMF_DATA * cert,KMF_DATA * name)307*269e59f9SJan Pechanec kmf_map_cert_to_name(KMF_HANDLE_T handle, KMF_DATA *cert, KMF_DATA *name)
308*269e59f9SJan Pechanec {
309*269e59f9SJan Pechanec 	KMF_MAPPER_RECORD *map = NULL;
310*269e59f9SJan Pechanec 	KMF_RETURN (*cert2name)(KMF_HANDLE *, KMF_DATA *, KMF_DATA *);
311*269e59f9SJan Pechanec 
312*269e59f9SJan Pechanec 	if (handle == NULL)
313*269e59f9SJan Pechanec 		return (KMF_ERR_BAD_PARAMETER);
314*269e59f9SJan Pechanec 
315*269e59f9SJan Pechanec 	map = &handle->policy->mapper;
316*269e59f9SJan Pechanec 	if (map->dldesc == NULL)
317*269e59f9SJan Pechanec 		return (KMF_ERR_MAPPER_NOT_FOUND);
318*269e59f9SJan Pechanec 
319*269e59f9SJan Pechanec 	cert2name = (KMF_RETURN(*)())dlsym(map->dldesc,
320*269e59f9SJan Pechanec 	    MAP_CERT_TO_NAME_FUNCTION);
321*269e59f9SJan Pechanec 	if (cert2name == NULL)
322*269e59f9SJan Pechanec 		return (KMF_ERR_FUNCTION_NOT_FOUND);
323*269e59f9SJan Pechanec 
324*269e59f9SJan Pechanec 	return (cert2name(handle, cert, name));
325*269e59f9SJan Pechanec }
326*269e59f9SJan Pechanec 
327*269e59f9SJan Pechanec /*
328*269e59f9SJan Pechanec  * If mapped_name is non-NULL the caller is later expected to free its Data
329*269e59f9SJan Pechanec  * after use.
330*269e59f9SJan Pechanec  */
331*269e59f9SJan Pechanec KMF_RETURN
kmf_match_cert_to_name(KMF_HANDLE_T handle,KMF_DATA * cert,KMF_DATA * name_to_match,KMF_DATA * mapped_name)332*269e59f9SJan Pechanec kmf_match_cert_to_name(KMF_HANDLE_T handle, KMF_DATA *cert,
333*269e59f9SJan Pechanec     KMF_DATA *name_to_match, KMF_DATA *mapped_name)
334*269e59f9SJan Pechanec {
335*269e59f9SJan Pechanec 	KMF_MAPPER_RECORD *map = NULL;
336*269e59f9SJan Pechanec 	KMF_RETURN (*cert2name)(KMF_HANDLE *, KMF_DATA *, KMF_DATA *,
337*269e59f9SJan Pechanec 	    KMF_DATA *);
338*269e59f9SJan Pechanec 
339*269e59f9SJan Pechanec 	if (handle == NULL)
340*269e59f9SJan Pechanec 		return (KMF_ERR_BAD_PARAMETER);
341*269e59f9SJan Pechanec 
342*269e59f9SJan Pechanec 	map = &handle->policy->mapper;
343*269e59f9SJan Pechanec 
344*269e59f9SJan Pechanec 	if (map->curpathname == NULL || map->dldesc == NULL)
345*269e59f9SJan Pechanec 		return (KMF_ERR_MAPPER_NOT_FOUND);
346*269e59f9SJan Pechanec 
347*269e59f9SJan Pechanec 	cert2name = (KMF_RETURN(*)())dlsym(map->dldesc,
348*269e59f9SJan Pechanec 	    MATCH_CERT_TO_NAME_FUNCTION);
349*269e59f9SJan Pechanec 	if (cert2name == NULL)
350*269e59f9SJan Pechanec 		return (KMF_ERR_FUNCTION_NOT_FOUND);
351*269e59f9SJan Pechanec 
352*269e59f9SJan Pechanec 	return (cert2name(handle, cert, name_to_match, mapped_name));
353*269e59f9SJan Pechanec }
354*269e59f9SJan Pechanec 
355*269e59f9SJan Pechanec /*
356*269e59f9SJan Pechanec  * The caller is responsible for freeing the error string (ie., *errstr) when
357*269e59f9SJan Pechanec  * done with it.
358*269e59f9SJan Pechanec  */
359*269e59f9SJan Pechanec KMF_RETURN
kmf_get_mapper_error_str(KMF_HANDLE_T handle,char ** errstr)360*269e59f9SJan Pechanec kmf_get_mapper_error_str(KMF_HANDLE_T handle, char **errstr)
361*269e59f9SJan Pechanec {
362*269e59f9SJan Pechanec 	KMF_HANDLE *h = NULL;
363*269e59f9SJan Pechanec 	KMF_MAPPER_RECORD *map = NULL;
364*269e59f9SJan Pechanec 	KMF_RETURN (*err2string)(KMF_HANDLE *, char **);
365*269e59f9SJan Pechanec 
366*269e59f9SJan Pechanec 	if (handle == NULL || errstr == NULL)
367*269e59f9SJan Pechanec 		return (KMF_ERR_BAD_PARAMETER);
368*269e59f9SJan Pechanec 
369*269e59f9SJan Pechanec 	h = (KMF_HANDLE *)handle;
370*269e59f9SJan Pechanec 	map = &(h->policy->mapper);
371*269e59f9SJan Pechanec 
372*269e59f9SJan Pechanec 	if (map->curpathname == NULL || map->dldesc == NULL)
373*269e59f9SJan Pechanec 		return (KMF_ERR_MAPPER_NOT_FOUND);
374*269e59f9SJan Pechanec 
375*269e59f9SJan Pechanec 	err2string = (KMF_RETURN(*)())dlsym(map->dldesc,
376*269e59f9SJan Pechanec 	    MAPPER_ERROR_STRING_FUNCTION);
377*269e59f9SJan Pechanec 	if (err2string == NULL)
378*269e59f9SJan Pechanec 		return (KMF_ERR_FUNCTION_NOT_FOUND);
379*269e59f9SJan Pechanec 
380*269e59f9SJan Pechanec 	return (err2string(h, errstr));
381*269e59f9SJan Pechanec }
382*269e59f9SJan Pechanec 
383*269e59f9SJan Pechanec void
kmf_set_mapper_lasterror(KMF_HANDLE_T handle,uint32_t err)384*269e59f9SJan Pechanec kmf_set_mapper_lasterror(KMF_HANDLE_T handle, uint32_t err)
385*269e59f9SJan Pechanec {
386*269e59f9SJan Pechanec 	handle->mapstate->lastmappererr = err;
387*269e59f9SJan Pechanec }
388*269e59f9SJan Pechanec 
389*269e59f9SJan Pechanec uint32_t
kmf_get_mapper_lasterror(KMF_HANDLE_T handle)390*269e59f9SJan Pechanec kmf_get_mapper_lasterror(KMF_HANDLE_T handle)
391*269e59f9SJan Pechanec {
392*269e59f9SJan Pechanec 	return (handle->mapstate->lastmappererr);
393*269e59f9SJan Pechanec }
394*269e59f9SJan Pechanec 
395*269e59f9SJan Pechanec void
kmf_set_mapper_options(KMF_HANDLE_T handle,void * opts)396*269e59f9SJan Pechanec kmf_set_mapper_options(KMF_HANDLE_T handle, void *opts)
397*269e59f9SJan Pechanec {
398*269e59f9SJan Pechanec 	handle->mapstate->options = opts;
399*269e59f9SJan Pechanec }
400*269e59f9SJan Pechanec 
401*269e59f9SJan Pechanec void *
kmf_get_mapper_options(KMF_HANDLE_T handle)402*269e59f9SJan Pechanec kmf_get_mapper_options(KMF_HANDLE_T handle)
403*269e59f9SJan Pechanec {
404*269e59f9SJan Pechanec 	return (handle->mapstate->options);
405*269e59f9SJan Pechanec }
406